shitty-ssg/cmd/ssg/site/post.go

144 lines
3.1 KiB
Go
Raw Normal View History

package site
import (
"errors"
"fmt"
"html"
"path"
"strconv"
"strings"
"time"
"git.sr.ht/~ewintr/go-kit/slugify"
"git.sr.ht/~ewintr/shitty-ssg/pkg/adoc"
)
var (
ErrInvalidPost = errors.New("invalid post")
)
var pluralKind = map[Kind]string{
KIND_NOTE: "notes",
KIND_STORY: "stories",
KIND_ARTICLE: "articles",
}
type Post struct {
doc *adoc.ADoc
Date time.Time
Kind Kind
Language Language
Tags []Tag
}
func NewPost(doc *adoc.ADoc) *Post {
var tags []Tag
for _, t := range doc.Tags {
tags = append(tags, Tag(t))
}
return &Post{
doc: doc,
Date: doc.Date,
Kind: NewKind(doc.Kind),
Language: Language(doc.Language),
Tags: tags,
}
}
func (p Post) Slug() string {
return slugify.Slugify(p.doc.Title)
}
func (p *Post) Year() string {
return strconv.Itoa(p.Date.Year())
}
func (p *Post) Link() string {
return fmt.Sprintf("%s/", path.Join("/", pluralKind[p.Kind], p.Year(), p.Slug()))
}
func (p *Post) FullLink() string {
return fmt.Sprintf("https://erikwinter.nl%s", p.Link())
}
func (p *Post) HTMLSummary() *HTMLSummary {
summary := ""
if len(p.doc.Content) > 0 {
summary = fmt.Sprintf("<p>%s...</p>", TruncateOnSpace(p.doc.Content[0].Text(), 150))
}
return &HTMLSummary{
Link: p.Link(),
Title: p.doc.Title,
Language: p.Language,
DateLong: FormatDate(p.Date, p.Language, DATE_LONG),
DateShort: FormatDate(p.Date, p.Language, DATE_SHORT),
Summary: summary,
}
}
func (p *Post) HTMLPost() *HTMLPost {
var content string
for _, be := range p.doc.Content {
content += fmt.Sprintf("%s\n", FormatBlock(be))
}
return &HTMLPost{
Slug: p.Slug(),
Title: html.EscapeString(p.doc.Title),
DateLong: FormatDate(p.Date, p.Language, DATE_LONG),
DateShort: FormatDate(p.Date, p.Language, DATE_SHORT),
Content: content,
}
}
func (p *Post) XMLPost() *XMLPost {
var content string
for _, be := range p.doc.Content {
content += fmt.Sprintf("%s\n", FormatBlock(be))
}
return &XMLPost{
Link: p.FullLink(),
Title: html.EscapeString(p.doc.Title),
DateFormal: FormatDate(p.Date, p.Language, DATE_FORMAL),
Content: content,
}
}
func FormatDate(date time.Time, language Language, format DateFormat) string {
switch {
case format == DATE_LONG && language == LANGUAGE_NL:
nlMonth := [...]string{"januari", "februari", "maart",
"april", "mei", "juni", "juli", "augustus", "september",
"oktober", "november", "december",
}
return fmt.Sprintf("%d %s %d", date.Day(), nlMonth[date.Month()-1], date.Year())
case format == DATE_LONG && language == LANGUAGE_EN:
return date.Format("January 2, 2006")
case format == DATE_FORMAL:
return date.Format(time.RFC1123Z)
case format == DATE_SHORT:
fallthrough
default:
return date.Format("2006-01-02 00:00:00")
}
}
func TruncateOnSpace(text string, maxChars int) string {
if len(text) <= maxChars {
return text
}
var keep []string
ss := strings.Split(text, " ")
for _, s := range ss {
if len(strings.Join(keep, " ")+s) > maxChars {
break
}
keep = append(keep, s)
}
return strings.Join(keep, " ")
}