@@ -54,6 +54,7 @@ def __init__(self, md):
54
54
self .__placeholder_re = util .INLINE_PLACEHOLDER_RE
55
55
self .markdown = md
56
56
self .inlinePatterns = md .inlinePatterns
57
+ self .ancestors = []
57
58
58
59
def __makePlaceholder (self , type ):
59
60
""" Generate a placeholder """
@@ -138,7 +139,7 @@ def __processElementText(self, node, subnode, isText=True):
138
139
139
140
childResult .reverse ()
140
141
for newChild in childResult :
141
- node .insert (pos , newChild )
142
+ node .insert (pos , newChild [ 0 ] )
142
143
143
144
def __processPlaceholders (self , data , parent , isText = True ):
144
145
"""
@@ -155,10 +156,10 @@ def __processPlaceholders(self, data, parent, isText=True):
155
156
def linkText (text ):
156
157
if text :
157
158
if result :
158
- if result [- 1 ].tail :
159
- result [- 1 ].tail += text
159
+ if result [- 1 ][ 0 ] .tail :
160
+ result [- 1 ][ 0 ] .tail += text
160
161
else :
161
- result [- 1 ].tail = text
162
+ result [- 1 ][ 0 ] .tail = text
162
163
elif not isText :
163
164
if parent .tail :
164
165
parent .tail += text
@@ -199,7 +200,7 @@ def linkText(text):
199
200
continue
200
201
201
202
strartIndex = phEndIndex
202
- result .append (node )
203
+ result .append (( node , self . ancestors [:]) )
203
204
204
205
else : # wrong placeholder
205
206
end = index + len (self .__placeholder_prefix )
@@ -230,6 +231,11 @@ def __applyPattern(self, pattern, data, patternIndex, startIndex=0):
230
231
Returns: String with placeholders instead of ElementTree elements.
231
232
232
233
"""
234
+
235
+ for exclude in pattern .ANCESTOR_EXCLUDES :
236
+ if exclude .lower () in self .ancestors :
237
+ return data , False , 0
238
+
233
239
match = pattern .getCompiledRegExp ().match (data [startIndex :])
234
240
leftData = data [:startIndex ]
235
241
@@ -247,9 +253,11 @@ def __applyPattern(self, pattern, data, patternIndex, startIndex=0):
247
253
for child in [node ] + list (node ):
248
254
if not isString (node ):
249
255
if child .text :
256
+ self .ancestors .append (child .tag .lower ())
250
257
child .text = self .__handleInline (
251
258
child .text , patternIndex + 1
252
259
)
260
+ self .ancestors .pop ()
253
261
if child .tail :
254
262
child .tail = self .__handleInline (
255
263
child .tail , patternIndex
@@ -261,7 +269,17 @@ def __applyPattern(self, pattern, data, patternIndex, startIndex=0):
261
269
match .group (1 ),
262
270
placeholder , match .groups ()[- 1 ]), True , 0
263
271
264
- def run (self , tree ):
272
+ def __build_ancestors (self , parent , parents ):
273
+ """Build the ancestor list."""
274
+ ancestors = []
275
+ while parent :
276
+ if parent :
277
+ ancestors .append (parent .tag .lower ())
278
+ parent = self .parent_map .get (parent )
279
+ ancestors .reverse ()
280
+ parents .extend (ancestors )
281
+
282
+ def run (self , tree , ancestors = None ):
265
283
"""Apply inline patterns to a parsed Markdown tree.
266
284
267
285
Iterate over ElementTree, find elements with inline tag, apply inline
@@ -274,28 +292,42 @@ def run(self, tree):
274
292
Arguments:
275
293
276
294
* tree: ElementTree object, representing Markdown tree.
295
+ * ancestors: List of parent tag names that preceed the tree node (if needed).
277
296
278
297
Returns: ElementTree object with applied inline patterns.
279
298
280
299
"""
281
300
self .stashed_nodes = {}
282
301
283
- stack = [tree ]
302
+ # Ensure a valid parent list, but copy passed in lists
303
+ # to ensure we don't have the user accidentally change it on us.
304
+ tree_parents = [] if ancestors is None else ancestors [:]
305
+
306
+ self .parent_map = dict ((c , p ) for p in tree .getiterator () for c in p )
307
+ stack = [(tree , tree_parents )]
284
308
285
309
while stack :
286
- currElement = stack .pop ()
310
+ currElement , parents = stack .pop ()
311
+
312
+ self .ancestors = parents
313
+ self .__build_ancestors (currElement , self .ancestors )
314
+
287
315
insertQueue = []
288
316
for child in currElement :
289
317
if child .text and not isinstance (
290
318
child .text , util .AtomicString
291
319
):
320
+ self .ancestors .append (child .tag .lower ())
292
321
text = child .text
293
322
child .text = None
294
323
lst = self .__processPlaceholders (
295
324
self .__handleInline (text ), child
296
325
)
326
+ for l in lst :
327
+ self .parent_map [l [0 ]] = child
297
328
stack += lst
298
329
insertQueue .append ((child , lst ))
330
+ self .ancestors .pop ()
299
331
if child .tail :
300
332
tail = self .__handleInline (child .tail )
301
333
dumby = util .etree .Element ('d' )
@@ -306,9 +338,11 @@ def run(self, tree):
306
338
pos = list (currElement ).index (child ) + 1
307
339
tailResult .reverse ()
308
340
for newChild in tailResult :
309
- currElement .insert (pos , newChild )
341
+ self .parent_map [newChild [0 ]] = currElement
342
+ currElement .insert (pos , newChild [0 ])
310
343
if len (child ):
311
- stack .append (child )
344
+ self .parent_map [child ] = currElement
345
+ stack .append ((child , self .ancestors [:]))
312
346
313
347
for element , lst in insertQueue :
314
348
if self .markdown .enable_attributes :
@@ -317,7 +351,8 @@ def run(self, tree):
317
351
element .text , element
318
352
)
319
353
i = 0
320
- for newChild in lst :
354
+ for obj in lst :
355
+ newChild = obj [0 ]
321
356
if self .markdown .enable_attributes :
322
357
# Processing attributes
323
358
if newChild .tail and isString (newChild .tail ):
0 commit comments