diff options
author | Jon Waltman <jonathan.waltman@gmail.com> | 2012-12-04 21:10:15 -0600 |
---|---|---|
committer | Jon Waltman <jonathan.waltman@gmail.com> | 2012-12-04 21:10:15 -0600 |
commit | 4ba1b19953223c6b4ac0f4e82b6116ee5849ef47 (patch) | |
tree | 55c818ca911dda55edc61e0a49e7c2b060b0046c | |
parent | 7adf543e001eaee607cce707512d851b02a885d8 (diff) | |
download | sphinx-4ba1b19953223c6b4ac0f4e82b6116ee5849ef47.tar.gz |
Add Docutils-native XML and pseudo-XML builders
-rw-r--r-- | CHANGES | 3 | ||||
-rw-r--r-- | doc/Makefile | 13 | ||||
-rw-r--r-- | doc/builders.rst | 23 | ||||
-rw-r--r-- | doc/config.rst | 10 | ||||
-rw-r--r-- | sphinx/builders/__init__.py | 2 | ||||
-rw-r--r-- | sphinx/builders/xml.py | 85 | ||||
-rw-r--r-- | sphinx/config.py | 3 | ||||
-rw-r--r-- | sphinx/quickstart.py | 32 | ||||
-rw-r--r-- | sphinx/writers/xml.py | 58 | ||||
-rw-r--r-- | tests/test_build.py | 8 |
10 files changed, 235 insertions, 2 deletions
@@ -57,6 +57,9 @@ Release 1.2 (in development) * PR#88: Added the "Sphinx Developer's Guide" (:file:`doc/devguide.rst`) which outlines the basic development process of the Sphinx project. +* Added the Docutils-native XML and pseudo-XML builders. See + :class:`XMLBuilder` and :class:`PseudoXMLBuilder`. + Release 1.1.3 (Mar 10, 2012) ============================ diff --git a/doc/Makefile b/doc/Makefile index 47951316..a46b0227 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -13,7 +13,8 @@ ALLSPHINXOPTS = -d _build/doctrees $(PAPEROPT_$(PAPER)) \ I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) $(O) . .PHONY: help clean html dirhtml singlehtml text man pickle json htmlhelp \ - qthelp devhelp epub latex latexpdf changes linkcheck doctest + qthelp devhelp epub latex latexpdf changes linkcheck doctest xml \ + pseudoxml help: @echo "Please use \`make <target>' where <target> is one of" @@ -147,3 +148,13 @@ info: @echo "Running Texinfo files through makeinfo..." make -C _build/texinfo info @echo "makeinfo finished; the Info files are in _build/texinfo." + +xml: + $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) _build/xml + @echo + @echo "Build finished. The XML files are in _build/XML." + +pseudoxml: + $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) _build/pseudoxml + @echo + @echo "Build finished. The pseudo-XML files are in _build/pseudoxml." diff --git a/doc/builders.rst b/doc/builders.rst index 6600807d..0075ad81 100644 --- a/doc/builders.rst +++ b/doc/builders.rst @@ -272,6 +272,29 @@ Note that a direct PDF builder using ReportLab is available in `rst2pdf Its name is ``linkcheck``. +.. module:: sphinx.builders.xml +.. class:: XMLBuilder + + This builder produces Docutils-native XML files. The output can be + transformed with standard XML tools such as XSLT processors into arbitrary + final forms. + + Its name is ``xml``. + + .. versionadded:: 1.2 + +.. class:: PseudoXMLBuilder + + This builder is used for debugging the Sphinx/Docutils "Reader to Transform + to Writer" pipeline. It produces compact pretty-printed "pseudo-XML", files + where nesting is indicated by indentation (no end-tags). External + attributes for all elements are output, and internal attributes for any + leftover "pending" elements are also given. + + Its name is ``pseudoxml``. + + .. versionadded:: 1.2 + Built-in Sphinx extensions that offer more builders are: diff --git a/doc/config.rst b/doc/config.rst index df5a208c..0ff6d405 100644 --- a/doc/config.rst +++ b/doc/config.rst @@ -1342,6 +1342,16 @@ Options for the linkcheck builder .. versionadded:: 1.2 +Options for the XML builder +--------------------------- + +.. confval:: xml_pretty + + If True, pretty-print the XML. Default is ``True``. + + .. versionadded:: 1.2 + + .. rubric:: Footnotes .. [1] A note on available globbing syntax: you can use the standard shell diff --git a/sphinx/builders/__init__.py b/sphinx/builders/__init__.py index 5240a1c7..4355b801 100644 --- a/sphinx/builders/__init__.py +++ b/sphinx/builders/__init__.py @@ -334,4 +334,6 @@ BUILTIN_BUILDERS = { 'linkcheck': ('linkcheck', 'CheckExternalLinksBuilder'), 'websupport': ('websupport', 'WebSupportBuilder'), 'gettext': ('gettext', 'MessageCatalogBuilder'), + 'xml': ('xml', 'XMLBuilder'), + 'pseudoxml': ('xml', 'PseudoXMLBuilder'), } diff --git a/sphinx/builders/xml.py b/sphinx/builders/xml.py new file mode 100644 index 00000000..74c1fc06 --- /dev/null +++ b/sphinx/builders/xml.py @@ -0,0 +1,85 @@ +# -*- coding: utf-8 -*- +""" + sphinx.builders.xml + ~~~~~~~~~~~~~~~~~~~ + + Docutils-native XML and pseudo-XML builders. + + :copyright: Copyright 2007-2012 by the Sphinx team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +import codecs +from os import path + +from docutils.io import StringOutput + +from sphinx.builders import Builder +from sphinx.util.osutil import ensuredir, os_path +from sphinx.writers.xml import XMLWriter, PseudoXMLWriter + +class XMLBuilder(Builder): + """ + Builds Docutils-native XML. + """ + name = 'xml' + format = 'xml' + out_suffix = '.xml' + + _writer_class = XMLWriter + + def init(self): + pass + + 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 get_target_uri(self, docname, typ=None): + return '' + + def prepare_writing(self, docnames): + self.writer = self._writer_class(self) + + def write_doc(self, docname, doctree): + destination = StringOutput(encoding='utf-8') + self.writer.write(doctree, destination) + outfilename = path.join(self.outdir, os_path(docname) + self.out_suffix) + ensuredir(path.dirname(outfilename)) + try: + f = codecs.open(outfilename, 'w', 'utf-8') + try: + f.write(self.writer.output) + finally: + f.close() + except (IOError, OSError), err: + self.warn("error writing file %s: %s" % (outfilename, err)) + + def finish(self): + pass + + +class PseudoXMLBuilder(XMLBuilder): + """ + Builds pseudo-XML for display purposes. + """ + name = 'pseudoxml' + format = 'pseudoxml' + out_suffix = '.pseudoxml' + + _writer_class = PseudoXMLWriter diff --git a/sphinx/config.py b/sphinx/config.py index 2012634e..eef8d31c 100644 --- a/sphinx/config.py +++ b/sphinx/config.py @@ -184,6 +184,9 @@ class Config(object): # gettext options gettext_compact = (True, 'gettext'), + + # XML options + xml_pretty = (True, 'env'), ) def __init__(self, dirname, filename, overrides, tags): diff --git a/sphinx/quickstart.py b/sphinx/quickstart.py index 64c2e23c..dd2df0df 100644 --- a/sphinx/quickstart.py +++ b/sphinx/quickstart.py @@ -387,7 +387,7 @@ to the full path of the 'sphinx-build' executable. Alternatively you may add the Sphinx directory to PATH. If you don't have Sphinx installed, grab it from -http://sphinx-doc.org/ +http://sphinx-doc.org/ endef $(error $(MSG)) endif @@ -423,6 +423,8 @@ help: \t@echo " info to make Texinfo files and run them through makeinfo" \t@echo " gettext to make PO message catalogs" \t@echo " changes to make an overview of all changed/added/deprecated items" +\t@echo " xml to make Docutils-native XML files" +\t@echo " pseudoxml to make pseudoxml-XML files for display purposes" \t@echo " linkcheck to check all external links for integrity" \t@echo " doctest to run all doctests embedded in the documentation \ (if enabled)" @@ -547,6 +549,16 @@ doctest: \t$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest \t@echo "Testing of doctests in the sources finished, look at the " \\ \t "results in $(BUILDDIR)/doctest/output.txt." + +xml: +\t$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml +\t@echo +\t@echo "Build finished. The XML files are in $(BUILDDIR)/xml." + +pseudoxml: +\t$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml +\t@echo +\t@echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." ''' BATCHFILE = '''\ @@ -585,6 +597,8 @@ if "%%1" == "help" ( \techo. texinfo to make Texinfo files \techo. gettext to make PO message catalogs \techo. changes to make an overview over all changed/added/deprecated items +\techo. xml to make Docutils-native XML files +\techo. pseudoxml to make pseudoxml-XML files for display purposes \techo. linkcheck to check all external links for integrity \techo. doctest to run all doctests embedded in the documentation if enabled \tgoto end @@ -773,6 +787,22 @@ results in %%BUILDDIR%%/doctest/output.txt. \tgoto end ) +if "%%1" == "xml" ( +\t%%SPHINXBUILD%% -b xml %%ALLSPHINXOPTS%% %%BUILDDIR%%/xml +\tif errorlevel 1 exit /b 1 +\techo. +\techo.Build finished. The XML files are in %%BUILDDIR%%/xml. +\tgoto end +) + +if "%%1" == "pseudoxml" ( +\t%%SPHINXBUILD%% -b pseudoxml %%ALLSPHINXOPTS%% %%BUILDDIR%%/pseudoxml +\tif errorlevel 1 exit /b 1 +\techo. +\techo.Build finished. The pseudo-XML files are in %%BUILDDIR%%/pseudoxml. +\tgoto end +) + :end ''' diff --git a/sphinx/writers/xml.py b/sphinx/writers/xml.py new file mode 100644 index 00000000..02becb73 --- /dev/null +++ b/sphinx/writers/xml.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +""" + sphinx.writers.xml + ~~~~~~~~~~~~~~~~~~ + + Docutils-native XML and pseudo-XML writers. + + :copyright: Copyright 2007-2012 by the Sphinx team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +from docutils import writers +from docutils.writers.docutils_xml import Writer as BaseXMLWriter +from docutils.writers.docutils_xml import XMLTranslator as BaseXMLTranslator + + +class XMLWriter(BaseXMLWriter): + + def __init__(self, builder): + BaseXMLWriter.__init__(self) + self.builder = builder + + def translate(self, *args, **kwargs): + self.document.settings.newlines = \ + self.document.settings.indents = \ + self.builder.env.config.xml_pretty + self.document.settings.xml_declaration = True + self.document.settings.doctype_declaration = True + return BaseXMLWriter.translate(self) + + +class XMLTranslator(BaseXMLTranslator): + def __init__(self, builder, doc): + BaseXMLTranslator.__init__(self, doc) + self.builder = builder + + +class PseudoXMLWriter(writers.Writer): + + supported = ('pprint', 'pformat', 'pseudoxml') + """Formats this writer supports.""" + + config_section = 'pseudoxml writer' + config_section_dependencies = ('writers',) + + output = None + """Final translated form of `document`.""" + + def __init__(self, builder): + writers.Writer.__init__(self) + self.builder = builder + + def translate(self): + self.output = self.document.pformat() + + def supports(self, format): + """This writer supports all format-specific elements.""" + return True diff --git a/tests/test_build.py b/tests/test_build.py index 5f24f89a..87f5a14c 100644 --- a/tests/test_build.py +++ b/tests/test_build.py @@ -61,3 +61,11 @@ else: @with_app(buildername='singlehtml', cleanenv=True) def test_singlehtml(app): app.builder.build_all() + +@with_app(buildername='xml') +def test_xml(app): + app.builder.build_all() + +@with_app(buildername='pseudoxml') +def test_pseudoxml(app): + app.builder.build_all() |