Files
mopac-pdf/templates/templates.go
T
mrcharles 10e930e46d mopac-pdf v0: markdown to beautiful PDFs via digest-pinned typst
Go CLI that turns the markdown currency of this stack (Redmine notes,
Discourse posts, briefing output) into typeset PDFs: two embedded typst
templates (report with title page/TOC/headers, dense brief), front-matter
(title/subtitle/author/date/classification/template), GFM tables, and
bar charts rendered in pure Go (go-chart) from fenced chart data blocks.
Engine is a prebuilt typst 0.15.1 container pinned by digest and run
--network none; PDF bytes to stdout or -o. Exit codes 0/1/2.

All dev in docker (dev.sh/Makefile); unit tests + golden typst fixtures
plus a host-side smoke against the real engine container.

Generated with Crush

Assisted-by: Crush:glm-5.2
2026-08-29 05:44:24 -05:00

53 lines
1.3 KiB
Go

// Package templates embeds the shipped typst templates so the mopac-pdf
// binary is self-contained: the engine container only ever sees the
// prepared compile root.
package templates
import (
"embed"
"fmt"
"os"
"path/filepath"
"strings"
)
//go:embed *.typ
var embedded embed.FS
// Names lists the shipped template names ("report", "brief").
func Names() []string {
entries, err := embedded.ReadDir(".")
if err != nil {
return nil
}
var names []string
for _, e := range entries {
if !e.IsDir() && strings.HasSuffix(e.Name(), ".typ") {
names = append(names, strings.TrimSuffix(e.Name(), ".typ"))
}
}
return names
}
// Source returns the template source for name: from dir when set (custom
// template drop-in), else the embedded copy.
func Source(dir, name string) (string, error) {
if strings.ContainsAny(name, `/\.`) || name == "" {
return "", fmt.Errorf("template: invalid name %q", name)
}
if dir != "" {
data, err := os.ReadFile(filepath.Join(dir, name+".typ"))
if err == nil {
return string(data), nil
}
if !os.IsNotExist(err) {
return "", err
}
}
data, err := embedded.ReadFile(name + ".typ")
if err != nil {
return "", fmt.Errorf("template %q not found (shipped: %s)", name, strings.Join(Names(), ", "))
}
return string(data), nil
}