📜 ⬆️ ⬇️

Publish DITA to PDF using the DITA Open Toolkit. Page layout - layout-master overview

In the previous article, I made a short review, giving an overview of the publication of DITA in PDF. Now I decided to tell you how XSL-FO does the layout of the pages of a future document and how it is implemented in the basic DITA-OT configuration.
Used materials from the book "Dave Pawson, XSL-FO - Making XML Look Good in Print, 2002".

Document structure


Any document in XSL-FO can be divided into three logical parts:
  1. front matter - the front part, which includes the title page, annotation, table of contents, list of illustrations, etc.
  2. main matter (or body ) - the main part, which contains the text of the document, tables, illustrations, etc.
  3. back matter - back part that contains indexes, glossaries, bibliography, etc.

It is worth noting that this is the structure of the final document from the point of view of XSL-FO. The original DITA document usually contains only text (tables and illustrations). DITA elements contain attributes whose values ​​also play a role in publishing (the language used, alignment, snapping to neighboring elements, etc.). Table of contents, lists and indexes, title page - these parts of the document are automatically generated based on the original content.
The final document may be missing the front and / or back, or they can be combined with the main part. The main part always exists.

Files that describe the markup


For each component of the document can use its own page markup. All markup (page types) are described in the layout-masters.xsl file located in the folder .. \ org.dita.pdf2 \ cfg \ fo .
Parameter sets for each markup are set in the layout-masters-attr.xsl file , which is located in the folder .. \ org.dita.pdf2 \ cfg \ fo \ attrs .
The values ​​of the parameters in the sets are either specified explicitly or as a link to another parameter. The parameter referenced must be explicitly specified in any of the parameter files.

Markup Elements


The root element of the document XSL-FO is fo: root . The conversion for it is located in the file .. \ org.dita.pdf2 \ xsl \ fo \ root-processing.xsl . Its child element, which contains the layout of all page types, is fo: layout-master-set (see figure).

The fo: layout-master-set element in turn contains two child elements:
  1. fo: simple-page-master - contains a description of the page markup of a specific part of the document (for example, a table of contents)
  2. fo: page-sequence-master - generates a sequence of pages with specific markup. When a document is formed, the initial content of DITA is distributed to these sequences.

Both elements have a unique name, which is specified in the master-name parameter. According to it, when forming a document, the required page markup is called. The call is made from the fo: page-sequence elements, which are intended to distribute the contents of the DITA among the pages with the required markup. The fo: page-sequence refers to the fo: simple-page-master or the fo: page-sequence-master via the master-reference parameter.
')
The question arises - why use fo: page-sequence-master if you can refer to fo: simple-page-master directly. The fact is that for the same type of markup, you can use subtypes: for the first page of the section, for the last page, for even pages, for odd pages. For each subtype, as well as for the main type, its own set of parameters is specified. And fo: page-sequence-master allows for input parameters to dynamically determine which type of markup should be used. If we call fo: simple-page-master directly, then we must know in advance which markup to choose, which is not always feasible.

In DITA-OT, the subtype names are given as follows:

Simple page master


As I said above, the fo: simple-page-master element is intended to describe the page markup of a specific part of a document.
In XSL-FO, any page contains five work areas (see picture):

Each region has a name. By default, it corresponds to the name of the element. The name can be set in the region-name parameter. The name of the area is used to indicate in which document the data is to be output to which area. For example, static fo: static-content data is most often displayed in footers or fields.

Each region in XSL-FO corresponds to the same-name element (in the fo namespace). All of these elements are children of fo: simple-page-master .

Parameters Simple Page Master


The fo: simple-page-master element has the following parameters:

The figure below shows the location of areas on the page, depending on the parameters of the reference-orientation and writing-mode .


Sizes of areas


Each of the regions (except for the region-body ) has the extent parameter, which determines the size of the region in the direction perpendicular to the corresponding side of the page. For headers and footers - this is the height, for fields - the width. Set in units of length, or as a percentage of the corresponding page size ( page-height and page-width parameters).

Region-body


The size of the region-body is determined in another way. First, they are limited by the size of the page margins. Secondly, it has 4 parameters: margin-top , margin-bottom , margin-left and margin-right , which define the indents of the border of the region-body region from the content rectangle of the page reference area , indicated by the dash in the second figure. These indents can be specified in units of length or as a percentage of the size of the content rectangle of the page reference area .
Here one should draw a rather significant conclusion that the boundaries of the region-body region do not depend on the sizes and parameters of the neighboring regions.

The indents of the region-body are arranged in accordance with the orientation of the page. For example, if the page has an orientation of 90, the upper indent is measured from this direction. If the region-body has its own orientation ( reference-orientation parameter), this does not affect the position of the indents. They are still counted according to the orientation of the page. Orientation of the region-body affects only how the child blocks will be located in it.

For the region-body region, the number of columns in which the contents of the document will be placed can be specified. Two parameters are responsible for this: column-count - sets the number of columns (must be greater than or equal to 1); column-gap - the distance between adjacent columns.

Alignment in areas


For alignment in areas, the display-align parameter is used, which can take values: auto , before , center , after . It determines the alignment of the child blocks in the region in the direction of their sequence, which is specified in the parameter writing-mode .

And what about the corners?


The two upper corners of the page can be occupied by either a header or left and right margins. Similarly, the bottom corners - footer or left and right margins. The precedence parameter specified for headers and footers is responsible for this. If the parameter is true , then the corners are occupied by the footer (the one for which the parameter is specified). If the parameter is false , then the corners occupy the fields. The default setting is false .

Page Sequence Master


The fo: page-sequence-master element, as I mentioned, is intended to create a sequence of pages into which the initial content of the DITA will be distributed when the document is created.
This element has three child elements:

The conditions for the selection of markup in the fo: repeatable-page-master-alternatives element are set using the fo elements : conditional-page-master-reference . Each condition can contain from one to three parameters, which together determine whether the condition is fulfilled or not.
These parameters are:

A little bit about fo: page-sequence


So, the markup is described, the selection conditions are set, how now to call them from the XSLT transformation?
To do this, use the fo element : page-sequence . It has the required master-reference parameter, which specifies the name of the markup being called.

Also in the element can be specified the parameters responsible for the pagination.

The initial-page-number parameter fixes the number of the first page of the generated sequence of pages:

The force-page-count parameter imposes a condition on the number of pages of the generated sequence:

And how is it in DITA-OT?


A lot of theory, but how is all this implemented in the DITA Open Toolkit.
If in general terms, all types of simple-page-master markup are described first (for covers, tables of contents, etc.). Further, according to the theory, the sequence of pages page-sequence-master for each markup should be described.
DITA-OT uses the generate-page-sequence-master XSL template for this, which generates a sequence of pages using the specified parameters.
The template works out several times from the call-template . Each call generates a sequence for one type of markup in accordance with the specified parameters.

All this we can see in the file layout-masters.xsl , located in the folder .. \ org.dita.pdf2 \ cfg \ fo .
In line 43 we see the beginning of the fo: layout-master-set element, in which the fo: simple-page-master elements are located, each of which contains a description of a separate markup.

For example, the first four pieces are for the cover:
<fo:simple-page-master master-name="front-matter-first" xsl:use-attribute-sets="simple-page-master"> <fo:region-body xsl:use-attribute-sets="region-body__frontmatter.odd"/> </fo:simple-page-master> <fo:simple-page-master master-name="front-matter-last" xsl:use-attribute-sets="simple-page-master"> <fo:region-body xsl:use-attribute-sets="region-body__frontmatter.even"/> <fo:region-before region-name="last-frontmatter-header" xsl:use-attribute-sets="region-before"/> <fo:region-after region-name="last-frontmatter-footer" xsl:use-attribute-sets="region-after"/> </fo:simple-page-master> <xsl:if test="$mirror-page-margins"> <fo:simple-page-master master-name="front-matter-even" xsl:use-attribute-sets="simple-page-master"> <fo:region-body xsl:use-attribute-sets="region-body__frontmatter.even"/> <fo:region-before region-name="even-frontmatter-header" xsl:use-attribute-sets="region-before"/> <fo:region-after region-name="even-frontmatter-footer" xsl:use-attribute-sets="region-after"/> </fo:simple-page-master> </xsl:if> <fo:simple-page-master master-name="front-matter-odd" xsl:use-attribute-sets="simple-page-master"> <fo:region-body xsl:use-attribute-sets="region-body__frontmatter.odd"/> <fo:region-before region-name="odd-frontmatter-header" xsl:use-attribute-sets="region-before"/> <fo:region-after region-name="odd-frontmatter-footer" xsl:use-attribute-sets="region-after"/> </fo:simple-page-master> 


Further, after the declaration of all the markup, the sequences of the pages page-sequence-master (line 169) are generated, into which during the formation of the document the data flow from the DITA topics will be distributed.

For example, the following code generates a sequence of pages for a table of contents (toc - table of content):
 <xsl:call-template name="generate-page-sequence-master"> <xsl:with-param name="master-name" select="'toc-sequence'"/> <xsl:with-param name="master-reference" select="'toc'"/> </xsl:call-template> 

To create each sequence, the generate-page-sequence-master XSL template is invoked with the appropriate parameters in the xsl: with-param elements. In the parameters: name - the name of the parameter, select - the value of the parameter.

At the end of the file is described the XSL template generate-page-sequence-master , which generates a sequence of pages page-sequence-master in accordance with the input parameters (see the last listing). In the basic DITA-OT configuration, only the universal fo: repeatable-page-master-alternatives is used , and depending on the input parameters one or another markup is chosen.

The template has four parameters:

Next, the template creates a page-sequence-master with the name specified in the template master-name parameter. The parameter value is passed as $ master-name variable. The page-sequence-master element contains one child fo: repeatable-page-master-alternatives , which contains three conditions:
  1. xsl: if test = "$ first" - is the page first in the sequence;
  2. xsl: if test = "$ last" - is the page last in the sequence;
  3. xsl: when test = "$ mirror-page-margins" - whether different markup is used for even and odd pages.

If the page is the first, then the conditional-page-master-reference calls the markup by the name specified in the $ master-reference variable for the first page ( -first is added to the name), with parameters: odd-or-even = "odd" (odd page ) and page-position = "first" (first page).
If the page is last, then conditional-page-master-reference invokes markup by the name specified in the $ master-reference variable for the last page ( -last is added to the name), with parameters: odd-or-even = "even" (even page ), page-position = “last” (last page) and blank-or-not-blank = “blank” (empty page).
If the parity of the pages is taken into account, two conditional-page-master-reference : for even and odd pages are used. Otherwise ( xsl: otherwise ), markup for odd pages is used.

 <xsl:template name="generate-page-sequence-master"> <xsl:param name="master-name"/> <xsl:param name="master-reference"/> <xsl:param name="first" select="true()"/> <xsl:param name="last" select="true()"/> <fo:page-sequence-master master-name="{$master-name}"> <fo:repeatable-page-master-alternatives> <xsl:if test="$first"> <fo:conditional-page-master-reference master-reference="{$master-reference}-first" odd-or-even="odd" page-position="first"/> </xsl:if> <xsl:if test="$last"> <fo:conditional-page-master-reference master-reference="{$master-reference}-last" odd-or-even="even" page-position="last" blank-or-not-blank="blank"/> </xsl:if> <xsl:choose> <xsl:when test="$mirror-page-margins"> <fo:conditional-page-master-reference master-reference="{$master-reference}-odd" odd-or-even="odd"/> <fo:conditional-page-master-reference master-reference="{$master-reference}-even" odd-or-even="even"/> </xsl:when> <xsl:otherwise> <fo:conditional-page-master-reference master-reference="{$master-reference}-odd"/> </xsl:otherwise> </xsl:choose> </fo:repeatable-page-master-alternatives> </fo:page-sequence-master> </xsl:template> 

Source: https://habr.com/ru/post/266497/


All Articles