Next / Previous / Contents / Shipman's homepage

6.15. buildPageSequence(): Set up the page sequence and headers

docbookindex
# - - -   b u i l d P a g e S e q u e n c e

def buildPageSequence(root, docTitle, timestamp):
    '''Create the page-sequence and the header static-content elements.

      [ (root is a 'root' element) and
        (docTitle is the title as an FO inline) and
        (timestamp is a timestamp string) ->
          root  +:=  a new page-sequence element with
              static-content children defining the header content
              of the ODD_BEFORE and EVEN_BEFORE regions using
              docTitle
          return that page-sequence element ]
    '''

For a general discussion of page layouts, see Section 5.2, “Structure of the XSL-FO output: Page masters”.

First add the page-sequence element.

docbookindex
    #-- 1
    # [ root  +:=  a new page-sequence element for REPEAT_MASTER
    #   pages  :=  that element ]
    pages = subElement(root, h.pageSequence(REPEAT_MASTER))

The odd-page header has the title on the left and the page number on the right. To position these two items requires a bit of FO trickery, which is covered on page 124 of Pawson's book. A block element occupies the full page width by default, and setting a text-align-last="justify" attribute on the block causes the last (in this case the only) line of text to be stretched so that it ends at the right side.

Inside, between the header and page number, is a leaders element, which fills the remaining area. The leaders element can be used to fill the are with a baseline rule, or with dots, but in this case we use leader-pattern="space" to fill with whitespace.

docbookindex
    #-- 2
    # [ pages  +:=  a new static-content element for the odd-page
    #       header, containing (docTitle) + space + (page number) ]
    oddHead = subElement(pages,
        h.staticContent(ODD_BEFORE,
            h.block(HEAD_FONT,
                h.dash(textAlignLast='justify'),
                docTitle,
                E.leader(),
                timestamp,
                E.leader(),
                E("page-number"))))

The next line is a fix for a subtle defect. Originally the docTitle was appended to two different static-content blocks, but a subtree cannot be a child of two different parents. The lxml documentation recommends that one use copy.deepcopy() to make a copy of an et.Element.

docbookindex
    #-- 3
    # [ newTitle  :=  a deep copy of docTitle ]
    newTitle = copy.deepcopy(docTitle)

Although the document is double-sided, the running head is the same on even pages because the content is flipped on the long edge of the sheet. In a previous version of this program, without the two-up landscape orientation, the even-page header's content is in the opposite order: page number, leader, and document title.

docbookindex
    #-- 3
    # [ pages  +:=  a new static-content element for the even-page
    #       header, containing (page number) + space + (docTitle) ]
    evenHead = subElement(pages,
        h.staticContent(EVEN_BEFORE,
            h.block(HEAD_FONT,
                h.dash(textAlignLast='justify'),
                newTitle,
                E.leader(),
                timestamp,
                E.leader(),
                E("page-number"))))
    #-- 4
    return pages