What is @messageformat/parser?
@messageformat/parser is a library for parsing ICU MessageFormat strings. It allows developers to handle complex internationalization (i18n) scenarios by parsing and formatting messages with pluralization, gender, and other language-specific rules.
What are @messageformat/parser's main functionalities?
Parsing MessageFormat strings
This feature allows you to parse a MessageFormat string into an abstract syntax tree (AST). The example demonstrates parsing a message that handles pluralization based on the count.
const { parse } = require('@messageformat/parser');
const message = 'You have {count, plural, one {# message} other {# messages}}.';
const parsed = parse(message);
console.log(JSON.stringify(parsed, null, 2));
Handling nested messages
This feature allows you to parse messages with nested structures, such as gender-based selection combined with pluralization. The example demonstrates parsing a message that handles both gender and pluralization.
const { parse } = require('@messageformat/parser');
const message = '{gender, select, male {He} female {She} other {They}} liked {count, plural, one {# message} other {# messages}}.';
const parsed = parse(message);
console.log(JSON.stringify(parsed, null, 2));
Custom formatting
This feature allows you to parse messages with custom formatting options, such as currency formatting. The example demonstrates parsing a message that formats a number as a currency.
const { parse } = require('@messageformat/parser');
const message = 'The price is {price, number, ::currency/USD}.';
const parsed = parse(message);
console.log(JSON.stringify(parsed, null, 2));
Other packages similar to @messageformat/parser
intl-messageformat
intl-messageformat is a library for formatting ICU MessageFormat strings. It provides similar functionality to @messageformat/parser but includes additional features for formatting messages directly, without the need for a separate parser.
messageformat
messageformat is a comprehensive library for handling ICU MessageFormat strings. It includes both parsing and formatting capabilities, making it a more complete solution compared to @messageformat/parser, which focuses solely on parsing.
fluent
fluent is a localization library developed by Mozilla. It offers a different approach to internationalization compared to ICU MessageFormat, focusing on natural language syntax and flexibility. While it serves a similar purpose, its syntax and usage differ significantly from @messageformat/parser.
@messageformat/parser
An AST parser for ICU MessageFormat strings – part of messageformat.
The parse(src, [options])
function takes two parameters, first the
string to be parsed, and a second optional parameter options
, an object with
the following possible keys:
-
cardinal
and ordinal
– Arrays of valid plural categories for the current
locale, used to validate plural
and selectordinal
keys. If these are
missing or set to false, the full set of valid Unicode CLDR keys is used:
'zero', 'one', 'two', 'few', 'many', 'other'
. To disable this check, pass in
an empty array.
-
strict
– By default, the parsing applies a few relaxations to the ICU
MessageFormat spec. Setting strict: true
will disable these relaxations:
- The
argType
of simpleArg
formatting functions will be restricted to the
set of number
, date
, time
, spellout
, ordinal
, and duration
,
rather than accepting any lower-case identifier that does not start with a
number. - The optional
argStyle
of simpleArg
formatting functions will not be
parsed as any other text, but instead as the spec requires: "In
argStyleText, every single ASCII apostrophe begins and ends quoted literal
text, and unquoted {curly braces} must occur in matched pairs." - Inside a
plural
or selectordinal
statement, a pound symbol (#
) is
replaced with the input number. By default, #
is also parsed as a special
character in nested statements too, and can be escaped using apostrophes
('#'
). In strict mode #
will be parsed as a special character only
directly inside a plural
or selectordinal
statement. Outside those, #
and '#'
will be parsed as literal text.
The parser only supports the default DOUBLE_OPTIONAL
apostrophe mode, in
which a single apostrophe only starts quoted literal text if it immediately
precedes a curly brace {}
, or a pound symbol #
if inside a plural format. A
literal apostrophe '
is represented by either a single '
or a doubled ''
apostrophe character.
This package was previously named messageformat-parser.
Installation
npm install @messageformat/parser
Usage
> const { parse } = require('@messageformat/parser')
> parse('So {wow}.')
[ { type: 'content', value: 'So ' },
{ type: 'argument', arg: 'wow' },
{ type: 'content', value: '.' } ]
> parse('Such { thing }. { count, selectordinal, one {First} two {Second}' +
' few {Third} other {#th} } word.')
[ { type: 'content', value: 'Such ' },
{ type: 'argument', arg: 'thing' },
{ type: 'content', value: '. ' },
{ type: 'selectordinal',
arg: 'count',
cases: [
{ key: 'one', tokens: [ { type: 'content', value: 'First' } ] },
{ key: 'two', tokens: [ { type: 'content', value: 'Second' } ] },
{ key: 'few', tokens: [ { type: 'content', value: 'Third' } ] },
{ key: 'other',
tokens: [ { type: 'octothorpe' }, { type: 'content', value: 'th' } ] }
] },
{ type: 'content', value: ' word.' } ]
> parse('Many{type,select,plural{ numbers}selectordinal{ counting}' +
'select{ choices}other{ some {type}}}.')
[ { type: 'content', value: 'Many' },
{ type: 'select',
arg: 'type',
cases: [
{ key: 'plural', tokens: [ { type: 'content', value: 'numbers' } ] },
{ key: 'selectordinal', tokens: [ { type: 'content', value: 'counting' } ] },
{ key: 'select', tokens: [ { type: 'content', value: 'choices' } ] },
{ key: 'other',
tokens: [ { type: 'content', value: 'some ' }, { type: 'argument', arg: 'type' } ] }
] },
{ type: 'content', value: '.' } ]
> parse('{Such compliance')
> const msg = '{words, plural, zero{No words} one{One word} other{# words}}'
> parse(msg)
[ { type: 'plural',
arg: 'words',
cases: [
{ key: 'zero', tokens: [ { type: 'content', value: 'No words' } ] },
{ key: 'one', tokens: [ { type: 'content', value: 'One word' } ] },
{ key: 'other',
tokens: [ { type: 'octothorpe' }, { type: 'content', value: ' words' } ] }
] } ]
> parse(msg, { cardinal: [ 'one', 'other' ], ordinal: [ 'one', 'two', 'few', 'other' ] })
For more example usage, please take a look at our test suite.
Structure
The output of parse()
is an array of tokens, Array<Content | PlainArg | FunctionArg | Select>
:
interface Content {
type: 'content'
value: string
ctx: Context
}
interface PlainArg {
type: 'argument'
arg: string
ctx: Context
}
interface FunctionArg {
type: 'function'
arg: string
key: string
param?: Array<Content | PlainArg | FunctionArg | Select | Octothorpe>
ctx: Context
}
interface Select {
type: 'plural' | 'select' | 'selectordinal'
arg: string
cases: Array<SelectCase>
pluralOffset?: number
ctx: Context
}
interface SelectCase {
key: string
tokens: Array<Content | PlainArg | FunctionArg | Select | Octothorpe>
ctx: Context
}
interface Octothorpe {
type: 'octothorpe'
ctx: Context
}
interface Context {
offset: number
line: number
col: number
text: string
lineBreaks: number
}
Messageformat is an OpenJS Foundation project, and we follow its Code of Conduct.