Skip to content

Commit ed0ff55

Browse files
committed
Merge pull request Python-Markdown#367 from facelessuser/master
Fix issue Python-Markdown#365 and Python-Markdown#366
2 parents f0357b2 + 69fd8b4 commit ed0ff55

File tree

4 files changed

+56
-51
lines changed

4 files changed

+56
-51
lines changed

markdown/extensions/toc.py

Lines changed: 47 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -27,60 +27,59 @@ def order_toc_list(toc_list):
2727
[{'level': 1}, {'level': 2}]
2828
=>
2929
[{'level': 1, 'children': [{'level': 2, 'children': []}]}]
30-
30+
3131
A wrong list is also converted:
3232
[{'level': 2}, {'level': 1}]
3333
=>
3434
[{'level': 2, 'children': []}, {'level': 1, 'children': []}]
3535
"""
36-
37-
def build_correct(remaining_list, prev_elements=[{'level': 1000}]):
38-
39-
if not remaining_list:
40-
return [], []
41-
42-
current = remaining_list.pop(0)
43-
if not 'children' in current.keys():
44-
current['children'] = []
45-
46-
if not prev_elements:
47-
# This happens for instance with [8, 1, 1], ie. when some
48-
# header level is outside a scope. We treat it as a
49-
# top-level
50-
next_elements, children = build_correct(remaining_list, [current])
51-
current['children'].append(children)
52-
return [current] + next_elements, []
53-
54-
prev_element = prev_elements.pop()
55-
children = []
56-
next_elements = []
57-
# Is current part of the child list or next list?
58-
if current['level'] > prev_element['level']:
59-
#print "%d is a child of %d" % (current['level'], prev_element['level'])
60-
prev_elements.append(prev_element)
61-
prev_elements.append(current)
62-
prev_element['children'].append(current)
63-
next_elements2, children2 = build_correct(remaining_list, prev_elements)
64-
children += children2
65-
next_elements += next_elements2
66-
else:
67-
#print "%d is ancestor of %d" % (current['level'], prev_element['level'])
68-
if not prev_elements:
69-
#print "No previous elements, so appending to the next set"
70-
next_elements.append(current)
71-
prev_elements = [current]
72-
next_elements2, children2 = build_correct(remaining_list, prev_elements)
73-
current['children'].extend(children2)
36+
37+
ordered_list = []
38+
if len(toc_list):
39+
# Initialize everything by processing the first entry
40+
last = toc_list.pop(0)
41+
last['children'] = []
42+
levels = [last['level']]
43+
ordered_list.append(last)
44+
parents = []
45+
46+
# Walk the rest nesting the entries properly
47+
while toc_list:
48+
t = toc_list.pop(0)
49+
current_level = t['level']
50+
t['children'] = []
51+
52+
# Reduce depth if current level < last item's level
53+
if current_level < levels[-1]:
54+
# Pop last level since we know we are less than it
55+
levels.pop()
56+
57+
# Pop parents and levels we are less than or equal to
58+
to_pop = 0
59+
for p in reversed(parents):
60+
if current_level <= p['level']:
61+
to_pop += 1
62+
else:
63+
break
64+
if to_pop:
65+
levels = levels[:-to_pop]
66+
parents = parents[:-to_pop]
67+
68+
# Note current level as last
69+
levels.append(current_level)
70+
71+
# Level is the same, so append to the current parent (if available)
72+
if current_level == levels[-1]:
73+
(parents[-1]['children'] if parents else ordered_list).append(t)
74+
75+
# Current level is > last item's level,
76+
# So make last item a parent and append current as child
7477
else:
75-
#print "Previous elements, comparing to those first"
76-
remaining_list.insert(0, current)
77-
next_elements2, children2 = build_correct(remaining_list, prev_elements)
78-
children.extend(children2)
79-
next_elements += next_elements2
80-
81-
return next_elements, children
82-
83-
ordered_list, __ = build_correct(toc_list)
78+
last['children'].append(t)
79+
parents.append(last)
80+
levels.append(current_level)
81+
last = t
82+
8483
return ordered_list
8584

8685

markdown/inlinepatterns.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,8 @@ def build_inlinepatterns(md_instance, **kwargs):
101101
ESCAPE_RE = r'\\(.)' # \<
102102
EMPHASIS_RE = r'(\*)([^\*]+)\2' # *emphasis*
103103
STRONG_RE = r'(\*{2}|_{2})(.+?)\2' # **strong**
104-
EM_STRONG_RE = r'(\*|_){3}(.+?)\2(.*?)\2{2}' # ***strongem*** or ***em*strong**
105-
STRONG_EM_RE = r'(\*|_){3}(.+?)\2{2}(.*?)\2' # ***strong**em*
104+
EM_STRONG_RE = r'(\*|_)\2{2}(.+?)\2(.*?)\2{2}' # ***strongem*** or ***em*strong**
105+
STRONG_EM_RE = r'(\*|_)\2{2}(.+?)\2{2}(.*?)\2' # ***strong**em*
106106
SMART_EMPHASIS_RE = r'(?<!\w)(_)(?!_)(.+?)(?<!_)\2(?!\w)' # _smart_emphasis_
107107
EMPHASIS_2_RE = r'(_)(.+?)\2' # _emphasis_
108108
LINK_RE = NOIMG + BRK + \

tests/misc/nested-patterns.html

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,6 @@
55
<strong><a href="http://example.com"><em>link</em></a></strong>
66
<strong><a href="http://example.com"><em>link</em></a></strong>
77
<a href="http://example.com"><strong><em>link</em></strong></a></p>
8-
<p><strong><em>I am <strong><em>italic</em> and</strong> bold</em> I am <code>just</code> bold</strong></p>
8+
<p><strong><em>I am <strong><em>italic</em> and</strong> bold</em> I am <code>just</code> bold</strong></p>
9+
<p>Example <strong><em>bold italic</em></strong> on the same line <strong><em>bold italic</em></strong>.</p>
10+
<p>Example <strong><em>bold italic</em></strong> on the same line <strong><em>bold italic</em></strong>.</p>

tests/misc/nested-patterns.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,7 @@ __[*link*](http://example.com)__
77
[***link***](http://example.com)
88

99
***I am ___italic_ and__ bold* I am `just` bold**
10+
11+
Example __*bold italic*__ on the same line __*bold italic*__.
12+
13+
Example **_bold italic_** on the same line **_bold italic_**.

0 commit comments

Comments
 (0)