-
Notifications
You must be signed in to change notification settings - Fork 3
/
content.go
186 lines (170 loc) · 4.1 KB
/
content.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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
package html
import (
"fmt"
"html"
"strings"
"github.com/thecsw/darkness/internals"
)
var (
// contentFunctions is a map of functions that process content
contentFunctions = []func(*internals.Content) string{
headings,
paragraph,
list,
listNumbered,
link,
sourceCode,
rawHTML,
horizontalLine,
attentionBlock,
table,
details,
}
)
// headings gives us a heading html representation
func headings(content *internals.Content) string {
start := ``
if !content.HeadingChild && !content.HeadingFirst {
start = `</div>` + "\n" + `</div>`
}
if content.HeadingChild && !content.HeadingFirst {
start = `</div>`
}
toReturn := fmt.Sprintf(start+`
<div class="sect%d">
<h%d id="%s">%s</h%d>
<div class="sectionbody">`,
content.HeadingLevel-1, // CSS class
content.HeadingLevel, // HTML open tag
extractID(content.Heading), // ID
processText(content.Heading), // Actual title
content.HeadingLevel, // HTML close tag
)
if content.HeadingLast {
toReturn += "\n" + `</div>`
}
return toReturn
}
// paragraph gives us a paragraph html representation
func paragraph(content *internals.Content) string {
return fmt.Sprintf(
`
<div class="paragraph%s">
<p>
%s
</p>
</div>`,
// div class
func() string {
if content.IsQuote() {
return " quote"
}
if content.IsCentered() {
return " center"
}
if content.IsDropCap() {
return " dropcap"
}
return ""
}(),
processText(content.Paragraph),
)
}
// list gives us a list html representation
func list(content *internals.Content) string {
elements := make([]string, len(content.List))
for i, item := range content.List {
elements[i] = fmt.Sprintf(`
<li>
<p>
%s
</p>
</li>`, processText(item))
}
return fmt.Sprintf(`
<div class="ulist">
<ul>
%s
</ul>
</div>
`, strings.Join(elements, "\n"))
}
// listNumbered gives us a numbered list html representation
func listNumbered(content *internals.Content) string {
// TODO
return ""
}
var sourceCodeLang = map[string]string{
"": "plaintext",
"sh": "bash",
}
func mapSourceCodeLang(s string) string {
if v, ok := sourceCodeLang[s]; ok {
return v
}
return s
}
// sourceCode gives us a source code html representation
func sourceCode(content *internals.Content) string {
lang := mapSourceCodeLang(content.SourceCodeLang)
return fmt.Sprintf(`
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-%s" data-lang="%s">%s</code></pre>
</div>
</div>
`, lang, lang, func() string {
// Remove the nested parser blockers
s := strings.ReplaceAll(content.SourceCode, ",#", "#")
// Escape the whatever HTML that is found in source code
s = html.EscapeString(s)
return s
}())
}
// rawHTML gives us a raw html representation
func rawHTML(content *internals.Content) string {
return content.RawHTML
}
// horizontalLine gives us a horizontal line html representation
func horizontalLine(content *internals.Content) string {
return `<hr>`
}
// attentionBlock gives us a attention block html representation
func attentionBlock(content *internals.Content) string {
return fmt.Sprintf(`
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<div class="title">%s</div>
</td>
<td class="content">
%s
</td>
</tr>
</table>
</div>`, content.AttentionTitle, processText(content.AttentionText))
}
// table gives an HTML formatted table
func table(content *internals.Content) string {
rows := make([]string, len(content.Table))
for i := range content.Table {
for j, v := range content.Table[i] {
topTag := "td"
if i == 0 && content.TableHeaders {
topTag = "th"
}
content.Table[i][j] = fmt.Sprintf("<%s>%s</%s>", topTag, processText(v), topTag)
}
rows[i] = fmt.Sprintf("<tr>\n%s</tr>", strings.Join(content.Table[i], "\n"))
}
tableHTML := fmt.Sprintf("<table>%s</table>", strings.Join(rows, "\n"))
return fmt.Sprintf(TableTemplate, content.Caption, tableHTML)
}
// table gives an HTML formatted table
func details(content *internals.Content) string {
if internals.HasFlag(&content.Options, internals.InDetailsFlag) {
return fmt.Sprintf("<details>\n<summary>%s</summary>\n<hr>", content.Summary)
}
return "</details>"
}