mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Add app.set_translator() API to register or override a Docutils translator class like :confval:html_translator_class
.
This commit is contained in:
parent
2e1c16486c
commit
f7399a261a
2
CHANGES
2
CHANGES
@ -43,6 +43,8 @@ Features added
|
||||
* PR#255: When generating latex references, also insert latex target/anchor
|
||||
for the ids defined on the node. Thanks to Olivier Heurtier.
|
||||
* PR#229: Allow registration of other translators. Thanks to Russell Sim.
|
||||
* Add app.set_translator() API to register or override a Docutils translator
|
||||
class like :confval:`html_translator_class`.
|
||||
|
||||
Bugs fixed
|
||||
----------
|
||||
|
@ -706,6 +706,8 @@ that use Sphinx's HTMLWriter class.
|
||||
used to translate document trees to HTML. Default is ``None`` (use the
|
||||
builtin translator).
|
||||
|
||||
.. seealso:: :meth:`~sphinx.application.Sphinx.set_translator`
|
||||
|
||||
.. confval:: html_show_copyright
|
||||
|
||||
If true, "(C) Copyright ..." is shown in the HTML footer. Default is
|
||||
|
@ -82,13 +82,17 @@ package.
|
||||
|
||||
Register an event called *name*. This is needed to be able to emit it.
|
||||
|
||||
.. method:: Sphinx.add_translator(name, translator_class)
|
||||
.. method:: Sphinx.set_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.
|
||||
Register or override a Docutils translator class. This is used to register
|
||||
a custom output translator or to replace a builtin translator.
|
||||
This allows extensions to use custom translator and define custom
|
||||
nodes for the translator (see :meth:`add_node`).
|
||||
|
||||
This is a API version of :confval:`html_translator_class` for all other
|
||||
builders. Note that if :confval:`html_translator_class` is specified and
|
||||
this API is called for html related builders, API overriding takes
|
||||
precedence.
|
||||
|
||||
.. versionadded:: 1.3
|
||||
|
||||
|
@ -99,8 +99,7 @@ class Sphinx(object):
|
||||
self.warningiserror = warningiserror
|
||||
|
||||
self._events = events.copy()
|
||||
self._translators = dict.fromkeys([
|
||||
'html', 'latex', 'text', 'man', 'texinfo'])
|
||||
self._translators = {}
|
||||
|
||||
# say hello to the world
|
||||
self.info(bold('Running Sphinx v%s' % sphinx.__version__))
|
||||
@ -451,10 +450,8 @@ class Sphinx(object):
|
||||
raise ExtensionError('Event %r already present' % name)
|
||||
self._events[name] = ''
|
||||
|
||||
def add_translator(self, name, translator_class):
|
||||
if name in self._translators:
|
||||
raise ExtensionError('A Translator by the name '
|
||||
'%s is already registered.' % name)
|
||||
def set_translator(self, name, translator_class):
|
||||
self.info(bold('A Translator for the %s builder is changed.' % name))
|
||||
self._translators[name] = translator_class
|
||||
|
||||
def add_node(self, node, **kwds):
|
||||
|
@ -65,6 +65,9 @@ class Builder(object):
|
||||
# images that need to be copied over (source -> dest)
|
||||
self.images = {}
|
||||
|
||||
# load default translator class
|
||||
self.translator_class = app._translators.get(self.name)
|
||||
|
||||
self.init()
|
||||
|
||||
# helper methods
|
||||
|
@ -152,7 +152,9 @@ class StandaloneHTMLBuilder(Builder):
|
||||
self.config.trim_doctest_flags)
|
||||
|
||||
def init_translator_class(self):
|
||||
if self.config.html_translator_class:
|
||||
if self.translator_class is not None:
|
||||
pass
|
||||
elif self.config.html_translator_class:
|
||||
self.translator_class = self.app.import_object(
|
||||
self.config.html_translator_class,
|
||||
'html_translator_class setting')
|
||||
|
@ -46,7 +46,8 @@ class WebSupportBuilder(PickleHTMLBuilder):
|
||||
self.storage = storage
|
||||
|
||||
def init_translator_class(self):
|
||||
self.translator_class = WebSupportTranslator
|
||||
if self.translator_class is None:
|
||||
self.translator_class = WebSupportTranslator
|
||||
|
||||
def prepare_writing(self, docnames):
|
||||
PickleHTMLBuilder.prepare_writing(self, docnames)
|
||||
|
@ -89,9 +89,11 @@ class LaTeXWriter(writers.Writer):
|
||||
def __init__(self, builder):
|
||||
writers.Writer.__init__(self)
|
||||
self.builder = builder
|
||||
self.translator_class = (
|
||||
self.builder.translator_class or LaTeXTranslator)
|
||||
|
||||
def translate(self):
|
||||
visitor = LaTeXTranslator(self.document, self.builder)
|
||||
visitor = self.translator_class(self.document, self.builder)
|
||||
self.document.walkabout(visitor)
|
||||
self.output = visitor.astext()
|
||||
|
||||
|
@ -26,9 +26,11 @@ class ManualPageWriter(Writer):
|
||||
def __init__(self, builder):
|
||||
Writer.__init__(self)
|
||||
self.builder = builder
|
||||
self.translator_class = (
|
||||
self.builder.translator_class or ManualPageTranslator)
|
||||
|
||||
def translate(self):
|
||||
visitor = ManualPageTranslator(self.builder, self.document)
|
||||
visitor = self.translator_class(self.builder, self.document)
|
||||
self.visitor = visitor
|
||||
self.document.walkabout(visitor)
|
||||
self.output = visitor.astext()
|
||||
|
@ -120,9 +120,12 @@ class TexinfoWriter(writers.Writer):
|
||||
def __init__(self, builder):
|
||||
writers.Writer.__init__(self)
|
||||
self.builder = builder
|
||||
self.translator_class = (
|
||||
self.builder.translator_class or TexinfoTranslator)
|
||||
|
||||
def translate(self):
|
||||
self.visitor = visitor = TexinfoTranslator(self.document, self.builder)
|
||||
self.visitor = visitor = self.translator_class(
|
||||
self.document, self.builder)
|
||||
self.document.walkabout(visitor)
|
||||
visitor.finish()
|
||||
for attr in self.visitor_attributes:
|
||||
|
@ -140,9 +140,10 @@ class TextWriter(writers.Writer):
|
||||
def __init__(self, builder):
|
||||
writers.Writer.__init__(self)
|
||||
self.builder = builder
|
||||
self.translator_class = self.builder.translator_class or TextTranslator
|
||||
|
||||
def translate(self):
|
||||
visitor = TextTranslator(self.document, self.builder)
|
||||
visitor = self.translator_class(self.document, self.builder)
|
||||
self.document.walkabout(visitor)
|
||||
self.output = visitor.body
|
||||
|
||||
|
@ -18,6 +18,8 @@ class XMLWriter(BaseXMLWriter):
|
||||
def __init__(self, builder):
|
||||
BaseXMLWriter.__init__(self)
|
||||
self.builder = builder
|
||||
if self.builder.translator_class:
|
||||
self.translator_class = self.builder.translator_class
|
||||
|
||||
def translate(self, *args, **kwargs):
|
||||
self.document.settings.newlines = \
|
||||
|
82
tests/roots/test-api-set-translator/conf.py
Normal file
82
tests/roots/test-api-set-translator/conf.py
Normal file
@ -0,0 +1,82 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
from sphinx.writers.html import HTMLTranslator
|
||||
from sphinx.writers.latex import LaTeXTranslator
|
||||
from sphinx.writers.manpage import ManualPageTranslator
|
||||
from sphinx.writers.texinfo import TexinfoTranslator
|
||||
from sphinx.writers.text import TextTranslator
|
||||
from sphinx.writers.websupport import WebSupportTranslator
|
||||
from docutils.writers.docutils_xml import XMLTranslator
|
||||
|
||||
|
||||
sys.path.insert(0, os.path.abspath('.'))
|
||||
|
||||
|
||||
project = 'test'
|
||||
master_doc = 'index'
|
||||
|
||||
|
||||
class ConfHTMLTranslator(HTMLTranslator):
|
||||
pass
|
||||
|
||||
|
||||
class ConfDirHTMLTranslator(HTMLTranslator):
|
||||
pass
|
||||
|
||||
|
||||
class ConfSingleHTMLTranslator(HTMLTranslator):
|
||||
pass
|
||||
|
||||
|
||||
class ConfPickleTranslator(HTMLTranslator):
|
||||
pass
|
||||
|
||||
|
||||
class ConfJsonTranslator(HTMLTranslator):
|
||||
pass
|
||||
|
||||
|
||||
class ConfLaTeXTranslator(LaTeXTranslator):
|
||||
pass
|
||||
|
||||
|
||||
class ConfManualPageTranslator(ManualPageTranslator):
|
||||
pass
|
||||
|
||||
|
||||
class ConfTexinfoTranslator(TexinfoTranslator):
|
||||
pass
|
||||
|
||||
|
||||
class ConfTextTranslator(TextTranslator):
|
||||
pass
|
||||
|
||||
|
||||
class ConfWebSupportTranslator(WebSupportTranslator):
|
||||
pass
|
||||
|
||||
|
||||
class ConfXMLTranslator(XMLTranslator):
|
||||
pass
|
||||
|
||||
|
||||
class ConfPseudoXMLTranslator(XMLTranslator):
|
||||
pass
|
||||
|
||||
|
||||
def setup(app):
|
||||
app.set_translator('html', ConfHTMLTranslator)
|
||||
app.set_translator('dirhtml', ConfDirHTMLTranslator)
|
||||
app.set_translator('singlehtml', ConfSingleHTMLTranslator)
|
||||
app.set_translator('pickle', ConfPickleTranslator)
|
||||
app.set_translator('json', ConfJsonTranslator)
|
||||
app.set_translator('latex', ConfLaTeXTranslator)
|
||||
app.set_translator('man', ConfManualPageTranslator)
|
||||
app.set_translator('texinfo', ConfTexinfoTranslator)
|
||||
app.set_translator('text', ConfTextTranslator)
|
||||
app.set_translator('websupport', ConfWebSupportTranslator)
|
||||
app.set_translator('xml', ConfXMLTranslator)
|
||||
app.set_translator('pseudoxml', ConfPseudoXMLTranslator)
|
3
tests/roots/test-api-set-translator/index.rst
Normal file
3
tests/roots/test-api-set-translator/index.rst
Normal file
@ -0,0 +1,3 @@
|
||||
=======================
|
||||
Test API set_translator
|
||||
=======================
|
9
tests/roots/test-api-set-translator/nonext/conf.py
Normal file
9
tests/roots/test-api-set-translator/nonext/conf.py
Normal file
@ -0,0 +1,9 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
sys.path.insert(0, os.path.dirname(os.path.abspath('.')))
|
||||
|
||||
project = 'test'
|
||||
master_doc = 'index'
|
6
tests/roots/test-api-set-translator/translator.py
Normal file
6
tests/roots/test-api-set-translator/translator.py
Normal file
@ -0,0 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from sphinx.writers.html import HTMLTranslator
|
||||
|
||||
class ExtHTMLTranslator(HTMLTranslator):
|
||||
pass
|
185
tests/test_api_translator.py
Normal file
185
tests/test_api_translator.py
Normal file
@ -0,0 +1,185 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
test_api_translator
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Test the Sphinx API for translator.
|
||||
|
||||
:copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS.
|
||||
:license: BSD, see LICENSE for details.
|
||||
"""
|
||||
|
||||
from util import with_app, test_roots
|
||||
|
||||
|
||||
@with_app(
|
||||
buildername='html',
|
||||
srcdir=(test_roots / 'test-api-set-translator'),
|
||||
confdir=(test_roots / 'test-api-set-translator' / 'nonext'),
|
||||
)
|
||||
def test_html_translator(app):
|
||||
# no set_translator(), no html_translator_class
|
||||
translator_class = app.builder.translator_class
|
||||
assert translator_class
|
||||
assert translator_class.__name__ == 'SmartyPantsHTMLTranslator'
|
||||
|
||||
|
||||
@with_app(
|
||||
buildername='html',
|
||||
srcdir=(test_roots / 'test-api-set-translator'),
|
||||
confdir=(test_roots / 'test-api-set-translator' / 'nonext'),
|
||||
confoverrides={
|
||||
'html_translator_class': 'translator.ExtHTMLTranslator'},
|
||||
)
|
||||
def test_html_with_html_translator_class(app):
|
||||
# no set_translator(), but html_translator_class
|
||||
translator_class = app.builder.translator_class
|
||||
assert translator_class
|
||||
assert translator_class.__name__ == 'ExtHTMLTranslator'
|
||||
|
||||
|
||||
@with_app(
|
||||
buildername='html',
|
||||
srcdir=(test_roots / 'test-api-set-translator'),
|
||||
confdir=(test_roots / 'test-api-set-translator' / 'nonext'),
|
||||
confoverrides={'html_use_smartypants': False},
|
||||
)
|
||||
def test_html_with_smartypants(app):
|
||||
# no set_translator(), html_use_smartypants=False
|
||||
translator_class = app.builder.translator_class
|
||||
assert translator_class
|
||||
assert translator_class.__name__ == 'HTMLTranslator'
|
||||
|
||||
|
||||
@with_app(
|
||||
buildername='html',
|
||||
srcdir=(test_roots / 'test-api-set-translator'),
|
||||
)
|
||||
def test_html_with_set_translator_for_html_(app):
|
||||
# use set_translator(), no html_translator_class
|
||||
translator_class = app.builder.translator_class
|
||||
assert translator_class
|
||||
assert translator_class.__name__ == 'ConfHTMLTranslator'
|
||||
|
||||
|
||||
@with_app(
|
||||
buildername='html',
|
||||
srcdir=(test_roots / 'test-api-set-translator'),
|
||||
confoverrides={'html_translator_class': 'ext.ExtHTMLTranslator'},
|
||||
)
|
||||
def test_html_with_set_translator_for_html_and_html_translator_class(app):
|
||||
# use set_translator() and html_translator_class.
|
||||
# set_translator() is given priority over html_translator_clas.
|
||||
translator_class = app.builder.translator_class
|
||||
assert translator_class
|
||||
assert translator_class.__name__ == 'ConfHTMLTranslator'
|
||||
|
||||
|
||||
@with_app(
|
||||
buildername='dirhtml',
|
||||
srcdir=(test_roots / 'test-api-set-translator'),
|
||||
)
|
||||
def test_dirhtml_set_translator_for_dirhtml(app):
|
||||
translator_class = app.builder.translator_class
|
||||
assert translator_class
|
||||
assert translator_class.__name__ == 'ConfDirHTMLTranslator'
|
||||
|
||||
|
||||
@with_app(
|
||||
buildername='singlehtml',
|
||||
srcdir=(test_roots / 'test-api-set-translator'),
|
||||
)
|
||||
def test_singlehtml_set_translator_for_singlehtml(app):
|
||||
translator_class = app.builder.translator_class
|
||||
assert translator_class
|
||||
assert translator_class.__name__ == 'ConfSingleHTMLTranslator'
|
||||
|
||||
|
||||
@with_app(
|
||||
buildername='pickle',
|
||||
srcdir=(test_roots / 'test-api-set-translator'),
|
||||
)
|
||||
def test_pickle_set_translator_for_pickle(app):
|
||||
translator_class = app.builder.translator_class
|
||||
assert translator_class
|
||||
assert translator_class.__name__ == 'ConfPickleTranslator'
|
||||
|
||||
|
||||
@with_app(
|
||||
buildername='json',
|
||||
srcdir=(test_roots / 'test-api-set-translator'),
|
||||
)
|
||||
def test_json_set_translator_for_json(app):
|
||||
translator_class = app.builder.translator_class
|
||||
assert translator_class
|
||||
assert translator_class.__name__ == 'ConfJsonTranslator'
|
||||
|
||||
|
||||
@with_app(
|
||||
buildername='latex',
|
||||
srcdir=(test_roots / 'test-api-set-translator'),
|
||||
)
|
||||
def test_html_with_set_translator_for_latex(app):
|
||||
translator_class = app.builder.translator_class
|
||||
assert translator_class
|
||||
assert translator_class.__name__ == 'ConfLaTeXTranslator'
|
||||
|
||||
|
||||
@with_app(
|
||||
buildername='man',
|
||||
srcdir=(test_roots / 'test-api-set-translator'),
|
||||
)
|
||||
def test_html_with_set_translator_for_man(app):
|
||||
translator_class = app.builder.translator_class
|
||||
assert translator_class
|
||||
assert translator_class.__name__ == 'ConfManualPageTranslator'
|
||||
|
||||
|
||||
@with_app(
|
||||
buildername='texinfo',
|
||||
srcdir=(test_roots / 'test-api-set-translator'),
|
||||
)
|
||||
def test_html_with_set_translator_for_texinfo(app):
|
||||
translator_class = app.builder.translator_class
|
||||
assert translator_class
|
||||
assert translator_class.__name__ == 'ConfTexinfoTranslator'
|
||||
|
||||
|
||||
@with_app(
|
||||
buildername='text',
|
||||
srcdir=(test_roots / 'test-api-set-translator'),
|
||||
)
|
||||
def test_html_with_set_translator_for_text(app):
|
||||
translator_class = app.builder.translator_class
|
||||
assert translator_class
|
||||
assert translator_class.__name__ == 'ConfTextTranslator'
|
||||
|
||||
|
||||
@with_app(
|
||||
buildername='websupport',
|
||||
srcdir=(test_roots / 'test-api-set-translator'),
|
||||
)
|
||||
def test_html_with_set_translator_for_websupport(app):
|
||||
translator_class = app.builder.translator_class
|
||||
assert translator_class
|
||||
assert translator_class.__name__ == 'ConfWebSupportTranslator'
|
||||
|
||||
|
||||
@with_app(
|
||||
buildername='xml',
|
||||
srcdir=(test_roots / 'test-api-set-translator'),
|
||||
)
|
||||
def test_html_with_set_translator_for_xml(app):
|
||||
translator_class = app.builder.translator_class
|
||||
assert translator_class
|
||||
assert translator_class.__name__ == 'ConfXMLTranslator'
|
||||
|
||||
|
||||
@with_app(
|
||||
buildername='pseudoxml',
|
||||
srcdir=(test_roots / 'test-api-set-translator'),
|
||||
)
|
||||
def test_html_with_set_translator_for_pseudoxml(app):
|
||||
translator_class = app.builder.translator_class
|
||||
assert translator_class
|
||||
assert translator_class.__name__ == 'ConfPseudoXMLTranslator'
|
Loading…
Reference in New Issue
Block a user