summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakeshi KOMIYA <i.tkomiya@gmail.com>2016-09-09 13:37:00 +0900
committerTakeshi KOMIYA <i.tkomiya@gmail.com>2016-09-21 10:48:52 +0900
commit50bf7960bd8aff516d0536b8c944896857d2ba71 (patch)
tree4c8d565e61f1fc06c5eaab8842568b7a82a87573
parent7863468683030dc42fe638d0ed3ed78cfd4546c9 (diff)
downloadsphinx-git-50bf7960bd8aff516d0536b8c944896857d2ba71.tar.gz
Uninstall sphinx directives and roles of domains after build
-rw-r--r--sphinx/environment.py110
-rw-r--r--sphinx/util/docutils.py71
-rw-r--r--tests/test_markup.py9
3 files changed, 106 insertions, 84 deletions
diff --git a/sphinx/environment.py b/sphinx/environment.py
index e2d446acc..02b041050 100644
--- a/sphinx/environment.py
+++ b/sphinx/environment.py
@@ -29,7 +29,7 @@ from docutils import nodes
from docutils.io import NullOutput
from docutils.core import Publisher
from docutils.utils import Reporter, relative_path, get_source_line
-from docutils.parsers.rst import roles, directives
+from docutils.parsers.rst import roles
from docutils.parsers.rst.languages import en as english
from docutils.frontend import OptionParser
@@ -43,6 +43,7 @@ from sphinx.util.images import guess_mimetype
from sphinx.util.i18n import find_catalog_files, get_image_filename_for_language, \
search_image_for_language
from sphinx.util.console import bold, purple
+from sphinx.util.docutils import sphinx_domains
from sphinx.util.matching import compile_matchers
from sphinx.util.parallel import ParallelTasks, parallel_available, make_chunks
from sphinx.util.websupport import is_commentable
@@ -51,13 +52,6 @@ from sphinx.locale import _
from sphinx.versioning import add_uids, merge_doctrees
from sphinx.transforms import SphinxContentsFilter
-orig_role_function = roles.role
-orig_directive_function = directives.directive
-
-
-class ElementLookupError(Exception):
- pass
-
default_settings = {
'embed_stylesheet': False,
@@ -634,51 +628,6 @@ class BuildEnvironment(object):
error.object[error.end:lineend]), lineno)
return (u'?', error.end)
- def lookup_domain_element(self, type, name):
- """Lookup a markup element (directive or role), given its name which can
- be a full name (with domain).
- """
- name = name.lower()
- # explicit domain given?
- if ':' in name:
- domain_name, name = name.split(':', 1)
- if domain_name in self.domains:
- domain = self.domains[domain_name]
- element = getattr(domain, type)(name)
- if element is not None:
- return element, []
- # else look in the default domain
- else:
- def_domain = self.temp_data.get('default_domain')
- if def_domain is not None:
- element = getattr(def_domain, type)(name)
- if element is not None:
- return element, []
- # always look in the std domain
- element = getattr(self.domains['std'], type)(name)
- if element is not None:
- return element, []
- raise ElementLookupError
-
- def patch_lookup_functions(self):
- """Monkey-patch directive and role dispatch, so that domain-specific
- markup takes precedence.
- """
- def directive(name, lang_module, document):
- try:
- return self.lookup_domain_element('directive', name)
- except ElementLookupError:
- return orig_directive_function(name, lang_module, document)
-
- def role(name, lang_module, lineno, reporter):
- try:
- return self.lookup_domain_element('role', name)
- except ElementLookupError:
- return orig_role_function(name, lang_module, lineno, reporter)
-
- directives.directive = directive
- roles.role = role
-
def read_doc(self, docname, app=None):
"""Parse a file and add/update inventory entries for the doctree."""
@@ -692,40 +641,39 @@ class BuildEnvironment(object):
self.config.trim_footnote_reference_space
self.settings['gettext_compact'] = self.config.gettext_compact
- self.patch_lookup_functions()
-
docutilsconf = path.join(self.srcdir, 'docutils.conf')
# read docutils.conf from source dir, not from current dir
OptionParser.standard_config_files[1] = docutilsconf
if path.isfile(docutilsconf):
self.note_dependency(docutilsconf)
- if self.config.default_role:
- role_fn, messages = roles.role(self.config.default_role, english,
- 0, dummy_reporter)
- if role_fn:
- roles._roles[''] = role_fn
- else:
- self.warn(docname, 'default role %s not found' %
- self.config.default_role)
-
- codecs.register_error('sphinx', self.warn_and_replace)
-
- # publish manually
- reader = SphinxStandaloneReader(self.app, parsers=self.config.source_parsers)
- pub = Publisher(reader=reader,
- writer=SphinxDummyWriter(),
- destination_class=NullOutput)
- pub.set_components(None, 'restructuredtext', None)
- pub.process_programmatic_settings(None, self.settings, None)
- src_path = self.doc2path(docname)
- source = SphinxFileInput(app, self, source=None, source_path=src_path,
- encoding=self.config.source_encoding)
- pub.source = source
- pub.settings._source = src_path
- pub.set_destination(None, None)
- pub.publish()
- doctree = pub.document
+ with sphinx_domains(self):
+ if self.config.default_role:
+ role_fn, messages = roles.role(self.config.default_role, english,
+ 0, dummy_reporter)
+ if role_fn:
+ roles._roles[''] = role_fn
+ else:
+ self.warn(docname, 'default role %s not found' %
+ self.config.default_role)
+
+ codecs.register_error('sphinx', self.warn_and_replace)
+
+ # publish manually
+ reader = SphinxStandaloneReader(self.app, parsers=self.config.source_parsers)
+ pub = Publisher(reader=reader,
+ writer=SphinxDummyWriter(),
+ destination_class=NullOutput)
+ pub.set_components(None, 'restructuredtext', None)
+ pub.process_programmatic_settings(None, self.settings, None)
+ src_path = self.doc2path(docname)
+ source = SphinxFileInput(app, self, source=None, source_path=src_path,
+ encoding=self.config.source_encoding)
+ pub.source = source
+ pub.settings._source = src_path
+ pub.set_destination(None, None)
+ pub.publish()
+ doctree = pub.document
# post-processing
self.process_dependencies(docname, doctree)
diff --git a/sphinx/util/docutils.py b/sphinx/util/docutils.py
index f39f62a9f..be9e2edad 100644
--- a/sphinx/util/docutils.py
+++ b/sphinx/util/docutils.py
@@ -26,3 +26,74 @@ def docutils_namespace():
finally:
directives._directives = _directives
roles._roles = _roles
+
+
+class ElementLookupError(Exception):
+ pass
+
+
+class sphinx_domains(object):
+ """Monkey-patch directive and role dispatch, so that domain-specific
+ markup takes precedence.
+ """
+ def __init__(self, env):
+ self.env = env
+ self.directive_func = None
+ self.roles_func = None
+
+ def __enter__(self):
+ self.enable()
+
+ def __exit__(self, type, value, traceback):
+ self.disable()
+
+ def enable(self):
+ self.directive_func = directives.directive
+ self.role_func = roles.role
+
+ directives.directive = self.lookup_directive
+ roles.role = self.lookup_role
+
+ def disable(self):
+ directives.directive = self.directive_func
+ roles.role = self.role_func
+
+ def lookup_domain_element(self, type, name):
+ """Lookup a markup element (directive or role), given its name which can
+ be a full name (with domain).
+ """
+ name = name.lower()
+ # explicit domain given?
+ if ':' in name:
+ domain_name, name = name.split(':', 1)
+ if domain_name in self.env.domains:
+ domain = self.env.domains[domain_name]
+ element = getattr(domain, type)(name)
+ if element is not None:
+ return element, []
+ # else look in the default domain
+ else:
+ def_domain = self.env.temp_data.get('default_domain')
+ if def_domain is not None:
+ element = getattr(def_domain, type)(name)
+ if element is not None:
+ return element, []
+
+ # always look in the std domain
+ element = getattr(self.env.domains['std'], type)(name)
+ if element is not None:
+ return element, []
+
+ raise ElementLookupError
+
+ def lookup_directive(self, name, lang_module, document):
+ try:
+ return self.lookup_domain_element('directive', name)
+ except ElementLookupError:
+ return self.directive_func(name, lang_module, document)
+
+ def lookup_role(self, name, lang_module, lineno, reporter):
+ try:
+ return self.lookup_domain_element('role', name)
+ except ElementLookupError:
+ return self.role_func(name, lang_module, lineno, reporter)
diff --git a/tests/test_markup.py b/tests/test_markup.py
index 133f187d3..ec203447f 100644
--- a/tests/test_markup.py
+++ b/tests/test_markup.py
@@ -17,30 +17,33 @@ from docutils.parsers import rst
from sphinx import addnodes
from sphinx.util import texescape
+from sphinx.util.docutils import sphinx_domains
from sphinx.writers.html import HTMLWriter, SmartyPantsHTMLTranslator
from sphinx.writers.latex import LaTeXWriter, LaTeXTranslator
from util import TestApp, with_app, assert_node
-app = settings = parser = None
+app = settings = parser = domain_context = None
def setup_module():
- global app, settings, parser
+ global app, settings, parser, domain_context
texescape.init() # otherwise done by the latex builder
app = TestApp()
optparser = frontend.OptionParser(
components=(rst.Parser, HTMLWriter, LaTeXWriter))
settings = optparser.get_default_values()
settings.env = app.builder.env
- settings.env.patch_lookup_functions()
settings.env.temp_data['docname'] = 'dummy'
parser = rst.Parser()
+ domain_context = sphinx_domains(settings.env)
+ domain_context.enable()
def teardown_module():
app.cleanup()
+ domain_context.disable()
# since we're not resolving the markup afterwards, these nodes may remain