Asciidoctor-pdf: Support page layout (landscape/portrait) per page

Created on 3 Aug 2016  路  15Comments  路  Source: asciidoctor/asciidoctor-pdf

Prawn supports different page layout per page. (through start_new_page and Document.new).
Asciidoctor-pdf could support toggle-able page layout for next page to be started.

I hacked abit on the source to experiment a bit, but did not find any clean solution.
I replaced all calls to start_new_page with a super method that takes the current node and retrieves
the :page-layout: attribute from it. But this probably would not work if the start_new_page is called in a block without this attribute set. This attribute should probably work similar to the :numbered: (sectnum?) toggling. Thus, it would need to be present in all blocks?

Given the following ADoc source:

= Snickers: twist
Test Author Of the Year

== First text page
This i cannot get landscape mode...

:page-layout: landscape
<<<

== Landscape page 1
Content 1

:page-layout: portrait
<<<

== Portrait page 1
Content 2

:page-layout: landscape
<<<

== Landscape page 2
Content 3

I was able to produce this PDF:
layout.pdf

I'm looking for both discussion and suggestions to how this could be implemented (if of course this is at all anything you desire to be part of Asciidoctor-pdf). I'd be more than happy to work on it further.

enhancement

Most helpful comment

bump

All 15 comments

I like this idea, except that the correct way to do this is by using a block attribute on the page break macro.

[page-layout=landscape]
<<<

or simply

[.landscape]
<<<

I've proposed something similar in https://github.com/asciidoctor/asciidoctor-pdf/issues/250#issuecomment-146379639.

Of course, we could consult the page-layout document attribute before starting any page so that we always use the latest setting.

I do not know the asciidoctor codebase well enough so could you clarify:

When you say document attribute, are those the top-level attributes or those per block (context)?
When changing an attribute like in my example above, this only changes the block attributes, not top-level? Which mean we will need to take the current node as argument to start_new_page derivative.

It may be easier and less invasive to only support block attribute on page_break macro.

When you say document attribute, are those the top-level attributes or those per block (context)?

Top-level. They are often defined in the document header, but can also be defined between any two blocks.

When changing an attribute like in my example above, this only changes the block attributes, not top-level?

Your solution works, it's just that you are essentially using a global variable (document attribute) to control the behavior of a local component (the block). This is exactly why block-level attributes were introduced. You can define settings directly on the block node. It's also more semantic.

It may be easier and less invasive to only support block attribute on page_break macro.

This is the direction I'm leaning.

We should probably support both size and layout.

Not sure in what stage of development this is at the moment, but if it is being developed, I would like to suggest to give the end user not only the ability to specify the page orientation, but also the page size.

For example, it would be great if I could have an A3 landscape page inside an otherwise A4 portrait document. That A3 page could be used for detailed graphics, a huge table, a scaled down blue print, etc.

When printed, the A3 page can be neatly folded, inline with the rest of the pages.

Marc.

That sounds reasonable.

The risk in this feature is that there are several places (I think) where we assume that the size of every page is the same. We could no longer make that assumption, or we'd have to enable a flag to disable it (and thus compute each time or on specified pages).

This would be awesome to have. I've gotten requests about this from my users now as well.

@veeg Could you share how you achieved your hack so I can use that until the full implementation is done?

@mojavelinux
One more thing to add as food for thought. If you support switched layouts between pages, there must be separate options in the theme file to set margins for the different layouts. I just exported one of my documents in landscape to test and the header and footer margins get way too narrow in landscape mode because they're apparently just rotated from portrait.

I would think something like

page:
  portrait:
    margin:
    margin_inner:
    margin_outer:
  landscape:
    margin:
    margin_inner:
    margin_outer:

Or

page:
  portrait:
    margin:
    margin_inner:
    margin_outer:
  landscape_margin_outer:

would make sense to control this. Then you should move layout to "base" since this will be the baseline default unless overridden in the document.

base:
  layout: portrait

bump

bump

Merged. We don't yet have support for controlling the margins per page, so all pages still get the same margins.

When using Asciidoctor PDF backend,

[.landscape]
<<<

works to flip the page, but

[.portrait]
<<<

doesn't flip it back.

@dalemartin Uh oh! We could be missing a test. Could you file a new issue so that I can address it specifically?

For sure.

EDIT: I opened #1091.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jniggemann picture jniggemann  路  4Comments

orloffm picture orloffm  路  6Comments

IbnSaeed picture IbnSaeed  路  9Comments

asilvestre picture asilvestre  路  5Comments

fly7632785 picture fly7632785  路  7Comments