all repos — legit @ 34521a5bc308c168d43f168e325ac4f43d5dd835

web frontend for git, written in go

routes: add syntax highlight
Gabriel A. Giovanini mail@gabrielgio.me
Sun, 14 Jul 2024 16:21:33 +0200
commit

34521a5bc308c168d43f168e325ac4f43d5dd835

parent

de182443db91ca71508c3466418bcdf1fe09531f

5 files changed, 72 insertions(+), 5 deletions(-)

jump to
M config/config.goconfig/config.go

@@ -21,8 +21,9 @@ Templates string `yaml:"templates"`

Static string `yaml:"static"` } `yaml:"dirs"` Meta struct { - Title string `yaml:"title"` - Description string `yaml:"description"` + Title string `yaml:"title"` + Description string `yaml:"description"` + SyntaxHighlight string `yaml:"syntaxHighlight"` } `yaml:"meta"` Server struct { Name string `yaml:"name,omitempty"`
M routes/routes.goroutes/routes.go

@@ -225,6 +225,10 @@ return

} contents, err := gr.FileContent(treePath) + if err != nil { + d.Write500(w) + return + } data := make(map[string]any) data["name"] = name data["displayname"] = getDisplayName(name)

@@ -235,9 +239,12 @@

if raw { d.showRaw(contents, w) } else { - d.showFile(contents, data, w) + if d.c.Meta.SyntaxHighlight == "" { + d.showFile(contents, data, w) + } else { + d.showFileWithHighlight(treePath, contents, data, w) + } } - return } func (d *deps) Archive(w http.ResponseWriter, r *http.Request) {
M routes/template.goroutes/template.go

@@ -10,6 +10,9 @@ "path/filepath"

"strings" "git.icyphox.sh/legit/git" + "github.com/alecthomas/chroma/v2/formatters/html" + "github.com/alecthomas/chroma/v2/lexers" + "github.com/alecthomas/chroma/v2/styles" ) func (d *deps) Write404(w http.ResponseWriter) {

@@ -69,6 +72,48 @@ }

} } +func (d *deps) showFileWithHighlight(name, content string, data map[string]any, w http.ResponseWriter) { + tpath := filepath.Join(d.c.Dirs.Templates, "*") + t := template.Must(template.ParseGlob(tpath)) + + lexer := lexers.Get(name) + if lexer == nil { + lexer = lexers.Get(".txt") + } + + style := styles.Get(d.c.Meta.SyntaxHighlight) + if style == nil { + style = styles.Get("monokailight") + } + + formatter := html.New( + html.WithLineNumbers(true), + html.WithLinkableLineNumbers(true, "L"), + ) + + iterator, err := lexer.Tokenise(nil, content) + if err != nil { + d.Write500(w) + return + } + + var code bytes.Buffer + err = formatter.Format(&code, style, iterator) + if err != nil { + d.Write500(w) + return + } + + data["content"] = template.HTML(code.String()) + data["meta"] = d.c.Meta + data["chroma"] = true + + if err := t.ExecuteTemplate(w, "file", data); err != nil { + log.Println(err) + return + } +} + func (d *deps) showFile(content string, data map[string]any, w http.ResponseWriter) { tpath := filepath.Join(d.c.Dirs.Templates, "*") t := template.Must(template.ParseGlob(tpath))

@@ -89,6 +134,7 @@

data["linecount"] = lines data["content"] = content data["meta"] = d.c.Meta + data["chroma"] = false if err := t.ExecuteTemplate(w, "file", data); err != nil { log.Println(err)
M static/style.cssstatic/style.css

@@ -274,6 +274,13 @@ background: var(--light-gray);

overflow-x: auto; } +.chroma-file-wrapper { + display: flex; + flex-direction: row; + grid-template-columns: 1rem minmax(0, 1fr); + overflow-x: auto; +} + .file-content { background: var(--light-gray); overflow-y: hidden;
M templates/file.htmltemplates/file.html

@@ -6,8 +6,13 @@ <body>

{{ template "nav" . }} <main> <p>{{ .path }} (<a style="color: gray" href="?raw=true">view raw</a>)</p> + {{if .chroma }} + <div class="chroma-file-wrapper"> + {{ .content }} + </div> + {{else}} <div class="file-wrapper"> - <table > + <table> <tbody><tr> <td class="line-numbers"> <pre>

@@ -24,6 +29,7 @@ </td>

</tbody></tr> </table> </div> + {{end}} </main> </body> </html>