Basic version that works
This commit is contained in:
parent
cab8022414
commit
514522950a
4 changed files with 160 additions and 20 deletions
107
main.go
107
main.go
|
@ -17,13 +17,30 @@ const (
|
||||||
|
|
||||||
// TemplateData is the data that is filled and passed to the HTML template
|
// TemplateData is the data that is filled and passed to the HTML template
|
||||||
type TemplateData struct {
|
type TemplateData struct {
|
||||||
Title string
|
Title string
|
||||||
CSSFile string
|
Credits string
|
||||||
Credits string
|
Sections []*TemplateSection
|
||||||
|
}
|
||||||
|
|
||||||
|
// TemplateSection is a section of the rules
|
||||||
|
type TemplateSection struct {
|
||||||
|
ID string
|
||||||
|
Title string
|
||||||
|
Extra bool
|
||||||
|
Rules []TemplateRule
|
||||||
|
Text string
|
||||||
|
}
|
||||||
|
|
||||||
|
// TemplateRule is a single rule
|
||||||
|
type TemplateRule struct {
|
||||||
|
ID string
|
||||||
|
Text string
|
||||||
|
Depth int
|
||||||
}
|
}
|
||||||
|
|
||||||
var funmap = template.FuncMap{
|
var funmap = template.FuncMap{
|
||||||
"htmlify": tplHtmlify,
|
"toCredits": tplToCredits,
|
||||||
|
"htmlify": tplHtmlify,
|
||||||
}
|
}
|
||||||
|
|
||||||
// HTMLrocCredits is the credit string to append to the other credits
|
// HTMLrocCredits is the credit string to append to the other credits
|
||||||
|
@ -33,15 +50,12 @@ func main() {
|
||||||
txtfile := flag.String("in", "rules.txt", "Path to rules.txt file")
|
txtfile := flag.String("in", "rules.txt", "Path to rules.txt file")
|
||||||
tplfile := flag.String("template", "template.html", "Path to template file")
|
tplfile := flag.String("template", "template.html", "Path to template file")
|
||||||
outname := flag.String("out", "out.html", "Output file")
|
outname := flag.String("out", "out.html", "Output file")
|
||||||
style := flag.String("css", "style.css", "Name of the CSS stylesheet")
|
|
||||||
|
|
||||||
// Read template file
|
// Read template file
|
||||||
tpl, err := template.New(*tplfile).Funcs(funmap).ParseFiles(*tplfile)
|
tpl, err := template.New(*tplfile).Funcs(funmap).ParseFiles(*tplfile)
|
||||||
checkErr(err, "Could not load template file \"%s\"", *tplfile)
|
checkErr(err, "Could not load template file \"%s\"", *tplfile)
|
||||||
|
|
||||||
tpldata := TemplateData{
|
tpldata := TemplateData{}
|
||||||
CSSFile: *style,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read rules file
|
// Read rules file
|
||||||
filebytes, err := ioutil.ReadFile(*txtfile)
|
filebytes, err := ioutil.ReadFile(*txtfile)
|
||||||
|
@ -74,12 +88,73 @@ func main() {
|
||||||
|
|
||||||
// Every rule is a line (pretty handy!)
|
// Every rule is a line (pretty handy!)
|
||||||
lines := strings.Split(filestr, "\n")
|
lines := strings.Split(filestr, "\n")
|
||||||
|
var currentSection *TemplateSection
|
||||||
for _, line := range lines {
|
for _, line := range lines {
|
||||||
|
// Trim line (used for several purposes)
|
||||||
|
trimmed := strings.TrimSpace(line)
|
||||||
|
|
||||||
// Skip empty lines
|
// Skip empty lines
|
||||||
line = strings.TrimSpace(line)
|
if len(trimmed) < 1 {
|
||||||
if len(line) < 1 {
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// All rules begin with "(ID)"
|
||||||
|
isRule := trimmed[0] == '('
|
||||||
|
|
||||||
|
// All sections begin with "N. "
|
||||||
|
// for sake of not making this check extra complicated we're going to
|
||||||
|
// assume it has to be within the first 5 characters
|
||||||
|
isSection := strings.Index(trimmed[:5], ". ") > 0
|
||||||
|
|
||||||
|
// Calculate depth based on number of whitespace (/2)
|
||||||
|
depth := len(line) - len(trimmed)
|
||||||
|
|
||||||
|
switch {
|
||||||
|
// It's a section
|
||||||
|
case isSection:
|
||||||
|
parts := strings.SplitN(trimmed, ". ", 2)
|
||||||
|
if len(parts) < 2 {
|
||||||
|
// ???
|
||||||
|
fmt.Fprintf(os.Stderr, "Found unexpected line: \"%s\"\n", trimmed)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// Create new section
|
||||||
|
currentSection = &TemplateSection{
|
||||||
|
ID: parts[0],
|
||||||
|
Title: parts[1],
|
||||||
|
Rules: []TemplateRule{},
|
||||||
|
Extra: false,
|
||||||
|
}
|
||||||
|
tpldata.Sections = append(tpldata.Sections, currentSection)
|
||||||
|
|
||||||
|
// It's a new rule
|
||||||
|
case isRule:
|
||||||
|
|
||||||
|
// ID is between ()s
|
||||||
|
endID := strings.IndexRune(trimmed, ')')
|
||||||
|
if endID < 0 {
|
||||||
|
// ???
|
||||||
|
fmt.Fprintf(os.Stderr, "Found unexpected or malformed line: \"%s\"\n", trimmed)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
currentSection.Rules = append(currentSection.Rules, TemplateRule{
|
||||||
|
ID: trimmed[1:endID],
|
||||||
|
Text: strings.TrimSpace(trimmed[endID+1:]),
|
||||||
|
Depth: depth,
|
||||||
|
})
|
||||||
|
|
||||||
|
// It's something else
|
||||||
|
default:
|
||||||
|
// If there is at least a rule, assume it's a continuation of the last rule
|
||||||
|
if len(currentSection.Rules) > 0 {
|
||||||
|
currentSection.Rules[len(currentSection.Rules)-1].Text += "\n" + line
|
||||||
|
} else {
|
||||||
|
// No rules? Might be an extra
|
||||||
|
currentSection.Extra = true
|
||||||
|
currentSection.Text += line + "\n"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create output file
|
// Create output file
|
||||||
|
@ -99,13 +174,19 @@ func checkErr(err error, fmtstr string, args ...interface{}) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func tplHtmlify(str string) template.HTML {
|
func tplToCredits(str string) template.HTML {
|
||||||
// Make first line an heading
|
// Make first line an heading
|
||||||
idx := strings.IndexRune(str, '\n')
|
idx := strings.IndexRune(str, '\n')
|
||||||
if idx > 0 {
|
if idx > 0 {
|
||||||
str = "<h1>" + str[:idx] + "</h1>" + str[idx:]
|
str = "<h1>" + str[:idx] + "</h1><p>" + str[idx+1:]
|
||||||
}
|
}
|
||||||
// Replace newlines with HTML line-break tag
|
// Wrap other lines in <p> tags
|
||||||
|
str = strings.ReplaceAll(str, "\n", "</p><p>") + "</p>"
|
||||||
|
return template.HTML(str)
|
||||||
|
}
|
||||||
|
|
||||||
|
func tplHtmlify(str string) template.HTML {
|
||||||
|
// Replace newlines with <br />
|
||||||
str = strings.ReplaceAll(str, "\n", "<br />")
|
str = strings.ReplaceAll(str, "\n", "<br />")
|
||||||
return template.HTML(str)
|
return template.HTML(str)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
package main
|
|
46
style.css
46
style.css
|
@ -0,0 +1,46 @@
|
||||||
|
@import url('https://fonts.googleapis.com/css?family=Roboto:300,400&display=swap');
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: 'Roboto', sans-serif;
|
||||||
|
font-weight: 300;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 11pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
flex: 1;
|
||||||
|
max-width: 60em;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1,
|
||||||
|
h2 {
|
||||||
|
color: #4b5b69;
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin: 0;
|
||||||
|
padding: 2pt 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
padding-left: 10pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
li {
|
||||||
|
margin: 10pt 0;
|
||||||
|
list-style-type: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.depth-2 {
|
||||||
|
padding-left: 20pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
.depth-4 {
|
||||||
|
padding-left: 40pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
.depth-6 {
|
||||||
|
padding-left: 60pt;
|
||||||
|
}
|
|
@ -3,15 +3,29 @@
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<title>{{ .Title }}</title>
|
<title>{{ .Title }}</title>
|
||||||
{{ if .CSSFile }}
|
<link rel="stylesheet" href="style.css">
|
||||||
<link href="{{ .CSSFile }}" rel="stylesheet" />
|
|
||||||
{{ end }}
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<header class="credits">
|
<main>
|
||||||
{{ .Credits | htmlify }}
|
<header class="credits">
|
||||||
</header>
|
{{ .Credits | toCredits }}
|
||||||
|
</header>
|
||||||
|
<section class="rules">
|
||||||
|
{{ range .Sections }}
|
||||||
|
<h2 id="{{ .ID }}">{{ .ID }}. {{ .Title }}</h2>
|
||||||
|
{{ if .Extra }}
|
||||||
|
{{ .Text | htmlify }}
|
||||||
|
{{ else }}
|
||||||
|
<ul>
|
||||||
|
{{ range .Rules }}
|
||||||
|
<li id="{{ .ID }}" class="depth-{{ .Depth }}">({{ .ID }}) {{ .Text | htmlify }}</li>
|
||||||
|
{{ end }}
|
||||||
|
</ul>
|
||||||
|
{{ end }}
|
||||||
|
{{ end }}
|
||||||
|
</section>
|
||||||
|
</main>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
Loading…
Reference in a new issue