diff options
-rw-r--r-- | markdown/extensions/toc.py | 57 | ||||
-rw-r--r-- | tests/extensions/test.cfg | 3 | ||||
-rw-r--r-- | tests/extensions/toc_out_of_order.html | 8 | ||||
-rw-r--r-- | tests/extensions/toc_out_of_order.txt | 5 |
4 files changed, 45 insertions, 28 deletions
diff --git a/markdown/extensions/toc.py b/markdown/extensions/toc.py index 594712e..173ae17 100644 --- a/markdown/extensions/toc.py +++ b/markdown/extensions/toc.py @@ -15,7 +15,7 @@ from markdown.extensions.headerid import slugify, unique, itertext import re -def flatten_list(toc_list): +def order_toc_list(toc_list): """Given an unsorted list with errors and skips, return a nested one. [{'level': 1}, {'level': 2}] => @@ -40,41 +40,41 @@ def flatten_list(toc_list): # This happens for instance with [8, 1, 1], ie. when some # header level is outside a scope. We treat it as a # top-level - next2, children2 = build_correct(remaining_list, [current]) - current['children'].append(children2) - return [current] + next2, [] + next_elements, children = build_correct(remaining_list, [current]) + current['children'].append(children) + return [current] + next_elements, [] prev_element = prev_elements.pop() children = [] - next = [] + next_elements = [] # Is current part of the child list or next list? if current['level'] > prev_element['level']: #print "%d is a child of %d" % (current['level'], prev_element['level']) prev_elements.append(prev_element) prev_elements.append(current) prev_element['children'].append(current) - next2, children2 = build_correct(remaining_list, prev_elements) + next_elements2, children2 = build_correct(remaining_list, prev_elements) children += children2 - next += next2 - return next, children + next_elements += next_elements2 else: #print "%d is ancestor of %d" % (current['level'], prev_element['level']) if not prev_elements: #print "No previous elements, so appending to the next set" - next.append(current) + next_elements.append(current) prev_elements = [current] - next2, children3 = build_correct(remaining_list, prev_elements) - current['children'].extend(children3) + next_elements2, children2 = build_correct(remaining_list, prev_elements) + current['children'].extend(children2) else: #print "Previous elements, comparing to those first" remaining_list.insert(0, current) - next2, children3 = build_correct(remaining_list, prev_elements) - children.extend(children3) - next += next2 - return next, children + next_elements2, children2 = build_correct(remaining_list, prev_elements) + children.extend(children2) + next_elements += next_elements2 + + return next_elements, children - flattened_list, __ = build_correct(toc_list) - return flattened_list + ordered_list, __ = build_correct(toc_list) + return ordered_list class TocTreeprocessor(markdown.treeprocessors.Treeprocessor): @@ -85,11 +85,11 @@ class TocTreeprocessor(markdown.treeprocessors.Treeprocessor): for child in parent: yield parent, child - def add_anchor(self, c, id): + def add_anchor(self, c, elem_id): #@ReservedAssignment if self.use_anchors: anchor = etree.Element("a") anchor.text = c.text - anchor.attrib["href"] = "#" + id + anchor.attrib["href"] = "#" + elem_id anchor.attrib["class"] = "toclink" c.text = "" for elem in c.getchildren(): @@ -133,7 +133,6 @@ class TocTreeprocessor(markdown.treeprocessors.Treeprocessor): used_ids.append(c.attrib["id"]) toc_list = [] - level = 0 marker_found = False for (p, c) in self.iterparent(doc): text = ''.join(itertext(c)).strip() @@ -158,21 +157,21 @@ class TocTreeprocessor(markdown.treeprocessors.Treeprocessor): # Do not override pre-existing ids if not "id" in c.attrib: - id = unique(self.config["slugify"](text, '-'), used_ids) - c.attrib["id"] = id + elem_id = unique(self.config["slugify"](text, '-'), used_ids) + c.attrib["id"] = elem_id else: - id = c.attrib["id"] + elem_id = c.attrib["id"] tag_level = int(c.tag[-1]) toc_list.append({'level': tag_level, - 'id': id, + 'id': elem_id, 'name': c.text}) - self.add_anchor(c, id) + self.add_anchor(c, elem_id) if marker_found: - toc_list_nested = flatten_list(toc_list) + toc_list_nested = order_toc_list(toc_list) self.build_toc_etree(div, toc_list_nested) # serialize and attach to markdown instance. prettify = self.markdown.treeprocessors.get('prettify') @@ -182,11 +181,12 @@ class TocTreeprocessor(markdown.treeprocessors.Treeprocessor): toc = pp.run(toc) self.markdown.toc = toc + class TocExtension(markdown.Extension): TreeProcessorClass = TocTreeprocessor - def __init__(self, configs): + def __init__(self, configs=[]): self.config = { "marker" : ["[TOC]", "Text to find and replace with Table of Contents -" "Defaults to \"[TOC]\""], @@ -212,6 +212,7 @@ class TocExtension(markdown.Extension): # attr_list extension. This must come last because we don't want # to redefine ids after toc is created. But we do want toc prettified. md.treeprocessors.add("toc", tocext, "<prettify") - + + def makeExtension(configs={}): return TocExtension(configs=configs) diff --git a/tests/extensions/test.cfg b/tests/extensions/test.cfg index 4efd837..7f082cf 100644 --- a/tests/extensions/test.cfg +++ b/tests/extensions/test.cfg @@ -12,6 +12,9 @@ extensions=toc [toc_invalid] extensions=toc +[toc_out_of_order] +extensions=toc + [toc_nested] extensions=toc diff --git a/tests/extensions/toc_out_of_order.html b/tests/extensions/toc_out_of_order.html new file mode 100644 index 0000000..93d8b04 --- /dev/null +++ b/tests/extensions/toc_out_of_order.html @@ -0,0 +1,8 @@ +<div class="toc"> +<ul> +<li><a href="#header-2">Header 2</a></li> +<li><a href="#header-1">Header 1</a></li> +</ul> +</div> +<h2 id="header-2">Header 2</h2> +<h1 id="header-1">Header 1</h1>
\ No newline at end of file diff --git a/tests/extensions/toc_out_of_order.txt b/tests/extensions/toc_out_of_order.txt new file mode 100644 index 0000000..f08bdbc --- /dev/null +++ b/tests/extensions/toc_out_of_order.txt @@ -0,0 +1,5 @@ +[TOC] + +## Header 2 + +# Header 1 |