From 8f542c71208b1944979b2e50ad1a328aab98f230 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C5=99emysl=20Eric=20Janouch?= Date: Mon, 21 Sep 2020 19:00:37 +0200 Subject: [PATCH] hswg: execute a template given on standard input So that information can be extracted from documents easily. --- hswg/main.go | 58 ++++++++++++++++++++++++++++++++++------------------ 1 file changed, 38 insertions(+), 20 deletions(-) diff --git a/hswg/main.go b/hswg/main.go index b8e6e40..fef3278 100644 --- a/hswg/main.go +++ b/hswg/main.go @@ -6,6 +6,7 @@ import ( "bytes" "encoding/xml" "fmt" + "html/template" "io" "io/ioutil" "log" @@ -127,13 +128,14 @@ func Render(r io.Reader, config configuration.Configuration) ( return } -// entry contains all context information about a single page. -type entry struct { - path string // path - mtime time.Time // modification time - metadata Metadata // metadata - document []byte // inner document with expanded LinkWords - backlinks []string // what documents link back here +// Entry contains all context information about a single page. +type Entry struct { + PathSource string // path to source AsciiDoc + PathDestination string // path to destination HTML + mtime time.Time // modification time + Metadata Metadata // metadata + document []byte // inner document with expanded LinkWords + backlinks []string // what documents link back here } var extRE = regexp.MustCompile(`\.[^/.]*$`) @@ -149,17 +151,17 @@ func resultPath(path string) string { return path + ".html" } -func makeLink(m *map[string]*entry, name string) string { +func makeLink(m *map[string]*Entry, name string) string { e := (*m)[name] - return fmt.Sprintf("%s", resultPath(e.path), name) + return fmt.Sprintf("%s", e.PathDestination, name) } var linkWordRE = regexp.MustCompile(`\b\p{Lu}\p{L}*\b`) -func expand(m *map[string]*entry, name string, chunk []byte) []byte { +func expand(m *map[string]*Entry, name string, chunk []byte) []byte { return linkWordRE.ReplaceAllFunc(chunk, func(match []byte) []byte { if link, ok := (*m)[string(match)]; ok && string(match) != name && - !link.metadata.IsDraft() { + !link.Metadata.IsDraft() { link.backlinks = append(link.backlinks, name) return []byte(makeLink(m, string(match))) } @@ -195,7 +197,7 @@ func main() { } // Create a map from document names to their page entries. - entries := map[string]*entry{} + entries := map[string]*Entry{} for _, glob := range os.Args[2:] { matches, err := filepath.Glob(glob) if err != nil { @@ -204,15 +206,18 @@ func main() { for _, path := range matches { name := stripExtension(filepath.Base(path)) if conflict, ok := entries[name]; ok { - log.Fatalf("%s: conflicts with %s\n", name, conflict.path) + log.Fatalf("%s: conflicts with %s\n", name, conflict.PathSource) + } + entries[name] = &Entry{ + PathSource: path, + PathDestination: resultPath(path), } - entries[name] = &entry{path: path} } } tagRE := regexp.MustCompile(`<[^<>]+>`) for name, e := range entries { - f, err := os.Open(e.path) + f, err := os.Open(e.PathSource) if err != nil { log.Fatalln(err) } @@ -224,8 +229,8 @@ func main() { } var html *bytes.Buffer - if html, e.metadata, err = Render(f, configuration.NewConfiguration( - configuration.WithFilename(e.path), + if html, e.Metadata, err = Render(f, configuration.NewConfiguration( + configuration.WithFilename(e.PathSource), configuration.WithLastUpdated(e.mtime), )); err != nil { log.Fatalln(err) @@ -243,15 +248,16 @@ func main() { e.document = expanded.Bytes() } + // TODO(p): These should be run through html/template. for name, e := range entries { - f, err := os.Create(resultPath(e.path)) + f, err := os.Create(e.PathDestination) if err != nil { log.Fatalln(err) } _, _ = f.Write(header) - title := e.metadata.Title + title := e.Metadata.Title if title == "" { title = name } @@ -277,6 +283,18 @@ func main() { _, _ = f.Write(e.document) _, _ = f.WriteString(fmt.Sprintf("\n", - e.metadata.LastUpdated, e.path)) + e.Metadata.LastUpdated, e.PathSource)) + } + + // Execute a template from the standard input. + var input []byte + if input, err = ioutil.ReadAll(os.Stdin); err != nil { + log.Fatalln(err) + } + + // TODO(p): Splitting content to categories would be nice. + t, err := template.New("-").Parse(string(input)) + if err = t.Execute(os.Stdout, entries); err != nil { + log.Fatalln(err) } }