summaryrefslogtreecommitdiffstats
path: root/syntax-highlight.py
diff options
context:
space:
mode:
Diffstat (limited to 'syntax-highlight.py')
-rwxr-xr-xsyntax-highlight.py67
1 files changed, 67 insertions, 0 deletions
diff --git a/syntax-highlight.py b/syntax-highlight.py
new file mode 100755
index 0000000..e7a8ad4
--- /dev/null
+++ b/syntax-highlight.py
@@ -0,0 +1,67 @@
+#!/usr/bin/env python3
+"""
+cgit source-filter: syntax highlighting via Pygments (Catppuccin Macchiato).
+
+cgit passes the filename as argv[1] and the file content on stdin.
+Output is HTML written to stdout.
+"""
+
+import sys
+import os
+
+try:
+ from pygments import highlight
+ from pygments.lexers import get_lexer_for_filename, TextLexer
+ from pygments.formatters import HtmlFormatter
+ from pygments.util import ClassNotFound
+ PYGMENTS_AVAILABLE = True
+except ImportError:
+ PYGMENTS_AVAILABLE = False
+
+
+def get_lexer(filename):
+ try:
+ return get_lexer_for_filename(filename, stripnl=False, ensurenl=False)
+ except ClassNotFound:
+ return TextLexer(stripnl=False, ensurenl=False)
+
+
+def main():
+ filename = sys.argv[1] if len(sys.argv) > 1 else ""
+
+ data = sys.stdin.buffer.read()
+
+ # Try UTF-8, fall back to latin-1 to avoid decode errors on binary-ish files
+ try:
+ text = data.decode("utf-8")
+ except UnicodeDecodeError:
+ try:
+ text = data.decode("latin-1")
+ except UnicodeDecodeError:
+ # Give up and emit as plain text
+ sys.stdout.write("<pre>" + data.decode("ascii", errors="replace") + "</pre>")
+ return
+
+ if not PYGMENTS_AVAILABLE or not filename:
+ sys.stdout.write("<pre>" + text.replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;") + "</pre>")
+ return
+
+ lexer = get_lexer(filename)
+
+ formatter = HtmlFormatter(
+ style="monokai", # base style; token colors overridden by CSS
+ nowrap=True, # no wrapping <div class="highlight">
+ cssclass="highlight",
+ noclasses=False, # use CSS classes, not inline styles
+ )
+
+ highlighted = highlight(text, lexer, formatter)
+
+ # Wrap in pre so cgit's blob table renders it correctly
+ sys.stdout.write('<pre><code class="highlight">')
+ sys.stdout.write(highlighted)
+ sys.stdout.write("</code></pre>")
+
+
+if __name__ == "__main__":
+ main()