From 8276f6bcb97be2a2ab0c76de1135517a3b97dc4b Mon Sep 17 00:00:00 2001
From: Přemysl Eric Janouch
Date: Tue, 22 Jun 2021 01:57:15 +0200
Subject: hswg: an initial attempt at refactoring main()
---
hswg/main.go | 195 ++++++++++++++++++++++++++++++++++-------------------------
1 file changed, 112 insertions(+), 83 deletions(-)
diff --git a/hswg/main.go b/hswg/main.go
index 5076bd1..a23e343 100644
--- a/hswg/main.go
+++ b/hswg/main.go
@@ -187,49 +187,61 @@ func expand(m *map[string]*Entry, name string, chunk []byte) []byte {
})
}
-func singleFile() {
- html, meta, err := Render(os.Stdin, configuration.NewConfiguration())
+var tagRE = regexp.MustCompile(`<[^<>]+>`)
+
+func renderEntry(name string, entries *map[string]*Entry) error {
+ e := (*entries)[name]
+
+ f, err := os.Open(e.PathSource)
if err != nil {
- log.Println(err)
- } else if meta.Title != "" {
- _, _ = os.Stdout.WriteString("
")
- _ = xml.EscapeText(os.Stdout, []byte(meta.Title))
- _, _ = os.Stdout.WriteString("
\n")
+ return err
}
- _, _ = io.Copy(os.Stdout, html)
-}
-func main() {
- if len(os.Args) < 2 {
- singleFile()
- return
+ if i, err := f.Stat(); err != nil {
+ return err
+ } else {
+ e.mtime = i.ModTime()
}
- if len(os.Args) < 3 {
- log.Fatalf("usage: %s TEMPLATE GLOB...\n", os.Args[0])
+
+ var html *bytes.Buffer
+ if html, e.Metadata, err = Render(f, configuration.NewConfiguration(
+ configuration.WithFilename(e.PathSource),
+ configuration.WithLastUpdated(e.mtime),
+ )); err != nil {
+ return err
}
- // Read the common page header.
- header, err := ioutil.ReadFile(os.Args[1])
- if err != nil {
- log.Fatalln(err)
+ // Every page needs to have a title.
+ if e.Title == "" {
+ e.Title = name
}
- t, err := template.New("page").Parse(string(header))
- if err != nil {
- log.Fatalln(err)
+ // Expand LinkWords anywhere between .
+ // We want something like the inverse of Regexp.ReplaceAllStringFunc.
+ raw, last, expanded := html.Bytes(), 0, bytes.NewBuffer(nil)
+ for _, where := range tagRE.FindAllIndex(raw, -1) {
+ _, _ = expanded.Write(expand(entries, name, raw[last:where[0]]))
+ _, _ = expanded.Write(raw[where[0]:where[1]])
+ last = where[1]
}
+ _, _ = expanded.Write(expand(entries, name, raw[last:]))
+ e.Content = template.HTML(expanded.String())
+ return nil
+}
+func loadEntries(globs []string) (map[string]*Entry, error) {
// Create a map from document names to their page entries.
entries := map[string]*Entry{}
- for _, glob := range os.Args[2:] {
+ for _, glob := range globs {
matches, err := filepath.Glob(glob)
if err != nil {
- log.Fatalf("%s: %s\n", glob, err)
+ return nil, fmt.Errorf("%s: %s\n", glob, err)
}
for _, path := range matches {
name := stripExtension(filepath.Base(path))
if conflict, ok := entries[name]; ok {
- log.Fatalf("%s: conflicts with %s\n", name, conflict.PathSource)
+ return nil, fmt.Errorf("%s: conflicts with %s\n",
+ name, conflict.PathSource)
}
entries[name] = &Entry{
PathSource: path,
@@ -239,68 +251,38 @@ func main() {
}
}
- tagRE := regexp.MustCompile(`<[^<>]+>`)
- for name, e := range entries {
- f, err := os.Open(e.PathSource)
- if err != nil {
- log.Fatalln(err)
- }
-
- if i, err := f.Stat(); err != nil {
- log.Fatalln(err)
- } else {
- e.mtime = i.ModTime()
- }
-
- var html *bytes.Buffer
- if html, e.Metadata, err = Render(f, configuration.NewConfiguration(
- configuration.WithFilename(e.PathSource),
- configuration.WithLastUpdated(e.mtime),
- )); err != nil {
- log.Fatalln(err)
- }
-
- // Every page needs to have a title.
- if e.Title == "" {
- e.Title = name
- }
-
- // Expand LinkWords anywhere between .
- // We want something like the inverse of Regexp.ReplaceAllStringFunc.
- raw, last, expanded := html.Bytes(), 0, bytes.NewBuffer(nil)
- for _, where := range tagRE.FindAllIndex(raw, -1) {
- _, _ = expanded.Write(expand(&entries, name, raw[last:where[0]]))
- _, _ = expanded.Write(raw[where[0]:where[1]])
- last = where[1]
+ for name := range entries {
+ if err := renderEntry(name, &entries); err != nil {
+ return nil, err
}
- _, _ = expanded.Write(expand(&entries, name, raw[last:]))
- e.Content = template.HTML(expanded.String())
}
+ return entries, nil
+}
- for _, e := range entries {
- f, err := os.Create(e.PathDestination)
- if err != nil {
- log.Fatalln(err)
- }
-
- backlinks := []string{}
- for name := range e.backlinks {
- backlinks = append(backlinks, name)
- }
- sort.Strings(backlinks)
- for _, name := range backlinks {
- e.Backlinks =
- append(e.Backlinks, template.HTML(makeLink(&entries, name)))
- }
+func writeEntry(e *Entry, t *template.Template,
+ entries *map[string]*Entry) error {
+ f, err := os.Create(e.PathDestination)
+ if err != nil {
+ return err
+ }
- if err = t.Execute(f, e); err != nil {
- log.Fatalln(err)
- }
+ backlinks := []string{}
+ for name := range e.backlinks {
+ backlinks = append(backlinks, name)
}
+ sort.Strings(backlinks)
+ for _, name := range backlinks {
+ e.Backlinks =
+ append(e.Backlinks, template.HTML(makeLink(entries, name)))
+ }
+
+ return t.Execute(f, e)
+}
+func writeIndex(t *template.Template, entries *map[string]*Entry) error {
// Reorder entries reversely, primarily by date, secondarily by filename.
ordered := []*Entry{}
- for _, e := range entries {
+ for _, e := range *entries {
ordered = append(ordered, e)
}
@@ -322,15 +304,62 @@ func main() {
return p2.Before(*p1)
})
- // Execute a template from the standard input.
+ // TODO(p): Splitting content to categories would be nice.
+ return t.Execute(os.Stdout, ordered)
+}
+
+func singleFile() {
+ html, meta, err := Render(os.Stdin, configuration.NewConfiguration())
+ if err != nil {
+ log.Println(err)
+ } else if meta.Title != "" {
+ _, _ = os.Stdout.WriteString("")
+ _ = xml.EscapeText(os.Stdout, []byte(meta.Title))
+ _, _ = os.Stdout.WriteString("
\n")
+ }
+ _, _ = io.Copy(os.Stdout, html)
+}
+
+func main() {
+ if len(os.Args) < 2 {
+ singleFile()
+ return
+ }
+ if len(os.Args) < 3 {
+ log.Fatalf("usage: %s TEMPLATE GLOB...\n", os.Args[0])
+ }
+
+ // Read the common page header.
+ header, err := ioutil.ReadFile(os.Args[1])
+ if err != nil {
+ log.Fatalln(err)
+ }
+ t, err := template.New("page").Parse(string(header))
+ if err != nil {
+ log.Fatalln(err)
+ }
+
+ // Process all entries.
+ entries, err := loadEntries(os.Args[2:])
+ if err != nil {
+ log.Fatalln(err)
+ }
+ for _, e := range entries {
+ if err := writeEntry(e, t, &entries); err != nil {
+ log.Fatalln(err)
+ }
+ }
+
+ // Read a template from the standard input, write an index.
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, ordered); err != nil {
+ if err != nil {
+ log.Fatalln(err)
+ }
+ if err := writeIndex(t, &entries); err != nil {
log.Fatalln(err)
}
}
--
cgit v1.2.3-70-g09d2