Index: tools/md_browser/md_browser.py |
diff --git a/tools/md_browser/md_browser.py b/tools/md_browser/md_browser.py |
index 43dc5bdc921deae8911c6f72d1152d417d07bc8e..322c145ab979275f79a9d01a8b1f284384f5150f 100755 |
--- a/tools/md_browser/md_browser.py |
+++ b/tools/md_browser/md_browser.py |
@@ -17,11 +17,12 @@ import sys |
import threading |
import time |
import webbrowser |
+from xml.etree import ElementTree |
THIS_DIR = os.path.realpath(os.path.dirname(__file__)) |
SRC_DIR = os.path.dirname(os.path.dirname(THIS_DIR)) |
-sys.path.append(os.path.join(SRC_DIR, 'third_party', 'Python-Markdown')) |
+sys.path.insert(0, os.path.join(SRC_DIR, 'third_party', 'Python-Markdown')) |
import markdown |
@@ -155,10 +156,19 @@ class Handler(SimpleHTTPServer.SimpleHTTPRequestHandler): |
} |
contents = self._Read(path[1:]) |
- md_fragment = markdown.markdown(contents, |
- extensions=extensions, |
- extension_configs=extension_configs, |
- output_format='html4').encode('utf-8') |
+ |
+ md = markdown.Markdown(extensions=extensions, |
+ extension_configs=extension_configs, |
+ output_format='html4') |
+ |
+ has_a_single_h1 = (len([line for line in contents.splitlines() |
+ if (line.startswith('#') and |
+ not line.startswith('##'))]) == 1) |
+ |
+ md.treeprocessors['adjust_toc'] = _AdjustTOC(has_a_single_h1) |
+ |
+ md_fragment = md.convert(contents).encode('utf-8') |
+ |
try: |
self._WriteHeader('text/html') |
self._WriteTemplate('header.html') |
@@ -199,5 +209,70 @@ class Handler(SimpleHTTPServer.SimpleHTTPRequestHandler): |
self.wfile.write(contents.encode('utf-8')) |
+class _AdjustTOC(markdown.treeprocessors.Treeprocessor): |
+ def __init__(self, has_a_single_h1): |
+ super(_AdjustTOC, self).__init__() |
+ self.has_a_single_h1 = has_a_single_h1 |
+ |
+ def run(self, tree): |
+ # The markdown.extensions.toc extension will replace |
+ # |
+ # # H1 |
+ # |
+ # [TOC] |
+ # |
+ # ## first H2 |
+ # |
+ # ## second H2 |
+ # |
+ # with the following HTML: |
+ # |
+ # <div class='toc'> |
+ # <ul><li><a>H1</a> |
+ # <ul><li>first H2 |
+ # <li>second H2</li></ul></li><ul></div> |
+ # |
+ # We want to replace the first ul with the second one, and also patch |
+ # in a new H2 header for the TOC itself, ending up with: |
+ # |
+ # <div class='toc'> |
+ # <h2>Contents</h2> |
+ # <div class='toc-aux'> |
+ # <ul><li>first H2 |
+ # <li>second H2</li></ul></div></div> |
+ # |
+ # If the document has more than one H1, or no H1s at all, we leave |
+ # the tree alone but still wrap it in a toc-aux div and add the |
+ # Contents header. |
+ |
+ toc_nodes = tree.findall(".//*[@class='toc']") |
+ if not toc_nodes: |
+ return |
+ |
+ for toc_node in toc_nodes: |
+ if self.has_a_single_h1: |
+ toc_ul = toc_node[0] |
+ toc_ul_li = toc_ul[0] |
+ toc_ul_li_ul = toc_ul_li[1] |
+ children = toc_ul_li_ul |
+ del toc_node[0] |
+ else: |
+ children = list(toc_node) |
jsbell
2016/11/08 17:29:12
I'm unfamiliar with ElementTree and the exact stru
Dirk Pranke
2016/11/08 21:55:07
Ah, good catch.
|
+ while len(toc_node): |
+ del toc_node[0] |
+ |
+ contents = ElementTree.SubElement(toc_node, 'h2') |
+ contents.text = 'Contents' |
+ contents.tail = '\n' |
+ toc_aux = ElementTree.SubElement(toc_node, 'div', |
+ attrib={'class': 'toc-aux'}) |
+ toc_aux.text = '\n' |
+ toc_aux_ul = ElementTree.SubElement(toc_aux, 'ul') |
+ toc_aux_ul.text = '\n' |
+ toc_aux_ul.extend(children) |
+ toc_aux_ul.tail = '\n' |
+ toc_aux.tail = '\n' |
+ |
+ |
if __name__ == '__main__': |
sys.exit(main(sys.argv[1:])) |