summaryrefslogtreecommitdiff
path: root/sphinx/util/docutils.py
diff options
context:
space:
mode:
Diffstat (limited to 'sphinx/util/docutils.py')
-rw-r--r--sphinx/util/docutils.py71
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)