docbook-apps

  • 1.  Page breaks at chapters

    Posted 02-12-2008 16:47
    I've been trying to get a book to have no page breaks before chapters in
    the PDF output. Bob Stayton offered the advice that "a chapter element
    generates a page-sequence in FO output, and a page sequence always
    starts on a new page. If you want to use book and chapter, you'll need
    to customize both templates so that book generates a page-sequence for
    all your content, and chapter does not."



    I took a look at the book and chapter templates but it was a bit murky
    to me how they generate page sequences and how to accomplish what Bob
    suggests. Does anyone have any further clarification that they can
    offer?



    Thanks in advance,



    Alan



    Alan C. Oehler

    Sr. Technical Writer

    Citrix Systems, Inc.

    Virtualization & Management Division




  • 2.  Re: [docbook-apps] Page breaks at chapters

    Posted 02-13-2008 00:55
    Hi Alan,
    This customization pretty much does what you want. It turns out I didn't have to change the book template, only the way the chapters were handled. I copied match="chapter" template from fo/component.xsl, and changed the match on it to only match on the first chapter in a sequence: "chapter[1]". That chapter forms the page-sequence, formats its content, and then processes the following-sibling chapters within the same page sequence, but in a new mode="chapter.merge".

    The chapter.merge template skips all the page-sequence stuff and just processes the chapter content. I had to define an empty template to match on these other chapters in the default mode so that they were not processed twice.

    The result should be a single-page sequence containing all the chapter content.

    <xsl:template match="chapter[1]" priority="1">
    <xsl:variable name="id">
    <xsl:call-template name="object.id"/>
    </xsl:variable>

    <xsl:variable name="master-reference">
    <xsl:call-template name="select.pagemaster"/>
    </xsl:variable>

    <fo:page-sequence hyphenate="{$hyphenate}"
    master-reference="{$master-reference}">
    <xsl:attribute name="language">
    <xsl:call-template name="l10n.language"/>
    </xsl:attribute>
    <xsl:attribute name="format">
    <xsl:call-template name="page.number.format">
    <xsl:with-param name="master-reference" select="$master-reference"/>
    </xsl:call-template>
    </xsl:attribute>
    <xsl:attribute name="initial-page-number">
    <xsl:call-template name="initial.page.number">
    <xsl:with-param name="master-reference" select="$master-reference"/>
    </xsl:call-template>
    </xsl:attribute>

    <xsl:attribute name="force-page-count">
    <xsl:call-template name="force.page.count">
    <xsl:with-param name="master-reference" select="$master-reference"/>
    </xsl:call-template>
    </xsl:attribute>

    <xsl:attribute name="hyphenation-character">
    <xsl:call-template name="gentext">
    <xsl:with-param name="key" select="'hyphenation-character'"/>
    </xsl:call-template>
    </xsl:attribute>
    <xsl:attribute name="hyphenation-push-character-count">
    <xsl:call-template name="gentext">
    <xsl:with-param name="key" select="'hyphenation-push-character-count'"/>
    </xsl:call-template>
    </xsl:attribute>
    <xsl:attribute name="hyphenation-remain-character-count">
    <xsl:call-template name="gentext">
    <xsl:with-param name="key" select="'hyphenation-remain-character-count'"/>
    </xsl:call-template>
    </xsl:attribute>

    <xsl:apply-templates select="." mode="running.head.mode">
    <xsl:with-param name="master-reference" select="$master-reference"/>
    </xsl:apply-templates>

    <xsl:apply-templates select="." mode="running.foot.mode">
    <xsl:with-param name="master-reference" select="$master-reference"/>
    </xsl:apply-templates>

    <fo:flow flow-name="xsl-region-body">
    <xsl:call-template name="set.flow.properties">
    <xsl:with-param name="element" select="local-name(.)"/>
    <xsl:with-param name="master-reference" select="$master-reference"/>
    </xsl:call-template>

    <fo:block id="{$id}"
    xsl:use-attribute-sets="component.titlepage.properties">
    <xsl:call-template name="chapter.titlepage"/>
    </fo:block>

    <xsl:variable name="toc.params">
    <xsl:call-template name="find.path.params">
    <xsl:with-param name="table" select="normalize-space($generate.toc)"/>
    </xsl:call-template>
    </xsl:variable>
    <xsl:if test="contains($toc.params, 'toc')">
    <xsl:call-template name="component.toc">
    <xsl:with-param name="toc.title.p"
    select="contains($toc.params, 'title')"/>
    </xsl:call-template>
    <xsl:call-template name="component.toc.separator"/>
    </xsl:if>
    <xsl:apply-templates/>

    <xsl:apply-templates select="following-sibling::chapter" mode="chapter.merge"/>

    </fo:flow>
    </fo:page-sequence>
    </xsl:template>

    <xsl:template match="chapter" />

    <xsl:template match="chapter" mode="chapter.merge">
    <xsl:variable name="id">
    <xsl:call-template name="object.id"/>
    </xsl:variable>

    <fo:block id="{$id}"
    xsl:use-attribute-sets="component.titlepage.properties">
    <xsl:call-template name="chapter.titlepage"/>
    </fo:block>

    <xsl:variable name="toc.params">
    <xsl:call-template name="find.path.params">
    <xsl:with-param name="table" select="normalize-space($generate.toc)"/>
    </xsl:call-template>
    </xsl:variable>
    <xsl:if test="contains($toc.params, 'toc')">
    <xsl:call-template name="component.toc">
    <xsl:with-param name="toc.title.p"
    select="contains($toc.params, 'title')"/>
    </xsl:call-template>
    <xsl:call-template name="component.toc.separator"/>
    </xsl:if>

    <xsl:apply-templates/>

    </xsl:template>

    </xsl:stylesheet>

    Bob Stayton
    Sagehill Enterprises
    bobs@sagehill.net





  • 3.  RE: [docbook-apps] Page breaks at chapters

    Posted 02-13-2008 01:09
    Bob,



    Many thanks!



    In the meantime I also managed to get your other suggested approach to
    work - making the document an article instead of a book. Originally when
    I did this fop produced the error



    page-sequence must be child of root, not fo:flow



    It occurred to me today that if I changed all my chapters to sect1s, it
    might work... and sure enough, it did.



    I will try your customization on the book version too and decide which
    makes the most sense...



    Regards,

    Alan



    From: Bob Stayton [mailto:bobs@sagehill.net]
    Sent: Tuesday, February 12, 2008 4:55 PM
    To: Alan Oehler; docbook-apps@lists.oasis-open.org
    Subject: Re: [docbook-apps] Page breaks at chapters



    Hi Alan,

    This customization pretty much does what you want. It turns out I
    didn't have to change the book template, only the way the chapters were
    handled. I copied match="chapter" template from fo/component.xsl, and
    changed the match on it to only match on the first chapter in a
    sequence: "chapter[1]". That chapter forms the page-sequence, formats
    its content, and then processes the following-sibling chapters within
    the same page sequence, but in a new mode="chapter.merge".



    The chapter.merge template skips all the page-sequence stuff and just
    processes the chapter content. I had to define an empty template to
    match on these other chapters in the default mode so that they were not
    processed twice.



    The result should be a single-page sequence containing all the chapter
    content.



    <xsl:template match="chapter[1]" priority="1">
    <xsl:variable name="id">
    <xsl:call-template name="object.id"/>
    </xsl:variable>



    <xsl:variable name="master-reference">
    <xsl:call-template name="select.pagemaster"/>
    </xsl:variable>



    <fo:page-sequence hyphenate="{$hyphenate}"
    master-reference="{$master-reference}">
    <xsl:attribute name="language">
    <xsl:call-template name="l10n.language"/>
    </xsl:attribute>
    <xsl:attribute name="format">
    <xsl:call-template name="page.number.format">
    <xsl:with-param name="master-reference"
    select="$master-reference"/>
    </xsl:call-template>
    </xsl:attribute>
    <xsl:attribute name="initial-page-number">
    <xsl:call-template name="initial.page.number">
    <xsl:with-param name="master-reference"
    select="$master-reference"/>
    </xsl:call-template>
    </xsl:attribute>



    <xsl:attribute name="force-page-count">
    <xsl:call-template name="force.page.count">
    <xsl:with-param name="master-reference"
    select="$master-reference"/>
    </xsl:call-template>
    </xsl:attribute>



    <xsl:attribute name="hyphenation-character">
    <xsl:call-template name="gentext">
    <xsl:with-param name="key" select="'hyphenation-character'"/>
    </xsl:call-template>
    </xsl:attribute>
    <xsl:attribute name="hyphenation-push-character-count">
    <xsl:call-template name="gentext">
    <xsl:with-param name="key"
    select="'hyphenation-push-character-count'"/>
    </xsl:call-template>
    </xsl:attribute>
    <xsl:attribute name="hyphenation-remain-character-count">
    <xsl:call-template name="gentext">
    <xsl:with-param name="key"
    select="'hyphenation-remain-character-count'"/>
    </xsl:call-template>
    </xsl:attribute>



    <xsl:apply-templates select="." mode="running.head.mode">
    <xsl:with-param name="master-reference"
    select="$master-reference"/>
    </xsl:apply-templates>



    <xsl:apply-templates select="." mode="running.foot.mode">
    <xsl:with-param name="master-reference"
    select="$master-reference"/>
    </xsl:apply-templates>



    <fo:flow flow-name="xsl-region-body">
    <xsl:call-template name="set.flow.properties">
    <xsl:with-param name="element" select="local-name(.)"/>
    <xsl:with-param name="master-reference"
    select="$master-reference"/>
    </xsl:call-template>



    <fo:block id="{$id}"
    xsl:use-attribute-sets="component.titlepage.properties">
    <xsl:call-template name="chapter.titlepage"/>
    </fo:block>



    <xsl:variable name="toc.params">
    <xsl:call-template name="find.path.params">
    <xsl:with-param name="table"
    select="normalize-space($generate.toc)"/>
    </xsl:call-template>
    </xsl:variable>
    <xsl:if test="contains($toc.params, 'toc')">
    <xsl:call-template name="component.toc">
    <xsl:with-param name="toc.title.p"
    select="contains($toc.params, 'title')"/>
    </xsl:call-template>
    <xsl:call-template name="component.toc.separator"/>
    </xsl:if>
    <xsl:apply-templates/>



    <xsl:apply-templates select="following-sibling::chapter"
    mode="chapter.merge"/>



    </fo:flow>
    </fo:page-sequence>
    </xsl:template>



    <xsl:template match="chapter" />



    <xsl:template match="chapter" mode="chapter.merge">
    <xsl:variable name="id">
    <xsl:call-template name="object.id"/>
    </xsl:variable>



    <fo:block id="{$id}"
    xsl:use-attribute-sets="component.titlepage.properties">
    <xsl:call-template name="chapter.titlepage"/>
    </fo:block>



    <xsl:variable name="toc.params">
    <xsl:call-template name="find.path.params">
    <xsl:with-param name="table"
    select="normalize-space($generate.toc)"/>
    </xsl:call-template>
    </xsl:variable>
    <xsl:if test="contains($toc.params, 'toc')">
    <xsl:call-template name="component.toc">
    <xsl:with-param name="toc.title.p"
    select="contains($toc.params, 'title')"/>
    </xsl:call-template>
    <xsl:call-template name="component.toc.separator"/>
    </xsl:if>



    <xsl:apply-templates/>



    </xsl:template>



    </xsl:stylesheet>

    Bob Stayton
    Sagehill Enterprises
    bobs@sagehill.net