1# -*- coding: utf-8 -*-
2"""
3    babel.lists
4    ~~~~~~~~~~~
5
6    Locale dependent formatting of lists.
7
8    The default locale for the functions in this module is determined by the
9    following environment variables, in that order:
10
11     * ``LC_ALL``, and
12     * ``LANG``
13
14    :copyright: (c) 2015-2021 by the Babel Team.
15    :license: BSD, see LICENSE for more details.
16"""
17
18from babel.core import Locale, default_locale
19
20DEFAULT_LOCALE = default_locale()
21
22
23def format_list(lst, style='standard', locale=DEFAULT_LOCALE):
24    """
25    Format the items in `lst` as a list.
26
27    >>> format_list(['apples', 'oranges', 'pears'], locale='en')
28    u'apples, oranges, and pears'
29    >>> format_list(['apples', 'oranges', 'pears'], locale='zh')
30    u'apples\u3001oranges\u548cpears'
31    >>> format_list(['omena', 'peruna', 'aplari'], style='or', locale='fi')
32    u'omena, peruna tai aplari'
33
34    These styles are defined, but not all are necessarily available in all locales.
35    The following text is verbatim from the Unicode TR35-49 spec [1].
36
37    * standard:
38      A typical 'and' list for arbitrary placeholders.
39      eg. "January, February, and March"
40    * standard-short:
41      A short version of a 'and' list, suitable for use with short or abbreviated placeholder values.
42      eg. "Jan., Feb., and Mar."
43    * or:
44      A typical 'or' list for arbitrary placeholders.
45      eg. "January, February, or March"
46    * or-short:
47      A short version of an 'or' list.
48      eg. "Jan., Feb., or Mar."
49    * unit:
50      A list suitable for wide units.
51      eg. "3 feet, 7 inches"
52    * unit-short:
53      A list suitable for short units
54      eg. "3 ft, 7 in"
55    * unit-narrow:
56      A list suitable for narrow units, where space on the screen is very limited.
57      eg. "3′ 7″"
58
59    [1]: https://www.unicode.org/reports/tr35/tr35-49/tr35-general.html#ListPatterns
60
61    :param lst: a sequence of items to format in to a list
62    :param style: the style to format the list with. See above for description.
63    :param locale: the locale
64    """
65    locale = Locale.parse(locale)
66    if not lst:
67        return ''
68    if len(lst) == 1:
69        return lst[0]
70
71    if style not in locale.list_patterns:
72        raise ValueError('Locale %s does not support list formatting style %r (supported are %s)' % (
73            locale,
74            style,
75            list(sorted(locale.list_patterns)),
76        ))
77    patterns = locale.list_patterns[style]
78
79    if len(lst) == 2:
80        return patterns['2'].format(*lst)
81
82    result = patterns['start'].format(lst[0], lst[1])
83    for elem in lst[2:-1]:
84        result = patterns['middle'].format(result, elem)
85    result = patterns['end'].format(result, lst[-1])
86
87    return result
88