...
1 package table
2
3 import (
4 "fmt"
5 "html"
6 "strings"
7 )
8
9 const (
10
11
12 DefaultHTMLCSSClass = "go-pretty-table"
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 func (t *Table) RenderHTML() string {
60 t.initForRender()
61
62 var out strings.Builder
63 if t.numColumns > 0 {
64 out.WriteString("<table class=\"")
65 if t.htmlCSSClass != "" {
66 out.WriteString(t.htmlCSSClass)
67 } else {
68 out.WriteString(t.style.HTML.CSSClass)
69 }
70 out.WriteString("\">\n")
71 t.htmlRenderTitle(&out)
72 t.htmlRenderRowsHeader(&out)
73 t.htmlRenderRows(&out, t.rows, renderHint{})
74 t.htmlRenderRowsFooter(&out)
75 t.htmlRenderCaption(&out)
76 out.WriteString("</table>")
77 }
78 return t.render(&out)
79 }
80
81 func (t *Table) htmlGetColStrAndTag(row rowStr, colIdx int, hint renderHint) (string, string) {
82
83 var colStr string
84 if colIdx < len(row) {
85 colStr = row[colIdx]
86 }
87
88
89 colTagName := "td"
90 if hint.isHeaderRow {
91 colTagName = "th"
92 }
93
94 return colStr, colTagName
95 }
96
97 func (t *Table) htmlRenderCaption(out *strings.Builder) {
98 if t.caption != "" {
99 out.WriteString(" <caption class=\"caption\" style=\"caption-side: bottom;\">")
100 out.WriteString(t.caption)
101 out.WriteString("</caption>\n")
102 }
103 }
104
105 func (t *Table) htmlRenderColumn(out *strings.Builder, colStr string) {
106 if t.style.HTML.EscapeText {
107 colStr = html.EscapeString(colStr)
108 }
109 if t.style.HTML.Newline != "\n" {
110 colStr = strings.Replace(colStr, "\n", t.style.HTML.Newline, -1)
111 }
112 out.WriteString(colStr)
113 }
114
115 func (t *Table) htmlRenderColumnAttributes(out *strings.Builder, row rowStr, colIdx int, hint renderHint) {
116
117 align := t.getAlign(colIdx, hint).HTMLProperty()
118 vAlign := t.getVAlign(colIdx, hint).HTMLProperty()
119
120 class := t.getColumnColors(colIdx, hint).HTMLProperty()
121
122 if align != "" {
123 out.WriteRune(' ')
124 out.WriteString(align)
125 }
126 if class != "" {
127 out.WriteRune(' ')
128 out.WriteString(class)
129 }
130 if vAlign != "" {
131 out.WriteRune(' ')
132 out.WriteString(vAlign)
133 }
134 }
135
136 func (t *Table) htmlRenderColumnAutoIndex(out *strings.Builder, hint renderHint) {
137 if hint.isHeaderRow {
138 out.WriteString(" <th>")
139 out.WriteString(t.style.HTML.EmptyColumn)
140 out.WriteString("</th>\n")
141 } else if hint.isFooterRow {
142 out.WriteString(" <td>")
143 out.WriteString(t.style.HTML.EmptyColumn)
144 out.WriteString("</td>\n")
145 } else {
146 out.WriteString(" <td align=\"right\">")
147 out.WriteString(fmt.Sprint(hint.rowNumber))
148 out.WriteString("</td>\n")
149 }
150 }
151
152 func (t *Table) htmlRenderRow(out *strings.Builder, row rowStr, hint renderHint) {
153 out.WriteString(" <tr>\n")
154 for colIdx := 0; colIdx < t.numColumns; colIdx++ {
155
156 if colIdx == 0 && t.autoIndex {
157 t.htmlRenderColumnAutoIndex(out, hint)
158 }
159
160 colStr, colTagName := t.htmlGetColStrAndTag(row, colIdx, hint)
161
162 out.WriteString(" <")
163 out.WriteString(colTagName)
164 t.htmlRenderColumnAttributes(out, row, colIdx, hint)
165 out.WriteString(">")
166 if len(colStr) == 0 {
167 out.WriteString(t.style.HTML.EmptyColumn)
168 } else {
169 t.htmlRenderColumn(out, colStr)
170 }
171 out.WriteString("</")
172 out.WriteString(colTagName)
173 out.WriteString(">\n")
174 }
175 out.WriteString(" </tr>\n")
176 }
177
178 func (t *Table) htmlRenderRows(out *strings.Builder, rows []rowStr, hint renderHint) {
179 if len(rows) > 0 {
180
181 rowsTag := "tbody"
182 if hint.isHeaderRow {
183 rowsTag = "thead"
184 } else if hint.isFooterRow {
185 rowsTag = "tfoot"
186 }
187
188 var renderedTagOpen, shouldRenderTagClose bool
189 for idx, row := range rows {
190 hint.rowNumber = idx + 1
191 if len(row) > 0 {
192 if !renderedTagOpen {
193 out.WriteString(" <")
194 out.WriteString(rowsTag)
195 out.WriteString(">\n")
196 renderedTagOpen = true
197 }
198 t.htmlRenderRow(out, row, hint)
199 shouldRenderTagClose = true
200 }
201 }
202 if shouldRenderTagClose {
203 out.WriteString(" </")
204 out.WriteString(rowsTag)
205 out.WriteString(">\n")
206 }
207 }
208 }
209
210 func (t *Table) htmlRenderRowsFooter(out *strings.Builder) {
211 if len(t.rowsFooter) > 0 {
212 t.htmlRenderRows(out, t.rowsFooter, renderHint{isFooterRow: true})
213 }
214 }
215
216 func (t *Table) htmlRenderRowsHeader(out *strings.Builder) {
217 if len(t.rowsHeader) > 0 {
218 t.htmlRenderRows(out, t.rowsHeader, renderHint{isHeaderRow: true})
219 } else if t.autoIndex {
220 hint := renderHint{isAutoIndexRow: true, isHeaderRow: true}
221 t.htmlRenderRows(out, []rowStr{t.getAutoIndexColumnIDs()}, hint)
222 }
223 }
224
225 func (t *Table) htmlRenderTitle(out *strings.Builder) {
226 if t.title != "" {
227 align := t.style.Title.Align.HTMLProperty()
228 colors := t.style.Title.Colors.HTMLProperty()
229 title := t.style.Title.Format.Apply(t.title)
230
231 out.WriteString(" <caption class=\"title\"")
232 if align != "" {
233 out.WriteRune(' ')
234 out.WriteString(align)
235 }
236 if colors != "" {
237 out.WriteRune(' ')
238 out.WriteString(colors)
239 }
240 out.WriteRune('>')
241 out.WriteString(title)
242 out.WriteString("</caption>\n")
243 }
244 }
245
View as plain text