13.4. XSL-FO Properties
The
finished document
shown in Figure 13-3 is quite Spartan. It simply
breaks the original XML document into a few separate paragraphs.
After quite a lot of work, it still hasn't reached
the polish that was achieved much more simply with CSS back in the
last chapter in Example 12-2 and Figure 12-1. Adding the sparkle of different fonts, bold
headlines, bulleted lists, and other desirable features requires
setting the relevant properties on the individual formatting objects.
These are set through optional attributes of the formatting object
elements like fo:block. The good news is that most
of the property names and semantics are exactly the same as they are
for CSS. For example, to make the text in an
fo:block element bold, add a
font-weight attribute with the value
bold, like this:
<fo:block font-weight="bold">Southern Corn Bread</fo:block>
The similarity with the equivalent CSS rule is obvious:
dish { font-weight: bold }
The property name is the same. The property value is the same. The
meaning of the property is the same. Similarly, you can use all the
font-weight keywords and values like
lighter and 100,
200, 300,
400, etc. that you learned for CSS. Only the
syntactic details of how the value bold is
assigned to the property font-weight and how that
property is then attached to the dish element has
changed. When XSL-FO and CSS converge, they do so closely.
Many other properties come across from CSS by straight extrapolation.
For instance, in Example 12-2 the
dish element was formatted with this rule:
dish {
display: block;
font-family: Helvetica, Arial, sans-serif;
font-size: 20pt;
font-weight: bold;
text-align: center
}
In XSL-FO, it will be formatted with this XSLT template:
<xsl:template match="dish">
<fo:block font-family="Helvetica, Arial, sans-serif" font-size="20pt"
font-weight="bold" text-align="center">
<xsl:apply-templates/>
</fo:block>
</xsl:template>
Similarly, the margin properties set the margins on the various
elements:
<xsl:template match="directions|story">
<fo:block margin-top="12pt" margin-left="4pt">
<xsl:apply-templates/>
</fo:block>
</xsl:template>
In a few cases CSS properties become XSL-FO elements rather than
attributes. For instance, to format the ingredients as a bulleted
list, we have to use the fo:list-block,
fo:list-item,
fo:list-item-label, and
fo:list-item-body elements. This XSLT template
does that:
<xsl:template match="ingredient">
<fo:list-item>
<!-- Unicode Bullet Character -->
<fo:list-item-label>•</fo:list-item-label>
<fo:list-item-body><xsl:apply-templates/></fo:list-item-body>
</fo:list-item>
</xsl:template>
We now have the pieces needed to put together a more attractive
XSL-FO document. Example 13-4 is an XSLT stylesheet that transforms
documents like Example 12-1 into XSL-FO documents.
Example 13-4. An XSLT-to-XSL-FO transform
<?xml version="1.0" encoding="UTF-8"?>
<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>
<fo:layout-master-set>
<fo:simple-page-master margin-right="1in" margin-left="1in"
margin-bottom="1in" margin-top="1in"
page-width="8.5in" page-height="11in"
master-name="first">
<fo:region-body/>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="first">
<fo:flow flow-name="xsl-region-body">
<xsl:apply-templates/>
</fo:flow>
</fo:page-sequence>
</fo:root>
</xsl:template>
<xsl:template match="recipe">
<fo:block font-family="Times, 'Times New Roman', serif"
font-size="12pt">
<xsl:apply-templates/>
</fo:block>
</xsl:template>
<xsl:template match="dish">
<fo:block font-family="Helvetica, Arial, sans-serif" font-size="20pt"
font-weight="bold" text-align="center">
<xsl:apply-templates/>
</fo:block>
</xsl:template>
<xsl:template match="directions|story">
<fo:block margin-top="12pt" margin-left="4pt">
<xsl:apply-templates/>
</fo:block>
</xsl:template>
<xsl:template match="ingredients">
<fo:list-block><xsl:apply-templates/></fo:list-block>
</xsl:template>
<xsl:template match="ingredient">
<fo:list-item>
<!-- Unicode Bullet Character -->
<fo:list-item-label>
<fo:block>•</fo:block>
</fo:list-item-label>
<fo:list-item-body>
<fo:block><xsl:apply-templates/></fo:block>
</fo:list-item-body>
</fo:list-item>
</xsl:template>
</xsl:stylesheet>
Example 13-5 shows the XSL-FO document produced by
applying the previous transform to the cornbread recipe in Example 12-1. The whitespace has been cleaned up a little
by hand, though that won't affect the final rendered
result.
Example 13-5. An XSL-FO document describing a recipe for cornbread
<?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="1in" margin-left="1in"
margin-bottom="1in" margin-top="1in" page-width="8.5in"
page-height="11in" master-name="first">
<fo:region-body/>
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="first">
<fo:flow flow-name="xsl-region-body">
<fo:block font-family="Times, 'Times New Roman', serif"
font-size="12pt">
<fo:block font-family="Helvetica, Arial, sans-serif"
font-size="20pt" font-weight="bold"
text-align="center">Southern Corn Bread</fo:block>
<fo:list-block>
<fo:list-item><fo:list-item-label><fo:block>·</fo:block>
</fo:list-item-label><fo:list-item-body><fo:block>
1 cup
flour
</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>
4 tablespoons
Royal Baking Powder
</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>
1/2 teaspoon
salt
</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>
1 cup
corn meal
</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>
11/2 cups
whole milk
</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>
4 tablespoons
melted butter
</fo:block></fo:list-item-body></fo:list-item>
</fo:list-block>
<fo:block margin-top="12pt" margin-left="4pt">
Sift flour, baking powder, sugar & salt together.
Add 1 cup corn meal.
Beat egg in cup and add beaten egg and 11/2 cups whole
milk to make a batter. Stir well.
Add melted shortening and beat until light and thoroughly mixed.
Pour into greased shallow pan or greased muffin rings.
Bake in hot oven at 425º F for
25 minutes.
Cut into squares if cooked in shallow pan.
</fo:block>
<fo:block margin-top="12pt" margin-left="4pt">
After my mother-in-law Marjorie Anderson died,
Beth and I found this recipe written on the "extra recipes"
page in a local cookbook in her cupboard.
This was published by the The Episcopal Churchwomen,
Church of Ascension, Mt. Sterling,
Kentucky.
</fo:block>
</fo:block></fo:flow></fo:page-sequence></fo:root>
This document can be run through a formatter to produce a PDF file
for viewing. Figure 13-4 shows the final result of
this process.
Figure 13-4. The recipe document after conversion from XSL-FO to PDF
XSL-FO does add a number of properties that CSS
doesn't provide. To name just a few, XSL-FO has
properties to control hyphenation, insert leaders, specify the number
of columns on a page, and determine where page breaks occur and which
paragraphs must be kept together. CSS has none of these. For the most
part, XSL-FO's properties are a superset of
CSS's properties.
 |  |  | 13.3. Laying Out the Master Pages |  | 13.5. Choosing Between CSS and XSL-FO |
Copyright © 2002 O'Reilly & Associates. All rights reserved.
|