Cldr_Messages v2.0.0

This is the changelog for Cldr_Messages v2.0.0. For older changelogs please consult the release tag on GitHub

Enhancements

  • Add full support for Unicode MessageFormat 2 (MF2) alongside the existing legacy ICU Message Format (v1).

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

  • Add a pure-Elixir MF2 parser (Cldr.Message.V2.Parser) built on NimbleParsec with full MF2 ABNF compliance.

  • Add a pure-Elixir MF2 interpreter (Cldr.Message.V2.Interpreter) supporting:

    • Variable substitution with $name syntax
    • Declarations (.input, .local)
    • Pattern matching with .match and variant selection
    • Built-in formatting functions: :string, :number, :integer, :percent, :currency, :date, :time, :datetime, :unit
    • Markup elements (open, close, standalone)
    • Literal and number literal expressions
  • Add an MF2 canonical format printer (Cldr.Message.V2.Print) for round-tripping AST back to string. Cldr.Message.canonical_message/2 now auto-detects and handles both v1 and v2 messages.

  • Add Unicode NFC normalization for variable names, literal values, and binding map keys per the MF2 specification, ensuring that pre-composed and decomposed Unicode characters are treated as equivalent.

  • Add an optional ICU4C NIF backend (Cldr.Message.V2.Nif) for MF2 formatting. Requires ICU 75+ and is enabled with CLDR_MESSAGES_MF2_NIF=true. The :formatter_backend option on Cldr.Message.format/3 controls NIF vs Elixir dispatch (:default, :nif, or :elixir).

  • Add Cldr.Gettext.Interpolation.V2 — a Gettext interpolation module that supports both v1 and v2 messages in the same .POT files. Messages are compiled as V2 first with V1 fallback.

  • Add Cldr.Message.detect_version/1 to programmatically detect whether a message string is v1 or v2.

Bug Fixes

  • Fix V1 pretty-printer whitespace duplication when a literal with trailing whitespace precedes a nested select, plural, or select_ordinal structure.

  • Preserve leading whitespace in MF2 simple messages per the MF2 specification. Leading whitespace is significant message content, not syntactic whitespace.

Known Limitations

  • Unbound variables return {:error, {Cldr.Message.BindError, reason}} (unlike ICU which produces a {$name} fallback string).

  • The MF2 :string function is a pass-through in the Elixir interpreter. The ICU NIF provides the full ICU :string implementation.

Cldr_Messages v1.0.4

This is the changelog for Cldr_Messages v1.0.4 released on March 18th, 2026. For older changelogs please consult the release tag on GitHub

Bug Fixes

  • Fix compiler warnings for Elixir 1.20.

  • Fix Gettext dependency configuration to allow "~> 0.26 or ~> 1.0".

Cldr_Messages v1.0.3

This is the changelog for Cldr_Messages v1.0.3 released on January 10th, 2025. For older changelogs please consult the release tag on GitHub

Bug Fixes

  • Update documentation, code and tests to reflect the Gettext API as of version 0.20.

Cldr_Messages v1.0.2

This is the changelog for Cldr_Messages v1.0.2 released on December 20th, 2023. For older changelogs please consult the release tag on GitHub

Bug Fixes

  • Restore ex_cldr_numbers as a required dependency. Thanks to @flurin for the report. Closes #18.

Cldr_Messages v1.0.1

This is the changelog for Cldr_Messages v1.0.1 released on October 21st, 2023. For older changelogs please consult the release tag on GitHub

Bug Fixes

Cldr_Messages v1.0.0

This is the changelog for Cldr_Messages v1.0.0 released on October 5th, 2023. For older changelogs please consult the release tag on GitHub

Since the API is stable, this becomes the 1.0 release.

Bug Fixes

  • Fix Cldr.Message.Print.to_string/2 to force a deterministic order of choices.

  • Fix extracting variable bindings from simple_format. Thanks to @AlexisChavez97 for the report and the PR. Closes #16.

  • Bump Elixir minimum required version to 1.11 to match the rest of ex_cldr.

Cldr_Messages v0.14.1

This is the changelog for Cldr_Messages v0.14.1 released on October 4th, 2022. For older changelogs please consult the release tag on GitHub

Bug Fixes

  • Returns a partially formatted message if bindings are missing. The message will be interpolated as far as possibly making the error message more meaningful for end user consumption. Thanks to @maennchen for the PR. Closes #14.

Cldr_Messages v0.14.0

This is the changelog for Cldr_Messages v0.14.0 released on February 22nd, 2022. For older changelogs please consult the release tag on GitHub

Enhancements

  • Updates to ex_cldr version 2.26.0 which uses atoms for locale names and rbnf locale names. This is consistent with other elements of t:Cldr.LanguageTag where atoms are used where the cardinality of the data is fixed and relatively small and strings where the data is free format.

Cldr_Messages v0.13.2

This is the changelog for Cldr_Messages v0.13.2 released on January 14th, 2022. For older changelogs please consult the release tag on GitHub

Bug Fixes

  • Fixes formatting when there is no :message_formats configured on a backend. Closes #11, again.

Cldr_Messages v0.13.1

This is the changelog for Cldr_Messages v0.13.1 released on January 13th, 2022. For older changelogs please consult the release tag on GitHub

Bug Fixes

  • Fix Cldr.Message.Interpolate.compile_interpolate/3 to ensure that the parsed message is escaped AST. Closes #11.

  • Fix passing RBNF format names as number format styles.

  • Fix converting strings to atoms at compile time. Previously these uses String.to_existing_atom/1 however the compilation graph sometimes means that the expected atoms are not available. Therefore String.to_atom/1 is now called. As a result, it is very important to note that allowing arbitrary message formats into the system could open an attack vector to exhaust the atom table.

Cldr_Messages v0.13.0

This is the changelog for Cldr_Messages v0.13.0 released on January 2nd, 2022. For older changelogs please consult the release tag on GitHub

Bug Fixes

  • Don't add :gettext to Mix.compilers/0 because it gets inherited into client applications and we want Gettext to remain optional. Thanks to @trarbr for the report.

  • Fix typos. Thanks as always to @kianmeng

Enhancements

  • Add an Elixir formatter plugin for sigil_M. For example in your .formatter.exs file:
    [
    inputs: ["mix.exs", "{config,lib,test,mix}/**/*.{ex,exs}"],
    locals_without_parens: [docp: 1, defparsec: 2, defparsec: 3],
    plugins: [Cldr.Formatter.Plugin]
    ]

Cldr_Messages v0.12.0

This is the changelog for Cldr_Messages v0.12.0 released on January 1st, 2022. For older changelogs please consult the release tag on GitHub

Enhancements

The primary focus of this release is gettext integration. The effort is kindly driven by @maennchen and the majority of the work is his.

  • Add Cldr.Message.format_to_iolist/3 which formats a binary message into an iolist. This helps with incrementally binding placeholders where some may be bound at compile time and others at runtime. It also makes integration with gettext simpler since this function returns a list of completed bindings and a list of bindings that were not found.

  • Adds an implementation of Gettext.Interpolation to support gettext integration.

Cldr_Messages v0.11.0

This is the changelog for Cldr_Messages v0.11.0 released on May 23rd, 2021. For older changelogs please consult the release tag on GitHub

Enhancements

  • Add Cldr.Message.bindings/1 to extract the names of variable bindings for a message

  • Add option :allow_positional_args to Cldr.Message.format/3. The default is true.

  • Add argument allow_positional_args? to Cldr.Message.Parser.parse/2

Cldr_Messages v0.10.0

This is the changelog for Cldr_Messages v0.10.0 released on April 8th, 2021. For older changelogs please consult the release tag on GitHub

Enhancements

Cldr_Messages v0.9.0

This is the changelog for Cldr_Messages v0.9.0 released on November 18th, 2019. For older changelogs please consult the release tag on GitHub

Enhancements

  • Supports number arguments to be either a number or a tuple of the form {number, keyword_list_of_formatting_options}. This provides an escape hatch for developers to influence formatting of the number beyond the textual format of the message. For example:
# Uses the currency for the current locale
iex> Cldr.Message.format "this is {one, number, currency}", one: 1
{:ok, "this is $1.00"}

# Forces the :MXP currency
iex> Cldr.Message.format "this is {one, number, currency}", one: {1, currency: :MXP}
{:ok, "this is MXP 1.00"}

Cldr_Messages v0.8.0

This is the changelog for Cldr_Messages v0.8.0 released on September 27th, 2019. For older changelogs please consult the release tag on GitHub

Enhancements

  • Fix Cldr.Message.Print.to_string/2 to omit blank spaces at the end of lines when pretty printing.

Cldr_Messages v0.7.0

This is the changelog for Cldr_Messages v0.7.0 released on September 26th, 2019. For older changelogs please consult the release tag on GitHub

Enhancements

  • Allow nimble_parsec versions ~> 0.5 or ~> 1.0

Cldr_Messages v0.6.0

This is the changelog for Cldr_Messages v0.6.0 released on September 26th, 2019. For older changelogs please consult the release tag on GitHub

Enhancements

  • Add Cldr.Message.canonical_message/2 that converts a string message into a canonical form. This allows for fuzzy matching between two messages that may have different formatting (this is possible since the CLDR message format allows for non-formatting whitespace in parts of the syntax).

  • Add documentation for some of the key functions. Much more documentation required before 1.0 release.

Cldr_Messages v0.5.0

This is the changelog for Cldr_Messages v0.5.0 released on September 22nd, 2019. For older changelogs please consult the release tag on GitHub

Enhancements

  • Adds compile time checking that bindings are provided to the format/3 macro wherever possible

  • Supports later versions of ex_cldr and friends, ex_money as well as Elixir 1.11 without warnings

Cldr_Messages v0.4.0

This is the changelog for Cldr_Messages v0.4.0 released on August 29th, 2019. For older changelogs please consult the release tag on GitHub

Bug Fixes

  • Conditionally compile functions that depend on optional dependencies

Cldr_Messages v0.3.0

This is the changelog for Cldr_Messages v0.3.0 released on August 29th, 2019. For older changelogs please consult the release tag on GitHub

Breaking Changes

Enhancements

  • Add the macro <backend>.Cldr.Message.format/3 to parse messages at compile time as a way to optiise performance at runtime. To use it add import <backend>.Cldr.Message to your module and use format/3. An example:
defmodule SomeModule do
  import MyApp.Cldr.Message

  def my_function do
    format("this is a string with a param {param}", param: 3)
  end
end
  • Add Cldr.Message.format_to_list/3 formats to an io_list

Bug Fixes

  • Fix dialyzer warnings. There are some warnings from combinators that will require nimble_parsec version 0.5.2 to be published before they are resolved.

Cldr_Messages v0.2.0

This is the changelog for Cldr_Messages v0.2.0 released on August 27th, 2019. For older changelogs please consult the release tag on GitHub

Enhancements

  • Uses Cldr.Number.to_string/3 to format simple arguments that are numeric (integer, float and decimal). This gives a localised number format. An example:
iex> Cldr.Message.to_string "You have {number} jelly beans", number: 1234
"You have 1,234 jelly beans"
  • Similarly applies localized formatting for dates, times, datetimes.

Cldr_Messages v0.1.0

This is the changelog for Cldr_Messages v0.1.0 released on August 26th, 2019. For older changelogs please consult the release tag on GitHub

This initial release is the basis for building a complete message localization solution as an alternative to Gettext. There is a long way to go until that is accomplished.