diff options
| author | Claude <noreply@anthropic.com> | 2026-03-31 12:11:18 +0200 |
|---|---|---|
| committer | Claude <noreply@anthropic.com> | 2026-03-31 12:11:18 +0200 |
| commit | 3cb7c82cf7c4e050148f69be23590a7fbe587a27 (patch) | |
| tree | d2b6506db2de72b3a6982cfbe69925b88936de90 /internal/builder/markdown.go | |
| parent | 33f214f6cd9729473bb55fd7b3b923d5d960bb98 (diff) | |
| download | nebbet.no-3cb7c82cf7c4e050148f69be23590a7fbe587a27.tar.xz nebbet.no-3cb7c82cf7c4e050148f69be23590a7fbe587a27.zip | |
Add static site builder: SQLite-backed MD→HTML pipeline
- 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
Diffstat (limited to 'internal/builder/markdown.go')
| -rw-r--r-- | internal/builder/markdown.go | 49 |
1 files changed, 49 insertions, 0 deletions
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) +} |
