1.2.1 Hello world example
Consider a simple, but complete, XSLFO instance
hellofo.fo for an A4 page report:
We can see the definition on line 2 of the default namespace being the XSLFO namespace, thus un-prefixed element names refer to element types in the XSLFO vocabulary. There are no prefixed element types used by any of the elements, thus the entire content is written in XSLFO.
The document model for XSLFO dictates the page geometries be summarized in
<layout-master-set> on lines 4 through 13, followed by the content to be paginated in a sequence of pages in
<page-sequence> on lines 14 through 19. The instance conforms to this and conveys our formatting intent to the formatter. The formatter needs to know the geometry of the pages being created and the content belonging on those pages.
Think of the parallel where we learned the document model for HTML requires the metadata in the
<head> element and the displayable content in the
<body> element. Both elements are required in the document model, the first to contain the mandatory title of the page and the second to contain the rendered information.
However we learned the vocabulary for HTML, when we create a page we know where the required components belong in the document. The same is true for XSLFO, in that we learn what information is required where and we express what we need in the constructs the formatter expects.
In this simple example the dimensions of A4 paper are given in a portrait orientation on line 8. Margins are specified on lines 6 and 7 to constrain the main body of the page within the page boundaries. That body region itself, described on lines 10 and 11, has margins to constrain its content, and is named so that it can be referenced from within a sequence of pages.
The sequence of pages in this example refers to the only geometry available and specifies on line 16 that the flow of paginated content is targeted to the body region on each page. The sequence is also titled on line 15, which is used by rendering agents choosing to expose the title outside the canvas for the content.
Consider two conforming XSLFO processors to process the simple
hellofo.fo example, one interactively through a GUI window interface, and the other producing a final-form representation of the page:
- Antenna House XSL Formatter (an interactive XSLFO rendering tool)
Adobe Acrobat (a Portable Document Format (PDF) display tool)
- PDF created by RenderX (a batch XSLFO rendering tool)
Note how the two renderings are not identical. If the XSLFO instance is insufficient in describing the entire intent of the formatting, the rendering may engage certain property values of its own choosing. Page fidelity is not guaranteed if the instance does not express the entire intent of formatting. Even within the expressiveness of the XSLFO semantics, there are some decisions still left up to the formatting tool.
This is not different than two web browsers with different user settings for the displayed font. A simple web page that does not use CSS stylesheets for font settings relies on the browser's tool options for the displayed font choice. The intent of the web page may be to render "a paragraph", but if two users have different tool option defaults for the font choice, there is no fidelity in the web page between the two renditions if the formatting intent is absent.
Consider an excerpt of a more complex use of formatting objects to produce a page from an early draft of the instructor-led derivative of this training material:
The nesting of the hierarchy of the formatting objects in the example page:
The page rendered in an interactive XSLFO rendering tool:
The information above the horizontal rule is rendered using a borderless table. Lines 1 through 15 describe the three columns of information: the page title and context, a placebo white box in place of the branding logo for the licensee of the training material, and the Crane registered trademark. The table cell with the page information contains text in different point sizes on lines 6 through 9.
Note how attribute value specified on line 2 is an expression, not a hard value. There is an expression language in XSLFO that is a superset of the expression language of XSLT. This can make an XSLT stylesheet easier to write by having it convey property values in a piecemeal fashion in an expression to be evaluated, rather than trying to calculate the resulting value in XSLT.
The horizontal rule below the title information needs to be block-oriented in that it needs to break the flow of information and be separate from the surrounding information. To achieve this effect with the inline-oriented leader construct, note on lines 16 and 17 how the leader is placed inside of a block. Note also how the line height of the block is adjusted in order to get the desired spacing around the leader.
The block on lines 18 and 19 lay out a simple paragraph.
Lines 20 through 28 lay out a list construct, where the labels and bodies of list items are synchronized and layout out adjacent to each other in the flow of information. This side-by-side effect cannot be achieved with simple paragraphs, and could be achieved to some extent with borderless tables, but the use of the list objects gives fine control over the nuances of the layout of a list construct.
The list block itself has properties on lines 20 and 21 governing all members of the list, including the provisional distance between the start edges of the list item label and the list item body, and the provisional label separation. These provisional values are very powerful constructs in XSLFO. They allow us to specify contingent behavior for the XSLFO processor to accommodate the varying lengths of the list item labels of the items of the list.
Remember one of the design goals of XML was that "terseness is of minimal importance" (could they have found a terser way of saying that?). Note how the attribute name specifying the first of these provisional property values is 35 characters long. It is not uncommon to need to use lengthy element and attribute names, and an XSLFO instance always seems to me to be so very verbose to read.
Note on lines 23 and 25 how functions can be used in attribute values. XSLFO defines a library of functions that can be invoked in the expression language. The
body-start() functions engage the appropriate use of one of the two provisional list construct properties based on the length of the item's label. This illustrates how XSLFO can offload layout decisions from the XSLT stylesheet, especially when it would be impossible for the XSLT stylesheet to know precise placement details that are effected by font and other issues being tracked by the formatting process.
Line 29 begins the block containing the listing of markup. To ensure a verbatim rendering of edited text, line 30 specifies that all linefeeds in the block of content be preserved, and not to collapse the white-space characters. This disengages the default behavior of treating linefeeds as white-space and collapsing white-space to a single space character, as would be typical for proportional-font paragraphs of prose.
Lines 31 and 32 show an inline sequence of text being formatted differently than the remainder of the text of the block. The desired effect of the line number being half the current font size is specified through the use of the function "
inherited-property-value(font-size)", though there are two alternate ways of specifying the same relative value: "
50%" and "
.5em". Using any of these expressions would both produce the same result.
The escaped markup on lines 33 and 35 may look incorrect, but this is an XML serialization of the XSLFO instance, hence, sensitive markup characters must be escaped in order to be recognized as text, and not as markup. Since this is a page describing markup, the markup being described needs to be distinguished from the markup of the document itself.
This is a prose version of an excerpt from an edited version of the book
Formatting Using XSLFO"
(First Edition ISBN 1-894049-07-1 at the time of this writing)
Softwrights Ltd., written by
G. Ken Holman.
Copyright © Crane Softwrights Ltd.