summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJon Waltman <jonathan.waltman@gmail.com>2012-12-04 21:10:15 -0600
committerJon Waltman <jonathan.waltman@gmail.com>2012-12-04 21:10:15 -0600
commit4ba1b19953223c6b4ac0f4e82b6116ee5849ef47 (patch)
tree55c818ca911dda55edc61e0a49e7c2b060b0046c
parent7adf543e001eaee607cce707512d851b02a885d8 (diff)
downloadsphinx-4ba1b19953223c6b4ac0f4e82b6116ee5849ef47.tar.gz
Add Docutils-native XML and pseudo-XML builders
-rw-r--r--CHANGES3
-rw-r--r--doc/Makefile13
-rw-r--r--doc/builders.rst23
-rw-r--r--doc/config.rst10
-rw-r--r--sphinx/builders/__init__.py2
-rw-r--r--sphinx/builders/xml.py85
-rw-r--r--sphinx/config.py3
-rw-r--r--sphinx/quickstart.py32
-rw-r--r--sphinx/writers/xml.py58
-rw-r--r--tests/test_build.py8
10 files changed, 235 insertions, 2 deletions
diff --git a/CHANGES b/CHANGES
index ef2be083..b67ed973 100644
--- a/CHANGES
+++ b/CHANGES
@@ -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()