@@ -53,16 +53,22 @@ var booleanAttrs = map[string]struct{}{
53
53
attrs .Selected : {},
54
54
}
55
55
56
+ type RenderOptions struct {
57
+ // DisableHtmlPreamble disables the doctype preamble for the HTML tag if it exists in the rendering tree
58
+ DisableHtmlPreamble bool
59
+ }
60
+
56
61
type Node interface {
57
- RenderTo (builder * strings.Builder )
62
+ RenderTo (builder * strings.Builder , opts RenderOptions )
58
63
Render () string
64
+ RenderWithOptions (opts RenderOptions ) string
59
65
}
60
66
61
67
// NoneNode represents a node that renders nothing.
62
68
type NoneNode struct {}
63
69
64
70
// RenderTo for NoneNode does nothing.
65
- func (n NoneNode ) RenderTo (builder * strings.Builder ) {
71
+ func (n NoneNode ) RenderTo (builder * strings.Builder , opts RenderOptions ) {
66
72
// Intentionally left blank to render nothing
67
73
}
68
74
@@ -71,37 +77,54 @@ func (n NoneNode) Render() string {
71
77
return ""
72
78
}
73
79
80
+ // RenderWithOptions for NoneNode returns an empty string.
81
+ func (n NoneNode ) RenderWithOptions (opts RenderOptions ) string {
82
+ return ""
83
+ }
84
+
74
85
type TextNode string
75
86
76
- func (t TextNode ) RenderTo (builder * strings.Builder ) {
87
+ func (t TextNode ) RenderTo (builder * strings.Builder , opts RenderOptions ) {
77
88
builder .WriteString (string (t ))
78
89
}
79
90
80
91
func (t TextNode ) Render () string {
81
92
return string (t )
82
93
}
83
94
95
+ func (t TextNode ) RenderWithOptions (opts RenderOptions ) string {
96
+ return string (t )
97
+ }
98
+
84
99
type RawNode string
85
100
86
- func (r RawNode ) RenderTo (builder * strings.Builder ) {
101
+ func (r RawNode ) RenderTo (builder * strings.Builder , opts RenderOptions ) {
87
102
builder .WriteString (string (r ))
88
103
}
89
104
90
105
func (r RawNode ) Render () string {
91
106
return string (r )
92
107
}
93
108
109
+ func (t RawNode ) RenderWithOptions (opts RenderOptions ) string {
110
+ return string (t )
111
+ }
112
+
94
113
type CommentNode string
95
114
96
- func (c CommentNode ) RenderTo (builder * strings.Builder ) {
115
+ func (c CommentNode ) RenderTo (builder * strings.Builder , opts RenderOptions ) {
97
116
builder .WriteString ("<!-- " )
98
117
builder .WriteString (string (c ))
99
118
builder .WriteString (" -->" )
100
119
}
101
120
102
121
func (c CommentNode ) Render () string {
122
+ return c .RenderWithOptions (RenderOptions {})
123
+ }
124
+
125
+ func (c CommentNode ) RenderWithOptions (opts RenderOptions ) string {
103
126
var builder strings.Builder
104
- c .RenderTo (& builder )
127
+ c .RenderTo (& builder , opts )
105
128
return builder .String ()
106
129
}
107
130
@@ -111,11 +134,11 @@ type Element struct {
111
134
Children []Node
112
135
}
113
136
114
- func (e * Element ) RenderTo (builder * strings.Builder ) {
137
+ func (e * Element ) RenderTo (builder * strings.Builder , opts RenderOptions ) {
115
138
// The HTML tag needs a doctype preamble in order to ensure
116
139
// browsers don't render in legacy/quirks mode
117
140
// https://developer.mozilla.org/en-US/docs/Glossary/Doctype
118
- if e .Tag == "html" {
141
+ if ! opts . DisableHtmlPreamble && e .Tag == "html" {
119
142
builder .WriteString ("<!DOCTYPE html>" )
120
143
}
121
144
@@ -146,7 +169,7 @@ func (e *Element) RenderTo(builder *strings.Builder) {
146
169
147
170
// Build the content
148
171
for _ , child := range e .Children {
149
- child .RenderTo (builder )
172
+ child .RenderTo (builder , opts )
150
173
}
151
174
152
175
// Append closing tag
@@ -174,8 +197,12 @@ func (e *Element) renderAttrTo(attrName string, builder *strings.Builder) {
174
197
}
175
198
176
199
func (e * Element ) Render () string {
200
+ return e .RenderWithOptions (RenderOptions {})
201
+ }
202
+
203
+ func (e * Element ) RenderWithOptions (opts RenderOptions ) string {
177
204
var builder strings.Builder
178
- e .RenderTo (& builder )
205
+ e .RenderTo (& builder , opts )
179
206
return builder .String ()
180
207
}
181
208
0 commit comments