├── logotype
└── logo_32x32.png
├── .travis.yml
├── t
├── 01-load.t
└── format.t
├── META6.json
├── README.md
└── lib
└── CLDR
└── List.pm
/logotype/logo_32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/patch/cldr-list-pm6/master/logotype/logo_32x32.png
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: perl6
2 |
3 | perl6:
4 | - latest
5 |
6 | install:
7 | - rakudobrew build-panda
8 | - panda installdeps .
9 |
--------------------------------------------------------------------------------
/t/01-load.t:
--------------------------------------------------------------------------------
1 | use v6;
2 | use Test;
3 | plan 4;
4 |
5 | use CLDR::List;
6 |
7 | my $list = CLDR::List.new;
8 |
9 | ok $list ~~ CLDR::List, 'instantiate object';
10 | ok $list.can('locale'), 'has locale method';
11 | ok $list.can('format'), 'has format method';
12 | is $list.locale, 'root', 'default locale';
13 |
--------------------------------------------------------------------------------
/META6.json:
--------------------------------------------------------------------------------
1 | {
2 | "perl" : "6.*",
3 | "name" : "CLDR::List",
4 | "version" : "*",
5 | "author" : "Nova Patch",
6 | "description" : "Localized list formatters using the Unicode CLDR",
7 | "depends" : [],
8 | "provides" : { "CLDR::List" : "lib/CLDR/List.pm" },
9 | "source-url" : "git://github.com/patch/cldr-list-pm6.git"
10 | }
11 |
--------------------------------------------------------------------------------
/t/format.t:
--------------------------------------------------------------------------------
1 | use v6;
2 | use Test;
3 | plan 16;
4 |
5 | use CLDR::List;
6 |
7 | my $list = CLDR::List.new;
8 |
9 | is $list.format(), '', 'root: 0 elements';
10 | is $list.format(1), '1', 'root: 1 Num element';
11 | is $list.format(1, 2), '1, 2', 'root: 2 Num elements';
12 | is $list.format(1..3), '1, 2, 3', 'root: 3 Num elements';
13 | is $list.format('A'), 'A', 'root: 1 Str element';
14 | is $list.format(), 'A, B', 'root: 2 Str elements';
15 | is $list.format('A'..'C'), 'A, B, C', 'root: 3 Str elements';
16 | is $list.format('A'..'D'), 'A, B, C, D', 'root: 4 Str elements';
17 |
18 | $list.locale = 'en';
19 | is $list.format('A'), 'A', 'en: 1 element';
20 | is $list.format(), 'A and B', 'en: 2 elements';
21 | is $list.format('A'..'C'), 'A, B, and C', 'en: 3 elements';
22 | is $list.format('A'..'D'), 'A, B, C, and D', 'en: 4 elements';
23 |
24 | $list.locale = 'en-GB';
25 | is $list.format('A'..'C'), 'A, B and C', 'en-GB: 3 elements';
26 |
27 | $list.locale = 'ru';
28 | is $list.format(<А Б В>), 'А, Б и В', 'ru: 3 elements';
29 |
30 | $list.locale = 'zh-Hant';
31 | is $list.format(<一 丁 丈>), '一、丁和丈', 'zh-Hant: 3 elements';
32 |
33 | $list.locale = 'ar';
34 | is $list.format(<ﺍ ﺏ ﺕ>), 'ﺍ، ﺏ، و ﺕ', 'ar: 3 elements';
35 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | # NAME
4 |
5 | CLDR::List - Localized list formatters using the Unicode CLDR
6 |
7 | # SYNOPSIS
8 |
9 | use CLDR::List;
10 |
11 | my $list = CLDR::List.new(locale => 'en');
12 | my @fruit = ;
13 |
14 | say $list.format(@fruit); # apples, oranges, and bananas
15 |
16 | $list.locale = 'en-GB'; # British English
17 | say $list.format(@fruit); # apples, oranges and bananas
18 |
19 | $list.locale = 'zh-Hant'; # Traditional Chinese
20 | say $list.format('1'..'4'); # 1、2、3和4
21 |
22 | # DESCRIPTION
23 |
24 | Localized list formatters using the Unicode CLDR.
25 |
26 | ## Attributes
27 |
28 | - locale
29 |
30 | ## Methods
31 |
32 | - format
33 |
34 | # SEE ALSO
35 |
36 | - [List Patterns in UTS \#35: Unicode
37 | LDML](http://www.unicode.org/reports/tr35/tr35-general.html\#ListPatterns)
38 | - [Perl Advent Calendar:
39 | CLDR TL;DR](http://perladvent.org/2014/2014-12-23.html)
40 | - [Unicode beyond just characters: Localization with the
41 | CLDR](http://patch.codes/talks/localization-with-the-unicode-cldr/) (video and
42 | slides)
43 |
44 | # AUTHOR
45 |
46 | Nova Patch
47 |
48 | # COPYRIGHT AND LICENSE
49 |
50 | © 2013–2015 Nova Patch
51 |
52 | This library is free software; you can redistribute it and/or modify it under
53 | the same terms as Perl itself.
54 |
--------------------------------------------------------------------------------
/lib/CLDR/List.pm:
--------------------------------------------------------------------------------
1 | unit class CLDR::List is rw;
2 |
3 | constant @placeholders = <{0} {1}>;
4 | constant %patterns = { # TODO: update with full CLDR data
5 | root => { middle => '{0}, {1}', 2 => '{0}, {1}' },
6 | ar => { middle => '{0}، {1}', end => '{0}، و {1}', 2 => '{0} و {1}' },
7 | ca => { 2 => '{0} i {1}' },
8 | cs => { 2 => '{0} a {1}' },
9 | da => { 2 => '{0} og {1}' },
10 | de => { 2 => '{0} und {1}' },
11 | el => { 2 => '{0} και {1}' },
12 | en => { end => '{0}, and {1}', 2 => '{0} and {1}' },
13 | 'en-AU' => { 2 => '{0} and {1}' },
14 | 'en-CA' => { end => '{0}, and {1}', 2 => '{0} and {1}' },
15 | 'en-GB' => { 2 => '{0} and {1}' },
16 | 'en-HK' => { 2 => '{0} and {1}' },
17 | 'en-IN' => { 2 => '{0} and {1}' },
18 | es => { 2 => '{0} y {1}' },
19 | fi => { 2 => '{0} ja {1}' },
20 | fr => { 2 => '{0} et {1}' },
21 | he => { 2 => '{0} ו{1}' },
22 | hi => { end => '{0}, और {1}', 2 => '{0} और {1}' },
23 | hr => { 2 => '{0} i {1}' },
24 | hu => { 2 => '{0} és {1}' },
25 | it => { end => '{0}, e {1}', 2 => '{0} e {1}' },
26 | ja => { middle => '{0}、{1}', 2 => '{0}、{1}' },
27 | ko => { 2 => '{0} 및 {1}' },
28 | nb => { 2 => '{0} og {1}' },
29 | nl => { 2 => '{0} en {1}' },
30 | pl => { 2 => '{0} i {1}' },
31 | pt => { 2 => '{0} e {1}' },
32 | 'pt-PT' => { 2 => '{0} e {1}' },
33 | ro => { 2 => '{0} și {1}' },
34 | ru => { 2 => '{0} и {1}' },
35 | sk => { 2 => '{0} a {1}' },
36 | sl => { 2 => '{0} in {1}' },
37 | sr => { 2 => '{0} и {1}' },
38 | sv => { 2 => '{0} och {1}' },
39 | th => { middle => '{0} {1}', end => '{0} และ{1}', 2 => '{0}และ{1}' },
40 | tr => { 2 => '{0} ve {1}' },
41 | vi => { 2 => '{0} và {1}' },
42 | uk => { 2 => '{0} та {1}' },
43 | zh => { middle => '{0}、{1}', 2 => '{0}和{1}' },
44 | 'zh-Hant' => { middle => '{0}、{1}', 2 => '{0}和{1}' },
45 | };
46 |
47 | # TODO: support type varients
48 | # TODO: allow setting default locale?
49 | has $.locale = 'root';
50 | has $!previous-locale;
51 | has %!pattern;
52 |
53 | method format (*@list) {
54 | self!update-pattern;
55 |
56 | return do given @list {
57 | when 0 { '' }
58 | when 1 { ~@list[0] }
59 | when 2 { %!pattern<2>.trans(@placeholders => @list) }
60 | when * {
61 | my $format = %!pattern.trans(
62 | @placeholders => @list[*-2,*-1]
63 | );
64 |
65 | if (* > 3) {
66 | for @list[1..*-3] -> $element {
67 | $format = %!pattern.trans(
68 | @placeholders => ($element, $format)
69 | );
70 | }
71 | }
72 |
73 | %!pattern.trans(
74 | @placeholders => (@list[0], $format)
75 | );
76 | }
77 | }
78 | }
79 |
80 | # TODO: does Perl 6 have attribute triggers like Moose?
81 | method !update-pattern {
82 | return if $!previous-locale && $!previous-locale eq $!locale;
83 |
84 | # TODO: robust locale tag handling with fallbacks
85 | %!pattern = %patterns{$.locale} || %patterns;
86 | %!pattern //= %patterns;
87 | %!pattern //= %!pattern;
88 | %!pattern //= %!pattern<2>;
89 | $!previous-locale = $.locale;
90 | }
91 |
92 | =begin pod
93 |
94 | =head1 NAME
95 |
96 | CLDR::List - Localized list formatters using the Unicode CLDR
97 |
98 | =head1 SYNOPSIS
99 |
100 | use CLDR::List;
101 |
102 | my $list = CLDR::List.new(locale => 'en');
103 | my @fruit = ;
104 |
105 | say $list.format(@fruit); # apples, oranges, and bananas
106 |
107 | $list.locale = 'en-GB'; # British English
108 | say $list.format(@fruit); # apples, oranges and bananas
109 |
110 | $list.locale = 'zh-Hant'; # Traditional Chinese
111 | say $list.format('1'..'4'); # 1、2、3和4
112 |
113 | =head1 DESCRIPTION
114 |
115 | Localized list formatters using the Unicode CLDR.
116 |
117 | =head2 Attributes
118 |
119 | =over
120 |
121 | =item locale
122 |
123 | =back
124 |
125 | =head2 Methods
126 |
127 | =over
128 |
129 | =item format
130 |
131 | =back
132 |
133 | =head1 SEE ALSO
134 |
135 | =over
136 |
137 | =item * L
139 |
140 | =item * L
142 |
143 | =item * L (video and
145 | slides)
146 |
147 | =back
148 |
149 | =head1 AUTHOR
150 |
151 | Nova Patch
152 |
153 | =head1 COPYRIGHT AND LICENSE
154 |
155 | © 2013–2015 Nova Patch
156 |
157 | This library is free software; you can redistribute it and/or modify it under
158 | the same terms as Perl itself.
159 |
160 | =end pod
161 |
--------------------------------------------------------------------------------