diff options
Diffstat (limited to 'internal/builder/frontmatter.go')
| -rw-r--r-- | internal/builder/frontmatter.go | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/internal/builder/frontmatter.go b/internal/builder/frontmatter.go new file mode 100644 index 0000000..34de484 --- /dev/null +++ b/internal/builder/frontmatter.go @@ -0,0 +1,64 @@ +package builder + +import ( + "strings" +) + +// Frontmatter holds parsed page metadata from YAML-style front matter. +type Frontmatter struct { + Title string + Date string + Tags []string + Layout string // template name without extension, default "base" + Draft bool +} + +// ParseFrontmatter splits the optional ---...--- block from the markdown body. +// Supports: title, date, tags (comma-list or [a, b]), layout, draft. +func ParseFrontmatter(content string) (Frontmatter, string) { + fm := Frontmatter{Layout: "base"} + if !strings.HasPrefix(content, "---") { + return fm, content + } + // Find closing --- + rest := content[3:] + end := strings.Index(rest, "\n---") + if end == -1 { + return fm, content + } + block := strings.TrimSpace(rest[:end]) + body := strings.TrimSpace(rest[end+4:]) // skip \n--- + + for _, line := range strings.Split(block, "\n") { + k, v, ok := strings.Cut(strings.TrimSpace(line), ":") + if !ok { + continue + } + k = strings.TrimSpace(k) + v = strings.TrimSpace(v) + switch k { + case "title": + fm.Title = strings.Trim(v, `"'`) + case "date": + fm.Date = v + case "layout": + fm.Layout = strings.Trim(v, `"'`) + case "draft": + fm.Draft = v == "true" + case "tags": + fm.Tags = parseTags(v) + } + } + return fm, body +} + +func parseTags(v string) []string { + v = strings.Trim(v, "[] ") + var tags []string + for _, p := range strings.Split(v, ",") { + if t := strings.Trim(strings.TrimSpace(p), `"'`); t != "" { + tags = append(tags, t) + } + } + return tags +} |
