Search code examples
python-sphinxrestructuredtextrst2pdf

Adding header and footer to PDF generated using rst2pdf and Sphinx


I have inherited a user guide that is built using reStructuredText and Sphinx, from which we want to (and can) produce a PDF using rst2pdf integration with Sphinx. The one thing that we'd like to do is apply custom headers and footers to each page of the document (a'la "Draft - Not for Release" or "Version x.y.z"), but there isn't an obvious (to me) way to do this. The rst2pdf command supports specifying --footer="..." and --header="...", but there doesn't seem to be an analogous option in the PDF configuration directives that one can specify in the Sphinx conf.py. Although RST does support header and foot directives, the Sphinx documentation explicitly warns against using them.

I think it might be possible to set this up using rst2pdf stylesheets, but I'm also having a bit of a time understanding how custom stylesheets interact with / extend / override existing stylesheets (if at all).

So what I am looking for is some guidance on how to get headers and footers added to each page cleanly using rst2pdf and Sphinx.


Solution

  • The answer I came up with is from piecing together information from:

    So what I did was create a stylesheet named draft.yaml and place it a _styles subdirectory of the document source code, which looked like:

    pageTemplates:
        decoratedPage:
            defaultFooter: |
                .. class:: right
    
                ###Page###
    
    
                .. class:: draft
    
                DRAFT - DO NOT RELEASE
    
    
            defaultHeader: &draftCentered |
    
                .. class:: draft
    
                DRAFT - DO NOT RELEASE
    
    
        mainPage: &draftTopAndBottom
            defaultFooter: *draftCentered
            defaultHeader: *draftCentered
            showFooter: true
            showHeader: true
    
        coverPage: *draftTopAndBottom
    
        emptyPage: *draftTopAndBottom
    
    
    styles:
        draft: {alignment: center, parent: bodytext, fontName: fontSansBold}
    

    noting that the stylesheet processor supports anchors and aliases, that I am simply modifying existing page templates to include a default header and footer on all of the pages, and that I could define and use my own style to apply in the header and footer. I had wanted try using table syntax to place the page number and footer banner on the same line like can be done in the body of the document as shown here, but it kept trying to treat the table syntax as a reference substitution.

    To get this working with Sphinx and rst2pdf, I needed to add some additional configuration information in conf.py - first by adding rst2pdf.pdfbuilder to the list of extensions, and then the following variable definitions to control the PDF rendering:

    # -- Options for PDF output ----------------------------------------------
    pdf_documents = [('index', u'mydoc', u'My Documentation', u'My Project'),]
    pdf_stylesheets = ['sphinx', 'letter', 'draft']
    pdf_style_path = ['source/_styles']
    

    With this configuration and the stylesheet in place, running sphinx with pdf builder the will apply the built-in sphinx and letter rst2pdf stylesheets on top of the rst2pdf defaults, and then my custom draft rst2pdf stylesheet, and produce the desired banner text at the top and bottom of each page.