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 }