Extract frontmatter before preprocessing

This commit is contained in:
Adnan Maolood 2021-05-09 16:14:50 -04:00
parent 19852f9e3b
commit b2ca453750
2 changed files with 74 additions and 83 deletions

86
dir.go
View file

@ -12,18 +12,27 @@ import (
"sort"
"strings"
"time"
"gopkg.in/yaml.v3"
)
// Dir represents a directory.
type Dir struct {
Path string
Pages []*Page
Dirs []*Dir
index *Page // The index page.
feed []byte // Atom feed.
}
// Page represents a page.
type Page struct {
Title string
Date time.Time
Content string
Path string
Pages []*Page
Dirs []*Dir
index *Page // The index page.
feed []byte // Atom feed.
Name string `yaml:"-"`
Path string `yaml:"-"`
Content string `yaml:"-"`
Params map[string]string
}
// NewDir returns a new Dir with the given 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
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
}