package main import ( "fmt" "html/template" "log" "os" "path" "strings" ) func main() { all := []string{} always := []string{} if err := recursePwd(func(p string) error { switch path.Ext(p) { case ".ctmpl": if path.Base(p)[0] == '_' { all = append(all, p) } } switch path.Base(p) { case "_import.ctmpl": always = append(always, strings.TrimSuffix(path.Base(p), path.Ext(p))) } return nil }); err != nil { panic(err) } t := func(p ...string) *template.Template { p = append(all, p...) oneT, err := template.ParseFiles(p...) if err != nil { panic(err) } return oneT } data := map[string]interface{}{ "This": map[string]interface{}{ "ID": "id00/id11", "Title": "title id11", "PID": "id00", "PTitle": "title id00", "Content": `# hello ## world | this | is | my | table | | ---- | ---| ---| ----- | | hey | | ya | hey | ya | * and * a bulleted * list > but here is a quote ` + "```" + `go // and some go code func main() { log.Println("hi") } ` + "```" + ` and now the newlines `, }, "Results": []struct { Title string ID string }{ {Title: "title id00", ID: "id00"}, {Title: "title id07 but it's really really really long", ID: "id07"}, {Title: "title id00 / title id10", ID: "id00/id10/id10"}, {Title: "title id00 / title id10 / title id20", ID: "id00/id10/id20"}, }, "Tree": `{ "Leaf": {"Title": ""}, "Branches": { "id00": { "Leaf": {"Title": "title id00"}, "Branches": { "id10": {"Leaf":{"Title":"title id10"},"Branches":{ "id20": {"Leaf":{"Title":"title id20"},"Branches":{}} }}, "id11": {"Leaf":{"Title":"title id11"},"Branches":{}} } }, "id01": {"Leaf":{"Title":"title id01"},"Branches":{}}, "id02": {"Leaf":{"Title":"title id02"},"Branches":{}}, "id03": {"Leaf":{"Title":"title id03"},"Branches":{}}, "id04": {"Leaf":{"Title":"title id04"},"Branches":{}}, "id04": {"Leaf":{"Title":"title id04"},"Branches":{}}, "id05": {"Leaf":{"Title":"title id05"},"Branches":{}}, "id06": {"Leaf":{"Title":"title id06"},"Branches":{}}, "id07": {"Leaf":{"Title":"title id07 but it's really really really long"},"Branches":{}} } }`, } if err := recursePwd(func(p string) error { switch path.Ext(p) { case ".ctmpl": target := path.Join(path.Dir(p), "."+path.Base(p)+".html") f, err := os.Create(path.Join(path.Dir(p), "."+path.Base(p)+".html")) if err != nil { return err } defer f.Close() templateToExecute := strings.TrimSuffix(path.Base(p), path.Ext(p)) tmpl := t(p) defer log.Printf("rendering %s (...%s) as %s", templateToExecute, path.Join(path.Base(path.Dir(p)), path.Base(p)), target) if strings.HasPrefix(templateToExecute, "_") { testTemplate := ` {{ define "test" }}
` for _, subtemplate := range always { testTemplate += fmt.Sprintf(`{{ template %q . }}`, subtemplate) } testTemplate += fmt.Sprintf(`{{ template %q . }}{{ end }}`, templateToExecute) testTemplate += ` ` tmpl = template.Must(tmpl.Parse(testTemplate)) templateToExecute = "test" } return tmpl.Lookup(templateToExecute).Execute(f, data) } return nil }); err != nil { panic(err) } } func recursePwd(foo func(string) error) error { wd, err := os.Getwd() if err != nil { return err } return recurseD(wd, foo) } func recurseD(d string, foo func(string) error) error { entries, err := os.ReadDir(d) if err != nil { return err } for _, entry := range entries { if entry.IsDir() { if err := recurseD(path.Join(d, entry.Name()), foo); err != nil { return err } } else if strings.HasPrefix(entry.Name(), ".") { } else if err := foo(path.Join(d, entry.Name())); err != nil { return err } } return nil }