From e525fd634b07600110cf0ac940a4b5e9c48f1ab1 Mon Sep 17 00:00:00 2001 From: Luka Hietala Date: Thu, 20 Nov 2025 17:16:26 +0200 Subject: [PATCH] add pygments syntax highlighting --- git/blob.py | 10 ++++++++-- highlight.py | 25 +++++++++++++++++++++++++ requirements.txt | 1 + templates/blob.html | 3 +-- 4 files changed, 35 insertions(+), 4 deletions(-) create mode 100644 highlight.py diff --git a/git/blob.py b/git/blob.py index 96496a6..a950dae 100644 --- a/git/blob.py +++ b/git/blob.py @@ -1,4 +1,5 @@ import pygit2 as git +from highlight import highlight_code # retrieves a blob content for given ref and path def get_blob(repo_path, ref="HEAD", blob_path=""): @@ -22,14 +23,19 @@ def get_blob(repo_path, ref="HEAD", blob_path=""): if entry.name == part: if entry.type == git.GIT_OBJECT_BLOB: blob = repo.get(entry.id) - return { + content = blob.data.decode('utf-8', errors='replace') + result = { 'name': entry.name, 'id': str(entry.id), 'path': blob_path, 'size': blob.size, 'is_binary': blob.is_binary, - 'content': blob.data.decode('utf-8', errors='replace') + 'content': content } + # add highlighted content + if not blob.is_binary: + result['highlighted'] = highlight_code(content, entry.name) + return result elif entry.type == git.GIT_OBJECT_TREE: tree = repo.get(entry.id) found = True diff --git a/highlight.py b/highlight.py new file mode 100644 index 0000000..ca5b64e --- /dev/null +++ b/highlight.py @@ -0,0 +1,25 @@ +from pygments import highlight +from pygments.util import ClassNotFound +from pygments.lexers import TextLexer +from pygments.lexers import guess_lexer +from pygments.lexers import guess_lexer_for_filename +from pygments.formatters import HtmlFormatter + +# server-side syntax highlighting + +# https://git.kernel.org/pub/scm/infra/cgit.git/tree/filters/syntax-highlighting.py?id=dbaee2672be14374acb17266477c19294c6155f3 + +def highlight_code(data, filename): + formatter = HtmlFormatter(style='sas', nobackground=True, linenos=True) + try: + lexer = guess_lexer_for_filename(filename, data) + except ClassNotFound: + if data.startswith('#!'): + lexer = guess_lexer(data) + else: + lexer = TextLexer() + except TypeError: + lexer = TextLexer() + css = formatter.get_style_defs('.highlight') + highlighted = highlight(data, lexer, formatter) + return f'{highlighted}' \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 1da7394..39f0eec 100644 --- a/requirements.txt +++ b/requirements.txt @@ -9,5 +9,6 @@ MarkupSafe==3.0.3 packaging==25.0 pycparser==2.23 pygit2==1.19.0 +Pygments==2.19.2 python-dotenv==1.2.1 Werkzeug==3.1.3 diff --git a/templates/blob.html b/templates/blob.html index f75c70d..e49ee3d 100644 --- a/templates/blob.html +++ b/templates/blob.html @@ -5,10 +5,9 @@

Blob id: {{ blob.id }}

Size: {{ blob.size }} bytes

Blame

-

Content:

{% if blob.is_binary %}
Binary...
{% else %} -
{{ blob.content }}
+{{ blob.highlighted|safe }} {% endif %} {% endblock %} \ No newline at end of file -- 2.47.3