-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathparser.go
117 lines (103 loc) · 1.9 KB
/
parser.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
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
package main
const EMPTY_STRING = ""
type Parser struct {
i int
l int
spaces int
clip string
content []rune
previous rune
interpreter Interpreter
}
type Interpreter interface {
report(kind, value string)
}
func NewParser(content string, interpreter Interpreter) *Parser {
return &Parser{
content: []rune(content),
interpreter: interpreter,
}
}
func (p *Parser) next() bool {
if p.i+1 < p.l {
p.i++
return true
}
return false
}
func (p *Parser) cut() {
if len(p.clip) == 0 {
return
}
p.interpreter.report("cut", p.clip)
p.clip = EMPTY_STRING
}
func (p *Parser) at(index int) rune {
return p.content[index]
}
func (p *Parser) char() rune {
return p.at(p.i)
}
func (p *Parser) append() {
p.clip += string(p.char())
}
func (p *Parser) Process() {
p.l = len(p.content)
var insideCommand bool
for {
var shouldUpdatePrevious bool = true
char := p.char()
if insideCommand {
switch char {
case '$':
p.cut()
insideCommand = false
default:
p.append()
}
} else {
switch char {
case '$':
p.cut()
p.append()
insideCommand = true
case '-':
if len(p.clip) == 0 || (p.at(p.i+1) == ' ' || p.at(p.i+1) == ',' && p.previous == ' ') {
p.content[p.i] = '—'
}
p.append()
case '\n', 13:
if p.previous == ' ' {
clipra := []rune(p.clip)
l := len(clipra)
if l > 2 && clipra[l-2] == '—' && clipra[l-3] != ' ' {
clipra[l-2] = '-'
p.clip = string(clipra[:l-1])
}
}
// ignore new lines
shouldUpdatePrevious = false
case '.':
p.append()
if p.spaces > 15 && p.at(p.i+1) != '.' {
p.cut()
p.spaces = 0
}
case ' ':
if p.previous != ' ' && len(p.clip) != 0 {
p.spaces++
p.append()
}
default:
p.append()
}
}
if shouldUpdatePrevious {
p.previous = char
}
if !p.next() {
p.cut()
return
}
}
}