2020-11-20 18:07:38 +01:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
pathpkg "path"
|
|
|
|
"regexp"
|
|
|
|
"strings"
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
|
|
|
// Page represents a page.
|
|
|
|
type Page struct {
|
|
|
|
Title string // The title of this page.
|
|
|
|
Path string // The path to this page.
|
|
|
|
Date time.Time // The date of the page.
|
|
|
|
Content string // The content of this page.
|
|
|
|
}
|
|
|
|
|
|
|
|
// titleRe is a regexp to parse titles from Gemini files.
|
|
|
|
// It also matches the next line if it is empty.
|
|
|
|
var titleRE = regexp.MustCompile("^# ?([^#\r\n]+)\r?\n?\r?\n?")
|
|
|
|
|
|
|
|
// 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)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Try to parse the title from the contents
|
|
|
|
if submatches := titleRE.FindSubmatch(content); submatches != nil {
|
|
|
|
page.Title = string(submatches[1])
|
|
|
|
// Remove the title from the contents
|
|
|
|
content = content[len(submatches[0]):]
|
|
|
|
}
|
|
|
|
|
|
|
|
// Remove extension from path
|
2021-02-28 03:42:37 +01:00
|
|
|
page.Path = "/" + strings.TrimSuffix(path, pathpkg.Ext(path)) + "/"
|
2020-11-20 18:07:38 +01:00
|
|
|
page.Content = string(content)
|
|
|
|
return &page
|
|
|
|
}
|