Allow registration of other translators

This adds an add_translator method to the sphinx application class.
It allows developers to register custom translators (writers) with
sphinx, so other extensions that add new nodes can register support
for the custom translators.
This commit is contained in:
Russell Sim 2014-03-20 12:34:11 +11:00
parent 3e7ce5d3a1
commit 45a0bcd453
2 changed files with 36 additions and 18 deletions

View File

@ -82,16 +82,25 @@ package.
Register an event called *name*. This is needed to be able to emit it.
.. method:: Sphinx.add_translator(name, translator_class)
Register a Docutils translator class. This is used to register a
custom output translator. This allows extensions to define custom
nodes for the translator (see :meth:`add_node`). If the name
clashes with an existing translator an
:exc:`sphinx.errors.ExtensionError` will be raised.
.. method:: Sphinx.add_node(node, **kwds)
Register a Docutils node class. This is necessary for Docutils internals.
It may also be used in the future to validate nodes in the parsed documents.
Node visitor functions for the Sphinx HTML, LaTeX, text and manpage writers
can be given as keyword arguments: the keyword must be one or more of
``'html'``, ``'latex'``, ``'text'``, ``'man'``, ``'texinfo'``, the value a
2-tuple of ``(visit, depart)`` methods. ``depart`` can be ``None`` if the
``visit`` function raises :exc:`docutils.nodes.SkipNode`. Example:
can be given as keyword arguments: the keyword should be one or more of
``'html'``, ``'latex'``, ``'text'``, ``'man'``, ``'texinfo'`` or any other
supported translators, the value a 2-tuple of ``(visit, depart)`` methods.
``depart`` can be ``None`` if the ``visit`` function raises
:exc:`docutils.nodes.SkipNode`. Example:
.. code-block:: python

View File

@ -38,6 +38,11 @@ from sphinx.util import pycompat # imported for side-effects
from sphinx.util.tags import Tags
from sphinx.util.osutil import ENOENT
from sphinx.util.console import bold, lightgray, darkgray
from sphinx.writers.html import HTMLTranslator
from sphinx.writers.latex import LaTeXTranslator
from sphinx.writers.text import TextTranslator
from sphinx.writers.manpage import ManualPageTranslator
from sphinx.writers.texinfo import TexinfoTranslator
if hasattr(sys, 'intern'):
intern = sys.intern
@ -57,6 +62,15 @@ events = {
'build-finished': 'exception',
}
TRANSLATORS = {
'html': HTMLTranslator,
'latex': LaTeXTranslator,
'text:': TextTranslator,
'man': ManualPageTranslator,
'texinfo': TexinfoTranslator
}
CONFIG_FILENAME = 'conf.py'
ENV_PICKLE_FILENAME = 'environment.pickle'
@ -440,6 +454,12 @@ class Sphinx(object):
raise ExtensionError('Event %r already present' % name)
self._events[name] = ''
def add_translator(self, name, translator_class):
if name in TRANSLATORS:
raise ExtensionError('A Translator by the name '
'%s is already registered.' % name)
TRANSLATORS[name] = translator_class
def add_node(self, node, **kwds):
self.debug('[app] adding node: %r', (node, kwds))
nodes._add_node_class_names([node.__name__])
@ -449,20 +469,9 @@ class Sphinx(object):
except ValueError:
raise ExtensionError('Value for key %r must be a '
'(visit, depart) function tuple' % key)
if key == 'html':
from sphinx.writers.html import HTMLTranslator as translator
elif key == 'latex':
from sphinx.writers.latex import LaTeXTranslator as translator
elif key == 'text':
from sphinx.writers.text import TextTranslator as translator
elif key == 'man':
from sphinx.writers.manpage import ManualPageTranslator \
as translator
elif key == 'texinfo':
from sphinx.writers.texinfo import TexinfoTranslator \
as translator
else:
# ignore invalid keys for compatibility
translator = TRANSLATORS.get(key)
# ignore invalid keys for compatibility
if not translator:
continue
setattr(translator, 'visit_'+node.__name__, visit)
if depart: