Source

sphinx-rst2pdf-builder / sphinx / builders / pdf.py

Full commit
# -*- coding: utf-8 -*-
"""
    sphinx.builders.pdf
    ~~~~~~~~~~~~~~~~~~~

    A rst2pdf builder

    :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS.
    :license: BSD, see LICENSE for details.
"""


from os import path

from docutils import writers
from docutils.io import FileOutput
import docutils.core

from sphinx import addnodes
from sphinx.builders import Builder
from sphinx.writers.pdf import PDFWriter
from sphinx.util.console import darkgreen
import rst2pdf.log
import logging
from pprint import pprint

class PDFBuilder(Builder):
    name = 'pdf'
    out_suffix = '.pdf'

    def init(self):
        self.docnames = []
        self.document_data = self.config.master_doc

    def write(self, *ignored):
        if self.config.pdf_verbosity > 1:
            rst2pdf.log.log.setLevel(logging.DEBUG)
        elif self.config.pdf_verbosity > 0:
            rst2pdf.log.log.setLevel(logging.INFO)

        docwriter = PDFWriter(self,
                            stylesheets=self.config.pdf_stylesheets,
                            language=self.config.pdf_language,
                            breaklevel=self.config.pdf_break_level,
                            fontpath=self.config.pdf_font_path,
                            fitmode=self.config.pdf_fit_mode,
                            compressed=self.config.pdf_compressed,
                            inline_footnotes=self.config.pdf_inline_footnotes,
                            )
        tgt_file = path.join(self.outdir, self.config.master_doc + self.out_suffix)
        destination = FileOutput(destination_path=tgt_file, encoding='utf-8')
        doctree = self.assemble_doctree(self.document_data)
        docwriter.write(doctree, destination)

    def assemble_doctree(self, indexfile):
        self.docnames = set([indexfile])
        self.info(darkgreen(indexfile) + " ", nonl=1)
        def process_tree(docname, tree):
            tree = tree.deepcopy()
            for toctreenode in tree.traverse(addnodes.toctree):
                newnodes = []
                includefiles = map(str, toctreenode['includefiles'])
                for includefile in includefiles:
                    try:
                        self.info(darkgreen(includefile) + " ", nonl=1)
                        subtree = process_tree(includefile,
                        self.env.get_doctree(includefile))
                        self.docnames.add(includefile)
                    except Exception:
                        self.warn('%s: toctree contains ref to nonexisting file %r'\
                                                     % (docname, includefile))
                    else:
                        newnodes.extend(subtree.children)
                toctreenode.parent.replace(toctreenode, newnodes)
            return tree

        tree = self.env.get_doctree(indexfile)
        tree = process_tree(indexfile, tree)
      
        # Add index at the end of the document

        genindex = self.env.create_index(self)
        index_nodes=genindex_nodes(genindex)
        tree.append(index_nodes)

        return tree
    

    def get_target_uri(self, docname, typ=None):
        return ''

    def get_outdated_docs(self):
        for docname in self.env.found_docs:
            if docname not in self.env.all_docs:
                yield docname
                continue
            targetname = self.env.doc2path(docname, self.outdir, self.out_suffix)
            try:
                targetmtime = path.getmtime(targetname)
            except Exception:
                targetmtime = 0
            try:
                srcmtime = path.getmtime(self.env.doc2path(docname))
                if srcmtime > targetmtime:
                    yield docname
            except EnvironmentError:
                # source doesn't exist anymore
                pass

def genindex_nodes(genindexentries):
    #pprint(genindexentries)
    def entrytext(entry):
        txt=[]
        for item in entry[1:][0]:
            txt.append("`%s <%s>`_"%(item[0],item[1][0]))
            if len(item[1]) > 1:
                for i,extra in enumerate(item[1][1:]):
                    txt[-1]+=' `[%d] <%s>`_ '%(i+1,extra)
            print '------------'
            print "genindex:",txt[-1]
            print '------------'
            txt[-1]+='\n\n'
        return txt

    output=['DUMMY','=====','','','INDEX','=====','']
    for i in genindexentries:
        title,entries=i
        output.append('**%s**'%title)
        output.append('')
        for entry in entries:
            pprint (entry)
            output.append('\\'.join(entry[0]))
            output.append('    '+'\n    '.join(entrytext(entry[1])))

    doctree = docutils.core.publish_doctree('\n'.join(output))
    return doctree[1]