-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathpipeline.go
More file actions
87 lines (78 loc) · 1.81 KB
/
pipeline.go
File metadata and controls
87 lines (78 loc) · 1.81 KB
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
package rescript
// PipelineFunc is a function that can be chained to process a set of tokens.
//
// The output is the modified set of tokens. A PipelineFunc may change, remove
// or insert tokens.
type PipelineFunc func(n *Node) *Node
// BuildPipeline combines several pipeline functions into one.
func BuildPipeline(p ...PipelineFunc) PipelineFunc {
return func(n *Node) *Node {
for _, f := range p {
n = f(n)
}
return n
}
}
// Dehyphenate merges words that are separated by a hyphen.
func Dehyphenate(n *Node) *Node {
count := 0
state := 0
var t *Token
for node := n; node != nil; node = node.Next() {
t = node.Token()
switch state {
case 0:
if t.IsWord() {
state = 1
count = 1
}
case 1:
if t.IsDash() {
state = 2
count++
} else {
state = 0
count = 0
}
case 2:
if t.IsWhitespace() {
state = 2 // same
count++
} else if t.IsWord() {
state = 3
} else {
state = 0
count = 0
}
}
// We have found a hyphenated word if we have reached state = 3
//
// Current node is the last part of the word
// We need to merge `count` preceeding nodes
//
// We update the start node (not the current)
// because the start node might be the return value of this function
if state == 3 {
// go back to the start of the hyphenated word
start := node.Behind(count)
// this will become the merged word
s := start.Token().String()
// drop `count` following nodes
for i := 0; i < count; i++ {
next := start.Next()
if next.Token().IsWord() {
s += next.Token().String()
}
next.Remove()
}
// make the merged word part of the list
start.Update(NewToken(s))
// "fix" the iterator - we have dropped the current node, reset it
node = start
// reset state
count = 0
state = 0
}
}
return n
}