diff options
| -rw-r--r-- | CLAUDE.md | 1 | ||||
| -rwxr-xr-x | about-filter.py | 42 | ||||
| -rw-r--r-- | cgit.css | 32 |
3 files changed, 61 insertions, 14 deletions
@@ -54,6 +54,7 @@ cgit generates fixed HTML. Key selectors used in `cgit.css`: | Line number cell | `td.linenumbers` | | Code cell | `td.lines` | | Footer | `div.footer` | +| About/README content | `div#summary` | If cgit's generated markup ever differs (version-dependent), inspect the live HTML first before changing selectors. 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("&", "&").replace("<", "<").replace(">", ">").replace(""", '"') + 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)) @@ -1260,35 +1260,39 @@ td.logmsg { } /* About page / README */ -div#readme { - background: var(--bg2); +div#summary { + background: var(--surface); border: 1px solid var(--border); border-radius: 6px; padding: 24px 28px; margin-top: 20px; + max-width: 1200px; + width: 100%; + box-sizing: border-box; + box-shadow: 0 0 20px rgba(var(--accent-rgb), 0.08); font-family: 'IBM Plex Sans', sans-serif; font-size: 15px; line-height: 1.75; color: var(--text); } -div#readme h1, -div#readme h2, -div#readme h3, -div#readme h4 { +div#summary h1, +div#summary h2, +div#summary h3, +div#summary h4 { font-family: 'Oxanium', monospace; color: var(--text); margin-top: 1.5em; margin-bottom: 0.5em; } -div#readme h1 { font-size: 26px; border-bottom: 1px solid var(--border); padding-bottom: 8px; } -div#readme h2 { font-size: 20px; } -div#readme h3 { font-size: 17px; } +div#summary h1 { font-size: 26px; border-bottom: 1px solid var(--border); padding-bottom: 8px; } +div#summary h2 { font-size: 20px; } +div#summary h3 { font-size: 17px; } -div#readme a { color: var(--accent); } +div#summary a { color: var(--accent); } -div#readme code { +div#summary code { font-family: 'JetBrains Mono', monospace; font-size: 13px; background: var(--surface); @@ -1298,7 +1302,7 @@ div#readme code { color: var(--accent2); } -div#readme pre { +div#summary pre { background: var(--surface); border: 1px solid var(--border); border-radius: 6px; @@ -1306,7 +1310,7 @@ div#readme pre { overflow-x: auto; } -div#readme pre code { +div#summary pre code { background: transparent; border: none; padding: 0; @@ -1314,7 +1318,7 @@ div#readme pre code { font-size: 13px; } -div#readme blockquote { +div#summary blockquote { border-left: 4px solid var(--accent); margin: 16px 0; padding: 8px 16px; |
