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
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
// 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
|
||||
}
|
||||
Reference in New Issue
Block a user