1. @messageformat/parser
An AST parser for ICU MessageFormat strings
@messageformat/parser
Package: @messageformat/parser
Created by: messageformat
Last modified: Thu, 08 Jun 2023 14:21:16 GMT
Version: 5.1.0
License: MIT
Downloads: 2,024,501
Repository: https://github.com/messageformat/messageformat

Install

npm install @messageformat/parser
yarn add @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')
// For clarity, the examples below do not show the ctx object included for each token

> 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')
// ParseError: invalid syntax at line 1 col 7:
//
//  {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' ] })
// ParseError: The plural case zero is not valid in this locale at line 1 col 17:
//
//   {words, plural, zero{
//                   ^

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.

OpenJS Foundation

Dependencies

RELATED POST

10 Must-Know Windows Shortcuts That Will Save You Time

10 Must-Know Windows Shortcuts That Will Save You Time

Arrays vs Linked Lists: Which is Better for Memory Management in Data Structures?

Arrays vs Linked Lists: Which is Better for Memory Management in Data Structures?

Navigating AWS Networking: Essential Hacks for Smooth Operation

Navigating AWS Networking: Essential Hacks for Smooth Operation

Achieving Stunning Visuals with Unity's Global Illumination

Achieving Stunning Visuals with Unity's Global Illumination

Nim's Hidden Gems: Lesser-known Features for Writing Efficient Code

Nim's Hidden Gems: Lesser-known Features for Writing Efficient Code