...
1 package text
2
3 import (
4 "bytes"
5 "github.com/yuin/goldmark/util"
6 )
7
8 var space = []byte(" ")
9
10
11 type Segment struct {
12
13 Start int
14
15
16
17 Stop int
18
19
20 Padding int
21 }
22
23
24 func NewSegment(start, stop int) Segment {
25 return Segment{
26 Start: start,
27 Stop: stop,
28 Padding: 0,
29 }
30 }
31
32
33 func NewSegmentPadding(start, stop, n int) Segment {
34 return Segment{
35 Start: start,
36 Stop: stop,
37 Padding: n,
38 }
39 }
40
41
42 func (t *Segment) Value(buffer []byte) []byte {
43 if t.Padding == 0 {
44 return buffer[t.Start:t.Stop]
45 }
46 result := make([]byte, 0, t.Padding+t.Stop-t.Start+1)
47 result = append(result, bytes.Repeat(space, t.Padding)...)
48 return append(result, buffer[t.Start:t.Stop]...)
49 }
50
51
52 func (t *Segment) Len() int {
53 return t.Stop - t.Start + t.Padding
54 }
55
56
57 func (t *Segment) Between(other Segment) Segment {
58 if t.Stop != other.Stop {
59 panic("invalid state")
60 }
61 return NewSegmentPadding(
62 t.Start,
63 other.Start,
64 t.Padding-other.Padding,
65 )
66 }
67
68
69 func (t *Segment) IsEmpty() bool {
70 return t.Start >= t.Stop && t.Padding == 0
71 }
72
73
74
75 func (t *Segment) TrimRightSpace(buffer []byte) Segment {
76 v := buffer[t.Start:t.Stop]
77 l := util.TrimRightSpaceLength(v)
78 if l == len(v) {
79 return NewSegment(t.Start, t.Start)
80 }
81 return NewSegmentPadding(t.Start, t.Stop-l, t.Padding)
82 }
83
84
85
86 func (t *Segment) TrimLeftSpace(buffer []byte) Segment {
87 v := buffer[t.Start:t.Stop]
88 l := util.TrimLeftSpaceLength(v)
89 return NewSegment(t.Start+l, t.Stop)
90 }
91
92
93
94 func (t *Segment) TrimLeftSpaceWidth(width int, buffer []byte) Segment {
95 padding := t.Padding
96 for ; width > 0; width-- {
97 if padding == 0 {
98 break
99 }
100 padding--
101 }
102 if width == 0 {
103 return NewSegmentPadding(t.Start, t.Stop, padding)
104 }
105 text := buffer[t.Start:t.Stop]
106 start := t.Start
107 for _, c := range text {
108 if start >= t.Stop-1 || width <= 0 {
109 break
110 }
111 if c == ' ' {
112 width--
113 } else if c == '\t' {
114 width -= 4
115 } else {
116 break
117 }
118 start++
119 }
120 if width < 0 {
121 padding = width * -1
122 }
123 return NewSegmentPadding(start, t.Stop, padding)
124 }
125
126
127 func (t *Segment) WithStart(v int) Segment {
128 return NewSegmentPadding(v, t.Stop, t.Padding)
129 }
130
131
132 func (t *Segment) WithStop(v int) Segment {
133 return NewSegmentPadding(t.Start, v, t.Padding)
134 }
135
136
137 func (t *Segment) ConcatPadding(v []byte) []byte {
138 if t.Padding > 0 {
139 return append(v, bytes.Repeat(space, t.Padding)...)
140 }
141 return v
142 }
143
144
145 type Segments struct {
146 values []Segment
147 }
148
149
150 func NewSegments() *Segments {
151 return &Segments{
152 values: nil,
153 }
154 }
155
156
157 func (s *Segments) Append(t Segment) {
158 if s.values == nil {
159 s.values = make([]Segment, 0, 20)
160 }
161 s.values = append(s.values, t)
162 }
163
164
165 func (s *Segments) AppendAll(t []Segment) {
166 if s.values == nil {
167 s.values = make([]Segment, 0, 20)
168 }
169 s.values = append(s.values, t...)
170 }
171
172
173 func (s *Segments) Len() int {
174 if s.values == nil {
175 return 0
176 }
177 return len(s.values)
178 }
179
180
181 func (s *Segments) At(i int) Segment {
182 return s.values[i]
183 }
184
185
186 func (s *Segments) Set(i int, v Segment) {
187 s.values[i] = v
188 }
189
190
191 func (s *Segments) SetSliced(lo, hi int) {
192 s.values = s.values[lo:hi]
193 }
194
195
196 func (s *Segments) Sliced(lo, hi int) []Segment {
197 return s.values[lo:hi]
198 }
199
200
201 func (s *Segments) Clear() {
202 s.values = nil
203 }
204
205
206 func (s *Segments) Unshift(v Segment) {
207 s.values = append(s.values[0:1], s.values[0:]...)
208 s.values[0] = v
209 }
210
View as plain text