commit 7d0c0f8
Artur Manuel
·
2026-05-31 18:40:26 +0000 UTC
parent 3beff71
meta: remove glerc leftovers
9 files changed,
+0,
-444
D
Makefile
+0,
-15
1@@ -1,15 +0,0 @@
2-.POSIX:
3-
4-GO ?= go
5-
6-all:
7- $(GO) build ./cmd/generate_pages
8-
9-clean:
10- rm generate_pages
11-
12-lint:
13- $(GO) fmt ./...
14- $(GO) vet ./...
15- $(GO) fix ./...
16- staticcheck ./...
+0,
-105
1@@ -1,105 +0,0 @@
2-package main
3-
4-import (
5- "context"
6- "log/slog"
7- "os"
8- "path/filepath"
9- "strings"
10-
11- "codeberg.org/dani-institute/pages/pkg/ssg"
12- "github.com/urfave/cli/v3"
13- "github.com/yuin/goldmark"
14- meta "github.com/yuin/goldmark-meta"
15- "github.com/yuin/goldmark/parser"
16-)
17-
18-var cmd = cli.Command{
19- Name: "generate_pages",
20- Version: "2026.5.0",
21- Flags: []cli.Flag{
22- &cli.StringFlag{
23- Name: "base-url",
24- Value: "",
25- },
26- &cli.StringFlag{
27- Name: "config",
28- Value: "./config.toml",
29- },
30- &cli.StringFlag{
31- Name: "templates-dir",
32- Value: "./templates",
33- },
34- &cli.StringFlag{
35- Name: "pages-dir",
36- Value: "./pages",
37- },
38- &cli.StringFlag{
39- Name: "assets-dir",
40- Value: "./assets",
41- },
42- &cli.StringFlag{
43- Name: "output-dir",
44- Value: "./output",
45- },
46- },
47- Action: mainAction,
48-}
49-
50-func mainAction(ctx context.Context, c *cli.Command) error {
51- slog.Info("generating pages")
52- var config ssg.Config
53- baseUrl := c.String("base-url")
54- _ = baseUrl
55- configFile := c.String("config")
56- if err := ssg.LoadConfigFile(configFile, &config); err != nil {
57- return err
58- }
59- pagesDir := c.String("pages-dir")
60- pages, err := ssg.GetPages(pagesDir)
61- if err != nil {
62- return err
63- }
64- templatesDir := c.String("templates-dir")
65- templates, err := ssg.GetTemplates(templatesDir)
66- if err != nil {
67- return err
68- }
69- sidebar, err := ssg.GetSidebar(pagesDir, config.SidebarOrder)
70- if err != nil {
71- return err
72- }
73- outputDir := c.String("output-dir")
74- if err := os.MkdirAll(outputDir, 0o700); os.IsNotExist(err) {
75- return err
76- }
77- assetsDir := c.String("assets-dir")
78- if err := ssg.CopyDir(assetsDir, outputDir); err != nil {
79- return err
80- }
81- markdown := goldmark.New(
82- goldmark.WithExtensions(meta.Meta),
83- goldmark.WithParserOptions(parser.WithAutoHeadingID()),
84- )
85- for path, page := range pages {
86- name := strings.TrimSuffix(filepath.Base(path), ".md")
87- slog.Info("building page", "page", name)
88- outputPath := filepath.Join(outputDir, name) + ".html"
89- f, err := os.Create(outputPath)
90- if err != nil {
91- return err
92- }
93- defer f.Close()
94- if err := ssg.BuildPage(f, name, path, page, markdown, templates, config, baseUrl, sidebar); err != nil {
95- return err
96- }
97- }
98- return nil
99-}
100-
101-func main() {
102- if err := cmd.Run(context.Background(), os.Args); err != nil {
103- slog.Error("got err while generating pages", "err", err)
104- os.Exit(1)
105- }
106-}
D
go.mod
+0,
-11
1@@ -1,11 +0,0 @@
2-module codeberg.org/dani-institute/pages
3-
4-go 1.26.2
5-
6-require (
7- github.com/BurntSushi/toml v1.6.0 // indirect
8- github.com/urfave/cli/v3 v3.8.0 // indirect
9- github.com/yuin/goldmark v1.8.2 // indirect
10- github.com/yuin/goldmark-meta v1.1.0 // indirect
11- gopkg.in/yaml.v2 v2.3.0 // indirect
12-)
D
go.sum
+0,
-11
1@@ -1,11 +0,0 @@
2-github.com/BurntSushi/toml v1.6.0 h1:dRaEfpa2VI55EwlIW72hMRHdWouJeRF7TPYhI+AUQjk=
3-github.com/BurntSushi/toml v1.6.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
4-github.com/urfave/cli/v3 v3.8.0 h1:XqKPrm0q4P0q5JpoclYoCAv0/MIvH/jZ2umzuf8pNTI=
5-github.com/urfave/cli/v3 v3.8.0/go.mod h1:ysVLtOEmg2tOy6PknnYVhDoouyC/6N42TMeoMzskhso=
6-github.com/yuin/goldmark v1.8.2 h1:kEGpgqJXdgbkhcOgBxkC0X0PmoPG1ZyoZ117rDVp4zE=
7-github.com/yuin/goldmark v1.8.2/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg=
8-github.com/yuin/goldmark-meta v1.1.0 h1:pWw+JLHGZe8Rk0EGsMVssiNb/AaPMHfSRszZeUeiOUc=
9-github.com/yuin/goldmark-meta v1.1.0/go.mod h1:U4spWENafuA7Zyg+Lj5RqK/MF+ovMYtBvXi1lBb2VP0=
10-gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
11-gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
12-gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+0,
-26
1@@ -1,26 +0,0 @@
2-package ssg
3-
4-import (
5- "os"
6-
7- "github.com/BurntSushi/toml"
8-)
9-
10-type Config struct {
11- BaseURL string `toml:"base_url"`
12- Title string `toml:"title"`
13- Description string `toml:"description"`
14- Extra map[string]any `toml:"extra"`
15- SidebarOrder []string `toml:"sidebar_order"`
16-}
17-
18-func LoadConfigFile(fn string, config *Config) error {
19- out, err := os.ReadFile(fn)
20- if err != nil {
21- return err
22- }
23- if err := toml.Unmarshal(out, config); err != nil {
24- return err
25- }
26- return nil
27-}
+0,
-103
1@@ -1,103 +0,0 @@
2-package ssg
3-
4-import (
5- "bytes"
6- "io"
7- "io/fs"
8- "log/slog"
9- "os"
10- "path/filepath"
11- "strings"
12-
13- "github.com/yuin/goldmark"
14- "github.com/yuin/goldmark-meta"
15- "github.com/yuin/goldmark/parser"
16-)
17-
18-type PageError int
19-
20-const (
21- _ PageError = iota
22- NonExistentTemplate
23-)
24-
25-func (e PageError) Error() string {
26- switch e {
27- case NonExistentTemplate:
28- return "given template does not exist"
29- }
30- panic("this should not be reached")
31-}
32-
33-func GetPages(dir string) (map[string]string, error) {
34- res := make(map[string]string, 0)
35- err := filepath.WalkDir(dir, func(path string, d fs.DirEntry, err error) error {
36- if err != nil {
37- slog.Error("got err while reading path", "path", path, "err", err)
38- return filepath.SkipDir
39- }
40- if !d.IsDir() && strings.HasSuffix(path, ".md") {
41- content, err := os.ReadFile(path)
42- if err != nil {
43- slog.Error("got err while reading file", "file", path, "err", err)
44- return filepath.SkipDir
45- }
46- res[path] = string(content)
47- }
48- return nil
49- })
50- if err != nil {
51- return res, err
52- }
53- return res, nil
54-}
55-
56-func BuildPage(w io.Writer, name string, path string, page string, markdown goldmark.Markdown, templates Templates, config Config, baseUrl string, sidebar []SidebarItem) error {
57- var buff bytes.Buffer
58- ctx := parser.NewContext()
59- if err := markdown.Convert([]byte(page), &buff, parser.WithContext(ctx)); err != nil {
60- return err
61- }
62- frontmatter := meta.Get(ctx)
63- var templateName string
64- switch v := frontmatter["template"]; v {
65- case nil:
66- if name == "index" {
67- templateName = "index"
68- } else {
69- templateName = "page"
70- }
71- default:
72- templateName = v.(string)
73- }
74- if baseUrl == "" {
75- baseUrl = config.BaseURL
76- }
77- var title string
78- switch v := frontmatter["title"]; v {
79- case nil:
80- title = config.Title
81- default:
82- title = v.(string)
83- }
84- var description string
85- switch v := frontmatter["description"]; v {
86- case nil:
87- description = config.Description
88- default:
89- description = v.(string)
90- }
91- templateData := TemplateData{
92- Title: title,
93- Description: description,
94- BaseURL: baseUrl,
95- Params: frontmatter,
96- Config: config,
97- Content: buff.String(),
98- Sidebar: sidebar,
99- }
100- if err := BuildTemplate(w, name, templates[templateName], templateData); err != nil {
101- return err
102- }
103- return nil
104-}
1@@ -1,43 +0,0 @@
2-package ssg
3-
4-import (
5- "os"
6- "sort"
7- "strings"
8-)
9-
10-func GetSidebar(pagesDir string, order []string) ([]SidebarItem, error) {
11- entries, err := os.ReadDir(pagesDir)
12- if err != nil {
13- return nil, err
14- }
15-
16- var nav []SidebarItem
17-
18- for _, entry := range entries {
19- name := entry.Name()
20- stem, ok := strings.CutSuffix(name, ".md")
21- if !ok {
22- continue
23- }
24- nav = append(nav, SidebarItem{
25- Name: stem,
26- Path: stem + ".html",
27- })
28- }
29-
30- sort.Slice(nav, func(i, j int) bool {
31- iIdx, jIdx := len(order), len(order)
32- for k, v := range order {
33- if nav[i].Name == v {
34- iIdx = k
35- }
36- if nav[j].Name == v {
37- jIdx = k
38- }
39- }
40- return iIdx < jIdx
41- })
42-
43- return nav, nil
44-}
+0,
-73
1@@ -1,73 +0,0 @@
2-package ssg
3-
4-import (
5- "io"
6- "os"
7- "path/filepath"
8- "strings"
9- "text/template"
10-)
11-
12-type TemplateData struct {
13- Title string
14- Description string
15- BaseURL string
16- Params map[string]any
17- Config Config
18- Content string
19- Sidebar []SidebarItem
20-}
21-
22-type SidebarItem struct {
23- Name string
24- Path string
25-}
26-
27-type Templates map[string]string
28-
29-func DefaultTemplateData() TemplateData {
30- return TemplateData{
31- Title: "",
32- Description: "",
33- BaseURL: "",
34- Params: map[string]any{},
35- Config: Config{},
36- Content: "",
37- }
38-}
39-
40-func BuildTemplate(w io.Writer, name string, t string, data TemplateData) error {
41- master, err := template.New(name).Parse(t)
42- if err != nil {
43- return err
44- }
45- _, err = master.New("content").Parse(data.Content)
46- if err != nil {
47- return err
48- }
49- if err := master.ExecuteTemplate(w, name, data); err != nil {
50- return err
51- }
52- return nil
53-}
54-
55-func GetTemplates(dir string) (Templates, error) {
56- res := make(map[string]string, 0)
57- entries, err := os.ReadDir(dir)
58- if err != nil {
59- return res, err
60- }
61- for _, entry := range entries {
62- entryName := entry.Name()
63- if !strings.HasSuffix(entryName, ".html") {
64- continue
65- }
66- name := strings.TrimSuffix(filepath.Base(entryName), ".html")
67- content, err := os.ReadFile(filepath.Join(dir, entryName))
68- if err != nil {
69- return res, err
70- }
71- res[name] = string(content)
72- }
73- return res, nil
74-}
+0,
-57
1@@ -1,57 +0,0 @@
2-package ssg
3-
4-import (
5- "io"
6- "os"
7- "path/filepath"
8-)
9-
10-func CopyDir(source string, destination string) error {
11- srcInfo, err := os.Stat(source)
12- if err != nil {
13- return err
14- }
15- if err := os.MkdirAll(destination, srcInfo.Mode()); err != nil {
16- return err
17- }
18- entries, err := os.ReadDir(source)
19- if err != nil {
20- return err
21- }
22- for _, entry := range entries {
23- entrySrc := filepath.Join(source, entry.Name())
24- entryDest := filepath.Join(destination, entry.Name())
25- if entry.IsDir() {
26- if err := CopyDir(entrySrc, entryDest); err != nil {
27- return err
28- }
29- } else {
30- if err := CopyFile(entrySrc, entryDest); err != nil {
31- return err
32- }
33- }
34- }
35- return nil
36-}
37-
38-func CopyFile(srcPath string, destPath string) error {
39- info, err := os.Stat(srcPath)
40- if err != nil {
41- return err
42- }
43- src, err := os.Open(srcPath)
44- if err != nil {
45- return err
46- }
47- defer src.Close()
48- dest, err := os.OpenFile(destPath, os.O_WRONLY|os.O_CREATE, info.Mode())
49- if err != nil {
50- return err
51- }
52- defer dest.Close()
53- _, err = io.Copy(dest, src)
54- if err != nil {
55- return err
56- }
57- return nil
58-}