-
Notifications
You must be signed in to change notification settings - Fork 1
/
html.go
60 lines (54 loc) · 1.42 KB
/
html.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
package midterm
import "bytes"
// HTML renders v as an HTML fragment. One idea for how to use this is to debug
// the current state of the screen reader.
func (v *Terminal) HTML() string {
v.mut.Lock()
defer v.mut.Unlock()
var buf bytes.Buffer
buf.WriteString(`<pre style="color:white;background-color:black;">`)
// Iterate each row. When the css changes, close the previous span, and open
// a new one. No need to close a span when the css is empty, we won't have
// opened one in the past.
var lastFormat Format
for y, row := range v.Content {
for x, r := range row {
f := v.Format[y][x]
if f != lastFormat {
if lastFormat != (Format{}) {
buf.WriteString("</span>")
}
if f != (Format{}) {
buf.WriteString(`<span style="` + f.css() + `">`)
}
lastFormat = f
}
if s := maybeEscapeRune(r); s != "" {
buf.WriteString(s)
} else {
buf.WriteRune(r)
}
}
buf.WriteRune('\n')
}
buf.WriteString("</pre>")
return buf.String()
}
// maybeEscapeRune potentially escapes a rune for display in an html document.
// It only escapes the things that html.EscapeString does, but it works without allocating
// a string to hold r. Returns an empty string if there is no need to escape.
func maybeEscapeRune(r rune) string {
switch r {
case '&':
return "&"
case '\'':
return "'"
case '<':
return "<"
case '>':
return ">"
case '"':
return """
}
return ""
}