forked from bytesparadise/libasciidoc
/
literal_blocks.go
72 lines (67 loc) · 2.12 KB
/
literal_blocks.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
package html5
import (
"bytes"
"html"
"math"
"strings"
texttemplate "text/template"
"github.com/bytesparadise/libasciidoc/pkg/renderer"
"github.com/bytesparadise/libasciidoc/pkg/types"
"github.com/pkg/errors"
log "github.com/sirupsen/logrus"
)
var literalBlockTmpl texttemplate.Template
// initializes the templates
func init() {
literalBlockTmpl = newTextTemplate("literal block", `{{ $ctx := .Context }}{{ with .Data }}<div {{ if .ID }}id="{{ .ID }}" {{ end }}class="literalblock">
{{ if .Title }}<div class="title">{{ escape .Title }}</div>
{{ end }}<div class="content">
<pre>{{ $lines := .Lines }}{{ range $index, $line := $lines}}{{ $line }}{{ includeNewline $ctx $index $lines }}{{ end }}</pre>
</div>
</div>{{ end }}`, texttemplate.FuncMap{
"includeNewline": includeNewline,
"escape": html.EscapeString,
})
}
func renderLiteralBlock(ctx *renderer.Context, b types.LiteralBlock) ([]byte, error) {
log.Debugf("rendering delimited block with content: %s", b.Lines)
var lines []string
if b.Attributes.GetAsString(types.AttrLiteralBlockType) == types.LiteralBlockWithSpacesOnFirstLine {
// remove as many spaces as needed on each line
lines = make([]string, len(b.Lines))
spaceCount := float64(0)
// first pass to detemine the minimum number of spaces to remove
for i, line := range b.Lines {
l := strings.TrimLeft(line, " ")
if i == 0 {
spaceCount = float64(len(line) - len(l))
} else {
spaceCount = math.Min(spaceCount, float64(len(line)-len(l)))
}
}
// then remove the same number of spaces on each line
spaces := strings.Repeat(" ", int(spaceCount))
for i, line := range b.Lines {
lines[i] = strings.TrimPrefix(line, spaces)
}
} else {
// just use the lines as-is
lines = b.Lines
}
result := bytes.NewBuffer(nil)
err := literalBlockTmpl.Execute(result, ContextualPipeline{
Context: ctx,
Data: struct {
ID string
Title string
Lines []string
}{
ID: generateID(ctx, b.Attributes),
Title: getTitle(b.Attributes),
Lines: lines,
}})
if err != nil {
return nil, errors.Wrapf(err, "unable to render delimited block")
}
return result.Bytes(), nil
}