Packages
localize
0.48.0
1.0.0-rc.4
1.0.0-rc.3
1.0.0-rc.2
1.0.0-rc.1
1.0.0-rc.0
0.50.0
0.49.0
0.48.0
0.47.0
0.46.0
0.45.0
0.44.0
0.41.3
0.41.2
0.41.1
0.41.0
0.40.0
0.39.0
0.38.0
0.37.0
0.36.0
0.35.0
0.34.0
0.33.0
0.32.0
0.31.0
0.30.1
0.30.0
retired
0.29.0
0.28.0
0.27.0
0.26.0
0.25.0
0.24.0
0.23.0
0.22.0
0.21.0
0.20.0
0.19.0
0.18.0
0.16.0
0.15.0
0.14.0
0.13.0
0.12.0
0.11.0
0.10.0
0.9.0
0.8.0
0.7.0
0.6.0
0.5.0
0.4.0
0.3.0
0.2.0
0.1.0
0.1.0-alpha.1
Localization (parsing, formatting) of numbers, dates/time/calendar, units of measure, messages and lists. Includes localized collation.
Current section
Files
Jump to
Current section
Files
lib/localize/substitution.ex
defmodule Localize.Substitution do
# Compiles substitution templates of the form `"{0} something {1}"`
# into token lists for efficient parameter substitution at runtime.
#
# Templates are parsed once into a list of string literals and
# integer indices. At runtime, values are substituted for the
# integer indices to produce the final output.
#
@moduledoc false
@doc """
Parses a substitution template into a list of tokens.
### Arguments
* `template` is a binary string that may include parameter
markers like `{0}`, `{1}`, etc.
### Returns
* A list of tokens where substitution markers become integers
and literal text remains as strings.
### Examples
iex> Localize.Substitution.parse("{0}, {1}")
[0, ", ", 1]
iex> Localize.Substitution.parse("{0} something {1} else {2}")
[0, " something ", 1, " else ", 2]
iex> Localize.Substitution.parse("")
[]
"""
@spec parse(String.t()) :: [String.t() | integer()]
def parse("") do
[]
end
def parse(template) when is_binary(template) do
template
|> String.split(~r/{[0-9]}/, include_captures: true, trim: true)
|> Enum.map(&item_from_token/1)
end
@doc """
Substitutes values into a pre-parsed template token list.
### Arguments
* `values` is a value or list of values to substitute into
the template.
* `tokens` is a template token list previously created by
`parse/1`.
### Returns
* A list with values substituted for integer indices in the
template.
### Examples
iex> template = Localize.Substitution.parse("{0} and {1}")
[0, " and ", 1]
iex> Localize.Substitution.substitute(["a", "b"], template)
["a", " and ", "b"]
iex> Localize.Substitution.substitute("x", [0, "!"])
["x", "!"]
"""
@spec substitute(term() | [term()], [String.t() | integer()]) :: [term()]
# Single item, single token
def substitute(item, [0]) do
[item]
end
def substitute([item], [0]) do
[item]
end
# No parameters used — just a literal string
def substitute([_item], [string]) when is_binary(string) do
[string]
end
def substitute(_item, [string]) when is_binary(string) do
[string]
end
# One parameter: {0}string
def substitute([item], [0, string]) when is_binary(string) do
[item, string]
end
def substitute(item, [0, string]) when is_binary(string) do
[item, string]
end
# One parameter: string{0}
def substitute([item], [string, 0]) when is_binary(string) do
[string, item]
end
def substitute(item, [string, 0]) when is_binary(string) do
[string, item]
end
# One parameter: string{0}string
def substitute(item, [string1, 0, string2])
when is_binary(string1) and is_binary(string2) do
[string1, item, string2]
end
# Two parameters: {0}{1}
def substitute([item_0, item_1], [0, 1]) do
[item_0, item_1]
end
# Two parameters: {0}string{1}
def substitute([item_0, item_1], [0, string, 1]) when is_binary(string) do
[item_0, string, item_1]
end
# Two parameters: {1}string{0}
def substitute([item_0, item_1], [1, string, 0]) when is_binary(string) do
[item_1, string, item_0]
end
# Two parameters with trailing: {0}string{1}string
def substitute([item_0, item_1], [0, string1, 1, string2]) do
[item_0, string1, item_1, string2]
end
def substitute([item_0, item_1], [1, string1, 0, string2]) do
[item_1, string1, item_0, string2]
end
# Three parameters: {0}string{1}string{2}
def substitute([item_0, item_1, item_2], [0, string_1, 1, string_2, 2])
when is_binary(string_1) and is_binary(string_2) do
[item_0, string_1, item_1, string_2, item_2]
end
# ── Private ─────────────────────────────────────────────────
@digits [?0, ?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9]
defp item_from_token(<<?{, digit, ?}>>) when digit in @digits do
digit - ?0
end
defp item_from_token(string) do
string
end
end