This commit is contained in:
2025-05-04 13:40:31 +02:00
parent afd8edaa6c
commit 92d272b36e
10 changed files with 293 additions and 0 deletions

97
internal/article/load.go Normal file
View File

@@ -0,0 +1,97 @@
// internal/article/load.go
package article
// internal/article/load.go (gekürzt)
import (
"bufio"
"encoding/json"
"fmt"
"html/template"
"io"
"io/fs"
"os"
"path/filepath"
"sort"
"strings"
"time"
md "github.com/gomarkdown/markdown"
"github.com/gomarkdown/markdown/html"
"github.com/gomarkdown/markdown/parser"
)
func LoadDir(root string) ([]Article, error) {
var out []Article
// gültige ExtensionMaske
exts := parser.CommonExtensions | parser.AutoHeadingIDs | parser.DefinitionLists
mdParser := parser.NewWithExtensions(exts)
mdRenderer := html.NewRenderer(html.RendererOptions{
Flags: html.CommonFlags | html.HrefTargetBlank,
})
err := filepath.WalkDir(root, func(p string, d fs.DirEntry, err error) error {
if err != nil || d.IsDir() {
return err
}
ext := filepath.Ext(p)
if ext != ".html" && ext != ".md" {
return nil
}
f, err := os.Open(p)
if err != nil {
return err
}
defer f.Close()
r := bufio.NewReader(f)
headerLine, err := r.ReadBytes('\n')
if err != nil && err != io.EOF {
return err
}
var meta struct {
Title string `json:"title"`
Date string `json:"date"`
Slug string `json:"slug"`
}
clean := strings.TrimSpace(string(headerLine))
clean = strings.TrimPrefix(clean, "<!--")
clean = strings.TrimSpace(clean)
// alles nach dem ersten "-->" abschneiden (egal ob Leerzeichen davor)
if idx := strings.Index(clean, "-->"); idx != -1 {
clean = clean[:idx]
}
clean = strings.TrimSpace(clean)
if err := json.Unmarshal([]byte(clean), &meta); err != nil {
return fmt.Errorf("FrontMatter in %s: %w (%q)", p, err, clean)
}
bodyBytes, err := io.ReadAll(r)
if err != nil {
return err
}
htmlBody := bodyBytes
if ext == ".md" {
htmlBody = md.ToHTML(bodyBytes, mdParser, mdRenderer)
}
date, _ := time.Parse("2006-01-02", meta.Date)
out = append(out, Article{
Title: meta.Title,
Slug: meta.Slug,
Date: date,
Body: template.HTML(htmlBody),
})
return nil
})
sort.Slice(out, func(i, j int) bool { return out[i].Date.After(out[j].Date) })
return out, err
}