summaryrefslogtreecommitdiff
path: root/sphinx/roles.py
diff options
context:
space:
mode:
authorTakeshi KOMIYA <i.tkomiya@gmail.com>2019-02-14 22:53:10 +0900
committerTakeshi KOMIYA <i.tkomiya@gmail.com>2019-02-16 12:37:46 +0900
commit3ec032fa39553570820c8d2ba62416561fa98d1a (patch)
treeeac09433edc20efb7f4d371599f41c4a9214a630 /sphinx/roles.py
parentcd360471c99defcb82a1215210a0155bffe0f83e (diff)
downloadsphinx-git-3ec032fa39553570820c8d2ba62416561fa98d1a.tar.gz
Replace :file: and :samp: roles by class based implementation
Diffstat (limited to 'sphinx/roles.py')
-rw-r--r--sphinx/roles.py59
1 files changed, 57 insertions, 2 deletions
diff --git a/sphinx/roles.py b/sphinx/roles.py
index db3feddc3..b7f2a99d6 100644
--- a/sphinx/roles.py
+++ b/sphinx/roles.py
@@ -393,6 +393,9 @@ parens_re = re.compile(r'(\\*{|\\*})')
def emph_literal_role(typ, rawtext, text, lineno, inliner,
options={}, content=[]):
# type: (str, str, str, int, Inliner, Dict, List[str]) -> Tuple[List[nodes.Node], List[nodes.system_message]] # NOQA
+ warnings.warn('emph_literal_role() is deprecated. '
+ 'Please use EmphasizedLiteral class instead.',
+ RemovedInSphinx40Warning, stacklevel=2)
env = inliner.document.settings.env
if not typ:
assert env.temp_data['default_role']
@@ -440,6 +443,58 @@ def emph_literal_role(typ, rawtext, text, lineno, inliner,
return [retnode], []
+class EmphasizedLiteral(SphinxRole):
+ parens_re = re.compile(r'(\\\\|\\{|\\}|{|})')
+
+ def run(self):
+ # type: () -> Tuple[List[nodes.Node], List[nodes.system_message]]
+ children = self.parse(self.text)
+ node = nodes.literal(self.rawtext, '', *children,
+ role=self.name.lower(), classes=[self.name])
+
+ return [node], []
+
+ def parse(self, text):
+ # type: (str) -> List[nodes.Node]
+ result = [] # type: List[nodes.Node]
+
+ stack = ['']
+ for part in self.parens_re.split(text):
+ if part == '\\\\': # escaped backslash
+ stack[-1] += '\\'
+ elif part == '{':
+ if len(stack) >= 2 and stack[-2] == "{": # nested
+ stack[-1] += "{"
+ else:
+ # start emphasis
+ stack.append('{')
+ stack.append('')
+ elif part == '}':
+ if len(stack) == 3 and stack[1] == "{" and len(stack[2]) > 0:
+ # emphasized word found
+ if stack[0]:
+ result.append(nodes.Text(stack[0], stack[0]))
+ result.append(nodes.emphasis(stack[2], stack[2]))
+ stack = ['']
+ else:
+ # emphasized word not found; the rparen is not a special symbol
+ stack.append('}')
+ stack = [''.join(stack)]
+ elif part == '\\{': # escaped left-brace
+ stack[-1] += '{'
+ elif part == '\\}': # escaped right-brace
+ stack[-1] += '}'
+ else: # others (containing escaped braces)
+ stack[-1] += part
+
+ if ''.join(stack):
+ # remaining is treated as Text
+ text = ''.join(stack)
+ result.append(nodes.Text(text, text))
+
+ return result
+
+
_abbr_re = re.compile(r'\((.*)\)$', re.S)
@@ -538,8 +593,8 @@ specific_docroles = {
'rfc': RFC(),
'guilabel': GUILabel(),
'menuselection': MenuSelection(),
- 'file': emph_literal_role,
- 'samp': emph_literal_role,
+ 'file': EmphasizedLiteral(),
+ 'samp': EmphasizedLiteral(),
'abbr': Abbreviation(),
'index': Index(),
} # type: Dict[str, RoleFunction]