- 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
56 lines
1.6 KiB
Go
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
|
|
}
|