diff --git a/rophako/utils.py b/rophako/utils.py
index 22ebfee..b6004e3 100644
--- a/rophako/utils.py
+++ b/rophako/utils.py
@@ -57,30 +57,71 @@ def template(name, **kwargs):
def markdown_template(path):
- """Render a Markdown page to the browser."""
+ """Render a Markdown page to the browser.
+
+ The first line in the Markdown page should be an H1 header beginning with
+ the # sign. This will set the page's
to match the header value.
+
+ Pages can include lines that begin with the keyword `:meta` to apply
+ meta information to control the Markdown parser. Supported meta lines
+ and examples:
+
+ To 'blacklist' extensions, i.e. to turn off line breaks inside a paragraph
+ getting translated into a
tag (the key is the minus sign):
+ :meta extensions -nl2br
+
+ To add an extension, i.e. the abbreviations from PHP Markdown Extra:
+ :meta extensions abbr"""
# The path is the absolute path to the Markdown file, so open it directly.
fh = codecs.open(path, "r", "utf-8")
body = fh.read()
fh.close()
+ # Look for meta information in the file.
+ lines = body.split("\n")
+ content = list() # New set of lines, without meta info.
+ extensions = set()
+ blacklist = set() # Blacklisted extensions
+ for line in lines:
+ if line.startswith(":meta"):
+ parts = line.split(" ")
+ if len(parts) >= 3:
+ # Supported meta commands.
+ if parts[1] == "extensions":
+ # Extension toggles.
+ for extension in parts[2:]:
+ if extension.startswith("-"):
+ extension = extension[1:]
+ blacklist.add(extension)
+ else:
+ extensions.add(extension)
+ else:
+ content.append(line)
+
# Extract a title from the first line.
- first = body.split("\n")[0]
+ first = content[0]
if first.startswith("#"):
first = first[1:].strip()
- rendered = render_markdown(body)
+ rendered = render_markdown("\n".join(content),
+ extensions=extensions,
+ blacklist=blacklist,
+ )
return template("markdown.inc.html",
title=first,
markdown=rendered,
)
-def render_markdown(body, html_escape=True):
+def render_markdown(body, html_escape=True, extensions=None, blacklist=None):
"""Render a block of Markdown text.
This will default to escaping literal HTML characters. Set
- `html_escape=False` to trust HTML."""
+ `html_escape=False` to trust HTML.
+
+ * extensions should be a set() of extensions to add.
+ * blacklist should be a set() of extensions to blacklist."""
args = dict(
lazy_ol=False, # If a numbered list starts at e.g. 4, show the there
@@ -101,6 +142,14 @@ def render_markdown(body, html_escape=True):
if html_escape:
args["safe_mode"] = "escape"
+ # Additional extensions?
+ if extensions is not None:
+ for ext in extensions:
+ args["extensions"].append(ext)
+ if blacklist is not None:
+ for ext in blacklist:
+ args["extensions"].remove(str(ext))
+
return markdown.markdown(body, **args)
@@ -157,4 +206,4 @@ def sanitize_name(name):
"""Sanitize a name that may be used in the filesystem.
Only allows numbers, letters, and some symbols."""
- return re.sub(r'[^A-Za-z0-9 .\-_]+', '', name)
\ No newline at end of file
+ return re.sub(r'[^A-Za-z0-9 .\-_]+', '', name)