stagit

HTML changes

Updated css

Fixed README and added a link to the original repo

Moved all static assets to point remote locations instead of local

Added a todo.md

Moved away from inline JS to navbar-active.js

Moved post-commit-hook to the repo

Arjun Choudhary contact@arjunchoudhary.com

commit: f6e994a parent: a3b214d
10 files changed, 332 insertions(+), 369 deletions(-)
MREADME.md+6-20
Aindex.html+34-0
Anavbar-active.js+5-0
Dstagit+0-0
Dstagit-index+0-0
Dstagit-index.1+0-47
Mstagit-index.c+13-16
Dstagit.1+0-125
Mstagit.c+21-33
Mstyle.css+253-128
M · README.md +6, -20
 1@@ -2,6 +2,9 @@ Static git page generator.
 2 
 3 It generates static HTML pages for a git repository.
 4 
 5+## Original Repo
 6+The original stagit repo can be found at https://git.codemadness.org/stagit/
 7+
 8 ## Changes
 9 This is my personal fork of stagit.    
10 It has been modified to fit my needs and some refs points
11@@ -10,12 +13,12 @@ you are stuck on some change.
12 
13 * Added functionality to view raw files
14 * Preserves the structure of directories in the files view
15-* Syntax highlighting using (chroma)[https://github.com/alecthomas/chroma] (pygments and linguist for both super slow and had other issues)
16+* Syntax highlighting using [chroma](https://github.com/alecthomas/chroma) (both pygments and linguist were slow and had lexer issues)
17 * The index page now links to the README.md file - hard dependency that the file needs to exist in the repo and be a valid .md file
18-* (md4c)[https://github.com/mity/md4c] has been added to parse markdown files
19+* [md4c](https://github.com/mity/md4c) has been added to parse markdown files
20 * Add classes and ids for better style targetting
21 * Draws elements (like the sidebar for example) to match the hugo site on the main domain
22-* Styling changes to improve responsive-ness and add personalized css 
23+* Styling changes to improve "responsive-ness" and add personalized css 
24 
25 Changes such as adding md4c and chroma were done while trying to preserve the speed of generating the static files.
26 
27@@ -83,25 +86,8 @@ else:
28     print("Content-Type: text/plain")
29     print()
30     print("404: File not found")
31-
32 ``` 
33 
34-The index page linking to the directory will not change the default 
35-behavior of stagit if the html files have been created with the [provided 
36-shell script](example_create.sh.html), since log.html is symlinked
37-to index.html.    
38-
39-This change was made so that the web-server could check if the
40-request is for a directory. If it is check if there is a file called 
41-README.md.html in the sub-directory file, if it exists serve that 
42-file instead of log.html.
43-
44-Lighttpd conf to implement this:
45-
46-    url.redirect = ( "^\/stagit\/([a-zA-Z0-9-_.,]\/$" => "/stagit/$1/file/README.md" )
47-    url.rewrite-if-not-file = ( "^\/stagit/([a-zA-Z0-9-_,.]*)\/file\/README.md.html$" => /redirect/$1" )
48-    url.redirect += ( "^\/redirect/\([a-zA-Z0-9-_,.]*)" => "/stagit/$1/log.html" )
49-
50 ### md4c
51 md4c is used to parse and convert markdown documents into html. If a file 
52 ends with `.md` it will be parsed by md4c rather than the regular way 
A · index.html +34, -0
 1@@ -0,0 +1,34 @@
 2+<!DOCTYPE html>
 3+<html>
 4+<head>
 5+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
 6+<meta name="viewport" content="width=device-width, initial-scale=1" />
 7+<title>Repositories</title>
 8+<link rel="icon" type="image/png" href="favicon.png" />
 9+<link rel="stylesheet" type="text/css" href="style.css" />
10+</head>
11+<body>
12+<div id="container">
13+<div id="sidebar">
14+<a id="logo" href="https://arjunchoudhary.com">
15+<div id="typing">ARJUN</div>
16+<hr id="cursor"/>
17+</a>
18+<img id="profile_img" src="me.webp" alt="my_profile_image"/>
19+<div><a id="contact" href="mailto:contact@arjunchoudhary.com">Contact</a> | <a id="contact" href="https://arjunchoudhary.com/public">PGP</a>
20+</div></div>
21+<div id="main-view">
22+<div id="header"><h1 id="repositories">Repositories</h1><div id="subtitle"><span class="desc"> Somewhat sorted collection of some of my projects. </span></div></div></td></tr>
23+</table>
24+<div id="content">
25+<table id="index"><thead>
26+<tr><td><b>Name</b></td><td><b>Description</b></td><td><b>Owner</b></td><td><b>Last commit</b></td></tr></thead><tbody>
27+<tr><td><a href="2dPathFindingVis/file/README.md.html">2dPathFindingVis</a></td><td>Unnamed repository; edit this file &#39;description&#39; to name the repository.
28+</td><td></td><td>2022-04-20 08:33</td></tr><tr><td><a href="stagit/file/README.md.html">stagit</a></td><td>Unnamed repository; edit this file &#39;description&#39; to name the repository.
29+</td><td></td><td>2022-06-06 11:15</td></tr></tbody>
30+</table>
31+</div>
32+</div>
33+</div>
34+</body>
35+</html>
A · navbar-active.js +5, -0
1@@ -0,0 +1,5 @@
2+for (var i = 0; i < document.links.length; i++) {
3+    if (document.links[i].href === document.URL) {
4+        document.links[i].className = "current";
5+    }
6+}
D · stagit +0, -0
D · stagit-index +0, -0
D · stagit-index.1 +0, -47
 1@@ -1,47 +0,0 @@
 2-.Dd August 2, 2021
 3-.Dt STAGIT-INDEX 1
 4-.Os
 5-.Sh NAME
 6-.Nm stagit-index
 7-.Nd static git index page generator
 8-.Sh SYNOPSIS
 9-.Nm
10-.Op Ar repodir...
11-.Sh DESCRIPTION
12-.Nm
13-will create an index HTML page for the repositories specified and writes
14-the HTML data to stdout.
15-The repos in the index are in the same order as the arguments
16-.Ar repodir
17-specified.
18-.Pp
19-The basename of the directory is used as the repository name.
20-The suffix ".git" is removed from the basename, this suffix is commonly used
21-for "bare" repos.
22-.Pp
23-The content of the follow files specifies the meta data for each repository:
24-.Bl -tag -width Ds
25-.It .git/description or description (bare repos).
26-description
27-.It .git/owner or owner (bare repo).
28-owner of repository
29-.El
30-.Pp
31-For changing the style of the page you can use the following files:
32-.Bl -tag -width Ds
33-.It favicon.png
34-favicon image.
35-.It logo.png
36-32x32 logo.
37-.It style.css
38-CSS stylesheet.
39-.El
40-.Sh EXAMPLES
41-.Bd -literal
42-cd htmlroot
43-stagit-index path/to/gitrepo1 path/to/gitrepo2 > index.html
44-.Ed
45-.Sh SEE ALSO
46-.Xr stagit 1
47-.Sh AUTHORS
48-.An Hiltjo Posthuma Aq Mt hiltjo@codemadness.org
M · stagit-index.c +13, -16
 1@@ -106,23 +106,20 @@ void writeheader(FILE* fp)
 2           "<title>",
 3         fp);
 4     xmlencode(fp, description, strlen(description));
 5-    fprintf(fp, "</title>\n<link rel=\"icon\" type=\"image/png\" href=\"%sfavicon.png\" />\n", relpath);
 6-    fprintf(fp, "<link rel=\"stylesheet\" type=\"text/css\" href=\"%sstyle.css\" />\n", relpath);
 7-    fprintf(fp, "<link rel=\"stylesheet\" type=\"text/css\" href=\"%sindex-style.css\" />\n", relpath);
 8-    fputs("</head>\n<body>\n<div id=\"container\">\n<div id=\"sidebar\">\n<a id=\"logo\" href=\"https://arjun.lol\">\n<div id=\"typing\">ARJUN</div>\n<hr id=\"cursor\"/>\n</a>\n<img id=\"profile_img\" src=\"me.webp\" alt=\"my_profile_image\"/>\n<div><a id=\"contact\" href=\"mailto:contact@arjunchoudhary.com\">Contact</a> | <a id=\"contact\" href=\"https://arjun.lol/public_pgp\">PGP</a>\n</div></div>\n<div id=\"main-view\">\n", fp);
 9+    fprintf(fp, "</title>\n<link rel=\"icon\" type=\"image/png\" href=\"https://git.arjun.lol/favicon.png\" />\n");
10+    fprintf(fp, "<link rel=\"stylesheet\" type=\"text/css\" href=\"https://git.arjun.lol/style.css\" />\n");
11+    fprintf(fp, "<link rel=\"stylesheet\" type=\"text/css\" href=\"https://git.arjun.lol/index-style.css\" />\n");
12+    fputs("</head>\n<body>\n<div id=\"container\">\n<div id=\"sidebar\">\n<a id=\"logo\" href=\"https://arjun.lol\">\n<div id=\"typing\">ARJUN</div>\n<hr id=\"cursor\"/>\n</a>\n<img id=\"profile_img\" src=\"https://git.arjun.lol/me.webp\" alt=\"my_profile_image\"/>\n<div><a id=\"contact\" href=\"mailto:contact@arjunchoudhary.com\">Contact</a> | <a id=\"contact\" href=\"https://arjun.lol/public_pgp\">PGP</a>\n</div></div>\n<div id=\"main-view\">\n", fp);
13+    fputs("<ul class=\"breadcrumb\"><li><a href=\"https://arjun.lol\">Home</a></li><li><a href=\"https://git.arjun.lol\">Repositories</a></li></ul>", fp);
14     fprintf(fp, "<div id=\"header\"><h1 id=\"repositories\">");
15     xmlencode(fp, description, strlen(description));
16     fputs("</h1><div id=\"subtitle\"><span class=\"desc\"> Somewhat sorted collection of some of my projects. | </span><a href=\"https://arjun.lol\">Back</a></div></div></td></tr>\n</table>\n<div id=\"content\">\n"
17-          "<table id=\"index\"><thead>\n"
18-          "<tr><td><b>Name</b></td><td><b>Description</b></td><td><b>Owner</b></td>"
19-          "<td><b>Last commit</b></td></tr>"
20-          "</thead><tbody>\n",
21-        fp);
22+          "<div id=\"index\">\n",fp);
23 }
24 
25 void writefooter(FILE* fp)
26 {
27-    fputs("</tbody>\n</table>\n</div>\n</div>\n</div>\n</body>\n</html>\n", fp);
28+    fputs("</div>\n</div>\n<footer><nav><ul><li><a href=\"https://creativecommons.org/licenses/by-sa/4.0/\">License</a></li><li><a href=\"https://arjun.lol/privacy\">Privacy</a></li><li><a href=\"https://git.arjun.lol/Stagit/file/README.md.html\">Source</a></li><li><a href=\"https://arjun.lol/usage\">Usage</a></li></ul></nav></footer>\n</div>\n</div>\n</body>\n</html>\n", fp);
29 }
30 
31 int writelog(FILE* fp)
32@@ -151,18 +148,18 @@ int writelog(FILE* fp)
33         if (!strcmp(p, ".git"))
34             *p = '\0';
35 
36-    fputs("<tr><td><a href=\"", fp);
37+    fputs("<h2><a href=\"", fp);
38     percentencode(fp, stripped_name, strlen(stripped_name));
39     fputs("/file/README.md.html\">", fp);
40     xmlencode(fp, stripped_name, strlen(stripped_name));
41-    fputs("</a></td><td>", fp);
42+    fputs("</a></h2><p>", fp);
43     xmlencode(fp, description, strlen(description));
44-    fputs("</td><td>", fp);
45-    xmlencode(fp, owner, strlen(owner));
46-    fputs("</td><td>", fp);
47+    fputs("</p>", fp);
48+/*     xmlencode(fp, owner, strlen(owner));
49+    fputs("</p><p>", fp);
50     if (author)
51         printtimeshort(fp, &(author->when));
52-    fputs("</td></tr>", fp);
53+    fputs("</p>", fp); */
54 
55     git_commit_free(commit);
56 err:
D · stagit.1 +0, -125
  1@@ -1,125 +0,0 @@
  2-.Dd August 2, 2021
  3-.Dt STAGIT 1
  4-.Os
  5-.Sh NAME
  6-.Nm stagit
  7-.Nd static git page generator
  8-.Sh SYNOPSIS
  9-.Nm
 10-.Op Fl c Ar cachefile
 11-.Op Fl l Ar commits
 12-.Op Fl u Ar baseurl
 13-.Ar repodir
 14-.Sh DESCRIPTION
 15-.Nm
 16-writes HTML pages for the repository
 17-.Ar repodir
 18-to the current directory.
 19-.Pp
 20-The options are as follows:
 21-.Bl -tag -width Ds
 22-.It Fl c Ar cachefile
 23-Cache the entries of the log page up to the point of
 24-the last commit.
 25-The
 26-.Ar cachefile
 27-will store the last commit id and the entries in the HTML table.
 28-It is up to the user to make sure the state of the
 29-.Ar cachefile
 30-is in sync with the history of the repository.
 31-.It Fl l Ar commits
 32-Write a maximum number of
 33-.Ar commits
 34-to the log.html file only.
 35-However the commit files are written as usual.
 36-.It Fl u Ar baseurl
 37-Base URL to make links in the Atom feeds absolute.
 38-For example: "https://git.codemadness.org/stagit/".
 39-.El
 40-.Pp
 41-The options
 42-.Fl c
 43-and
 44-.Fl l
 45-cannot be used at the same time.
 46-.Pp
 47-The following files will be written:
 48-.Bl -tag -width Ds
 49-.It atom.xml
 50-Atom XML feed of the last 100 commits.
 51-.It tags.xml
 52-Atom XML feed of the tags.
 53-.It files.html
 54-List of files in the latest tree, linking to the file.
 55-.It log.html
 56-List of commits in reverse chronological applied commit order, each commit
 57-links to a page with a diffstat and diff of the commit.
 58-.It refs.html
 59-Lists references of the repository such as branches and tags.
 60-.El
 61-.Pp
 62-For each entry in HEAD a file will be written in the format:
 63-file/filepath.html.
 64-This file will contain the textual data of the file prefixed by line numbers.
 65-The file will have the string "Binary file" if the data is considered to be
 66-non-textual.
 67-.Pp
 68-For each commit a file will be written in the format:
 69-commit/commitid.html.
 70-This file will contain the diffstat and diff of the commit.
 71-It will write the string "Binary files differ" if the data is considered to
 72-be non-textual.
 73-Too large diffs will be suppressed and a string
 74-"Diff is too large, output suppressed" will be written.
 75-.Pp
 76-When a commit HTML file exists it won't be overwritten again, note that if
 77-you've changed
 78-.Nm
 79-or changed one of the metadata files of the repository it is recommended to
 80-recreate all the output files because it will contain old data.
 81-To do this remove the output directory and
 82-.Ar cachefile ,
 83-then recreate the files.
 84-.Pp
 85-The basename of the directory is used as the repository name.
 86-The suffix ".git" is removed from the basename, this suffix is commonly used
 87-for "bare" repos.
 88-.Pp
 89-The content of the follow files specifies the metadata for each repository:
 90-.Bl -tag -width Ds
 91-.It .git/description or description (bare repo).
 92-description
 93-.It .git/owner or owner (bare repo).
 94-owner of repository
 95-.It .git/url or url (bare repo).
 96-primary clone URL of the repository, for example:
 97-git://git.codemadness.org/stagit
 98-.El
 99-.Pp
100-When a README or LICENSE file exists in HEAD or a .gitmodules submodules file
101-exists in HEAD a direct link in the menu is made.
102-.Pp
103-For changing the style of the page you can use the following files:
104-.Bl -tag -width Ds
105-.It favicon.png
106-favicon image.
107-.It logo.png
108-32x32 logo.
109-.It style.css
110-CSS stylesheet.
111-.El
112-.Sh EXIT STATUS
113-.Ex -std
114-.Sh EXAMPLES
115-.Bd -literal
116-mkdir -p htmlroot/htmlrepo1 && cd htmlroot/htmlrepo1
117-stagit path/to/gitrepo1
118-# repeat for other repositories.
119-.Ed
120-.Pp
121-To update the HTML files when the repository is changed a git post-receive hook
122-can be used, see the file example_post-receive.sh for an example.
123-.Sh SEE ALSO
124-.Xr stagit-index 1
125-.Sh AUTHORS
126-.An Hiltjo Posthuma Aq Mt hiltjo@codemadness.org
M · stagit.c +21, -33
  1@@ -520,15 +520,21 @@ void writeheader(FILE* fp, const char* title)
  2     if (description[0])
  3         fputs(" - ", fp);
  4     xmlencode(fp, description, strlen(description));
  5-    fprintf(fp, "</title>\n<link rel=\"icon\" type=\"image/png\" href=\"%sfavicon.png\" />\n", relpath);
  6+    fprintf(fp, "</title>\n<link rel=\"icon\" type=\"image/png\" href=\"https://git.arjun.lol/favicon.png\" />\n");
  7     fputs("<link rel=\"alternate\" type=\"application/atom+xml\" title=\"", fp);
  8     xmlencode(fp, name, strlen(name));
  9     fprintf(fp, " Atom Feed\" href=\"%satom.xml\" />\n", relpath);
 10     fputs("<link rel=\"alternate\" type=\"application/atom+xml\" title=\"", fp);
 11     xmlencode(fp, name, strlen(name));
 12     fprintf(fp, " Atom Feed (tags)\" href=\"%stags.xml\" />\n", relpath);
 13-    fprintf(fp, "<link rel=\"stylesheet\" type=\"text/css\" href=\"%sstyle.css\" />\n", relpath);
 14-    fputs("</head>\n<body>\n<div id=\"container\">\n<div id=\"sidebar\">\n<a id=\"logo\" href=\"https://git.arjun.lol\">\n<div id=\"typing\">ARJUN</div>\n<hr id=\"cursor\"/>\n</a>\n<img id=\"profile_img\" src=\"me.webp\" alt=\"my_profile_image\"/>\n<div><a id=\"contact\" href=\"mailto:contact@arjunchoudhary.com\">Contact</a> | <a id=\"contact\" href=\"https://arjun.lol/public_pgp\">PGP</a>\n</div></div>\n<div id=\"main-view\">\n", fp);
 15+    fprintf(fp, "<link rel=\"stylesheet\" type=\"text/css\" href=\"https://git.arjun.lol/style.css\" />\n");
 16+    fputs("</head>\n<body>\n<div id=\"container\">\n<div id=\"sidebar\">\n<a id=\"logo\" href=\"https://git.arjun.lol\">\n", fp);
 17+    fputs("<div id=\"typing\">ARJUN</div>\n<hr id=\"cursor\"/>\n</a>\n<img id=\"profile_img\" src=\"https://git.arjun.lol/me.webp\" alt=\"my_profile_image\"/>\n<div><a id=\"contact\" href=\"mailto:contact@arjunchoudhary.com\">Contact</a> | <a id=\"contact\" href=\"https://arjun.lol/public_pgp\">PGP</a>\n</div></div>\n", fp);
 18+    fputs("<div id=\"main-view\">\n<ul class=\"breadcrumb\"><li><a href=\"https://arjun.lol\">Home</a></li><li><a href=\"https://git.arjun.lol\">Repositories</a></li>", fp);
 19+    fprintf(fp, "<li><a href=\"%sfile/%s.html\">", relpath, readme);
 20+    xmlencode(fp, strippedname, strlen(strippedname));
 21+    fputs("</a></li>", fp);
 22+    fputs("</ul>", fp);
 23     fputs("<div id=\"header\">", fp);
 24     fputs("<h1>", fp);
 25     xmlencode(fp, strippedname, strlen(strippedname));
 26@@ -564,7 +570,7 @@ void writeheader(FILE* fp, const char* title)
 27 
 28 void writefooter(FILE* fp)
 29 {
 30-    fputs("</div>\n</div>\n</div>\n<script nonce=\"TGV0c0Z1Y2tpbmdHb0xtYW9w\" >for (var i = 0; i < document.links.length; i++) { if (document.links[i].href === document.URL) {document.links[i].className = 'current';}}</script>\n</body>\n</html>\n", fp);
 31+    fputs("</div><footer><nav><ul><li><a href=\"https://creativecommons.org/licenses/by-sa/4.0/\">License</a></li><li><a href=\"https://arjun.lol/privacy\">Privacy</a></li><li><a href=\"https://git.arjun.lol/Stagit/file/README.md.html\">Source</a></li><li><a href=\"https://arjun.lol/usage\">Usage</a></li></ul></nav></footer>\n</div>\n</div>\n</div>\n<script src=\"https://git.arjun.lol/navbar.js\"></script></body>\n</html>\n", fp);
 32 }
 33 
 34 void processmd(const char* output, unsigned int len, void* fp)
 35@@ -647,22 +653,6 @@ writeblobhtml(const char* filename, FILE* fp, const git_blob* blob)
 36 
 37     if (len > 0) {
 38         syntax_highlight(filename, fp, s, len);
 39-        /* Uncomment to render the original file (no syntax highlight) */
 40-        /* 		for (i = 0, prev = 0; i < len; i++) {
 41-                                if (s[i] != '\n')
 42-                                        continue;
 43-                                n++;
 44-                                fprintf(fp, nfmt, n, n, n);
 45-                                xmlencodeline(fp, &s[prev], i - prev + 1);
 46-                                putc('\n', fp);
 47-                                prev = i + 1;
 48-                        } */
 49-        /* trailing data */
 50-        /* 		if ((len - prev) > 0) {
 51-                                n++;
 52-                                fprintf(fp, nfmt, n, n, n);
 53-                                xmlencodeline(fp, &s[prev], len - prev);
 54-                        } */
 55     }
 56     fputs("</pre>\n", fp);
 57 
 58@@ -671,11 +661,11 @@ writeblobhtml(const char* filename, FILE* fp, const git_blob* blob)
 59 
 60 void printcommit(FILE* fp, struct commitinfo* ci)
 61 {
 62-    fprintf(fp, "<b>commit</b> <a href=\"%scommit/%s.html\">%s</a>\n",
 63+    fprintf(fp, "<b>commit:</b> <a href=\"%scommit/%s.html\">%s</a>\n",
 64         relpath, ci->oid, ci->oid);
 65 
 66     if (ci->parentoid[0])
 67-        fprintf(fp, "<b>parent</b> <a href=\"%scommit/%s.html\">%s</a>\n",
 68+        fprintf(fp, "<b>parent:</b> <a href=\"%scommit/%s.html\">%s</a>\n",
 69             relpath, ci->parentoid, ci->parentoid);
 70 
 71     if (ci->author) {
 72@@ -705,7 +695,6 @@ void printshowfile(FILE* fp, struct commitinfo* ci)
 73     size_t nhunks, nhunklines, changed, add, del, total, i, j, k;
 74     char linestr[80];
 75     int c;
 76-
 77     printcommit(fp, ci);
 78 
 79     if (!ci->deltas)
 80@@ -776,7 +765,7 @@ void printshowfile(FILE* fp, struct commitinfo* ci)
 81         fwrite(&linestr[add], 1, del, fp);
 82         fputs("</span></td></tr>\n", fp);
 83     }
 84-    fprintf(fp, "</table></pre><pre>%zu file%s changed, %zu insertion%s(+), %zu deletion%s(-)\n",
 85+    fprintf(fp, "</table>%zu file%s changed, %zu insertion%s(+), %zu deletion%s(-)\n</pre>",
 86         ci->filecount, ci->filecount == 1 ? "" : "s",
 87         ci->addcount, ci->addcount == 1 ? "" : "s",
 88         ci->delcount, ci->delcount == 1 ? "" : "s");
 89@@ -784,27 +773,24 @@ void printshowfile(FILE* fp, struct commitinfo* ci)
 90     for (i = 0; i < ci->ndeltas; i++) {
 91         patch = ci->deltas[i]->patch;
 92         delta = git_patch_get_delta(patch);
 93-        fprintf(fp, "<b id=\"diff\">diff --git a/<a id=\"h%zu\" href=\"%sfile/", i, relpath);
 94-        percentencode(fp, delta->old_file.path, strlen(delta->old_file.path));
 95-        fputs(".html\">", fp);
 96-        xmlencode(fp, delta->old_file.path, strlen(delta->old_file.path));
 97-        fprintf(fp, "</a> b/<a href=\"%sfile/", relpath);
 98+        fprintf(fp, "<div id=\"diff-container\">");
 99+        fprintf(fp, "<span id=\"diff-name\"><a id=\"h%zu\" href=\"%sfile/", i, relpath);
100         percentencode(fp, delta->new_file.path, strlen(delta->new_file.path));
101         fprintf(fp, ".html\">");
102         xmlencode(fp, delta->new_file.path, strlen(delta->new_file.path));
103-        fprintf(fp, "</a></b>\n");
104+        fprintf(fp, "</a></span>\n");
105 
106         /* check binary data */
107         if (delta->flags & GIT_DIFF_FLAG_BINARY) {
108-            fputs("Binary files differ.\n", fp);
109+            fputs("Binary files differ.\n</pre>\n</div>", fp);
110             continue;
111         }
112 
113         nhunks = git_patch_num_hunks(patch);
114+        fprintf(fp, "<pre id=\"diff-code\">");
115         for (j = 0; j < nhunks; j++) {
116             if (git_patch_get_hunk(&hunk, &nhunklines, patch, j))
117                 break;
118-
119             fprintf(fp, "<a href=\"#h%zu-%zu\" id=\"h%zu-%zu\" class=\"h\">", i, j, i, j);
120             xmlencode(fp, hunk->header, hunk->header_len);
121             fputs("</a>", fp);
122@@ -824,8 +810,10 @@ void printshowfile(FILE* fp, struct commitinfo* ci)
123                 putc('\n', fp);
124                 if (line->old_lineno == -1 || line->new_lineno == -1)
125                     fputs("</a>", fp);
126-            }
127+            }    
128         }
129+        fprintf(fp, "</pre>\n");
130+        fprintf(fp, "</div>");
131     }
132 }
133 
M · style.css +253, -128
  1@@ -1,41 +1,22 @@
  2-@font-face {
  3-    font-family: "Inter";
  4-    font-style: normal;
  5-    font-weight: 400;
  6-    font-display: swap;
  7-    src: url("../fonts/inter-regular-latin.woff2") format("woff2");
  8-}
  9-
 10-@font-face {
 11-    font-family: "Inter";
 12-    font-style: normal;
 13-    font-weight: 500;
 14-    font-display: swap;
 15-    src: url("../fonts/inter-medium-latin.woff2") format("woff2");
 16-}
 17-
 18-@font-face {
 19-    font-family: "Inter";
 20-    font-style: normal;
 21-    font-weight: 600;
 22-    font-display: swap;
 23-    src: url("../fonts/inter-semi-bold-latin.woff2") format("woff2");
 24-}
 25-
 26-@font-face {
 27-    font-family: "JetBrains Mono";
 28-    font-style: normal;
 29-    font-weight: 500;
 30-    font-display: swap;
 31-    src: url("../fonts/jetbrains-mono-nl-medium-latin.woff2") format("woff2");
 32-}
 33-
 34 :root {
 35     --link: #0969da;
 36     --scrollbar: #dedede;
 37-    --text: #1d1d1d;
 38-    --background: #fafafa;
 39+    --text: #404040;
 40+    --header: #000000;
 41+    --background: #ffffff;
 42     --border: #e8e8e8;
 43+    --sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
 44+        Helvetica, "Helvetica Neue", Arial, Ubuntu, noto, Cantarell, sans-serif,
 45+        "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
 46+    --heading: "Inter", -apple-system, BlinkMacSystemFont, Roboto, Ubuntu,
 47+        "Liberation Sans", "Noto Sans", Fira Sans, Droid Sans, "Helvetica",
 48+        "Helvetica Neue", Arial, system-ui, sans-serif;
 49+    --serif: "PlayFair Display", "Apple Garamond", "Baskerville",
 50+        "Times New Roman", "Droid Serif", "Times", "Source Serif Pro", serif;
 51+    --mono: "JetBrains Mono", "SF Mono", Menlo, "Ubuntu Mono", "Monaco",
 52+        "Cascadia Mono", "Segoe UI Mono", "Inconsolata", "Fira Mono",
 53+        "Droid Sans Mono", "Noto Sans Mono Condensed", "Liberation Mono",
 54+        "Source Code Pro", Consolas, ui-monospace, monospace;
 55 }
 56 
 57 ::-webkit-scrollbar {
 58@@ -58,18 +39,28 @@
 59 * {
 60     scrollbar-width: thin;
 61     scrollbar-color: var(--scrollbar) transparent;
 62+    box-sizing: border-box;
 63+    scroll-behavior: smooth;
 64+}
 65+
 66+*::before,
 67+*::after {
 68+    box-sizing: border-box;
 69+    scroll-behavior: smooth;
 70 }
 71 
 72 html {
 73-    font-size: calc(16px + 0.15vw);
 74+    font-size: calc(17px + 0.025vw);
 75 }
 76 
 77 body {
 78+    transition: color .35s,background-color .35s;
 79     margin: 0;
 80     color: var(--text);
 81     background-color: var(--background);
 82-    font-family: "Inter", sans-serif;
 83+    font-family: var(--sans);
 84     overflow-x: hidden;
 85+    box-sizing: border-box;
 86 }
 87 
 88 *::before,
 89@@ -94,31 +85,35 @@ a:hover {
 90 }
 91 
 92 #navbar > a {
 93-    padding: 0.55em 0.85em;
 94+    width: 100%;
 95+    text-align: center;
 96+    padding: 0.55em 0.45em;
 97     line-height: normal;
 98-    border-radius: 10px;
 99     color: currentColor;
100+    border-bottom: 2px dashed var(--border);
101+}
102+
103+#navbar > a:hover {
104+   color: var(--link);
105 }
106 
107 #navbar .current {
108-    color: white;
109-    background: grey;
110+    font-weight: 600;
111+    color: var(--link);
112+    border-bottom: 2px solid var(--link);
113 }
114 
115 #repositories {
116     font-weight: 600;
117-    margin-top: 1.5rem;
118-    margin-bottom: 1.5rem;
119     font-size: 2rem;
120-    line-height: 1;
121 }
122 
123 #header > h1 {
124-    font-weight: 600;
125-    margin-top: 1.5rem;
126-    margin-bottom: 0.6rem;
127+    color: var(--header);
128+    font-family: var(--heading);
129     font-size: 2rem;
130-    line-height: 1;
131+    margin-top: 0em;
132+    margin-bottom: 0.25em;
133 }
134 
135 #sidebar {
136@@ -138,7 +133,7 @@ a:hover {
137 #profile_img {
138     width: fit-content;
139     width: 50%;
140-    max-width: 350px;
141+    max-width: 200px;
142     margin: 2em 1em;
143     border: 0px solid;
144     border-radius: 15%;
145@@ -153,18 +148,18 @@ a:hover {
146 }
147 
148 @keyframes cursor-blinking-animation {
149-  from,
150-  to {
151-    visibility: hidden;
152-  }
153-  50% {
154-    visibility: visible;
155-  }
156+    from,
157+    to {
158+        visibility: hidden;
159+    }
160+    50% {
161+        visibility: visible;
162+    }
163 }
164 
165 #cursor {
166-    background-color: var(--text);
167-    color: var(--text);
168+    background-color: var(--header);
169+    color: var(--header);
170     animation: cursor-blinking-animation 1.2s step-end infinite;
171     border: none;
172     height: 2.2em;
173@@ -175,15 +170,15 @@ a:hover {
174 }
175 
176 #logo {
177-  position: absolute;
178-  color: currentColor;
179-  top: 0;
180-  display: flex;
181-  align-items: center;
182-  cursor: pointer;
183-  justify-content: center;
184-  text-decoration: none;
185-  margin-top: 1.5rem;
186+    position: absolute;
187+    color: var(--header);
188+    top: 0;
189+    display: flex;
190+    align-items: center;
191+    cursor: pointer;
192+    justify-content: center;
193+    text-decoration: none;
194+    margin-top: 1.5rem;
195 }
196 
197 .logo:hover {
198@@ -197,22 +192,71 @@ a:hover {
199 }
200 
201 #main-view {
202-    overflow-y: auto;
203-    width: 100%;
204     line-height: 1.5;
205+    word-wrap: wrap;
206+    display: flex;
207+    flex-direction: column;
208+    align-items: flex-start;
209+    justify-content: flex-start;
210+    width: 100%;
211+    overflow-y: scroll;
212+    overflow-x: hidden;
213+    padding-bottom: 1em;
214+    box-sizing: border-box;
215+}
216+
217+/* Breadcrumbs */
218+.breadcrumb {
219+    width: 100%;
220+}
221+ul.breadcrumb {
222+    list-style: none;
223+    padding: 0;
224+}
225+
226+/* Display list items side by side */
227+ul.breadcrumb li {
228+    padding: 0.5rem 0;
229+    display: inline;
230+    font-weight: 500;
231+}
232+
233+/* Add a slash symbol (/) before/behind each list item */
234+ul.breadcrumb li:first-child::before {
235+    padding: 8px 5px 8px 5px;
236+    color: var(--text);
237+    content: "~/";
238+}
239+
240+ul.breadcrumb li + li:before {
241+    padding: 8px 5px 8px 5px;
242+    color: var(--text);
243+    content: "/";
244+}
245+
246+/* Add a color to all links inside the list */
247+ul.breadcrumb li a {
248+    color: var(--text);
249+    text-decoration: none;
250+}
251+
252+/* Add a color on mouse-over */
253+ul.breadcrumb li a:hover {
254+    color: var(--link);
255+    text-decoration: underline;
256 }
257 
258-#subtitle {
259-	padding-left: 2px;
260+#repositories + #subtitle {
261+    padding-left: 50px;
262+    margin: 0 0 20px;
263 }
264 
265 #branches,
266 #tags,
267-#index,
268 #log,
269 #files {
270     width: 100%;
271-    font-family: "Inter", sans-serif;
272+    font-family: var(--sans);
273 }
274 
275 td > a {
276@@ -224,37 +268,74 @@ td > a {
277 }
278 
279 #md > pre {
280-    padding: 20px;
281+    padding: 10px;
282     border-radius: 15px;
283     border: 1px solid #d2d2d2;
284 }
285 
286+#index {
287+ padding-left: 50px;
288+ width:100%;
289+ flex-direction:column;
290+ display:flex;
291+ align-items:flex-start;
292+ justify-content:center
293+}
294+
295+#index a { 
296+ color: var(--header);
297+}
298+
299+#index a:hover {  
300+ color: var(--link);
301+}
302+
303+#index > h2 {
304+ font-weight:500;
305+ font-size:1.5rem;
306+ margin:0;
307+ padding:15px 0 0;
308+ color:var(--header);
309+ font-family:var(--heading)
310+}
311+
312+#index > p {
313+ text-align:left;
314+ margin:0 1px 20px;
315+ display:block;
316+ color:var(--text)
317+}
318+
319 @media screen and (min-width: 1000px) {
320     #content {
321         display: flex;
322         flex-direction: column;
323         justify-content: flex-start;
324         align-items: center;
325+	
326     }
327 }
328 
329 @media screen and (max-width: 1000px) {
330-	html {
331-		font-size: 17px;
332-	}
333+    html {
334+        font-size: 17px;
335+    }
336+    #repositories + #subtitle {
337+    	padding-left: 45px;
338+   }
339+   #index {
340+	padding-left: 45px;
341+   }
342 }
343 
344 #head,
345 #content,
346 .table-container {
347-    width: auto;
348-    overflow-x: auto;
349-    margin: auto;
350-    padding: 0px 25px 0px 0px;
351+    width: 100%;
352+    padding-right: 10px;
353 }
354 
355-#log,
356-#index {
357+#log {
358     min-width: 600px;
359     width: 100%;
360     overflow-x: auto;
361@@ -287,7 +368,7 @@ pre:not(#about) {
362 }
363 
364 #cloneurl {
365-    font-family: "JetBrains Mono", monospace;
366+    font-family: var(--mono);
367     background-color: var(--border);
368     border: 0px solid transparent;
369     border-radius: 8px;
370@@ -295,23 +376,40 @@ pre:not(#about) {
371 }
372 
373 #home h1 {
374+    font-family: var(--heading);
375     font-size: 1.5em;
376+    color: var(--header);
377     text-align: center;
378     margin-top: 1em;
379 }
380 
381 #home h2 {
382+    font-family: var(--heading);
383     font-size: 1.25em;
384+    color: var(--header);
385     margin-top: 2.5em;
386     margin-bottom: 1em;
387 }
388 
389-.md h1 {
390+#md h1 {
391+    font-family: var(--heading);
392     font-size: 1.5em;
393+    font-weight: 500;
394+    color: var(--header);
395 }
396 
397-.md h2 {
398+#md h2 {
399     font-size: 1.25em;
400+    font-family: var(--heading);
401+    color: var(--header);
402+    font-weight: 500;
403+}
404+
405+#md h3 {
406+    font-size: 1.1em;
407+    font-family: var(--heading);
408+    color: var(--header);
409+    font-weight: 500;
410 }
411 
412 img,
413@@ -341,6 +439,7 @@ a.line {
414 pre {
415     max-width: 100%;
416     display: block;
417+    font-size: 0.95rem;
418 }
419 
420 #blob a {
421@@ -352,7 +451,7 @@ pre {
422 }
423 
424 #blob {
425-	max-width: 100%;
426+    width: 100%;
427 }
428 
429 table {
430@@ -369,6 +468,10 @@ table td {
431     white-space: normal;
432 }
433 
434+#header {
435+	width: 100%;
436+}
437+
438 #commit-message {
439     min-width: 300px;
440     white-space: normal !important;
441@@ -382,7 +485,6 @@ tr:not(:last-child) {
442 
443 #branches tr td,
444 #tags tr td,
445-#index tr td,
446 #log tr td,
447 #files tr td {
448     padding: 0.75em 0.25em;
449@@ -390,7 +492,6 @@ tr:not(:last-child) {
450 
451 #branches tr:hover td,
452 #tags tr:hover td,
453-#index tr:hover td,
454 #log tr:hover td,
455 #files tr:hover td {
456     background-color: var(--border);
457@@ -401,12 +502,37 @@ td.num {
458 }
459 
460 #navbar {
461-    font-weight: 600;
462+    font-weight: 500;
463     display: flex;
464     width: 100%;
465     margin: 10px 0px;
466-    align-items: space-evenly;
467+    align-items: center;
468+    justify-content: space-evenly;
469+}
470+
471+/* Footer */
472+
473+footer {
474+    margin-top: auto;
475+    width: 100%;
476+}
477+
478+footer ul {
479+    width: 100%;
480+    list-style: none;
481+    display: flex;
482+    flex-wrap: wrap;
483     justify-content: space-evenly;
484+    padding: 0;
485+}
486+
487+footer li {
488+    padding: 0.25em 1em;
489+}
490+
491+footer a {
492+    color: currentColor;
493+    text-decoration: none;
494 }
495 
496 hr {
497@@ -417,12 +543,11 @@ hr {
498 
499 #md pre {
500     margin: 0;
501-    width: 90%;
502-    font-family: "JetBrains Mono", monospace;
503+    font-family: var(--mono);
504 }
505 
506 pre > code {
507-    font-family: "JetBrains Mono", monospace;
508+    font-family: var(--mono);
509 }
510 
511 .A,
512@@ -443,28 +568,20 @@ pre a.d:hover {
513     text-decoration: none;
514 }
515 
516-.md table {
517+#md table {
518     border-collapse: collapse;
519     margin: 1em 1em;
520     border: 1px solid #d2d2d2;
521 }
522 
523-.md table td,
524-.md table th {
525+#md table td,
526+#md table th {
527     padding: 0.25em 1em;
528     border: 1px solid #d2d2d2;
529 }
530 
531-#index .cat td {
532-    font-style: italic;
533-}
534-
535-#index .repo td:first-child {
536-    padding-left: 1.5em;
537-}
538-
539 .chroma {
540-	font-family: "JetBrains Mono", monospace;
541+    font-family: var(--mono);
542 }
543 
544 /* Syntax (light) */
545@@ -745,9 +862,6 @@ pre a.d:hover {
546 .gp {
547     color: #000080;
548 }
549-/* GenericStrong */
550-.gs {
551-}
552 /* GenericSubheading */
553 .gu {
554     color: #800080;
555@@ -766,7 +880,7 @@ pre a.d:hover {
556 }
557 
558 @media screen and (max-width: 1300px) {
559-        ::-webkit-scrollbar {
560+    ::-webkit-scrollbar {
561         width: 5px;
562     }
563 
564@@ -774,7 +888,7 @@ pre a.d:hover {
565         width: 0px;
566     }
567 
568-	#sidebar {
569+    #sidebar {
570         justify-content: space-between;
571         align-items: center;
572         max-height: 60vh;
573@@ -796,39 +910,52 @@ pre a.d:hover {
574         margin: 1em;
575     }
576 
577-    #header {
578-        padding: 15px;
579-    }
580-
581     #content {
582         display: block;
583-        padding: 0px 10px;
584+	padding: 0px 0px 5em 0px;
585+	overflow-x: auto;
586     }
587 
588     #header > h1 {
589         font-size: 1.75rem;
590+        color: var(--header);
591     }
592 
593     #header > h2 {
594         font-size: 1.5rem;
595+        color: var(--header);
596     }
597 
598     #header > h3 {
599         font-size: 1.25rem;
600+        color: var(--header);
601     }
602 
603     #container {
604-        display: block;
605-        height: auto;
606-    }
607+        flex-direction: column;
608+        overflow-y: scroll;
609+        overflow-x: hidden;
610+        min-height: 100vh;
611+        height: fit-content;
612+	}
613+    #main-view {
614+        flex: 1 1 60%;
615+        overflow-x: hidden;
616+	overflow-y: hidden;
617+	width: auto;
618+	padding: 10px;
619+	word-wrap: break-word;
620+    }    
621 }
622 
623+
624 @media (prefers-color-scheme: dark) {
625     :root {
626         --link: #58a6ff;
627         --scrollbar: #4f4f4f;
628-        --text: #ededed;
629-        --background: #0f0f0f;
630+        --text: #d4d4d4;
631+        --header: #ffffff;
632+        --background: #000000;
633         --border: #292929;
634     }
635 
636@@ -870,26 +997,24 @@ pre a.d:hover {
637         padding-left: 5px;
638         padding-right: 5px;
639     }
640-	
641+
642     .chroma:not(pre) {
643-    	border: 1px solid #292929;
644+        border: 1px solid #292929;
645     }
646 
647     #md > pre {
648         border: 1px solid #292929;
649     }
650 
651-    .md table {
652+    #md table {
653         border: 1px solid #292929;
654     }
655-    
656-    .md table td,
657-    .md table th {
658+
659+    #md table td,
660+    #md table th {
661         border: 1px solid #292929;
662     }
663 
664-
665-
666     .hll {
667         background-color: #212121;
668     }