-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpress.go
75 lines (65 loc) · 1.52 KB
/
press.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
// press is a utility for applying simple HTML templates to content
package main
import (
"flag"
"golang.org/x/net/html"
"html/template"
"log"
"os"
"strings"
)
var tf string
var cf string
func init() {
flag.StringVar(&tf, "t", "", "path to template file")
flag.StringVar(&cf, "c", "", "path to content file")
}
func main() {
flag.Parse()
if tf == "" || cf == "" {
log.Fatal("Template or content file not provided")
}
type pageData struct {
Title string
Content template.HTML
}
content, err := os.ReadFile(cf)
if err != nil {
log.Fatal(err)
}
// Because the user is providing this content, we assume it is safe
htmlContent := template.HTML(string(content))
pageTitle := getFirstElemValue(string(content), "h1")
t, err := template.ParseFiles(tf)
if err != nil {
log.Fatal(err)
}
data := pageData{pageTitle, htmlContent}
err = t.Execute(os.Stdout, data)
if err != nil {
log.Fatal(err)
}
}
// getFirstElemValue reads the HTML content provided and retrieves
// the value in the first tag matching the given name
func getFirstElemValue(content string, name string) string {
var val string
reader := strings.NewReader(content)
tokenizer := html.NewTokenizer(reader)
for {
token := tokenizer.Next()
switch token {
case html.ErrorToken:
// we've reached the end
return val
case html.StartTagToken, html.SelfClosingTagToken:
tagName, _ := tokenizer.TagName()
if string(tagName) == name {
token = tokenizer.Next()
val = tokenizer.Token().String()
break
}
}
}
return val
}