From 103e84d847262830bbaa550b37218e9ca8b317d3 Mon Sep 17 00:00:00 2001 From: Himanshu Sardana Date: Thu, 26 Mar 2026 21:26:35 +0000 Subject: refactor: split into cmd, pkg --- internal/build/parser.go | 82 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 internal/build/parser.go (limited to 'internal/build/parser.go') diff --git a/internal/build/parser.go b/internal/build/parser.go new file mode 100644 index 0000000..e1ef3b0 --- /dev/null +++ b/internal/build/parser.go @@ -0,0 +1,82 @@ +package build + +import ( + "fmt" + "os" + "strings" + + "github.com/adrg/frontmatter" + "github.com/gomarkdown/markdown" + "github.com/gomarkdown/markdown/ast" + "github.com/gomarkdown/markdown/html" + "github.com/gomarkdown/markdown/parser" + + "github.com/HimanshuSardana/kite/pkg/content" +) + +type TOCItem struct { + Level int + Text string + ID string +} + +type ParsedPage struct { + Frontmatter content.Frontmatter + Content []byte + TOC []TOCItem +} + +func ParseMarkdown(path string) (*ParsedPage, error) { + md, err := os.ReadFile(path) + if err != nil { + return nil, fmt.Errorf("reading %s: %w", path, err) + } + + var matter content.Frontmatter + rest, err := frontmatter.Parse(strings.NewReader(string(md)), &matter) + if err != nil { + return nil, fmt.Errorf("parsing frontmatter: %w", err) + } + + extensions := parser.CommonExtensions | parser.AutoHeadingIDs + p := parser.NewWithExtensions(extensions) + doc := p.Parse(rest) + + var toc []TOCItem + ast.WalkFunc(doc, func(node ast.Node, entering bool) ast.WalkStatus { + if heading, ok := node.(*ast.Heading); ok && entering { + text := extractText(heading) + id := string(heading.HeadingID) + + toc = append(toc, TOCItem{ + Level: heading.Level, + Text: text, + ID: id, + }) + } + return ast.GoToNext + }) + + renderer := html.NewRenderer(html.RendererOptions{ + Flags: html.CommonFlags, + }) + + output := markdown.Render(doc, renderer) + + return &ParsedPage{ + Frontmatter: matter, + Content: output, + TOC: toc, + }, nil +} + +func extractText(h *ast.Heading) string { + var text string + ast.WalkFunc(h, func(node ast.Node, entering bool) ast.WalkStatus { + if leaf, ok := node.(*ast.Text); ok && entering { + text += string(leaf.Literal) + } + return ast.GoToNext + }) + return text +} -- cgit v1.3.1