mirror of
https://git.sr.ht/~adnano/kiln
synced 2024-11-27 20:14:20 +00:00
Extract frontmatter before preprocessing
This commit is contained in:
parent
fa19a1746b
commit
4736a6580e
80
dir.go
80
dir.go
|
@ -12,13 +12,12 @@ import (
|
|||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
// Dir represents a directory.
|
||||
type Dir struct {
|
||||
Title string
|
||||
Date time.Time
|
||||
Content string
|
||||
Path string
|
||||
Pages []*Page
|
||||
Dirs []*Dir
|
||||
|
@ -26,6 +25,16 @@ type Dir struct {
|
|||
feed []byte // Atom feed.
|
||||
}
|
||||
|
||||
// Page represents a page.
|
||||
type Page struct {
|
||||
Title string
|
||||
Date time.Time
|
||||
Name string `yaml:"-"`
|
||||
Path string `yaml:"-"`
|
||||
Content string `yaml:"-"`
|
||||
Params map[string]string
|
||||
}
|
||||
|
||||
// NewDir returns a new Dir with the given path.
|
||||
func NewDir(path string) *Dir {
|
||||
if path == "" {
|
||||
|
@ -69,18 +78,59 @@ func (d *Dir) read(srcDir, path string, task *Task) error {
|
|||
return err
|
||||
}
|
||||
|
||||
page := &Page{}
|
||||
|
||||
// Try to parse the date from the page filename
|
||||
const layout = "2006-01-02"
|
||||
base := pathpkg.Base(path)
|
||||
if len(base) >= len(layout) {
|
||||
dateStr := base[:len(layout)]
|
||||
if time, err := time.Parse(layout, dateStr); err == nil {
|
||||
page.Date = time
|
||||
// Remove the date from the path
|
||||
base = base[len(layout):]
|
||||
if len(base) > 0 {
|
||||
// Remove a leading dash
|
||||
if base[0] == '-' {
|
||||
base = base[1:]
|
||||
}
|
||||
if len(base) > 0 {
|
||||
dir := pathpkg.Dir(path)
|
||||
if dir == "." {
|
||||
dir = ""
|
||||
}
|
||||
path = pathpkg.Join(dir, base)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Extract frontmatter from content
|
||||
frontmatter, content := extractFrontmatter(content)
|
||||
if len(frontmatter) != 0 {
|
||||
if err := yaml.Unmarshal(frontmatter, page); err != nil {
|
||||
log.Printf("failed to parse frontmatter for %q: %v", path, err)
|
||||
}
|
||||
|
||||
// Trim leading newlines from content
|
||||
content = bytes.TrimLeft(content, "\r\n")
|
||||
}
|
||||
|
||||
if cmd := task.PreProcess; cmd != "" {
|
||||
content = RunProcessCmd(cmd, bytes.NewReader(content))
|
||||
}
|
||||
page.Content = string(content)
|
||||
|
||||
// Gather page data
|
||||
if strings.TrimSuffix(name, ext) == "index" {
|
||||
d.index = NewPage(d.Path, content)
|
||||
d.Title = d.index.Title
|
||||
d.Date = d.index.Date
|
||||
d.Content = d.index.Content
|
||||
page.Path = d.Path
|
||||
d.index = page
|
||||
} else {
|
||||
d.Pages = append(d.Pages, NewPage(path, content))
|
||||
// Remove extension from path
|
||||
// TODO: Allow using ugly URLs
|
||||
path = strings.TrimSuffix(path, pathpkg.Ext(path))
|
||||
page.Name = pathpkg.Base(path)
|
||||
page.Path = "/" + path + "/"
|
||||
d.Pages = append(d.Pages, page)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -222,3 +272,15 @@ func RunProcessCmd(command string, input io.Reader) []byte {
|
|||
}
|
||||
return output
|
||||
}
|
||||
|
||||
func (d *Dir) Title() string {
|
||||
return d.index.Title
|
||||
}
|
||||
|
||||
func (d *Dir) Date() time.Time {
|
||||
return d.index.Date
|
||||
}
|
||||
|
||||
func (d *Dir) Content() string {
|
||||
return d.index.Content
|
||||
}
|
||||
|
|
71
page.go
71
page.go
|
@ -1,71 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"log"
|
||||
pathpkg "path"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
// Page represents a page.
|
||||
type Page struct {
|
||||
Title string
|
||||
Date time.Time
|
||||
Name string `yaml:"-"`
|
||||
Path string `yaml:"-"`
|
||||
Content string `yaml:"-"`
|
||||
Params map[string]string
|
||||
}
|
||||
|
||||
// NewPage returns a new Page with the given path and content.
|
||||
func NewPage(path string, content []byte) *Page {
|
||||
var page Page
|
||||
|
||||
// Try to parse the date from the page filename
|
||||
const layout = "2006-01-02"
|
||||
base := pathpkg.Base(path)
|
||||
if len(base) >= len(layout) {
|
||||
dateStr := base[:len(layout)]
|
||||
if time, err := time.Parse(layout, dateStr); err == nil {
|
||||
page.Date = time
|
||||
// Remove the date from the path
|
||||
base = base[len(layout):]
|
||||
if len(base) > 0 {
|
||||
// Remove a leading dash
|
||||
if base[0] == '-' {
|
||||
base = base[1:]
|
||||
}
|
||||
if len(base) > 0 {
|
||||
dir := pathpkg.Dir(path)
|
||||
if dir == "." {
|
||||
dir = ""
|
||||
}
|
||||
path = pathpkg.Join(dir, base)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Extract frontmatter from content
|
||||
var frontmatter []byte
|
||||
frontmatter, content = extractFrontmatter(content)
|
||||
if len(frontmatter) != 0 {
|
||||
if err := yaml.Unmarshal(frontmatter, &page); err != nil {
|
||||
log.Printf("failed to parse frontmatter for %q: %v", path, err)
|
||||
}
|
||||
|
||||
// Trim leading newlines from content
|
||||
content = bytes.TrimLeft(content, "\r\n")
|
||||
}
|
||||
|
||||
// Remove extension from path
|
||||
// TODO: Allow using ugly URLs
|
||||
path = strings.TrimSuffix(path, pathpkg.Ext(path))
|
||||
page.Name = pathpkg.Base(path)
|
||||
page.Path = "/" + path + "/"
|
||||
page.Content = string(content)
|
||||
return &page
|
||||
}
|
Loading…
Reference in a new issue