Skip to content

Commit 4633b9b

Browse files
committed
👌 IMPROVE: susbstitution; configurable delimiters
1 parent d873fc2 commit 4633b9b

2 files changed

Lines changed: 77 additions & 71 deletions

File tree

‎mdit_py_plugins/substitution.py‎

Lines changed: 75 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
from markdown_it.rules_block import StateBlock
44

55

6-
def substitution_plugin(md: MarkdownIt):
6+
def substitution_plugin(
7+
md: MarkdownIt, start_delimiter: str = "{", end_delimiter: str = "}"
8+
):
79
"""A plugin to create substitution tokens.
810
911
These, token should be handled by the renderer.
@@ -15,93 +17,97 @@ def substitution_plugin(md: MarkdownIt):
1517
a {{ inline }} b
1618
1719
"""
18-
md.block.ruler.before("fence", "substitution_block", _substitution_block)
19-
md.inline.ruler.before("escape", "substitution_inline", _substitution_inline)
2020

21+
start_char = ord(start_delimiter)
22+
end_char = ord(end_delimiter)
2123

22-
def _substitution_inline(state: StateInline, silent: bool):
23-
try:
24-
if (
25-
state.srcCharCode[state.pos] != 0x7B # /* { */
26-
or state.srcCharCode[state.pos + 1] != 0x7B
27-
):
28-
return False
29-
except IndexError:
30-
return False
31-
32-
pos = state.pos + 2
33-
found_closing = False
34-
while True:
24+
def _substitution_inline(state: StateInline, silent: bool):
3525
try:
36-
end = state.srcCharCode.index(0x7D, pos) # /* } */
37-
except ValueError:
38-
return False
39-
try:
40-
if state.srcCharCode[end + 1] == 0x7D:
41-
found_closing = True
42-
break
26+
if (
27+
state.srcCharCode[state.pos] != start_char
28+
or state.srcCharCode[state.pos + 1] != start_char
29+
):
30+
return False
4331
except IndexError:
4432
return False
45-
pos = end + 2
4633

47-
if not found_closing:
48-
return False
34+
pos = state.pos + 2
35+
found_closing = False
36+
while True:
37+
try:
38+
end = state.srcCharCode.index(end_char, pos)
39+
except ValueError:
40+
return False
41+
try:
42+
if state.srcCharCode[end + 1] == end_char:
43+
found_closing = True
44+
break
45+
except IndexError:
46+
return False
47+
pos = end + 2
48+
49+
if not found_closing:
50+
return False
4951

50-
text = state.src[state.pos + 2 : end].strip()
51-
state.pos = end + 2
52+
text = state.src[state.pos + 2 : end].strip()
53+
state.pos = end + 2
5254

53-
if silent:
54-
return True
55+
if silent:
56+
return True
5557

56-
token = state.push("substitution_inline", "span", 0)
57-
token.block = False
58-
token.content = text
59-
token.attrSet("class", "substitution")
60-
token.attrSet("text", text)
61-
token.markup = "{{"
58+
token = state.push("substitution_inline", "span", 0)
59+
token.block = False
60+
token.content = text
61+
token.attrSet("class", "substitution")
62+
token.attrSet("text", text)
63+
token.markup = f"{start_delimiter}{end_delimiter}"
6264

63-
return True
65+
return True
6466

67+
def _substitution_block(
68+
state: StateBlock, startLine: int, endLine: int, silent: bool
69+
):
70+
startPos = state.bMarks[startLine] + state.tShift[startLine]
71+
end = state.eMarks[startLine]
6572

66-
def _substitution_block(state: StateBlock, startLine: int, endLine: int, silent: bool):
67-
startPos = state.bMarks[startLine] + state.tShift[startLine]
68-
end = state.eMarks[startLine]
73+
# if it's indented more than 3 spaces, it should be a code block
74+
if state.sCount[startLine] - state.blkIndent >= 4:
75+
return False
76+
77+
lineText = state.src[startPos:end].strip()
6978

70-
# if it's indented more than 3 spaces, it should be a code block
71-
if state.sCount[startLine] - state.blkIndent >= 4:
72-
return False
79+
try:
80+
if (
81+
lineText[0] != start_delimiter
82+
or lineText[1] != start_delimiter
83+
or lineText[-1] != end_delimiter
84+
or lineText[-2] != end_delimiter
85+
or len(lineText) < 5
86+
):
87+
return False
88+
except IndexError:
89+
return False
7390

74-
lineText = state.src[startPos:end].strip()
91+
text = lineText[2:-2].strip()
7592

76-
try:
77-
if (
78-
lineText[0] != "{"
79-
or lineText[1] != "{"
80-
or lineText[-1] != "}"
81-
or lineText[-2] != "}"
82-
or len(lineText) < 5
83-
):
93+
# special case if multiple on same line, e.g. {{a}}{{b}}
94+
if (end_delimiter * 2) in text:
8495
return False
85-
except IndexError:
86-
return False
8796

88-
text = lineText[2:-2].strip()
97+
state.line = startLine + 1
8998

90-
# special case if multiple on same line, e.g. {{a}}{{b}}
91-
if "}}" in text:
92-
return False
99+
if silent:
100+
return True
93101

94-
state.line = startLine + 1
102+
token = state.push("substitution_block", "div", 0)
103+
token.block = True
104+
token.content = text
105+
token.attrSet("class", "substitution")
106+
token.attrSet("text", text)
107+
token.markup = f"{start_delimiter}{end_delimiter}"
108+
token.map = [startLine, state.line]
95109

96-
if silent:
97110
return True
98111

99-
token = state.push("substitution_block", "div", 0)
100-
token.block = True
101-
token.content = text
102-
token.attrSet("class", "substitution")
103-
token.attrSet("text", text)
104-
token.markup = "{{"
105-
token.map = [startLine, state.line]
106-
107-
return True
112+
md.block.ruler.before("fence", "substitution_block", _substitution_block)
113+
md.inline.ruler.before("escape", "substitution_inline", _substitution_inline)

‎tests/test_substitution/test_tokens.yml‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
map:
1313
- 0
1414
- 1
15-
markup: '{{'
15+
markup: '{}'
1616
meta: {}
1717
nesting: 0
1818
tag: div
@@ -60,7 +60,7 @@
6060
info: ''
6161
level: 0
6262
map: null
63-
markup: '{{'
63+
markup: '{}'
6464
meta: {}
6565
nesting: 0
6666
tag: span

0 commit comments

Comments
 (0)