diff options
| author | Přemysl Eric Janouch <p@janouch.name> | 2020-09-21 19:00:37 +0200 | 
|---|---|---|
| committer | Přemysl Eric Janouch <p@janouch.name> | 2020-09-21 19:26:55 +0200 | 
| commit | 8f542c71208b1944979b2e50ad1a328aab98f230 (patch) | |
| tree | d5344be3420be7c8272cf854cacfc9615b8f6533 /hswg | |
| parent | ea8c59961cf4b1d1ee72f6c364bff460462f2447 (diff) | |
| download | haven-8f542c71208b1944979b2e50ad1a328aab98f230.tar.gz haven-8f542c71208b1944979b2e50ad1a328aab98f230.tar.xz haven-8f542c71208b1944979b2e50ad1a328aab98f230.zip | |
hswg: execute a template given on standard input
So that information can be extracted from documents easily.
Diffstat (limited to 'hswg')
| -rw-r--r-- | hswg/main.go | 58 | 
1 files 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("<a href='%s'>%s</a>", resultPath(e.path), name) +	return fmt.Sprintf("<a href='%s'>%s</a>", 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("<p id=footer>Last updated: %s"+  			" — <a href='%s'>Source</p>\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)  	}  } | 
