XSL for FOP from the XSL-DocBook-XML-4.4 project


<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet  
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:fo="http://www.w3.org/1999/XSL/Format"
    version="1.0">
  <!-- It is necessary to include both namespaces, or so I am told -->

<!-- 
     The bugs in this project are mine. 

     Virtually everything that works came from one of the following: 
       1) Bob Stayton's book, DocBook XSL: The Complete Guide 
       2) one of the other DocBook experts on the docbook or 
          docbook-apps mailing lists 
       3) Bob Stayton himself on the docbook or docbook-apps 
          mailing lists. 

     You can browse the HTML version of DocBook XSL: The Complete Guide
     at http://www.sagehill.net/docbookxsl/index.html

     You can sign up for the docbook or docbook-apps mailing list at:
     http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=docbook

     I did figure out a few things by myself too.

     *********************************************************************
 

     Here is a list of what still needs fixing. 

     Here is a list of what still needs fixing. 

     * [FIXED]. In a previous version I wrote: "FOP botches vertical text 
       in SVG graphics. The fact that the font is not embedded in those 
       SVG graphics whose text is botched may be relevant. But then, FOP 
       does not botch the horizontal text in SVG graphics whose fonts are 
       not embedded." What I thought was an FOP error with vertical text 
       in SVG graphics is actually the fault of Adobe Illustrator 10. 
       Illustrator was exporting EPS graphics to SVG while incorrectly 
       specifying matrix attribute values on text elements intended to run 
       vertically. In each case, Adobe Illustrator 10 specified a matrix 
       value not equal to zero when the value needed to be exactly zero. 
       To fix it, I manually edited the SVG and changed the necessary 
       values to zero.

     * FOP error message 
       "unknown font ZapfDingbats,italic,normal so defaulted font to any"
       occurs whenever FOP encounters <citetitle></citetitle> or 
       <emphasis></emphasis> as child elements within a <para></para>. 
       I can make that error message go away by including an entry for 
       ZapfDingbats,italic,normal in fop's cfg.xml file. But when I do that, 
       the text of <emphasis></emphasis> and <citetitle></citetitle> 
       elements turns to whitespace in the PDF file. This error message is 
       related to something I am doing in this customization layer. The 
       error message does not occur when using the default DocBook XSL.

     * Prevent widow/orphans.

     * Remove forced pagebreaks. Implement necessary keep-together.

     * Prevent line breaks on certain characters, such as "/"

     * Implement some kind of variable or context-sensitive forced 
       keep-with-next in table cells, and across table cells.

     * Keep-together for individual table cell content  

     * Enable curly quotes. I think I remember someone saying this is bad.
       Can't remember why it's supposed to be bad.

     * Detailed control of space-before and space-after for section headings.

     * The xref page number in footnote number 5 is not properly spaced in 
       relation to its text (too close). Looks like this is an FOP bug.

     * Because of what is apparently a deficiency caused by 
       shared/contributing factors of FOP and fonts that are not UNICODE 
       encoded, there can be problems trying to use bullet symbols other than 
       the "round bullet, filled" (Unicode Code Point 2022). Bullets in front 
       of items in nested lists need to be something different from regular 
       bullets. But without customizing (see the lists section below) FOP 
       does not use the default symbols for nested lists (open circle, etc.)
       So, I did do some customization, but I'm not so sure it is complete.
       I'm using an ndash. FOP's default behavior seems to be to use the 
       regular bullet symbol if it cannot find the value of an itemized 
       list's mark="" attribute. Also, with my solution there is a weird 
       side affect. All items in nested lists whose "itemizedlist" parent 
       element does not use a mark="ndash" attribute get a # (hash) for a 
       bullet. FOP's deficiencies with respect to alternate bullet character 
       support has been discussed on the docbook-apps mailing list. 
       Essentially, the itemized list attribute values such as mark="circle" 
       (or "round", "square", or "box") do not work with FOP. For more 
       information, traverse the thread starting at:
       http://sources.redhat.com/ml/docbook-apps/2004-q1/msg00654.html
       and 
       http://sources.redhat.com/ml/docbook-apps/2004-q1/msg00656.html

-->

  <!-- I am told that FOP 0.20.5 is known to be buggy and lacking required 
       functionality. Experts suggest trying RenderX XEP, and at least one 
       expert has stated: "If you use FOP, you simply will not get the output 
       expected when applying legal XSL." I hope that is false, because I 
       use FOP and I do not want to buy XEP.    -->


<!-- ***************  DOCUMENT FONTS  ***************************  -->
<!-- ************************************************************  -->

<!-- Desired fonts for this document are the Adobe PostScript versions of 
     the following:

       AGaramond-Regular
         Local files:      GDRG____.pfa, GDRG____.PFM, GDRG____.PFB

       AGaramond-Semibold
         Local files:      GDSB____.pfa, GDSB____.PFM, GDSB____.PFB         

       AGaramond-Italic
         Local files:      GDI_____.pfa, GDI_____.PFM, GDI_____.PFB

       Helvetica
         Local files:      HV______.pfa, HV______.PFM, HV______.PFB

       Helvetica-Bold        
         Local files:      HVB_____.pfa, HVB_____.PFM, HVB_____.PFB

       GillSans
         Local files:      GN______.pfa, GN______.PFM, GN______.PFB

       GillSans-Light
         Local files:      GNL_____.pfa, GNL_____.PFM, GNL_____.PFB

       GillSans-Bold
         Local files:      GNB_____.pfa, GNB_____.PFM, GNB_____.PFB   

       GillSans-BoldItalic
         Local files:      GNBI____.pfa, GNB_____.PFM, GNB_____.PFB

       Times-Roman
         Local files:      TIR_____.pfa, TIR_____.PFM, TIR_____.PFB

  In your local version of fop's cfg.xml file, map the above font names 
  to either 1) local versions of the fonts named above, or 2) substitute 
  versions of, hopefully, similar fonts, and if not similar then whatever 
  fonts you do have. 

  The SVG graphics used in the XML reference system fonts with some of 
  the names listed above. There is no way around this. FOP-0.20.5 
  does not handle SVG with embedded fonts, and I cannot supply to you 
  copies of the fonts I used because they are copyrighted. If you have 
  not already become familiar with FOP and embedding fonts. This is 
  the time to do that. 

  A good instruction page is at:
  http://xml.apache.org/fop/fonts.html

  If the SVG graphics give you font-related problems, you can try to 
  fool FOP in cfg.xml by mapping fonts you have to the names the SVG 
  graphics are trying to reference. I didn't try this, just an idea.

  XML font metrics files suitable for registering with FOP were created 
  using commands similar to the following:

java -cp /usr/local/fop-0.20.5/build/fop.jar: \
/usr/local/fop-0.20.5/lib/avalon-framework-cvs-20020806.jar: \
/usr/local/fop-0.20.5/lib/xml-apis.jar: \
/usr/local/fop-0.20.5/lib/xercesImpl.jar: \
/usr/local/fop-0.20.5/lib/xalan.jar org.apache.fop.fonts.apps.PFMReader \
/usr/X11R6/lib/X11/fonts/WindowsPS/XXXX____.PFM XXXX____.xml

  Important Note:
  As of fop-0.20.5, fop cannot produce correct PDF output if the document 
  uses eps graphics. The eps graphics are not rendered to PDF. Instead, the 
  PDF output includes blank placeholders where the eps graphics should be. 
  However, fop can correctly produce PostScript output that includes eps 
  graphics. The PostScript file can then be converted to PDF using ps2pdf 
  or Adobe Acrobat Distiller. Unfortunately, fop-0.20.5 does not embed fonts 
  in PostScript output, not even PostScript fonts. The result is that an 
  author is free to use eps graphics, or embed fonts, but not both. The 
  solution is to use SVG graphics, embed the SVG graphics, embed the 
  PostScript fonts, and produce PDF with fop using the -pdf option. Caveats 
  with this approach: 1) if the graphic's fonts are embedded in the SVG 
  image, fop cannot convert the SVG graphic to PDF. So, don't embed the 
  graphic's font in the SVG image file, but rather add the font to the fop 
  cfg.xml file. 2) when acrobat displays the PDF file, fonts in the 
  embedded SVG graphic won't look very good unless "smooth line art" is 
  chosen from edit > preferences > general (writes to .acrorc ?). 
  I know of no similar setting in the In the xpdf config file (xpdfrc or 
  .xpdfrc). Also, you need to set the FOP config file entry for the 
  key "strokeSVGText" to false. That forces fop to use the vectors for 
  the fonts instead of rasterizing them.

  I posted this info to the docbook-apps mailing list. That was then 
  posted to http://caraldi.com/jbq/fop-graphics/

-->

  <!-- START PRINT CUSTOMIZATION --> 


  <!-- This is the local path to Norm Walsh's DocBook stylesheets   -->
  <xsl:import href="/usr/share/xml/docbook/xsl-stylesheets/fo/docbook.xsl"/>

  <!-- Include local common customization stylesheet (currently empty) -->
  <xsl:include href="common-customizations.xsl" />

  <!-- current docs say that "At present, this consists of PDF 
         bookmarks."  -->
  <xsl:param name="fop.extensions" select="1"/>

 <!-- Turn off draft mode -->  
  <xsl:param name="draft.mode" select="no"/>

  <!-- Body font. The body font family is the default font used for text 
       in the page body. --> 
  <xsl:param name="body.font.family">AGaramond-Regular</xsl:param>

  <!-- Specifies the default font size for body text. -->
    <xsl:param name="body.font.master">11</xsl:param>
    <xsl:param name="body.font.size">
      <xsl:value-of select="$body.font.master"/><xsl:text>pt</xsl:text>
    </xsl:param>

  <!-- The dingbat font family is used for dingbats. If it is defined as 
       the empty string, no font change is effected around dingbats. --> 
  <!-- <xsl:param name="dingbat.font.family">Times-Roman</xsl:param> -->
  <!-- <xsl:param name="dingbat.font.family" select="'serif'"></xsl:param> -->
  <!-- seems to have no affect on my system. FOP still claims it cannot find
       ZapfDingbats,italic,normal-->
  <xsl:param name="dingbat.font.family"></xsl:param>

  <!-- The monospace font family is used for verbatim environments 
       (program listings, screens, etc.). --> 
  <xsl:param name="monospace.font.family">Courier</xsl:param>

  <!-- The default sans-serif font family. At the present, this isn't 
       actually used by the stylesheets. --> 
  <xsl:param name="sans.font.family">GillSans</xsl:param>

  <!-- The title font family is used for titles (chapter, section, figure, 
       etc.) --> 
  <xsl:param name="title.font.family">GillSans-Bold</xsl:param>

  <!-- FOP looks for this image even if the image is not used, and issues 
       an error message if it cannot find the image -->
  <xsl:param name="draft.watermark.image" 
    select="'file:///usr/share/xml/docbook/images/draft.png'"/>


<!-- ****  GENERAL, LAYOUT, ETC.   ******************************  -->
<!-- ************************************************************  -->

  <!-- Text alignmnet for the entire document -->
  <xsl:param name="alignment">justify</xsl:param>

  <!-- Hyphenation  true/false for all text in the entire document --> 
  <xsl:param name="hyphenate">false</xsl:param>

  <!-- Allow SVG in the result tree   -->
  <xsl:param name="use.svg" select="1"></xsl:param>

  <!-- Include an auto-generated List of Figures -->
  <xsl:param name="generate.book.figure.lot" select="1"/>

  <!-- Include an auto-generated List of Tables -->
  <xsl:param name="generate.book.table.lot" select="1"/>

  <!-- Include an auto-generated Index -->
  <xsl:param name="generate.index" select="1"/>

  <!-- Double/single sided. 0 = single, 1 = double -->
  <xsl:param name="double.sided">0</xsl:param>

  <!-- The portrait page height is the length of the long edge of the 
       physical page. -->
  <xsl:param name="page.height.portrait">11in</xsl:param>

  <!-- The portrait page width is the length of the short edge of the 
       physical page. --> 
  <xsl:param name="page.width.portrait">8.5in</xsl:param>

  <!-- Distance from binding edge of the page to the first column of 
       text. -->
  <xsl:param name="page.margin.inner">.875in</xsl:param>

  <!-- Distance from the non-binding edge of the page to the last column 
       of text. -->
  <xsl:param name="page.margin.outer">.875in</xsl:param>

  <!-- Top of page edge to top of header area. -->
  <xsl:param name= "page.margin.top">0.50in</xsl:param>

  <!-- Columns for the various page types. --> 
  <xsl:param name="column.count.titlepage" select="1"/>
  <xsl:param name="column.count.lot" select="1"/>
  <xsl:param name="column.count.front" select="1"/>
  <xsl:param name="column.count.body" select="1"/>
  <xsl:param name="column.count.back" select="1"/>
  <xsl:param name="column.count.index" select="2"/>


<!-- ****  LISTS, ITEMIZEDLISTS, ORDEREDLISTS  ETC.   ***********  -->
<!-- ************************************************************  -->

  <!-- From Bob S. Indents lists. -->
  <xsl:template match="orderedlist|itemizedlist">
    <xsl:choose>
      <xsl:when test="not(ancestor::itemizedlist or ancestor::orderedlist)">
        <fo:block margin-left=".25in">
          <xsl:apply-imports/>
        </fo:block>
      </xsl:when>
      <xsl:otherwise>
        <xsl:apply-imports/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

  <!--  spacing before the list, and between list elements -->
  <xsl:attribute-set name="list.block.spacing">
    <xsl:attribute name="space-before.optimum">0.5em</xsl:attribute>
    <xsl:attribute name="space-before.minimum">0.4em</xsl:attribute>
    <xsl:attribute name="space-before.maximum">0.6em</xsl:attribute>
  </xsl:attribute-set>
  <xsl:attribute-set name="list.item.spacing">
    <xsl:attribute name="space-before.optimum">0.5em</xsl:attribute>
    <xsl:attribute name="space-before.minimum">0.4em</xsl:attribute>
    <xsl:attribute name="space-before.maximum">0.6em</xsl:attribute>
  </xsl:attribute-set>

  <!-- control what symbols are used in lists, copied from 
       common/common.xsl -->
  <xsl:template name="next.itemsymbol">
    <xsl:param name="itemsymbol" select="'default'"/>
    <xsl:choose>
      <!-- Change this list if you want to change the order of symbols -->
      <xsl:when test="$itemsymbol = 'disc'">circle</xsl:when>
      <xsl:when test="$itemsymbol = 'round'">square</xsl:when>
      <!--  I added the next line.  -->
      <xsl:when test="$itemsymbol = 'ndash'">ndash</xsl:when>
      <xsl:otherwise>disc</xsl:otherwise>
    </xsl:choose>
  </xsl:template>

  <!--  Entire template copied from fo/lists.xsl  -->
  <xsl:template match="itemizedlist/listitem">
    <xsl:variable name="id"><xsl:call-template name="object.id"/>
       </xsl:variable>
    <xsl:variable name="itemsymbol">
      <xsl:call-template name="list.itemsymbol">
        <xsl:with-param name="node" select="parent::itemizedlist"/>
      </xsl:call-template>
    </xsl:variable>
    <xsl:variable name="item.contents">
      <fo:list-item-label end-indent="label-end()">
        <fo:block>
          <xsl:choose>
            <xsl:when test="$itemsymbol='disc'">•</xsl:when>
            <xsl:when test="$itemsymbol='bullet'">•</xsl:when>
            <!-- why do these symbols not work? FOP deficiency most of the 
                 time, probably. -->
            <!-- I added the next line.  -->
            <xsl:when test="$itemsymbol='ndash'">–</xsl:when>
            <xsl:when test="$itemsymbol='circle'">∘</xsl:when>
            <xsl:when test="$itemsymbol='round'">∘</xsl:when>
            <xsl:when test="$itemsymbol='square'">☐</xsl:when>
            <xsl:when test="$itemsymbol='box'">☐</xsl:when>
            <xsl:otherwise>•</xsl:otherwise>
          </xsl:choose>
        </fo:block>
      </fo:list-item-label>
      <fo:list-item-body start-indent="body-start()">
        <fo:block>
          <xsl:apply-templates/>
        </fo:block>
      </fo:list-item-body>
    </xsl:variable>
    <xsl:choose>
      <xsl:when test="parent::*/@spacing = 'compact'">
        <fo:list-item 
          id="{$id}" xsl:use-attribute-sets="compact.list.item.spacing">
          <xsl:copy-of select="$item.contents"/>
        </fo:list-item>
      </xsl:when>
      <xsl:otherwise>
        <fo:list-item id="{$id}" xsl:use-attribute-sets="list.item.spacing">
          <xsl:copy-of select="$item.contents"/>
        </fo:list-item>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

  <!-- Force a page break prior to each level 1 heading -->
  <!-- <xsl:attribute-set name="section.level1.properties">
    <xsl:attribute name="break-before">page</xsl:attribute>
  </xsl:attribute-set> -->


<!-- ****  Section titles (headings)  and Chapter titles ********  -->
<!-- ************************************************************  -->
  <!--  This is supposed to control how Chapter titles are displayed, 
        but it seems to not work.
  <xsl:param name="local.l10n.xml" 
    select="document('')"/>
    <l:i18n xmlns:l="http://docbook.sourceforge.net/xmlns/l10n/1.0">
      <l:l10n language="en">
        <l:context name="title">
          <l:template name="chapter" text="%t"/>
        </l:context>
      </l:l10n>
    </l:i18n>       -->

  <!-- Suppress automatic "Chapter #" in Chapter titles (works) --> 
  <xsl:param name="chapter.autolabel" select="0"/>  

  <!-- Set the outdent for section and chapter titles -->
  <xsl:param name="title.margin.left" select="'0pc'"/>

  <!-- Turns on/off section numbering. 0=off, 1=on -->
  <xsl:param name="section.autolabel" select="0"/>

  <!-- Adds the chapter number to the section numbering -->
  <xsl:param name="section.label.includes.component.label" select="0"/>

  <!-- style properties for all lvels of section titles -->
  <xsl:attribute-set name="section.title.properties">
    <xsl:attribute name="font-family">
      <xsl:value-of select="$title.font.family"/>
    </xsl:attribute>
    <xsl:attribute name="font-weight">bold</xsl:attribute>
    <!-- keep-with-next does not seem to work -->
    <xsl:attribute name="keep-with-next.within-column">always</xsl:attribute>
    <!-- font size is calculated dynamically by section.heading template -->
    <xsl:attribute name="keep-with-next.within-column">always</xsl:attribute>
    <xsl:attribute name="space-before.minimum">0.8em</xsl:attribute>
    <xsl:attribute name="space-before.optimum">1.0em</xsl:attribute>
    <xsl:attribute name="space-before.maximum">1.2em</xsl:attribute>
  </xsl:attribute-set>

  <!-- font-family, font-size and color of the Chapter titles -->
  <xsl:template match="title" mode="chapter.titlepage.recto.auto.mode">  
    <fo:block color="#336666" xmlns:fo="http://www.w3.org/1999/XSL/Format" 
           xsl:use-attribute-sets="chapter.titlepage.recto.style" 
           margin-left="{$title.margin.left}" 
           font-size="20pt" 
           font-weight="bold"
           font-style="italic"
           font-family="GillSans-BoldItalic"
           border-bottom-style="solid"
           border-bottom-width="3pt"
           border-bottom-color="#336666"
           space-after="9pt">
      <xsl:call-template name="component.title">
        <xsl:with-param name="node" select="ancestor-or-self::chapter[1]"/>
      </xsl:call-template>
    </fo:block>
  </xsl:template>

  <!-- set the font size for level 1 headings. defaul = * 2.0736 -->
  <xsl:attribute-set name="section.title.level1.properties">
    <xsl:attribute name="font-size">
      <!--   <xsl:value-of select="$body.font.master * 2.0736"/> -->
      <xsl:text>16pt</xsl:text>
    </xsl:attribute>
  </xsl:attribute-set>

  <!-- Include a rule below level1 headings  -->
  <xsl:attribute-set name="section.title.level1.properties">
    <xsl:attribute name="border-bottom-style">solid</xsl:attribute>
    <xsl:attribute name="border-bottom-width">.5pt</xsl:attribute>
    <xsl:attribute name="space-after">6pt</xsl:attribute>
  </xsl:attribute-set>

  <!-- set the font size for level 2 headings. default = * 1.728 -->
  <xsl:attribute-set name="section.title.level2.properties">
    <xsl:attribute name="font-size">
      <!--  <xsl:value-of select="$body.font.master * 1.728"/> -->
      <xsl:text>14pt</xsl:text>
    </xsl:attribute>
  </xsl:attribute-set>

  <!-- set the font size for level 3 headings. default = * 1.44 -->
  <xsl:attribute-set name="section.title.level3.properties">
    <xsl:attribute name="font-size">
      <!--      <xsl:value-of select="$body.font.master * 1.44"/> -->
      <xsl:text>12pt</xsl:text>
    </xsl:attribute>
  </xsl:attribute-set>

  <!-- set the font size for level 4 headings. defaul = * 1.2 -->
  <xsl:attribute-set name="section.title.level4.properties">
    <xsl:attribute name="font-size">
      <xsl:value-of select="$body.font.master * 1.2"/>
      <xsl:text>pt</xsl:text>
    </xsl:attribute>
  </xsl:attribute-set>

  <!-- set the font size for level 5 headings. default = body font size -->
  <xsl:attribute-set name="section.title.level5.properties">
    <xsl:attribute name="font-size">
      <xsl:value-of select="$body.font.master"/>
      <xsl:text>pt</xsl:text>
    </xsl:attribute>
  </xsl:attribute-set>

  <!-- set the font size for level 6 headings. default = body font size-->
  <xsl:attribute-set name="section.title.level6.properties">
    <xsl:attribute name="font-size">
      <xsl:value-of select="$body.font.master"/>
      <xsl:text>pt</xsl:text>
    </xsl:attribute>
  </xsl:attribute-set>


<!-- ****  TOCS                    ******************************  -->
<!-- ************************************************************  -->
  <!-- TOCs in components (Chapters, Appendixes, etc.) 
        0=false, nonzero=true -->   
  <xsl:param name="generate.component.toc" select="0"/>

  <!-- Limits the TOC to the level of sect_N at the most -->
  <xsl:param name="toc.section.depth" select="2"/>
 

<!-- ****  Running HEADERS AND FOOTERS **************************  -->
<!-- ************************************************************  -->
  <!-- Specify the height of the header -->  
  <xsl:param name="region.before.extent" select="'0.5in'"/>

  <!-- Specify the height of the footer -->      
  <xsl:param name="region.after.extent" select="'0.5in'"/>

  <!-- Footnote font size as a percentage of the body font. -->
  <xsl:param name="footnote.font.size">
    <xsl:value-of select="$body.font.master * 0.8"/>
    <xsl:text>pt</xsl:text>
  </xsl:param>

  <!-- Bottom of footer area to bottom of page edge. --> 
  <xsl:param name="page.margin.bottom">0.25in</xsl:param>

  <!-- Top of header area to top of main text area. -->
  <xsl:param name="body.margin.top">0.5in</xsl:param>

  <!-- Bottom of main text area to bottom of footer area. --> 
  <xsl:param name="body.margin.bottom">0.25in</xsl:param>

  <!-- Header content and placement. -->
  <xsl:template name="header.content">  
    <xsl:param name="pageclass" select="''"/>
    <xsl:param name="sequence" select="''"/>
    <xsl:param name="position" select="''"/>
    <xsl:param name="gentext-key" select="''"/>
    <xsl:variable name="candidate">  
      <!-- sequence can be odd, even, first, blank -->
      <!-- position can be left, center, right -->
      <xsl:choose>
        <xsl:when test="$sequence = 'odd' and $position = 'left'">  
        </xsl:when>
        <xsl:when test="$sequence = 'odd' and $position = 'center'">
        </xsl:when>
        <xsl:when test="$sequence = 'odd' and $position = 'right'">
          <xsl:text>freedom Architecture    </xsl:text>
          <fo:page-number/>  
        </xsl:when>
        <xsl:when test="$sequence = 'even' and $position = 'left'">  
          <fo:page-number/>
          <xsl:text>    freedom Architecture</xsl:text>
        </xsl:when>
        <xsl:when test="$sequence = 'even' and $position = 'center'">
        </xsl:when>
        <xsl:when test="$sequence = 'even' and $position = 'right'">
        </xsl:when>
        <xsl:when test="$sequence = 'first' and $position = 'left'"> 
        </xsl:when>
        <xsl:when test="$sequence = 'first' and $position = 'right'">  
        </xsl:when>
        <xsl:when test="$sequence = 'first' and $position = 'center'"> 
        </xsl:when>
        <xsl:when test="$sequence = 'blank' and $position = 'left'">
          <fo:page-number/>
          <xsl:text> freedom Architecture</xsl:text>
        </xsl:when>
        <xsl:when test="$sequence = 'blank' and $position = 'center'">
          <!-- no output -->
        </xsl:when>
        <xsl:when test="$sequence = 'blank' and $position = 'right'">
        </xsl:when>
      </xsl:choose>
    </xsl:variable>

      <!-- Does runtime parameter turn off blank page headers? -->
      <xsl:choose>
        <xsl:when test="$sequence='blank' and $headers.on.blank.pages=1"> 
          <!-- no output -->
        </xsl:when>

      <!-- titlepages have no headers -->
        <xsl:when test="$pageclass = 'titlepage'">  
          <!-- no output -->
        </xsl:when>
        <xsl:otherwise>
          <xsl:copy-of select="$candidate"/>
        </xsl:otherwise>
      </xsl:choose>
  </xsl:template>

  <!-- Header fonts and font size. -->
  <xsl:attribute-set name="header.content.properties">
    <xsl:attribute name="font-family">Helvetica</xsl:attribute>
    <xsl:attribute name="font-size">9pt</xsl:attribute>
  </xsl:attribute-set>

  <!-- Header rule -->
  <xsl:template name="head.sep.rule">
    <xsl:if test="$header.rule != 0">
      <xsl:attribute name="border-bottom-width">0.0pt</xsl:attribute>
      <xsl:attribute name="border-bottom-style">solid</xsl:attribute>
      <xsl:attribute name="border-bottom-color">black</xsl:attribute>
    </xsl:if>
  </xsl:template>

  <!-- Footer content and placement. -->
  <xsl:template name="footer.content">  
    <xsl:param name="pageclass" select="''"/>
    <xsl:param name="sequence" select="''"/>
    <xsl:param name="position" select="''"/>
    <xsl:param name="gentext-key" select="''"/>
    <xsl:variable name="candidate">  
      <!-- sequence can be odd, even, first, blank -->
      <!-- position can be left, center, right -->
      <xsl:choose>
        <xsl:when test="$sequence = 'odd' and $position = 'left'">  
        </xsl:when>
        <xsl:when test="$sequence = 'odd' and $position = 'center'">
        </xsl:when>
        <xsl:when test="$sequence = 'odd' and $position = 'right'">
        </xsl:when>
        <xsl:when test="$sequence = 'even' and $position = 'left'">  
        </xsl:when>
        <xsl:when test="$sequence = 'even' and $position = 'center'">
        </xsl:when>
        <xsl:when test="$sequence = 'even' and $position = 'right'">
        </xsl:when>
        <xsl:when test="$sequence = 'first' and $position = 'left'"> 
        </xsl:when>
        <xsl:when test="$sequence = 'first' and $position = 'right'">  
        </xsl:when>
        <xsl:when test="$sequence = 'first' and $position = 'center'"> 
        </xsl:when>
        <xsl:when test="$sequence = 'blank' and $position = 'left'">
        </xsl:when>
        <xsl:when test="$sequence = 'blank' and $position = 'center'">
        </xsl:when>
        <xsl:when test="$sequence = 'blank' and $position = 'right'">
        </xsl:when>
      </xsl:choose>
    </xsl:variable>
      <!-- Does runtime parameter turn off blank page footers? -->
      <xsl:choose>
        <xsl:when test="$sequence='blank' and $footers.on.blank.pages=0"> 
          <!-- no output -->
        </xsl:when>
      <!-- titlepages have no footers -->
        <xsl:when test="$pageclass = 'titlepage'">  
          <!-- no output -->
        </xsl:when>
        <xsl:otherwise>
          <xsl:copy-of select="$candidate"/>
        </xsl:otherwise>
      </xsl:choose>
  </xsl:template>

  <!-- Footer fonts and font size. -->
  <xsl:attribute-set name="footer.content.properties">
    <xsl:attribute name="font-family">Helvetica</xsl:attribute>
    <xsl:attribute name="font-size">9pt</xsl:attribute>
  </xsl:attribute-set>

  <!-- Footer rule -->
  <xsl:template name="foot.sep.rule">
    <xsl:if test="$footer.rule != 0">
      <xsl:attribute name="border-bottom-width">0.0pt</xsl:attribute>
      <xsl:attribute name="border-bottom-style">solid</xsl:attribute>
      <xsl:attribute name="border-bottom-color">black</xsl:attribute>
    </xsl:if>
  </xsl:template>



<!-- ****  MISC. DETAILS, FINE TUNING ***************************  -->
<!-- ************************************************************  -->

<!-- Specify how formal object titles should be styled. (figures, etc.) -->
  <xsl:attribute-set name="formal.title.properties" 
                   use-attribute-sets="normal.para.spacing">
    <xsl:attribute name="font-family">Helvetica</xsl:attribute>
    <xsl:attribute name="font-weight">normal</xsl:attribute>
    <xsl:attribute name="font-size">10pt</xsl:attribute>
    <xsl:attribute name="hyphenate">false</xsl:attribute>
    <xsl:attribute name="space-after.minimum">0.4em</xsl:attribute>
    <xsl:attribute name="space-after.optimum">0.6em</xsl:attribute>
    <xsl:attribute name="space-after.maximum">0.8em</xsl:attribute>
    <xsl:attribute name="keep-together.within-column">always</xsl:attribute>
  </xsl:attribute-set>

  <!-- Specify the vertical placement of the figure/example/table  title -->
  <xsl:param name="formal.title.placement">
    figure after
    example after
    equation after
    table after
    procedure after
  </xsl:param>

  <!-- To prevent figure, table, example, or procedure  autolabels from 
       resetting to 1 at the beginning of each chapter, but rather cary 
       on with a continuous sequence starting from the beginning of the 
       book, I changed the order of two xsl:number command lines commented 
       out below. I understand some, but not all of this code. -->
  <xsl:template match="figure|table|example|procedure" mode="label.markup">
    <xsl:variable name="pchap"
                  select="ancestor::chapter
                          |ancestor::appendix
                          |ancestor::article[ancestor::book]"/>
    <xsl:variable name="prefix">
      <xsl:if test="count($pchap) > 0">
        <xsl:apply-templates select="$pchap" mode="label.markup"/>
      </xsl:if>
    </xsl:variable>
    <xsl:choose>
      <xsl:when test="@label">
        <xsl:value-of select="@label"/>
      </xsl:when>
      <xsl:when test="local-name() = 'procedure' and
                      $formal.procedures = 0">
        <!-- No label -->
      </xsl:when>
      <xsl:otherwise>
        <xsl:choose>
          <xsl:when test="count($pchap)>0">
            <xsl:if test="$prefix != ''">
              <xsl:apply-templates select="$pchap" mode="label.markup"/>
              <xsl:apply-templates select="$pchap" 
                mode="intralabel.punctuation"/>
            </xsl:if>
              <!--  <xsl:number format="1" from="chapter|appendix" 
                      level="any"/> -->
             <xsl:number format="1" from="book|article" level="any"/>
          </xsl:when>
          <xsl:otherwise>
           <xsl:number format="1" from="chapter|appendix" level="any"/>
            <!-- <xsl:number format="1" from="book|article" level="any"/> -->
          </xsl:otherwise>
        </xsl:choose>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>


  <!-- Tip from Bob Stayton. What we do to get center alignment of
       table titles. This will probably work for figure, example, etc. 
       Most of this template is copied from fo/formal.xsl. The 
       xsl if test part does what's needed. -->
  <xsl:template name="formal.object.heading">
    <xsl:param name="object" select="."/>
    <xsl:param name="placement" select="'before'"/>
    <fo:block xsl:use-attribute-sets="formal.title.properties">
      <xsl:if test="self::table">
        <xsl:attribute name="text-align">center</xsl:attribute>
      </xsl:if>
      <xsl:choose>
        <xsl:when test="$placement = 'before'">
          <xsl:attribute
               name="keep-with-next.within-column">always</xsl:attribute>
        </xsl:when>
        <xsl:otherwise>
          <xsl:attribute
               name="keep-with-previous.within-column">always</xsl:attribute>
        </xsl:otherwise>
      </xsl:choose>
      <xsl:apply-templates select="$object" mode="object.title.markup">
        <xsl:with-param name="allow-anchors" select="1"/>
      </xsl:apply-templates>
    </fo:block>
  </xsl:template>




  <!-- -->
  <xsl:attribute-set name="formal.object.properties">
    <xsl:attribute name="space-before.minimum">0.5em</xsl:attribute>
    <xsl:attribute name="space-before.optimum">1em</xsl:attribute>
    <xsl:attribute name="space-before.maximum">2em</xsl:attribute>
    <xsl:attribute name="space-after.minimum">0.5em</xsl:attribute>
    <xsl:attribute name="space-after.optimum">1em</xsl:attribute>
    <xsl:attribute name="space-after.maximum">2em</xsl:attribute>
    <xsl:attribute name="keep-together.within-column">always</xsl:attribute>
  </xsl:attribute-set>


   <!-- Create a border and background around figures -->
   <!-- <xsl:attribute-set name="figure.properties" 
    use-attribute-sets="formal.object.properties">
         <xsl:attribute name="border-color">#000000</xsl:attribute>
         <xsl:attribute name="border-style">solid</xsl:attribute>
         <xsl:attribute name="border-width">1px</xsl:attribute>
         <xsl:attribute name="padding">1em</xsl:attribute>
         <xsl:attribute name="background-color">#dddddd</xsl:attribute>
  </xsl:attribute-set> -->



  <!--  Spacing between paragraphs    -->
  <xsl:attribute-set name="normal.para.spacing">
    <xsl:attribute name="space-before.optimum">0.5em</xsl:attribute>
    <xsl:attribute name="space-before.minimum">0.4em</xsl:attribute>
    <xsl:attribute name="space-before.maximum">0.6em</xsl:attribute>
    </xsl:attribute-set>

  <!-- Triggers generation of page number citations after xrefs  -->
  <!-- Don't put the id on the title element.  Put it on the element that 
       contains the title. A title element does not output its id value to 
       the XSL-FO.  -->
  <xsl:param name="insert.xref.page.number">maybe</xsl:param>

  <!-- Force a page break. You must include the following in the XML 
       document where you want the pagebreak: <?pagebreak?> -->
  <xsl:template match="processing-instruction('pagebreak')">
    <fo:block break-after="page"/>
  </xsl:template>

  <!-- suppress generation and inclusion of title in xrefs -->
  <xsl:param name="xref.with.number.and.title" select="0"></xsl:param>

  <!-- Controls the size of the superscript number denoting a footnote -->
  <xsl:template name="format.footnote.mark">
    <xsl:param name="mark" select="'?'"/>
    <fo:inline font-size="80%">
      <xsl:choose>
        <xsl:when test="$fop.extensions != 0">
          <xsl:attribute name="vertical-align">super</xsl:attribute>
        </xsl:when>
        <xsl:otherwise>
          <xsl:attribute name="baseline-shift">super</xsl:attribute>
        </xsl:otherwise>
      </xsl:choose>
      <xsl:copy-of select="$mark"/>
    </fo:inline>
  </xsl:template>


<!-- ****    Tables     *****************************************  -->
<!-- ************************************************************  -->

  <!--  This changes the font-family in the text of a table. The text of 
        column headings will automatically be set to a bold variation of 
        the table text. So, you must make sure that FOP is properly 
        configured to also use the bold variation.--> 
  <xsl:attribute-set name="table.properties" 
    use-attribute-sets="formal.object.properties">
    <xsl:attribute name="font-family">GillSans</xsl:attribute>
    <xsl:attribute name="font-size">10pt</xsl:attribute>
  </xsl:attribute-set>


  <!-- Set table cell padding (globally.) You cannot set the padding 
       values for individual tables for FO output. -->
  <xsl:attribute-set name="table.cell.padding">
    <xsl:attribute name="padding-left">8pt</xsl:attribute>
    <xsl:attribute name="padding-right">8pt</xsl:attribute>
    <xsl:attribute name="padding-top">8pt</xsl:attribute>
    <xsl:attribute name="padding-bottom">8pt</xsl:attribute>
  </xsl:attribute-set>





<!-- ****    Title page customization ***************************  -->
<!-- ************************************************************  -->
















<!-- ****    Experimental             ***************************  -->
<!-- ************************************************************  -->



<!-- This is supposed to implement a general keep-with-next ****  
     from:
     http://lists.oasis-open.org/archives/docbook-apps/200210/msg00109.html

     ". . .  "

-->

<!--

  <xsl:template match="para[informalfigure or figure or screenshot]">
  <fo:block xsl:use-attribute-sets="normal.para.spacing">
    <xsl:call-template name="anchor"/>
    <xsl:call-template name="para.figure">
      <xsl:with-param name="current.nodeset">
	<xsl:copy-of select="./* | ./text() | ./processing-instruction() | ./comment()"/>
      </xsl:with-param>
    </xsl:call-template>
  </fo:block>
  </xsl:template>

  <xsl:template name="para.figure">

  <xsl:param name="current.nodeset"/>

  <xsl:variable name="before.figure">
    <xsl:for-each select="node()">
      <xsl:if test="
	not(self::informalfigure) and 
	not(self::figure) and 
	not(self::screenshot) and 
	not(preceding-sibling::informalfigure) and 
	not(preceding-sibling::figure) and
	not(preceding-sibling::screenshot)">
	<xsl:copy-of select="current()"/>
      </xsl:if>
    </xsl:for-each>
  </xsl:variable>

  <xsl:variable name="rest">
    <xsl:for-each select="$current.nodeset/node()">
      <xsl:if test="preceding-sibling::informalfigure or
	preceding-sibling::figure or preceding-sibling::screenshot">
	<xsl:copy-of select="current()"/>
      </xsl:if>
    </xsl:for-each>
  </xsl:variable>

  <fo:block> --> <!-- before.figure --> <!--
    <xsl:apply-templates select="$before.figure/node()"/>
  </fo:block>
  <xsl:if test="
    $current.nodeset/informalfigure or
    $current.nodeset/figure or 
    $current.nodeset/screenshot">
    <fo:block  
      keep-with-previous.within-column="always" 
      keep-together.within-column="always"
      xsl:use-attribute-sets="normal.para.spacing">
      <xsl:apply-templates select="$current.nodeset/informalfigure[
	not(preceding-sibling::figure) and 
	not(preceding-sibling::informalfigure) and
	not(preceding-sibling::screenshot)]"/>
      <xsl:apply-templates select="$current.nodeset/figure[
	not(preceding-sibling::figure) and 
	not(preceding-sibling::informalfigure) and
	not(preceding-sibling::screenshot)]"/>
      <xsl:apply-templates select="$current.nodeset/screenshot[
	not(preceding-sibling::figure) and 
	not(preceding-sibling::informalfigure) and
	not(preceding-sibling::screenshot)]"/>
    </fo:block>
  </xsl:if>
  <xsl:if test="normalize-space($rest) != ''">
    <xsl:call-template name="para.figure">
      <xsl:with-param name="current.nodeset" select="$rest"/>
    </xsl:call-template>
  </xsl:if>
  </xsl:template> -->
</xsl:stylesheet>