26
26
27
from __future__ import annotations
27
from __future__ import annotations
28
28
29
+ import functools
29
import re
30
import re
30
import xml .etree .ElementTree as etree
31
import xml .etree .ElementTree as etree
31
from typing import TYPE_CHECKING , Any
32
from typing import TYPE_CHECKING , Any
@@ -250,13 +251,14 @@ def linkText(text: str | None) -> None:
250
251
251
return result
252
return result
252
253
254
+ @functools .singledispatchmethod
253
def __applyPattern (
255
def __applyPattern (
254
self ,
256
self ,
255
- pattern : inlinepatterns .Pattern ,
257
+ pattern : inlinepatterns .LegacyPattern ,
256
data : str ,
258
data : str ,
257
patternIndex : int ,
259
patternIndex : int ,
258
startIndex : int = 0
260
startIndex : int = 0
259
- ) -> tuple [str , bool , int ]:
261
+ ) -> tuple [str , bool , int ]: # pragma: no cover
260
"""
262
"""
261
Check if the line fits the pattern, create the necessary
263
Check if the line fits the pattern, create the necessary
262
elements, add it to `stashed_nodes`.
264
elements, add it to `stashed_nodes`.
@@ -271,64 +273,85 @@ def __applyPattern(
271
String with placeholders instead of `ElementTree` elements.
273
String with placeholders instead of `ElementTree` elements.
272
274
273
"""
275
"""
274
- new_style = isinstance (pattern , inlinepatterns .InlineProcessor )
276
+ # This overload handles old-style patterns.
275
-
276
for exclude in pattern .ANCESTOR_EXCLUDES :
277
for exclude in pattern .ANCESTOR_EXCLUDES :
277
if exclude .lower () in self .ancestors :
278
if exclude .lower () in self .ancestors :
278
return data , False , 0
279
return data , False , 0
279
280
280
- if new_style :
281
+ match = pattern .getCompiledRegExp ().match (data [startIndex :])
281
- match = None
282
+ leftData = data [:startIndex ]
282
- # Since `handleMatch` may reject our first match,
283
- # we iterate over the buffer looking for matches
284
- # until we can't find any more.
285
- for match in pattern .getCompiledRegExp ().finditer (data , startIndex ):
286
- node , start , end = pattern .handleMatch (match , data )
287
- if start is None or end is None :
288
- startIndex += match .end (0 )
289
- match = None
290
- continue
291
- break
292
- else : # pragma: no cover
293
- match = pattern .getCompiledRegExp ().match (data [startIndex :])
294
- leftData = data [:startIndex ]
295
283
296
if not match :
284
if not match :
297
return data , False , 0
285
return data , False , 0
298
286
299
- if not new_style : # pragma: no cover
287
+ node = pattern .handleMatch (match )
300
- node = pattern .handleMatch (match )
288
+
301
- start = match .start (0 )
289
+ if node is None :
302
- end = match .end (0 )
290
+ return data , True , match .end (0 )
291
+
292
+ if not isinstance (node , str ):
293
+ self .__handleInlineForChildNodes (node , patternIndex )
294
+
295
+ placeholder = self .__stashNode (node , pattern .type ())
296
+
297
+ return "{}{}{}{}" .format (leftData ,
298
+ match .group (1 ),
299
+ placeholder , match .groups ()[- 1 ]), True , 0
300
+
301
+ @__applyPattern .register
302
+ def _ (
303
+ self ,
304
+ pattern : inlinepatterns .InlineProcessor ,
305
+ data : str ,
306
+ patternIndex : int ,
307
+ startIndex : int = 0
308
+ ) -> tuple [str , bool , int ]:
309
+ # This overload handles new-style patterns.
310
+ for exclude in pattern .ANCESTOR_EXCLUDES :
311
+ if exclude .lower () in self .ancestors :
312
+ return data , False , 0
313
+
314
+ match = None
315
+ # Since `handleMatch` may reject our first match,
316
+ # we iterate over the buffer looking for matches
317
+ # until we can't find any more.
318
+ for match in pattern .getCompiledRegExp ().finditer (data , startIndex ):
319
+ node , start , end = pattern .handleMatch (match , data )
320
+ if start is None or end is None :
321
+ startIndex += match .end (0 )
322
+ match = None
323
+ continue
324
+ break
325
+
326
+ if not match :
327
+ return data , False , 0
303
328
304
if node is None :
329
if node is None :
305
return data , True , end
330
return data , True , end
306
331
307
if not isinstance (node , str ):
332
if not isinstance (node , str ):
308
- if not isinstance (node .text , util .AtomicString ):
333
+ self .__handleInlineForChildNodes (node , patternIndex )
309
- # We need to process current node too
310
- for child in [node ] + list (node ):
311
- if not isString (node ):
312
- if child .text :
313
- self .ancestors .append (child .tag .lower ())
314
- child .text = self .__handleInline (
315
- child .text , patternIndex + 1
316
- )
317
- self .ancestors .pop ()
318
- if child .tail :
319
- child .tail = self .__handleInline (
320
- child .tail , patternIndex
321
- )
322
334
323
placeholder = self .__stashNode (node , pattern .type ())
335
placeholder = self .__stashNode (node , pattern .type ())
324
336
325
- if new_style :
337
+ return "{}{}{}" .format (data [:start ],
326
- return "{}{}{}" .format (data [:start ],
338
+ placeholder , data [end :]), True , 0
327
- placeholder , data [end :]), True , 0
339
+
328
- else : # pragma: no cover
340
+ def __handleInlineForChildNodes (self , node : etree .Element , patternIndex : int ) -> None :
329
- return "{}{}{}{}" .format (leftData ,
341
+ if not isinstance (node .text , util .AtomicString ):
330
- match .group (1 ),
342
+ # We need to process current node too
331
- placeholder , match .groups ()[- 1 ]), True , 0
343
+ for child in [node ] + list (node ):
344
+ if not isString (node ):
345
+ if child .text :
346
+ self .ancestors .append (child .tag .lower ())
347
+ child .text = self .__handleInline (
348
+ child .text , patternIndex + 1
349
+ )
350
+ self .ancestors .pop ()
351
+ if child .tail :
352
+ child .tail = self .__handleInline (
353
+ child .tail , patternIndex
354
+ )
332
355
333
def __build_ancestors (self , parent : etree .Element | None , parents : list [str ]) -> None :
356
def __build_ancestors (self , parent : etree .Element | None , parents : list [str ]) -> None :
334
"""Build the ancestor list."""
357
"""Build the ancestor list."""
0 commit comments