diff options
Diffstat (limited to 'pkg/handler')
| -rw-r--r-- | pkg/handler/git/handler.go | 2 | ||||
| -rw-r--r-- | pkg/handler/router.go | 15 | ||||
| -rw-r--r-- | pkg/handler/static/handler.go | 59 |
3 files changed, 76 insertions, 0 deletions
diff --git a/pkg/handler/git/handler.go b/pkg/handler/git/handler.go index ffa5dfd..d046d19 100644 --- a/pkg/handler/git/handler.go +++ b/pkg/handler/git/handler.go @@ -349,6 +349,7 @@ func (g *GitHandler) Blob(w http.ResponseWriter, r *ext.Request) error { formatter := html.New( html.WithLineNumbers(true), html.WithLinkableLineNumbers(true, "L"), + html.WithClasses(true), ) iterator, err := lexer.Tokenise(nil, string(file)) @@ -440,6 +441,7 @@ func (g *GitHandler) Commit(w http.ResponseWriter, r *ext.Request) error { formatter := html.New( html.WithLineNumbers(true), html.WithLinkableLineNumbers(true, "L"), + html.WithClasses(true), ) iterator, err := lexer.Tokenise(nil, diff) diff --git a/pkg/handler/router.go b/pkg/handler/router.go index fea8827..1fbc4e3 100644 --- a/pkg/handler/router.go +++ b/pkg/handler/router.go @@ -1,6 +1,7 @@ package handler import ( + "fmt" "net/http" serverconfig "git.gabrielgio.me/cerrado/pkg/config" @@ -10,6 +11,7 @@ import ( "git.gabrielgio.me/cerrado/pkg/handler/git" "git.gabrielgio.me/cerrado/pkg/handler/static" "git.gabrielgio.me/cerrado/pkg/service" + "git.gabrielgio.me/cerrado/templates" ) // Mount handler gets the requires service and repository to build the handlers @@ -31,6 +33,14 @@ func MountHandler( return nil, err } + cssStaticHandler, err := static.ServeStaticCSSHandler( + configRepo.GetSyntaxHighlight(), + configRepo.GetSyntaxHighlightDark(), + ) + if err != nil { + return nil, err + } + mux := ext.NewRouter() mux.AddMiddleware(ext.Compress) mux.AddMiddleware(ext.Log) @@ -45,6 +55,11 @@ func MountHandler( } mux.HandleFunc("/static/{file}", staticHandler) + // add slug and session so css file can be cached forever. + // Slug follow commit id, which is update every new version + // Session is update every time server restarts, this allows the css to be + // cached forever but refresh if the admin updates the server configuration. + mux.HandleFunc(fmt.Sprintf("/static/theme.%s%s.css", templates.Session, templates.Slug), cssStaticHandler) mux.HandleFunc("/{name}/about/{$}", gitHandler.About) mux.HandleFunc("/{name}", gitHandler.Multiplex) mux.HandleFunc("/{name}/{rest...}", gitHandler.Multiplex) diff --git a/pkg/handler/static/handler.go b/pkg/handler/static/handler.go index cdb2ae6..6cc884e 100644 --- a/pkg/handler/static/handler.go +++ b/pkg/handler/static/handler.go @@ -1,6 +1,9 @@ package static import ( + "bytes" + "fmt" + "io" "io/fs" "mime" "net/http" @@ -8,6 +11,9 @@ import ( "git.gabrielgio.me/cerrado/pkg/ext" "git.gabrielgio.me/cerrado/static" + "github.com/alecthomas/chroma/v2" + "github.com/alecthomas/chroma/v2/formatters/html" + "github.com/alecthomas/chroma/v2/styles" ) func ServeStaticHandler() (ext.ErrorRequestHandler, error) { @@ -28,3 +34,56 @@ func ServeStaticHandler() (ext.ErrorRequestHandler, error) { return nil }, nil } + +func ServeStaticCSSHandler(lightTheme, darkTheme string) (ext.ErrorRequestHandler, error) { + var ( + lightStyle = styles.Get(lightTheme) + darkStyle = styles.Get(darkTheme) + formatter = html.New( + html.WithCSSComments(false), + ) + ) + + return func(w http.ResponseWriter, r *ext.Request) error { + ext.SetMIME(w, "text/css") + w.Header().Add("Cache-Control", "max-age=31536000") + + // use buffer so this function can fail before writing to http.ResponseWriter + var buffer bytes.Buffer + + var style *chroma.Style + style = darkStyle + buffer.Write([]byte("[data-bs-theme=\"dark\"] {\n")) + err := formatter.WriteCSS(&ws{&buffer}, style) + if err != nil { + return err + } + buffer.Write([]byte("}\n")) + + style = lightStyle + buffer.Write([]byte("[data-bs-theme=\"light\"] {\n")) + err = formatter.WriteCSS(&ws{&buffer}, style) + if err != nil { + return err + } + buffer.Write([]byte("}")) + + _, err = io.Copy(w, &buffer) + if err != nil { + return err + } + + return nil + }, nil +} + +type ws struct { + inner io.Writer +} + +// This is very cursed, and rely on the fact that it writes every css rule at time. +// it adds & to the begging so it can be nested by the ServeStaticCSSHandler. +// This will allow the follow bootstrap data-bs-theme. +func (w *ws) Write(p []byte) (n int, err error) { + return fmt.Fprintf(w.inner, "& %s", string(p)) +} |
