htmlroc/main.go

112 lines
2.8 KiB
Go

package main // import "git.fromouter.space/mcg/htmlroc"
import (
"flag"
"fmt"
"html/template"
"io/ioutil"
"os"
"strings"
)
// Where are we in the file
const (
FStart = "start" // File start
InTOC = "intoc" // In Table of content
AfterTOC = "aftertoc" // After Table of content
)
// TemplateData is the data that is filled and passed to the HTML template
type TemplateData struct {
Title string
CSSFile string
Credits string
}
var funmap = template.FuncMap{
"htmlify": tplHtmlify,
}
// HTMLrocCredits is the credit string to append to the other credits
const HTMLrocCredits = "Converted to HTML using <a href=\"https://git.fromouter.space/mcg/htmlroc\">htmlroc</a>"
func main() {
txtfile := flag.String("in", "rules.txt", "Path to rules.txt file")
tplfile := flag.String("template", "template.html", "Path to template file")
outname := flag.String("out", "out.html", "Output file")
style := flag.String("css", "style.css", "Name of the CSS stylesheet")
// Read template file
tpl, err := template.New(*tplfile).Funcs(funmap).ParseFiles(*tplfile)
checkErr(err, "Could not load template file \"%s\"", *tplfile)
tpldata := TemplateData{
CSSFile: *style,
}
// Read rules file
filebytes, err := ioutil.ReadFile(*txtfile)
checkErr(err, "Could not read rules file \"%s\"", *txtfile)
filestr := string(filebytes)
// Use table of content as delimiter between credits and rule text
toc := strings.Index(filestr, "Table of Contents")
if toc < 0 {
fmt.Fprintln(os.Stderr, "could not find TOC")
os.Exit(1)
}
// Extract credits
tpldata.Credits, filestr = strings.TrimSpace(filestr[:toc]), filestr[toc:]
// Add our own credits
tpldata.Credits += "\n" + HTMLrocCredits
// Rules are after TOC
tocend := strings.Index(filestr, "\n\n")
if tocend < 0 {
fmt.Fprintln(os.Stderr, "could not find end of TOC")
os.Exit(1)
}
// Strip TOC out
filestr = filestr[tocend+2:]
// Every rule is a line (pretty handy!)
lines := strings.Split(filestr, "\n")
for _, line := range lines {
// Skip empty lines
line = strings.TrimSpace(line)
if len(line) < 1 {
continue
}
}
// Create output file
outfile, err := os.Create(*outname)
checkErr(err, "Could not create output file \"%s\"", *outname)
defer outfile.Close()
// Run template on output file stream
checkErr(tpl.Execute(outfile, tpldata), "Error running template")
}
func checkErr(err error, fmtstr string, args ...interface{}) {
if err != nil {
fmt.Fprintf(os.Stderr, "FATAL: "+fmtstr+":\n ", args...)
fmt.Fprintln(os.Stderr, err.Error())
os.Exit(1)
}
}
func tplHtmlify(str string) template.HTML {
// Make first line an heading
idx := strings.IndexRune(str, '\n')
if idx > 0 {
str = "<h1>" + str[:idx] + "</h1>" + str[idx:]
}
// Replace newlines with HTML line-break tag
str = strings.ReplaceAll(str, "\n", "<br />")
return template.HTML(str)
}