# `Cldr.Message`
[🔗](https://github.com/elixir-cldr/cldr_messages/blob/v2.0.1/lib/cldr/messages/messages.ex#L1)

Implements the [ICU Message Format](http://userguide.icu-project.org/formatparse/messages)
with functions to parse and interpolate messages.

Supports both ICU Message Format v1 and
[Message Format 2](https://unicode.org/reports/tr35/tr35-messageFormat.html).

Version detection is automatic: messages starting with `.` (`.input`,
`.local`, `.match`) or `{{` are treated as MF2; everything else is v1.
An explicit `:version` option (`:v1` or `:v2`) overrides detection.

# `arguments`

```elixir
@type arguments() :: bindings()
```

# `bindings`

```elixir
@type bindings() :: list() | map()
```

# `formatter_backend`

```elixir
@type formatter_backend() :: :default | :nif | :elixir
```

# `message`

```elixir
@type message() :: binary()
```

# `options`

```elixir
@type options() :: Keyword.t()
```

# `bindings`

```elixir
@spec bindings(String.t() | list() | map()) ::
  [String.t()] | {:error, {module(), String.t()}}
```

Extract the binding names from an ICU message.

## Arguments

* `message` is a CLDR message in binary or
  parsed form.

### Returns

* A list of binding names as strings or

* `{:error, {exception, reason}}`

### Examples

     iex> Cldr.Message.bindings "This {variable} is in the message"
     ["variable"]

# `canonical_message`

```elixir
@spec canonical_message(String.t(), Keyword.t()) ::
  {:ok, String.t()} | {:error, {module(), String.t()}}
```

Formats a message into a canonical form.

This allows for messages to be compared
directly, or using `Cldr.Message.jaro_distance/3`.

## Arguments

* `message` is a CLDR message in binary form.

* `options` is a keyword list of options. The
  default is `[]`.

## Options

* `:trim` determines if the message is trimmed
  of whitespace before formatting. The default is
  `true`.

* `:pretty` determines if the message if
  formatted with indentation to aid readability.
  The default is `false`.

## Returns

* `{ok, canonical_message}` where `canonical_message`
  is a string or

* `{:error, {exception, reason}}`

## Examples

    iex> Cldr.Message.canonical_message "{greeting } to you!"
    {:ok, "{greeting} to you!"}

# `canonical_message!`

```elixir
@spec canonical_message!(String.t(), Keyword.t()) :: String.t() | no_return()
```

Formats a message into a canonical form
or raises if the message cannot be parsed.

This allows for messages to be compared
directly, or using `Cldr.Message.jaro_distance/3`.

## Arguments

* `message` is a CLDR message in binary form.

* `options` is a keyword list of options. The
  default is `[]`.

## Options

* `:trim` determines if the message is trimmed
  of whitespace before formatting. The default is
  `true`.

* `:pretty` determines if the message if
  formatted with indentation to aid readability.
  The default is `false`.

## Returns

* `canonical_message` as a string or

* raises an exception

## Examples

    iex> Cldr.Message.canonical_message! "{greeting } to you!"
    "{greeting} to you!"

# `detect_version`

```elixir
@spec detect_version(String.t()) :: :v1 | :v2
```

Detects whether a message string is MF2 (`:v2`) or legacy ICU (`:v1`).

MF2 messages start with `.` (declarations/matcher) or `{{` (quoted pattern).

### Arguments

* `message` is an ICU message string.

### Returns

* `:v1` if the message is a legacy ICU Message Format string.

* `:v2` if the message is an MF2 message.

### Examples

    iex> Cldr.Message.detect_version("Hello {name}")
    :v1

    iex> Cldr.Message.detect_version("{{Hello, world!}}")
    :v2

    iex> Cldr.Message.detect_version(".input {$count :number}\n.match $count\n  1 {{one}}\n  * {{other}}")
    :v2

# `format`

```elixir
@spec format(String.t(), bindings(), options()) ::
  {:ok, String.t()} | {:error, {module(), String.t()}}
```

Format a message in the [ICU Message Format](https://unicode-org.github.io/icu/userguide/format_parse/messages)
into a string.

The ICU Message Format uses message `"pattern"` strings with
variable-element placeholders enclosed in {curly braces}. The
argument syntax can include formatting details, otherwise a
default format is used.

## Arguments

* `bindings` is a list or map of arguments that
  are used to replace placeholders in the message.

* `options` is a keyword list of options.

## Options

* `backend` is any `Cldr` backend. That is, any module that
  contains `use Cldr`.

* `:locale` is any valid locale name returned by `Cldr.known_locale_names/0`
  or a `t:Cldr.LanguageTag` struct.  The default is `Cldr.get_locale/0`.

* `:trim` determines if the message is trimmed
  of whitespace before formatting. The default is
  `false`.

* `:allow_positional_args` determines if position arguments
  are permitted. Positional arguments are in the format
  `{0}` in the message. The default is `true`.

* `:formatter_backend` determines which formatting engine to use
  for MF2 (v2) messages. Accepts `:default`, `:nif`, or `:elixir`.
  When set to `:default`, the ICU NIF is used if available, otherwise
  the pure-Elixir interpreter is used. When set to `:nif`, the NIF
  is required and a `RuntimeError` is raised if it is not available.
  When set to `:elixir`, the pure-Elixir interpreter is always used.
  The default is `:default`. This option has no effect on v1 messages.

* All other options are passed to the `to_string/2`
  function of a formatting module.

## Returns

* `{:ok, formatted_message}` or

* `{:error, {module, reason}}`

## Examples

    iex> Cldr.Message.format "{greeting} to you!", greeting: "Good morning"
    {:ok, "Good morning to you!"}

# `format!`

```elixir
@spec format!(String.t(), bindings(), options()) :: String.t() | no_return()
```

Formats a message and returns the result or raises on error.

Same as `format/3` but returns the formatted string directly
or raises an exception.

## Examples

    iex> Cldr.Message.format! "{greeting} to you!", greeting: "Good morning"
    "Good morning to you!"

    iex> Cldr.Message.format! "{{Hello, world!}}"
    "Hello, world!"

# `format_list`

# `format_list!`

# `format_to_iolist`

```elixir
@spec format_to_iolist(String.t(), bindings(), options()) ::
  {:ok, list(), list(), list()}
  | {:error, list(), list(), list()}
  | {:error, {module(), binary()}}
```

Format a message in the [ICU Message Format](https://unicode-org.github.io/icu/userguide/format_parse/messages)
into an iolist.

The ICU Message Format uses message `"pattern"` strings with
variable-element placeholders enclosed in {curly braces}. The
argument syntax can include formatting details, otherwise a
default format is used.

## Arguments

* `bindings` is a list or map of arguments that
  are used to replace placeholders in the message.

* `options` is a keyword list of options.

## Options

* `backend` is any `Cldr` backend. That is, any module that
  contains `use Cldr`.

* `:locale` is any valid locale name returned by `Cldr.known_locale_names/0`
  or a `t:Cldr.LanguageTag` struct.  The default is `Cldr.get_locale/0`.

* `:trim` determines if the message is trimmed
  of whitespace before formatting. The default is
  `false`.

* `:allow_positional_args` determines if position arguments
  are permitted. Positional arguments are in the format
  `{0}` in the message. The default is `true`.

* All other options are passed to the `to_string/2`
  function of a formatting module.

## Returns

* `{:ok, formatted_message}` or

* `{:error, {module, reason}}`

## Examples

    iex> Cldr.Message.format_to_iolist "{greeting} to you!", greeting: "Good morning"
    {:ok, ["Good morning", " to you!"], ["greeting"], []}

# `jaro_distance`

```elixir
@spec jaro_distance(String.t(), String.t(), Keyword.t()) ::
  {:ok, float()} | {:error, {module(), String.t()}}
```

Returns the [Jaro distance](https://en.wikipedia.org/wiki/Jaro–Winkler_distance)
between two messages.

This allows for fuzzy matching of message
which can be helpful when a message string
is changed but the semantics remain the same.

## Arguments

* `message1` is a CLDR message in binary form.

* `message2` is a CLDR message in binary form.

* `options` is a keyword list of options. The
  default is `[]`.

## Options

* `:trim` determines if the message is trimmed
  of whitespace before formatting. The default is
  `false`.

## Returns

* `{ok, distance}` where `distance` is a float value between 0.0
  (equates to no similarity) and 1.0 (is an
  exact match) representing Jaro distance between `message1`
  and `message2` or

* `{:error, {exception, reason}}`

## Examples

    iex> Cldr.Message.jaro_distance "{greetings} to you!", "{greeting} to you!"
    {:ok, 0.9824561403508771}

# `jaro_distance!`

```elixir
@spec jaro_distance!(String.t(), String.t(), Keyword.t()) :: float() | no_return()
```

Returns the [Jaro distance](https://en.wikipedia.org/wiki/Jaro–Winkler_distance)
between two messages or raises.

This allows for fuzzy matching of message
which can be helpful when a message string
is changed but the semantics remain the same.

## Arguments

* `message1` is a CLDR message in binary form.

* `message2` is a CLDR message in binary form.

* `options` is a keyword list of options. The
  default is `[]`.

## Options

* `:trim` determines if the message is trimmed
  of whitespace before formatting. The default is
  `false`.

## Returns

* `distance` where `distance` is a float value between 0.0
  (equates to no similarity) and 1.0 (is an
  exact match) representing Jaro distance between `message1`
  and `message2` or

* raises an exception

## Examples

    iex> Cldr.Message.jaro_distance! "{greetings} to you!", "{greeting} to you!"
    0.9824561403508771

# `t`
*macro* 

Returns the translation of the given ICU-formatted
message string.

Any placeholders are replaced with the value of variables
already in scope at the time of compilation.

`t/1` is a wrapper around the `gettext/2` macro
which should therefore be imported from a `Gettext`
backend prior to calling `t/1`.

## Arguments

* `message` is an ICU format message string.

## Returns

* A translated string.

## Examples

    import MyApp.Gettext
    Cldr.Message.t("{greeting} to you!")

# `t`
*macro* 

Returns the translation of the given ICU-formatted
message string.

`t/2` is a wrapper around the `gettext/2` macro
which should therefore be imported from a `Gettext`
backend prior to calling `t/2`.

## Arguments

* `message` is an ICU format message string.

* `bindings` is a keyword list or map of bindings used
  to replace placeholders in the message.

## Returns

* A translated string.

## Examples

    import MyApp.Gettext
    Cldr.Message.t("{greeting} to you!", greeting: "Good morning")

---

*Consult [api-reference.md](api-reference.md) for complete listing*
