mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Move translators to SphinxFactory
This commit is contained in:
parent
f346e7dc1d
commit
78ea36a787
@ -146,7 +146,6 @@ class Sphinx(object):
|
||||
logging.setup(self, self._status, self._warning)
|
||||
|
||||
self.events = EventManager()
|
||||
self._translators = {} # type: Dict[unicode, nodes.GenericNodeVisitor]
|
||||
|
||||
# keep last few messages for traceback
|
||||
# This will be filled by sphinx.util.logging.LastMessagesWriter
|
||||
@ -515,9 +514,9 @@ class Sphinx(object):
|
||||
self.events.add(name)
|
||||
|
||||
def set_translator(self, name, translator_class):
|
||||
# type: (unicode, Any) -> None
|
||||
# type: (unicode, Type[nodes.NodeVisitor]) -> None
|
||||
logger.info(bold(_('A Translator for the %s builder is changed.') % name))
|
||||
self._translators[name] = translator_class
|
||||
self.factory.add_translator(name, translator_class)
|
||||
|
||||
def add_node(self, node, **kwds):
|
||||
# type: (nodes.Node, Any) -> None
|
||||
@ -535,7 +534,7 @@ class Sphinx(object):
|
||||
except ValueError:
|
||||
raise ExtensionError(_('Value for key %r must be a '
|
||||
'(visit, depart) function tuple') % key)
|
||||
translator = self._translators.get(key)
|
||||
translator = self.factory.translators.get(key)
|
||||
translators = []
|
||||
if translator is not None:
|
||||
translators.append(translator)
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
import os
|
||||
from os import path
|
||||
import warnings
|
||||
|
||||
try:
|
||||
import multiprocessing
|
||||
@ -20,6 +21,7 @@ except ImportError:
|
||||
from six import itervalues
|
||||
from docutils import nodes
|
||||
|
||||
from sphinx.deprecation import RemovedInSphinx20Warning
|
||||
from sphinx.util import i18n, path_stabilize, logging, status_iterator
|
||||
from sphinx.util.osutil import SEP, relative_uri
|
||||
from sphinx.util.i18n import find_catalog
|
||||
@ -53,6 +55,9 @@ class Builder(object):
|
||||
name = '' # type: unicode
|
||||
#: The builder's output format, or '' if no document output is produced.
|
||||
format = '' # type: unicode
|
||||
# default translator class for the builder. This will be overrided by
|
||||
# ``app.set_translator()``.
|
||||
default_translator_class = None # type: nodes.NodeVisitor
|
||||
# doctree versioning method
|
||||
versioning_method = 'none' # type: unicode
|
||||
versioning_compare = False
|
||||
@ -101,9 +106,6 @@ class Builder(object):
|
||||
self.parallel_ok = False
|
||||
self.finish_tasks = None # type: Any
|
||||
|
||||
# load default translator class
|
||||
self.translator_class = app._translators.get(self.name)
|
||||
|
||||
def set_environment(self, env):
|
||||
# type: (BuildEnvironment) -> None
|
||||
"""Store BuildEnvironment object."""
|
||||
@ -111,6 +113,38 @@ class Builder(object):
|
||||
self.env.set_versioning_method(self.versioning_method,
|
||||
self.versioning_compare)
|
||||
|
||||
def get_translator_class(self, *args):
|
||||
# type: (Any) -> nodes.NodeVisitor
|
||||
"""Return a class of translator."""
|
||||
return self.app.factory.get_translator_class(self)
|
||||
|
||||
def create_translator(self, *args):
|
||||
# type: (Any) -> nodes.NodeVisitor
|
||||
"""Return an instance of translator.
|
||||
|
||||
This method returns an instance of ``default_translator_class`` by default.
|
||||
Users can replace the translator class with ``app.set_translator()`` API.
|
||||
"""
|
||||
translator_class = self.app.factory.get_translator_class(self)
|
||||
assert translator_class, "translator not found for %s" % self.__class__.__name__
|
||||
return translator_class(*args)
|
||||
|
||||
@property
|
||||
def translator_class(self):
|
||||
# type: () -> Callable[[Any], nodes.NodeVisitor]
|
||||
"""Return a class of translator.
|
||||
|
||||
.. deprecated:: 1.6
|
||||
"""
|
||||
translator_class = self.app.factory.get_translator_class(self)
|
||||
if translator_class is None and self.default_translator_class is None:
|
||||
warnings.warn('builder.translator_class() is now deprecated. '
|
||||
'Please use builder.create_translator() and '
|
||||
'builder.default_translator_class instead.',
|
||||
RemovedInSphinx20Warning)
|
||||
return None
|
||||
return self.create_translator
|
||||
|
||||
# helper methods
|
||||
def init(self):
|
||||
# type: () -> None
|
||||
|
@ -158,7 +158,6 @@ class StandaloneHTMLBuilder(Builder):
|
||||
|
||||
self.init_templates()
|
||||
self.init_highlighter()
|
||||
self.init_translator_class()
|
||||
if self.config.html_file_suffix is not None:
|
||||
self.out_suffix = self.config.html_file_suffix
|
||||
|
||||
@ -218,23 +217,18 @@ class StandaloneHTMLBuilder(Builder):
|
||||
self.highlighter = PygmentsBridge('html', style,
|
||||
self.config.trim_doctest_flags)
|
||||
|
||||
def init_translator_class(self):
|
||||
# type: () -> None
|
||||
if self.translator_class is None:
|
||||
use_html5_writer = self.config.html_experimental_html5_writer
|
||||
if use_html5_writer is None:
|
||||
use_html5_writer = self.default_html5_translator and html5_ready
|
||||
|
||||
if use_html5_writer and html5_ready:
|
||||
if self.config.html_use_smartypants:
|
||||
self.translator_class = SmartyPantsHTML5Translator
|
||||
else:
|
||||
self.translator_class = HTML5Translator
|
||||
@property
|
||||
def default_translator_class(self):
|
||||
if self.config.html_experimental_html5_writer and html5_ready:
|
||||
if self.config.html_use_smartypants:
|
||||
return SmartyPantsHTML5Translator
|
||||
else:
|
||||
if self.config.html_use_smartypants:
|
||||
self.translator_class = SmartyPantsHTMLTranslator
|
||||
else:
|
||||
self.translator_class = HTMLTranslator
|
||||
return HTML5Translator
|
||||
else:
|
||||
if self.config.html_use_smartypants:
|
||||
return SmartyPantsHTMLTranslator
|
||||
else:
|
||||
return HTMLTranslator
|
||||
|
||||
def get_outdated_docs(self):
|
||||
# type: () -> Iterator[unicode]
|
||||
@ -1200,7 +1194,6 @@ class SerializingHTMLBuilder(StandaloneHTMLBuilder):
|
||||
self.current_docname = None
|
||||
self.theme = None # no theme necessary
|
||||
self.templates = None # no template bridge necessary
|
||||
self.init_translator_class()
|
||||
self.init_templates()
|
||||
self.init_highlighter()
|
||||
self.use_index = self.get_builder_config('use_index', 'html')
|
||||
|
@ -31,7 +31,7 @@ from sphinx.util.nodes import inline_all_toctrees
|
||||
from sphinx.util.fileutil import copy_asset_file
|
||||
from sphinx.util.osutil import SEP, make_filename
|
||||
from sphinx.util.console import bold, darkgreen # type: ignore
|
||||
from sphinx.writers.latex import LaTeXWriter
|
||||
from sphinx.writers.latex import LaTeXWriter, LaTeXTranslator
|
||||
|
||||
if False:
|
||||
# For type annotation
|
||||
@ -51,6 +51,7 @@ class LaTeXBuilder(Builder):
|
||||
format = 'latex'
|
||||
supported_image_types = ['application/pdf', 'image/png', 'image/jpeg']
|
||||
supported_remote_images = False
|
||||
default_translator_class = LaTeXTranslator
|
||||
|
||||
def init(self):
|
||||
# type: () -> None
|
||||
|
@ -23,7 +23,7 @@ from sphinx.util import logging
|
||||
from sphinx.util.nodes import inline_all_toctrees
|
||||
from sphinx.util.osutil import make_filename
|
||||
from sphinx.util.console import bold, darkgreen # type: ignore
|
||||
from sphinx.writers.manpage import ManualPageWriter
|
||||
from sphinx.writers.manpage import ManualPageWriter, ManualPageTranslator
|
||||
|
||||
if False:
|
||||
# For type annotation
|
||||
@ -40,6 +40,7 @@ class ManualPageBuilder(Builder):
|
||||
"""
|
||||
name = 'man'
|
||||
format = 'man'
|
||||
default_translator_class = ManualPageTranslator
|
||||
supported_image_types = [] # type: List[unicode]
|
||||
|
||||
def init(self):
|
||||
|
@ -27,7 +27,7 @@ from sphinx.util.fileutil import copy_asset_file
|
||||
from sphinx.util.nodes import inline_all_toctrees
|
||||
from sphinx.util.osutil import SEP, make_filename
|
||||
from sphinx.util.console import bold, darkgreen # type: ignore
|
||||
from sphinx.writers.texinfo import TexinfoWriter
|
||||
from sphinx.writers.texinfo import TexinfoWriter, TexinfoTranslator
|
||||
|
||||
if False:
|
||||
# For type annotation
|
||||
@ -99,6 +99,7 @@ class TexinfoBuilder(Builder):
|
||||
format = 'texinfo'
|
||||
supported_image_types = ['image/png', 'image/jpeg',
|
||||
'image/gif']
|
||||
default_translator_class = TexinfoTranslator
|
||||
|
||||
def init(self):
|
||||
# type: () -> None
|
||||
|
@ -17,7 +17,7 @@ from docutils.io import StringOutput
|
||||
from sphinx.builders import Builder
|
||||
from sphinx.util import logging
|
||||
from sphinx.util.osutil import ensuredir, os_path
|
||||
from sphinx.writers.text import TextWriter
|
||||
from sphinx.writers.text import TextWriter, TextTranslator
|
||||
|
||||
if False:
|
||||
# For type annotation
|
||||
@ -33,6 +33,7 @@ class TextBuilder(Builder):
|
||||
format = 'text'
|
||||
out_suffix = '.txt'
|
||||
allow_parallel = True
|
||||
default_translator_class = TextTranslator
|
||||
|
||||
current_docname = None # type: unicode
|
||||
|
||||
|
@ -34,6 +34,7 @@ class WebSupportBuilder(PickleHTMLBuilder):
|
||||
name = 'websupport'
|
||||
versioning_method = 'commentable'
|
||||
versioning_compare = True # for commentable node's uuid stability.
|
||||
default_translator_class = WebSupportTranslator
|
||||
|
||||
def init(self):
|
||||
# type: () -> None
|
||||
@ -54,11 +55,6 @@ class WebSupportBuilder(PickleHTMLBuilder):
|
||||
self.search = search
|
||||
self.storage = storage
|
||||
|
||||
def init_translator_class(self):
|
||||
# type: () -> None
|
||||
if self.translator_class is None:
|
||||
self.translator_class = WebSupportTranslator
|
||||
|
||||
def prepare_writing(self, docnames):
|
||||
# type: (Iterable[unicode]) -> None
|
||||
PickleHTMLBuilder.prepare_writing(self, docnames)
|
||||
|
@ -14,6 +14,7 @@ from os import path
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.io import StringOutput
|
||||
from docutils.writers.docutils_xml import XMLTranslator
|
||||
|
||||
from sphinx.builders import Builder
|
||||
from sphinx.util import logging
|
||||
@ -38,6 +39,7 @@ class XMLBuilder(Builder):
|
||||
allow_parallel = True
|
||||
|
||||
_writer_class = XMLWriter
|
||||
default_translator_class = XMLTranslator
|
||||
|
||||
def init(self):
|
||||
# type: () -> None
|
||||
|
@ -39,6 +39,7 @@ class SphinxFactory(object):
|
||||
self.builders = {} # type: Dict[unicode, Type[Builder]]
|
||||
self.domains = {} # type: Dict[unicode, Type[Domain]]
|
||||
self.source_parsers = {} # type: Dict[unicode, Parser]
|
||||
self.translators = {} # type: Dict[unicode, nodes.NodeVisitor]
|
||||
|
||||
def add_builder(self, builder):
|
||||
# type: (Type[Builder]) -> None
|
||||
@ -152,3 +153,17 @@ class SphinxFactory(object):
|
||||
def get_source_parsers(self):
|
||||
# type: () -> Dict[unicode, Parser]
|
||||
return self.source_parsers
|
||||
|
||||
def add_translator(self, name, translator):
|
||||
# type: (unicode, Type[nodes.NodeVisitor]) -> None
|
||||
self.translators[name] = translator
|
||||
|
||||
def get_translator_class(self, builder):
|
||||
# type: (Builder) -> Type[nodes.NodeVisitor]
|
||||
return self.translators.get(builder.name,
|
||||
builder.default_translator_class)
|
||||
|
||||
def create_translator(self, builder, document):
|
||||
# type: (Builder, nodes.Node) -> nodes.NodeVisitor
|
||||
translator_class = self.get_translator_class(builder)
|
||||
return translator_class(builder, document)
|
||||
|
@ -52,8 +52,8 @@ class HTMLWriter(Writer):
|
||||
def translate(self):
|
||||
# type: () -> None
|
||||
# sadly, this is mostly copied from parent class
|
||||
self.visitor = visitor = self.builder.translator_class(self.builder,
|
||||
self.document)
|
||||
self.visitor = visitor = self.builder.create_translator(self.builder,
|
||||
self.document)
|
||||
self.document.walkabout(visitor)
|
||||
self.output = visitor.astext()
|
||||
for attr in ('head_prefix', 'stylesheet', 'head', 'body_prefix',
|
||||
|
@ -159,14 +159,12 @@ class LaTeXWriter(writers.Writer):
|
||||
# type: (Builder) -> None
|
||||
writers.Writer.__init__(self)
|
||||
self.builder = builder
|
||||
self.translator_class = (
|
||||
self.builder.translator_class or LaTeXTranslator)
|
||||
|
||||
def translate(self):
|
||||
# type: () -> None
|
||||
transform = ShowUrlsTransform(self.document)
|
||||
transform.apply()
|
||||
visitor = self.translator_class(self.document, self.builder)
|
||||
visitor = self.builder.create_translator(self.document, self.builder)
|
||||
self.document.walkabout(visitor)
|
||||
self.output = visitor.astext()
|
||||
|
||||
|
@ -35,14 +35,12 @@ class ManualPageWriter(Writer):
|
||||
# type: (Builder) -> None
|
||||
Writer.__init__(self)
|
||||
self.builder = builder
|
||||
self.translator_class = (
|
||||
self.builder.translator_class or ManualPageTranslator)
|
||||
|
||||
def translate(self):
|
||||
# type: () -> None
|
||||
transform = NestedInlineTransform(self.document)
|
||||
transform.apply()
|
||||
visitor = self.translator_class(self.builder, self.document)
|
||||
visitor = self.builder.create_translator(self.builder, self.document)
|
||||
self.visitor = visitor
|
||||
self.document.walkabout(visitor)
|
||||
self.output = visitor.astext()
|
||||
|
@ -133,13 +133,10 @@ class TexinfoWriter(writers.Writer):
|
||||
# type: (TexinfoBuilder) -> None
|
||||
writers.Writer.__init__(self)
|
||||
self.builder = builder
|
||||
self.translator_class = (
|
||||
self.builder.translator_class or TexinfoTranslator)
|
||||
|
||||
def translate(self):
|
||||
# type: () -> None
|
||||
self.visitor = visitor = self.translator_class(
|
||||
self.document, self.builder)
|
||||
self.visitor = visitor = self.builder.create_translator(self.document, self.builder)
|
||||
self.document.walkabout(visitor)
|
||||
visitor.finish()
|
||||
for attr in self.visitor_attributes:
|
||||
|
@ -159,11 +159,10 @@ class TextWriter(writers.Writer):
|
||||
# type: (TextBuilder) -> None
|
||||
writers.Writer.__init__(self)
|
||||
self.builder = builder
|
||||
self.translator_class = self.builder.translator_class or TextTranslator
|
||||
|
||||
def translate(self):
|
||||
# type: () -> None
|
||||
visitor = self.translator_class(self.document, self.builder)
|
||||
visitor = self.builder.create_translator(self.document, self.builder)
|
||||
self.document.walkabout(visitor)
|
||||
self.output = visitor.body
|
||||
|
||||
|
@ -24,8 +24,7 @@ class XMLWriter(BaseXMLWriter):
|
||||
# type: (Builder) -> None
|
||||
BaseXMLWriter.__init__(self)
|
||||
self.builder = builder
|
||||
if self.builder.translator_class:
|
||||
self.translator_class = self.builder.translator_class
|
||||
self.translator_class = self.builder.get_translator_class()
|
||||
|
||||
def translate(self, *args, **kwargs):
|
||||
# type: (Any, Any) -> None
|
||||
|
@ -26,7 +26,7 @@ def teardown_module():
|
||||
@pytest.mark.sphinx('html')
|
||||
def test_html_translator(app, status, warning):
|
||||
# no set_translator()
|
||||
translator_class = app.builder.translator_class
|
||||
translator_class = app.builder.get_translator_class()
|
||||
assert translator_class
|
||||
assert translator_class.__name__ == 'SmartyPantsHTMLTranslator'
|
||||
|
||||
@ -35,7 +35,7 @@ def test_html_translator(app, status, warning):
|
||||
'html_use_smartypants': False})
|
||||
def test_html_with_smartypants(app, status, warning):
|
||||
# no set_translator(), html_use_smartypants=False
|
||||
translator_class = app.builder.translator_class
|
||||
translator_class = app.builder.get_translator_class()
|
||||
assert translator_class
|
||||
assert translator_class.__name__ == 'HTMLTranslator'
|
||||
|
||||
@ -43,7 +43,7 @@ def test_html_with_smartypants(app, status, warning):
|
||||
@pytest.mark.sphinx('html', testroot='api-set-translator')
|
||||
def test_html_with_set_translator_for_html_(app, status, warning):
|
||||
# use set_translator()
|
||||
translator_class = app.builder.translator_class
|
||||
translator_class = app.builder.get_translator_class()
|
||||
assert translator_class
|
||||
assert translator_class.__name__ == 'ConfHTMLTranslator'
|
||||
|
||||
@ -61,62 +61,62 @@ def test_html_with_set_translator_for_html_(app, status, warning):
|
||||
|
||||
@pytest.mark.sphinx('singlehtml', testroot='api-set-translator')
|
||||
def test_singlehtml_set_translator_for_singlehtml(app, status, warning):
|
||||
translator_class = app.builder.translator_class
|
||||
translator_class = app.builder.get_translator_class()
|
||||
assert translator_class
|
||||
assert translator_class.__name__ == 'ConfSingleHTMLTranslator'
|
||||
|
||||
|
||||
@pytest.mark.sphinx('pickle', testroot='api-set-translator')
|
||||
def test_pickle_set_translator_for_pickle(app, status, warning):
|
||||
translator_class = app.builder.translator_class
|
||||
translator_class = app.builder.get_translator_class()
|
||||
assert translator_class
|
||||
assert translator_class.__name__ == 'ConfPickleTranslator'
|
||||
|
||||
|
||||
@pytest.mark.sphinx('json', testroot='api-set-translator')
|
||||
def test_json_set_translator_for_json(app, status, warning):
|
||||
translator_class = app.builder.translator_class
|
||||
translator_class = app.builder.get_translator_class()
|
||||
assert translator_class
|
||||
assert translator_class.__name__ == 'ConfJsonTranslator'
|
||||
|
||||
|
||||
@pytest.mark.sphinx('latex', testroot='api-set-translator')
|
||||
def test_html_with_set_translator_for_latex(app, status, warning):
|
||||
translator_class = app.builder.translator_class
|
||||
translator_class = app.builder.get_translator_class()
|
||||
assert translator_class
|
||||
assert translator_class.__name__ == 'ConfLaTeXTranslator'
|
||||
|
||||
|
||||
@pytest.mark.sphinx('man', testroot='api-set-translator')
|
||||
def test_html_with_set_translator_for_man(app, status, warning):
|
||||
translator_class = app.builder.translator_class
|
||||
translator_class = app.builder.get_translator_class()
|
||||
assert translator_class
|
||||
assert translator_class.__name__ == 'ConfManualPageTranslator'
|
||||
|
||||
|
||||
@pytest.mark.sphinx('texinfo', testroot='api-set-translator')
|
||||
def test_html_with_set_translator_for_texinfo(app, status, warning):
|
||||
translator_class = app.builder.translator_class
|
||||
translator_class = app.builder.get_translator_class()
|
||||
assert translator_class
|
||||
assert translator_class.__name__ == 'ConfTexinfoTranslator'
|
||||
|
||||
|
||||
@pytest.mark.sphinx('text', testroot='api-set-translator')
|
||||
def test_html_with_set_translator_for_text(app, status, warning):
|
||||
translator_class = app.builder.translator_class
|
||||
translator_class = app.builder.get_translator_class()
|
||||
assert translator_class
|
||||
assert translator_class.__name__ == 'ConfTextTranslator'
|
||||
|
||||
|
||||
@pytest.mark.sphinx('xml', testroot='api-set-translator')
|
||||
def test_html_with_set_translator_for_xml(app, status, warning):
|
||||
translator_class = app.builder.translator_class
|
||||
translator_class = app.builder.get_translator_class()
|
||||
assert translator_class
|
||||
assert translator_class.__name__ == 'ConfXMLTranslator'
|
||||
|
||||
|
||||
@pytest.mark.sphinx('pseudoxml', testroot='api-set-translator')
|
||||
def test_html_with_set_translator_for_pseudoxml(app, status, warning):
|
||||
translator_class = app.builder.translator_class
|
||||
translator_class = app.builder.get_translator_class()
|
||||
assert translator_class
|
||||
assert translator_class.__name__ == 'ConfPseudoXMLTranslator'
|
||||
|
Loading…
Reference in New Issue
Block a user