web frontend for git (tangled's grandpa)

routes: add syntax highlight

authored by

Gabriel A. Giovanini and committed by anirudh.fi 34521a5b de182443

+72 -5
+3 -2
config/config.go
··· 21 21 Static string `yaml:"static"` 22 22 } `yaml:"dirs"` 23 23 Meta struct { 24 - Title string `yaml:"title"` 25 - Description string `yaml:"description"` 24 + Title string `yaml:"title"` 25 + Description string `yaml:"description"` 26 + SyntaxHighlight string `yaml:"syntaxHighlight"` 26 27 } `yaml:"meta"` 27 28 Server struct { 28 29 Name string `yaml:"name,omitempty"`
+9 -2
routes/routes.go
··· 225 225 } 226 226 227 227 contents, err := gr.FileContent(treePath) 228 + if err != nil { 229 + d.Write500(w) 230 + return 231 + } 228 232 data := make(map[string]any) 229 233 data["name"] = name 230 234 data["displayname"] = getDisplayName(name) ··· 235 239 if raw { 236 240 d.showRaw(contents, w) 237 241 } else { 238 - d.showFile(contents, data, w) 242 + if d.c.Meta.SyntaxHighlight == "" { 243 + d.showFile(contents, data, w) 244 + } else { 245 + d.showFileWithHighlight(treePath, contents, data, w) 246 + } 239 247 } 240 - return 241 248 } 242 249 243 250 func (d *deps) Archive(w http.ResponseWriter, r *http.Request) {
+46
routes/template.go
··· 10 10 "strings" 11 11 12 12 "git.icyphox.sh/legit/git" 13 + "github.com/alecthomas/chroma/v2/formatters/html" 14 + "github.com/alecthomas/chroma/v2/lexers" 15 + "github.com/alecthomas/chroma/v2/styles" 13 16 ) 14 17 15 18 func (d *deps) Write404(w http.ResponseWriter) { ··· 69 72 } 70 73 } 71 74 75 + func (d *deps) showFileWithHighlight(name, content string, data map[string]any, w http.ResponseWriter) { 76 + tpath := filepath.Join(d.c.Dirs.Templates, "*") 77 + t := template.Must(template.ParseGlob(tpath)) 78 + 79 + lexer := lexers.Get(name) 80 + if lexer == nil { 81 + lexer = lexers.Get(".txt") 82 + } 83 + 84 + style := styles.Get(d.c.Meta.SyntaxHighlight) 85 + if style == nil { 86 + style = styles.Get("monokailight") 87 + } 88 + 89 + formatter := html.New( 90 + html.WithLineNumbers(true), 91 + html.WithLinkableLineNumbers(true, "L"), 92 + ) 93 + 94 + iterator, err := lexer.Tokenise(nil, content) 95 + if err != nil { 96 + d.Write500(w) 97 + return 98 + } 99 + 100 + var code bytes.Buffer 101 + err = formatter.Format(&code, style, iterator) 102 + if err != nil { 103 + d.Write500(w) 104 + return 105 + } 106 + 107 + data["content"] = template.HTML(code.String()) 108 + data["meta"] = d.c.Meta 109 + data["chroma"] = true 110 + 111 + if err := t.ExecuteTemplate(w, "file", data); err != nil { 112 + log.Println(err) 113 + return 114 + } 115 + } 116 + 72 117 func (d *deps) showFile(content string, data map[string]any, w http.ResponseWriter) { 73 118 tpath := filepath.Join(d.c.Dirs.Templates, "*") 74 119 t := template.Must(template.ParseGlob(tpath)) ··· 89 134 data["linecount"] = lines 90 135 data["content"] = content 91 136 data["meta"] = d.c.Meta 137 + data["chroma"] = false 92 138 93 139 if err := t.ExecuteTemplate(w, "file", data); err != nil { 94 140 log.Println(err)
+7
static/style.css
··· 274 274 overflow-x: auto; 275 275 } 276 276 277 + .chroma-file-wrapper { 278 + display: flex; 279 + flex-direction: row; 280 + grid-template-columns: 1rem minmax(0, 1fr); 281 + overflow-x: auto; 282 + } 283 + 277 284 .file-content { 278 285 background: var(--light-gray); 279 286 overflow-y: hidden;
+7 -1
templates/file.html
··· 6 6 {{ template "nav" . }} 7 7 <main> 8 8 <p>{{ .path }} (<a style="color: gray" href="?raw=true">view raw</a>)</p> 9 + {{if .chroma }} 10 + <div class="chroma-file-wrapper"> 11 + {{ .content }} 12 + </div> 13 + {{else}} 9 14 <div class="file-wrapper"> 10 - <table > 15 + <table> 11 16 <tbody><tr> 12 17 <td class="line-numbers"> 13 18 <pre> ··· 24 29 </tbody></tr> 25 30 </table> 26 31 </div> 32 + {{end}} 27 33 </main> 28 34 </body> 29 35 </html>