message_format 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +12 -0
- data/CODE_OF_CONDUCT.md +13 -0
- data/lib/message_format.rb +10 -2
- data/lib/message_format/interpreter.rb +46 -52
- data/lib/message_format/parser.rb +110 -115
- data/lib/message_format/version.rb +1 -1
- data/spec/message_format_spec.rb +24 -1
- metadata +3 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 90b4292d4e0a33c497f1cf9ec2efe3650592c900
|
4
|
+
data.tar.gz: 8833b184ef0771db6d1b3bebcf5e79520ec5e59e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a535a9ab8e3239bfcb46fe08b27fab14aacc5de742098be6e3839c0635bed11ec3c5232218220fc2b0f5c65ec9f3034bfee3806f7070a77dfdf1995b677a1521
|
7
|
+
data.tar.gz: 32a2459fcb0ffda22a8aa63193172558d49c2b43db209d2e6cd1d36ab629cfbd3a7a20a4310cbca8f591f3b9a92a963acf01ae32be060b48d7e5ddb60e68fda1
|
data/CHANGELOG.md
ADDED
data/CODE_OF_CONDUCT.md
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# Contributor Code of Conduct
|
2
|
+
|
3
|
+
As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
|
4
|
+
|
5
|
+
We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, age, or religion.
|
6
|
+
|
7
|
+
Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.
|
8
|
+
|
9
|
+
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team.
|
10
|
+
|
11
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.
|
12
|
+
|
13
|
+
This Code of Conduct is adapted from the [Contributor Covenant](http:contributor-covenant.org), version 1.0.0, available at [http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org/version/1/0/0/)
|
data/lib/message_format.rb
CHANGED
@@ -15,7 +15,7 @@ module MessageFormat
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def format ( args=nil )
|
18
|
-
|
18
|
+
@format.call(args)
|
19
19
|
end
|
20
20
|
|
21
21
|
end
|
@@ -23,7 +23,15 @@ module MessageFormat
|
|
23
23
|
class << self
|
24
24
|
|
25
25
|
def new ( pattern, locale=nil )
|
26
|
-
|
26
|
+
MessageFormat.new(pattern, locale)
|
27
|
+
end
|
28
|
+
|
29
|
+
def format_message ( pattern, args=nil, locale=nil )
|
30
|
+
locale ||= TwitterCldr.locale
|
31
|
+
Interpreter.interpret(
|
32
|
+
Parser.parse(pattern),
|
33
|
+
{ :locale => locale.to_sym }
|
34
|
+
).call(args)
|
27
35
|
end
|
28
36
|
|
29
37
|
end
|
@@ -19,19 +19,19 @@ module MessageFormat
|
|
19
19
|
|
20
20
|
def initialize ( options=nil )
|
21
21
|
if options and options.has_key?(:locale)
|
22
|
-
@
|
22
|
+
@locale = options[:locale]
|
23
23
|
else
|
24
|
-
@
|
24
|
+
@locale = TwitterCldr.locale
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
28
|
def interpret ( elements )
|
29
|
-
|
29
|
+
interpret_subs(elements)
|
30
30
|
end
|
31
31
|
|
32
|
-
def
|
32
|
+
def interpret_subs ( elements, parent=nil )
|
33
33
|
elements = elements.map do |element|
|
34
|
-
|
34
|
+
interpret_element(element, parent)
|
35
35
|
end
|
36
36
|
|
37
37
|
# optimize common case
|
@@ -39,18 +39,14 @@ module MessageFormat
|
|
39
39
|
return elements[0]
|
40
40
|
end
|
41
41
|
|
42
|
-
|
43
|
-
|
44
|
-
elements.map do |element|
|
45
|
-
message += element.call(args)
|
46
|
-
end
|
47
|
-
return message
|
42
|
+
lambda do |args|
|
43
|
+
elements.map { |element| element.call(args) }.join ''
|
48
44
|
end
|
49
45
|
end
|
50
46
|
|
51
|
-
def
|
47
|
+
def interpret_element ( element, parent=nil )
|
52
48
|
if element.is_a?(String)
|
53
|
-
return lambda { |
|
49
|
+
return lambda { |_=nil| element }
|
54
50
|
end
|
55
51
|
|
56
52
|
id, type, style = element
|
@@ -67,104 +63,102 @@ module MessageFormat
|
|
67
63
|
|
68
64
|
case type
|
69
65
|
when 'number'
|
70
|
-
|
66
|
+
interpret_number(id, offset, style)
|
71
67
|
when 'date', 'time'
|
72
|
-
|
68
|
+
interpret_date_time(id, type, style)
|
73
69
|
when 'plural', 'selectordinal'
|
74
70
|
offset = element[2]
|
75
71
|
options = element[3]
|
76
|
-
|
72
|
+
interpret_plural(id, type, offset, options)
|
77
73
|
when 'select'
|
78
|
-
|
74
|
+
interpret_select(id, style)
|
79
75
|
when 'spellout', 'ordinal', 'duration'
|
80
|
-
|
76
|
+
interpret_number(id, offset, type)
|
81
77
|
else
|
82
|
-
|
78
|
+
interpret_simple(id)
|
83
79
|
end
|
84
80
|
end
|
85
81
|
|
86
|
-
def
|
87
|
-
locale = @
|
88
|
-
|
82
|
+
def interpret_number ( id, offset, style )
|
83
|
+
locale = @locale
|
84
|
+
lambda do |args|
|
89
85
|
number = TwitterCldr::Localized::LocalizedNumber.new(args[id] - offset, locale)
|
90
86
|
if style == 'integer'
|
91
|
-
|
87
|
+
number.to_decimal(:precision => 0).to_s
|
92
88
|
elsif style == 'percent'
|
93
|
-
|
89
|
+
number.to_percent.to_s
|
94
90
|
elsif style == 'currency'
|
95
|
-
|
91
|
+
number.to_currency.to_s
|
96
92
|
elsif style == 'spellout'
|
97
|
-
|
93
|
+
number.spellout
|
98
94
|
elsif style == 'ordinal'
|
99
|
-
|
95
|
+
number.to_rbnf_s('OrdinalRules', 'digits-ordinal')
|
100
96
|
else
|
101
|
-
|
97
|
+
number.to_s
|
102
98
|
end
|
103
99
|
end
|
104
100
|
end
|
105
101
|
|
106
|
-
def
|
107
|
-
locale = @
|
108
|
-
|
102
|
+
def interpret_date_time ( id, type, style='medium' )
|
103
|
+
locale = @locale
|
104
|
+
lambda do |args|
|
109
105
|
datetime = TwitterCldr::Localized::LocalizedDateTime.new(args[id], locale)
|
110
106
|
datetime = type == 'date' ? datetime.to_date : datetime.to_time
|
111
107
|
if style == 'medium'
|
112
|
-
|
108
|
+
datetime.to_medium_s
|
113
109
|
elsif style == 'long'
|
114
|
-
|
110
|
+
datetime.to_long_s
|
115
111
|
elsif style == 'short'
|
116
|
-
|
112
|
+
datetime.to_short_s
|
117
113
|
elsif style == 'full'
|
118
|
-
|
114
|
+
datetime.to_full_s
|
119
115
|
else
|
120
|
-
|
116
|
+
datetime.to_additional_s(style)
|
121
117
|
end
|
122
118
|
end
|
123
119
|
end
|
124
120
|
|
125
|
-
def
|
121
|
+
def interpret_plural ( id, type, offset, children )
|
126
122
|
parent = [ id, type, offset ]
|
127
123
|
options = {}
|
128
124
|
children.each do |key, value|
|
129
|
-
options[key.to_sym] =
|
125
|
+
options[key.to_sym] = interpret_subs(value, parent)
|
130
126
|
end
|
131
127
|
|
132
|
-
locale = @
|
133
|
-
|
134
|
-
|
128
|
+
locale = @locale
|
129
|
+
plural_type = type == 'selectordinal' ? :ordinal : :cardinal
|
130
|
+
lambda do |args|
|
135
131
|
arg = args[id]
|
136
132
|
exactSelector = ('=' + arg.to_s).to_sym
|
137
|
-
keywordSelector = TwitterCldr::Formatters::Plurals::Rules.rule_for(arg - offset, locale,
|
133
|
+
keywordSelector = TwitterCldr::Formatters::Plurals::Rules.rule_for(arg - offset, locale, plural_type)
|
138
134
|
func =
|
139
135
|
options[exactSelector] ||
|
140
136
|
options[keywordSelector] ||
|
141
137
|
options[:other]
|
142
|
-
|
138
|
+
func.call(args)
|
143
139
|
end
|
144
140
|
end
|
145
141
|
|
146
|
-
def
|
142
|
+
def interpret_select ( id, children )
|
147
143
|
options = {}
|
148
144
|
children.each do |key, value|
|
149
|
-
options[key.to_sym] =
|
145
|
+
options[key.to_sym] = interpret_subs(value, nil)
|
150
146
|
end
|
151
|
-
|
147
|
+
lambda do |args|
|
152
148
|
selector = args[id].to_sym
|
153
149
|
func =
|
154
150
|
options[selector] ||
|
155
151
|
options[:other]
|
156
|
-
|
152
|
+
func.call(args)
|
157
153
|
end
|
158
154
|
end
|
159
155
|
|
160
|
-
def
|
161
|
-
|
162
|
-
return args[id].to_s
|
163
|
-
end
|
156
|
+
def interpret_simple ( id )
|
157
|
+
lambda { |args| args[id].to_s }
|
164
158
|
end
|
165
159
|
|
166
160
|
def self.interpret ( elements, options=nil )
|
167
|
-
|
161
|
+
Interpreter.new(options).interpret(elements)
|
168
162
|
end
|
169
163
|
|
170
164
|
end
|
@@ -26,61 +26,57 @@ module MessageFormat
|
|
26
26
|
|
27
27
|
def parse ( pattern )
|
28
28
|
if !pattern.is_a?(String)
|
29
|
-
|
29
|
+
raise_expected('String pattern', pattern.class.to_s)
|
30
30
|
end
|
31
31
|
|
32
32
|
@pattern = pattern
|
33
33
|
@length = pattern.length
|
34
34
|
@index = 0
|
35
|
-
|
35
|
+
parse_message("message")
|
36
36
|
end
|
37
37
|
|
38
|
-
def
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
char == '9'
|
50
|
-
)
|
38
|
+
def is_digit ( char )
|
39
|
+
char == '0' or
|
40
|
+
char == '1' or
|
41
|
+
char == '2' or
|
42
|
+
char == '3' or
|
43
|
+
char == '4' or
|
44
|
+
char == '5' or
|
45
|
+
char == '6' or
|
46
|
+
char == '7' or
|
47
|
+
char == '8' or
|
48
|
+
char == '9'
|
51
49
|
end
|
52
50
|
|
53
|
-
def
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
char == "\u2029"
|
64
|
-
)
|
51
|
+
def is_whitespace ( char )
|
52
|
+
char == "\s" or
|
53
|
+
char == "\t" or
|
54
|
+
char == "\n" or
|
55
|
+
char == "\r" or
|
56
|
+
char == "\f" or
|
57
|
+
char == "\v" or
|
58
|
+
char == "\u00A0" or
|
59
|
+
char == "\u2028" or
|
60
|
+
char == "\u2029"
|
65
61
|
end
|
66
62
|
|
67
|
-
def
|
68
|
-
while @index < @length and
|
63
|
+
def skip_whitespace ()
|
64
|
+
while @index < @length and is_whitespace(@pattern[@index])
|
69
65
|
@index += 1
|
70
66
|
end
|
71
67
|
end
|
72
68
|
|
73
|
-
def
|
74
|
-
|
75
|
-
|
69
|
+
def parse_text ( parent_type )
|
70
|
+
is_hash_special = (parent_type == 'plural' or parent_type == 'selectordinal')
|
71
|
+
is_arg_style = (parent_type == 'style')
|
76
72
|
text = ''
|
77
73
|
while @index < @length
|
78
74
|
char = @pattern[@index]
|
79
75
|
if (
|
80
76
|
char == '{' or
|
81
77
|
char == '}' or
|
82
|
-
(
|
83
|
-
(
|
78
|
+
(is_hash_special and char == '#') or
|
79
|
+
(is_arg_style and is_whitespace(char))
|
84
80
|
)
|
85
81
|
break
|
86
82
|
elsif char == '\''
|
@@ -93,8 +89,8 @@ module MessageFormat
|
|
93
89
|
# only when necessary
|
94
90
|
char == '{' or
|
95
91
|
char == '}' or
|
96
|
-
(
|
97
|
-
(
|
92
|
+
(is_hash_special and char == '#') or
|
93
|
+
(is_arg_style and is_whitespace(char))
|
98
94
|
)
|
99
95
|
text += char
|
100
96
|
while @index + 1 < @length
|
@@ -120,28 +116,28 @@ module MessageFormat
|
|
120
116
|
end
|
121
117
|
end
|
122
118
|
|
123
|
-
|
119
|
+
text
|
124
120
|
end
|
125
121
|
|
126
|
-
def
|
122
|
+
def parse_argument ()
|
127
123
|
if @pattern[@index] == '#'
|
128
124
|
@index += 1 # move passed #
|
129
125
|
return [ '#' ]
|
130
126
|
end
|
131
127
|
|
132
128
|
@index += 1 # move passed {
|
133
|
-
id =
|
129
|
+
id = parse_arg_id()
|
134
130
|
char = @pattern[@index]
|
135
131
|
if char == '}' # end argument
|
136
132
|
@index += 1 # move passed }
|
137
133
|
return [ id ]
|
138
134
|
end
|
139
135
|
if char != ','
|
140
|
-
|
136
|
+
raise_expected(',')
|
141
137
|
end
|
142
138
|
@index += 1 # move passed ,
|
143
139
|
|
144
|
-
type =
|
140
|
+
type = parse_arg_type()
|
145
141
|
char = @pattern[@index]
|
146
142
|
if char == '}' # end argument
|
147
143
|
if (
|
@@ -149,191 +145,191 @@ module MessageFormat
|
|
149
145
|
type == 'selectordinal' or
|
150
146
|
type == 'select'
|
151
147
|
)
|
152
|
-
|
148
|
+
raise_expected(type + ' message options')
|
153
149
|
end
|
154
150
|
@index += 1 # move passed }
|
155
151
|
return [ id, type ]
|
156
152
|
end
|
157
153
|
if char != ','
|
158
|
-
|
154
|
+
raise_expected(',')
|
159
155
|
end
|
160
156
|
@index += 1 # move passed ,
|
161
157
|
|
162
158
|
format = nil
|
163
159
|
offset = nil
|
164
160
|
if type == 'plural' or type == 'selectordinal'
|
165
|
-
offset =
|
166
|
-
format =
|
161
|
+
offset = parse_plural_offset()
|
162
|
+
format = parse_sub_messages(type)
|
167
163
|
elsif type == 'select'
|
168
|
-
format =
|
164
|
+
format = parse_sub_messages(type)
|
169
165
|
else
|
170
|
-
format =
|
166
|
+
format = parse_simple_format()
|
171
167
|
end
|
172
168
|
char = @pattern[@index]
|
173
169
|
if char != '}' # not ended argument
|
174
|
-
|
170
|
+
raise_expected('}')
|
175
171
|
end
|
176
172
|
@index += 1 # move passed
|
177
173
|
|
178
|
-
|
174
|
+
(type == 'plural' or type == 'selectordinal') ?
|
179
175
|
[ id, type, offset, format ] :
|
180
176
|
[ id, type, format ]
|
181
177
|
end
|
182
178
|
|
183
|
-
def
|
184
|
-
|
179
|
+
def parse_arg_id ()
|
180
|
+
skip_whitespace()
|
185
181
|
id = ''
|
186
182
|
while @index < @length
|
187
183
|
char = @pattern[@index]
|
188
184
|
if char == '{' or char == '#'
|
189
|
-
|
185
|
+
raise_expected('argument id')
|
190
186
|
end
|
191
|
-
if char == '}' or char == ',' or
|
187
|
+
if char == '}' or char == ',' or is_whitespace(char)
|
192
188
|
break
|
193
189
|
end
|
194
190
|
id += char
|
195
191
|
@index += 1
|
196
192
|
end
|
197
193
|
if id.empty?
|
198
|
-
|
194
|
+
raise_expected('argument id')
|
199
195
|
end
|
200
|
-
|
201
|
-
|
196
|
+
skip_whitespace()
|
197
|
+
id
|
202
198
|
end
|
203
199
|
|
204
|
-
def
|
205
|
-
|
206
|
-
|
200
|
+
def parse_arg_type ()
|
201
|
+
skip_whitespace()
|
202
|
+
arg_type = nil
|
207
203
|
types = [
|
208
204
|
'number', 'date', 'time', 'ordinal', 'duration', 'spellout', 'plural', 'selectordinal', 'select'
|
209
205
|
]
|
210
206
|
types.each do |type|
|
211
207
|
if @pattern.slice(@index, type.length) == type
|
212
|
-
|
208
|
+
arg_type = type
|
213
209
|
@index += type.length
|
214
210
|
break
|
215
211
|
end
|
216
212
|
end
|
217
|
-
if !
|
218
|
-
|
213
|
+
if !arg_type
|
214
|
+
raise_expected(types.join(', '))
|
219
215
|
end
|
220
|
-
|
221
|
-
|
216
|
+
skip_whitespace()
|
217
|
+
arg_type
|
222
218
|
end
|
223
219
|
|
224
|
-
def
|
225
|
-
|
226
|
-
style =
|
220
|
+
def parse_simple_format ()
|
221
|
+
skip_whitespace()
|
222
|
+
style = parse_text('style')
|
227
223
|
if style.empty?
|
228
|
-
|
224
|
+
raise_expected('argument style name')
|
229
225
|
end
|
230
|
-
|
231
|
-
|
226
|
+
skip_whitespace()
|
227
|
+
style
|
232
228
|
end
|
233
229
|
|
234
|
-
def
|
235
|
-
|
230
|
+
def parse_plural_offset ()
|
231
|
+
skip_whitespace()
|
236
232
|
offset = 0
|
237
233
|
if @pattern.slice(@index, 7) == 'offset:'
|
238
234
|
@index += 7 # move passed offset:
|
239
|
-
|
235
|
+
skip_whitespace()
|
240
236
|
start = @index
|
241
237
|
while (
|
242
238
|
@index < @length and
|
243
|
-
|
239
|
+
is_digit(@pattern[@index])
|
244
240
|
)
|
245
241
|
@index += 1
|
246
242
|
end
|
247
243
|
if start == @index
|
248
|
-
|
244
|
+
raise_expected('offset number')
|
249
245
|
end
|
250
246
|
offset = @pattern[start..@index].to_i
|
251
|
-
|
247
|
+
skip_whitespace()
|
252
248
|
end
|
253
|
-
|
249
|
+
offset
|
254
250
|
end
|
255
251
|
|
256
|
-
def
|
257
|
-
|
252
|
+
def parse_sub_messages ( parent_type )
|
253
|
+
skip_whitespace()
|
258
254
|
options = {}
|
259
|
-
|
255
|
+
has_subs = false
|
260
256
|
while (
|
261
257
|
@index < @length and
|
262
258
|
@pattern[@index] != '}'
|
263
259
|
)
|
264
|
-
selector =
|
265
|
-
|
266
|
-
options[selector] =
|
267
|
-
|
268
|
-
|
260
|
+
selector = parse_selector()
|
261
|
+
skip_whitespace()
|
262
|
+
options[selector] = parse_sub_message(parent_type)
|
263
|
+
has_subs = true
|
264
|
+
skip_whitespace()
|
269
265
|
end
|
270
|
-
if !
|
271
|
-
|
266
|
+
if !has_subs
|
267
|
+
raise_expected(parent_type + ' message options')
|
272
268
|
end
|
273
269
|
if !options.has_key?('other') # does not have an other selector
|
274
|
-
|
270
|
+
raise_expected(nil, nil, '"other" option must be specified in ' + parent_type)
|
275
271
|
end
|
276
|
-
|
272
|
+
options
|
277
273
|
end
|
278
274
|
|
279
|
-
def
|
275
|
+
def parse_selector ()
|
280
276
|
selector = ''
|
281
277
|
while @index < @length
|
282
278
|
char = @pattern[@index]
|
283
279
|
if char == '}' or char == ','
|
284
|
-
|
280
|
+
raise_expected('{')
|
285
281
|
end
|
286
|
-
if char == '{' or
|
282
|
+
if char == '{' or is_whitespace(char)
|
287
283
|
break
|
288
284
|
end
|
289
285
|
selector += char
|
290
286
|
@index += 1
|
291
287
|
end
|
292
288
|
if selector.empty?
|
293
|
-
|
289
|
+
raise_expected('selector')
|
294
290
|
end
|
295
|
-
|
296
|
-
|
291
|
+
skip_whitespace()
|
292
|
+
selector
|
297
293
|
end
|
298
294
|
|
299
|
-
def
|
295
|
+
def parse_sub_message ( parent_type )
|
300
296
|
char = @pattern[@index]
|
301
297
|
if char != '{'
|
302
|
-
|
298
|
+
raise_expected('{')
|
303
299
|
end
|
304
300
|
@index += 1 # move passed {
|
305
|
-
message =
|
301
|
+
message = parse_message(parent_type)
|
306
302
|
char = @pattern[@index]
|
307
303
|
if char != '}'
|
308
|
-
|
304
|
+
raise_expected('}')
|
309
305
|
end
|
310
306
|
@index += 1 # move passed }
|
311
|
-
|
307
|
+
message
|
312
308
|
end
|
313
309
|
|
314
|
-
def
|
310
|
+
def parse_message ( parent_type )
|
315
311
|
elements = []
|
316
|
-
text =
|
312
|
+
text = parse_text(parent_type)
|
317
313
|
if !text.empty?
|
318
314
|
elements.push(text)
|
319
315
|
end
|
320
316
|
while @index < @length
|
321
317
|
if @pattern[@index] == '}'
|
322
|
-
if
|
323
|
-
|
318
|
+
if parent_type == 'message'
|
319
|
+
raise_expected()
|
324
320
|
end
|
325
321
|
break
|
326
322
|
end
|
327
|
-
elements.push(
|
328
|
-
text =
|
323
|
+
elements.push(parse_argument())
|
324
|
+
text = parse_text(parent_type)
|
329
325
|
if !text.empty?
|
330
326
|
elements.push(text)
|
331
327
|
end
|
332
328
|
end
|
333
|
-
|
329
|
+
elements
|
334
330
|
end
|
335
331
|
|
336
|
-
def
|
332
|
+
def raise_expected ( expected=nil, found=nil, message=nil )
|
337
333
|
lines = @pattern[0..@index].split(/\r?\n/)
|
338
334
|
line = lines.length
|
339
335
|
column = lines.last.length
|
@@ -341,22 +337,21 @@ module MessageFormat
|
|
341
337
|
found = @index < @length ? @pattern[@index] : 'end of input'
|
342
338
|
end
|
343
339
|
if !message
|
344
|
-
message =
|
340
|
+
message = error_message(expected, found)
|
345
341
|
end
|
346
342
|
message += ' in "' + @pattern.gsub(/\r?\n/, "\n") + '"'
|
347
343
|
|
348
344
|
raise SyntaxError.new(message, expected, found, @index, line, column)
|
349
345
|
end
|
350
346
|
|
351
|
-
def
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
return "Expected \"#{ expected }\" but found \"#{ found }\""
|
347
|
+
def error_message ( expected=nil, found )
|
348
|
+
expected ?
|
349
|
+
"Expected \"#{ expected }\" but found \"#{ found }\"" :
|
350
|
+
"Unexpected \"#{ found }\" found"
|
356
351
|
end
|
357
352
|
|
358
353
|
def self.parse ( pattern )
|
359
|
-
|
354
|
+
Parser.new().parse(pattern)
|
360
355
|
end
|
361
356
|
|
362
357
|
#
|
data/spec/message_format_spec.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe MessageFormat do
|
4
|
-
describe '
|
4
|
+
describe '.new' do
|
5
5
|
it 'throws an error on bad syntax' do
|
6
6
|
expect { MessageFormat.new({}) }.to raise_error
|
7
7
|
expect { MessageFormat.new('no finish arg {') }.to raise_error
|
@@ -109,6 +109,29 @@ describe MessageFormat do
|
|
109
109
|
end
|
110
110
|
end
|
111
111
|
|
112
|
+
describe '.formatMessage' do
|
113
|
+
it 'formats messages' do
|
114
|
+
pattern =
|
115
|
+
'On {takenDate, date, short} {name} {numPeople, plural, offset:1
|
116
|
+
=0 {didn\'t carpool.}
|
117
|
+
=1 {drove himself.}
|
118
|
+
other {drove # people.}}'
|
119
|
+
message = MessageFormat.format_message(pattern,
|
120
|
+
:takenDate => DateTime.now,
|
121
|
+
:name => 'Bob',
|
122
|
+
:numPeople => 5
|
123
|
+
)
|
124
|
+
expect(message).to match(/^On \d\d?\/\d\d?\/\d{2,4} Bob drove 4 people.$/)
|
125
|
+
|
126
|
+
message = MessageFormat::format_message(pattern,
|
127
|
+
:takenDate => DateTime.now,
|
128
|
+
:name => 'Bill',
|
129
|
+
:numPeople => 6
|
130
|
+
)
|
131
|
+
expect(message).to match(/^On \d\d?\/\d\d?\/\d{2,4} Bill drove 5 people.$/)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
112
135
|
describe 'locales' do
|
113
136
|
it 'doesn\'t throw for any locale\'s plural function' do
|
114
137
|
pattern =
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: message_format
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andy VanWagoner
|
@@ -62,6 +62,8 @@ extensions: []
|
|
62
62
|
extra_rdoc_files: []
|
63
63
|
files:
|
64
64
|
- ".gitignore"
|
65
|
+
- CHANGELOG.md
|
66
|
+
- CODE_OF_CONDUCT.md
|
65
67
|
- Gemfile
|
66
68
|
- LICENSE.txt
|
67
69
|
- README.md
|