Chapter 14. XSL Formatting Objects

CONTENTS
  •  Formatting an XML Document
  •  Creating the XSLT Style Sheet
  •  Transforming a Document into a Formatting Object Form
  •  Creating a Formatted Document
  •  XSL Formatting Objects

In the previous chapter, we took a look at the XSL transformation language. In this chapter, we'll take a look at the second half of XSL: formatting objects.

The W3C has defined such formatting objects as root, block, and character that support different properties such as font-weight, line-height, and border. Using these predefined objects, you can specify the exact formatting for a document. At this writing, there are 56 formatting objects and 177 properties that apply to these objects. Each of these objects has its own XML tag, and the properties that it supports are attributes of that tag. (Many of these properties come from CSS2, which you can read more about in Chapter 9, "Cascading Style Sheets.")

Like other XML applications, XSL formatting objects have their own namespace, "http://www.w3.org/1999/XSL/Format", and the namespace prefix that people use for that namespace is almost invariably fo, for "formatting objects." For example, here's how I can create a block (recall from CSS that blocks are rectangular areas in the output document) that displays the text Welcome to XSL formatting. in 36 point sans-serif font using the <fo:block> formatting object:

<fo:block font-family="sans-serif" line-height="48pt" font-size="36pt">     Welcome to XSL formatting. </fo:block>

The formatting object that I'm using here is fo:block, and the properties that I'm assigning values to are font-family, line-height, and font-size. After you've created a document using the XSL formatting objects, you can let an XSL processor format that document. We'll see one such program in this chapter that creates files in PDF format (portable document format, the common format that you see on the Web for document exchange) from documents written with the XSL formatting objects.

That's the idea if you write your documents using the formatting objects, you can actually specify how that document will be displayed, down to the last comma and figure. Unfortunately, very little software actually interprets and uses the XSL formatting objects yet. In this chapter, we'll use the only such package that I know of: the Apache XML Project's FOP processor.

The <fo:block> and all the other formatting objects are defined by the W3C, and you can find the W3C recommendation for the XSL formatting objects at http://www.w3.org/TR/xsl. The specification for all the formatting objects is at http://www.w3.org/TR/xsl/slice6.html, and the specification of the properties that you can use with these objects is at http://www.w3.org/TR/xsl/slice7.html.

We can't cover the entire field of formatting objects here because that would take a book by itself. For all the details, refer to http://www.w3.org/TR/xsl.

Formatting an XML Document

Writing an entire document using the XSL formatting objects is not an easy task except for short documents. I have a hard time imagining anyone using the formatting objects to write a book, for example. W3C foresaw that difficulty, and that's one of the main reasons that it also introduced the transformation language we took a look at in the previous chapter. You can write a document using your own tags, and you can use XSLT to transform the document so that it uses the XSL formatting objects. In practice, that's almost invariably the way it's done, which means that all you have to supply is an XSLT style sheet that can be used to convert your document to use formatting objects. In this way, an XSLT processor can do all the work for you, transforming a document from a form you're comfortable working with to formatting an object form, which you can then feed to a program that can handle formatting objects and display the formatted result.

To make all this self-evident, I'll write an example here using the planets.xml document we saw in the previous chapter:

<?xml version="1.0"?> <?xml-stylesheet type="text/xml" href="planets.xsl"?> <PLANETS>   <PLANET COLOR="RED">     <NAME>Mercury</NAME>     <MASS UNITS="(Earth = 1)">.0553</MASS>     <DAY UNITS="days">58.65</DAY>     <RADIUS UNITS="miles">1516</RADIUS>     <DENSITY UNITS="(Earth = 1)">.983</DENSITY>     <DISTANCE UNITS="million miles">43.4</DISTANCE><!--At perihelion-->   </PLANET>   <PLANET COLOR="WHITE">     <NAME>Venus</NAME>     <MASS UNITS="(Earth = 1)">.815</MASS>     <DAY UNITS="days">116.75</DAY>     <RADIUS UNITS="miles">3716</RADIUS>     <DENSITY UNITS="(Earth = 1)">.943</DENSITY>     <DISTANCE UNITS="million miles">66.8</DISTANCE><!--At perihelion-->   </PLANET>   <PLANET COLOR="BLUE">     <NAME>Earth</NAME>     <MASS UNITS="(Earth = 1)">1</MASS>     <DAY UNITS="days">1</DAY>     <RADIUS UNITS="miles">2107</RADIUS>     <DENSITY UNITS="(Earth = 1)">1</DENSITY>     <DISTANCE UNITS="million miles">128.4</DISTANCE><!--At perihelion-->   </PLANET> </PLANETS>

In this chapter, I'll write an XSLT style sheet for this document, transforming it so that it uses formatting objects. Then I'll use the FOP processor to turn the new document into a PDF file. I'll also take a look at the formatted document with Adobe Acrobat.

Creating the XSLT Style Sheet

I could translate planets.xsl into a document using the formatting objects by hand. As mentioned, however, that doesn't really work for anything but short documents in general. The usual technique is to create an XSLT style sheet that you can use to transform a document so that it uses the XSL formatting objects, and I'll do that in this chapter. Here's what that style sheet, planets.xsl, will look like; in this case, I'm using a large font for 36-point text:

<?xml version='1.0'?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"     xmlns:fo="http://www.w3.org/1999/XSL/Format"     version='1.0'>     <xsl:template match="PLANETS">         <fo:root>             <fo:layout-master-set>                  <fo:simple-page-master master-name="page"                      page-height="400mm" page-width="300mm"                      margin-top="10mm" margin-bottom="10mm"                      margin-left="20mm" margin-right="20mm">                      <fo:region-body                        margin-top="0mm" margin-bottom="10mm"                        margin-left="0mm" margin-right="0mm"/>                      <fo:region-after extent="10mm"/>                  </fo:simple-page-master>              </fo:layout-master-set>              <fo:page-sequence master-name="page">                  <!-- Added for fop -->                  <fo:sequence-specification>                      <fo:sequence-specifier-single master-name="page"/>                  </fo:sequence-specification>                  <!-- Added for fop -->                  <fo:flow>                      <xsl:apply-templates/>                  </fo:flow>              </fo:page-sequence>         </fo:root>     </xsl:template>     <xsl:template match="PLANET/NAME">         <fo:block font-weight="bold" font-size="36pt"             line-height="48pt" font-family="sans-serif">             Name:             <xsl:apply-templates/>         </fo:block>     </xsl:template>     <xsl:template match="PLANET/MASS">         <fo:block font-size="36pt" line-height="48pt"             font-family="sans-serif">             Mass (Earth = 1):             <xsl:apply-templates/>         </fo:block>     </xsl:template>     <xsl:template match="PLANET/DAY">         <fo:block font-size="36pt" line-height="48pt" font-family="sans-serif">             Day (Earth = 1):             <xsl:apply-templates/>         </fo:block>     </xsl:template>     <xsl:template match="PLANET/RADIUS">         <fo:block font-size="36pt" line-height="48pt" font-family="sans-serif">             Radius (in miles):             <xsl:apply-templates/>         </fo:block>     </xsl:template>     <xsl:template match="PLANET/DENSITY">         <fo:block font-size="36pt" line-height="48pt" font-family="sans-serif">             Density (Earth = 1):             <xsl:apply-templates/>         </fo:block>     </xsl:template>     <xsl:template match="PLANET/DISTANCE">         <fo:block font-size="36pt" line-height="48pt" font-family="sans-serif">             Distance (million miles):             <xsl:apply-templates/>         </fo:block>     </xsl:template> </xsl:stylesheet>

Transforming a Document into a Formatting Object Form

To transform planets.xml into a document that uses formatting objects, which I'll call planets.fo, all I have to do is to apply the style sheet planets.xsl. You can do that using the XSLT techniques we saw in the previous chapter. For example, to use the xslt Java class I created in that chapter, you first set the class path to include the alphaWorks' xalan.jar and xerces.jar files, something like this:

%set classpath=%classpath%;C:\lotusxsl_1_0_1\xalan.jar;C:\xsl\lotusxsl_1_0_1\xerces.jar;

Then you apply planets.xsl to planets.xml to produce planets.fo:

%java xslt planets.xml planets.xsl planets.fo

The document planets.fo uses the XSL formatting objects to specify how the document should be formatted. Here's what planets.fo looks like:

<?xml version="1.0" encoding="UTF-8"?> <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">     <fo:layout-master-set>         <fo:simple-page-master margin-right="20mm"             margin-left="20mm" margin-bottom="10mm"             margin-top="10mm" page-width="300mm"             page-height="400mm" master-name="page">             <fo:region-body margin-right="0mm"                 margin-left="0mm" margin-bottom="10mm"                 margin-top="0mm"/>          <fo:region-after extent="10mm"/>         </fo:simple-page-master>     </fo:layout-master-set>     <fo:page-sequence master-name="page">         <!-- Added for fop -->         <fo:sequence-specification>             <fo:sequence-specifier-single master-name="page"/>         </fo:sequence-specification>         <!-- Added for fop -->         <fo:flow>             <fo:block font-family="sans-serif" line-height="48pt"                 font-size="36pt" font-weight="bold">                 Name:                 Mercury             </fo:block>             <fo:block font-family="sans-serif" line-height="48pt"                 font-size="36pt">                 Mass (Earth = 1):                 .0553</fo:block>             <fo:block font-family="sans-serif" line-height="48pt"                 font-size="36pt">                 Day (Earth = 1):                 58.65</fo:block>             <fo:block font-family="sans-serif" line-height="48pt"                 font-size="36pt">                 Radius (in miles):                 1516</fo:block>             <fo:block font-family="sans-serif" line-height="48pt"                 font-size="36pt">                 Density (Earth = 1):                 .983</fo:block>             <fo:block font-family="sans-serif" line-height="48pt"                 font-size="36pt">                 Distance (million miles):                 43.4</fo:block>             <fo:block font-family="sans-serif" line-height="48pt"                 font-size="36pt" font-weight="bold">                 Name:                 Venus             </fo:block>             <fo:block font-family="sans-serif" line-height="48pt"                 font-size="36pt">                 Mass (Earth = 1):                 .815             </fo:block>             <fo:block font-family="sans-serif" line-height="48pt"                 font-size="36pt">                 Day (Earth = 1):                 116.75             </fo:block>             <fo:block font-family="sans-serif" line-height="48pt"                 font-size="36pt">                 Radius (in miles):                 3716             </fo:block>             <fo:block font-family="sans-serif" line-height="48pt"                 font-size="36pt">                 Density (Earth = 1):                 .943             </fo:block>             <fo:block font-family="sans-serif" line-height="48pt"                 font-size="36pt">                  Distance (million miles):                  66.8             </fo:block>             <fo:block font-family="sans-serif" line-height="48pt"                 font-size="36pt" font-weight="bold">                 Name:                 Earth             </fo:block>             <fo:block font-family="sans-serif" line-height="48pt"                 font-size="36pt">                 Mass (Earth = 1):                 1             </fo:block>             <fo:block font-family="sans-serif" line-height="48pt"                 font-size="36pt">                 Day (Earth = 1):                 1             </fo:block>             <fo:block font-family="sans-serif" line-height="48pt"                 font-size="36pt">                 Radius (in miles):                 2107             </fo:block>             <fo:block font-family="sans-serif" line-height="48pt"                 font-size="36pt">                 Density (Earth = 1):                 1             </fo:block>             <fo:block font-family="sans-serif" line-height="48pt"                 font-size="36pt">                 Distance (million miles):                 128.4             </fo:block>         </fo:flow>     </fo:page-sequence> </fo:root>

Okay, now we have planets.fo. How can we use it to create a formatted PDF file?

Creating a Formatted Document

To process planets.fo and create a formatted document, I'll use the only XSL formatting object processor currently available as far as I know: James Tauber's FOP (formatting objects processor), which has now been donated to the Apache XML Project. (The alphaWorks XML for Java parsers I've been using for several chapters is based on the Apache XML Project's Xerces XML parser.)

Here's how the Apache XML Project describes FOP:

FOP is the world's first print formatter driven by XSL formatting objects. It is a Java application that reads a formatting object tree and then turns it into a PDF document. The formatting object tree can be in the form of an XML document (output by an XSLT engine like XT or Xalan) or can be passed in memory as a DOM document or (in the case of XT) SAX events.

Here's how the Apache XML Project describes the objectives of FOP:

The goals of the Apache XML FOP Project are to deliver an XSL FO->PDF formatter that is compliant to at least the Basic conformance level described in the 27 March 2000 XSL WD [W3C Working Draft], and that complies with the 11 March 1999 Portable Document Format Specification (Version 1.3) from Adobe Systems.

You can get FOP at http://xml.apache.org/fop; just click the Download button to download it. The FOP package, including documentation, comes zipped, and you must unzip it. It's implemented as a Java JAR file, fop_bin_0_12_1.jar (this jar file is updated frequently; during tech review of this book, a new version, fop_bin_0_13_0.jar, appeared). You can use FOP from the command line with a class that at this writing is org.apache.fop.apps.CommandLine. You must provide the parser you want to use; I'll use the XML for Java parsers in xerces.jar.

Here's how I use FOP to convert planets.fo to planets.pdf with the java tool; note that I'm specifying the class path with the -cp switch to include fop_bin_0_12_1.jar and xerces.jar:

%java -cp fop_bin_0_12_1.jar;xerces.jar org.apache.fop.apps.CommandLine planets.fo planets.pdf

And that's it; you can see the final results, planets.pdf, in the Adobe Acrobat PDF reader (which you can get for free at http://www.adobe.com/products/acrobat/readermain.html) in Figure 14.1. The planets.xml document appears in that figure formatted exactly as it should be.

The PDF format is a good one for formatting object output, although it has some limitations for example, it can't handle dynamic tables that can expand or collapse at the click of a mouse, or interactive multiple-target links, both of which are part of the formatting objects specification. Although FOP is, as far as I know, the only software package that handles formatting objects (even partially), formatting objects most likely will be supported in the major browsers one day.

Figure 14.1. A PDF document created with formatting objects.

graphics/14fig01.gif

Now you've seen how the process works; it's time to get to the details, starting with an overview of the available formatting objects.

XSL Formatting Objects

Here's an overview of the 56 formatting objects that exist as of this writing we'll see a good number of them in action in this chapter.

Object Description
bidi-override Overrides the default Unicode-bidirectionality algorithm direction in mixed-language documents.
block Creates a display block, often used for formatting paragraphs, titles, headlines, figure and table captions, and so on.
block-container Generates a block-level reference area.
character Represents a character that is associated with a glyph for display.
color-profile Declares a color profile for a style sheet.
conditional-page-master-reference Specifies a page master to be used when the given conditions are met.
declarations Groups global declarations for a style sheet.
external-graphic Adds an inline graphic to the document, where the graphics data is outside the XML result document.
float Can specify that some content is formatted in a separate area at the beginning of the page or placed to one side.
flow Supports the flowing text content that is displayed in pages.
footnote Creates a footnote citation and the associated footnote.
footnote-body Creates the content of the footnote.
initial-property-set Sets the formatting properties for the first line of a block.
inline Usually is used to format part of the text with a background or to give it a border.
inline-container Creates an inline reference area.
instream-foreign-object Is used to insert an inline graphic or other object where the object data is a descendant of the fo:instream-foreign-object.
layout-master-set Is a wrapper for all the masters used in the document.
leader Creates a rule or row of repeating characters or a repeating pattern of characters that is used between two text-formatting objects.
list-block Is used to format a list.
list-item Holds the label and the body of an item in a list.
list-item-body Holds the content of the body of a list item.
list-item-label Holds the content of the label of a list item.
marker Is used with fo:retrieve-marker to create on-the-fly headers or footers.
multi-case Adds flow objects that the parent object, fo:multi-switch, can be used to show or hide.
multi-properties Switches between two or more property sets that are connected to a given part of the content.
multi-property-set Indicates an alternative set of formatting properties that can be applied to the content.
multi-switch Switches between two or more subtrees of formatting objects.
multi-toggle Is used inside an fo:multi-case object to switch to another fo:multi-case.
page-number Holds the current page number.
page-number-citation References the page number for the page containing the cited formatting object.
page-sequence Specifies how to create a sequence of pages within a document.
page-sequence-master Contains sequences of page masters that are used to generate sequences of pages.
region-after Refers to the region located after a fo:region-body region.
region-before Refers to the region before a fo:region-body region.
region-body Refers to the region in the center of the fo:simple-page-master.
region-end Refers to the region at the end of a fo:region-body region.
region-start Refers to the region starting a fo:region-body region.
repeatable-page-master-alternatives Indicates a subsequence made up of repeated instances of a set of alternative page masters.
repeatable-page-master-reference Indicates a subsequence of repeated instances of a single page master.
retrieve-marker Is used with fo:marker to create on-the-fly headers or footers.
root Is the top node of an XSL formatted document.
simple-link Represents the start location in a simple link.
simple-page-master Gives the geometry of a page, which may be divided into up to five regions.
single-page-master-reference Indicates a subsequence made up of a single instance of a single page master.
static-content Contains a sequence of formatting objects that should be presented in a single region or repeated in like-named regions on one or more pages in the page-sequence. This most often is used for repeating headers and footers.
table Formats the data in a table.
table-and-caption Formats the data and caption of a table.
table-body Holds the content of the table body.
table-caption Holds block-level formatting objects that, in turn, hold the caption for a table.
table-cell Groups content to be placed in a table cell.
table-column Sets characteristics for table cells that have the same column.
table-footer Holds the content of the table footer.
table-header Holds the content of the table header.
table-row Groups table cells into rows.
title Gives a document a title. The content of the fo:title object can be formatted and displayed in the document.
wrapper Indicates inherited properties for a group of formatting objects.

XSL Formatting Properties

The formatting objects in the previous section have properties that you can use to customize what they do. As we'll see in this chapter, a typical formatting object can support quite a few properties. Here are the current formatting properties that the W3C formatting objects specification supports many of these properties are taken from and behave the same as in CSS, and you set lengths and other units exactly as you do in CSS (using units such as px for pixels, pt for points, mm for millimeters, % for percentages, and so on) you can find more details at http://www.w3.org/TR/xsl/sliceC.html#prtab1 and http://www.w3.org/TR/xsl/sliceC.html#prtab2:

  • absolute-position

  • active-state

  • alignment-adjust

  • auto-restore

  • azimuth

  • background

  • background-attachment

  • background-color

  • background-image

  • background-position

  • background-position-horizontal

  • background-position-vertical

  • background-repeat

  • baseline-identifier

  • baseline-shift

  • blank-or-not-blank

  • block-progression-dimension

  • border

  • border-after-color

  • border-after-style

  • border-after-width

  • border-before-color

  • 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-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-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-height-override-after

  • font-height-override-before

  • 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

  • max-height

  • maximum-repeats

  • max-width

  • 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-numeral

  • 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

  • text-align

  • text-align-last

  • text-decoration

  • 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

Working with Formatting Objects

This chapter is all about working with the XSL formatting objects, and I'll cover those objects in depth. Knowing how to use these objects is crucial to the whole formatting process because, even if you use a transformation style sheet to transform XML documents to formatting-object form, you still have to know how to create the style sheet to do so. By the end of this chapter, you'll have a solid idea of exactly how that works.

The first formatting object I'll cover is fo:root, the root object of any formatting object document.

The Document Root: fo:root

The fo:root object is the top node of the formatting object tree that makes up a formatting object document that is, the document node of the formatting object document must be fo:root.

The children of the fo:root formatting object are a single fo:layout-master-set and a sequence of one or more fo:page-sequences. The fo:layout-master-set formatting object holds all "masters" used in the document, which you use to specify how each page will actually be built. Each fo:page-sequence represents a sequence of pages formatted the way you want them. For example, each chapter of a book could be made up of its own page sequence, and you can give each sequence the same header and footer, such as Chapter 2: The Plot Thickens.

In planets.xml, the document node is <PLANETS>; however, the document node of a formatting object document is <fo:root>, which means that we must replace <PLANETS> with <fo:root>. That looks like this in planets.xsl, the transformation style sheet:

<?xml version='1.0'?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"     xmlns:fo="http://www.w3.org/1999/XSL/Format"     version='1.0'>     <xsl:template match="PLANETS">         <fo:root>         .         .         .

The fo:root object can contain both master set layouts and page sequences. I'll take a look at the fo:layout-master-set object first.

The Master Set Layout: fo:layout-master-set

You use masters to create templates for pages, page sequences, and regions. The fo:layout-master-set object contain all the masters used in the document, including page sequence master objects, page master objects, and region master objects, which you apply to create page sequences, pages, and regions.

The name of each master ends in -master in XSL. For example, the page master that we'll use is the simple-page-master object. Page masters specify the subdivisions of a page and the geometry of these subdivisions. Page sequence masters specify the sequence of page masters that will be used to generate pages during the formatting.

You list the masters you want to use in the document in the <fo:layout-master-set> element, so I'll add that element to planets.xsl now:

<?xml version='1.0'?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"     xmlns:fo="http://www.w3.org/1999/XSL/Format"     version='1.0'>     <xsl:template match="PLANETS">         <fo:root>             <fo:layout-master-set>     .     .     .

To configure each page, you use a page master; the one I'll use here is the fo:simple-page-master object.

Using a Page Master: fo:simple-page-master

A page master is a master template that is used to generate a page, and it specifies the actual layout of the page. You can use a page master whenever you want to in a document, and each page master has a unique name.

In the current XSL specification, there is only one kind of page-master, the fo:simple-page-master object (in the future, the XSL specification may support additional page masters). You use the fo:simple-page-master object to generate pages and define the geometry of the page.

To set the overall geometry of the page, you can use these properties of the fo:simple-page-master object:

  • Common margin properties for blocks: margin-top, margin-bottom, margin-left, margin-right, space-before, space-after, start-indent, end-indent

  • master-name

  • page-height

  • page-width

  • reference-orientation

  • writing-mode

In planets.xsl, I'll name the simple page master "page" using the master-name property; when I want to create pages using this master, I'll be able to refer to it by name. I'll also specify the page dimensions and margins like this:

<?xml version='1.0'?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"     xmlns:fo="http://www.w3.org/1999/XSL/Format"     version='1.0'>     <xsl:template match="PLANETS">         <fo:root>             <fo:layout-master-set>                  <fo:simple-page-master master-name="page"                      page-height="400mm" page-width="300mm"                      margin-top="10mm" margin-bottom="10mm"                      margin-left="20mm" margin-right="20mm">     .     .     .

Besides laying out the margins of a page, an fo:simple-page-master has children that specify one or more regions in the page, enabling you to customize the layout in detail.

Creating Regions

In version 1.0 of the XSL recommendation, page masters have up to five regions. The central region, which corresponds to the body of the page, is called the body region. The top part of the page, the header, is called the before region, the bottom part of the page, the footer, is called the after region. In languages that read left to right, such as English, the left side of the page is called the start region, and the right side is called the end region. In languages that read right to left, the start and end regions are reversed. You can think of start and end regions as sidebars that flank the body region.

Five XSL formatting objects correspond to these regions:

  • fo:region-before

  • fo:region-after

  • fo:region-body

  • fo:region-start

  • fo:region-end

You can use these properties with these formatting objects:

  • Common border, padding, and background properties: background-attachment, background-color, background-image, background-repeat, background-position-horizontal, background-position-vertical, border-before-color, border-before-style, border-before-width, border-after-color, border-after-style, border-after-width, border-start-color, border-start-style, border-start-width, border-end-color, border-end-style, border-end-width, border-top-color, border-top-style, border-top-width, border- bottom-color, border-bottom-style, border-bottom-width, border-left-color, border-left-style, border-left-width, border-right-color, border-right-style, border-right-width, padding-before, padding-after, padding-start, padding-end, padding-top, padding-bottom, padding-left, padding-right

  • Common margin properties for blocks: margin-top, margin-bottom, margin-left, margin-right, space-before, space-after, start-indent, end-indent

  • clip

  • column-count

  • column-gap

  • display-align

  • extent

  • overflow

  • region-name

  • reference-orientation

  • writing-mode

You can customize the regions of a page as you like, as in planets.xsl, where I'm setting margins for the body region. The four outer regions (but not the body region) have an extent property that sets the size of those regions, and I'll use that here:

<?xml version='1.0'?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"     xmlns:fo="http://www.w3.org/1999/XSL/Format"     version='1.0'>     <xsl:template match="PLANETS">         <fo:root>             <fo:layout-master-set>                  <fo:simple-page-master master-name="page"                      page-height="400mm" page-width="300mm"                      margin-top="10mm" margin-bottom="10mm"                      margin-left="20mm" margin-right="20mm">                      <fo:region-body                        margin-top="0mm" margin-bottom="10mm"                        margin-left="0mm" margin-right="0mm"/>                      <fo:region-after extent="10mm"/>                  </fo:simple-page-master>              </fo:layout-master-set>     .     .     .

That ends the only master I'll have in this document, the simple page master named "page", so that completes the fo:layout-master-set object.

As mentioned, besides the fo:layout-master-set, a formatting object document usually also contains one or more fo:page-sequence objects that define page sequences using the masters you define in the fo:layout-master-set.

Creating Page Sequences: fo:page-sequence

The pages in the output document are actually created when the XSL processor processes fo:page-sequence objects. A page sequence consists of a run of pages that share the same characteristics, such as a chapter in a book.

Each fo:page-sequence object references either an fo:page-sequence-master or a page master, and the actual layout of the pages is specified by those masters. You can get fairly involved here, creating sequences in which the page numbering alternates from side to side on the page, as when you're creating pages for a book.

These properties apply to the fo:page-sequence object:

  • country

  • format

  • language

  • letter-value

  • grouping-separator

  • grouping-size

  • id

  • initial-page-number

  • force-page-count

  • master-name

In the current W3C XSL recommendation, you specify what page master you want to use for a page sequence with the <fo:page-sequence> element's master-name attribute. I named the simple page master we created "page", so I'll set that attribute to that name here. However, FOP is based on an earlier version of XSL and requires an <fo:sequence-specification> element which is no longer supported in the XSL recommendation to let you specify the page master. So, in addition to using the master-name attribute, I'll add an <fo:sequence-specification> element for FOP, enclosing an <fo:sequence-specifier-single> element, which also is no longer supported, and setting that element's master-name attribute to "page". (For future XSL formatting processors that conform to the current XSL recommendation, remove the <fo:sequence-specification> and <fo:sequence-specifier-single> elements.)

<?xml version='1.0'?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"     xmlns:fo="http://www.w3.org/1999/XSL/Format"     version='1.0'>     <xsl:template match="PLANETS">         <fo:root>             <fo:layout-master-set>                  <fo:simple-page-master master-name="page"                      page-height="400mm" page-width="300mm"                      margin-top="10mm" margin-bottom="10mm"                      margin-left="20mm" margin-right="20mm">                      <fo:region-body                        margin-top="0mm" margin-bottom="10mm"                        margin-left="0mm" margin-right="0mm"/>                      <fo:region-after extent="10mm"/>                  </fo:simple-page-master>              </fo:layout-master-set>              <fo:page-sequence master-name="page">                  <!-- Added for fop -->                  <fo:sequence-specification>                      <fo:sequence-specifier-single master-name="page"/>                  </fo:sequence-specification>                  <!-- Added for fop -->                  .                  .                  .

That specifies what page master we want to use for a page sequence. Next, you must specify the content of the page sequence. The content of these pages comes from flow children of the fo:page-sequence.

Creating Flows: fo:flow

Flow objects are so called because the text in them "flows" and is arranged to fit the page by the displaying software. The content of a page is handled with flow objects.

Two kinds of flow objects exist: fo:static-content and fo:flow. An fo:static-content flow object holds content, such as the text that goes into headers and footers, that is repeated on the pages of the page sequence. The fo:flow flow object, on the other hand, holds the text itself that makes up the content of the document. The fo:flow object has a single property, flow-name.

I'll add a fo:flow object to planets.xsl to handle the text content of planets.xml. To make sure that the text content of planets.xml is transformed into that flow, I'll use an <xsl:apply-templates> element, which we first saw in the previous chapter. The <xsl:apply-templates> element will make the XSL processor process the various elements in planets.xml (note that I also add the declaration of the xsl namespace) and will insert them into the flow:

<?xml version='1.0'?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"     xmlns:fo="http://www.w3.org/1999/XSL/Format"     version='1.0'>     <xsl:template match="PLANETS">         <fo:root>             <fo:layout-master-set>                  <fo:simple-page-master master-name="page"                      page-height="400mm" page-width="300mm"                      margin-top="10mm" margin-bottom="10mm"                      margin-left="20mm" margin-right="20mm">                      <fo:region-body                        margin-top="0mm" margin-bottom="10mm"                        margin-left="0mm" margin-right="0mm"/>                      <fo:region-after extent="10mm"/>                  </fo:simple-page-master>              </fo:layout-master-set>              <fo:page-sequence master-name="page">                  <!-- Added for fop -->                  <fo:sequence-specification>                      <fo:sequence-specifier-single master-name="page"/>                  </fo:sequence-specification>                  <!-- Added for fop -->                  <fo:flow>                      <xsl:apply-templates/>                  </fo:flow>              </fo:page-sequence>         </fo:root>     </xsl:template>     .     .     .

That completes the fo:page-sequence object; we've specified a master to use for this sequence and provided the XSL processor a way to get the content that will go into the pages in the formatted document. Besides fo:flow, there's another flow object: fo:static-content.

Creating Static Content: fo:static-content

The fo:static-content formatting object holds formatting objects that are to be presented in a single region or repeated in regions on one or more pages in the page sequence. It is most often used to create repeating headers and footers because its content is repeated on every page to which it is assigned.

Like the fo:flow flow object, the fo:static-content formatting object has a single property, flow-name.

Creating Block-level Content: fo:block

You use blocks in XSL just as we did in CSS: to create a rectangular display area set off from other display areas in a document. You use the fo:block formatting object for formatting such items as paragraphs, titles, headlines, figure and table captions, and so on. Here's an example from the beginning of the chapter:

<fo:block font-family="sans-serif" line-height="48pt" font-size="36pt">     Welcome to XSL formatting. </fo:block>

You can use these properties with fo:block:

  • Common accessibility properties: source-document, role

  • Common aural properties: azimuth, cue-after, cue-before, elevation, pause-after, pause-before, pitch, pitch-range, play-during, richness, speak, speak-header, speak-numeral, speak-punctuation, speech-rate, stress, voice-family, volume

  • Common border, padding, and background properties: background-attachment, background-color, background-image, background-repeat, background-position-horizontal, background-position-vertical, border-before-color, border-before-style, border-before-width, border-after-color, border-after-style, border-after-width, border-start-color, border-start-style, border-start-width, border-end-color, border-end-style, border-end-width, border-top-color, border-top-style, border-top-width, border-bottom-color, border-bottom-style, border-bottom-width, border-left-color, border-left-style, border-left-width, border-right-color, border-right-style, border-right-width, padding-before, padding-after, padding-start, padding-end, padding-top, padding-bottom, padding-left, padding-right

  • Common font properties: font-family, font-size, font-stretch, font-size-adjust, font-style, font-variant, font-weight

  • Common hyphenation properties: country, language, script, hyphenate, hyphenation-character, hyphenation-push-character-count, hyphenation-remain-character-count

  • Common margin properties for blocks: margin-top, margin-bottom, margin-left, margin-right, space-before, space-after, start-indent, end-indent

  • break-after

  • break-before

  • color

  • font-height-override-after

  • font-height-override-before

  • hyphenation-keep

  • hyphenation-ladder-count

  • id

  • keep-together

  • keep-with-next

  • keep-with-previous

  • last-line-end-indent

  • linefeed-treatment

  • line-height

  • line-height-shift-adjustment

  • line-stacking-strategy

  • orphans

  • relative-position

  • space-treatment

  • span

  • text-align

  • text-align-last

  • text-indent

  • visibility

  • white-space-collapse

  • widows

  • wrap-option

  • z-index

Note that the data in planets.xml is broken up into various child elements of a <PLANET> element, such as <NAME>, <MASS>, and so on like this:

<PLANET COLOR="RED">   <NAME>Mercury</NAME>   <MASS UNITS="(Earth = 1)">.0553</MASS>   <DAY UNITS="days">58.65</DAY>   <RADIUS UNITS="miles">1516</RADIUS>   <DENSITY UNITS="(Earth = 1)">.983</DENSITY>   <DISTANCE UNITS="million miles">43.4</DISTANCE><!--At perihelion--> </PLANET>

In this example, I'll give the data in each of the children of a <PLANET> element its own block in the formatted document. To do that, I add a rule to planets.xsl for each of those children, specifying the font to use for each block:

<?xml version='1.0'?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"     xmlns:fo="http://www.w3.org/1999/XSL/Format"     version='1.0'>     <xsl:template match="PLANETS">         <fo:root>             <fo:layout-master-set>                  <fo:simple-page-master master-name="page"                      page-height="400mm" page-width="300mm"                      margin-top="10mm" margin-bottom="10mm"                      margin-left="20mm" margin-right="20mm">                      <fo:region-body                        margin-top="0mm" margin-bottom="10mm"                        margin-left="0mm" margin-right="0mm"/>                      <fo:region-after extent="10mm"/>                  </fo:simple-page-master>              </fo:layout-master-set>              <fo:page-sequence master-name="page">                  <!-- Added for fop -->                  <fo:sequence-specification>                      <fo:sequence-specifier-single master-name="page"/>                  </fo:sequence-specification>                  <!-- Added for fop -->                  <fo:flow>                      <xsl:apply-templates/>                  </fo:flow>              </fo:page-sequence>         </fo:root>     </xsl:template>     <xsl:template match="PLANET/NAME">         <fo:block font-weight="bold" font-size="36pt"             line-height="48pt" font-family="sans-serif">             Name:             <xsl:apply-templates/>         </fo:block>     </xsl:template>     <xsl:template match="PLANET/MASS">         <fo:block font-size="36pt" line-height="48pt"             font-family="sans-serif">             Mass (Earth = 1):             <xsl:apply-templates/>         </fo:block>     </xsl:template>     <xsl:template match="PLANET/DAY">         <fo:block font-size="36pt" line-height="48pt"             font-family="sans-serif">             Day (Earth = 1):             <xsl:apply-templates/>         </fo:block>     </xsl:template>     <xsl:template match="PLANET/RADIUS">         <fo:block font-size="36pt" line-height="48pt"             font-family="sans-serif">             Radius (in miles):             <xsl:apply-templates/>         </fo:block>     </xsl:template>     <xsl:template match="PLANET/DENSITY">         <fo:block font-size="36pt" line-height="48pt"             font-family="sans-serif">             Density (Earth = 1):             <xsl:apply-templates/>         </fo:block>     </xsl:template>     <xsl:template match="PLANET/DISTANCE">         <fo:block font-size="36pt" line-height="48pt"             font-family="sans-serif">             Distance (million miles):             <xsl:apply-templates/>         </fo:block>     </xsl:template> </xsl:stylesheet>

And now we've handled all the elements in planets.xml, so that completes planets.xsl. You can see the results in Figure 14.2 congratulations, you've completed your first transformation to XSL formatting objects.

Figure 14.2. Using planets.xsl for formatting.

graphics/14fig02.gif

Inline-Level Formatting Objects

Besides block objects, you can also create inline objects. Inline objects are usually used to format part of the text as that text follows the normal flow in the page. For example, you can make the first character in a paragraph larger, make the whole first line smaller, insert page numbers into text, and so on.

Here are the inline formatting objects:

  • fo:bidi-override

  • fo:character

  • fo:initial-property-set

  • fo:external-graphic

  • fo:instream-foreign-object

  • fo:inline

  • fo:inline-container

  • fo:leader

  • fo:page-number

  • fo:page-number-citation

I'll take a look at a few of the more common of these objects next.

Using fo:character

The fo:character object enables you to handle the characters in a document individually, which is very useful if you want to write an XSL processor, but not necessarily that useful otherwise. You can use fo:character to replace characters with other characters. Here's an example; in this case, I'm matching an element named <MASKED> and replacing the characters in it with a hyphen (-):

<xsl:template match="MASKED">     <fo:character character="-">         <xsl:value-of select="."/>     </fo:character> </xsl:template>

You can use these properties with fo:character:

  • Common aural properties: azimuth, cue-after, cue-before, elevation, pause-after, pause-before, pitch, pitch-range, play-during, richness, speak, speak-header, speak-numeral, speak-punctuation, speech-rate, stress, voice-family, volume

  • Common border, padding, and background properties: background-attachment, background-color, background-image, background-repeat, background-position-horizontal, background-position-vertical, border-before-color, border-before-style, border-before-width, border-after-color, border-after-style, border-after-width, border-start-color, border-start-style, border-start-width, border-end-color, border-end-style, border-end-width, border-top-color, border-top-style, border-top-width, border-bottom-color, border-bottom-style, border-bottom-width, border-left-color, border-left-style, border-left-width, border-right-color, border-right-style, border-right-width, padding-before, padding-after, padding-start, padding-end, padding-top, padding-bottom, padding-left, padding-right

  • Common font properties: font-family, font-size, font-stretch, font-size-adjust, font-style, font-variant, font-weight

  • Common hyphenation properties: country, language, script, hyphenate, hyphenation-character, hyphenation-push-character-count, hyphenation-remain-character-count

  • Common margin properties-inline: space-end, space-start

  • alignment-adjust

  • treat-as-word-space

  • baseline-identifier

  • baseline-shift

  • character

  • color

  • dominant-baseline

  • font-height-override-after

  • font-height-override-before

  • glyph-orientation-horizontal

  • glyph-orientation-vertical

  • id

  • keep-with-next

  • keep-with-previous

  • letter-spacing

  • line-height

  • line-height-shift-adjustment

  • relative-position

  • score-spaces

  • suppress-at-line-break

  • text-decoration

  • text-shadow

  • text-transform

  • word-spacing

fo:initial-property-set

You can format the first line of an fo:block object with fo:initial-property-set (it's much like the CSS first-line pseudoelement). Here's an example where I'm setting the first line of a block in small caps:

<fo:block>     <fo:initial-property-set font-variant="small-caps" />     Here is the actual text of the paragraph; the first line,     and only the first line, will be displayed in small caps. </fo:block>

You can use these properties with fo:initial-property-set:

  • Common accessibility properties: source-document, role

  • Common aural properties: azimuth, cue-after, cue-before, elevation, pause-after, pause-before, pitch, pitch-range, play-during, richness, speak, speak-header, speak-numeral, speak-punctuation, speech-rate, stress, voice-family, volume

  • Common border, padding, and background properties: background-attachment, background-color, background-image, background-repeat, background-position-horizontal, background-position-vertical, border-before-color, border-before-style, border-before-width, border-after-color, border-after-style, border-after-width, border-start-color, border-start-style, border-start-width, border-end-color, border-end-style, border-end-width, border-top-color, border-top-style, border-top-width, border-bottom-color, border-bottom-style, border-bottom-width, border-left-color, border-left-style, border-left-width, border-right-color, border-right-style, border-right-width, padding-before, padding-after, padding-start, padding-end, padding-top, padding-bottom, padding-left, padding-right

  • Common font properties: font-family, font-size, font-stretch, font-size-adjust, font-style, font-variant, font-weight

  • color

  • id

  • letter-spacing

  • line-height

  • line-height-shift-adjustment

  • relative-position

  • score-spaces

  • text-decoration

  • text-shadow

  • text-transform

  • word-spacing

Adding Graphics: fo:external-graphic

Another inline formatting object that is available is fo:external-graphic, which you use to embed an image in a document. (Unfortunately, fo:external-graphic is not supported by FOP yet.)

You can set the size of the image in the document with the content-height, content-width, and scaling properties; if you don't set these properties, the image is displayed in its original size. Here's an example displaying an image and a caption:

<?xml version="1.0" encoding="UTF-8"?> <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">     <fo:layout-master-set>         <fo:simple-page-master margin-right="20mm"             margin-left="20mm" margin-bottom="10mm"             margin-top="10mm" page-width="300mm"             page-height="400mm" master-name="page">             <fo:region-body margin-right="0mm"                 margin-left="0mm" margin-bottom="10mm"                 margin-top="0mm"/>          <fo:region-after extent="10mm"/>         </fo:simple-page-master>     </fo:layout-master-set>     <fo:page-sequence master-name="page">         <!-- Added for fop -->         <fo:sequence-specification>             <fo:sequence-specifier-single master-name="page"/>         </fo:sequence-specification>         <!-- Added for fop -->         <fo:flow>             <fo:block>                 <fo:external-graphic src="alps15.jpg"/>             </fo:block>             <fo:block space-before="10pt" start-indent="10mm"                 end-indent="0mm">                 A view of the Austrian Alps near Wolfgang See             </fo:block>         </fo:flow>     </fo:page-sequence> </fo:root>

You can use these properties with fo:external-graphic:

  • Common accessibility properties: source-document, role

  • Common aural properties: azimuth, cue-after, cue-before, elevation, pause-after, pause-before, pitch, pitch-range, play-during, richness, speak, speak-header, speak-numeral, speak-punctuation, speech-rate, stress, voice-family, volume

  • Common border, padding, and background properties: background-attachment, background-color, background-image, background-repeat, background-position-horizontal, background-position-vertical, border-before-color, border-before-style, border-before-width, border-after-color, border-after-style, border-after-width, border-start-color, border-start-style, border-start-width, border-end-color, border-end-style, border-end-width, border-top-color, border-top-style, border-top-width, border-bottom-color, border-bottom-style, border-bottom-width, border-left-color, border-left-style, border-left-width, border-right-color, border-right-style, border-right-width, padding-before, padding-after, padding-start, padding-end, padding-top, padding-bottom, padding-left, padding-right

  • Common margin properties-inline: space-end, space-start

  • alignment-adjust

  • baseline-identifier

  • baseline-shift

  • block-progression-dimension

  • content-height

  • content-type

  • content-width

  • dominant-baseline

  • height

  • id

  • inline-progression-dimension

  • keep-with-next

  • keep-with-previous

  • line-height

  • line-height-shift-adjustment

  • relative-position

  • overflow

  • scaling

  • scaling-method

  • src

  • width

The Inline Formatting Object: fo:inline

You can use the fo:inline formatting object to format a part of your text with a background or surround it with a border. This object is fairly general and lets you format an inline area almost as though it were a block.

You can use these properties with fo:inline:

  • Common accessibility properties: source-document, role

  • Common aural properties: azimuth, cue-after, cue-before, elevation, pause-after, pause-before, pitch, pitch-range, play-during, richness, speak, speak-header, speak-numeral, speak-punctuation, speech-rate, stress, voice-family, volume

  • Common border, padding, and background properties: background-attachment, background-color, background-image, background-repeat, background-position-horizontal, background-position-vertical, border-before-color, border-before-style, border-before-width, border-after-color, border-after-style, border-after-width, border-start-color, border-start-style, border-start-width, border-end-color, border-end-style, border-end-width, border-top-color, border-top-style, border-top-width, border-bottom-color, border-bottom-style, border-bottom-width, border-left-color, border-left-style, border-left-width, border-right-color, border-right-style, border-right-width, padding-before, padding-after, padding-start, padding-end, padding-top, padding-bottom, padding-left, padding-right

  • Common font properties: font-family, font-size, font-stretch, font-size-adjust, font-style, font-variant, font-weight

  • Common margin properties-inline: space-end, space-start

  • alignment-adjust

  • baseline-identifier

  • baseline-shift

  • color

  • dominant-baseline

  • id

  • keep-together

  • keep-with-next

  • keep-with-previous

  • line-height

  • line-height-shift-adjustment

  • relative-position

  • text-decoration

  • visibility

  • z-index

Creating Page Numbers: fo:page-number

Another useful inline formatting object is fo:page-number, which creates an inline area displaying the current page number. Here's an example:

<fo:block>     <xsl:text>This is page </xsl:text><fo:page-number/>. </fo:block>

You can use these properties with fo:page-number:

  • Common accessibility properties: source-document, role

  • Common aural properties: azimuth, cue-after, cue-before, elevation, pause-after, pause-before, pitch, pitch-range, play-during, richness, speak, speak-header, speak-numeral, speak-punctuation, speech-rate, stress, voice-family, volume

  • Common border, padding, and background properties: background-attachment, background-color, background-image, background-repeat, background-position-horizontal, background-position-vertical, border-before-color, border-before-style, border-before-width, border-after-color, border-after-style, border-after-width, border-start-color, border-start-style, border-start-width, border-end-color, border-end-style, border-end-width, border-top-color, border-top-style, border-top-width, border- bottom-color, border-bottom-style, border-bottom-width, border-left-color, border-left-style, border-left-width, border-right-color, border-right-style, border-right-width, padding-before, padding-after, padding-start, padding-end, padding-top, padding-bottom, padding-left, padding-right

  • Common font properties: font-family, font-size, font-stretch, font-size-adjust, font-style, font-variant, font-weight

  • Common margin properties-inline: space-end, space-start

  • alignment-adjust

  • baseline-identifier

  • baseline-shift

  • dominant-baseline

  • id

  • keep-with-next

  • keep-with-previous

  • letter-spacing

  • line-height

  • line-height-shift-adjustment

  • relative-position

  • score-spaces

  • text-decoration

  • text-shadow

  • text-transform

  • word-spacing

Creating Tables

Some of the most useful constructs you can format with XSL are tables. A table in XSL is much like one in HTML a rectangular grid of rows and columns of cells. You can use nine formatting objects to create tables:

  • fo:table-and-caption

  • fo:table

  • fo:table-column

  • fo:table-caption

  • fo:table-header

  • fo:table-footer

  • fo:table-body

  • fo:table-row

  • fo:table-cell

Creating tables is a little involved in XSL. You create a fo:table object, format each column with an fo:table-column object, and then create a table-body object, as well as table-row objects for each row and table-cell objects for each cell in each row. Here's an example creating a 3 x 3 table with the words Tic, Tac, and Toe repeated on each line:

<?xml version="1.0" encoding="UTF-8"?> <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">     <fo:layout-master-set>         <fo:simple-page-master margin-right="20mm"             margin-left="20mm" margin-bottom="20mm"             margin-top="20mm" page-width="300mm"             page-height="400mm" master-name="page">             <fo:region-body margin-right="0mm" margin-left="0mm"                 margin-bottom="20mm" margin-top="0mm"/>             <fo:region-after extent="20mm"/>         </fo:simple-page-master>     </fo:layout-master-set>     <fo:page-sequence master-name="page">         <!-- Added for fop -->         <fo:sequence-specification>             <fo:sequence-specifier-single master-name="page"/>         </fo:sequence-specification>         <!-- Added for fop -->         <fo:flow>             <fo:table width="12cm" table-layout="fixed">                 <fo:table-column column-number="1" column-width="25mm">                 </fo:table-column>                 <fo:table-column column-number="2" column-width="25mm">                 </fo:table-column>                 <fo:table-column column-number="3" column-width="25mm">                 </fo:table-column>                 <fo:table-body>                      <fo:table-row line-height="20mm">                          <fo:table-cell column-number="1">                              <fo:block font-family="sans-serif"                                  font-size="36pt">                                  Tic                              </fo:block>                          </fo:table-cell>                          <fo:table-cell column-number="2">                              <fo:block font-family="sans-serif"                                  font-size="36pt">                                  Tac                              </fo:block>                          </fo:table-cell>                          <fo:table-cell column-number="3">                              <fo:block font-family="sans-serif"                                  font-size="36pt">                                  Toe                              </fo:block>                          </fo:table-cell>                      </fo:table-row>                      <fo:table-row line-height="20mm">                          <fo:table-cell column-number="1">                              <fo:block font-family="sans-serif"                                  font-size="36pt">                                  Tic                              </fo:block>                          </fo:table-cell>                          <fo:table-cell column-number="2">                              <fo:block font-family="sans-serif"                                  font-size="36pt">                                  Tac                              </fo:block>                          </fo:table-cell>                          <fo:table-cell column-number="3">                              <fo:block font-family="sans-serif"                                  font-size="36pt">                                  Toe                              </fo:block>                          </fo:table-cell>                      </fo:table-row>                      <fo:table-row line-height="20mm">                          <fo:table-cell column-number="1">                              <fo:block font-family="sans-serif"                                  font-size="36pt">                                  Tic                              </fo:block>                          </fo:table-cell>                          <fo:table-cell column-number="2">                              <fo:block font-family="sans-serif"                                  font-size="36pt">                                  Tac                              </fo:block>                          </fo:table-cell>                          <fo:table-cell column-number="3">                              <fo:block font-family="sans-serif"                                  font-size="36pt">                                  Toe                              </fo:block>                          </fo:table-cell>                      </fo:table-row>                </fo:table-body>             </fo:table>         </fo:flow>     </fo:page-sequence> </fo:root>

After running this file, table.fo, through FOP and creating table.pdf, you can see the result in Figure 14.3.

Figure 14.3. An XSL formatted table in Adobe Acrobat.

graphics/14fig03.gif

I'll now take a look at the various objects you use to create tables.

fo:table

You use the fo:table object to create a new table. The table itself consists of an optional header, an optional footer, and one or more table bodies. The actual grid of cells, arranged into rows and columns, appears in a table body.

You can use these properties with the fo:table object:

  • Common accessibility properties: source-document, role

  • Common aural properties: azimuth, cue-after, cue-before, elevation, pause-after, pause-before, pitch, pitch-range, play-during, richness, speak, speak-header, speak-numeral, speak-punctuation, speech-rate, stress, voice-family, volume

  • Common border, padding, and background properties: background-attachment, background-color, background-image, background-repeat, background-position-horizontal, background-position-vertical, border-before-color, border-before-style, border-before-width, border-after-color, border-after-style, border-after-width, border-start-color, border-start-style, border-start-width, border-end-color, border-end-style, border-end-width, border-top-color, border-top-style, border-top-width, border-bottom-color, border-bottom-style, border-bottom-width, border-left-color, border-left-style, border-left-width, border-right-color, border-right-style, border-right-width, padding-before, padding-after, padding-start, padding-end, padding-top, padding-bottom, padding-left, padding-right

  • Common margin properties-block: margin-top, margin-bottom, margin-left, margin-right, space-before, space-after, start-indent, end-indent

  • block-progression-dimension

  • border-collapse

  • border-separation

  • break-after

  • break-before

  • id

  • inline-progression-dimension

  • height

  • keep-together

  • keep-with-next

  • keep-with-previous

  • relative-position

  • table-layout

  • table-omit-footer-at-break

  • table-omit-header-at-break

  • width

  • writing-mode

fo:table-column

You can use the fo:table-column formatting object to indicate characteristics that apply to table cells that have the same column. Probably the most important property here is the column-width property, which you use to set the width of each column.

You can use these properties with the fo:table-column object:

  • Common border, padding, and background properties: background-attachment, background-color, background-image, background-repeat, background-position-horizontal, background-position-vertical, border-before-color, border-before-style, border-before-width, border-after-color, border-after-style, border-after-width, border-start-color, border-start-style, border-start-width, border-end-color, border-end-style, border-end-width, border-top-color, border-top-style, border-top-width, border- bottom-color, border-bottom-style, border-bottom-width, border-left-color, border-left-style, border-left-width, border-right-color, border-right-style, border-right-width, padding-before, padding-after, padding-start, padding-end, padding-top, padding-bottom, padding-left, padding-right

  • column-number

  • column-width

  • number-columns-repeated

  • number-columns-spanned

  • visibility

fo:table-body

The actual content of tables appears in fo:table-body objects. The object is the one that contains the actual fo:table-row objects, which, in turn, contain the fo:table-cell objects that hold the data for the table.

You can use these properties with the fo:table-body object:

  • Common border, padding, and background properties: background-attachment, background-color, background-image, background-repeat, background-position-horizontal, background-position-vertical, border-before-color, border-before-style, border-before-width, border-after-color, border-after-style, border-after-width, border-start-color, border-start-style, border-start-width, border-end-color, border-end-style, border-end-width, border-top-color, border-top-style, border-top-width, border-bottom-color, border-bottom-style, border-bottom-width, border-left-color, border-left-style, border-left-width, border-right-color, border-right-style, border-right-width, padding-before, padding-after, padding-start, padding-end, padding-top, padding-bottom, padding-left, padding-right

  • id

  • relative-position

fo:table-row

You use the fo:table-row object is used to group table cells into rows. The XSL processor determines the dimensions of the table by how many rows you've added to the table.

You can use these properties with the fo:table-row object:

  • Common accessibility properties: source-document, role

  • Common aural properties: azimuth, cue-after, cue-before, elevation, pause-after, pause-before, pitch, pitch-range, play-during, richness, speak, speak-header, speak-numeral, speak-punctuation, speech-rate, stress, voice-family, volume

  • Common border, padding, and background properties: background-attachment, background-color, background-image, background-repeat, background-position-horizontal, background-position-vertical, border-before-color, border-before-style, border-before-width, border-after-color, border-after-style, border-after-width, border-start-color, border-start-style, border-start-width, border-end-color, border-end-style, border-end-width, border-top-color, border-top-style, border-top-width, border-bottom-color, border-bottom-style, border-bottom-width, border-left-color, border-left-style, border-left-width, border-right-color, border-right-style, border-right-width, padding-before, padding-after, padding-start, padding-end, padding-top, padding-bottom, padding-left, padding-right

  • block-progression-dimension

  • break-after

  • break-before

  • id

  • height

  • keep-together

  • keep-with-next

  • keep-with-previous

  • relative-position

fo:table-cell

You place the content for each cell in an fo:table-cell object. To specify the font and other characteristics of that content, you can enclose an fo:block object inside each fo:table-cell object. You can connect a table cell with a table column using the column-number property.

You can use these properties with the fo:table-cell object:

  • Common accessibility properties: source-document, role

  • Common aural properties: azimuth, cue-after, cue-before, elevation, pause-after, pause-before, pitch, pitch-range, play-during, richness, speak, speak-header, speak-numeral, speak-punctuation, speech-rate, stress, voice-family, volume

  • Common border, padding, and background properties: background-attachment, background-color, background-image, background-repeat, background-position-horizontal, background-position-vertical, border-before-color, border-before-style, border-before-width, border-after-color, border-after-style, border-after-width, border-start-color, border-start-style, border-start-width, border-end-color, border-end-style, border-end-width, border-top-color, border-top-style, border-top-width, border-bottom-color, border-bottom-style, border-bottom-width, border-left-color, border-left-style, border-left-width, border-right-color, border-right-style, border-right-width, padding-before, padding-after, padding-start, padding-end, padding-top, padding-bottom, padding-left, padding-right

  • block-progression-dimension

  • column-number

  • display-align

  • empty-cells

  • ends-row

  • height

  • id

  • number-columns-spanned

  • number-rows-spanned

  • relative-align

  • relative-position

  • starts-row

  • width

Creating Lists

Besides tables, another XSL construct that is very close to the corresponding construct in HTML are lists. An XSL list presents a vertical arrangement of items, just as in HTML. You use four formatting objects to construct lists:

  • fo:list-block

  • fo:list-item

  • fo:list-item-label

  • fo:list-item-body

You enclose the whole list in an fo:list-block object, and you enclose each item in the list in an fo:list-item object. To create a label for the list item, you use an fo:list-item-label object; to insert the actual data for each list item, you use an fo:list-item-body object.

Here's an example creating a numbered list with three list items: Tic, Tac, and Toe:

<?xml version="1.0" encoding="UTF-8"?> <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">     <fo:layout-master-set>         <fo:simple-page-master margin-right="20mm" margin-left="20mm"             margin-bottom="10mm" margin-top="10mm" page-width="300mm"             page-height="400mm" master-name="page">             <fo:region-body margin-right="0mm" margin-left="0mm"             margin-bottom="10mm" margin-top="0mm"/>             <fo:region-after extent="10mm"/>         </fo:simple-page-master>     </fo:layout-master-set>     <fo:page-sequence master-name="page">         <!-- Added for fop -->         <fo:sequence-specification>             <fo:sequence-specifier-single master-name="page"/>         </fo:sequence-specification>         <!-- Added for fop -->         <fo:flow>             <fo:list-block                 provisional-distance-between-starts="15mm"                 provisional-label-separation="5mm">                  <fo:list-item line-height="20mm">                     <fo:list-item-label>                         <fo:block font-family="sans-serif"                             font-size="36pt">                             1.                         </fo:block>                     </fo:list-item-label>                     <fo:list-item-body>                         <fo:block font-family="sans-serif"                             font-size="36pt">                             Tic.                         </fo:block>                     </fo:list-item-body>                 </fo:list-item>                 <fo:list-item line-height="20mm">                     <fo:list-item-label>                         <fo:block font-family="sans-serif"                             font-size="36pt">                             2.                         </fo:block>                     </fo:list-item-label>                     <fo:list-item-body>                         <fo:block font-family="sans-serif"                             font-size="36pt">                             Tac.                         </fo:block>                     </fo:list-item-body>                 </fo:list-item>                  <fo:list-item line-height="20mm">                     <fo:list-item-label>                         <fo:block font-family="sans-serif"                             font-size="36pt">                             3.                         </fo:block>                     </fo:list-item-label>                     <fo:list-item-body>                         <fo:block font-family="sans-serif"                             font-size="36pt">                             Toe.                         </fo:block>                     </fo:list-item-body>                 </fo:list-item>             </fo:list-block>         </fo:flow>     </fo:page-sequence> </fo:root>

You can see the resulting PDF file displayed in the Adobe Acrobat in Figure 14.4, showing the list.

Figure 14.4. An XSL formatted list in Adobe Acrobat.

graphics/14fig04.gif

I'll take a look at the list formatting objects in more detail now.

fo:list-block

You use fo:list-block to format a list; this object encloses fo:list-item objects.

You can use these properties with the fo:list-block object:

  • Common accessibility properties: source-document, role

  • Common aural properties: azimuth, cue-after, cue-before, elevation, pause-after, pause-before, pitch, pitch-range, play-during, richness, speak, speak-header, speak-numeral, speak-punctuation, speech-rate, stress, voice-family, volume

  • Common border, padding, and background properties: background-attachment, background-color, background-image, background-repeat, background-position-horizontal, background-position-vertical, border-before-color, border-before-style, border-before-width, border-after-color, border-after-style, border-after-width, border-start-color, border-start-style, border-start-width, border-end-color, border-end-style, border-end-width, border-top-color, border-top-style, border-top-width, border-bottom-color, border-bottom-style, border-bottom-width, border-left-color, border-left-style, border-left-width, border-right-color, border-right-style, border-right-width, padding-before, padding-after, padding-start, padding-end, padding-top, padding-bottom, padding-left, padding-right

  • Common margin properties-block: margin-top, margin-bottom, margin-left, margin-right, space-before, space-after, start-indent, end-indent

  • break-after

  • break-before

  • id

  • keep-together

  • keep-with-next

  • keep-with-previous

  • provisional-distance-between-starts

  • provisional-label-separation

  • relative-position

fo:list-item

You use a fo:list-item object to contain the label and the body of an item in a list.

You can use these properties with the fo:list-item object:

  • Common accessibility properties: source-document, role

  • Common aural properties: azimuth, cue-after, cue-before, elevation, pause-after, pause-before, pitch, pitch-range, play-during, richness, speak, speak-header, speak-numeral, speak-punctuation, speech-rate, stress, voice-family, volume

  • Common border, padding, and background properties: background-attachment, background-color, background-image, background-repeat, background-position-horizontal, background-position-vertical, border-before-color, border-before-style, border-before-width, border-after-color, border-after-style, border-after-width, border-start-color, border-start-style, border-start-width, border-end-color, border-end-style, border-end-width, border-top-color, border-top-style, border-top-width, border-bottom-color, border-bottom-style, border-bottom-width, border-left-color, border-left-style, border-left-width, border-right-color, border-right-style, border-right-width, padding-before, padding-after, padding-start, padding-end, padding-top, padding-bottom, padding-left, padding-right

  • Common margin properties-block: margin-top, margin-bottom, margin-left, margin-right, space-before, space-after, start-indent, end-indent

  • break-after

  • break-before

  • id

  • keep-together

  • keep-with-next

  • keep-with-previous

  • relative-align

  • relative-position

fo:list-item-label

You use the fo:list-item-label object to hold the label of a list item, usually to enumerate or decorate (as with a bullet) the body of the list item.

You can use these properties with the fo:list-item-label object:

  • Common accessibility properties: source-document, role

  • id

  • keep-together

fo:list-item-body

You use the fo:list-item-body object to hold the actual body of a list item. To format the item's body the way you want it, you can enclose an fo:block object in an fo:list-item-body object.

You can use these properties with the fo:list-item-body object:

  • Common accessibility properties: source-document, role

  • id

  • keep-together

As you can see, there's a lot to XSL formatting objects; in fact, there's a lot more that we don't have the space to cover here. For more details, take a look at the W3C site. Not a lot of software packages can put formatting objects to work yet, but that should change in the future.

In the next chapter, I'm going to start taking an in-depth look at another important part of the XML specification XLinks and XPointers.

CONTENTS


Inside XML
Real World XML (2nd Edition)
ISBN: 0735712867
EAN: 2147483647
Year: 2005
Pages: 23
Authors: Steve Holzner

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net