Packages
ex_cldr_numbers
2.17.0
2.38.3
2.38.2
2.38.1
2.38.0
2.37.0
2.36.0
2.35.2
2.35.1
2.35.0
2.34.1
2.34.0
2.33.6
2.33.5
2.33.4
2.33.3
2.33.2
2.33.1
2.33.0
2.32.4
2.32.3
2.32.2
2.32.1
2.32.0
retired
2.31.3
retired
2.31.2
2.31.1
2.31.0
2.30.1
2.30.0
2.29.0
2.28.0
2.27.3
2.27.2
2.27.1
2.27.0
2.26.0
2.25.2
2.25.1
2.25.0
2.24.0
2.23.3
2.23.2
2.23.1
2.23.0
2.23.0-rc.4
2.23.0-rc.3
2.23.0-rc.2
2.23.0-rc.1
2.23.0-rc.0
2.22.1
2.22.0
2.21.0
2.20.0
2.19.0
2.18.4
2.18.3
2.18.2
2.18.1
2.18.0
2.17.0
2.17.0-rc.1
2.17.0-rc.0
2.16.1
2.16.0
2.16.0-rc.0
2.15.4
2.15.3
2.15.2
2.15.1
2.15.0
2.14.0
2.13.2
2.13.1
2.13.0
2.13.0-rc.0
2.12.1
2.12.0
2.11.0
2.10.0
2.9.0
2.8.0
2.7.2
2.7.1
2.7.0
2.6.4
2.6.3
2.6.2
2.6.1
2.6.0
2.5.0
2.4.4
2.4.3
2.4.2
2.4.1
2.4.0
2.3.0
2.2.0
2.1.1
2.1.0
2.0.0
2.0.0-rc.0
1.6.0
1.5.2
1.5.1
1.5.0
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.3.1
1.3.0
1.3.0-rc.1
1.3.0-rc.0
retired
1.2.0
1.1.0
1.0.1
1.0.0
1.0.0-rc.0
retired
0.3.3
0.3.2
retired
0.3.1
retired
0.3.0
retired
0.2.3
0.2.2
0.2.1
0.2.0
0.1.0
Number and currency localization and formatting functions for the Common Locale Data Repository (CLDR).
Current section
Files
Jump to
Current section
Files
lib/cldr/number/format/meta.ex
defmodule Cldr.Number.Format.Meta do
@moduledoc """
Describes the metadata that drives
number formatting and provides functions to
update the struct.
## Format definition
The `:format` is a keyword list that with two
elements:
* `:positive` which is a keyword list for
formatting a number >= zero
* `:negative` which is a keyword list for
formatting negtive number
There are two formats because we can format in
an accounting style (that is, numbers surrounded
by `()`) or any other arbitrary style. Typically
the format for a negative number is the same as
that for a positive number with a prepended
minus sign.
## Localisation of number formatting
Number formatting is always localised to either
the currency processes locale or a locale
provided as an option to `Cldr.Number.to_string/3`.
The metadata is independent of the localisation
process. Signs (`+`/`-`), grouping (`,`), decimal markers
(`.`) and exponent signs are all localised when
the number is formatted.
## Formatting directives
The formats - positive and negative - are defined
in the metadata struct, as a keyword list of keywords
and values.
The simplest formatting list might be:
```
[format: _]`
```
The `:format` keyword indicates
that this is where the formatting number will be
substituted into the format pattern.
Another example would be for formatting a negative
number:
```
[minus: _, format: _]
```
which will format with a localised minus sign
followed by the formatted number. Note that the
keyword value for `:minus` and `:format` are
ignored.
## List of formatting keywords
The following is the full list of formatting
keywords which can be used to format a
number. A `_` in the keyword format is
used to denote `:dont_care`.
* `[format: _]` inserts the formatted number
exclusive of any sign
* `[minus: _]` inserts a localised minus
sign
* `[plus: _]` inserts a localised plus sign
* `[percent: _]` inserts a localised percent sign
* `[permille: _]` inserts a localised permille sign
* `[literal: "string"]` inserts `string` into the
format without any processing
* `[currency: 1..4]` inserts a localised currency
symbol of the given `type`. A `:currency` must be
provided as an option to `Cldr.Number.Formatter.Decimal.to_string/3`.
* `[pad: "char"]` inserts the correct number of `char`s
to pad the number format to the width specified by
`:padding_length` in the `%Meta{}` struct. The `:pad`
can be anywhere in the format list but it is most
typically inserted before or after the `:format`
keyword. The assumption is tha the `char` is a single
binary character but this is not checked.
## Currency symbol formatting
Currency are localised and have four ways of being
presented. The different types are defined in the
`[currency: type]` keyword where `type` is an integer
in the range `1..4` These types will insert
into the final format:
1. The standard currency symbol like `$`,`¥` or `€`
2. The ISO currency code (like `USD` and `JPY`)
3. The localised and pluralised currency display name
like "Australian dollar" or "Australian dollars"
4. The narrow currency symbol if defined for a locale
"""
defstruct integer_digits: %{max: 0, min: 1},
fractional_digits: %{max: 0, min: 0},
significant_digits: %{max: 0, min: 0},
exponent_digits: 0,
exponent_sign: false,
scientific_rounding: 0,
grouping: %{
fraction: %{first: 0, rest: 0},
integer: %{first: 0, rest: 0}
},
round_nearest: 0,
padding_length: 0,
padding_char: " ",
multiplier: 1,
format: [
positive: [format: "#"],
negative: [minus: '-', format: :same_as_positive]
],
number: 0
@typedoc "Metadata type that drives how to format a number"
@type t :: %__MODULE__{}
@doc """
Returns a new number formatting metadata
struct.
"""
@spec new :: t()
def new do
%__MODULE__{}
end
@doc """
Set the minimum, and optionally maximum, integer digits to
format.
"""
@spec put_integer_digits(t(), non_neg_integer, non_neg_integer) :: t()
def put_integer_digits(%__MODULE__{} = meta, min, max \\ 0)
when is_integer(min) and is_integer(max) do
meta
|> Map.put(:integer_digits, %{min: min, max: max})
end
@doc """
Set the minimum, and optionally maximum, fractional digits to
format.
"""
@spec put_fraction_digits(t(), non_neg_integer, non_neg_integer) :: t()
def put_fraction_digits(%__MODULE__{} = meta, min, max \\ 0)
when is_integer(min) and is_integer(max) do
meta
|> Map.put(:fractional_digits, %{min: min, max: max})
end
@doc """
Set the minimum, and optionally maximum, significant digits to
format.
"""
@spec put_significant_digits(t(), non_neg_integer, non_neg_integer) :: t()
def put_significant_digits(%__MODULE__{} = meta, min, max \\ 0)
when is_integer(min) and is_integer(max) do
meta
|> Map.put(:significant_digits, %{min: min, max: max})
end
@doc """
Set the number of exponent digits to
format.
"""
@spec put_exponent_digits(t(), non_neg_integer) :: t()
def put_exponent_digits(%__MODULE__{} = meta, digits) when is_integer(digits) do
meta
|> Map.put(:exponent_digits, digits)
end
@doc """
Set whether to add the sign of the exponent to
the format.
"""
@spec put_exponent_sign(t(), boolean) :: t()
def put_exponent_sign(%__MODULE__{} = meta, flag) when is_boolean(flag) do
meta
|> Map.put(:exponent_sign, flag)
end
@doc """
Set the increment to which the number should
be rounded.
"""
@spec put_round_nearest_digits(t(), non_neg_integer) :: t()
def put_round_nearest_digits(%__MODULE__{} = meta, digits) when is_integer(digits) do
meta
|> Map.put(:round_nearest, digits)
end
@doc """
Set the number of scientific digits to which the number should
be rounded.
"""
@spec put_scientific_rounding_digits(t(), non_neg_integer) :: t()
def put_scientific_rounding_digits(%__MODULE__{} = meta, digits) when is_integer(digits) do
meta
|> Map.put(:scientific_rounding, digits)
end
@spec put_padding_length(t(), non_neg_integer) :: t()
def put_padding_length(%__MODULE__{} = meta, digits) when is_integer(digits) do
meta
|> Map.put(:padding_length, digits)
end
@doc """
Set the padding character to be used when
padding the formatted number.
"""
@spec put_padding_char(t(), String.t()) :: t()
def put_padding_char(%__MODULE__{} = meta, char) when is_binary(char) do
meta
|> Map.put(:padding_char, char)
end
@doc """
Sets the multiplier for the number.
Before formatting, the number is multiplied
by this amount. This is useful when
formatting as a percent or permille.
"""
@spec put_multiplier(t(), non_neg_integer) :: t()
def put_multiplier(%__MODULE__{} = meta, multiplier) when is_integer(multiplier) do
meta
|> Map.put(:multiplier, multiplier)
end
@doc """
Sets the number of digits in a group or
optionally the first group and subsequent
groups for the integer part of a number.
The grouping character is defined by the locale
defined for the current process or supplied
as the `:locale` option to `to_string/3`.
"""
@spec put_integer_grouping(t(), non_neg_integer, non_neg_integer) :: t()
def put_integer_grouping(%__MODULE__{} = meta, first, rest)
when is_integer(first) and is_integer(rest) do
grouping =
meta
|> Map.get(:grouping)
|> Map.put(:integer, %{first: first, rest: rest})
Map.put(meta, :grouping, grouping)
end
@spec put_integer_grouping(t(), non_neg_integer) :: t()
def put_integer_grouping(%__MODULE__{} = meta, all) when is_integer(all) do
grouping =
meta
|> Map.get(:grouping)
|> Map.put(:integer, %{first: all, rest: all})
Map.put(meta, :grouping, grouping)
end
@doc """
Sets the number of digits in a group or
optionally the first group and subsequent
groups for the fractional part of a number.
The grouping character is defined by the locale
defined for the current process or supplied
as the `:locale` option to `to_string/3`.
"""
@spec put_fraction_grouping(t(), non_neg_integer, non_neg_integer) :: t()
def put_fraction_grouping(%__MODULE__{} = meta, first, rest)
when is_integer(first) and is_integer(rest) do
grouping =
meta
|> Map.get(:grouping)
|> Map.put(:fraction, %{first: first, rest: rest})
Map.put(meta, :grouping, grouping)
end
@spec put_fraction_grouping(t(), non_neg_integer) :: t()
def put_fraction_grouping(%__MODULE__{} = meta, all) when is_integer(all) do
grouping =
meta
|> Map.get(:grouping)
|> Map.put(:fraction, %{first: all, rest: all})
Map.put(meta, :grouping, grouping)
end
@doc """
Set the metadata format for the positive
and negative number format.
Note that this is the parsed format as a simple keyword
list, not a binary representation.
Its up to each formatting engine to transform its input
into this form. See `Cldr.Number.Format.Meta` module
documentation for the available keywords.
"""
@spec put_format(t(), Keyword.t(), Keyword.t()) :: t()
def put_format(%__MODULE__{} = meta, positive_format, negative_format) do
meta
|> Map.put(:format, positive: positive_format, negative: negative_format)
end
@spec put_format(t(), Keyword.t()) :: t()
def put_format(%__MODULE__{} = meta, positive_format) do
put_format(meta, positive_format, minus: '-', format: :same_as_positive)
end
end