oXygen XML Editor

Docbook Style

Background

A recent piece of work I did involved some serious style application, far beyond anything I've done before with docbook, being driven by a non-XML customer.

It made me think about adding to docbook markup (the schema) and styling (the stylesheets) to facilitate styling for PDF output via XSL-FO.

I am using Docbook v5

1. How to extend the vocabulary.

1.

How to extend the vocabulary.

By this I mean adding style information to existing Docbook elements. So my target was the addition of properties. I started with a basic block and inline, i.e. para and phrase elements.

DaveP

My starting point was a simple list of properties which could map straight across to XSL-FO. I chose



<!-- Grouped style attributes -->
<define name='db.fo.style.attributes'>
<optional>
  <attribute name='color'/>
  </optional>
 <optional>
  <attribute name='font-family'/>
  </optional>
<optional>
  <attribute name='font-size'/>
  </optional>
<optional>
  <attribute name='font-style'/>
  </optional>
<optional>
  <attribute name='font-variant'/>
  </optional>
</define>

So I want an easy entry to the schema for these. Being so well designed this was no problem at all.



<define name="db.common.attributes" combine='interleave'>
  <optional>
  <ref name="db.fo.style.attributes"/>
</optional>
</define>

And then of course include the main schema.

This lets me add these properties to blocks and inlines as I want. Next the stylesheet customization. This is basically adding processing to copy over these attributes (and no more) to the XSL-FO output.



<!-- Copy over additional attributes from schema extension -->
<xsl:template name="fo.styles" >
<xsl:copy-of select="@color"/>
<xsl:copy-of select="@font-size"/>
<xsl:copy-of select="@font-family"/>
<xsl:copy-of select="@font-variant"/>
</xsl:template>

I wanted these in a named template to retain a single point of match, since it could become a mismatch without due care. Next to customize the para and phrase processing to use this template.



<!-- Override of para. -->
<xsl:template match="d:para[@*[not(self::xml:id )]]">
  <xsl:variable name="keep.together">
    <xsl:call-template name="pi.dbfo_keep-together"/>
  </xsl:variable>
  <fo:block xsl:use-attribute-sets="normal.para.spacing">
    <xsl:call-template name="fo.styles"/>
    <xsl:if test="$keep.together != ''">
      <xsl:attribute name="keep-together.within-column"><xsl:value-of
                      select="$keep.together"/></xsl:attribute>
    </xsl:if>
    <xsl:call-template name="anchor"/>
    <xsl:apply-templates/>
  </fo:block>
</xsl:template>

<!-- Override of phrase -->
<xsl:template match="d:phrase">
  <fo:inline>
    <xsl:call-template name="anchor"/>
    <xsl:call-template name="fo.styles"/>
    <xsl:call-template name="inline.charseq"/>
  </fo:inline>
</xsl:template>

As you see, para is a little messier than phrase, but not too bad. Same reason as before. No massive templates, just a judicious use of partitioning makes it easy.

And that is it. The main stylesheets are imported as with any customization layer.

I asked on the docbook-apps list and received no support, so I assume this will have little interest for anyone using docbook semantically, but for me it makes markup such as the following quite easy.



<para><phrase font-family="gillsans" font-variant="small-caps">A
    Pleasant evening</phrase>.

This produces a small-caps leader as the first sentance of a chapter. It could be fudged using @role, though it would be less easy were it in red, italics with the first letter a different font and size.