Make domains instances, which have factory methods for their roles and directives.

This commit is contained in:
Georg Brandl 2009-07-13 16:59:45 +02:00
parent 92e29ad323
commit ab7cfb4a99
4 changed files with 56 additions and 17 deletions

View File

@ -23,7 +23,7 @@ import sphinx
from sphinx.roles import XRefRole from sphinx.roles import XRefRole
from sphinx.config import Config from sphinx.config import Config
from sphinx.errors import SphinxError, SphinxWarning, ExtensionError 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.builders import BUILTIN_BUILDERS
from sphinx.directives import GenericDesc, Target, additional_xref_types from sphinx.directives import GenericDesc, Target, additional_xref_types
from sphinx.environment import SphinxStandaloneReader from sphinx.environment import SphinxStandaloneReader
@ -104,6 +104,11 @@ class Sphinx(object):
# now that we know all config values, collect them from conf.py # now that we know all config values, collect them from conf.py
self.config.init_values() 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: if buildername is None:
print >>status, 'No builder selected, using default: html' print >>status, 'No builder selected, using default: html'
buildername = 'html' buildername = 'html'
@ -300,9 +305,9 @@ class Sphinx(object):
roles.register_local_role(name, role) roles.register_local_role(name, role)
def add_domain(self, domain): def add_domain(self, domain):
if domain.name in domains: if domain.name in all_domains:
raise ExtensionError('domain %s already registered' % domain.name) 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='', def add_description_unit(self, directivename, rolename, indextemplate='',
parse_node=None, ref_nodeclass=None): parse_node=None, ref_nodeclass=None):

View File

@ -366,7 +366,8 @@ 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 = 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 # Note: the target directive is not registered here, it is used by the

View File

@ -23,6 +23,36 @@ class Domain(object):
roles = {} roles = {}
label = '' 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 # REs for Python signatures
py_sig_re = re.compile( py_sig_re = re.compile(
@ -479,7 +509,7 @@ class CDomain(Domain):
# this contains all registered domains # this contains all registered domains
domains = { all_domains = {
'py': PythonDomain, 'py': PythonDomain,
'c': CDomain, 'c': CDomain,
} }

View File

@ -45,7 +45,6 @@ from sphinx import addnodes
from sphinx.util import movefile, get_matching_docs, SEP, ustrftime, \ from sphinx.util import movefile, get_matching_docs, SEP, ustrftime, \
docname_join, FilenameUniqDict, url_re docname_join, FilenameUniqDict, url_re
from sphinx.errors import SphinxError from sphinx.errors import SphinxError
from sphinx.domains import domains
from sphinx.directives import additional_xref_types from sphinx.directives import additional_xref_types
orig_role_function = roles.role orig_role_function = roles.role
@ -561,6 +560,7 @@ class BuildEnvironment:
# remove all inventory entries for that file # remove all inventory entries for that file
if app: if app:
app.emit('env-purge-doc', self, docname) app.emit('env-purge-doc', self, docname)
self.clear_doc(docname) self.clear_doc(docname)
if src_path is None: if src_path is None:
@ -600,18 +600,19 @@ class BuildEnvironment:
return data return data
# defaults to the global default, but can be re-set in a document # 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 # monkey-patch, so that domain directives take precedence
def directive(directive_name, language_module, document): def directive(directive_name, language_module, document):
if ':' in directive_name: if ':' in directive_name:
domain_name, directive_name = directive_name.split(':', 1) domain_name, directive_name = directive_name.split(':', 1)
if domain_name in domains: if domain_name in app.domains:
domain = domains[domain_name] domain = app.domains[domain_name]
if directive_name in domain.directives: directive = domain.directive(directive_name)
return domain.directives[directive_name], [] if directive is not None:
return directive, []
elif self.default_domain is not None: 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: if directive is not None:
return directive, [] return directive, []
return orig_directive_function(directive_name, language_module, return orig_directive_function(directive_name, language_module,
@ -621,12 +622,13 @@ class BuildEnvironment:
def role(role_name, language_module, lineno, reporter): def role(role_name, language_module, lineno, reporter):
if ':' in role_name: if ':' in role_name:
domain_name, role_name = role_name.split(':', 1) domain_name, role_name = role_name.split(':', 1)
if domain_name in domains: if domain_name in app.domains:
domain = domains[domain_name] domain = app.domains[domain_name]
if role_name in domain.roles: role = domain.role(role_name)
return domain.roles[role_name], [] if role is not None:
return role, []
elif self.default_domain is not None: 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: if role is not None:
return role, [] return role, []
return orig_role_function(role_name, language_module, return orig_role_function(role_name, language_module,
@ -678,6 +680,7 @@ class BuildEnvironment:
self.docname = None self.docname = None
self.currmodule = None self.currmodule = None
self.currclass = None self.currclass = None
self.default_domain = None
self.gloss_entries = set() self.gloss_entries = set()
if save_parsed: if save_parsed: