Sarah@auth.lopeos.org submitted a patch request Feb 16, 2025 18:43
- Title: Add Syntax Highlighting with Chroma
- Author: Sarah Jamie Lewis <sarah@openprivacy.ca>
gen/generate.go
@@ -1,18 +1,22 @@
package gen
import (
+ "bytes"
"fmt"
+ "html/template"
"os/exec"
"senary/common"
"slices"
- "os"
- "path/filepath"
- "strings"
-
+ htmlform "github.com/alecthomas/chroma/v2/formatters/html"
+ "github.com/alecthomas/chroma/v2/lexers"
+ "github.com/alecthomas/chroma/v2/styles"
"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing"
"github.com/go-git/go-git/v5/plumbing/object"
+ "os"
+ "path/filepath"
+ "strings"
)
type StaticBase struct {
@@ -43,7 +47,7 @@ type StaticCommit struct {
type StaticListing struct {
StaticBase
FileName string
- Contents []string
+ Contents template.HTML
}
func GenerateRepoPages(config *common.Config, repo string) error {
@@ -83,11 +87,33 @@ func GenerateRepoPages(config *common.Config, repo string) error {
} else {
data, _ := f.Contents()
- lines := strings.Split(data, "\n")
+
file, _ := os.Create(staticPath + ".html")
defer file.Close()
- config.Templates.ExecuteTemplate(file, "listing.tpl.html", StaticListing{StaticBase: StaticBase{Repo: filepath.Base(repo)}, FileName: f.Name, Contents: lines})
+ langLexer := lexers.Match(f.Name)
+ if langLexer == nil {
+ langLexer = lexers.Analyse(data)
+ if langLexer == nil {
+ langLexer = lexers.Fallback
+ }
+ }
+ style := styles.Get("dracula")
+ if style == nil {
+ style = styles.Fallback
+ }
+ formatter := htmlform.New(htmlform.Standalone(false), htmlform.LineNumbersInTable(true), htmlform.WithLineNumbers(true), htmlform.WithLinkableLineNumbers(true, ""))
+
+ iterator, err := langLexer.Tokenise(nil, string(strings.TrimSpace(data)))
+ var doc bytes.Buffer
+ formatter.Format(&doc, style, iterator)
+ // lines := strings.Split(doc.String(), "\n")
+ // htmlLines := []template.HTML{}
+ // for _, line := range lines {
+ // htmlLines = append(htmlLines, template.HTML(line))
+ // }
+
+ config.Templates.ExecuteTemplate(file, "listing.tpl.html", StaticListing{StaticBase: StaticBase{Repo: filepath.Base(repo)}, FileName: f.Name, Contents: template.HTML(doc.String())})
if err != nil {
fmt.Printf("[error] %v\n", err)
}
@@ -100,7 +126,7 @@ func GenerateRepoPages(config *common.Config, repo string) error {
os.MkdirAll(dir, 0755)
file, _ := os.Create(staticPath + ".html")
defer file.Close()
- config.Templates.ExecuteTemplate(file, "listing.tpl.html", StaticListing{StaticBase: StaticBase{Repo: filepath.Base(repo)}, FileName: f.Name, Contents: lines})
+ config.Templates.ExecuteTemplate(file, "listing.tpl.html", StaticListing{StaticBase: StaticBase{Repo: filepath.Base(repo)}, FileName: f.Name, Contents: template.HTML(doc.String())})
}
}
go.mod
@@ -5,6 +5,8 @@ go 1.23.2
require github.com/go-git/go-git/v5 v5.13.2
require (
+ github.com/alecthomas/chroma v0.10.0
+ github.com/alecthomas/chroma/v2 v2.15.0
github.com/bluekeyes/go-gitdiff v0.8.1
go.hacdias.com/indielib v0.4.3
)
@@ -15,6 +17,7 @@ require (
github.com/ProtonMail/go-crypto v1.1.5 // indirect
github.com/cloudflare/circl v1.5.0 // indirect
github.com/cyphar/filepath-securejoin v0.3.6 // indirect
+ github.com/dlclark/regexp2 v1.11.4 // indirect
github.com/emirpasic/gods v1.18.1 // indirect
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
github.com/go-git/go-billy/v5 v5.6.2 // indirect
go.sum
@@ -5,6 +5,14 @@ github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERo
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
github.com/ProtonMail/go-crypto v1.1.5 h1:eoAQfK2dwL+tFSFpr7TbOaPNUbPiJj4fLYwwGE1FQO4=
github.com/ProtonMail/go-crypto v1.1.5/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE=
+github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8vS6K3D0=
+github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k=
+github.com/alecthomas/chroma v0.10.0 h1:7XDcGkCQopCNKjZHfYrNLraA+M7e0fMiJ/Mfikbfjek=
+github.com/alecthomas/chroma v0.10.0/go.mod h1:jtJATyUxlIORhUOFNA9NZDWGAQ8wpxQQqNSB4rjA/1s=
+github.com/alecthomas/chroma/v2 v2.15.0 h1:LxXTQHFoYrstG2nnV9y2X5O94sOBzf0CIUpSTbpxvMc=
+github.com/alecthomas/chroma/v2 v2.15.0/go.mod h1:gUhVLrPDXPtp/f+L1jo9xepo9gL4eLwRuGAunSZMkio=
+github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc=
+github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
github.com/andybalholm/cascadia v1.3.1/go.mod h1:R4bJ1UQfqADjvDa4P6HZHLh/3OxWWEqc0Sk8XGwHqvA=
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4=
@@ -19,6 +27,9 @@ github.com/cyphar/filepath-securejoin v0.3.6/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGL
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
+github.com/dlclark/regexp2 v1.11.4 h1:rPYF9/LECdNymJufQKmri9gV604RvvABwgOA8un7yAo=
+github.com/dlclark/regexp2 v1.11.4/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
github.com/elazarl/goproxy v1.4.0 h1:4GyuSbFa+s26+3rmYNSuUVsx+HgPrV1bk1jXI0l9wjM=
github.com/elazarl/goproxy v1.4.0/go.mod h1:X/5W/t+gzDyLfHW4DrMdpjqYjpXsURlBt9lpBDxZZZQ=
github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
@@ -38,6 +49,8 @@ github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUv
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
+github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4=
@@ -67,6 +80,7 @@ github.com/skeema/knownhosts v1.3.0/go.mod h1:sPINvnADmT/qYH1kfv+ePMmOBTH6Tbl7b5
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
+github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/wsxiaoys/terminal v0.0.0-20160513160801-0940f3fc43a0/go.mod h1:IXCdmsXIht47RaVFLEdVnh1t+pgYtTAhQGj73kz+2DM=
@@ -110,6 +124,7 @@ gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
willnorris.com/go/microformats v1.2.1-0.20240301064101-b5d1b9d2120e h1:TRIOwo0NxN4KVSgYlYmiQktd9I96YgZ3942/JVzhwTM=
static/css/custom.css
@@ -82,4 +82,19 @@ mark.info {
.clone {
font-size:0.8em;
+}
+
+pre {
+ border-radius: 0px;
+ padding:10px;
+}
+
+pre > code{
+ display: initial;
+ line-height: normal;
+ padding:0px;
+}
+
+td {
+ line-height: normal;
}
templates/listing.tpl.html
@@ -1,6 +1,2 @@
-
-<pre class="code">
-
-{{range $line := .Contents}}<code>{{$line}}</code>{{end}}
-
-</pre>
+<div class="listing">{{.Contents}}
+</div>