Skip to content

Commit 65f73e0

Browse files
authored
👌 IMPROVE: MyST role syntax parsing (#32)
Match characters instead of using regex. This now allows for an unlimited name length and new lines in the content.
1 parent fc130fa commit 65f73e0

File tree

2 files changed

+64
-14
lines changed

2 files changed

+64
-14
lines changed

‎mdit_py_plugins/myst_role/index.py

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from markdown_it.common.utils import escapeHtml
55
from markdown_it.rules_inline import StateInline
66

7-
PATTERN = re.compile(r"^\{([a-zA-Z0-9\_\-\+\:]{1,36})\}(`+)(?!`)(.+?)(?<!`)\2(?!`)")
7+
VALID_NAME_PATTERN = re.compile(r"^\{([a-zA-Z0-9\_\-\+\:]+)\}")
88

99

1010
def myst_role_plugin(md: MarkdownIt):
@@ -14,22 +14,45 @@ def myst_role_plugin(md: MarkdownIt):
1414

1515

1616
def myst_role(state: StateInline, silent: bool):
17+
18+
# check name
19+
match = VALID_NAME_PATTERN.match(state.src[state.pos :])
20+
if not match:
21+
return False
22+
name = match.group(1)
23+
24+
# check for starting backslash escape
1725
try:
1826
if state.srcCharCode[state.pos - 1] == 0x5C: # /* \ */
1927
# escaped (this could be improved in the case of edge case '\\{')
2028
return False
2129
except IndexError:
2230
pass
2331

24-
match = PATTERN.search(state.src[state.pos :])
32+
# scan opening tick length
33+
start = pos = state.pos + match.end()
34+
try:
35+
while state.src[pos] == "`":
36+
pos += 1
37+
except IndexError:
38+
return False
39+
40+
tick_length = pos - start
41+
if not tick_length:
42+
return False
43+
44+
# search for closing ticks
45+
match = re.search("`" * tick_length, state.src[pos + 1 :])
2546
if not match:
2647
return False
27-
state.pos += match.end()
48+
content = state.src[pos : pos + match.start() + 1].replace("\n", " ")
2849

2950
if not silent:
3051
token = state.push("myst_role", "", 0)
31-
token.meta = {"name": match.group(1)}
32-
token.content = match.group(3)
52+
token.meta = {"name": name}
53+
token.content = content
54+
55+
state.pos = pos + match.end() + 1
3356

3457
return True
3558

@@ -38,7 +61,5 @@ def render_myst_role(self, tokens, idx, options, env):
3861
token = tokens[idx]
3962
name = token.meta.get("name", "unknown")
4063
return (
41-
'<code class="sphinx-role">'
42-
f"{{{name}}}[{escapeHtml(token.content)}]"
43-
"</code>"
64+
'<code class="myst role">' f"{{{name}}}[{escapeHtml(token.content)}]" "</code>"
4465
)

‎tests/fixtures/myst_role.md

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,30 @@ Basic:
33
.
44
{abc}`xyz`
55
.
6-
<p><code class="sphinx-role">{abc}[xyz]</code></p>
6+
<p><code class="myst role">{abc}[xyz]</code></p>
7+
.
8+
9+
Multiple:
10+
.
11+
{abc}`xyz`{def}`uvw`
12+
.
13+
<p><code class="myst role">{abc}[xyz]</code><code class="myst role">{def}[uvw]</code></p>
714
.
815

916
Surrounding Text:
1017
.
1118
a {abc}`xyz` b
1219
.
13-
<p>a <code class="sphinx-role">{abc}[xyz]</code> b</p>
20+
<p>a <code class="myst role">{abc}[xyz]</code> b</p>
21+
.
22+
23+
New lines:
24+
.
25+
{abc}`xy
26+
z` `d
27+
e`
28+
.
29+
<p><code class="myst role">{abc}[xy z]</code> <code>d e</code></p>
1430
.
1531

1632
In Code:
@@ -20,20 +36,26 @@ In Code:
2036
<p><code>{abc}`xyz`</code></p>
2137
.
2238

39+
Empty content:
40+
.
41+
{name}`` a
42+
.
43+
<p>{name}`` a</p>
44+
.
2345

2446
Surrounding Code:
2547
.
2648
`a` {abc}`xyz` `b`
2749
.
28-
<p><code>a</code> <code class="sphinx-role">{abc}[xyz]</code> <code>b</code></p>
50+
<p><code>a</code> <code class="myst role">{abc}[xyz]</code> <code>b</code></p>
2951
.
3052

3153
In list:
3254
.
3355
- {abc}`xyz`
3456
.
3557
<ul>
36-
<li><code class="sphinx-role">{abc}[xyz]</code></li>
58+
<li><code class="myst role">{abc}[xyz]</code></li>
3759
</ul>
3860
.
3961

@@ -42,15 +64,22 @@ In Quote:
4264
> {abc}`xyz` b
4365
.
4466
<blockquote>
45-
<p><code class="sphinx-role">{abc}[xyz]</code> b</p>
67+
<p><code class="myst role">{abc}[xyz]</code> b</p>
4668
</blockquote>
4769
.
4870

4971
Multiple ticks:
5072
.
5173
{abc}``xyz``
5274
.
53-
<p><code class="sphinx-role">{abc}[xyz]</code></p>
75+
<p><code class="myst role">{abc}[xyz]</code></p>
76+
.
77+
78+
Inner tick:
79+
.
80+
{abc}``x`yz``
81+
.
82+
<p><code class="myst role">{abc}[x`yz]</code></p>
5483
.
5584

5685
Unbalanced ticks:

0 commit comments

Comments
 (0)