-
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
-
187
-
188
-
189
-
190
-
191
-
192
-
193
-
194
-
195
-
196
-
197
-
198
-
199
-
200
-
201
-
202
-
203
-
204
-
205
-
206
-
207
-
208
-
209
-
210
-
211
-
212
-
213
-
214
-
215
-
216
-
217
-
218
-
219
-
220
-
221
-
222
-
223
-
224
-
225
-
226
-
227
-
228
-
229
-
230
-
231
-
232
-
233
-
234
-
235
-
236
-
237
-
238
-
239
-
240
-
241
-
242
-
243
-
244
-
245
-
246
-
247
-
248
-
249
-
250
-
251
-
252
-
253
-
254
-
255
-
256
-
257
-
258
-
259
-
260
-
261
-
262
-
263
-
264
-
265
-
266
-
267
-
268
-
269
-
270
-
271
-
272
-
273
-
274
-
275
-
276
-
277
-
278
-
279
-
280
-
281
-
282
-
283
-
284
-
285
-
286
-
287
-
288
-
289
-
290
-
291
-
292
-
293
-
294
-
295
-
296
-
297
-
298
-
299
-
300
-
301
-
302
-
303
-
304
-
305
-
306
-
307
-
308
-
309
-
310
-
311
-
312
-
313
-
314
-
315
-
316
-
317
-
318
-
319
-
320
-
321
-
322
-
323
-
324
-
325
-
326
-
327
-
328
-
329
-
330
-
331
-
332
-
333
-
334
-
335
-
336
-
337
-
338
-
339
-
340
-
341
-
342
-
343
-
344
-
345
-
346
-
347
-
348
-
349
-
350
-
351
-
352
-
353
-
354
-
355
-
356
-
357
-
358
-
359
-
360
-
361
-
362
-
363
-
364
-
365
-
366
-
367
-
368
-
369
-
370
-
371
-
372
-
373
-
374
-
375
-
376
-
377
-
378
-
379
-
380
-
381
-
382
-
383
-
384
-
385
-
386
-
387
-
388
-
389
-
390
-
391
-
392
-
393
-
394
-
395
-
396
-
397
-
398
-
399
-
400
-
401
-
402
-
403
-
404
-
405
-
406
-
407
-
408
-
409
-
410
-
411
-
412
-
413
-
414
-
415
-
416
-
417
-
418
-
419
-
420
-
421
-
422
-
423
-
424
-
425
-
426
-
427
-
428
-
429
-
430
-
431
-
432
-
433
-
434
-
435
-
436
-
437
-
438
-
439
-
440
-
441
-
442
-
443
-
444
-
445
-
446
-
447
-
448
-
449
-
450
-
451
-
452
-
453
-
454
-
455
-
456
-
457
-
458
-
459
-
460
-
461
-
462
-
463
-
464
-
465
-
466
-
467
-
468
-
469
-
470
-
471
-
472
-
473
-
474
-
475
-
476
-
477
-
478
-
479
-
480
-
481
-
482
-
483
-
484
-
485
-
486
-
487
-
488
-
489
-
490
-
491
-
492
-
493
-
494
-
495
-
496
-
497
-
498
-
499
-
500
-
501
-
502
-
503
-
504
-
505
-
506
-
507
-
508
-
509
-
510
-
511
-
512
-
513
-
514
-
515
-
516
-
517
-
518
-
519
-
520
-
521
-
522
-
523
-
524
-
525
-
526
-
527
-
528
-
529
-
530
-
531
-
532
-
533
-
534
-
535
-
536
-
537
-
538
-
539
-
540
-
541
-
542
-
543
package text
import (
"io"
"regexp"
"unicode/utf8"
"github.com/yuin/goldmark/util"
)
const invalidValue = -1
// EOF indicates the end of file.
const EOF = byte(0xff)
// A Reader interface provides abstracted method for reading text.
type Reader interface {
io.RuneReader
// Source returns a source of the reader.
Source() []byte
// ResetPosition resets positions.
ResetPosition()
// Peek returns a byte at current position without advancing the internal pointer.
Peek() byte
// PeekLine returns the current line without advancing the internal pointer.
PeekLine() ([]byte, Segment)
// PrecendingCharacter returns a character just before current internal pointer.
PrecendingCharacter() rune
// Value returns a value of the given segment.
Value(Segment) []byte
// LineOffset returns a distance from the line head to current position.
LineOffset() int
// Position returns current line number and position.
Position() (int, Segment)
// SetPosition sets current line number and position.
SetPosition(int, Segment)
// SetPadding sets padding to the reader.
SetPadding(int)
// Advance advances the internal pointer.
Advance(int)
// AdvanceAndSetPadding advances the internal pointer and add padding to the
// reader.
AdvanceAndSetPadding(int, int)
// AdvanceLine advances the internal pointer to the next line head.
AdvanceLine()
// SkipSpaces skips space characters and returns a non-blank line.
// If it reaches EOF, returns false.
SkipSpaces() (Segment, int, bool)
// SkipSpaces skips blank lines and returns a non-blank line.
// If it reaches EOF, returns false.
SkipBlankLines() (Segment, int, bool)
// Match performs regular expression matching to current line.
Match(reg *regexp.Regexp) bool
// Match performs regular expression searching to current line.
FindSubMatch(reg *regexp.Regexp) [][]byte
}
type reader struct {
source []byte
sourceLength int
line int
peekedLine []byte
pos Segment
head int
lineOffset int
}
// NewReader return a new Reader that can read UTF-8 bytes .
func NewReader(source []byte) Reader {
r := &reader{
source: source,
sourceLength: len(source),
}
r.ResetPosition()
return r
}
func (r *reader) ResetPosition() {
r.line = -1
r.head = 0
r.lineOffset = -1
r.AdvanceLine()
}
func (r *reader) Source() []byte {
return r.source
}
func (r *reader) Value(seg Segment) []byte {
return seg.Value(r.source)
}
func (r *reader) Peek() byte {
if r.pos.Start >= 0 && r.pos.Start < r.sourceLength {
if r.pos.Padding != 0 {
return space[0]
}
return r.source[r.pos.Start]
}
return EOF
}
func (r *reader) PeekLine() ([]byte, Segment) {
if r.pos.Start >= 0 && r.pos.Start < r.sourceLength {
if r.peekedLine == nil {
r.peekedLine = r.pos.Value(r.Source())
}
return r.peekedLine, r.pos
}
return nil, r.pos
}
// io.RuneReader interface
func (r *reader) ReadRune() (rune, int, error) {
return readRuneReader(r)
}
func (r *reader) LineOffset() int {
if r.lineOffset < 0 {
v := 0
for i := r.head; i < r.pos.Start; i++ {
if r.source[i] == '\t' {
v += util.TabWidth(v)
} else {
v++
}
}
r.lineOffset = v - r.pos.Padding
}
return r.lineOffset
}
func (r *reader) PrecendingCharacter() rune {
if r.pos.Start <= 0 {
if r.pos.Padding != 0 {
return rune(' ')
}
return rune('\n')
}
i := r.pos.Start - 1
for ; i >= 0; i-- {
if utf8.RuneStart(r.source[i]) {
break
}
}
rn, _ := utf8.DecodeRune(r.source[i:])
return rn
}
func (r *reader) Advance(n int) {
r.lineOffset = -1
if n < len(r.peekedLine) && r.pos.Padding == 0 {
r.pos.Start += n
r.peekedLine = nil
return
}
r.peekedLine = nil
l := r.sourceLength
for ; n > 0 && r.pos.Start < l; n-- {
if r.pos.Padding != 0 {
r.pos.Padding--
continue
}
if r.source[r.pos.Start] == '\n' {
r.AdvanceLine()
continue
}
r.pos.Start++
}
}
func (r *reader) AdvanceAndSetPadding(n, padding int) {
r.Advance(n)
if padding > r.pos.Padding {
r.SetPadding(padding)
}
}
func (r *reader) AdvanceLine() {
r.lineOffset = -1
r.peekedLine = nil
r.pos.Start = r.pos.Stop
r.head = r.pos.Start
if r.pos.Start < 0 {
return
}
r.pos.Stop = r.sourceLength
for i := r.pos.Start; i < r.sourceLength; i++ {
c := r.source[i]
if c == '\n' {
r.pos.Stop = i + 1
break
}
}
r.line++
r.pos.Padding = 0
}
func (r *reader) Position() (int, Segment) {
return r.line, r.pos
}
func (r *reader) SetPosition(line int, pos Segment) {
r.lineOffset = -1
r.line = line
r.pos = pos
}
func (r *reader) SetPadding(v int) {
r.pos.Padding = v
}
func (r *reader) SkipSpaces() (Segment, int, bool) {
return skipSpacesReader(r)
}
func (r *reader) SkipBlankLines() (Segment, int, bool) {
return skipBlankLinesReader(r)
}
func (r *reader) Match(reg *regexp.Regexp) bool {
return matchReader(r, reg)
}
func (r *reader) FindSubMatch(reg *regexp.Regexp) [][]byte {
return findSubMatchReader(r, reg)
}
// A BlockReader interface is a reader that is optimized for Blocks.
type BlockReader interface {
Reader
// Reset resets current state and sets new segments to the reader.
Reset(segment *Segments)
}
type blockReader struct {
source []byte
segments *Segments
segmentsLength int
line int
pos Segment
head int
last int
lineOffset int
}
// NewBlockReader returns a new BlockReader.
func NewBlockReader(source []byte, segments *Segments) BlockReader {
r := &blockReader{
source: source,
}
if segments != nil {
r.Reset(segments)
}
return r
}
func (r *blockReader) ResetPosition() {
r.line = -1
r.head = 0
r.last = 0
r.lineOffset = -1
r.pos.Start = -1
r.pos.Stop = -1
r.pos.Padding = 0
if r.segmentsLength > 0 {
last := r.segments.At(r.segmentsLength - 1)
r.last = last.Stop
}
r.AdvanceLine()
}
func (r *blockReader) Reset(segments *Segments) {
r.segments = segments
r.segmentsLength = segments.Len()
r.ResetPosition()
}
func (r *blockReader) Source() []byte {
return r.source
}
func (r *blockReader) Value(seg Segment) []byte {
line := r.segmentsLength - 1
ret := make([]byte, 0, seg.Stop-seg.Start+1)
for ; line >= 0; line-- {
if seg.Start >= r.segments.At(line).Start {
break
}
}
i := seg.Start
for ; line < r.segmentsLength; line++ {
s := r.segments.At(line)
if i < 0 {
i = s.Start
}
ret = s.ConcatPadding(ret)
for ; i < seg.Stop && i < s.Stop; i++ {
ret = append(ret, r.source[i])
}
i = -1
if s.Stop > seg.Stop {
break
}
}
return ret
}
// io.RuneReader interface
func (r *blockReader) ReadRune() (rune, int, error) {
return readRuneReader(r)
}
func (r *blockReader) PrecendingCharacter() rune {
if r.pos.Padding != 0 {
return rune(' ')
}
if r.segments.Len() < 1 {
return rune('\n')
}
firstSegment := r.segments.At(0)
if r.line == 0 && r.pos.Start <= firstSegment.Start {
return rune('\n')
}
l := len(r.source)
i := r.pos.Start - 1
for ; i < l && i >= 0; i-- {
if utf8.RuneStart(r.source[i]) {
break
}
}
if i < 0 || i >= l {
return rune('\n')
}
rn, _ := utf8.DecodeRune(r.source[i:])
return rn
}
func (r *blockReader) LineOffset() int {
if r.lineOffset < 0 {
v := 0
for i := r.head; i < r.pos.Start; i++ {
if r.source[i] == '\t' {
v += util.TabWidth(v)
} else {
v++
}
}
r.lineOffset = v - r.pos.Padding
}
return r.lineOffset
}
func (r *blockReader) Peek() byte {
if r.line < r.segmentsLength && r.pos.Start >= 0 && r.pos.Start < r.last {
if r.pos.Padding != 0 {
return space[0]
}
return r.source[r.pos.Start]
}
return EOF
}
func (r *blockReader) PeekLine() ([]byte, Segment) {
if r.line < r.segmentsLength && r.pos.Start >= 0 && r.pos.Start < r.last {
return r.pos.Value(r.source), r.pos
}
return nil, r.pos
}
func (r *blockReader) Advance(n int) {
r.lineOffset = -1
if n < r.pos.Stop-r.pos.Start && r.pos.Padding == 0 {
r.pos.Start += n
return
}
for ; n > 0; n-- {
if r.pos.Padding != 0 {
r.pos.Padding--
continue
}
if r.pos.Start >= r.pos.Stop-1 && r.pos.Stop < r.last {
r.AdvanceLine()
continue
}
r.pos.Start++
}
}
func (r *blockReader) AdvanceAndSetPadding(n, padding int) {
r.Advance(n)
if padding > r.pos.Padding {
r.SetPadding(padding)
}
}
func (r *blockReader) AdvanceLine() {
r.SetPosition(r.line+1, NewSegment(invalidValue, invalidValue))
r.head = r.pos.Start
}
func (r *blockReader) Position() (int, Segment) {
return r.line, r.pos
}
func (r *blockReader) SetPosition(line int, pos Segment) {
r.lineOffset = -1
r.line = line
if pos.Start == invalidValue {
if r.line < r.segmentsLength {
s := r.segments.At(line)
r.head = s.Start
r.pos = s
}
} else {
r.pos = pos
if r.line < r.segmentsLength {
s := r.segments.At(line)
r.head = s.Start
}
}
}
func (r *blockReader) SetPadding(v int) {
r.lineOffset = -1
r.pos.Padding = v
}
func (r *blockReader) SkipSpaces() (Segment, int, bool) {
return skipSpacesReader(r)
}
func (r *blockReader) SkipBlankLines() (Segment, int, bool) {
return skipBlankLinesReader(r)
}
func (r *blockReader) Match(reg *regexp.Regexp) bool {
return matchReader(r, reg)
}
func (r *blockReader) FindSubMatch(reg *regexp.Regexp) [][]byte {
return findSubMatchReader(r, reg)
}
func skipBlankLinesReader(r Reader) (Segment, int, bool) {
lines := 0
for {
line, seg := r.PeekLine()
if line == nil {
return seg, lines, false
}
if util.IsBlank(line) {
lines++
r.AdvanceLine()
} else {
return seg, lines, true
}
}
}
func skipSpacesReader(r Reader) (Segment, int, bool) {
chars := 0
for {
line, segment := r.PeekLine()
if line == nil {
return segment, chars, false
}
for i, c := range line {
if util.IsSpace(c) {
chars++
r.Advance(1)
continue
}
return segment.WithStart(segment.Start + i + 1), chars, true
}
}
}
func matchReader(r Reader, reg *regexp.Regexp) bool {
oldline, oldseg := r.Position()
match := reg.FindReaderSubmatchIndex(r)
r.SetPosition(oldline, oldseg)
if match == nil {
return false
}
r.Advance(match[1] - match[0])
return true
}
func findSubMatchReader(r Reader, reg *regexp.Regexp) [][]byte {
oldline, oldseg := r.Position()
match := reg.FindReaderSubmatchIndex(r)
r.SetPosition(oldline, oldseg)
if match == nil {
return nil
}
runes := make([]rune, 0, match[1]-match[0])
for i := 0; i < match[1]; {
r, size, _ := readRuneReader(r)
i += size
runes = append(runes, r)
}
result := [][]byte{}
for i := 0; i < len(match); i += 2 {
result = append(result, []byte(string(runes[match[i]:match[i+1]])))
}
r.SetPosition(oldline, oldseg)
r.Advance(match[1] - match[0])
return result
}
func readRuneReader(r Reader) (rune, int, error) {
line, _ := r.PeekLine()
if line == nil {
return 0, 0, io.EOF
}
rn, size := utf8.DecodeRune(line)
if rn == utf8.RuneError {
return 0, 0, io.EOF
}
r.Advance(size)
return rn, size, nil
}