From 3cb7c82cf7c4e050148f69be23590a7fbe587a27 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 31 Mar 2026 10:11:18 +0000 Subject: Add static site builder: SQLite-backed MD→HTML pipeline MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - cmd/nebbet: CLI with build [--watch] and user add/passwd/delete/list - internal/builder: markdown→HTML, component injection via HTML comments, auto importmap from lib/, fsnotify watch with 150ms debounce - internal/db: meta.db (page index, tag queries) + search.db (FTS5) - internal/sqlitedrv: minimal CGO database/sql driver for system libsqlite3 - internal/auth: htpasswd-compatible bcrypt password file management - templates/base.html + admin.html, styles/main.css + admin.css - nginx.conf with auth_basic for /admin, clean URLs, gzip - nebbet.service systemd unit for watch daemon - Example content/index.md and components/site-greeting.js https://claude.ai/code/session_01HTc1BCBCiMTEB54XQP1Wz9 --- internal/builder/markdown.go | 49 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 internal/builder/markdown.go (limited to 'internal/builder/markdown.go') diff --git a/internal/builder/markdown.go b/internal/builder/markdown.go new file mode 100644 index 0000000..4e00ca3 --- /dev/null +++ b/internal/builder/markdown.go @@ -0,0 +1,49 @@ +package builder + +import ( + "bytes" + "regexp" + "strings" + + "github.com/yuin/goldmark" + "github.com/yuin/goldmark/extension" + "github.com/yuin/goldmark/parser" + "github.com/yuin/goldmark/renderer/html" +) + +var md = goldmark.New( + goldmark.WithExtensions( + extension.GFM, + extension.Table, + extension.Strikethrough, + extension.TaskList, + ), + goldmark.WithParserOptions( + parser.WithAutoHeadingID(), + ), + goldmark.WithRendererOptions( + // Allow raw HTML pass-through so component tags survive round-trip. + html.WithUnsafe(), + ), +) + +// MarkdownToHTML converts a markdown string to an HTML fragment. +func MarkdownToHTML(body string) (string, error) { + var buf bytes.Buffer + if err := md.Convert([]byte(body), &buf); err != nil { + return "", err + } + return buf.String(), nil +} + +var ( + htmlTagRe = regexp.MustCompile(`<[^>]+>`) + multiSpaceRe = regexp.MustCompile(`\s+`) +) + +// StripHTML removes HTML tags and normalises whitespace for search indexing. +func StripHTML(h string) string { + plain := htmlTagRe.ReplaceAllString(h, " ") + plain = multiSpaceRe.ReplaceAllString(plain, " ") + return strings.TrimSpace(plain) +} -- cgit v1.3