...
1
2
3
4
5 package pipeline
6
7 import (
8 "encoding/json"
9 "errors"
10 "strings"
11
12 "golang.org/x/text/language"
13 )
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 type Messages struct {
29 Language language.Tag `json:"language"`
30 Messages []Message `json:"messages"`
31 Macros map[string]Text `json:"macros,omitempty"`
32 }
33
34
35 type Message struct {
36
37 ID IDList `json:"id"`
38
39 Key string `json:"key,omitempty"`
40 Meaning string `json:"meaning,omitempty"`
41 Message Text `json:"message"`
42 Translation Text `json:"translation"`
43
44 Comment string `json:"comment,omitempty"`
45 TranslatorComment string `json:"translatorComment,omitempty"`
46
47 Placeholders []Placeholder `json:"placeholders,omitempty"`
48
49
50
51
52 Fuzzy bool `json:"fuzzy,omitempty"`
53
54
55
56
57
58 Position string `json:"position,omitempty"`
59 }
60
61
62
63 func (m *Message) Placeholder(id string) *Placeholder {
64 for _, p := range m.Placeholders {
65 if p.ID == id {
66 return &p
67 }
68 }
69 return nil
70 }
71
72
73 func (m *Message) Substitute(msg string) (sub string, err error) {
74 last := 0
75 for i := 0; i < len(msg); {
76 pLeft := strings.IndexByte(msg[i:], '{')
77 if pLeft == -1 {
78 break
79 }
80 pLeft += i
81 pRight := strings.IndexByte(msg[pLeft:], '}')
82 if pRight == -1 {
83 return "", errorf("unmatched '}'")
84 }
85 pRight += pLeft
86 id := strings.TrimSpace(msg[pLeft+1 : pRight])
87 i = pRight + 1
88 if id != "" && id[0] == '$' {
89 continue
90 }
91 sub += msg[last:pLeft]
92 last = i
93 ph := m.Placeholder(id)
94 if ph == nil {
95 return "", errorf("unknown placeholder %q in message %q", id, msg)
96 }
97 sub += ph.String
98 }
99 sub += msg[last:]
100 return sub, err
101 }
102
103 var errIncompatibleMessage = errors.New("messages incompatible")
104
105 func checkEquivalence(a, b *Message) error {
106 for _, v := range a.ID {
107 for _, w := range b.ID {
108 if v == w {
109 return nil
110 }
111 }
112 }
113
114 return errIncompatibleMessage
115 }
116
117
118
119
120 type Placeholder struct {
121
122 ID string `json:"id"`
123
124
125
126
127 String string `json:"string"`
128
129 Type string `json:"type"`
130 UnderlyingType string `json:"underlyingType"`
131
132
133 ArgNum int `json:"argNum,omitempty"`
134 Expr string `json:"expr,omitempty"`
135
136 Comment string `json:"comment,omitempty"`
137 Example string `json:"example,omitempty"`
138
139
140
141 Features []Feature `json:"features,omitempty"`
142 }
143
144
145 type argument struct {
146
147
148 ArgNum int `json:"argNum,omitempty"`
149
150 used bool
151 Type string `json:"type"`
152 UnderlyingType string `json:"underlyingType"`
153 Expr string `json:"expr"`
154 Value string `json:"value,omitempty"`
155 Comment string `json:"comment,omitempty"`
156 Position string `json:"position,omitempty"`
157 }
158
159
160
161 type Feature struct {
162 Type string `json:"type"`
163
164
165
166 }
167
168
169 type Text struct {
170
171
172 Msg string `json:"msg,omitempty"`
173 Select *Select `json:"select,omitempty"`
174
175
176
177 Var map[string]Text `json:"var,omitempty"`
178
179
180 Example string `json:"example,omitempty"`
181 }
182
183
184 func (t *Text) IsEmpty() bool {
185 return t.Msg == "" && t.Select == nil && t.Var == nil
186 }
187
188
189 type rawText Text
190
191
192 func (t *Text) UnmarshalJSON(b []byte) error {
193 if b[0] == '"' {
194 return json.Unmarshal(b, &t.Msg)
195 }
196 return json.Unmarshal(b, (*rawText)(t))
197 }
198
199
200 func (t *Text) MarshalJSON() ([]byte, error) {
201 if t.Select == nil && t.Var == nil && t.Example == "" {
202 return json.Marshal(t.Msg)
203 }
204 return json.Marshal((*rawText)(t))
205 }
206
207
208
209
210 type IDList []string
211
212
213 func (id *IDList) UnmarshalJSON(b []byte) error {
214 if b[0] == '"' {
215 *id = []string{""}
216 return json.Unmarshal(b, &((*id)[0]))
217 }
218 return json.Unmarshal(b, (*[]string)(id))
219 }
220
221
222 func (id *IDList) MarshalJSON() ([]byte, error) {
223 if len(*id) == 1 {
224 return json.Marshal((*id)[0])
225 }
226 return json.Marshal((*[]string)(id))
227 }
228
229
230
231 type Select struct {
232 Feature string `json:"feature"`
233 Arg string `json:"arg"`
234 Cases map[string]Text `json:"cases"`
235 }
236
237
238
239
240
241
242
View as plain text