├── 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 | ![Perl CLDR](https://www.gravatar.com/avatar/656f15a25eff4437f5a82e7c929f41dd?s=96) 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 | --------------------------------------------------------------------------------