diff --git a/README.md b/README.md index 59150e0..8163a37 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,19 @@ # htmlroc -Converts MLP:CCG rule files from text (thanks Hithroc!) to HTML! +Converts MLP:CCG rule files from text to HTML! ## Installation +### Requirements + +- Go 1.12+ +- The text rules from Hithroc's site: + https://horse.cards/rules/latest.txt + +### Running htmlroc + 1. Clone project locally and `cd` to it -2. Download `rules.txt` from Hithroc's site and place it inside the project's folder: - https://horse.cards/rules/latest.txt +2. Place the text rules inside the project's folder as `rules.txt` 3. Run this command: ``` go run . @@ -17,4 +24,4 @@ Alternately, you can compile with `go install` and use the command line flags to ## Thanks to - [Hithroc](https://hithroc.org/) for maitaining text versions of the rules -- [CommentaryIsMagic](http://www.commentaryismagic.com/) for maitaining the rules +- [CommentaryIsMagic](http://www.commentaryismagic.com/) for maitaining the official rules diff --git a/main.go b/main.go index f611dd6..1edd409 100644 --- a/main.go +++ b/main.go @@ -31,14 +31,11 @@ type TemplateRule struct { Depth int } -var funmap = template.FuncMap{ - "toCredits": tplToCredits, - "htmlify": tplHtmlify, -} - // HTMLrocCredits is the credit string to append to the other credits const HTMLrocCredits = "Converted to HTML using htmlroc" +var tpl *template.Template + func main() { // Command line flags txtfile := flag.String("in", "rules.txt", "Path to rules.txt file") @@ -47,7 +44,8 @@ func main() { flag.Parse() // Read template file - tpl, err := template.New(*tplfile).Funcs(funmap).ParseFiles(*tplfile) + var err error + tpl, err = template.New(*tplfile).Funcs(funmap).ParseFiles(*tplfile) checkErr(err, "Could not load template file \"%s\"", *tplfile) tpldata := TemplateData{} @@ -116,7 +114,7 @@ func main() { // Create new section currentSection = &TemplateSection{ ID: parts[0], - Title: parts[1], + Title: strings.TrimSpace(parts[1]), Rules: []TemplateRule{}, Extra: false, } @@ -166,21 +164,4 @@ func checkErr(err error, fmtstr string, args ...interface{}) { fmt.Fprintln(os.Stderr, err.Error()) os.Exit(1) } -} - -func tplToCredits(str string) template.HTML { - // Make first line an heading - idx := strings.IndexRune(str, '\n') - if idx > 0 { - str = "

" + str[:idx] + "

" + str[idx+1:] - } - // Wrap other lines in

tags - str = strings.ReplaceAll(str, "\n", "

") + "

" - return template.HTML(str) -} - -func tplHtmlify(str string) template.HTML { - // Replace newlines with
- str = strings.ReplaceAll(str, "\n", "
") - return template.HTML(str) -} +} \ No newline at end of file diff --git a/style.css b/style.css index 4e69787..2df7db6 100644 --- a/style.css +++ b/style.css @@ -1,46 +1,56 @@ -@import url('https://fonts.googleapis.com/css?family=Roboto:300,400&display=swap'); +@import url("https://fonts.googleapis.com/css?family=Roboto:300,400,700&display=swap"); body { - font-family: 'Roboto', sans-serif; - font-weight: 300; - display: flex; - justify-content: center; - font-size: 11pt; + font-family: "Roboto", sans-serif; + font-weight: 300; + display: flex; + justify-content: center; + font-size: 11pt; + line-height: 150%; } main { - flex: 1; - max-width: 60em; + flex: 1; + max-width: 60em; } h1, h2 { - color: #4b5b69; - font-weight: 400; + color: #4b5b69; + font-weight: 400; } p { - margin: 0; - padding: 2pt 0; + margin: 0; + padding: 2pt 0; } ul { - padding-left: 10pt; + padding-left: 10pt; } li { - margin: 10pt 0; - list-style-type: none; + margin: 10pt 0; + list-style-type: none; } .depth-2 { - padding-left: 20pt; + padding-left: 20pt; } .depth-4 { - padding-left: 40pt; + padding-left: 40pt; } .depth-6 { - padding-left: 60pt; -} \ No newline at end of file + padding-left: 60pt; +} + +.glossary dt { + font-weight: bold; +} + +.glossary dd { + margin-inline-start: 10pt; + margin-bottom: 1rem; +} diff --git a/template.go b/template.go new file mode 100644 index 0000000..eb744d1 --- /dev/null +++ b/template.go @@ -0,0 +1,59 @@ +package main + +import ( + "html/template" + "strings" +) + +var funmap = template.FuncMap{ + "toCredits": tplToCredits, + "htmlify": tplHtmlify, + "toGlossary": tplToGlossary, +} + +func tplToCredits(str string) template.HTML { + // Make first line an heading + idx := strings.IndexRune(str, '\n') + if idx > 0 { + str = "

" + str[:idx] + "

" + str[idx+1:] + } + // Wrap other lines in

tags + str = strings.ReplaceAll(str, "\n", "

") + "

" + return template.HTML(str) +} + +func tplHtmlify(str string) template.HTML { + // Replace newlines with
+ str = strings.ReplaceAll(str, "\n", "
") + return template.HTML(str) +} + +type glossaryEntry struct { + Keyword string + Definition string +} + +func tplToGlossary(str string) (glob []glossaryEntry) { + lines := strings.Split(str, "\n") + for _, line := range lines { + // Skip empty lines + line = strings.TrimSpace(line) + if len(line) < 1 { + continue + } + + // Find delimiter + delim := strings.IndexRune(line, ':') + if delim < 0 { + // No delim? Add to last entry + glob[len(glob)-1].Definition += line + continue + } + + glob = append(glob, glossaryEntry{ + Keyword: line[:delim], + Definition: strings.TrimSpace(line[delim+1:]), + }) + } + return +} diff --git a/template.html b/template.html index 22e7f99..e7070c2 100644 --- a/template.html +++ b/template.html @@ -15,7 +15,16 @@ {{ range .Sections }}

{{ .ID }}. {{ .Title }}

{{ if .Extra }} + {{ if (eq .Title "Glossary")}} +
+ {{ range (toGlossary .Text) }} +
{{ .Keyword }}
+
{{ .Definition }}
+ {{ end }} +
+ {{ else }} {{ .Text | htmlify }} + {{ end }} {{ else }}