summaryrefslogtreecommitdiffstats
path: root/about-filter.py
diff options
context:
space:
mode:
Diffstat (limited to 'about-filter.py')
-rwxr-xr-xabout-filter.py42
1 files changed, 42 insertions, 0 deletions
diff --git a/about-filter.py b/about-filter.py
new file mode 100755
index 0000000..fecbb1c
--- /dev/null
+++ b/about-filter.py
@@ -0,0 +1,42 @@
+#!/usr/bin/env python3
+"""
+cgit about-filter: renders README.md as HTML with Pygments syntax highlighting.
+
+cgit calls this script with the readme filename as argv[1] and file content on stdin.
+Output is HTML written to stdout.
+"""
+
+import sys
+import re
+import markdown
+from pygments import highlight
+from pygments.lexers import get_lexer_by_name, TextLexer
+from pygments.formatters import HtmlFormatter
+from pygments.util import ClassNotFound
+
+
+def highlight_code_blocks(html):
+ def replacer(match):
+ lang = match.group(1) or ""
+ code = match.group(2)
+ # Unescape HTML entities from markdown output
+ code = code.replace("&amp;", "&").replace("&lt;", "<").replace("&gt;", ">").replace("&quot;", '"')
+ try:
+ lexer = get_lexer_by_name(lang.strip(), stripnl=False) if lang.strip() else TextLexer(stripnl=False)
+ except ClassNotFound:
+ lexer = TextLexer(stripnl=False)
+ formatter = HtmlFormatter(nowrap=True, cssclass="highlight", noclasses=False)
+ highlighted = highlight(code, lexer, formatter)
+ return f'<pre><code class="highlight">{highlighted}</code></pre>'
+
+ # Match <pre><code class="language-LANG"> or <pre><code>
+ pattern = re.compile(
+ r'<pre><code(?:\s+class="language-([^"]*)")?>(.*?)</code></pre>',
+ re.DOTALL
+ )
+ return pattern.sub(replacer, html)
+
+
+content = sys.stdin.read()
+html = markdown.markdown(content, extensions=["fenced_code", "tables", "toc"])
+print(highlight_code_blocks(html))