-
Notifications
You must be signed in to change notification settings - Fork 0
/
para.go
84 lines (78 loc) · 1.92 KB
/
para.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
82
83
84
package mdblock
import (
"bytes"
"gopkg.in/akavel/vfmd.v0/md"
"gopkg.in/akavel/vfmd.v0/mdutils"
)
type ParagraphDetector struct {
InQuote bool
InList bool
}
func (p ParagraphDetector) Detect(first, second Line, detectors Detectors) Handler {
block := md.ParagraphBlock{}
return HandlerFunc(func(next Line, ctx Context) (bool, error) {
if next.EOF() {
return p.close(block, ctx)
}
if len(block.Raw) == 0 {
block.Raw = append(block.Raw, md.Run(next))
return true, nil
}
prev := Line(block.Raw[len(block.Raw)-1])
// TODO(akavel): support HTML parser & related interactions [#paragraph-line-sequence]
if prev.isBlank() {
return p.close(block, ctx)
}
nextBytes := bytes.TrimRight(next.Bytes, "\n")
if !next.hasFourSpacePrefix() {
if reHorizontalRule.Match(nextBytes) ||
(p.InQuote && bytes.HasPrefix(bytes.TrimLeft(next.Bytes, " "), []byte(">"))) ||
(p.InList && reOrderedList.Match(nextBytes)) ||
(p.InList && reUnorderedList.Match(nextBytes)) {
return p.close(block, ctx)
}
}
block.Raw = append(block.Raw, md.Run(next))
return true, nil
})
}
func (ParagraphDetector) close(block md.ParagraphBlock, ctx Context) (bool, error) {
ctx.Emit(block)
parseSpans(trim(block.Raw), ctx)
ctx.Emit(md.End{})
return false, nil
}
func trim(region md.Raw) md.Raw {
// rtrim
for len(region) > 0 {
n := len(region)
l := bytes.TrimRight(region[n-1].Bytes, mdutils.Whites)
if len(l) == 0 {
region = region[:n-1]
continue
}
if len(l) < len(region[n-1].Bytes) {
region = append(append(md.Raw{}, region[:n-1]...), md.Run{
Line: region[n-1].Line,
Bytes: l,
})
}
break
}
// ltrim
for len(region) > 0 {
l := bytes.TrimLeft(region[0].Bytes, mdutils.Whites)
if len(l) == 0 {
region = region[1:]
continue
}
if len(l) < len(region[0].Bytes) {
region = append(md.Raw{{
Line: region[0].Line,
Bytes: l,
}}, region[1:]...)
}
break
}
return region
}