From b2ca453750075f6b57b4624f25bd2a454dfabc43 Mon Sep 17 00:00:00 2001 From: Adnan Maolood Date: Sun, 9 May 2021 16:14:50 -0400 Subject: [PATCH] Extract frontmatter before preprocessing --- dir.go | 86 +++++++++++++++++++++++++++++++++++++++++++++++++-------- page.go | 71 ----------------------------------------------- 2 files changed, 74 insertions(+), 83 deletions(-) delete mode 100644 page.go diff --git a/dir.go b/dir.go index 1ffdf62..bb12891 100644 --- a/dir.go +++ b/dir.go @@ -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 +} diff --git a/page.go b/page.go deleted file mode 100644 index 32b08e2..0000000 --- a/page.go +++ /dev/null @@ -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 -}