Files
summercms/internal/docsite/render.go
Jakub Zych 6dacddc040 feat(11.1-01): add summer docs:build with the docsite generator core
- internal/docsite loads docs/ with strict site.yaml and frontmatter decoding
- goldmark GFM pipeline renders pages into an embedded html/template shell
- emits .html pages, .md siblings, llms.txt, llms-full.txt, search-index.json
- output guard refuses unmarked non-empty dirs and --out inside --src or root
- docs/index.md and docs/setup/installation.md; /site/ is gitignored
2026-09-30 21:18:32 +02:00

56 lines
1.6 KiB
Go

package docsite
import (
"bytes"
"fmt"
"github.com/yuin/goldmark"
"github.com/yuin/goldmark/ast"
"github.com/yuin/goldmark/extension"
"github.com/yuin/goldmark/parser"
"github.com/yuin/goldmark/text"
"github.com/yuin/goldmark/util"
)
// newMarkdown returns the one goldmark pipeline every page goes through:
// CommonMark plus GFM, heading IDs, and the page transformers. The html
// renderer keeps its default safe mode, so raw HTML in Markdown is never
// passed through.
func newMarkdown() goldmark.Markdown {
return goldmark.New(
goldmark.WithExtensions(extension.GFM),
goldmark.WithParserOptions(
parser.WithAutoHeadingID(),
parser.WithASTTransformers(
util.Prioritized(h1Stripper{}, 100),
),
),
)
}
// h1Stripper removes the page's leading "# Title" heading; the template
// renders the title once.
type h1Stripper struct{}
func (h1Stripper) Transform(doc *ast.Document, _ text.Reader, _ parser.Context) {
if h, ok := doc.FirstChild().(*ast.Heading); ok && h.Level == 1 {
doc.RemoveChild(doc, h)
}
}
// renderedPage is one page after parsing and rendering.
type renderedPage struct {
html []byte
}
// renderPage parses and renders a page body to HTML.
func (s *site) renderPage(md goldmark.Markdown, p *Page) (renderedPage, error) {
ctx := parser.NewContext()
doc := md.Parser().Parse(text.NewReader(p.Body), parser.WithContext(ctx))
var buf bytes.Buffer
if err := md.Renderer().Render(&buf, p.Body, doc); err != nil {
return renderedPage{}, fmt.Errorf("docsite: render %s: %w", p.Source, err)
}
return renderedPage{html: buf.Bytes()}, nil
}