Add hooks for Markdown pages to render their own table of contents

This commit is contained in:
Noah 2016-06-17 14:54:45 -07:00
parent 753b84cdf1
commit 38594a382b
2 changed files with 47 additions and 1 deletions

View File

@ -130,6 +130,7 @@ def markdown_template(path):
content = list() # New set of lines, without meta info. content = list() # New set of lines, without meta info.
extensions = set() extensions = set()
blacklist = set() # Blacklisted extensions blacklist = set() # Blacklisted extensions
toc = False # Render a table of contents
for line in lines: for line in lines:
if line.startswith(":meta"): if line.startswith(":meta"):
parts = line.split(" ") parts = line.split(" ")
@ -143,6 +144,9 @@ def markdown_template(path):
blacklist.add(extension) blacklist.add(extension)
else: else:
extensions.add(extension) extensions.add(extension)
elif parts[1] == "toc":
# Table of contents.
toc = parts[2] == "on"
else: else:
content.append(line) content.append(line)
@ -155,9 +159,16 @@ def markdown_template(path):
extensions=extensions, extensions=extensions,
blacklist=blacklist, blacklist=blacklist,
) )
# Including a table of contents?
nav = None
if toc:
nav = parse_anchors(rendered)
return template("markdown.inc.html", return template("markdown.inc.html",
title=first, title=first,
markdown=rendered, markdown=rendered,
toc=nav,
) )
@ -202,6 +213,29 @@ def render_markdown(body, html_escape=True, extensions=None, blacklist=None):
) )
def parse_anchors(html):
"""Parse HTML code and identify anchor tags for Table of Contents.
Args:
* str html: HTML code generated by `render_markdown()`
Returns:
* list of dicts containing the parsed table of contents, with keys
including `id`, `level` (<h1> level as int) and `text`
"""
toc = []
regexp = re.compile(r'<h(\d) id="(.+?)">(.+?)</h\d>')
for match in re.findall(regexp, html):
toc.append(dict(
id=match[1],
level=int(match[0]),
text=match[2],
))
return toc
def send_email(to, subject, message, sender=None, reply_to=None): def send_email(to, subject, message, sender=None, reply_to=None):
"""Send an e-mail out.""" """Send an e-mail out."""
if sender is None: if sender is None:

View File

@ -2,6 +2,18 @@
{% block title %}{{ title }}{% endblock %} {% block title %}{{ title }}{% endblock %}
{% block content %} {% block content %}
{% if toc %}
<nav class="markdown-toc">
<ul>
{% for entry in toc %}
<li class="toc-{{ entry['level'] }}">
<a href="#{{ entry['id'] }}">{{ entry['text'] }}</a>
</li>
{% endfor %}
</ul>
</nav>
{% endif %}
{{ markdown|safe }} {{ markdown|safe }}
{% endblock %} {% endblock %}