-
Notifications
You must be signed in to change notification settings - Fork 1
/
htmlcolor.go
98 lines (74 loc) · 2.18 KB
/
htmlcolor.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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
package htmlcolor
import (
"bytes"
"fmt"
"io"
"github.com/fatih/color"
"golang.org/x/net/html"
)
type SprintfFuncer interface {
SprintfFunc() func(format string, a ...interface{}) string
}
type Formatter struct {
TagColor SprintfFuncer
BracketColor SprintfFuncer
CommentColor SprintfFuncer
AttrKeyColor SprintfFuncer
AttrValColor SprintfFuncer
}
func NewFormatter() *Formatter {
return &Formatter{
TagColor: color.New(color.FgMagenta),
BracketColor: color.New(color.FgCyan),
CommentColor: color.New(color.FgBlue),
AttrKeyColor: color.New(color.FgGreen),
AttrValColor: color.New(color.FgRed),
}
}
func (f *Formatter) TagFprint(dst io.Writer, token html.Token) {
sprintfAttrkey := f.AttrKeyColor.SprintfFunc()
sprintfAttrval := f.AttrValColor.SprintfFunc()
for _, attr := range token.Attr {
fmt.Fprint(dst, " ", sprintfAttrkey(attr.Key+"="))
fmt.Fprint(dst, sprintfAttrval("\""+attr.Val+"\""))
}
}
func (f *Formatter) Format(dst io.Writer, src []byte) error {
sprintfTag := f.TagColor.SprintfFunc()
sprintfBracket := f.BracketColor.SprintfFunc()
sprintfComment := f.CommentColor.SprintfFunc()
BracketOpen := "<"
BracketClose := ">"
srcReader := bytes.NewReader(src)
tokenizer := html.NewTokenizer(srcReader)
for {
tokentype := tokenizer.Next()
if tokentype == html.ErrorToken {
return tokenizer.Err()
}
token := tokenizer.Token()
switch tokentype {
case html.CommentToken:
fmt.Fprint(dst, sprintfComment(token.String()))
case html.DoctypeToken:
fmt.Fprint(dst, sprintfComment(token.String()))
case html.StartTagToken:
fmt.Fprint(dst, sprintfBracket(BracketOpen))
fmt.Fprint(dst, sprintfTag(token.Data))
f.TagFprint(dst, token)
fmt.Fprint(dst, sprintfBracket(BracketClose))
case html.EndTagToken:
fmt.Fprint(dst, sprintfBracket(BracketOpen+"/"))
fmt.Fprint(dst, sprintfTag(token.Data))
fmt.Fprint(dst, sprintfBracket(BracketClose))
case html.SelfClosingTagToken:
fmt.Fprint(dst, sprintfBracket(BracketOpen))
fmt.Fprint(dst, sprintfTag(token.Data))
f.TagFprint(dst, token)
fmt.Fprint(dst, sprintfBracket(" /"+BracketClose))
case html.TextToken:
fmt.Fprint(dst, token.Data)
}
}
return nil
}