This repository has been archived by the owner on Feb 9, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
text.go
127 lines (111 loc) · 2.6 KB
/
text.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
118
119
120
121
122
123
124
125
126
127
package dhelpers
import (
"errors"
"runtime"
"strings"
)
var quoteReplacer = strings.NewReplacer("“", "\"", "”", "\"", "‘", "'", "’", "'")
// ToArgv converts string s into an string array
// text in quotes will be counted as 1 array element
// Source: https://github.com/Seklfreak/Robyul2/blob/master/helpers/text.go#L14
func ToArgv(s string) ([]string, error) {
s = quoteReplacer.Replace(s)
const (
InArg = iota
InArgQuote
OutOfArg
)
currentState := OutOfArg
currentQuoteChar := "\x00" // to distinguish between ' and " quotations
// this allows to use "foo'bar"
currentArg := ""
argv := []string{}
isQuote := func(c string) bool {
return c == `"` || c == `'`
}
isEscape := func(c string) bool {
return c == `\`
}
isWhitespace := func(c string) bool {
return c == " " || c == "\t"
}
L := len(s)
for i := 0; i < L; i++ {
c := s[i : i+1]
//fmt.Printf("c %s state %v arg %s argv %v i %d\n", c, currentState, currentArg, args, i)
if isQuote(c) {
switch currentState {
case OutOfArg:
currentArg = ""
fallthrough
case InArg:
currentState = InArgQuote
currentQuoteChar = c
case InArgQuote:
if c == currentQuoteChar {
currentState = InArg
} else {
currentArg += c
}
}
} else if isWhitespace(c) {
switch currentState {
case InArg:
argv = append(argv, currentArg)
currentState = OutOfArg
case InArgQuote:
currentArg += c
case OutOfArg:
// nothing
}
} else if isEscape(c) {
switch currentState {
case OutOfArg:
currentArg = ""
currentState = InArg
fallthrough
case InArg:
fallthrough
case InArgQuote:
if i == L-1 {
if runtime.GOOS == "windows" {
// just add \ to end for windows
currentArg += c
} else {
return nil, errors.New("escape character at end string")
}
} else {
if runtime.GOOS == "windows" {
peek := s[i+1 : i+2]
if peek != `"` {
currentArg += c
}
} else {
i++
c = s[i : i+1]
currentArg += c
}
}
}
} else {
switch currentState {
case InArg, InArgQuote:
currentArg += c
case OutOfArg:
currentArg = ""
currentArg += c
currentState = InArg
}
}
}
if currentState == InArg {
argv = append(argv, currentArg)
} else if currentState == InArgQuote {
return nil, errors.New("starting quote has no ending quote")
}
return argv, nil
}
// EscapeLinkForMarkdown escapes a link to be ready to used in markdown
func EscapeLinkForMarkdown(input string) (result string) {
return strings.Replace(strings.Replace(input, ")", "%29", -1), "(", "%28", -1)
}