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