-
Notifications
You must be signed in to change notification settings - Fork 5
/
tag.go
123 lines (110 loc) · 2.6 KB
/
tag.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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/*
* @Author : Klarkxy
* @Date : 2020-02-07 13:30:31
* @LastEditors : Klarkxy
* @LastEditTime : 2020-02-18 17:28:50
* @FilePath : \gohtml\tag.go
*/
package gohtml
import (
"bytes"
"fmt"
"strings"
)
// Tag: <{name} {attr}}>{tags}</{name}>
type GoTag struct {
name string // tag名
attr map[string]string // 属性列表
singleAttr []string // 无值属性
tags []fmt.Stringer // 所有支持String()输出的都可以作为tag
self bool // 自闭合
Tab int // 层数,用来缩进
}
func (cur *GoTag) String() string {
b := new(bytes.Buffer)
if cur.name != "" {
b.WriteByte('<')
b.WriteString(cur.name)
for k, v := range cur.attr {
b.WriteByte(' ')
b.WriteString(k)
b.WriteString("=\"")
b.WriteString(v)
b.WriteString("\"")
}
for _, k := range cur.singleAttr {
b.WriteByte(' ')
b.WriteString(k)
}
b.WriteByte('>')
}
if !cur.self {
if len(cur.tags) > 0 {
// 内含多个Tag,换行
b.WriteByte('\n')
}
// 非自闭合,输出里面的内容和尾巴
for _, v := range cur.tags {
str := v.String()
if str != "" {
// 非空,缩进
b.WriteString(strings.Repeat(" ", cur.Tab+1))
}
b.WriteString(str)
if str != "" && len(cur.tags) > 0 {
// 内含多个Tag,换行
b.WriteByte('\n')
}
}
if cur.name != "" {
b.WriteString(strings.Repeat(" ", cur.Tab))
b.WriteString("</")
b.WriteString(cur.name)
b.WriteByte('>')
}
}
return b.String()
}
// 在当前Tag中插入若干个Tag/Text,返回当前Tag
func (cur *GoTag) Append(tags ...fmt.Stringer) *GoTag {
for _, v := range tags {
cur.tags = append(cur.tags, v)
}
return cur
}
// 在当前Tag下新建一个Tag,返回新建出来的Tag
func (cur *GoTag) Tag(name string) *GoTag {
newtag := Tag(name)
if name != "" {
newtag.Tab = cur.Tab + 1
} else {
newtag.Tab = cur.Tab
}
cur.Append(newtag)
return newtag
}
// 设置当前Tag为self-Closing,返回当前Tag
func (cur *GoTag) Self() *GoTag {
cur.self = true
return cur
}
// 在当前Tag中插入一条string,返回当前Tag
func (cur *GoTag) Text(str string) *GoTag {
buf := bytes.NewBufferString(str)
cur.Append(buf)
return cur
}
// 设置属性,返回当前Tag
func (cur *GoTag) Attr(attrs ...string) *GoTag {
for i := 0; i+1 < len(attrs); i += 2 {
cur.attr[attrs[i]] = attrs[i+1]
}
return cur
}
// 设置单项属性,返回当前Tag
func (cur *GoTag) SingleAttr(attrs ...string) *GoTag {
for i := 0; i+1 < len(attrs); i++ {
cur.singleAttr = append(cur.singleAttr, attrs[i])
}
return cur
}