What is messageformat-parser?
The messageformat-parser npm package is a tool for parsing ICU MessageFormat strings. It is used to handle internationalization (i18n) by parsing messages that can include variables, plurals, and select statements. This package is particularly useful for applications that need to support multiple languages and complex message formatting.
What are messageformat-parser's main functionalities?
Parsing Simple Messages
This feature allows you to parse simple messages with placeholders. The `parse` function takes a message string and returns an abstract syntax tree (AST) representing the structure of the message.
const { parse } = require('messageformat-parser');
const message = 'Hello, {name}!';
const parsed = parse(message);
console.log(JSON.stringify(parsed, null, 2));
Handling Plurals
This feature allows you to parse messages that include pluralization. The `parse` function can handle ICU MessageFormat plural syntax, making it easier to manage messages that need to change based on quantity.
const { parse } = require('messageformat-parser');
const message = '{count, plural, one {# item} other {# items}}';
const parsed = parse(message);
console.log(JSON.stringify(parsed, null, 2));
Handling Select Statements
This feature allows you to parse messages that include select statements. The `parse` function can handle ICU MessageFormat select syntax, which is useful for gender-specific or other conditional messages.
const { parse } = require('messageformat-parser');
const message = '{gender, select, male {He} female {She} other {They}} will respond soon.';
const parsed = parse(message);
console.log(JSON.stringify(parsed, null, 2));
Other packages similar to messageformat-parser
intl-messageformat
The intl-messageformat package provides similar functionality for parsing and formatting ICU MessageFormat strings. It also includes additional features for formatting dates, times, and numbers, making it a more comprehensive solution for internationalization.
format-message
The format-message package offers a similar capability to parse and format ICU MessageFormat strings. It also includes utilities for message extraction and translation, making it a good choice for projects that require a full i18n workflow.
messageformat
The messageformat package is another alternative that not only parses ICU MessageFormat strings but also compiles them into JavaScript functions for runtime evaluation. This can be useful for performance optimization in large applications.
messageformat-parser
A PEG.js parser for ICU MessageFormat strings – part of messageformat.
Outputs an AST defined by parser.pegjs.
The generated 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.
Installation
npm install messageformat-parser
Usage
> var parse = require('messageformat-parser').parse;
> parse('So {wow}.')
[ 'So ', { type: 'argument', arg: 'wow' }, '.' ]
> parse('Such { thing }. { count, selectordinal, one {First} two {Second}' +
' few {Third} other {#th} } word.')
[ 'Such ',
{ type: 'argument', arg: 'thing' },
'. ',
{ type: 'selectordinal',
arg: 'count',
offset: 0,
cases:
[ { key: 'one', tokens: [ 'First' ] },
{ key: 'two', tokens: [ 'Second' ] },
{ key: 'few', tokens: [ 'Third' ] },
{ key: 'other', tokens: [ { type: 'octothorpe' }, 'th' ] } ] },
' word.' ]
> parse('Many{type,select,plural{ numbers}selectordinal{ counting}' +
'select{ choices}other{ some {type}}}.')
[ 'Many',
{ type: 'select',
arg: 'type',
cases:
[ { key: 'plural', tokens: [ ' numbers' ] },
{ key: 'selectordinal', tokens: [ ' counting' ] },
{ key: 'select', tokens: [ ' choices' ] },
{ key: 'other', tokens: [ ' some',
{ type: 'argument', arg: 'type' } ] } ] },
'.' ]
> parse('{Such compliance')
> var msg = '{words, plural, zero{No words} one{One word} other{# words}}';
> var englishKeys = { cardinal: [ 'one', 'other' ],
ordinal: [ 'one', 'two', 'few', 'other' ] };
> parse(msg)
[ { type: 'plural',
arg: 'words',
offset: 0,
cases:
[ { key: 'zero', tokens: [ 'No words' ] },
{ key: 'one', tokens: [ 'One word' ] },
{ key: 'other', tokens: [ { type: 'octothorpe' }, ' words' ] } ] } ]
> parse(msg, englishKeys)
For more example usage, please take a look at our test suite.
Structure
The output of parse()
is a Token
array:
type Token = string | Argument | Plural | Select | Function
type Argument = {
type: 'argument',
arg: Identifier
}
type Plural = {
type: 'plural' | 'selectordinal',
arg: Identifier,
offset: number,
cases: PluralCase[]
}
type Select = {
type: 'select',
arg: Identifier,
cases: SelectCase[]
}
type Function = {
type: 'function',
arg: Identifier,
key: Identifier,
param: {
tokens: options.strict ? [string] : (Token | Octothorpe)[]
} | null
}
type PluralCase = {
key: 'zero' | 'one' | 'two' | 'few' | 'many' | 'other' | '=0' | '=1' | '=2' | ...,
tokens: (Token | Octothorpe)[]
}
type SelectCase = {
key: Identifier,
tokens: options.strict ? Token[] : (Token | Octothorpe)[]
}
type Octothorpe = {
type: 'octothorpe'
}
type Identifier = string
Messageformat is an OpenJS Foundation project, and we follow its Code of Conduct.