Skip to content
This repository was archived by the owner on Dec 17, 2018. It is now read-only.

Commit 2b9b637

Browse files
committed
[#1] Replace function params with single param, drop strictFunctionParams option
1 parent 87783f3 commit 2b9b637

File tree

3 files changed

+24
-70
lines changed

3 files changed

+24
-70
lines changed

README.md

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,6 @@ the following possible keys:
1313
`'zero', 'one', 'two', 'few', 'many', 'other'`. To disable this check, pass in
1414
an empty array.
1515

16-
- `strictFunctionParams` – By default, function parameters are split on commas
17-
and trimmed, so the parameters in `{x,fn, a, b }` are parsed as
18-
`['a','b']`. Setting `strictFunctionParams` to true will make the parser
19-
follow the ICU MessageFormat spec more closely, and result in a params array
20-
with a single element: `[' a, b ']`.
21-
2216
- `strictNumberSign` – Inside a `plural` or `selectordinal` statement, a pound
2317
symbol (`#`) is replaced with the input number. By default, `#` is also parsed
2418
as a special character in nested statements too, and can be escaped using
@@ -136,7 +130,7 @@ type Function = {
136130
type: 'function',
137131
arg: Identifier,
138132
key: Identifier,
139-
params: string[]
133+
param: string | null
140134
}
141135

142136
type PluralCase = {

parser.pegjs

Lines changed: 7 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
{
22
var inPlural = false;
3-
var whitespaceChars = "[\u0009-\u000d \u0085\u200e\u200f\u2028\u2029]*";
4-
var whitespaceTrimRE = new RegExp("^" + whitespaceChars + "|" + whitespaceChars + "$", "g");
53
}
64

75
start = token*
@@ -44,22 +42,18 @@ plural = '{' _ arg:id _ ',' _ type:(m:('plural'/'selectordinal') { inPlural = tr
4442
};
4543
}
4644

47-
function = '{' _ arg:id _ ',' _ key:(m:id { if (options.strictNumberSign) { inPlural = false; } return m; }) _ params:functionParams '}' {
45+
function = '{' _ arg:id _ ',' _ key:(m:id { if (options.strictNumberSign) { inPlural = false; } return m; }) _ param:functionParam? '}' {
4846
return {
4947
type: 'function',
5048
arg: arg,
5149
key: key,
52-
params: params
50+
param: param
5351
};
5452
}
5553

5654
// not Pattern_Syntax or Pattern_White_Space
5755
id = $([^\u0009-\u000d \u0085\u200e\u200f\u2028\u2029\u0021-\u002f\u003a-\u0040\u005b-\u005e\u0060\u007b-\u007e\u00a1-\u00a7\u00a9\u00ab\u00ac\u00ae\u00b0\u00b1\u00b6\u00bb\u00bf\u00d7\u00f7\u2010-\u2027\u2030-\u203e\u2041-\u2053\u2055-\u205e\u2190-\u245f\u2500-\u2775\u2794-\u2bff\u2e00-\u2e7f\u3001-\u3003\u3008-\u3020\u3030\ufd3e\ufd3f\ufe45\ufe46]+)
5856

59-
paramDefault = str:paramcharsDefault+ { return str.join(''); }
60-
61-
paramStrict = str:paramcharsStrict+ { return str.join(''); }
62-
6357
selectCase = _ key:id _ tokens:caseTokens { return { key: key, tokens: tokens }; }
6458

6559
pluralCase = _ key:pluralKey _ tokens:caseTokens { return { key: key, tokens: tokens }; }
@@ -72,13 +66,12 @@ pluralKey
7266
= id
7367
/ '=' d:digits { return d; }
7468

75-
functionParams
76-
= p:functionParamsDefault* ! { return options.strictFunctionParams; } { return p; }
77-
/ p:functionParamsStrict* & { return options.strictFunctionParams; } { return p; }
78-
79-
functionParamsStrict = _ ',' p:paramStrict { return p; }
69+
functionParam = _ ',' str:paramChars+ { return str.join(''); }
8070

81-
functionParamsDefault = _ ',' _ p:paramDefault _ { return p.replace(whitespaceTrimRE, ''); }
71+
paramChars
72+
= doubleapos
73+
/ quotedCurly
74+
/ [^}]
8275

8376
doubleapos = "''" { return "'"; }
8477

@@ -93,28 +86,12 @@ quoted
9386
/ quotedOcto:(("'#"str:inapos*"'" { return "#"+str.join(''); }) & { return inPlural; }) { return quotedOcto[0]; }
9487
/ "'"
9588

96-
quotedFunctionParams
97-
= quotedCurly
98-
/ "'"
99-
10089
char
10190
= doubleapos
10291
/ quoted
10392
/ octo:'#' & { return !inPlural; } { return octo; }
10493
/ [^{}#\0-\x08\x0e-\x1f\x7f]
10594

106-
paramcharsCommon
107-
= doubleapos
108-
/ quotedFunctionParams
109-
110-
paramcharsDefault
111-
= paramcharsCommon
112-
/ str:[^',}]+ { return str.join(''); }
113-
114-
paramcharsStrict
115-
= paramcharsCommon
116-
/ str:[^'}]+ { return str.join(''); }
117-
11895
digits = $([0-9]+)
11996

12097
// Pattern_White_Space

test.js

Lines changed: 16 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ describe("Plurals", function() {
234234
expect(parse("{NUM, plural, one{{x,date,y-M-dd # '#'}} two{two}}")[0].cases[0].tokens[0].arg).to.eql('x');
235235
expect(parse("{NUM, plural, one{{x,date,y-M-dd # '#'}} two{two}}")[0].cases[0].tokens[0].key).to.eql('date');
236236
// Octothorpe is not special here regardless of strict number sign
237-
expect(parse("{NUM, plural, one{{x,date,y-M-dd # '#'}} two{two}}")[0].cases[0].tokens[0].params[0]).to.eql("y-M-dd # '#'");
237+
expect(parse("{NUM, plural, one{{x,date,y-M-dd # '#'}} two{two}}")[0].cases[0].tokens[0].param).to.eql("y-M-dd # '#'");
238238

239239
expect(parse("{NUM, plural, one{# '' #} two{two}}")[0].cases[0].tokens[0].type).to.eql('octothorpe');
240240
expect(parse("{NUM, plural, one{# '' #} two{two}}")[0].cases[0].tokens[1]).to.eql(" ' ");
@@ -280,55 +280,38 @@ describe("Functions", function() {
280280
it("should accept no parameters", function() {
281281
expect(parse('{var,date}')[0].type).to.eql('function');
282282
expect(parse('{var,date}')[0].key).to.eql('date');
283-
expect(parse('{var,date}')[0].params).to.be.empty;
283+
expect(parse('{var,date}')[0].param).to.be.null;
284284
})
285285

286286
it("should accept parameters", function() {
287287
expect(parse('{var,date,long}')[0].type).to.eql('function');
288288
expect(parse('{var,date,long}')[0].key).to.eql('date');
289-
expect(parse('{var,date,long}')[0].params[0]).to.eql('long');
290-
expect(parse('{var,date,long,short}')[0].params[0]).to.eql('long');
291-
expect(parse('{var,date,long,short}')[0].params[1]).to.eql('short');
289+
expect(parse('{var,date,long}')[0].param).to.eql('long');
290+
expect(parse('{var,date,long,short}')[0].param).to.eql('long,short');
292291
})
293292

294293
it("should accept parameters with whitespace", function() {
295294
expect(parse('{var,date,y-M-d HH:mm:ss zzzz}')[0].type).to.eql('function');
296295
expect(parse('{var,date,y-M-d HH:mm:ss zzzz}')[0].key).to.eql('date');
297-
expect(parse('{var,date,y-M-d HH:mm:ss zzzz}')[0].params[0]).to.eql('y-M-d HH:mm:ss zzzz');
298-
// This is not how ICU works. ICU does not trim whitespace,
299-
// but messageformat-parse must trim it to maintain backwards compatibility.
300-
expect(parse('{var,date, y-M-d HH:mm:ss zzzz }')[0].params[0]).to.eql('y-M-d HH:mm:ss zzzz');
301-
// This is how ICU works.
302-
expect(parse('{var,date, y-M-d HH:mm:ss zzzz }', { strictFunctionParams: true })[0].params[0]).to.eql(' y-M-d HH:mm:ss zzzz ');
296+
expect(parse('{var,date,y-M-d HH:mm:ss zzzz}')[0].param).to.eql('y-M-d HH:mm:ss zzzz');
297+
expect(parse('{var,date, y-M-d HH:mm:ss zzzz }')[0].param).to.eql(' y-M-d HH:mm:ss zzzz ');
303298
})
304299

305300
it("should accept parameters with special characters", function() {
306301
expect(parse("{var,date,y-M-d '{,}' '' HH:mm:ss zzzz}")[0].type).to.eql('function');
307302
expect(parse("{var,date,y-M-d '{,}' '' HH:mm:ss zzzz}")[0].key).to.eql('date');
308-
expect(parse("{var,date,y-M-d '{,}' '' HH:mm:ss zzzz}")[0].params[0]).to.eql("y-M-d {,} ' HH:mm:ss zzzz");
309-
expect(parse("{var,date,y-M-d '{,}' '' HH:mm:ss zzzz'}'}")[0].params[0]).to.eql("y-M-d {,} ' HH:mm:ss zzzz}");
310-
expect(parse("{var,date,y-M-d # HH:mm:ss zzzz}")[0].params[0]).to.eql("y-M-d # HH:mm:ss zzzz");
311-
expect(parse("{var,date,y-M-d '#' HH:mm:ss zzzz}")[0].params[0]).to.eql("y-M-d '#' HH:mm:ss zzzz");
312-
// This is not how ICU works.
313-
expect(parse("{var,date,y-M-d, HH:mm:ss zzzz}")[0].params[0]).to.eql("y-M-d");
314-
expect(parse("{var,date,y-M-d, HH:mm:ss zzzz}")[0].params[1]).to.eql("HH:mm:ss zzzz");
315-
// This is how ICU works, but this only allows a single argStyle parameter.
316-
expect(parse("{var,date,y-M-d, HH:mm:ss zzzz}", { strictFunctionParams: true })[0].params[0]).to.eql("y-M-d, HH:mm:ss zzzz");
303+
expect(parse("{var,date,y-M-d '{,}' '' HH:mm:ss zzzz}")[0].param).to.eql("y-M-d {,} ' HH:mm:ss zzzz");
304+
expect(parse("{var,date,y-M-d '{,}' '' HH:mm:ss zzzz'}'}")[0].param).to.eql("y-M-d {,} ' HH:mm:ss zzzz}");
305+
expect(parse("{var,date,y-M-d # HH:mm:ss zzzz}")[0].param).to.eql("y-M-d # HH:mm:ss zzzz");
306+
expect(parse("{var,date,y-M-d '#' HH:mm:ss zzzz}")[0].param).to.eql("y-M-d '#' HH:mm:ss zzzz");
307+
expect(parse("{var,date,y-M-d, HH:mm:ss zzzz}")[0].param).to.eql("y-M-d, HH:mm:ss zzzz");
317308
})
318309

319-
it("should be gracious with whitespace", function() {
320-
var firstRes = JSON.stringify(parse('{var, date, long, short}'));
321-
expect(JSON.stringify(parse('{ var, date, long, short }'))).to.eql(firstRes);
322-
expect(JSON.stringify(parse('{var,date,long,short}'))).to.eql(firstRes);
323-
expect(JSON.stringify(parse('{\nvar, \ndate,\n long\n\n,\n short\n\n\n}'))).to.eql(firstRes);
324-
expect(JSON.stringify(parse('{\tvar\t,\t\t\r date\t\n, \tlong\n, short\t\n\n\n\n}'))).to.eql(firstRes);
325-
326-
// This is not how ICU works. ICU does not trim whitespace.
327-
firstRes = JSON.stringify(parse('{var, date, y-M-d HH:mm:ss zzzz}'));
328-
expect(JSON.stringify(parse('{ var, date, y-M-d HH:mm:ss zzzz }'))).to.eql(firstRes);
329-
expect(JSON.stringify(parse('{var,date,y-M-d HH:mm:ss zzzz}'))).to.eql(firstRes);
330-
expect(JSON.stringify(parse('{\nvar, \ndate,\n \n\n\n y-M-d HH:mm:ss zzzz\n\n\n}'))).to.eql(firstRes);
331-
expect(JSON.stringify(parse('{\tvar\t,\t\t\r date\t\n, \t\ny-M-d HH:mm:ss zzzz\t\n\n\n\n}'))).to.eql(firstRes);
310+
it("should be gracious with whitespace around arg and key", function() {
311+
var firstRes = JSON.stringify(parse('{var, date}'));
312+
expect(JSON.stringify(parse('{ var, date }'))).to.eql(firstRes);
313+
expect(JSON.stringify(parse('{var,date}'))).to.eql(firstRes);
314+
expect(JSON.stringify(parse('{\nvar, \ndate\n}'))).to.eql(firstRes);
332315
});
333316
});
334317
describe("Nested/Recursive blocks", function() {

0 commit comments

Comments
 (0)