Files
volumen/internal/markdown/diagram.go
T

35 lines
1.4 KiB
Go
Raw Normal View History

2026-09-18 12:03:35 +02:00
// Copyright (c) 2026 Petr Balvín <opensource@petrbalvin.org> (https://petrbalvin.org)
// SPDX-License-Identifier: PolyForm-Noncommercial-1.0.0
package markdown
import (
stdhtml "html"
"regexp"
"sourcedock.dev/petrbalvin/scriptorium"
)
// mermaidBlockRe matches the fenced mermaid blocks the renderer writes.
// The diagram source arrives HTML-escaped, as code content always does.
var mermaidBlockRe = regexp.MustCompile(`(?s)<pre><code class="language-mermaid">(.*?)</code></pre>`)
// renderDiagrams replaces every fenced mermaid block with the SVG
// scriptorium draws from it, wrapped so a style sheet can tell diagrams
// from prose. It runs on sanitised HTML: the SVG is machine-drawn output
// whose vocabulary the library itself bounds, and the sanitiser's
// HTML-only parser would corrupt its case-sensitive attributes. A
// diagram the library does not carry, or a line it cannot parse, keeps
// its code block: the author sees the source that was not understood,
// and the reader never a half-drawn figure.
func renderDiagrams(html string) string {
return mermaidBlockRe.ReplaceAllStringFunc(html, func(block string) string {
src := stdhtml.UnescapeString(mermaidBlockRe.FindStringSubmatch(block)[1])
svg, err := scriptorium.RenderDiagram([]byte(src))
if err != nil {
return block
}
return `<div class="diagram">` + "\n" + string(svg) + "\n</div>"
})
}