1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
|
# -*- coding: utf-8 -*-
"""
sphinx.util.docutils
~~~~~~~~~~~~~~~~~~~~
Utility functions for docutils.
:copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
from __future__ import absolute_import
from copy import copy
from contextlib import contextmanager
from docutils.parsers.rst import directives, roles
@contextmanager
def docutils_namespace():
"""Create namespace for reST parsers."""
try:
_directives = copy(directives._directives)
_roles = copy(roles._roles)
yield
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)
|