Add hooks for Markdown pages to render their own table of contents
This commit is contained in:
parent
753b84cdf1
commit
38594a382b
|
@ -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:
|
||||||
|
|
|
@ -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 %}
|
Loading…
Reference in New Issue
Block a user