| XSL FO (Formatting Objects) |
|
| XSL Formatting Objects |
|
| XSL Formatting Objects (XSL-FO) are the second half of the Extensible Stylesheet Language (XSL). XSL-FO is an XML application that describes how pages will look when presented to a reader. A style sheet uses the XSL transformation language to transform an XML document in a semantic vocabulary into a new XMLdocument that uses the XSL-FO presentational vocabulary. |
|
| While one can hope that Web browsers will one day know how to directly display data marked up with XSL formatting objects, for now an additional step is necessary in which the output document is further transformed into some other format, such as Adobe’s PDF. |
|
| Unlike the combination of HTML and CSS, XSL-FO is a unified presentational language. It has no semantic markup in the way it is meant in HTML. And, unlike CSS which modifies the default presentation of an external XML or HTML document, it stores all of the document's data within itself. |
|
| The general idea behind XSL-FO's use is that the user writes a document, not in FO, but in an XML language. XHTML, DocBook, and TEI are all possibilities, but it could be any XML language. Then, the user obtains an XSLT transform, either by writing one themselves or by finding one for the document type in question. This XSLT transform converts the XML into XSL-FO. |
|
| Once the XSL-FO document is generated, it is then passed to an application called a FOprocessor. FO processors convert the XSL-FO document into something that is readable, printable or both. The most common output of XSL-FO is a PDF file or as PS, but some FO processors can output to other formats like RTF files or even just a window in the user's GUI displaying the sequence of pages and their contents. |
|
| The XSLT language itself was originally conceived only for this purpose; it has obviously now been supplanted for more general XML transformations. This transformation step is taken so much for granted in XSL-FO that it is not uncommon for people to call theXSLT that turns XML into XSL-FO the actual XSL-FO document itself. Even tutorials onXSL-FO tend to be written with XSLT commands around the FO processing instructions. |
|
| The XSLT transformation step is exceptionally powerful. It allows for the automatic generation of a table of contents, linked references, an index, and various other possibilities. |
|
| An XSL-FO document is not like a PDF or a PostScript document. It does not fully describe the layout of the text on various pages. Instead, it describes what the pages look like and where the various contents go. |
|
| From there, a FO processor determines how to position the text within the boundaries described by the FO document. The XSL-FO specification even allows different FOprocessors to have varying responses with regard to the resultant generated pages. |
|
| For example, some FO processors can hyphenate words to minimize space when breaking a line, while others choose not to. Different processors may even use different hyphenation algorithms, ranging from very simple to more complex hyphenated algorithms that take into account whether the previous or next line also is hyphenated. |
|
| These will change, in some borderline cases quite substantially, the layout of the various pages. There are other cases where the XSL-FO specification explicitly allows FO processors some degree of choice with regard to layout. |
|
| This differentiation between FO processors, creating inconsistent results between processors is often not a concern. This is because the general purpose behind XSL-FOis to generate paged, printed media. XSL-FO documents themselves are usually used as intermediaries, mostly to generate either PDF files or a printed document as the final form to be distributed. |
|
| This is as opposed to how HTML is generated and distributed as a final form directly to the user. As such, a person wanting to generate a printed document only has to select the FO processor that fulfills their needs, usually in the realm of layout quality and reduction of unnecessary whitespace, rather than having to test their XSL-FO document on multiple processors. |
|
| XSL-FO Language Concepts |
|
| The XSL-FO language was designed for paged media, in much the same way that HTMLand CSS were designed for unpaged (or screen-based) media. As such, the concept of pages is an integral part of XSL-FO's structure, and FO gives the user significant power in dealing with how information is displayed on a page. |
|
| FO works best for what could be called "content-driven" design. This is the standard method of layout for books, articles, legal documents, and so forth. It involves a single flowing span of fairly contiguous text, with various repeating information built into the margins of a page. |
|
| This is as opposed to "layout-driven" design, which is used in newspapers or magazines. If content in those documents does not fit in the required space, some of it is trimmed away until it does fit. XSL-FO does not easily handle the tight restrictions of magazine layout; indeed, in many cases, it lacks the ability to express some forms of said layout. |
|
| Despite the basic nature of the language's design, it is capable of a great deal of expressiveness. Tables, lists, side floats, and a variety of other features are available. These features are comparable to CSS's layout features, though some of those features are expected to be built by the XSLT. |
|
|
|
|
| XSL FO(Formatting Objects) |
|
| Formatting objects and properties |
|
| XSL-FO provides a more sophisticated visual layout model than HTML+CSS. Formatting supported by XSL-FO, but not supported by HTML+CSS, includes right-to-left and top-to-bottom text, footnotes, margin notes, page numbers in cross-references, and more. |
|
| In particular, while CSS (Cascading Style Sheets) is primarily intended for use on the Web, XSL-FO is designed for broader use. You should, for instance, be able to write anXSL style sheet that uses formatting objects to lay out an entire printed book. A different style sheet should be able to transform the same XML document into a Web site. |
|
| A Word of Caution about XSL Formatting Objects |
|
| This chapter is based on the October 15, 2001 Recommendation of the XSLspecification. However, most software does not implement all of the the final recommendation for XSL. In fact, so far there are only a few standalone programs that convert XSL-FO documents into PDF files. |
|
| There are no Web browsers that can display a document written with XSL formatting objects. Eventually, of course, this should be straightened out as more vendors implement XSL formatting objects. |
|
| There are exactly 56 XSL formatting object elements. These are placed in thehttp://www.w3.org/1999/XSL/Format namespace. At least 99 percent of the time, the chosen prefix is fo. In this chapter, I use the fo prefix to indicate this namespace without further comment. |
|
| Of the 56 elements, most signify various kinds of rectangular areas. Most of the rest are containers for rectangular areas and spaces. In alphabetical order, these formatting objects are: |
|
1. fo:basic-link
2. fo:bidi-override
3. fo:block
4. fo:block-container
5. fo:character
6. fo:color-profile
7. fo:conditional-page-master-reference
8. fo:declarations
9. fo:external-graphic
10. fo:float 11. fo:flow
12. fo:footnote
13. fo:footnote-body
14. fo:initial-property-set
15. fo:inline
16. fo:inline-container
17. fo:instream-foreign-object
18. fo:layout-master-set
19. fo:leader
20. fo:list-block
21. and 36 more |
|
| The XSL formatting model is based on rectangular boxes called areas that can contain text, empty space, images, or other formatting objects. As with CSS boxes, an area has borders and padding on each of its sides, although CSS's margins are replaced byXSL's space-before and space-after. |
|
| An XSL formatter reads the formatting objects to determine which areas to place where on the page. Many formatting objects produce single areas (at least most of the time);` but because of page breaks, word wrapping, hyphenation, and other details that must be taken into account when fitting a potentially infinite amount of text into a finite amount of space, some formatting objects do occasionally generate more than one area. |
|
| The formatting objects differ primarily in what they represent. For example, the fo:list-item-label formatting object is a box that contains a bullet, a number, or another indicator placed in front of a list item. |
|
| A fo:list-item-body formatting object is a box that contains the text, sans label, of the list item. And a fo:list-item formatting object is a box that contains both the fo:list-item-label and fo:list-item-body formatting objects. |
|
| When processed, the formatting objects document is broken up into pages. A Web browser window will normally be treated as one very long page. A print format will often contain many individual pages. Each page contains a number of areas. There are four primary kinds of areas: |
|
1. regions
2. block areas
3. line areas
4. inline areas |
|
| These form a rough hierarchy. Regions contain block areas. Block areas contain other block areas, line areas, and content. Line areas contain inline areas. Inline areas contain other inline areas and content. More specifically: |
|
| • A region is the highest-level container in XSL-FO. You can think of a page of this book as containing three regions: the header, the main body of the page, and the footer. Formatting objects that produce regions include fo:region-body, fo:region-before, fo:region-after, fo:region-start, and fo:region-end. |
|
| • A block area represents a block-level element, such as a paragraph or a list item. Although block areas may contain other block areas, there should always be a line break before the start and after the end of each block area. A block area, rather than being precisely positioned by coordinates, is placed sequentially in the area that contains it. |
|
| As other block areas are added and deleted before it or within it, the block area’s position shifts as necessary to make room. A block area may contain parsed character data, inline areas, line areas, and other block areas that are sequentially arranged in the containing block area. Formatting objects that produce block areas include fo:block, fo:table-and-caption, and fo:list-block. |
|
| • A line area represents a line of text inside a block. For example, each of the lines in this list item is a line area. Line areas can contain inline areas and inline spaces. There are no formatting objects that correspond to line areas. Instead, the formatting engine calculates the line areas as it decides how to wrap lines inside block areas. |
|
| • Inline areas are parts of a line such as a single character, a footnote reference, or a mathematical equation. Inline areas can contain other inline areas and raw text. Formatting objects that produce inline areas include fo:character, fo:external-graphic, fo:inline, fo:instream-foreign-object, fo:leader, and fo:page-number. |
|
| Formatting properties |
|
| When taken as a whole, the various formatting objects in an XSL-FO document specify the order in which content is to be placed on pages. However, formatting properties specify the details of formatting such as size, position, font, color, and a lot more. Formatting properties are represented as attributes on the individual formatting object elements. |
|
| The details of many of these properties should be familiar from CSS. Work is ongoing to ensure that CSS and XSL-FO use the same names to mean the same things. For example, the CSS font-family property means the same thing as the XSL font-family property; and although the syntax for assigning values to properties is different in CSSand XSL-FO, the meaning of the values themselves is the same. To indicate that the fo:block element is formatted in some approximation of Times, you might use this CSSrule: |
|
fo:block {font-family: 'New York', 'Times New Roman', serif}
The XSL-FO equivalent is to include a font-family attribute in the fo:block start tag in this way: |
|
| <fo:block font-family="'New York', 'Times New Roman', serif"> |
|
| Although this is superficially different, the style name (font-family) and the style value ('New York', 'Times New Roman', serif) are the same. CSS's font-family property is specified as a list of font names, separated by commas, in order from first choice to last choice. |
|
| XSL-FO’s font-family property is specified as a list of font names, separated by commas, in order from first choice to last choice. Both CSS and XSL-FO quote font names that contain white space. Both CSS and XSL-FO understand the keyword serif to mean an arbitrary serif font. |
|
| Of course, XSL formatting objects support many properties that have no CSSequivalent, such as destination-placement-offset, block-progression-dimension, character, and hyphenation-keep. You need to learn these to take full advantage ofXSL. The standard XSL-FO properties follow: |
|
• absolute-position
• active-state
• alignment-adjust
• alignment-baseline
• auto-restore
• azimuth
• background
• background-attachment
• background-color
• background-image
• background-position
• background-position-horizontal
• background-position-vertical
• background-repeat
• baseline-shift
• blank-or-not-blank
• block-progression-dimension
• border
• border-after-color
• border-after-precedence
• border-after-style
• border-after-width
• border-before-color
• border-before-precedence
• border-before-style
• border-before-width
• border-bottom
• border-bottom-color
• border-bottom-style
• border-bottom-width
• border-collapse
• border-color
• border-end-color
• border-end-precedence
• border-end-style
• border-end-width
• border-left
• border-left-color |
• border-left-style
• border-left-width
• border-right
• border-right-color
• border-right-style
• border-right-width
• border-separation
• border-spacing
• border-start-color
• border-start-precedence
• border-start-style
• border-start-width
• border-style
• border-top
• border-top-color
• border-top-style
• border-top-width
• border-width
• bottom
• break-after
• break-before
• caption-side
• case-name
• case-title
• character
• clear
• clip
• color
• color-profile-name
• column-count
• column-gap
• column-number
• column-width
• content-height
• content-type
• content-width
• country
• cue
• cue-after
• cue-before
• destination-placement-offset
• direction
• display-align
• dominant-baseline
• elevation
• empty-cells
• end-indent
• ends-row
• extent |
|
• external-destination
• float
• flow-name
• font
• font-family
• font-selection-strategy
• font-size
• font-size-adjust
• font-stretch
• font-style
• font-variant
• font-weight
• force-page-count
• format
• glyph-orientation-horizontal
• glyph-orientation-vertical
• grouping-separator
• grouping-size
• height
• hyphenate
• hyphenation-character
• hyphenation-keep
• hyphenation-ladder-count
• hyphenation-push-character-count
• hyphenation-remain-character-count
• id
• indicate-destination
• initial-page-number
• inline-progression-dimension
• internal-destination
• keep-together
• keep-with-next
• keep-with-previous
• language
• last-line-end-indent
• leader-alignment
• leader-length
• leader-pattern
• leader-pattern-width
• left
• letter-spacing
• letter-value
• linefeed-treatment
• line-height
• line-height-shift-adjustment
• line-stacking-strategy
• margin
• margin-bottom
• margin-left |
|
• margin-right
• margin-top
• marker-class-name
• master-name
• master-reference
• max-height
• maximum-repeats
• max-width
• media-usage
• min-height
• min-width
• number-columns-repeated
• number-columns-spanned
• number-rows-spanned
• odd-or-even
• orphans
• overflow
• padding
• padding-after
• padding-before
• padding-bottom
• padding-end
• padding-left
• padding-right
• padding-start
• padding-top
• page-break-after
• page-break-before
• page-break-inside
• page-height
• page-position
• page-width
• pause
• pause-after
• pause-before
• pitch
• pitch-range
• play-during
• position
• precedence
• provisional-distance-between-starts
• provisional-label-separation
• reference-orientation
• ref-id
• region-name
• relative-align
• relative-position
• rendering-intent
• retrieve-boundary |
|
• retrieve-class-name
• retrieve-position
• richness
• right
• role
• rule-style
• rule-thickness
• scaling
• scaling-method
• score-spaces
• script
• show-destination
• size
• source-document
• space-after
• space-before
• space-end
• space-start
• space-treatment
• span
• speak
• speak-header
• speak-numera
l
• speak-punctuation
• speech-rate
• src
• start-indent
• starting-state
• starts-row
• stress
• suppress-at-line-break
• switch-to
• table-layout
• table-omit-footer-at-break
• table-omit-header-at-break
• target-presentation-context
• target-processing-context
• target-stylesheet
• text-align
• text-align-last
• text-altitude
• text-decoration
• text-depth
• text-indent
• text-shadow
• text-transform
• top
• treat-as-word-space
• unicode-bidi |
|
• vertical-align
• visibility
• voice-family
• volume
• white-space
• white-space-collapse
• widows
• width
• word-spacing
• wrap-option
• writing-mode
• xml:lang
• z-index |
|
| Transforming to formatting objects |
|
| XSL-FO is a complete XML vocabulary for laying out text on a page. An XSL-FOdocument is simply a well-formed XML document that uses this vocabulary. That means it has an XML declaration, a root element, child elements, and so forth. |
|
| It must adhere to all the well-formedness rules of any XML document, or formatters will not accept it. By convention, a file that contains XSL formatting objects has the three-letter extension .fob or the two-letter extension .fo. However, it might have the suffix .xml because it also is a well-formed XML file. |
|
| Listing 19-1 is a simple document marked up using XSL formatting objects. The root of the document is fo:root. This element contains a fo:layout-master-set and a fo:page-sequence. The fo:layout-master-set element contains fo:simple-page-master child elements. Each fo:simple-page-master describes a kind of page on which content will be placed. |
|
| Here there's only one very simple page, but more complex documents can have different master pages for first, right, and left, body pages, front matter, back matter, and more, each with a potentially different set of margins, page numbering, and other features. The name bu which the page master will be referred to is given in the master-name attribute. |
|
| Content is placed on copies of the master page using a fo:page-sequence. The fo:page-sequence has a master-reference attribute naming the master page to be used. Its fo:flow child element holds the actual content to be placed on the pages. The content here is given as two fo:block children, each with a font-size property of 20 points, a font-family property of serif, and a line-height of 30 points. |
|
|
|
|
| XSL FO(Formatting Objects) |
|
| Sample XSL-FO |
|
| XSL-FO documents are XML files with output information. They contain information about the output layout and output contents. XSL-FO documents are stored in files with a .fo or a .fob file extension. It is also quite common to see XSL-FO documents stored with an .xml extension, because this makes them more accessible to XML editors. |
|
<?xml version="1.0" encoding="ISO-8859-1"?>
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:layout-master-set>
<fo:simple-page-master master-name="A4">
<!-- Page template goes here -->
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="A4">
<!-- Page content goes here -->
</fo:page-sequence>
</fo:root>
|
|
| Explanation of the above structure |
|
| XSL-FO documents are XML documents, and must always start with an XML declaration: |
|
| <?xml version="1.0" encoding="ISO-8859-1"?> |
|
| The <fo:root> element is the root element of XSL-FO documents. The root element also declares the namespace for XSL-FO: |
|
| <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"> <!-- The XSL-FO document goes here --> </fo:root> |
|
| The <fo:layout-master-set> element contains one or more page templates: |
|
<fo:layout-master-set>
<!—The page templates go here -->
</fo:layout-master-set> |
|
| Each <fo:simple-page-master> element contains a single page template. Each template must have a unique name (master-name): |
|
<fo:simple-page-master master-name="A4">
<!-- One page template goes here -->
</fo:simple-page-master> |
|
| One or more <fo:page-sequence> elements describe the page contents. The master-reference attribute refers to the simple-page-master template with the same name: |
|
<fo:page-sequence master-reference="A4">
<!-- Page content goes here -->
</fo:page-sequence> |
|
| Note: The master-reference "A4" does not actually describe a predefined page format. It is just a name. You can use any name like "eBIZ", "MyDoc", etc. |
|
| Sample XSL-FO template |
|
<xsl:template match="chapter">
<fo:flow>
<xsl:apply-templates/>
</fo:flow>
</xsl:template>
<xsl:template match="chapter/title">
<fo:block font-size="18pt" font-weight="bold"
text-align="centered">
<xsl:apply-templates/>
</fo:block>
</xsl:template>
<xsl:template match="para">
<fo:block font-size="12pt" space-before="1pc"
text-align="justified">
<xsl:apply-templates/>
</fo:block>
</xsl:template>
<xsl:template match="emphasis">
<fo:inline font-style="italic">
<xsl:apply-templates/>
</fo:inline>
</xsl:template>
|
|
|
|
|
| XSL FO(Formatting Objects) |
|
| Formatting Object Basics |
|
| Page Layout |
|
| The root element of a formatting objects document is fo:root. This element contains one fo:layout-master-set element and one or more fo:page-sequence elements. The fo:page-sequence elements contain content; that is, text and images to be placed on the pages. The fo:layout-master-set contains templates for the pages that will be created. |
|
| When the formatter reads an XSL-FO document, it creates a page based on the first template in the fo:layout-master-set. Then it fills it with content from the fo:page-sequence. When it's filled the first page, it instantiates a second page based on a template, and fills it with content. The process continues until the formatter runs out of content. |
|
| The root element |
|
| The fo:root element generally has an xmlns:fo attribute with the valuehttp://www.w3.org/1999/XSL/Format and may (though it generally does not) have an id attribute. The fo:root element exists just to declare the namespace and be the document root. It has no direct effect on page layout or formatting. |
|
| Simple page masters |
|
| The page templates are called page masters. Page masters are similar in purpose to QuarkXPress master pages or PowerPoint slide masters. Each defines a general layout for a page including its margins, the sizes of the header, footer, and body area of the page, and so forth. |
|
| Each actual page in the rendered document is based on one master page, and inherits certain properties like margins, page numbering, and layout from that master page.XSL-FO 1.0 defines exactly one kind of page master, the fo:simple-page-master, which represents a rectangular page. The fo:layout-master-set contains one or more fo:simple-page-master elements that define master pages. |
|
Note
Future versions of XSL-FO will add other kinds of page masters, possibly including non-rectangular pages. |
|
| Each master page is represented by a fo:simple-page-master element. A fo:simple-page-master element defines a page layout, including the size of its before region, body region, after region, end region, and start region. Figure 19-2 shows the typical layout of these parts. |
|
| One thing that may not be obvious from this picture is that the body region overlaps the other four regions (though not the page margins); that is, the body is everything inside the thick black line including the start, end, before, and after regions. |
|
 |
|
| The layout of the parts of a simple page of English text |
|
Note
In normal English text, the end region is the right side of the page and the start region is the left side of the page. This is reversed in Hebrew or Arabic text, because these languages are written from right to left. In almost all modern languages, the before region is the header and the after region is the footer, but this could be reversed in a language that wrote from bottom to top. |
|
| Simple page master properties |
|
| The fo:simple-page-master element has three main attributes: |
|
• master-name: the name by which page sequences will reference this master page
• page-height: the height of the page
• page-width: the width of the page |
|
| If the page-height and page-width are not provided, then the formatter chooses a reasonable default based on the media in use (for example, 8.5" × 11"). |
|
| Other attributes commonly applied to page masters include: |
|
• The margin-bottom, margin-left, margin-right, and margin-top attributes, or the shorthand margin attribute
• The writing-mode attribute that determines which direction text flows on the page, for example, left-to-right or right-to-left or top-to-bottom
• The reference-orientation attribute that specifies in 90-degree increments whether and how much the content is rotated |
|
| For example, here is a fo:layout-master-set containing one fo:simple-page-master named US-Letter. It specifies an 8.5 × 11-inch page with half-inch margins on each side. It contains a single region, the body, into which all content will be placed. |
|
<fo:layout-master-set>
<fo:simple-page-master master-name="US-Letter"
page-height="11in" page-width="8.5in"
margin-top="0.5in" margin-bottom="0.5in"
margin-left="0.5in" margin-right="0.5in">
<fo:region-body/>
</fo:simple-page-master>
</fo:layout-master-set>
|
|
| Regions |
|
| The designer sets the size of the body (center) region, header, footer, end region, and start region, as well as the distances between them, by adding region child elements to the fo:simple-page-master. These are: |
|
• fo:region-before
• fo:region-after
• fo:region-body • fo:region-start
• fo:region-end |
|
| The fo:region-before and fo:region-after elements each have an extent attribute that gives the height of these regions. Their width extends from the left side of the page to the right side. The fo:region-start and fo:region-end elements each have an extent attribute that specifies their widths. |
|
| Their height extends from the bottom of the start region to the top of the end region. (This assumes normal Western text. Details would be rotated in Chinese or Hebrew or some other non-right-to-left-top-to-bottom script.) |
|
| The fo:region-body does not have an extent attribute. Instead, the size of the body is everything inside the page margins. Thus, the region body overlaps the other four regions on the page. If you place text into the body and the other four regions, text will be drawn on top of other content. To avoid this, you must set the left margin of the body to be as large or larger than the extent of the start region, the top margin of the body to be as large or larger than the extent of the before region, and so on. |
|
| Each of the five regions of a simple page master may be filled with content from a fo:flow or fo:static-content element when the document is processed. However, these elements do not contain that content. Instead, they simply give the dimensions of the boxes the formatter will build to put content in. They are blueprints for the boxes, not the boxes themselves. |
|
| For example, this fo:simple-page-master creates pages with one-inch before and after regions. The region body will extend vertically from the bottom of the before region to the top of the after region. It will extend horizontally from the left side of the page to the right side of the page because there is no start or end region. |
|
<fo:simple-page-master master-name="table_page">
<fo:region-before extent="1.0in"/>
<fo:region-body margin-top="1.0in" margin-bottom="1.0in"/>
<fo:region-after extent="1.0in"/>
</fo:simple-page-master>
|
|
| For another example, here is a fo:layout-master-set that makes all outer regions one inch. Furthermore, the page itself has a half-inch margin on all sides. |
|
<fo:layout-master-set>
<fo:simple-page-master master-name="only"
page-width="8.5in" page-height="11in"
margin-top="0.5in" margin-bottom="0.5in"
margin-left="0.5in" margin-right="0.5in">
<fo:region-start extent="1.0in"/>
<fo:region-before extent="1.0in"/>
<fo:region-body margin="1.0in"/>
<fo:region-end extent="1.0in"/>
<fo:region-after extent="1.0in"/>
</fo:simple-page-master>
</fo:layout-master-set>
|
|
| The body regions from pages based on this page master will be 5.5 inches wide and 8 inches high. That's calculated by subtracting the sum of the body region's margins and the page margins from the size of the page. |
|
| Page sequences |
|
| In addition to a fo:layout-master-set, each formatting object document contains one or more fo:page-sequence elements. Each page in the sequence has an associated page master that defines how the page will look. Which page master this is, is determined by the master-reference attribute of the fo:page-sequence element. |
|
| This must match the name of a page master in the fo:layout-master-set. Listing 19-1 used a fo:simple-master-page named only to fill this role, but it is not uncommon to have more than one master page. In this case, the master pages might be grouped as part of a fo:page-sequence-master instead. |
|
| For instance, you could have one master page for the first page of each chapter, a different one for all the subsequent left-hand pages, and a third for all the subsequent right-hand pages. Or, there could be one simple page master for a table of contents, another for body text, and a third for the index. In this case, you use one page sequence each for the table of contents, the body text, and the index. |
|
| Each page sequence contains three child elements in this order: |
|
1. An optional fo:title element containing inline content that can be used as the title of the document. This would normally be placed in the title bar of the browser window like the TITLE element in HTML
2. Zero or more fo:static-content elements containing text to be placed on every page
3. One fo:flow element containing data to be placed on each page in turn |
|
| The main difference between a fo:flow and a fo:static-content is that text from the flow isn't placed on more than one page, whereas the static content is. For example, the words you're reading now are flow content that only appear on this page, whereas the part and chapter titles at the top of the page are static content that is repeated from page to page. |
|
| The fo:flow element contains, in order, the elements to be placed on the page. As each page fills with elements from the flow, a new page is created with the next master page in the page sequence master for the elements that remain in the flow. With a simple page master, the same page will be instantiated repeatedly, as many times as necessary to hold all the content. |
|
| The fo:static-content element contains information to be placed on each page. For instance, it may place the title of a book in the header of each page. Static content can be adjusted depending on the master page. For instance, the part title may be placed on left-hand pages, and the chapter title on right-hand pages. The fo:static-content element can also be used for items such as page numbers that have to be calculated from page to page. In other words, what's static is not the text, but the calculation that produces the text. |
|
| Flows |
|
| The fo:flow object holds the actual content, which will be placed on the instances of the master pages. This content is composed of a sequence of fo:block, fo:block-container, fo:table-and-caption, fo:table, and fo:list-block elements. This section sticks to basic fo:block elements, which are roughly equivalent HTML's DIV elements. Later in this chapter, you learn more block-level elements that a flow can contain. |
|
| For example, here is a basic flow containing the names of several atoms, each in its own block: |
|
|
<fo:flow flow-name="xsl-region-body">
<fo:block>Actinium</fo:block>
<fo:block>Aluminum</fo:block>
<fo:block>Americium</fo:block>
</fo:flow> |
|
| The flow-name attribute of the fo:flow, here with the value xsl-region-body, specifies which of the five regions of the page this flow's content will be placed in. The allowed values are: |
|
• xsl-region-body
• xsl-region-before
• xsl-region-after
• xsl-region-start
• xsl-region-end |
|
| For example, a flow for the header has a flow-name value of xsl-region-before. A flow for the body would have a flow-name of xsl-region-body. Only one fo:flow is allowed in the same page sequence. The other four regions have to be filled with a fo:static-content if anything. |
|
| You can now put together a complete style sheet that lays out the entire periodic table. Listing 19-3 demonstrates this with an XSLT style sheet that converts the periodic table into XSL formatting objects. The flow grabs all the atoms and places each one in its own block. A simple page master named only defines an A4-sized master page in landscape mode with half-inch margins on each side. |
|
Listing 19-3 A
basic style
sheet for the
periodic table |
|
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:template match="/">
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:layout-master-set>
<fo:simple-page-master master-name="A4"
page-width="297mm" page-height="210mm"
margin-top="0.5in" margin-bottom="0.5in"
margin-left="0.5in" margin-right="0.5in">
<fo:region-body/>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="A4">
<fo:flow flow-name="xsl-region-body">
<xsl:apply-templates select="//ATOM"/>
</fo:flow>
</fo:page-sequence>
</fo:root>
</xsl:template>
<xsl:template match="ATOM">
<fo:block><xsl:value-of select="NAME"/></fo:block>
</xsl:template>
</xsl:stylesheet>
|
|
| Figure 19-3 shows the resulting document after Listing 19-3 has been run through anXSLT processor to produce an XSL-FO document, and that document has been run through FOP to produce a PDF file. |
|
 |
|
|
|
|
| XSL FO(Formatting Objects) |
|
| Common Formatting Objects |
|
• page-sequence--a major part (such as front or body) in which the basic page layout may differ from other parts
• flow--a chapter- or section-like division within a page-sequence
• block--a paragraph (or title or block quote, etc.)
• inline--e.g., a font change within a paragraph
• wrapper--a "transparent" object usable as either a block or inline object that has no effect other than to provide a place to hang inheritable properties
• list FOs--list-block, list-item, list-item-label, list-item-body
• graphic--references an external graphic object
• table FOs--mostly analogous to the standard (CALS, OASIS, HTML) table models
|
|
| Basic properties |
|
• font properties
• margin and spacing properties
• border and padding properties
• keeps/breaks
• horizontal alignment/justification
• indentation
• more formatting object specific properties |
|
| Formatting properties |
|
| When taken as a whole, the various formatting objects in an XSL-FO document specify the order in which content is to be placed on pages. However, formatting properties specify the details of formatting such as size, position, font, color, and a lot more. Formatting properties are represented as attributes on the individual formatting object elements. |
|
| The details of many of these properties should be familiar from CSS. Work is ongoing to ensure that CSS and XSL-FO use the same names to mean the same things. For example, the CSS font-family property means the same thing as the XSL font-family property; and although the syntax for assigning values to properties is different in CSSand XSL-FO, the meaning of the values themselves is the same. |
|
| To indicate that the fo:block element is formatted in some approximation of Times, you might use this CSS rule: |
|
| fo:block {font-family: 'New York', 'Times New Roman', serif} |
|
| The XSL-FO equivalent is to include a font-family attribute in the fo:block start tag in this way: |
|
| <fo:block font-family="'New York', 'Times New Roman', serif"> |
|
| Although this is superficially different, the style name (font-family) and the style value ('New York', 'Times New Roman', serif) are the same. CSS's font-family property is specified as a list of font names, separated by commas, in order from first choice to last choice. |
|
| XSL-FO’s font-family property is specified as a list of font names, separated by commas, in order from first choice to last choice. Both CSS and XSL-FO quote font names that contain white space. Both CSS and XSL-FO understand the keyword serif to mean an arbitrary serif font. |
|
|
|
|
| XSL FO(Formatting Objects) |
|
| Page Layout |
|
| Page Layout |
|
| The root element of a formatting objects document is fo:root. This element contains one fo:layout-master-set element and one or more fo:page-sequence elements. The fo:page-sequence elements contain content; that is, text and images to be placed on the pages. The fo:layout-master-set contains templates for the pages that will be created. |
|
| When the formatter reads an XSL-FO document, it creates a page based on the first template in the fo:layout-master-set. Then it fills it with content from the fo:page-sequence. When it's filled the first page, it instantiates a second page based on a template, and fills it with content. The process continues until the formatter runs out of content. |
|
 |
|
| The root element |
|
| The fo:root element generally has an xmlns:fo attribute with the valuehttp://www.w3.org/1999/XSL/Format and may (though it generally does not) have an id attribute. The fo:root element exists just to declare the namespace and be the document root. It has no direct effect on page layout or formatting. |
|
| Simple page masters |
|
| The page templates are called page masters. Page masters are similar in purpose to QuarkXPress master pages or PowerPoint slide masters. Each defines a general layout for a page including its margins, the sizes of the header, footer, and body area of the page, and so forth. |
|
| Each actual page in the rendered document is based on one master page, and inherits certain properties like margins, page numbering, and layout from that master page.XSL-FO 1.0 defines exactly one kind of page master, the fo:simple-page-master, which represents a rectangular page. The fo:layout-master-set contains one or more fo:simple-page-master elements that define master pages. |
|
| Each master page is represented by a fo:simple-page-master element. A fo:simple-page-master element defines a page layout, including the size of its before region, body region, after region, end region, and start region. Figure 19-2 shows the typical layout of these parts. |
|
| One thing that may not be obvious from this picture is that the body region overlaps the other four regions (though not the page margins); that is, the body is everything inside the thick black line including the start, end, before, and after regions. |
|
| Simple page master properties |
|
| The fo:simple-page-master element has three main attributes: |
|
• master-name: the name by which page sequences will reference this master page
• page-height: the height of the page
• page-width: the width of the page |
|
| If the page-height and page-width are not provided, then the formatter chooses a reasonable default based on the media in use (for example, 8.5" × 11"). |
|
| Other attributes commonly applied to page masters include: |
|
• The margin-bottom, margin-left, margin-right, and margin-top attributes, or the shorthand margin attribute
• The writing-mode attribute that determines which direction text flows on the page, for example, left-to-right or right-to-left or top-to-bottom
• The reference-orientation attribute that specifies in 90-degree increments whether and how much the content is rotated |
|
| For example, here is a fo:layout-master-set containing one fo:simple-page-master named US-Letter. It specifies an 8.5 × 11-inch page with half-inch margins on each side. It contains a single region, the body, into which all content will be placed. |
|
<fo:layout-master-set>
<fo:simple-page-master master-name="US-Letter"
page-height="11in" page-width="8.5in"
margin-top="0.5in" margin-bottom="0.5in"
margin-left="0.5in" margin-right="0.5in">
<fo:region-body/>
</fo:simple-page-master>
</fo:layout-master-set>
|
|
| Regions |
|
| The designer sets the size of the body (center) region, header, footer, end region, and start region, as well as the distances between them, by adding region child elements to the fo:simple-page-master. These are: |
|
• fo:region-before
• fo:region-after
• fo:region-body • fo:region-start
• fo:region-end |
|
| The fo:region-before and fo:region-after elements each have an extent attribute that gives the height of these regions. Their width extends from the left side of the page to the right side. The fo:region-start and fo:region-end elements each have an extent attribute that specifies their widths. |
|
| Their height extends from the bottom of the start region to the top of the end region. (This assumes normal Western text. Details would be rotated in Chinese or Hebrew or some other non-right-to-left-top-to-bottom script.) |
|
| The fo:region-body does not have an extent attribute. Instead, the size of the body is everything inside the page margins. Thus, the region body overlaps the other four regions on the page. If you place text into the body and the other four regions, text will be drawn on top of other content. To avoid this, you must set the left margin of the body to be as large or larger than the extent of the start region, the top margin of the body to be as large or larger than the extent of the before region, and so on. |
|
| Each of the five regions of a simple page master may be filled with content from a fo:flow or fo:static-content element when the document is processed. However, these elements do not contain that content. Instead, they simply give the dimensions of the boxes the formatter will build to put content in. They are blueprints for the boxes, not the boxes themselves. |
|
| For example, this fo:simple-page-master creates pages with one-inch before and after regions. The region body will extend vertically from the bottom of the before region to the top of the after region. It will extend horizontally from the left side of the page to the right side of the page because there is no start or end region. |
|
<fo:simple-page-master master-name="table_page">
<fo:region-before extent="1.0in"/>
<fo:region-body margin-top="1.0in" margin-bottom="1.0in"/>
<fo:region-after extent="1.0in"/>
</fo:simple-page-master>
|
|
| For another example, here is a fo:layout-master-set that makes all outer regions one inch. Furthermore, the page itself has a half-inch margin on all sides. |
|
<fo:layout-master-set>
<fo:simple-page-master master-name="only"
page-width="8.5in" page-height="11in"
margin-top="0.5in" margin-bottom="0.5in"
margin-left="0.5in" margin-right="0.5in">
<fo:region-start extent="1.0in"/>
<fo:region-before extent="1.0in"/>
<fo:region-body margin="1.0in"/>
<fo:region-end extent="1.0in"/>
<fo:region-after extent="1.0in"/>
</fo:simple-page-master>
</fo:layout-master-set>
|
|
| The body regions from pages based on this page master will be 5.5 inches wide and 8 inches high. That's calculated by subtracting the sum of the body region's margins and the page margins from the size of the page. |
|
| Page sequences |
|
| In addition to a fo:layout-master-set, each formatting object document contains one or more fo:page-sequence elements. Each page in the sequence has an associated page master that defines how the page will look. Which page master this is, is determined by the master-reference attribute of the fo:page-sequence element. |
|
| This must match the name of a page master in the fo:layout-master-set. Listing 19-1 used a fo:simple-master-page named only to fill this role, but it is not uncommon to have more than one master page. In this case, the master pages might be grouped as part of a fo:page-sequence-master instead. |
|
| For instance, you could have one master page for the first page of each chapter, a different one for all the subsequent left-hand pages, and a third for all the subsequent right-hand pages. Or, there could be one simple page master for a table of contents, another for body text, and a third for the index. In this case, you use one page sequence each for the table of contents, the body text, and the index. |
|
| Each page sequence contains three child elements in this order: |
|
1. An optional fo:title element containing inline content that can be used as the title of the document. This would normally be placed in the title bar of the browser window like the TITLE element in HTML
2. Zero or more fo:static-content elements containing text to be placed on every page
3. One fo:flow element containing data to be placed on each page in turn |
|
| The main difference between a fo:flow and a fo:static-content is that text from the flow isn't placed on more than one page, whereas the static content is. For example, the words you're reading now are flow content that only appear on this page, whereas the part and chapter titles at the top of the page are static content that is repeated from page to page. |
|
| The fo:flow element contains, in order, the elements to be placed on the page. As each page fills with elements from the flow, a new page is created with the next master page in the page sequence master for the elements that remain in the flow. With a simple page master, the same page will be instantiated repeatedly, as many times as necessary to hold all the content. |
|
| The fo:static-content element contains information to be placed on each page. For instance, it may place the title of a book in the header of each page. Static content can be adjusted depending on the master page. For instance, the part title may be placed on left-hand pages, and the chapter title on right-hand pages. The fo:static-content element can also be used for items such as page numbers that have to be calculated from page to page. In other words, what's static is not the text, but the calculation that produces the text. |
|
|
|
|
| XSL FO(Formatting Objects) |
|
| Content |
|
| The content (as opposed to markup) of an XSL-FO document is mostly text. Non-XMLcontent such as GIF and JPEG images can be included in a fashion similar to the IMGelement of HTML. Other forms of XML content, such as MathML and SVG, can be embedded directly inside the XSL-FO document. This content is stored in several kinds of elements including: |
|
• Block-level formatting objects
• Inline formatting objects
• Table formatting objects
• Out-of-line formatting objects |
|
| All of these different kinds of elements are descendants of either a fo:flow or a fo:static-content element. They are never placed directly on page masters or page sequences. |
|
| Block-level formatting objects |
|
| A block-level formatting object is drawn as a rectangular area separated by a line break and possibly extra white space from any content that precedes or follows it. Blocks may contain other blocks, in which case the contained blocks are also separated from the containing block by a line break and perhaps extra white space. Block-level formatting objects include: |
|
• fo:block
• fo:block-container
• fo:table-and-caption
• fo:table
• fo:list-block |
|
| The fo:block element is the XSL-FO equivalent of display: block in CSS or DIV inHTML. Blocks may be contained in fo:flow elements, other fo:block elements, and fo:static-content elements. fo:block elements may contain other fo:block elements, other block-level elements such as fo:table and fo:list-block, and inline elements such as fo:inline and fo:page-number. Block-level elements may also contain raw text. |
|
| For example: |
|
|
| <fo:block>The Periodic Table, Page <fo:page-number/></fo:block> |
|
| The block-level elements generally have attributes for both area properties and text-formatting properties. The text-formatting properties are inherited by any child elements of the block unless overridden. |
|
| Inline formatting objects |
|
| An inline formatting object is also drawn as a rectangular area that may contain text or other inline areas. However, inline areas are most commonly arranged in lines running from left to right. When a line fills up, a new line is started below the previous one. |
|
| The exact order in which inline elements are placed depends on the writing mode. For example, when working in Hebrew or Arabic, inline elements are first placed on the right and then fill to the left. Inline formatting objects include: |
|
• fo:bidi-override
• fo:character
• fo:external-graphic
• fo:initial-property-set
• fo:instream-foreign-object
• fo:inline
• fo:inline-container
• fo:leader
• fo:page-number
• fo:page-number-citation |
|
| Caution |
|
| As of version 0.20.4, FOP does not support fo:bidi-override, fo:initial-property-set, or fo:inline-container. |
|
| Table formatting objects |
|
| The table formatting objects are the XSL-FO equivalents of CSS2 table properties. However, tables do work somewhat more naturally in XSL-FO than in CSS. For the most part, an individual table is a block-level object, while the parts of the table aren't really either inline or block level. However, an entire table can be turned into an inline object by wrapping it in a fo:inline-container. |
|
| There are nine XSL table formatting objects: |
|
• fo:table-and-caption
• fo:table
• fo:table-caption
• fo:table-column
• fo:table-header
• fo:table-footer
• fo:table-body
• fo:table-row
• fo:table-cell |
|
| The root of a table is either a fo:table or a fo:table-and-caption that contains a fo:table and a fo:caption. The fo:table contains a fo:table-header, fo:table-body, and fo:table-footer. The table body contains fo:table-row elements that are divided up into fo:table-cell elements. |
|
| Caution |
|
| FOP 0.20.4 has limited support for the table formatting objects, and none at all for fo:table-and-caption and fo:table-caption. |
|
| Out-of-line formatting objects |
|
| There are three "out-of-line" formatting objects: |
|
• fo:float
• fo:footnote
• fo:footnote-body |
|
| Out-of-line formatting objects "borrow" space from existing inline or block objects. On the page, they do not necessarily appear between the same elements that they appeared between in the input formatting object XML tree. |
|
|
|
|
| XSL FO(Formatting Objects) |
|
| Leaders and Rules |
|
| A rule is a block-level horizontal line inserted into text similar to the line below thechapter title on the first page of this chapter. The HR element in HTML produces a rule. A leader is a line that extends from the right side of left-aligned text in the middle of a line to the left side of some right-aligned text on the same line. |
|
| It's most commonly made up of dots, although other characters can be used. Leaders are commonly seen in menus and tables of contents. In fact, if you flip back to the table of contents at the beginning of this book, you'll see leaders between chapter and section titles and the page numbers. |
|
| In XSL-FO both leaders and rules are produced by the fo:leader element. This is an inline element that represents a leader, although it can easily serve as a rule by placing it inside a fo:block. |
|
| Six attributes describe the appearance of a leader: |
|
| • Leader-alignment: This can be set to reference-area or page to indicate that the start edge of the leader should be aligned with the start edge of the named item. It can also be set to none or inherit. |
|
| • Leader-length: The length of the leader, such as 12pc or 5in. |
|
| • leader-pattern: This can be set to space, rule, dots, use-content, or inherit. The use-content value means that the leader characters should be read from the content of the fo:leader element. |
|
| • leader-pattern-width: This property can be set to a specific length such as 2mm or to use-font-metrics, which indicates that the leader should simply be as big as it would naturally be. This is not the length of the entire leader (which is set by leader-length); it is the length of each repeating pattern in the leader. If necessary, white space will be added to stretch each pattern out to the requested length. |
|
| • rule-style: This property has the same values as the CSS border-style properties; that is, none, dotted, dashed, solid, double, groove, ridge, and inherit. |
|
| • rule-thickness: This property is the thickness (width) of the rule; 1pt by default. |
|
| In addition, a number of other common properties apply to leaders. For instance, you can use the font-family property to change the font in which a leader is drawn or the color property to change the color in which a leader is drawn. |
|
| For example, this is a green horizontal line that’s 7.5 inches long and 2 points thick: |
|
| <fo:block> <fo:leader leader-length="7.5in" leader-pattern="rule" rule-thickness="2pt" color="green"/> </fo:block> |
|
| Listing 19-6 uses fo:leader to place a rule at the top of each page footer. |
|
| Using fo:leader to separate the footer from the body with a horizontal line |
|
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:template match="/">
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:layout-master-set>
<fo:simple-page-master master-name="A4"
page-width="297mm" page-height="210mm"
margin-top="0.5in" margin-bottom="0.5in"
margin-left="0.5in" margin-right="0.5in">
<fo:region-before extent="1.0in"/>
<fo:region-body margin-top="1.0in"
margin-bottom="1.0in"/>
<fo:region-after extent="1.0in"/>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference`="A4"
initial-page-number="1" language="en" country="us">
<fo:static-content flow-name="xsl-region-before">
<fo:block>The Periodic Table</fo:block>
</fo:static-content>
<fo:static-content flow-name="xsl-region-after">
<fo:block><fo:leader leader-pattern="rule"
leader-length="18cm" />
</fo:block>
<fo:block>p. <fo:page-number/></fo:block>
</fo:static-content>
<fo:flow flow-name="xsl-region-body">
<xsl:apply-templates select="//ATOM"/>
</fo:flow>
</fo:page-sequence>
</fo:root>
</xsl:template>
<xsl:template match="ATOM">
<fo:block><xsl:value-of select="NAME"/></fo:block>
</xsl:template>
</xsl:stylesheet>
|
|
| Figure below shows the third page of the PDF file generated from Listing 19-6. The rule appears at the bottom of this and every other page in the document. |
|
 |
|
|
|
|
| XSL FO(Formatting Objects) |
|
| Graphics |
|
| XSL-FO provides two elements for embedding pictures in a rendered document. The fo:external-graphic element inserts a non-XML graphic, such as a JPEG image. The fo:instream-foreign-object element inserts an XML document that is not an XSL-FOdocument, such as an SVG picture or a MathML equation. |
|
| fo:external-graphic |
|
| The fo:external-graphic element provides the equivalent of an HTML IMG element. That is, it loads an image, probably in a non-XML format, from a URL. fo:external-graphic is always an empty element with no children. The src attribute contains a URI identifying the location of the image to be embedded. For example, consider this standard HTMLIMG element: |
|
| <IMG SRC="cup.gif"> |
|
| The fo:external-graphic equivalent looks like this: |
|
| <fo:external-graphic src="cup.gif"/> |
|
| Of course, you can use an absolute URL if you like: |
|
| <fo:external-graphic src="http://www.cafeconleche.org/cup.gif"/> |
|
| Just as with Web browsers and HTML, there's no guarantee that any particular formatting engine recognizes and supports any particular graphic format. Currently,FOP supports GIF, JPEG, and SVG images. PNG is supported if you have Sun's JIMIlibrary installed. More formats may be added in the future. |
|
| fo:external-graphic is an inline element. You can make it a block-level picture simply by wrapping it in a fo:block element like this: |
|
| <fo:block><fo:external-graphic src="cup.gif"/></fo:block> |
|
| An XSL style sheet that references an external graphic |
|
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:template match="/">
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:layout-master-set>
<fo:simple-page-master master-name="A4"
page-width="297mm" page-height="210mm"
margin-top="0.5in" margin-bottom="0.5in"
margin-left="0.5in" margin-right="0.5in">
<fo:region-before extent="1.0in"/>
<fo:region-body margin-top="1.0in"
margin-bottom="1.0in"/>
<fo:region-after extent="1.0in"/>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="A4"
initial-page-number="1" language="en" country="us">
<fo:static-content flow-name="xsl-region-before">
<fo:block>
<fo:external-graphic
src="/images/atom.jpg"
/>
The Periodic Table
</fo:block>
</fo:static-content>
<fo:static-content flow-name="xsl-region-after">
<fo:block>
<fo:leader leader-pattern="rule"
leader-length="18cm"/>
</fo:block>
<fo:block>p. <fo:page-number/></fo:block>
</fo:static-content>
<fo:flow flow-name="xsl-region-body">
<xsl:apply-templates select="//ATOM"/>
</fo:flow>
</fo:page-sequence>
</fo:root>
</xsl:template>
<xsl:template match="ATOM">
<fo:block><xsl:value-of select="NAME"/></fo:block>
</xsl:template>
</xsl:stylesheet>
|
|
|
| shows the first page of the PDF file . The picture appears at the top of this and every other page in the document. |
|
|
 |
|
| Inserting an external graphic in the header |
|
| fo:instream-foreign-object |
|
| The fo:instream-foreign-object inserts a graphic element that is described in XML and that is included directly in the XSL-FO document. For example, a fo:instream-foreign-object element might contain an SVG picture. |
|
| The formatter would render the picture in the finished document. Listing 19-8 is an XSL-FO document that places the pink triangle SVG example from Chapter 2 on the header of each page: |
|
| An XSL style sheet that contains an instream SVG picture |
|
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:template match="/">
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:layout-master-set>
<fo:simple-page-master master-name="A4"
page-width="297mm" page-height="210mm"
margin-top="0.5in" margin-bottom="0.5in"
margin-left="0.5in" margin-right="0.5in">
<fo:region-before extent="1.0in"/>
<fo:region-body margin-top="1.0in"/>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="A4"
initial-page-number="1" language="en" country="us">
<fo:static-content flow-name="xsl-region-before">
<fo:block> The Periodic Table
<fo:instream-foreign-object>
<svg xmlns="http://www.w3.org/2000/svg"
width="1.5cm" height="1cm">
<polygon style="fill:#FFCCCC" points="0,31 18,0 36,31"/>
</svg>
</fo:instream-foreign-object>
</fo:block>
</fo:static-content>
<fo:flow flow-name="xsl-region-body">
<xsl:apply-templates select="//ATOM"/>
</fo:flow>
</fo:page-sequence>
</fo:root>
</xsl:template>
<xsl:template match="ATOM">
<fo:block><xsl:value-of select="NAME"/></fo:block>
</xsl:template>
</xsl:stylesheet>
|
|
| Figure below shows the first page of the PDF file . The triangle appears at the top of this and every other page in the document. |
|
|
 |
|
| Embedding an instream graphic in the header |
|
| Not all formatters support all possible XML graphics formats. For instance, FOP does not support MathML at all, and only supports a subset of SVG. Still this is a useful technique, especially when you want XSLT to generate pictures at runtime. |
|
| For instance, you could write an XSLT style sheet that produced nicely formatted annual reports, including all the charts and graphics, simply by transforming some of the input document into XSL-FO and other parts of the input document into SVG. |
|
| Graphic properties |
|
| fo:external-graphic and fo:instream-foreign-object share a number of properties designed to scale, position, crop, align, and otherwise adjust the appearance of the image on the page. |
|
| Content type |
|
| The content-type attribute specifies the type of the graphic. You can give this as a MIME media type, such as image/jpg or image/svg+xml, by prefixing the actual type with content-type:. For example, to specify that the fo:external-graphic element refers to a GIF image you would write it as |
|
| <fo:external-graphic content-type="content-type:image/gif" src="cup.gif" /> |
|
| This can also be given in terms of a namespace prefix by using a value in the form namespace-prefix:prefix. For example, to specify that the fo:instream-foreign-object includes an SVG picture you write it as |
|
| <fo:instream-foreign-object xmlns:svg="http://www.w3.org/2000/svg" content-type="namespace-prefix:svg"> |
|
| The namespace prefix does not have to be declared on the fo:instream-foreign-object element. It simply needs to be declared somewhere in the ancestors of the element. |
|
| Size |
|
| The height and width attributes specify the vertical and horizontal size of the rectangle set aside on the page for the image. Either or both of these can be set to the keyword auto, rather than to an absolute length, to indicate that the size of the image itself should be used. |
|
| The content-height and content-width attributes specify the vertical and horizontal size of the image itself. If either or both of these is not the same as height and width, respectively, then the image has to be scaled. |
|
| Scaling |
|
| The scaling attribute can be set to either uniform or non-uniform. Uniform scaling maintains the height-to-width ratio of the image as it's scaled. This is the default. Non-uniform scaling may scale the height and width differently, so that the image is distorted. |
|
| You can also choose the algorithm by which scaling occurs by using the scaling-method attribute. This can be set to auto, integer-pixels, or resample-any-method. Integer scaling maintains an integral ratio between original and scaled images such as 2:1 or 3:1, but not 1.5:1. In most cases, integer-scaled images are smaller than images scaled by resample-any-method, but won’t require dithering. The value auto lets the formatter decide what to do. |
|
| In addition, you can set a variety of common properties for inline elements. These include the common accessibility, aural, background, border, padding, and margin properties. Because graphics shouldn't be split across multiple pages, they don’t support the usual break properties, but they do support keep-with-next and keep-with-previous. |
|
|
|
|
| XSL FO(Formatting Objects) |
|
| Links |
|
| The fo:basic-link element encodes HTML-style hyperlinks in XSL-FO documents. This is an inline formatting object that the user can click on to move to a different document, or to a different place in the same document. This doesn’t offer much for print, but it might be useful when and if Web browsers support XSL-FO directly. The link behavior is controlled by these eight attributes: |
|
• external-destination
• internal-destination
• indicate-destination
• show-destination
• destination-placement-offset
• target-presentation-context
• target-processing-context
• target-stylesheet |
|
| A link to a remote document target specifies the URI through the value of the external-destination attribute. The browser should replace the current document with the document at this URI when the reader activates the link. In most GUI environments, the user activates the link by clicking on its contents. For example: |
|
| <fo:block> Be sure to visit the <fo:basic-link external-destination="http://www.ebizel.com/"> Cafe con Leche Web site! </fo:basic-link> </fo:block> |
|
| You can also link to another node in the same document by using the internal-destination attribute. The value of this attribute is not a URI, but rather the ID of the element you're linking to. |
|
| You can often use the generate-id() function of XSLT to produce both the IDs on the output elements and the links to those elements inside the XSL-FO output. You should not specify both the internal and external destination for one link. |
|
| The three other destination attributes affect the appearance and behavior of the link. The indicate-destination attribute has a boolean value (true or false; false by default) that specifies whether, when the linked item is loaded, it should somehow be distinguished from non-linked parts of the same document. |
|
| For example, if you follow a link to one ATOM element in a table of 100 atoms, the specific atom you were connecting to might be in boldface while the other atoms are in normal type. The exact details are system dependent. |
|
| The show-destination attribute has two possible values: replace (the default) and new. With a value of replace, when a link is followed, the target document replaces the existing document in the same window. With a value of new, when the user activates a link, the browser opens a new window in which to display the target document. |
|
| When a browser follows an HTML link into the middle of a document, generally the specific linked element is positioned at the tip-top of the window. The destination-placement-offset attribute specifies how far down the browser should scroll the linked element in the window. It's given as a length such as 3in or 156px. |
|
| The three target properties describe how the document at the other end of the link will be displayed. The target-presentation-context attribute contains a URI that generally indicates some subset of the external destination that should actually be presented to the user. For instance, an XPointer could be used here to say that although an entire book is loaded only the seventh chapter will be shown. |
|
| The target-processing-context attribute contains a URI that serves as a base URI in the event that the external destination contains a relative URI. Otherwise, that would be considered relative to the current document. |
|
| Finally, the target-stylesheet attribute contains a URI that points to a style sheet that should be used when the targeted document is rendered. This overrides any style sheet that the targeted document itself specifies, whether through an xml-stylesheet processing instruction, a LINK element in HTML, or an HTTP header. |
|
| In addition, the link may have the usual accessibility, margin, background, border, padding, and aural properties. |
|
|
|
|
| XSL FO(Formatting Objects) |
|
| Lists |
|
| The fo:list-block formatting object element describes a block-level list element. (There are no inline lists.) A list may or may not be bulleted, numbered, indented, or otherwise formatted. Each fo:list-block element contains either a series of fo:list-item elements or fo:list-item-label fo:list-item-body pairs. |
|
| (It cannot contain both.) A fo:list-item must contain a fo:list-item-label and a fo:list-item-body. The fo:list-item-label contains the bullet, number, or other label for the list item as a block level element. |
|
| The fo:list-item-body contains block-level elements holding the actual content of the list item. To summarize, a fo:list-block contains fo:list-item elements. Each fo:list-item contains a fo:list-item-label and fo:list-item-body. However, the fo:list-item elements can be omitted. For example: |
|
<fo:list-block>
<fo:list-item>
<fo:list-item-label><fo:block>*</fo:block>
</fo:list-item-label>
<fo:list-item-body> |
|
<fo:block>Actinium</fo:block>
</fo:list-item-body>
</fo:list-item>
<fo:list-item>
<fo:list-item-label><fo:block>*</fo:block> </fo:list-item-label>
<fo:list-item-body>
|
|
<fo:block>Aluminum</fo:block>
</fo:list-item-body>
</fo:list-item> </fo:list-block> |
|
| Or, with the fo:list-item tags removed: |
|
<fo:list-block>
<fo:list-item-label>
<fo:block>*</fo:block>
</fo:list-item-label>
<fo:list-item-body> |
|
<fo:block>Actinium</fo:block>
</fo:list-item-body>
<fo:list-item-label>
<fo:block>*</fo:block>
</fo:list-item-label>
<fo:list-item-body> |
|
<fo:block>Aluminum</fo:block>
</fo:list-item-body>
</fo:list-block> |
|
| The fo:list-block element has two special attributes that control list formatting: |
|
| • provisional-label-separation: The distance between the list item label and the list item body, given as a triplet of maximum;minimum;optimum, such as 2mm;0.5mm;1mm. |
|
| • provisional-distance-between-starts: The distance between the start edge of the list item label and the start edge of the list item body. |
|
| fo:list-block also has the usual accessibility, aural, border, padding, background, margin, and keeps and breaks properties. The fo:list-item element has the standard block-level properties for backgrounds, position, aural rendering, borders, padding, margins, line and page breaking. |
|
| The fo:list-item-label and fo:list-item-body elements only have the accessibility properties: id and keep-together. The rest of their formatting is controlled either by the parent elements (fo:list-item and fo:list-item-block) or the child elements they contain. |
|
| formats the periodic table as a list in which the atomic numbers are the list labels and the names of the elements are the list bodies. Figure shows the second page of output produced by this style sheet. |
|
| An XSL style sheet that formats the periodic table as a list |
|
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format"> <xsl:template match="/">
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:layout-master-set> |
|
<fo:simple-page-master master-name="A4"
page-width="297mm" page-height="210mm"
margin-top="0.5in" margin-bottom="0.5in"
margin-left="0.5in" margin-right="0.5in">
<fo:region-body/>
</fo:simple-page-master> |
|
</fo:layout-master-set>
<fo:page-sequence master-reference="A4">
<fo:flow flow-name="xsl-region-body">
<fo:list-block>
<xsl:apply-templates select="//ATOM">
<xsl:sort data-type="number" |
|
select="ATOMIC_NUMBER"/>
</xsl:apply-templates>
</fo:list-block>
</fo:flow>
</fo:page-sequence>
|
|
</fo:root>
</xsl:template>
<xsl:template match="ATOM">
<fo:list-item> |
|
<fo:list-item-label><fo:block>
<xsl:value-of select="ATOMIC_NUMBER"/>
</fo:block></fo:list-item-label>
<fo:list-item-body><fo:block>
<xsl:value-of select="NAME"/> |
|
</fo:block></fo:list-item-body>
</fo:list-item>
</xsl:template>
</xsl:stylesheet> |
|
 |
|
| The periodic table formatted as a list |
|
| In HTML a list item implies a certain level of indenting. However, as you can see in Figure , no such indenting is implied by any of the XSL-FO list elements. If you want list items to be indented, you can use the start-indent and end-indent attributes on thefo:list-item-label and fo:list-item-body elements. |
|
| Each of these is set to a length. However, because the list item body normally starts on the same line as the list item label, its start indent is often given by the special XSL-FObody-start() function. This returns the combined length of the start-indent and the provisional-distance-between-starts. For example, |
|
<xsl:template match="ATOM">
<fo:list-item>
<fo:list-item-label start-indent="1.0cm" end-indent="1.0cm">
<fo:block>
<xsl:value-of select="ATOMIC_NUMBER"/> |
|
</fo:block>
</fo:list-item-label>
<fo:list-item-body start-indent="body-start()">
<fo:block>
<xsl:value-of select="NAME"/> |
|
</fo:block>
</fo:list-item-body>
</fo:list-item>
</xsl:template> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
0 comments: