aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pkg/handler/git/handler.go2
-rw-r--r--pkg/handler/router.go9
-rw-r--r--pkg/handler/static/handler.go49
-rw-r--r--templates/base.qtpl2
-rw-r--r--templates/base.qtpl.go53
5 files changed, 88 insertions, 27 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..bc81350 100644
--- a/pkg/handler/router.go
+++ b/pkg/handler/router.go
@@ -31,6 +31,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 +53,7 @@ func MountHandler(
}
mux.HandleFunc("/static/{file}", staticHandler)
+ mux.HandleFunc("/static/theme", 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..779c786 100644
--- a/pkg/handler/static/handler.go
+++ b/pkg/handler/static/handler.go
@@ -1,6 +1,8 @@
package static
import (
+ "fmt"
+ "io"
"io/fs"
"mime"
"net/http"
@@ -8,6 +10,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 +33,47 @@ 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")
+
+ var style *chroma.Style
+ style = darkStyle
+ w.Write([]byte("[data-bs-theme=\"dark\"] {\n"))
+ err := formatter.WriteCSS(&ws{w}, style)
+ if err != nil {
+ return err
+ }
+ w.Write([]byte("}\n"))
+
+ style = lightStyle
+ w.Write([]byte("[data-bs-theme=\"light\"] {\n"))
+ err = formatter.WriteCSS(&ws{w}, style)
+ if err != nil {
+ return err
+ }
+ w.Write([]byte("\n}"))
+
+ 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))
+}
diff --git a/templates/base.qtpl b/templates/base.qtpl
index b3df94a..e43fb67 100644
--- a/templates/base.qtpl
+++ b/templates/base.qtpl
@@ -60,6 +60,8 @@ Page prints a page implementing Page interface.
<link rel="icon" href="data:,">
<title>{%= p.Title(ctx) %}</title>
<link rel="stylesheet" href="/static/main{%s Slug %}.css">
+ <link rel="stylesheet" href="/static/themes/dark">
+ <link rel="stylesheet" href="/static/themes/light">
<html data-bs-theme="dark">
<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
<meta name="viewport" content="width=device-width, initial-scale=1" />
diff --git a/templates/base.qtpl.go b/templates/base.qtpl.go
index dce4cbc..783de2c 100644
--- a/templates/base.qtpl.go
+++ b/templates/base.qtpl.go
@@ -8,16 +8,14 @@
package templates
//line templates/base.qtpl:3
-import "context"
-
-//line templates/base.qtpl:4
-import "strconv"
+import (
+ "context"
+ "strconv"
+ "time" //line templates/base.qtpl:4
-//line templates/base.qtpl:5
-import "time"
+ //line templates/base.qtpl:5
+ //line templates/base.qtpl:7
-//line templates/base.qtpl:7
-import (
qtio422016 "io"
qt422016 "github.com/valyala/quicktemplate"
@@ -112,59 +110,60 @@ func StreamPageTemplate(qw422016 *qt422016.Writer, p Page, ctx context.Context)
qw422016.E().S(Slug)
//line templates/base.qtpl:62
qw422016.N().S(`.css">
+ <link rel="stylesheet" href="/static/theme">
<html data-bs-theme="dark">
<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
<meta name="viewport" content="width=device-width, initial-scale=1" />
</head>
<body>
`)
-//line templates/base.qtpl:68
+//line templates/base.qtpl:70
p.StreamNavbar(qw422016, ctx)
-//line templates/base.qtpl:68
+//line templates/base.qtpl:70
qw422016.N().S(`
<div class="container">
`)
-//line templates/base.qtpl:70
+//line templates/base.qtpl:72
p.StreamContent(qw422016, ctx)
-//line templates/base.qtpl:70
+//line templates/base.qtpl:72
qw422016.N().S(`
</div>
</body>
`)
-//line templates/base.qtpl:73
+//line templates/base.qtpl:75
p.StreamScript(qw422016, ctx)
-//line templates/base.qtpl:73
+//line templates/base.qtpl:75
qw422016.N().S(`
<script>
function a(){const e=window.matchMedia("(prefers-color-scheme: dark)").matches;document.documentElement.setAttribute("data-bs-theme",e?"dark":"light")}a(),window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change",a);
</script>
</html>
`)
-//line templates/base.qtpl:78
+//line templates/base.qtpl:80
}
-//line templates/base.qtpl:78
+//line templates/base.qtpl:80
func WritePageTemplate(qq422016 qtio422016.Writer, p Page, ctx context.Context) {
-//line templates/base.qtpl:78
+//line templates/base.qtpl:80
qw422016 := qt422016.AcquireWriter(qq422016)
-//line templates/base.qtpl:78
+//line templates/base.qtpl:80
StreamPageTemplate(qw422016, p, ctx)
-//line templates/base.qtpl:78
+//line templates/base.qtpl:80
qt422016.ReleaseWriter(qw422016)
-//line templates/base.qtpl:78
+//line templates/base.qtpl:80
}
-//line templates/base.qtpl:78
+//line templates/base.qtpl:80
func PageTemplate(p Page, ctx context.Context) string {
-//line templates/base.qtpl:78
+//line templates/base.qtpl:80
qb422016 := qt422016.AcquireByteBuffer()
-//line templates/base.qtpl:78
+//line templates/base.qtpl:80
WritePageTemplate(qb422016, p, ctx)
-//line templates/base.qtpl:78
+//line templates/base.qtpl:80
qs422016 := string(qb422016.B)
-//line templates/base.qtpl:78
+//line templates/base.qtpl:80
qt422016.ReleaseByteBuffer(qb422016)
-//line templates/base.qtpl:78
+//line templates/base.qtpl:80
return qs422016
-//line templates/base.qtpl:78
+//line templates/base.qtpl:80
}