-
Notifications
You must be signed in to change notification settings - Fork 0
/
indent.go
81 lines (72 loc) · 1.63 KB
/
indent.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
package text
import (
"bytes"
"io"
)
// Indentiation options
type IndentOptions uint32
const (
IndentOptionNone = 0
IndentOptionIndentFirstLine = 1 << 0
)
// Indent a string by prefixing each line with the provided string
func Indent(s, p string) string {
return IndentWithOptions(s, p, IndentOptionIndentFirstLine)
}
// Indent a string by prefixing each line with the provided string
func IndentWithOptions(s, p string, opt IndentOptions) string {
b := &bytes.Buffer{}
_, err := indent(s, p, opt, b)
if err != nil {
panic(err)
}
return string(b.Bytes())
}
// Indent and write
type indentWriter struct {
prefix string
opt IndentOptions
dst io.Writer
first bool
}
// Create an indent writer
func NewIndentWriter(p string, opt IndentOptions, w io.Writer) io.Writer {
return &indentWriter{p, opt, w, true}
}
// Write
func (w *indentWriter) Write(s []byte) (int, error) {
opt := w.opt
if w.first {
opt |= IndentOptionIndentFirstLine
} else {
opt = opt &^ IndentOptionIndentFirstLine
}
w.first = false
return indent(string(s), w.prefix, opt, w.dst)
}
// Indent a string by prefixing each line with the provided string
func indent(s, p string, opt IndentOptions, dst io.Writer) (int, error) {
var n int
if (opt & IndentOptionIndentFirstLine) == IndentOptionIndentFirstLine {
x, err := io.WriteString(dst, p)
if err != nil {
return n, err
}
n += x
}
for i := 0; i < len(s); i++ {
x, err := io.WriteString(dst, string(s[i]))
if err != nil {
return n, err
}
n += x
if s[i] == '\n' {
x, err = io.WriteString(dst, p)
if err != nil {
return n, err
}
n += x
}
}
return n, nil
}