From 560f081852a8b04bcb628d7396d13a22c00ffa26 Mon Sep 17 00:00:00 2001 From: Demonstrandum Date: Wed, 5 Aug 2020 20:43:12 +0100 Subject: [PATCH] Add synatx highlighting with Pygment. --- Gemfile | 4 ++++ Gemfile.lock | 25 +++++++++++++++++++++++++ Makefile | 3 ++- highlight | 29 +++++++++++++++++++++++++++++ repo-gen.sh | 2 +- stagit.c | 46 +++++++++++++++++++++++++--------------------- style.css | 14 +++++++++++--- 7 files changed, 97 insertions(+), 26 deletions(-) create mode 100644 Gemfile create mode 100644 Gemfile.lock create mode 100755 highlight diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..9452483 --- /dev/null +++ b/Gemfile @@ -0,0 +1,4 @@ +source 'https://rubygems.org' + +gem 'github-linguist' +gem 'pygments.rb' diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 0000000..86591cb --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,25 @@ +GEM + remote: https://rubygems.org/ + specs: + charlock_holmes (0.7.7) + escape_utils (1.2.1) + github-linguist (7.9.0) + charlock_holmes (~> 0.7.6) + escape_utils (~> 1.2.0) + mini_mime (~> 1.0) + rugged (>= 0.25.1) + mini_mime (1.0.2) + multi_json (1.15.0) + pygments.rb (1.2.1) + multi_json (>= 1.0.0) + rugged (1.0.1) + +PLATFORMS + ruby + +DEPENDENCIES + github-linguist + pygments.rb + +BUNDLED WITH + 2.1.2 diff --git a/Makefile b/Makefile index 56b52e6..1b2750e 100644 --- a/Makefile +++ b/Makefile @@ -63,7 +63,8 @@ dist: ${OBJ}: ${HDR} -stagit.out: stagit.o ${COMPATOBJ} +stagit.out: stagit.o ${COMPATOBJ} Gemfile + bundle install ${CC} -o $@ stagit.o ${COMPATOBJ} ${STAGIT_LDFLAGS} stagit-index.out: stagit-index.o ${COMPATOBJ} diff --git a/highlight b/highlight new file mode 100755 index 0000000..c67e703 --- /dev/null +++ b/highlight @@ -0,0 +1,29 @@ +#!/usr/bin/env ruby + +require 'linguist' +require 'pygments' + +stdin = ARGF.file + +filename = stdin.readline.strip # Read first line (filename). +contents = stdin.read # Read rest (code). + +detected = Linguist::FileBlob.new(filename).language + +# Debugging +#puts "File #{filename}" +#puts "Code: +#{contents}" +#print "Language: " +#pp detected + +html = Pygments.highlight(contents, + :lexer => detected.name, + :formatter => 'html', + :options => { + :encoding => 'utf-8', + :linenos => 'table', + :lineanchors => 'loc', + :anchorlinenos => true}) + +puts html diff --git a/repo-gen.sh b/repo-gen.sh index afae930..b58559f 100755 --- a/repo-gen.sh +++ b/repo-gen.sh @@ -36,5 +36,5 @@ echo "Generating index.html with \`$STAGIT_INDEX\`." "$STAGIT_INDEX" /srv/git/*.git > /var/www/git/index.html # Correct ownership of the web files. -chowm git:www-data -R /var/www/git -f +chown git:www-data -R /var/www/git -f chmod g+rw -R /var/www/git -f diff --git a/stagit.c b/stagit.c index e823fba..20f6b65 100644 --- a/stagit.c +++ b/stagit.c @@ -394,36 +394,40 @@ writefooter(FILE *fp) fputs("\n\n\n", fp); } +void +syntax_highlight(const char *fpath, FILE *fp, const char *s, size_t len) +{ + // Ruby script for syntax highlighting. + FILE *child = popen("./highlight", "w"); + // Give filename: + fprintf(child, "%s\n", fpath); + // Give code to highlight: + size_t i; + for (i = 0; *s && i < len; s++, i++) + fputc(*s, child); + + // Write returned HTML to the HTML file. + char c; + while ((c = fgetc(child)) != EOF) + fputc(c, fp); + + pclose(child); +} + int -writeblobhtml(FILE *fp, const git_blob *blob) +writeblobhtml(const char *fpath, FILE *fp, const git_blob *blob) { size_t n = 0, i, prev; - const char *nfmt = "%7d"; const char *s = git_blob_rawcontent(blob); git_off_t len = git_blob_rawsize(blob); - fputs("
\n", fp);
+	fputs("
\n", fp); if (len > 0) { - for (i = 0, prev = 0; i < (size_t)len; i++) { - if (s[i] != '\n') - continue; - n++; - fprintf(fp, nfmt, n, n, n); - xmlencode(fp, &s[prev], i - prev + 1); - fprintf(fp, ""); - prev = i + 1; - } - /* trailing data */ - if ((len - prev) > 0) { - n++; - fprintf(fp, nfmt, n, n, n); - xmlencode(fp, &s[prev], len - prev); - fprintf(fp, ""); - } + syntax_highlight(fpath, fp, s, len); } - fputs("
\n", fp); + fputs("\n", fp); return n; } @@ -791,7 +795,7 @@ writeblob(git_object *obj, const char *fpath, const char *filename, git_off_t fi if (git_blob_is_binary((git_blob *)obj)) { fputs("

Binary file.

\n", fp); } else { - lc = writeblobhtml(fp, (git_blob *)obj); + lc = writeblobhtml(fpath, fp, (git_blob *)obj); if (ferror(fp)) err(1, "fwrite"); } diff --git a/style.css b/style.css index 02a9d97..c35d6e9 100644 --- a/style.css +++ b/style.css @@ -35,14 +35,22 @@ a.line { text-decoration: none; } -.loc { - margin-left: 0.9em; +#blob { + display: block; + max-width: 100%; + overflow-x: scroll; } -.line { +.linenos { user-select: none; } +.linenos a { + margin-right: 0.9em; + user-select: none; + text-decoration: none; +} + #blob a { color: #777; } -- 2.39.2