mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Make domains instances, which have factory methods for their roles and directives.
This commit is contained in:
parent
92e29ad323
commit
ab7cfb4a99
@ -23,7 +23,7 @@ import sphinx
|
||||
from sphinx.roles import XRefRole
|
||||
from sphinx.config import Config
|
||||
from sphinx.errors import SphinxError, SphinxWarning, ExtensionError
|
||||
from sphinx.domains import domains
|
||||
from sphinx.domains import all_domains
|
||||
from sphinx.builders import BUILTIN_BUILDERS
|
||||
from sphinx.directives import GenericDesc, Target, additional_xref_types
|
||||
from sphinx.environment import SphinxStandaloneReader
|
||||
@ -104,6 +104,11 @@ class Sphinx(object):
|
||||
# now that we know all config values, collect them from conf.py
|
||||
self.config.init_values()
|
||||
|
||||
# intialize domains
|
||||
self.domains = {}
|
||||
for domain in all_domains.keys():
|
||||
self.domains[domain] = all_domains[domain](self)
|
||||
|
||||
if buildername is None:
|
||||
print >>status, 'No builder selected, using default: html'
|
||||
buildername = 'html'
|
||||
@ -300,9 +305,9 @@ class Sphinx(object):
|
||||
roles.register_local_role(name, role)
|
||||
|
||||
def add_domain(self, domain):
|
||||
if domain.name in domains:
|
||||
if domain.name in all_domains:
|
||||
raise ExtensionError('domain %s already registered' % domain.name)
|
||||
domains[domain.name] = domain
|
||||
all_domains[domain.name] = domain
|
||||
|
||||
def add_description_unit(self, directivename, rolename, indextemplate='',
|
||||
parse_node=None, ref_nodeclass=None):
|
||||
|
@ -366,7 +366,8 @@ class DefaultDomain(Directive):
|
||||
def run(self):
|
||||
env = self.state.document.settings.env
|
||||
domain_name = arguments[0]
|
||||
env.default_domain = domains.get(domain_name)
|
||||
# XXX won't work
|
||||
env.default_domain = env.domains.get(domain_name)
|
||||
|
||||
|
||||
# Note: the target directive is not registered here, it is used by the
|
||||
|
@ -23,6 +23,36 @@ class Domain(object):
|
||||
roles = {}
|
||||
label = ''
|
||||
|
||||
def __init__(self, app):
|
||||
self.app = app
|
||||
self._role_cache = {}
|
||||
self._directive_cache = {}
|
||||
|
||||
def role(self, name):
|
||||
if name in self._role_cache:
|
||||
return self._role_cache[name]
|
||||
if name not in self.roles:
|
||||
return None
|
||||
def role_adapter(typ, rawtext, text, lineno, inliner,
|
||||
options={}, content=[]):
|
||||
return self.roles[name](name, rawtext, text, lineno,
|
||||
inliner, options, content)
|
||||
self._role_cache[name] = role_adapter
|
||||
return role_adapter
|
||||
|
||||
def directive(self, name):
|
||||
if name in self._directive_cache:
|
||||
return self._directive_cache[name]
|
||||
if name not in self.directives:
|
||||
return None
|
||||
BaseDirective = self.directives[name]
|
||||
class DirectiveAdapter(BaseDirective):
|
||||
def run(self):
|
||||
self.name = name
|
||||
return BaseDirective.run(self)
|
||||
self._directive_cache[name] = DirectiveAdapter
|
||||
return DirectiveAdapter
|
||||
|
||||
|
||||
# REs for Python signatures
|
||||
py_sig_re = re.compile(
|
||||
@ -479,7 +509,7 @@ class CDomain(Domain):
|
||||
|
||||
|
||||
# this contains all registered domains
|
||||
domains = {
|
||||
all_domains = {
|
||||
'py': PythonDomain,
|
||||
'c': CDomain,
|
||||
}
|
||||
|
@ -45,7 +45,6 @@ from sphinx import addnodes
|
||||
from sphinx.util import movefile, get_matching_docs, SEP, ustrftime, \
|
||||
docname_join, FilenameUniqDict, url_re
|
||||
from sphinx.errors import SphinxError
|
||||
from sphinx.domains import domains
|
||||
from sphinx.directives import additional_xref_types
|
||||
|
||||
orig_role_function = roles.role
|
||||
@ -561,6 +560,7 @@ class BuildEnvironment:
|
||||
# remove all inventory entries for that file
|
||||
if app:
|
||||
app.emit('env-purge-doc', self, docname)
|
||||
|
||||
self.clear_doc(docname)
|
||||
|
||||
if src_path is None:
|
||||
@ -600,18 +600,19 @@ class BuildEnvironment:
|
||||
return data
|
||||
|
||||
# defaults to the global default, but can be re-set in a document
|
||||
self.default_domain = domains.get(self.config.default_domain)
|
||||
self.default_domain = app.domains.get(self.config.default_domain)
|
||||
|
||||
# monkey-patch, so that domain directives take precedence
|
||||
def directive(directive_name, language_module, document):
|
||||
if ':' in directive_name:
|
||||
domain_name, directive_name = directive_name.split(':', 1)
|
||||
if domain_name in domains:
|
||||
domain = domains[domain_name]
|
||||
if directive_name in domain.directives:
|
||||
return domain.directives[directive_name], []
|
||||
if domain_name in app.domains:
|
||||
domain = app.domains[domain_name]
|
||||
directive = domain.directive(directive_name)
|
||||
if directive is not None:
|
||||
return directive, []
|
||||
elif self.default_domain is not None:
|
||||
directive = self.default_domain.directives.get(directive_name)
|
||||
directive = self.default_domain.directive(directive_name)
|
||||
if directive is not None:
|
||||
return directive, []
|
||||
return orig_directive_function(directive_name, language_module,
|
||||
@ -621,12 +622,13 @@ class BuildEnvironment:
|
||||
def role(role_name, language_module, lineno, reporter):
|
||||
if ':' in role_name:
|
||||
domain_name, role_name = role_name.split(':', 1)
|
||||
if domain_name in domains:
|
||||
domain = domains[domain_name]
|
||||
if role_name in domain.roles:
|
||||
return domain.roles[role_name], []
|
||||
if domain_name in app.domains:
|
||||
domain = app.domains[domain_name]
|
||||
role = domain.role(role_name)
|
||||
if role is not None:
|
||||
return role, []
|
||||
elif self.default_domain is not None:
|
||||
role = self.default_domain.roles.get(role_name)
|
||||
role = self.default_domain.role(role_name)
|
||||
if role is not None:
|
||||
return role, []
|
||||
return orig_role_function(role_name, language_module,
|
||||
@ -678,6 +680,7 @@ class BuildEnvironment:
|
||||
self.docname = None
|
||||
self.currmodule = None
|
||||
self.currclass = None
|
||||
self.default_domain = None
|
||||
self.gloss_entries = set()
|
||||
|
||||
if save_parsed:
|
||||
|
Loading…
Reference in New Issue
Block a user