Question

I'm trying to affect the properties of the fo:list-block within a docbook 5 procedure. What I want to do is take the following docbook XML code:

<procedure>
    <title>Eating a banana</title>
    <step><para>Find banana</para></step>
    <step><para>Peel banana</para></step>
    <step><para>Stick banana in mouth</para></step>
<procedure>

and affect the FO output of just the steps (a list), not the title.

Using this:

<xsl:template match="d:procedure">
    <fo:block border-left-width="1pt" border-left-style="solid" padding-left="0.25in">
        <xsl:apply-imports />
    </fo:block>
</xsl:template>

Gets me something like this:

|
| Procedure 1: Eating a banana
|   1. Find banana
|   2. Peal banana
|   3. Stick banana in mouth
|

What I'm trying to get is:

Procedure 1: Eating a banana
  |   1. Find banana
  |   2. Peal banana
  |   3. Stick banana in mouth

Trying to match to <step> is invalid, since docbook turns those into fo:list-block (fo:block as a descendant of fo:list-block generates an "invalid child" error).

Docbook has a xsl:attribute-set for <procedures>, but as far as I can tell, that can only be used to style the entire block (similar to the template match='d:procedure', not just the list.

Was it helpful?

Solution

Here is how it can be done.

  1. Add this version of the "procedure" template (the original is in lists.xsl) to your customization layer:

    <xsl:template match="d:procedure">
      <xsl:variable name="id">
        <xsl:call-template name="object.id"/>
      </xsl:variable>
    
      <!-- Preserve order of PIs and comments -->
      <xsl:variable name="preamble"
            select="*[not(self::d:step
                      or self::d:title
                      or self::d:titleabbrev)]
                    |comment()[not(preceding-sibling::d:step)]
                    |processing-instruction()[not(preceding-sibling::d:step)]"/>
    
      <xsl:variable name="steps" 
                    select="d:step
                            |comment()[preceding-sibling::d:step]
                            |processing-instruction()[preceding-sibling::d:step]"/>
    
      <xsl:call-template name="formal.object.heading"/>  
    
      <fo:block id="{$id}" xsl:use-attribute-sets="procedure.properties list.block.spacing"
            border-left-width="1pt" border-left-style="solid" padding-left="0.25in">
    
        <xsl:apply-templates select="$preamble"/>
    
        <fo:list-block xsl:use-attribute-sets="list.block.spacing"
                       provisional-distance-between-starts="2em"
                       provisional-label-separation="0.2em">
          <xsl:apply-templates select="$steps"/>
        </fo:list-block>
    
      </fo:block>
    </xsl:template>
    

    <xsl:call-template name="formal.object.heading"/> (which returns a fo:block with the procedure title) is executed before the block with the border is being output. I have also simplified the template by removing code that handles placement of the title.

  2. Add text-indent to the formal.title.properties attribute-set:

    <xsl:attribute-set name="formal.title.properties" 
                   use-attribute-sets="normal.para.spacing">
      <xsl:attribute name="text-indent">
        <xsl:choose>
          <xsl:when test="self::d:procedure">-30pt</xsl:when>
          <xsl:otherwise>0pt</xsl:otherwise>
        </xsl:choose>
      </xsl:attribute>
    </xsl:attribute-set>
    

This will push the procedure title to the left (but leave other titles alone).

OTHER TIPS

I came up with this idea. While it works fine for single-level procedures, anything with substeps will cause problems.

<xsl:template match="d:step">
    <fo:list-item margin-left="0.25in" padding-left='1em' border-left-width='2pt' border-left-color="gray" border-left-style='solid'>
        <fo:list-item-label start-indent="0.40in" end-indent="label-end()">
            <fo:block>
                <xsl:number format="1."/>
            </fo:block>
        </fo:list-item-label>       
        <fo:list-item-body start-indent="3.5pc">
            <fo:block>
                <xsl:apply-templates />
            </fo:block>
        </fo:list-item-body>
    </fo:list-item>
</xsl:template>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top