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
|
package mardown
import "fmt"
type lexerType string
const (
lexerBreak lexerType = "break"
lexerModifier lexerType = "modifier"
lexerCode lexerType = "code"
lexerHeader lexerType = "header"
lexerQuote lexerType = "quote"
lexerList lexerType = "list"
lexerExternal lexerType = "external"
lexerLiteral lexerType = "literal"
)
type lexer struct {
Type lexerType
Value string
}
func (l *lexer) String() string {
return fmt.Sprintf("%s(%s)", l.Type, l.Value)
}
type lexers struct {
current int
lexers []lexer
}
func (l *lexers) Next() bool {
l.current++
return !l.Finished()
}
func (l *lexers) Current() lexer {
return l.lexers[l.current]
}
func (l *lexers) Finished() bool {
return l.current >= len(l.lexers)
}
func (l *lexers) Before() bool {
l.current--
return l.current >= 0 && !l.Finished()
}
func (l *lexers) String() string {
s := "Lexers["
for _, l := range l.lexers {
s += l.String() + " "
}
return s + "]"
}
func lex(s string) *lexers {
lxs := &lexers{current: -1}
var lexs []lexer
var currentType lexerType
var previous string
fn := func(c rune, t lexerType) {
if currentType != t && len(previous) > 0 {
lexs = append(lexs, lexer{Type: currentType, Value: previous})
previous = ""
}
currentType = t
previous += string(c)
}
literalNext := false
for _, c := range []rune(s) {
if literalNext {
fn(c, lexerLiteral)
literalNext = false
continue
}
if c == '\\' {
literalNext = true
continue
}
switch c {
case '*', '_':
if (currentType != lexerModifier && len(previous) > 0) ||
(len(previous) > 0 && []rune(previous)[0] != c) ||
len(previous) > 2 {
lexs = append(lexs, lexer{Type: currentType, Value: previous})
previous = ""
}
currentType = lexerModifier
previous += string(c)
case '`':
fn(c, lexerCode)
case '\n':
fn(c, lexerBreak)
case '#':
fn(c, lexerHeader)
case '>':
fn(c, lexerQuote)
case '[', ']', '(', ')', '!':
fn(c, lexerExternal)
case '-', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.':
fn(c, lexerList)
default:
fn(c, lexerLiteral)
}
}
if len(previous) > 0 {
lexs = append(lexs, lexer{Type: currentType, Value: previous})
}
lxs.lexers = lexs
return lxs
}
|