70 lines
2.9 KiB
Go
70 lines
2.9 KiB
Go
// Copyright (c) 2026 Petr Balvín <opensource@petrbalvin.org> (https://petrbalvin.org)
|
|||
|
|
// SPDX-License-Identifier: MIT
|
||
|
|
|
||
|
|
// Package scriptorium renders scientific documents server-side. It renders
|
||
|
|
// Markdown to HTML, TeX mathematics to MathML Core, and Mermaid flowchart
|
||
|
|
// and sequence diagrams to SVG. The output is deterministic, so the same
|
||
|
|
// input always produces byte-identical output.
|
||
|
|
//
|
||
|
|
// The library is built on the Go standard library alone: it carries no
|
||
|
|
// dependency of its own. It renders trusted input and applies no
|
||
|
|
// sanitisation; whether the produced HTML may reach a given audience is
|
||
|
|
// the consumer's policy, not the renderer's.
|
||
|
|
//
|
||
|
|
// A construct the renderer refuses to guess at is never dropped or
|
||
|
|
// mistranslated: it stays visible as its verbatim source in a marked
|
||
|
|
// element, so the author sees exactly what was not understood.
|
||
|
|
package scriptorium
|
||
|
|
|
||
|
|
import (
|
||
|
|
"sourcedock.dev/petrbalvin/scriptorium/internal/diagram"
|
||
|
|
"sourcedock.dev/petrbalvin/scriptorium/internal/markdown"
|
||
|
|
"sourcedock.dev/petrbalvin/scriptorium/internal/mathml"
|
||
|
|
)
|
||
|
|
|
||
|
|
// Render renders the Markdown source to HTML. The grammar is the full
|
||
|
|
// CommonMark specification with the GitHub Flavored Markdown extensions,
|
||
|
|
// footnotes and definition lists. Rendering never fails and never
|
||
|
|
// sanitises: the input is trusted, and whether the output may reach an
|
||
|
|
// audience is the consumer's policy.
|
||
|
|
func Render(source []byte) []byte {
|
||
|
|
return markdown.RenderHTML(source)
|
||
|
|
}
|
||
|
|
|
||
|
|
// RenderMath renders the TeX mathematics source to a MathML Core math
|
||
|
|
// element, in the inline form. A construct outside the mappable surface
|
||
|
|
// stays in the output as its verbatim source inside an merror element.
|
||
|
|
func RenderMath(source []byte) []byte {
|
||
|
|
return mathml.Render(source, false)
|
||
|
|
}
|
||
|
|
|
||
|
|
// RenderMathDisplay renders the TeX mathematics source to a MathML Core
|
||
|
|
// math element in the display form, with display="block".
|
||
|
|
func RenderMathDisplay(source []byte) []byte {
|
||
|
|
return mathml.Render(source, true)
|
||
|
|
}
|
||
|
|
|
||
|
|
// RenderDiagram renders the Mermaid diagram source to SVG. The diagram
|
||
|
|
// type must be one SupportedDiagram reports; every other type is refused
|
||
|
|
// with an error naming it.
|
||
|
|
func RenderDiagram(source []byte) ([]byte, error) {
|
||
|
|
return diagram.Render(source)
|
||
|
|
}
|
||
|
|
|
||
|
|
// The Mermaid scope: every diagram type the library accepts. The choice
|
||
|
|
// is measured, not aesthetic: across the documentation of this forge the
|
||
|
|
// diagrams are 44 flowcharts (including the historical "graph" spelling)
|
||
|
|
// and 22 sequence diagrams, with a single outlying state diagram. Every
|
||
|
|
// other type is refused with a clear error rather than a guess.
|
||
|
|
var supportedDiagrams = map[string]bool{
|
||
|
|
"flowchart": true,
|
||
|
|
"graph": true, // the historical alias of flowchart
|
||
|
|
"sequenceDiagram": true,
|
||
|
|
}
|
||
|
|
|
||
|
|
// SupportedDiagram reports whether the library renders the named
|
||
|
|
// Mermaid diagram type.
|
||
|
|
func SupportedDiagram(kind string) bool {
|
||
|
|
return supportedDiagrams[kind]
|
||
|
|
}
|