Commits

Anonymous committed d172c66

Added basic rst2pdf builder handling

Comments (0)

Files changed (6)

sphinx/builder.py

 import warnings
 
 from sphinx.builders import Builder
+from sphinx.builders.pdf import PDFBuilder
 from sphinx.builders.text import TextBuilder
 from sphinx.builders.html import StandaloneHTMLBuilder, WebHTMLBuilder, \
      PickleHTMLBuilder, JSONHTMLBuilder

sphinx/builders/__init__.py

 
 
 BUILTIN_BUILDERS = {
+    'pdf':       ('pdf', 'PDFBuilder'),
     'html':      ('html', 'StandaloneHTMLBuilder'),
     'dirhtml':   ('html', 'DirectoryHTMLBuilder'),
     'pickle':    ('html', 'PickleHTMLBuilder'),

sphinx/builders/pdf.py

+# -*- coding: utf-8 -*-
+"""
+    sphinx.builders.pdf
+    ~~~~~~~~~~~~~~~~~~~
+
+    Several HTML builders.
+
+    :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
+
+from sphinx import addnodes
+from sphinx.builders import Builder
+from sphinx.writers.pdf import PDFWriter
+from sphinx.util.console import darkgreen
+
+class PDFBuilder(Builder):
+   name = 'pdf'
+   out_suffix = '.pdf'
+
+   def init(self):
+      self.docnames = []
+      self.document_data = self.config.master_doc
+
+   def write(self, *ignored):
+      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)
+      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)
+      return process_tree(indexfile, 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 finish(self):
+      pass
         latex_additional_files = ([], None),
         # now deprecated - use latex_elements
         latex_preamble = ('', None),
+
+        # PDF options
+        pdf_documents = ([], None),
+        pdf_stylesheets = ([], None),
+        pdf_compressed = (False, None),
+        pdf_font_path = ([], None),
+        pdf_language = ('', None),
+        pdf_fit_mode = ('', None),
+        pdf_break_level = (0, None),
     )
 
     def __init__(self, dirname, filename, overrides, tags):

sphinx/quickstart.py

 
 # If false, no module index is generated.
 #latex_use_modindex = True
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title, author, documentclass [howto/manual]).
+# XXX: unused at the moment
+#pdf_documents = [
+#  ('%(master_str)s', '%(project_fn)s.pdf', u'%(project_doc_texescaped_str)s',
+#   u'%(author_texescaped_str)s', 'manual'), 
+#]
+
+# A comma-separated list of custom stylesheets. Example:
+# stylesheets=["fruity.json", "a4paper.json", "verasans.json"]
+#pdf_stylesheets = ['autumn.json']
+
+# Create a compressed PDF
+# Use True/False or 1/0
+# Example: compressed=True
+#pdf_compressed=False
+
+# A colon-separated list of folders to search for fonts. Example:
+# pdf_font_path=['/usr/share/fonts', '/usr/share/texmf-dist/fonts/']
+#pdf_font_path= ['/usr/share/fonts', '/usr/share/texmf-dist/fonts/']
+
+# Language to be used for hyphenation support
+#pdf_language="en_EN"
 '''
 
 INTERSPHINX_CONFIG = '''
 \t@echo "  htmlhelp  to make HTML files and a HTML help project"
 \t@echo "  qthelp    to make HTML files and a qthelp project"
 \t@echo "  latex     to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
+\t@echo "  pdf       to make standalone PDF files"
 \t@echo "  changes   to make an overview of all changed/added/deprecated items"
 \t@echo "  linkcheck to check all external links for integrity"
 \t@echo "  doctest   to run all doctests embedded in the documentation \
 \t@echo "Run \\`make all-pdf' or \\`make all-ps' in that directory to" \\
 \t      "run these through (pdf)latex."
 
+pdf:
+\t$(SPHINXBUILD) -b pdf $(ALLSPHINXOPTS) %(rbuilddir)s/pdf
+\t@echo
+\t@echo "Build finished. The PDF files are in %(rbuilddir)s/pdf."
+
 changes:
 \t$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) %(rbuilddir)s/changes
 \t@echo
 \techo.  htmlhelp  to make HTML files and a HTML help project
 \techo.  qthelp    to make HTML files and a qthelp project
 \techo.  latex     to make LaTeX files, you can set PAPER=a4 or PAPER=letter
+\techo.  pdf       to make PDF files
 \techo.  changes   to make an overview over all changed/added/deprecated items
 \techo.  linkcheck to check all external links for integrity
 \techo.  doctest   to run all doctests embedded in the documentation if enabled
 \tgoto end
 )
 
+if "%%1" == "pdf" (
+\t%%SPHINXBUILD%% -b pdf %%ALLSPHINXOPTS%% %(rbuilddir)s/pdf
+\techo.
+\techo.Build finished. The PDF pages are in %(rbuilddir)s/pdf.
+\tgoto end
+)
+
 if "%%1" == "changes" (
 \t%%SPHINXBUILD%% -b changes %%ALLSPHINXOPTS%% %(rbuilddir)s/changes
 \techo.

sphinx/writers/pdf.py

+# -*- coding: utf-8 -*-
+"""
+    sphinx.writers.pdf
+    ~~~~~~~~~~~~~~~~~~
+
+    docutils writers handling Sphinx' custom nodes.
+
+    :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS.
+    :license: BSD, see LICENSE for details.
+"""
+
+from StringIO import StringIO
+from docutils import writers
+from rst2pdf import createpdf
+
+class PDFWriter(writers.Writer):
+   def __init__(self, builder, stylesheets, language, breaklevel, fontpath, fitmode, compressed):
+      writers.Writer.__init__(self)
+      self.builder = builder
+      self.output = ''
+      self.stylesheets = stylesheets
+      self.language = language
+      self.breaklevel = int(breaklevel)
+      self.fontpath = fontpath
+      self.fitmode = fitmode
+      self.compressed = compressed
+
+   supported = ('pdf')
+   config_section = 'pdf writer'
+   config_section_dependencies = ('writers',)
+
+   def translate(self):
+      sio=StringIO('')
+      createpdf.RstToPdf(sphinx=True,
+                         stylesheets=self.stylesheets,
+                         language=self.language,
+                         breaklevel=self.breaklevel,
+                         fitMode=self.fitmode,
+                         fontPath=self.fontpath
+                        ).createPdf(doctree=self.document,
+                                    output=sio,
+                                    compressed=self.compressed)
+      self.output=unicode(sio.getvalue(),'utf-8','ignore')
+
+   def supports(self, format):
+      """This writer supports all format-specific elements."""
+      return 1
+