-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathparse.go
115 lines (101 loc) · 3.61 KB
/
parse.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
// This file is part of Go WML.
//
// Go WML is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Go WML is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Go WML. If not, see <https://www.gnu.org/licenses/>.
package wml
import (
"regexp"
"strconv"
"strings"
)
func ParseTag(text string) Tag {
r, _ := regexp.Compile(`^\[([0-9a-z_]+)\]\n` +
`((?:` + `(?:[\t ]*#textdomain [0-9a-z_-]+\n)?` + `[\t ]*[0-9a-z_]+[\t ]*=.+\n` + `)*)` +
`((?:` + `(?:[\t ]*#textdomain [0-9a-z_-]+\n)?` + `[\t ]*\[[0-9a-z_]+\]\n` + `(?:.+\n)*` + `[\t ]*\[/[0-9a-z_]+\]\n` + `)*)` +
`[\t ]*\[/[0-9a-z_]+\]$`)
submatches := r.FindStringSubmatch(text)
submatches = append(submatches, make([]string, 4-len(submatches))...)
return Tag{submatches[1], MergeData(parseAttributes(submatches[2]), parseTags(submatches[3]))}
}
func ParseData(text string) Data {
r, _ := regexp.Compile(`^` + `((?:` + `(?:[\t ]*#textdomain [0-9a-z_-]+\n)?` +
`[\t ]*[0-9a-z_]+[\t ]*=(?:(?:"(?:.|\n)*?(?:[^"]|\n)")|(?:[^"].*))(?:\n|$)` + `)*)` +
`((?:` + `(?:[\t ]*#textdomain [0-9a-z_-]+\n)?` +
`[\t ]*\[[0-9a-z_]+\]\n` + `(?:.*\n)*` + `[\t ]*\[/[0-9a-z_]+\](?:\n|$)` + `)*)`)
submatches := r.FindStringSubmatch(text)
submatches = append(submatches, make([]string, 3-len(submatches))...)
return MergeData(parseAttributes(submatches[1]), parseTags(submatches[2]))
}
func parseAttributes(text string) Data {
r, _ := regexp.Compile(`(?:[\t ]*#textdomain ([0-9a-z_-]+)\n)?` +
`[\t ]*([0-9a-z_]+)[\t ]*=[\t ]*(_?)[\t ]*` +
`(?:(?:(")((?:.|\n)*?(?:[^"]|\n))")|([^"].*?))` +
`[\t ]*(?:\n|$)`)
data := make(Data)
float, _ := regexp.Compile(`^\d+\.\d+$`)
integer, _ := regexp.Compile(`^\d+$`)
for _, v := range r.FindAllStringSubmatch(text, -1) {
var value interface{}
switch {
case v[3] == "" && v[4] == "\"":
value = v[5]
case v[3] == "_" && v[4] == "\"":
value = Tr(v[5])
case v[4] == "" && v[6] == "yes":
value = true
case v[4] == "" && v[6] == "no":
value = false
case v[4] == "" && integer.MatchString(v[6]):
value, _ = strconv.Atoi(v[6])
case v[4] == "" && float.MatchString(v[6]):
value, _ = strconv.ParseFloat(v[6], 64)
default:
value = Raw(v[6])
}
if v[1] == "" {
data[v[2]] = value
} else {
data[v[2]] = Domain{value, v[1]}
}
}
return data
}
func parseTags(text string) Data {
i, _ := regexp.Compile(`^(?:[\t ]*#textdomain [0-9a-z_-]+\n)?` + `([\t ]*)\[[0-9a-z_]+\]`)
submatches := i.FindStringSubmatch(text)
indent := append(submatches, make([]string, 2-len(submatches))...)[1]
text = strings.ReplaceAll(strings.Replace(text, indent, "", 1), "\n"+indent, "\n")
r, _ := regexp.Compile(`(?U)` + `(?:[\t ]*#textdomain ([0-9a-z_-]+)\n)?` + `\[([0-9a-z_]+)\]\n` + `((?:.*\n)*)` + `\[/[0-9a-z_]+\]`)
data := make(Data)
for _, v := range r.FindAllStringSubmatch(text, -1) {
textdomain := v[1]
key := v[2]
var value interface{}
if textdomain == "" {
value = ParseData(v[3])
} else {
value = Domain{ParseData(v[3]), textdomain}
}
if data.Contains(key) {
switch data[key].(type) {
case Multiple:
data[key] = append(data[key].(Multiple), value)
default:
data[key] = Multiple{data[key], value}
}
} else {
data[key] = value
}
}
return data
}