From 56b0df9e6c84bbcdaffbde50632e7fdd992791e5 Mon Sep 17 00:00:00 2001 From: Alan Pearce Date: Mon, 15 Apr 2024 08:55:53 +0200 Subject: wip: render feeds --- src/build.go | 245 ----------------------------------------------------------- 1 file changed, 245 deletions(-) delete mode 100644 src/build.go (limited to 'src/build.go') diff --git a/src/build.go b/src/build.go deleted file mode 100644 index 3c2dfd5..0000000 --- a/src/build.go +++ /dev/null @@ -1,245 +0,0 @@ -package main - -import ( - "bytes" - "fmt" - "log" - "os" - "path" - "path/filepath" - "slices" - "strings" - "time" - - "github.com/PuerkitoBio/goquery" - "github.com/adrg/frontmatter" - mapset "github.com/deckarep/golang-set/v2" - "github.com/yuin/goldmark" - "github.com/yuin/goldmark/extension" -) - -type PostMatter struct { - Date time.Time `toml:"date"` - Description string `toml:"description"` - Title string `toml:"title"` - Taxonomies struct { - Tags []string `toml:"tags"` - } `toml:"taxonomies"` -} - -type Post struct { - Input string - Output string - Basename string - URL string - Content string - PostMatter -} - -type Tags mapset.Set[string] - -func check(err error) { - if err != nil { - log.Panic(err) - } -} - -func getPost(filename string) (PostMatter, []byte) { - matter := PostMatter{} - content, err := os.Open(filename) - check(err) - rest, err := frontmatter.Parse(content, &matter) - check(err) - - return matter, rest -} - -func readPosts(root string, inputDir string, outputDir string) ([]Post, Tags) { - tags := mapset.NewSet[string]() - posts := []Post{} - subdir := filepath.Join(root, inputDir) - files, err := os.ReadDir(subdir) - outputReplacer := strings.NewReplacer(root, outputDir, ".md", "/index.html") - urlReplacer := strings.NewReplacer(root, "", ".md", "/") - check(err) - md := goldmark.New( - goldmark.WithExtensions( - extension.GFM, - extension.Footnote, - extension.Typographer, - ), - ) - for _, f := range files { - pathFromRoot := filepath.Join(subdir, f.Name()) - check(err) - if !f.IsDir() && path.Ext(pathFromRoot) == ".md" { - output := outputReplacer.Replace(pathFromRoot) - url := urlReplacer.Replace(pathFromRoot) - matter, content := getPost(pathFromRoot) - - for _, tag := range matter.Taxonomies.Tags { - tags.Add(strings.ToLower(tag)) - } - - var buf bytes.Buffer - err := md.Convert(content, &buf) - check(err) - post := Post{ - Input: pathFromRoot, - Output: output, - Basename: filepath.Base(url), - URL: url, - PostMatter: matter, - Content: buf.String(), - } - - posts = append(posts, post) - } - } - slices.SortFunc(posts, func(a, b Post) int { - return b.Date.Compare(a.Date) - }) - return posts, tags -} - -func layout(html string, config Config, pageTitle string) *goquery.Document { - css, err := os.ReadFile("templates/style.css") - check(err) - doc, err := goquery.NewDocumentFromReader(strings.NewReader(html)) - check(err) - doc.Find("html").SetAttr("lang", config.DefaultLanguage) - doc.Find("head > link[rel=alternate]").Add(".title").SetAttr("title", config.Title) - doc.Find("title").Add(".p-name").SetText(pageTitle) - doc.Find("head > style").SetText(string(css)) - nav := doc.Find("nav") - navLink := doc.Find("nav a") - nav.Empty() - for _, link := range config.Menus["main"] { - nav.AppendSelection(navLink.Clone().SetAttr("href", link.URL).SetText(link.Name)) - } - return doc -} - -func renderPost(post Post, config Config) string { - tbytes, err := os.ReadFile("templates/post.html") - check(err) - doc := layout(string(tbytes), config, post.PostMatter.Title) - doc.Find(".title").AddClass("h-card p-author").SetAttr("rel", "author") - datetime, err := post.PostMatter.Date.MarshalText() - check(err) - doc.Find(".h-entry .dt-published").SetAttr("datetime", string(datetime)).SetText( - post.PostMatter.Date.Format("2006-01-02"), - ) - doc.Find(".h-entry .e-content").SetHtml(post.Content) - categories := doc.Find(".h-entry .p-categories") - cat := categories.Find(".p-category").ParentsUntilSelection(categories) - cat.Remove() - for _, tag := range post.Taxonomies.Tags { - categories.AppendSelection(cat.Clone().Find(".p-category").SetAttr("href", fmt.Sprintf("/tags/%s/", tag)).SetText("#" + tag)).Parent() - } - html, err := doc.Html() - check(err) - return html -} - -func renderTags(tags Tags, config Config) string { - tbytes, err := os.ReadFile("templates/tags.html") - check(err) - - doc := layout(string(tbytes), config, config.Title) - tagList := doc.Find(".tags") - tpl := doc.Find(".h-feed") - tpl.Remove() - for _, tag := range mapset.Sorted(tags) { - tagList.AppendSelection( - tpl.Clone().SetAttr("href", fmt.Sprintf("/tags/%s/", tag)).SetText("#" + tag), - ) - } - html, err := doc.Html() - check(err) - return html -} - -func renderListPage(tag string, config Config, posts []Post) string { - tbytes, err := os.ReadFile("templates/list.html") - check(err) - var title string - if len(tag) > 0 { - title = tag - } else { - title = config.Title - } - doc := layout(string(tbytes), config, title) - feed := doc.Find(".h-feed") - tpl := feed.Find(".h-entry") - tpl.Remove() - - doc.Find(".title").AddClass("h-card p-author").SetAttr("rel", "author") - if tag == "" { - doc.Find(".filter").Remove() - } else { - doc.Find(".filter").Find("h3").SetText("#" + tag) - } - - for _, post := range posts { - entry := tpl.Clone() - datetime, err := post.PostMatter.Date.MarshalText() - check(err) - - entry.Find(".p-name").SetText(post.Title).SetAttr("href", post.URL) - entry.Find(".dt-published").SetAttr("datetime", string(datetime)).SetText(post.PostMatter.Date.Format("2006-01-02")) - feed.AppendSelection(entry) - } - - html, err := doc.Html() - check(err) - return html -} - -func main() { - config := getConfig() - err := os.MkdirAll("public/post", 0755) - check(err) - log.Print("Generating site...") - posts, tags := readPosts("content", "post", "public") - for _, post := range posts { - err := os.MkdirAll(path.Join("public", "post", post.Basename), 0755) - check(err) - // output := renderPost(post, config) - // err = os.WriteFile(post.Output, []byte(output), 0755) - // check(err) - } - err = os.MkdirAll("public/tags", 0755) - check(err) - // fmt.Printf("%+v\n", renderTags(tags, config)) - // err = os.WriteFile("public/tags/index.html", []byte(renderTags(tags, config)), 0755) - // check(err) - for _, tag := range tags.ToSlice() { - matchingPosts := []Post{} - for _, post := range posts { - if slices.Contains(post.Taxonomies.Tags, tag) { - matchingPosts = append(matchingPosts, post) - } - } - err := os.MkdirAll(path.Join("public", "tags", tag), 0755) - check(err) - // tagPage := renderListPage(tag, config, matchingPosts) - // fmt.Printf("%+v\n", tagPage) - // err = os.WriteFile(path.Join("public", "tags", tag, "index.html"), []byte(tagPage), 0755) - // check(err) - - // TODO: tag atom - - fmt.Printf("%+v\n", renderListPage("", config, posts)) - - // TODO: atom - - // TODO: renderFeedStyles - - // TODO: renderHomepage - - // TODO: render404Page - } - - fmt.Printf("%+v\n", tags) -} -- cgit 1.4.1