diff options
author | Takeshi KOMIYA <i.tkomiya@gmail.com> | 2018-04-28 11:39:13 +0900 |
---|---|---|
committer | Takeshi KOMIYA <i.tkomiya@gmail.com> | 2018-04-28 12:56:01 +0900 |
commit | 622119a9d4e1294ce9718e490983edf58b50e6ac (patch) | |
tree | 6ce01e6f920033950142de62eb6b1ebdb507177e /sphinx/roles.py | |
parent | 93837bb01ecb185d8ee64b1f794f010c510b32e1 (diff) | |
download | sphinx-git-622119a9d4e1294ce9718e490983edf58b50e6ac.tar.gz |
Fix #789: ``:samp:`` role supports to escape curly braces with backslash
Diffstat (limited to 'sphinx/roles.py')
-rw-r--r-- | sphinx/roles.py | 47 |
1 files changed, 37 insertions, 10 deletions
diff --git a/sphinx/roles.py b/sphinx/roles.py index 2971c8fc3..453eb5aa0 100644 --- a/sphinx/roles.py +++ b/sphinx/roles.py @@ -284,6 +284,7 @@ def menusel_role(typ, rawtext, text, lineno, inliner, options={}, content=[]): _litvar_re = re.compile('{([^}]+)}') +parens_re = re.compile(r'(\\*{|\\*})') def emph_literal_role(typ, rawtext, text, lineno, inliner, @@ -296,17 +297,43 @@ def emph_literal_role(typ, rawtext, text, lineno, inliner, else: typ = typ.lower() - text = utils.unescape(text) - pos = 0 retnode = nodes.literal(role=typ.lower(), classes=[typ]) - for m in _litvar_re.finditer(text): # type: ignore - if m.start() > pos: - txt = text[pos:m.start()] - retnode += nodes.Text(txt, txt) - retnode += nodes.emphasis(m.group(1), m.group(1)) - pos = m.end() - if pos < len(text): - retnode += nodes.Text(text[pos:], text[pos:]) + parts = list(parens_re.split(utils.unescape(text))) + stack = [''] + for part in parts: + matched = parens_re.match(part) + if matched: + backslashes = len(part) - 1 + if backslashes % 2 == 1: # escaped + stack[-1] += "\\" * int((backslashes - 1) / 2) + part[-1] + elif part[-1] == '{': # rparen + stack[-1] += "\\" * int(backslashes / 2) + if len(stack) >= 2 and stack[-2] == "{": + # nested + stack[-1] += "{" + else: + # start emphasis + stack.append('{') + stack.append('') + else: # lparen + stack[-1] += "\\" * int(backslashes / 2) + if len(stack) == 3 and stack[1] == "{" and len(stack[2]) > 0: + # emphasized word found + if stack[0]: + retnode += nodes.Text(stack[0], stack[0]) + retnode += nodes.emphasis(stack[2], stack[2]) + stack = [''] + else: + # emphasized word not found; the rparen is not a special symbol + stack.append('}') + stack = [''.join(stack)] + else: + stack[-1] += part + if ''.join(stack): + # remaining is treated as Text + text = ''.join(stack) + retnode += nodes.Text(text, text) + return [retnode], [] |