Formats ICU MessageFormat 1 messages with Localize.
ICU MessageFormat 1 (MF1) is the message syntax of ICU4J and ICU4C, of
translation management systems such as Crowdin, and of ex_cldr_messages: arguments ({name}), formatted arguments ({count, number}) and the
plural, select and selectordinal selectors. Localize itself formats
MessageFormat 2 (Localize.Message); this library formats MF1 messages with
Localize's locales, plural rules and formatters, so that applications can
keep existing MF1 translations.
The API follows Cldr.Message from ex_cldr_messages:
format/3,format!/3andformat_to_iolist/3format a message with its bindings. An MF2 message given toformat/3orformat!/3is formatted byLocalize.Message, asCldr.Messagedid.format_list/3formats a message already parsed byLocalize.Message.MF1.Parser.parse/2.bindings/1lists the arguments a message uses.canonical_message/2andjaro_distance/3give a message's canonical form, for use as a Gettext message id, and compare two messages. The~Msigil ofLocalize.Message.MF1.Sigilscanonicalizes a message at compile time.
Arguments and bindings
Bindings are a keyword list or map, keyed by atom or string, for named
arguments such as {name}, or a list of values for positional arguments
such as {0}. A number binding may be a {number, options} tuple whose
options are given to Localize.Number.to_string/2.
Formatted arguments
| Argument | Formatted with |
|---|---|
{n} | Localize.Chars.to_string/2 |
{n, number}, {n, number, integer} (and currency, percent, permille, short, long) | Localize.Number.to_string/2 |
{n, number, ordinal} | the digits_ordinal rule ("1st") |
{n, spellout} (and verbose, year, ordinal) | Localize.Number.Rbnf.to_string/3 |
{d, date}, {t, time}, {dt, datetime} (and short to full, or a pattern) | Localize.Date, Localize.Time and Localize.DateTime |
{u, unit} (and short, long, narrow) | Localize.Unit.to_string/2 |
{l, list} (and or, unit and the other list styles) | Localize.List.to_string/2 |
{m, money} (and short, long) | Money.to_string/2, when ex_money is a dependency |
A :name style, as in {n, number, :spellout_ordinal}, is a format
configured with the :formats option or the :formats key of the
:localize_mf1 application environment, or else an RBNF rule or a number
format of that name. Number and date skeletons (::…) are not supported.
Summary
Types
Bindings for a message's arguments.
Functions
Returns the names (and positions) of the arguments a message uses.
Returns a message in canonical form.
Returns a message in canonical form, raising on error.
Formats a MessageFormat 1 message.
Formats a MessageFormat 1 message, raising on error.
Formats a message parsed by Localize.Message.MF1.Parser.parse/2 to an
iolist.
Formats a MessageFormat 1 message to an iolist, with the arguments that were and were not bound.
Returns the Jaro distance between the canonical forms of two messages.
Returns the Jaro distance between two messages, raising on error.
Returns whether a message is written in MessageFormat 2 rather than MessageFormat 1.
Types
Functions
@spec bindings(String.t() | Localize.Message.MF1.Parser.t()) :: [String.t() | non_neg_integer()] | {:error, Exception.t()}
Returns the names (and positions) of the arguments a message uses.
Arguments
messageis a MessageFormat 1 message string, or a message parsed byLocalize.Message.MF1.Parser.parse/2.
Returns
A list of argument names (strings) and positions (integers), in the order
Cldr.Message.bindings/1gave them, or{:error, exception}when the message cannot be parsed.
Examples
iex> Localize.Message.MF1.bindings("This {variable} is in the message")
["variable"]
@spec canonical_message(String.t(), Keyword.t()) :: {:ok, String.t()} | {:error, Exception.t()}
Returns a message in canonical form.
Messages that differ only in layout white space and quoting have the same
canonical form, so it can be used as a Gettext message id. The form is
that of Cldr.Message.canonical_message/2, so existing msgids carry over.
Arguments
messageis a message string. A MessageFormat 2 message (seemf2?/1) is given toLocalize.Message.canonical_message/2.optionsis a keyword list of options.
Options
:trimistrue(the default) to trim white space from the message first, orfalse.:prettyistrueto put each selector clause on a line of its own, indented, orfalse(the default).
Returns
{:ok, canonical_message}, or{:error, exception}when the message cannot be parsed or is not a string.
Examples
iex> Localize.Message.MF1.canonical_message("{greeting } to you!")
{:ok, "{greeting} to you!"}
iex> Localize.Message.MF1.canonical_message("{n, plural, other {# items} one {# item}}")
{:ok, "{n, plural, one {# item} other {# items}}"}
Returns a message in canonical form, raising on error.
Arguments
messageis a message string.optionsis a keyword list of options.
Options
- See
canonical_message/2.
Returns
- The canonical message. An exception is raised when the message cannot be parsed.
Examples
iex> Localize.Message.MF1.canonical_message!("{greeting } to you!")
"{greeting} to you!"
@spec format(String.t(), bindings(), Keyword.t()) :: {:ok, String.t()} | {:error, Exception.t()}
Formats a MessageFormat 1 message.
Arguments
messageis a MessageFormat 1 message string. A MessageFormat 2 message (seemf2?/1) is formatted byLocalize.Message.format/3.bindingsis a keyword list or map of named arguments, or a list of positional arguments. The default is[].optionsis a keyword list of options.
Options
:localeis a locale identifier or aLocalize.LanguageTag.t/0. The default isLocalize.get_locale/0.:trimistrueto trim white space from the message before it is formatted. The default isfalse.:allow_positional_argsisfalseto return an error for a message with positional arguments. The default istrue.:formatsis a map or keyword list of named formats, each a keyword list of formatter options, used by:namestyles.Any other option is given to every formatter, as in
ex_cldr_messages; for examplecurrency: :EURfor{price, number, currency}.
Returns
{:ok, formatted_message}, or{:error, %Localize.BindError{}}when an argument has no binding, or{:error, exception}when the message cannot be parsed or a value cannot be formatted.
Examples
iex> Localize.Message.MF1.format("{greeting} to you!", greeting: "Good morning")
{:ok, "Good morning to you!"}
iex> Localize.Message.MF1.format("{count, plural, one {# item} other {# items}}", count: 3)
{:ok, "3 items"}
Formats a MessageFormat 1 message, raising on error.
Arguments
messageis a message string, as forformat/3.bindingsis a keyword list, map or list of bindings.optionsis a keyword list of options.
Options
- See
format/3.
Returns
- The formatted message. An exception is raised when the message cannot be formatted.
Examples
iex> Localize.Message.MF1.format!("{greeting} to you!", greeting: "Good morning")
"Good morning to you!"
iex> Localize.Message.MF1.format!("{{Hello, world!}}")
"Hello, world!"
@spec format_list(Localize.Message.MF1.Parser.t(), bindings(), Keyword.t()) :: {:ok, list(), list(), list()} | {:error, list(), list(), list()} | {:error, Exception.t()}
Formats a message parsed by Localize.Message.MF1.Parser.parse/2 to an
iolist.
Arguments
parsedis a parsed message.bindingsis a keyword list, map or list of bindings.optionsis a keyword list of options.
Options
- See
format/3.:trimand:allow_positional_argsapply only when parsing, so they have no effect here.
Returns
- As for
format_to_iolist/3.
Examples
iex> {:ok, parsed} = Localize.Message.MF1.Parser.parse("{count, number} jelly beans")
iex> Localize.Message.MF1.format_list(parsed, [count: 1234], locale: :de)
{:ok, ["1.234", " jelly beans"], ["count"], []}
@spec format_to_iolist(String.t(), bindings(), Keyword.t()) :: {:ok, list(), list(), list()} | {:error, list(), list(), list()} | {:error, Exception.t()}
Formats a MessageFormat 1 message to an iolist, with the arguments that were and were not bound.
Arguments
messageis a MessageFormat 1 message string.bindingsis a keyword list, map or list of bindings.optionsis a keyword list of options.
Options
- See
format/3.
Returns
{:ok, iolist, bound, []}whereboundlists the arguments used, or{:error, iolist, bound, unbound}when arguments inunboundhave no binding; each is written intoiolistas its source text, such as{name}, or{:error, exception}when the message cannot be parsed or a value cannot be formatted.
Examples
iex> Localize.Message.MF1.format_to_iolist("{greeting} to you!", greeting: "Good morning")
{:ok, ["Good morning", " to you!"], ["greeting"], []}
@spec jaro_distance(String.t(), String.t(), Keyword.t()) :: {:ok, float()} | {:error, Exception.t()}
Returns the Jaro distance between the canonical forms of two messages.
It finds a message that changed only a little, such as a translation key edited for readability.
Arguments
message1andmessage2are MessageFormat 1 message strings.optionsis a keyword list of options.
Options
:trimistrueto trim white space from the messages first, orfalse(the default).
Returns
{:ok, distance}wheredistanceis a float from0.0(no similarity) to1.0(the same canonical message), or{:error, exception}when either message cannot be parsed.
Examples
iex> Localize.Message.MF1.jaro_distance("{greetings} to you!", "{greeting} to you!")
{:ok, 0.9824561403508771}
Returns the Jaro distance between two messages, raising on error.
Arguments
message1andmessage2are MessageFormat 1 message strings.optionsis a keyword list of options.
Options
- See
jaro_distance/3.
Returns
- A float from
0.0to1.0. An exception is raised when either message cannot be parsed.
Examples
iex> Localize.Message.MF1.jaro_distance!("{greetings} to you!", "{greeting} to you!")
0.9824561403508771
Returns whether a message is written in MessageFormat 2 rather than MessageFormat 1.
An MF2 message starts with a declaration or matcher (.input, .local,
.match) or a quoted pattern ({{); any other message is read as MF1.
Arguments
messageis a message string.
Returns
truewhenmessageis an MF2 message, orfalseotherwise, including whenmessageis not a string.
Examples
iex> Localize.Message.MF1.mf2?("Hello {name}")
false
iex> Localize.Message.MF1.mf2?("{{Hello {$name}}}")
true