33from 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 )
0 commit comments