appview/pages/markup: syntax highlight code blocks #493

merged
opened by oppi.li targeting master from push-stktrzvlltpw
Changed files
+35 -11
appview
pages
markup
nix
+20 -1
appview/pages/markup/markdown.go
···
"bytes"
"fmt"
"io"
+
"maps"
"net/url"
"path"
"regexp"
+
"slices"
"strings"
+
"github.com/alecthomas/chroma/v2"
+
chromahtml "github.com/alecthomas/chroma/v2/formatters/html"
+
"github.com/alecthomas/chroma/v2/styles"
"github.com/microcosm-cc/bluemonday"
"github.com/yuin/goldmark"
+
highlighting "github.com/yuin/goldmark-highlighting/v2"
"github.com/yuin/goldmark/ast"
"github.com/yuin/goldmark/extension"
"github.com/yuin/goldmark/parser"
···
func (rctx *RenderContext) RenderMarkdown(source string) string {
md := goldmark.New(
-
goldmark.WithExtensions(extension.GFM),
+
goldmark.WithExtensions(
+
extension.GFM,
+
highlighting.NewHighlighting(
+
highlighting.WithFormatOptions(
+
chromahtml.Standalone(false),
+
chromahtml.WithClasses(true),
+
),
+
highlighting.WithCustomStyle(styles.Get("catppuccin-latte")),
+
),
+
),
goldmark.WithParserOptions(
parser.WithAutoHeadingID(),
),
···
policy.AllowAttrs("type").Matching(regexp.MustCompile(`^checkbox$`)).OnElements("input")
policy.AllowAttrs("checked", "disabled", "data-source-position").OnElements("input")
+
// for code blocks
+
policy.AllowAttrs("class").Matching(regexp.MustCompile(`chroma`)).OnElements("pre")
+
policy.AllowAttrs("class").Matching(regexp.MustCompile(strings.Join(slices.Collect(maps.Values(chroma.StandardTypes)), "|"))).OnElements("span")
+
// centering content
policy.AllowElements("center")
+3 -2
go.mod
···
github.com/go-enry/go-enry/v2 v2.9.2
github.com/go-git/go-git/v5 v5.14.0
github.com/google/uuid v1.6.0
+
github.com/gorilla/feeds v1.2.0
github.com/gorilla/sessions v1.4.0
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674
github.com/hiddeco/sshsig v0.2.0
···
github.com/stretchr/testify v1.10.0
github.com/urfave/cli/v3 v3.3.3
github.com/whyrusleeping/cbor-gen v0.3.1
-
github.com/yuin/goldmark v1.4.13
+
github.com/yuin/goldmark v1.4.15
+
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc
golang.org/x/crypto v0.40.0
golang.org/x/net v0.42.0
golang.org/x/sync v0.16.0
···
github.com/golang/mock v1.6.0 // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/gorilla/css v1.0.1 // indirect
-
github.com/gorilla/feeds v1.2.0 // indirect
github.com/gorilla/securecookie v1.1.2 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
+5 -1
go.sum
···
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
+
github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
github.com/dlclark/regexp2 v1.11.5 h1:Q/sSnsKerHeCkc/jSTNq1oCm7KiVgUMZRDUoRu0JQZQ=
github.com/dlclark/regexp2 v1.11.5/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
github.com/docker/docker v28.2.2+incompatible h1:CjwRSksz8Yo4+RmQ339Dp/D2tGO5JxwYeqtMOEe0LDw=
···
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
-
github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
+
github.com/yuin/goldmark v1.4.15 h1:CFa84T0goNn/UIXYS+dmjjVxMyTAvpOmzld40N/nfK0=
+
github.com/yuin/goldmark v1.4.15/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
+
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc h1:+IAOyRda+RLrxa1WC7umKOZRsGq4QrFFMYApOeHzQwQ=
+
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc/go.mod h1:ovIvrum6DQJA4QsJSovrkC4saKHQVs7TvcaeO8AIl5I=
gitlab.com/yawning/secp256k1-voi v0.0.0-20230925100816-f2616030848b h1:CzigHMRySiX3drau9C6Q5CAbNIApmLdat5jPMqChvDA=
gitlab.com/yawning/secp256k1-voi v0.0.0-20230925100816-f2616030848b/go.mod h1:/y/V339mxv2sZmYYR64O07VuCpdNZqCTwO8ZcouTMI8=
gitlab.com/yawning/tuplehash v0.0.0-20230713102510-df83abbf9a02 h1:qwDnMxjkyLmAFgcfgTnfJrmYKWhHnci3GjDqcZp1M3Q=
+1 -2
input.css
···
/* PreWrapper */
.chroma {
color: #4c4f69;
-
background-color: #eff1f5;
+
background-color: #00000000;
}
/* Error */
.chroma .err {
···
/* PreWrapper */
.chroma {
color: #cad3f5;
-
background-color: #24273a;
}
/* Error */
.chroma .err {
+5 -2
nix/gomod2nix.toml
···
version = "v0.3.1"
hash = "sha256-PAd8M2Z8t6rVRBII+Rg8Bz+QaJIwbW64bfyqsv31kgc="
[mod."github.com/yuin/goldmark"]
-
version = "v1.4.13"
-
hash = "sha256-GVwFKZY6moIS6I0ZGuio/WtDif+lkZRfqWS6b4AAJyI="
+
version = "v1.4.15"
+
hash = "sha256-MvSOT6dwf5hVYkIg4MnqMpsy5ZtWZ7amAE7Zo9HkEa0="
+
[mod."github.com/yuin/goldmark-highlighting/v2"]
+
version = "v2.0.0-20230729083705-37449abec8cc"
+
hash = "sha256-HpiwU7jIeDUAg2zOpTIiviQir8dpRPuXYh2nqFFccpg="
[mod."gitlab.com/yawning/secp256k1-voi"]
version = "v0.0.0-20230925100816-f2616030848b"
hash = "sha256-X8INg01LTg13iOuwPI3uOhPN7r01sPZtmtwJ2sudjCA="
+1 -3
tailwind.config.js
···
css: {
maxWidth: "none",
pre: {
-
backgroundColor: colors.gray[100],
-
color: colors.black,
-
"@apply font-normal text-black bg-gray-100 dark:bg-gray-900 dark:text-gray-300 dark:border-gray-700 dark:border": {},
+
"@apply font-normal text-black bg-gray-100 dark:bg-gray-900 dark:text-gray-300 dark:border-gray-700 border": {},
},
code: {
"@apply font-normal font-mono p-1 rounded text-black bg-gray-100 dark:bg-gray-900 dark:text-gray-300 dark:border-gray-700": {},