66
77def processDelimiters (state : StateInline , delimiters : list [Delimiter ]) -> None :
88 """For each opening emphasis-like marker find a matching closing one."""
9+ if not delimiters :
10+ return
11+
912 openersBottom = {}
1013 maximum = len (delimiters )
1114
15+ # headerIdx is the first delimiter of the current (where closer is) delimiter run
16+ headerIdx = 0
17+ lastTokenIdx = - 2 # needs any value lower than -1
18+ jumps : list [int ] = []
1219 closerIdx = 0
1320 while closerIdx < maximum :
1421 closer = delimiters [closerIdx ]
1522
23+ jumps .append (0 )
24+
25+ # markers belong to same delimiter run if:
26+ # - they have adjacent tokens
27+ # - AND markers are the same
28+ #
29+ if (
30+ delimiters [headerIdx ].marker != closer .marker
31+ or lastTokenIdx != closer .token - 1
32+ ):
33+ headerIdx = closerIdx
34+ lastTokenIdx = closer .token
35+
1636 # Length is only used for emphasis-specific "rule of 3",
1737 # if it's not defined (in strikethrough or 3rd party plugins),
1838 # we can default it to 0 to disable those checks.
@@ -34,20 +54,15 @@ def processDelimiters(state: StateInline, delimiters: list[Delimiter]) -> None:
3454 (3 if closer .open else 0 ) + (closer .length % 3 )
3555 ]
3656
37- openerIdx = closerIdx - closer .jump - 1
38-
39- # avoid crash if `closer.jump` is pointing outside of the array,
40- # e.g. for strikethrough
41- if openerIdx < - 1 :
42- openerIdx = - 1
57+ openerIdx = headerIdx - jumps [headerIdx ] - 1
4358
4459 newMinOpenerIdx = openerIdx
4560
4661 while openerIdx > minOpenerIdx :
4762 opener = delimiters [openerIdx ]
4863
4964 if opener .marker != closer .marker :
50- openerIdx -= opener . jump + 1
65+ openerIdx -= jumps [ openerIdx ] + 1
5166 continue
5267
5368 if opener .open and opener .end < 0 :
@@ -73,19 +88,25 @@ def processDelimiters(state: StateInline, delimiters: list[Delimiter]) -> None:
7388 # sure algorithm has linear complexity (see *_*_*_*_*_... case).
7489 #
7590 if openerIdx > 0 and not delimiters [openerIdx - 1 ].open :
76- lastJump = delimiters [openerIdx - 1 ]. jump + 1
91+ lastJump = jumps [openerIdx - 1 ] + 1
7792 else :
7893 lastJump = 0
7994
80- closer .jump = closerIdx - openerIdx + lastJump
95+ jumps [closerIdx ] = closerIdx - openerIdx + lastJump
96+ jumps [openerIdx ] = lastJump
97+
8198 closer .open = False
8299 opener .end = closerIdx
83- opener .jump = lastJump
84100 opener .close = False
85101 newMinOpenerIdx = - 1
102+
103+ # treat next token as start of run,
104+ # it optimizes skips in **<...>**a**<...>** pathological case
105+ lastTokenIdx = - 2
106+
86107 break
87108
88- openerIdx -= opener . jump + 1
109+ openerIdx -= jumps [ openerIdx ] + 1
89110
90111 if newMinOpenerIdx != - 1 :
91112 # If match for this delimiter run failed, we want to set lower bound for
0 commit comments