mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Refactor directive/role lookup from domains a bit to avoid code duplication.
This commit is contained in:
parent
52d5411f6d
commit
68c545cf22
@ -284,7 +284,7 @@ class DefaultDomain(Directive):
|
|||||||
def run(self):
|
def run(self):
|
||||||
env = self.state.document.settings.env
|
env = self.state.document.settings.env
|
||||||
domain_name = arguments[0]
|
domain_name = arguments[0]
|
||||||
env.default_domain = env.domains.get(domain_name)
|
env.doc_read_data['default_domain'] = env.domains.get(domain_name)
|
||||||
|
|
||||||
|
|
||||||
directives.register_directive('default-domain', directive_dwim(DefaultDomain))
|
directives.register_directive('default-domain', directive_dwim(DefaultDomain))
|
||||||
|
@ -40,9 +40,39 @@ from sphinx.util import movefile, get_matching_docs, SEP, ustrftime, \
|
|||||||
docname_join, FilenameUniqDict, url_re, make_refnode
|
docname_join, FilenameUniqDict, url_re, make_refnode
|
||||||
from sphinx.errors import SphinxError, ExtensionError
|
from sphinx.errors import SphinxError, ExtensionError
|
||||||
|
|
||||||
|
|
||||||
orig_role_function = roles.role
|
orig_role_function = roles.role
|
||||||
orig_directive_function = directives.directive
|
orig_directive_function = directives.directive
|
||||||
|
|
||||||
|
class ElementLookupError(Exception): pass
|
||||||
|
|
||||||
|
def lookup_domain_element(env, 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 env.domains:
|
||||||
|
domain = 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 = env.doc_read_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(env.domains['std'], type)(name)
|
||||||
|
if element is not None:
|
||||||
|
return element, []
|
||||||
|
raise ElementLookupError
|
||||||
|
|
||||||
|
|
||||||
default_settings = {
|
default_settings = {
|
||||||
'embed_stylesheet': False,
|
'embed_stylesheet': False,
|
||||||
'cloak_email_addresses': True,
|
'cloak_email_addresses': True,
|
||||||
@ -538,6 +568,25 @@ class BuildEnvironment:
|
|||||||
error.object[error.end:lineend]), lineno)
|
error.object[error.end:lineend]), lineno)
|
||||||
return (u'?', error.end)
|
return (u'?', error.end)
|
||||||
|
|
||||||
|
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 lookup_domain_element(self, 'directive', name)
|
||||||
|
except ElementLookupError:
|
||||||
|
return orig_directive_function(name, lang_module, document)
|
||||||
|
|
||||||
|
def role(name, lang_module, lineno, reporter):
|
||||||
|
try:
|
||||||
|
return lookup_domain_element(self, 'role', name)
|
||||||
|
except ElementLookupError:
|
||||||
|
return orig_role_function(name, lang_module, lineno, reporter)
|
||||||
|
|
||||||
|
directives.directive = directive
|
||||||
|
roles.role = role
|
||||||
|
|
||||||
def read_doc(self, docname, src_path=None, save_parsed=True, app=None):
|
def read_doc(self, docname, src_path=None, save_parsed=True, app=None):
|
||||||
"""
|
"""
|
||||||
Parse a file and add/update inventory entries for the doctree.
|
Parse a file and add/update inventory entries for the doctree.
|
||||||
@ -562,11 +611,15 @@ class BuildEnvironment:
|
|||||||
self.config.default_role)
|
self.config.default_role)
|
||||||
|
|
||||||
self.doc_read_data['docname'] = docname
|
self.doc_read_data['docname'] = docname
|
||||||
|
# defaults to the global default, but can be re-set in a document
|
||||||
|
self.doc_read_data['default_domain'] = \
|
||||||
|
self.domains.get(self.config.default_domain)
|
||||||
|
|
||||||
self.settings['input_encoding'] = self.config.source_encoding
|
self.settings['input_encoding'] = self.config.source_encoding
|
||||||
self.settings['trim_footnote_reference_space'] = \
|
self.settings['trim_footnote_reference_space'] = \
|
||||||
self.config.trim_footnote_reference_space
|
self.config.trim_footnote_reference_space
|
||||||
|
|
||||||
codecs.register_error('sphinx', self.warn_and_replace)
|
self.patch_lookup_functions()
|
||||||
|
|
||||||
codecs.register_error('sphinx', self.warn_and_replace)
|
codecs.register_error('sphinx', self.warn_and_replace)
|
||||||
|
|
||||||
@ -585,61 +638,6 @@ class BuildEnvironment:
|
|||||||
else:
|
else:
|
||||||
return data
|
return data
|
||||||
|
|
||||||
# defaults to the global default, but can be re-set in a document
|
|
||||||
self.default_domain = self.domains.get(self.config.default_domain)
|
|
||||||
|
|
||||||
# monkey-patch, so that domain directives take precedence
|
|
||||||
def directive(directive_name, language_module, document):
|
|
||||||
"""Lookup a directive."""
|
|
||||||
directive_name = directive_name.lower()
|
|
||||||
# explicit domain given?
|
|
||||||
if ':' in directive_name:
|
|
||||||
domain_name, directive_name = directive_name.split(':', 1)
|
|
||||||
if domain_name in self.domains:
|
|
||||||
domain = self.domains[domain_name]
|
|
||||||
directive = domain.directive(directive_name)
|
|
||||||
if directive is not None:
|
|
||||||
return directive, []
|
|
||||||
# else look in the default domain
|
|
||||||
elif self.default_domain is not None:
|
|
||||||
directive = self.default_domain.directive(directive_name)
|
|
||||||
if directive is not None:
|
|
||||||
return directive, []
|
|
||||||
# always look in the std domain
|
|
||||||
# (XXX or register them in the docutils namespace?)
|
|
||||||
directive = self.domains['std'].directive(directive_name)
|
|
||||||
if directive is not None:
|
|
||||||
return directive, []
|
|
||||||
# last, look in the default docutils namespace
|
|
||||||
return orig_directive_function(directive_name, language_module,
|
|
||||||
document)
|
|
||||||
directives.directive = directive
|
|
||||||
|
|
||||||
def role(role_name, language_module, lineno, reporter):
|
|
||||||
"""Lookup a role name."""
|
|
||||||
role_name = role_name.lower()
|
|
||||||
# explicit domain given?
|
|
||||||
if ':' in role_name:
|
|
||||||
domain_name, role_name = role_name.split(':', 1)
|
|
||||||
if domain_name in self.domains:
|
|
||||||
domain = self.domains[domain_name]
|
|
||||||
role = domain.role(role_name)
|
|
||||||
if role is not None:
|
|
||||||
return role, []
|
|
||||||
# else look in the default domain
|
|
||||||
elif self.default_domain is not None:
|
|
||||||
role = self.default_domain.role(role_name)
|
|
||||||
if role is not None:
|
|
||||||
return role, []
|
|
||||||
# always look in the std domain
|
|
||||||
role = self.domains['std'].role(role_name)
|
|
||||||
if role is not None:
|
|
||||||
return role, []
|
|
||||||
# last, look in the default docutils namespace
|
|
||||||
return orig_role_function(role_name, language_module,
|
|
||||||
lineno, reporter)
|
|
||||||
roles.role = role
|
|
||||||
|
|
||||||
# publish manually
|
# publish manually
|
||||||
pub = Publisher(reader=SphinxStandaloneReader(),
|
pub = Publisher(reader=SphinxStandaloneReader(),
|
||||||
writer=SphinxDummyWriter(),
|
writer=SphinxDummyWriter(),
|
||||||
@ -654,6 +652,8 @@ class BuildEnvironment:
|
|||||||
doctree = pub.document
|
doctree = pub.document
|
||||||
except UnicodeError, err:
|
except UnicodeError, err:
|
||||||
raise SphinxError(str(err))
|
raise SphinxError(str(err))
|
||||||
|
|
||||||
|
# post-processing
|
||||||
self.filter_messages(doctree)
|
self.filter_messages(doctree)
|
||||||
self.process_dependencies(docname, doctree)
|
self.process_dependencies(docname, doctree)
|
||||||
self.process_images(docname, doctree)
|
self.process_images(docname, doctree)
|
||||||
@ -665,12 +665,13 @@ class BuildEnvironment:
|
|||||||
self.note_citations_from(docname, doctree)
|
self.note_citations_from(docname, doctree)
|
||||||
self.build_toc_from(docname, doctree)
|
self.build_toc_from(docname, doctree)
|
||||||
|
|
||||||
# store time of reading, used to find outdated files
|
# allow extension-specific post-processing
|
||||||
self.all_docs[docname] = time.time()
|
|
||||||
|
|
||||||
if app:
|
if app:
|
||||||
app.emit('doctree-read', doctree)
|
app.emit('doctree-read', doctree)
|
||||||
|
|
||||||
|
# store time of reading, used to find outdated files
|
||||||
|
self.all_docs[docname] = time.time()
|
||||||
|
|
||||||
# make it picklable
|
# make it picklable
|
||||||
doctree.reporter = None
|
doctree.reporter = None
|
||||||
doctree.transformer = None
|
doctree.transformer = None
|
||||||
@ -683,7 +684,6 @@ class BuildEnvironment:
|
|||||||
|
|
||||||
# cleanup
|
# cleanup
|
||||||
self.doc_read_data.clear()
|
self.doc_read_data.clear()
|
||||||
self.default_domain = None
|
|
||||||
|
|
||||||
if save_parsed:
|
if save_parsed:
|
||||||
# save the parsed doctree
|
# save the parsed doctree
|
||||||
|
@ -29,6 +29,7 @@ def setup_module():
|
|||||||
components=(rst.Parser, HTMLWriter, LaTeXWriter))
|
components=(rst.Parser, HTMLWriter, LaTeXWriter))
|
||||||
settings = optparser.get_default_values()
|
settings = optparser.get_default_values()
|
||||||
settings.env = app.builder.env
|
settings.env = app.builder.env
|
||||||
|
settings.env.patch_lookup_functions()
|
||||||
parser = rst.Parser()
|
parser = rst.Parser()
|
||||||
|
|
||||||
def teardown_module():
|
def teardown_module():
|
||||||
@ -60,7 +61,7 @@ def verify_re(rst, html_expected, latex_expected):
|
|||||||
html_translator = ForgivingHTMLTranslator(app.builder, document)
|
html_translator = ForgivingHTMLTranslator(app.builder, document)
|
||||||
document.walkabout(html_translator)
|
document.walkabout(html_translator)
|
||||||
html_translated = ''.join(html_translator.fragment).strip()
|
html_translated = ''.join(html_translator.fragment).strip()
|
||||||
assert re.match(html_expected, html_translated), 'from' + rst
|
assert re.match(html_expected, html_translated), 'from ' + rst
|
||||||
|
|
||||||
if latex_expected:
|
if latex_expected:
|
||||||
latex_translator = ForgivingLaTeXTranslator(document, app.builder)
|
latex_translator = ForgivingLaTeXTranslator(document, app.builder)
|
||||||
|
Loading…
Reference in New Issue
Block a user