From 722d765973ab368a313455d2179d7b3d67ec25cb Mon Sep 17 00:00:00 2001 From: Alberto Bertogli Date: Sun, 4 Mar 2018 20:53:35 +0000 Subject: [PATCH] markdown: Handle local links By default, the markdown generator creates links for local files transparently. For example, "[text](link.md)" will generate "text". This works fine for absolute and external links, but breaks for links relative to the repository itself, as git-arr links are of the form "dir/f=file.ext.html". So this patch adds a markdown extension to rewrite the links. It uses a heuristic to detect them, which should work for the vast majority of common cases. --- utils.py | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/utils.py b/utils.py index 008f11a..ada9c7e 100644 --- a/utils.py +++ b/utils.py @@ -14,12 +14,14 @@ except ImportError: try: import markdown + import markdown.treeprocessors except ImportError: markdown = None import base64 import mimetypes import string +import os.path def shorten(s, width = 60): if len(s) < 60: @@ -100,6 +102,7 @@ def markdown_blob(s): extensions = [ "markdown.extensions.fenced_code", "markdown.extensions.tables", + RewriteLocalLinksExtension(), ] return markdown.markdown(s, extensions = extensions) @@ -122,3 +125,41 @@ def hexdump(s): yield offset, ' '.join(hexvals[:8]), ' '.join(hexvals[8:]), text offset += 16 s = s[16:] + + +if markdown: + class RewriteLocalLinks(markdown.treeprocessors.Treeprocessor): + """Rewrites relative links to files, to match git-arr's links. + + A link of "[example](a/file.md)" will be rewritten such that it links to + "a/f=file.md.html". + + Note that we're already assuming a degree of sanity in the HTML, so we + don't re-check that the path is reasonable. + """ + def run(self, root): + for child in root: + if child.tag == "a": + self.rewrite_href(child) + + # Continue recursively. + self.run(child) + + def rewrite_href(self, tag): + """Rewrite an 's href.""" + target = tag.get("href") + if not target: + return + if "://" in target or target.startswith("/"): + return + + head, tail = os.path.split(target) + new_target = os.path.join(head, "f=" + tail + ".html") + tag.set("href", new_target) + + + class RewriteLocalLinksExtension(markdown.Extension): + def extendMarkdown(self, md, md_globals): + md.treeprocessors.add( + "RewriteLocalLinks", RewriteLocalLinks(), "_end") +