summaryrefslogtreecommitdiff
path: root/internal/generator/templates/embed.go
blob: ac3efbd484917166c5f12f1a47907f6b23ef71e9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
// Package templates exposes the embedded HTML shell, shared CSS/JS bundles,
// and per-theme assets used by the generator. Themes live as directories
// under templates/themes/<name>/ containing theme.css, theme.js, and meta.json.
// All assets are compiled into the binary via //go:embed so snonux still ships
// as a single self-contained executable.
package templates

import (
	"embed"
	"fmt"
	"io/fs"
	"path"
	"sort"
)

//go:embed shell.tmpl shared/*.tmpl shared/shared.css shared/shared.js themes/*/theme.css themes/*/theme.js themes/*/meta.json
var FS embed.FS

// Shell returns the body of shell.tmpl — the single page template used for
// every generated HTML page. Theme-specific markup is injected at gen time
// from the default theme's meta.json (and at runtime by shared.js for any
// other selected theme).
func Shell() (string, error) {
	b, err := FS.ReadFile("shell.tmpl")
	if err != nil {
		return "", fmt.Errorf("read shell.tmpl: %w", err)
	}
	return string(b), nil
}

// Shared reads a named shared sub-template (currently only "nav").
func Shared(name string) (string, error) {
	b, err := FS.ReadFile(path.Join("shared", name+".tmpl"))
	if err != nil {
		return "", fmt.Errorf("read shared template %q: %w", name, err)
	}
	return string(b), nil
}

// SharedCSS returns the bundled CSS that every page links via shared.css.
// Used by the generator to write dist/shared.css.
func SharedCSS() ([]byte, error) {
	return FS.ReadFile("shared/shared.css")
}

// SharedJS returns the bundled JS that every page references via shared.js.
// Used by the generator to write dist/shared.js.
func SharedJS() ([]byte, error) {
	return FS.ReadFile("shared/shared.js")
}

// ThemeCSS returns the per-theme stylesheet bytes for the named theme.
func ThemeCSS(name string) ([]byte, error) {
	return FS.ReadFile(path.Join("themes", name, "theme.css"))
}

// ThemeJS returns the per-theme script bytes for the named theme.
func ThemeJS(name string) ([]byte, error) {
	return FS.ReadFile(path.Join("themes", name, "theme.js"))
}

// ThemeMeta returns the per-theme meta.json bytes for the named theme.
func ThemeMeta(name string) ([]byte, error) {
	return FS.ReadFile(path.Join("themes", name, "meta.json"))
}

// ThemeNames returns a sorted list of available theme names derived from the
// directories present under templates/themes/.
func ThemeNames() ([]string, error) {
	entries, err := fs.ReadDir(FS, "themes")
	if err != nil {
		return nil, fmt.Errorf("list theme dir: %w", err)
	}

	names := make([]string, 0, len(entries))
	for _, e := range entries {
		if !e.IsDir() {
			continue
		}
		names = append(names, e.Name())
	}

	sort.Strings(names)
	return names, nil
}