Multi-columns and spans

The DocBook XSL stylesheets are capable of generating pages with two or more columns of text. By default, only the index uses two columns. Other XSL-FO page masters can be changed to multiple columns using stylesheet parameters, as described in the section “Multi-column”.

When XSL-FO creates multiple columns on a page, the columns are called snaking columns. That's because the text flows down the first column to the bottom of the page, loops back up to the top of the second column, flows down the second column, and so on. In XSL-FO 1.0, all of the columns are the same width and evenly spaced apart.

Normally all of the content that flows onto such pages is fit into the width of the column. This includes chapter and section titles, figures, tables, code samples, lists, and other content. A narrow column can sometimes produce unwanted results. Here are some potential problem elements for narrow columns.

Page column spans

When using multiple columns, the narrow column width often makes it hard to fit some figures, tables, and examples. It would be nice if you could tell the processor to span all columns for particular elements. You can, but there are limitations in the DocBook schema and stylesheets.

The DocBook 4.5 DTD provides a pgwide attribute on figure, informalfigure, table, and informaltable. The DocBook 5 schema adds example and equation. The pgwide attribute in the schema indicates the element is wide and may need special handling. There are two ways to handle a wider element:

  • In a one-column layout that uses a body.start.indent to indent the body text relative to the headings, a wide element could intrude into the body indent space. That would be accomplished by setting the XSL-FO property start-indent="0pt" on just that element. The DocBook attribute-set named pgwide.properties is the place to do that:

    <xsl:attribute-set name="pgwide.properties">
      <xsl:attribute name="start-indent">0pt</xsl:attribute>
    </xsl:attribute-set>
  • In a multi-column layout, a wide element could span all the columns. That would be accomplished by setting the XSL-FO property span="all" on just that element. Use the same attribute-set with a different attribute:

    <xsl:attribute-set name="pgwide.properties">
      <xsl:attribute name="span">all</xsl:attribute>
    </xsl:attribute-set>

The problem with span="all" is that the XSL-FO 1.0 standard says that span="all" can only appear on an fo:block that is a child of the fo:flow used for a page sequence. This is an unfortunate limitation for DocBook XSL, because it uses a lot of nested blocks that correspond to nested elements. That means if you have a figure inside a section, the fo:block for the figure will not meet that requirement because a section element wraps its content in its own fo:block to set properties that apply to all sections. A figure inside a chapter but before the first section element will work.

If you are using the Antenna House XSL-FO processor, you have it easy. That processor supports spans on nested blocks, so a figure with a pgwide attribute will work anywhere if you set the span property in pgwide.properties as shown above.

If you are using another XSL-FO processor, you can try setting the stylesheet parameter section.container.element to wrapper. This causes each section's output to use an fo:wrapper instead of fo:block as the outer element. This avoids the nesting of fo:block and allows a pgwide span to work when inside a section. This method is known to work with the XEP XSL-FO processor, but not the Antenna House processor (for which it is not needed), nor with FOP. The fo:wrapper element can accept the section id and the section attribute-set. However, the attribute-set only supports properties that are inheritable. That's because there is no block to apply them to. Properties such as font-family are inheritable, but properties such as border are not. The section.container.element parameter was added in version 1.73 of the stylesheets.

A span in XSL-FO alters the text layout on a page as follows:

  • Content preceding a spanned element in the XML file is flowed in balanced columns above the spanned element. The content does not flow past the span to the bottom of the page and then back up to the top of the page. It stops at the span and restarts at the top of the page (or the bottom of a preceding span if it is on the same page).

  • Content following a span is flowed in the columns below the span.

  • Effectively, the top edge of a span acts as the bottom of a page for the content that precedes it.

  • The bottom of a span acts as the top of a page for the content that follows it.

Because a span acts like a page boundary, any space-before or space-after properties are ignored. The effect is to push the text above and below a span right next to it. You can relieve such crowding by adding padding attributes as follows:

<xsl:attribute-set name="pgwide.properties">
  <xsl:attribute name="span">all</xsl:attribute>
  <xsl:attribute name="padding-top">12pt</xsl:attribute>
  <xsl:attribute name="padding-bottom">12pt</xsl:attribute>
</xsl:attribute-set>

Titles in chapters can also span a multiple column layout. Titles are handled as part of the titlepage specification system, described in Chapter 11, Title page customization. The titlepage system includes many nested fo:block elements, which normally would cause spans to be suppressed. But the stylesheet lets you add a span to the outer fo:block that handles all the title page information for a chapter. This means subtitle, author (if used), and any other title page information will be spanned.

The stylesheets support a global span feature using the attribute-set named component.titlepage.properties that applies to all chapters. In fact, it applies to all component elements including appendix, preface, dedication, and colophon in addition to chapter. Here is how it is used:

<xsl:attribute-set name="component.titlepage.properties">
  <xsl:attribute name="span">all</xsl:attribute>
</xsl:attribute-set>

With this property set, the title and any other titlepage information output for chapters will span across all columns. If you want the title page information centered, then specify that property in the titlepage spec file as described in Chapter 11, Title page customization. This attribute-set was added in the 1.73 version of the stylesheets.