# `i18n` – Helper functions for localizing text

This module provides facilities to faciliate the internationalization of applications using `aioxmpp`.

class `aioxmpp.i18n.``LocalizingFormatter`(locale=None, tzinfo=None)

  This is an alternative implementation on top of `string.Formatter`. It is designed to work well with `babel`, which also means that some things work differently when compared with the default `string.Formatter`.

  Most notably, all objects from `datetime` are handled without using their `__format__()` method. Depending on their type, they are forwarded to the respective formatting method in `babel.dates`.

  Type | Babel function | Timezone support
  --- | --- | ---
  `datetime` | `babel.dates.format_datetime()` | yes
  `timedelta` | `babel.dates.format_timedelta()` | no
  `date` | `babel.dates.format_date()` | no
  `time` | `babel.dates.format_time()` | no

  If the format specification is empty, the default format as babel defines it is used.

  In addition to date and time formatting, numbers which use the `n` format type are also formatted with babel. If the format specificaton is empty (except for the trailing `n`), `babel.numbers.format_number()` is used. Otherwise, the remainder of the format specification is passed as format to `babel.numbers.format_decimal()`.

  Examples:

      >>> import pytz, babel, datetime, aioxmpp.i18n
      >>> tz = pytz.timezone("Europe/Berlin")
      >>> dt = datetime.datetime(year=2015, 5, 5, 15, 55, 55, tzinfo=tz)
      >>> fmt = aioxmpp.i18n.LocalizingFormatter(locale=babel.Locale("en_GB"))
      >>> fmt.format("{}", dt)
      '5 May 2015 15:55:55'
      >>> fmt.format("{:full}", dt)
      'Tuesday, 5 May 2015 15:55:55 GMT+00:00'
      >>> fmt.format("{:##.###n}, 120.3)
      >>> fmt.format("{:##.###n}", 12.3)
      '12.3'
      >>> fmt.format("{:##.###;-(#)n}", -1.234)
      '-(1.234)'
      >>> fmt.format("{:n}", -10000)
      '-10,000'

class `aioxmpp.i18n.``LocalizableString`(singular, plural=None, number_index=None)

  This class can be used for lazily translated localizable strings.

  singular must be a `str`. If plural is not set, the string will be localized using gettext; otherwise, ngettext will be used. The detailed process on localizing a string is described in the documentation of `localize()`.

  Localizable strings compare equal if their singular, plural and number_index values all match. The `str()` of a localizable string is its singular string. The `repr()` depends on whether plural is set and refers to the usage of `_()` and `ngettext()`.

  The arguments are stored in attributes named like the arguments. `LocalizableString` instances are immutable and hashable.

  Examples:

      >>> import aioxmpp.i18n, pytz, babel, gettext
      >>> fmt = aioxmpp.i18n.LocalizingFormatter()
      >>> translator = gettext.NullTranslations()
      >>> s1 = aioxmpp.i18n.LocalizableString(
      ...     "{count} thing",
      ...     "{count} things", "count")
      >>> s1.localize(fmt, translator, count=1)
      '1 thing'
      >>> s1.localize(fmt, translator, count=10)
      '10 things'

  `localize`(formatter, translator, *args, **kwargs)

    Localize and format the string using the given formatter and translator. The remaining args are passed to the `format()` method of the formatter.

    The translator must be an object supporting the `gettext.NullTranslations` interface.

    If `plural` is not `None`, the number which will be passed to the ngettext method of translator is first extracted from the args or kwargs, depending on `number_index`. The whole semantics of all three are described in `string.Formatter.get_field()`, which is used by this method (`number_index` is passed as field_name).

    The value returned by `get_field()` is then used as third argument to ngettext, while the others are sourced from `singular` and `plural`.

    If `plural` is `None`, the gettext method of translator is used with `singular` as its only argument.

    After the translation step, the formatter is used with the translated string and args and kwargs to obtain a formatted version of the string which is then returned.

    All of this works best when using a `LocalizingFormatter`.

## Shorthand functions

`aioxmpp.i18n.``_`(s)

  Return a new singular `LocalizableString` using s as singular form.

`aioxmpp.i18n.``ngettext`(singular, plural, number_index)

  Return a new plural `LocalizableString` with the given arguments; these are passed to the constructor of `LocalizableString`.