package page import ( "context" "io" "log/slog" "net/url" "strings" "git.schreifuchs.ch/schreifuchs/schreifuchs.ch/internal/components/images" "github.com/gomarkdown/markdown" "github.com/gomarkdown/markdown/ast" "github.com/gomarkdown/markdown/html" "github.com/gomarkdown/markdown/parser" ) // image can be used to preload type Image struct { SrcSet string Src string } func (s *Service) getHTML(ctx context.Context, page PageHeader) (out []byte, imgs []Image, err error) { extensions := parser.CommonExtensions | parser.AutoHeadingIDs | parser.NoEmptyLineBeforeBlock p := parser.NewWithExtensions(extensions) doc := p.Parse(page.md) // create HTML renderer with extensions htmlFlags := html.CommonFlags | html.HrefTargetBlank opts := html.RendererOptions{ Flags: htmlFlags, RenderNodeHook: imageMiddleware(page, &imgs), } renderer := html.NewRenderer(opts) out = markdown.Render(doc, renderer) return } func imageMiddleware(page PageHeader, imgs *[]Image) func(w io.Writer, node ast.Node, entering bool) (ast.WalkStatus, bool) { return func(w io.Writer, node ast.Node, entering bool) (ast.WalkStatus, bool) { if !entering { return ast.GoToNext, false } img, ok := node.(*ast.Image) if !ok { return ast.GoToNext, false } src := string(img.Destination) if strings.HasPrefix(src, ".attachments") { imgPath, err := url.PathUnescape(src) if err != nil { slog.Error("could not unescape path", "err", err) return ast.GoToNext, false } src, err = images.URLFromPath(page.UID + "/" + imgPath) if err != nil { slog.Error("could not get image url", "err", err) return ast.GoToNext, false } image := Image{ SrcSet: images.SourceSet(src), Src: src + "?w=1024", } img.Attribute = &ast.Attribute{Attrs: map[string][]byte{ // "srcset": []byte(image.SrcSet), "fetchpriority": []byte("low"), "loading": []byte("lazy"), "class": []byte("min-h-48"), "src": []byte(image.Src), }} *imgs = append(*imgs, image) // // img.Attrs["srcset"] = } img.Destination = []byte(src) return ast.GoToNext, false } }