Extract frontmatter before preprocessing

This commit is contained in:
adnano 2021-05-09 16:14:50 -04:00
parent fa19a1746b
commit 4736a6580e
2 changed files with 74 additions and 83 deletions

80
dir.go
View file

@ -12,13 +12,12 @@ import (
"sort" "sort"
"strings" "strings"
"time" "time"
"gopkg.in/yaml.v3"
) )
// Dir represents a directory. // Dir represents a directory.
type Dir struct { type Dir struct {
Title string
Date time.Time
Content string
Path string Path string
Pages []*Page Pages []*Page
Dirs []*Dir Dirs []*Dir
@ -26,6 +25,16 @@ type Dir struct {
feed []byte // Atom feed. 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. // NewDir returns a new Dir with the given path.
func NewDir(path string) *Dir { func NewDir(path string) *Dir {
if path == "" { if path == "" {
@ -69,18 +78,59 @@ func (d *Dir) read(srcDir, path string, task *Task) error {
return err 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 != "" { if cmd := task.PreProcess; cmd != "" {
content = RunProcessCmd(cmd, bytes.NewReader(content)) content = RunProcessCmd(cmd, bytes.NewReader(content))
} }
page.Content = string(content)
// Gather page data
if strings.TrimSuffix(name, ext) == "index" { if strings.TrimSuffix(name, ext) == "index" {
d.index = NewPage(d.Path, content) page.Path = d.Path
d.Title = d.index.Title d.index = page
d.Date = d.index.Date
d.Content = d.index.Content
} else { } 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 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
View file

@ -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
}