diff options
Diffstat (limited to 'syntax-highlight.py')
| -rwxr-xr-x | syntax-highlight.py | 67 |
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("&", "&").replace("<", "<").replace(">", ">") + "</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() |
