diff options
Diffstat (limited to 'sphinx/util/docutils.py')
-rw-r--r-- | sphinx/util/docutils.py | 71 |
1 files changed, 71 insertions, 0 deletions
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) |