twitter_cldr 3.0.0.beta1 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (698) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +16 -2
  3. data/History.txt +9 -1
  4. data/README.md +297 -113
  5. data/Rakefile +97 -17
  6. data/lib/twitter_cldr/collation/collator.rb +12 -3
  7. data/lib/twitter_cldr/collation/trie_builder.rb +1 -1
  8. data/lib/twitter_cldr/{tokenizers/calendars → data_readers}/additional_date_format_selector.rb +6 -4
  9. data/lib/twitter_cldr/data_readers/calendar_data_reader.rb +91 -0
  10. data/lib/twitter_cldr/data_readers/data_reader.rb +32 -0
  11. data/lib/twitter_cldr/data_readers/date_data_reader.rb +26 -0
  12. data/lib/twitter_cldr/data_readers/date_time_data_reader.rb +41 -0
  13. data/lib/twitter_cldr/data_readers/number_data_reader.rb +142 -0
  14. data/lib/twitter_cldr/data_readers/time_data_reader.rb +26 -0
  15. data/lib/twitter_cldr/data_readers/timespan_data_reader.rb +122 -0
  16. data/lib/twitter_cldr/data_readers.rb +17 -0
  17. data/lib/twitter_cldr/formatters/calendars/{datetime_formatter.rb → date_time_formatter.rb} +27 -42
  18. data/lib/twitter_cldr/formatters/calendars/timespan_formatter.rb +3 -64
  19. data/lib/twitter_cldr/formatters/formatter.rb +39 -0
  20. data/lib/twitter_cldr/formatters/list_formatter.rb +22 -12
  21. data/lib/twitter_cldr/formatters/numbers/abbreviated/abbreviated_number_formatter.rb +5 -26
  22. data/lib/twitter_cldr/formatters/numbers/currency_formatter.rb +2 -11
  23. data/lib/twitter_cldr/formatters/numbers/decimal_formatter.rb +4 -2
  24. data/lib/twitter_cldr/formatters/numbers/number_formatter.rb +45 -27
  25. data/lib/twitter_cldr/formatters/numbers/percent_formatter.rb +3 -13
  26. data/lib/twitter_cldr/formatters/numbers/rbnf/formatters.rb +224 -0
  27. data/lib/twitter_cldr/formatters/numbers/rbnf/post_processors/chinese.rb +122 -0
  28. data/lib/twitter_cldr/formatters/numbers/rbnf/rule.rb +93 -0
  29. data/lib/twitter_cldr/formatters/numbers/rbnf/rule_group.rb +20 -0
  30. data/lib/twitter_cldr/formatters/numbers/rbnf/rule_parser.rb +86 -0
  31. data/lib/twitter_cldr/formatters/numbers/rbnf/rule_set.rb +259 -0
  32. data/lib/twitter_cldr/formatters/numbers/rbnf/substitution.rb +30 -0
  33. data/lib/twitter_cldr/formatters/numbers/rbnf.rb +127 -0
  34. data/lib/twitter_cldr/formatters/plurals/plural_formatter.rb +18 -6
  35. data/lib/twitter_cldr/formatters.rb +4 -5
  36. data/lib/twitter_cldr/localized/localized_array.rb +1 -1
  37. data/lib/twitter_cldr/localized/localized_date.rb +6 -3
  38. data/lib/twitter_cldr/localized/localized_datetime.rb +38 -15
  39. data/lib/twitter_cldr/localized/localized_number.rb +40 -24
  40. data/lib/twitter_cldr/localized/localized_object.rb +4 -4
  41. data/lib/twitter_cldr/localized/localized_string.rb +40 -7
  42. data/lib/twitter_cldr/localized/localized_time.rb +9 -2
  43. data/lib/twitter_cldr/localized/localized_timespan.rb +50 -5
  44. data/lib/twitter_cldr/normalization.rb +8 -19
  45. data/lib/twitter_cldr/parsers/parser.rb +50 -0
  46. data/lib/twitter_cldr/parsers/segmentation_parser.rb +137 -0
  47. data/lib/twitter_cldr/parsers/symbol_table.rb +30 -0
  48. data/lib/twitter_cldr/parsers/unicode_regex/character_class.rb +91 -0
  49. data/lib/twitter_cldr/parsers/unicode_regex/character_range.rb +39 -0
  50. data/lib/twitter_cldr/parsers/unicode_regex/character_set.rb +65 -0
  51. data/lib/twitter_cldr/parsers/unicode_regex/component.rb +50 -0
  52. data/lib/twitter_cldr/parsers/unicode_regex/literal.rb +83 -0
  53. data/lib/twitter_cldr/parsers/unicode_regex/unicode_string.rb +41 -0
  54. data/lib/twitter_cldr/parsers/unicode_regex_parser.rb +262 -0
  55. data/lib/twitter_cldr/parsers.rb +5 -1
  56. data/lib/twitter_cldr/resources/casefolder.rb.erb +64 -0
  57. data/lib/twitter_cldr/resources/casefolder_class_generator.rb +75 -0
  58. data/lib/twitter_cldr/resources/download.rb +10 -4
  59. data/lib/twitter_cldr/resources/icu_based_importer.rb +18 -0
  60. data/lib/twitter_cldr/resources/locales_resources_importer.rb +24 -13
  61. data/lib/twitter_cldr/resources/normalization_quick_check_importer.rb +1 -14
  62. data/lib/twitter_cldr/resources/rbnf_test_importer.rb +107 -0
  63. data/lib/twitter_cldr/resources/readme_renderer.rb +115 -0
  64. data/lib/twitter_cldr/resources/tailoring_importer.rb +2 -8
  65. data/lib/twitter_cldr/resources/uli/segment_exceptions_importer.rb +62 -0
  66. data/lib/twitter_cldr/resources/uli.rb +12 -0
  67. data/lib/twitter_cldr/resources/unicode_data_importer.rb +84 -14
  68. data/lib/twitter_cldr/resources/unicode_importer.rb +37 -0
  69. data/lib/twitter_cldr/resources/unicode_properties_importer.rb +79 -0
  70. data/lib/twitter_cldr/resources.rb +8 -1
  71. data/lib/twitter_cldr/shared/break_iterator.rb +213 -0
  72. data/lib/twitter_cldr/shared/calendar.rb +38 -14
  73. data/lib/twitter_cldr/shared/casefolder.rb +210 -0
  74. data/lib/twitter_cldr/shared/code_point.rb +103 -16
  75. data/lib/twitter_cldr/shared/numbering_system.rb +58 -0
  76. data/lib/twitter_cldr/shared/territories.rb +43 -1
  77. data/lib/twitter_cldr/shared/unicode_regex.rb +81 -0
  78. data/lib/twitter_cldr/shared.rb +13 -9
  79. data/lib/twitter_cldr/tokenizers/calendars/date_time_tokenizer.rb +77 -0
  80. data/lib/twitter_cldr/tokenizers/calendars/date_tokenizer.rb +14 -29
  81. data/lib/twitter_cldr/tokenizers/calendars/time_tokenizer.rb +13 -28
  82. data/lib/twitter_cldr/tokenizers/calendars/timespan_tokenizer.rb +11 -87
  83. data/lib/twitter_cldr/tokenizers/numbers/number_tokenizer.rb +16 -71
  84. data/lib/twitter_cldr/tokenizers/numbers/rbnf_tokenizer.rb +53 -0
  85. data/lib/twitter_cldr/tokenizers/pattern_tokenizer.rb +42 -0
  86. data/lib/twitter_cldr/tokenizers/segmentation/segmentation_tokenizer.rb +39 -0
  87. data/lib/twitter_cldr/tokenizers/tokenizer.rb +116 -0
  88. data/lib/twitter_cldr/tokenizers/unicode_regex/unicode_regex_tokenizer.rb +52 -0
  89. data/lib/twitter_cldr/tokenizers.rb +8 -4
  90. data/lib/twitter_cldr/utils/code_points.rb +1 -1
  91. data/lib/twitter_cldr/utils/range_set.rb +242 -0
  92. data/lib/twitter_cldr/utils/yaml.rb +17 -12
  93. data/lib/twitter_cldr/utils.rb +1 -1
  94. data/lib/twitter_cldr/version.rb +1 -1
  95. data/lib/twitter_cldr.rb +2 -1
  96. data/resources/custom/locales/sv/units.yml +8 -0
  97. data/resources/locales/af/calendars.yml +278 -224
  98. data/resources/locales/af/currencies.yml +954 -916
  99. data/resources/locales/af/languages.yml +583 -580
  100. data/resources/locales/af/layout.yml +5 -5
  101. data/resources/locales/af/lists.yml +23 -7
  102. data/resources/locales/af/numbers.yml +59 -54
  103. data/resources/locales/af/plurals.yml +2 -2
  104. data/resources/locales/af/rbnf.yml +261 -0
  105. data/resources/locales/af/territories.yml +264 -263
  106. data/resources/locales/ar/calendars.yml +287 -259
  107. data/resources/locales/ar/currencies.yml +1730 -1692
  108. data/resources/locales/ar/languages.yml +583 -580
  109. data/resources/locales/ar/layout.yml +5 -5
  110. data/resources/locales/ar/lists.yml +23 -7
  111. data/resources/locales/ar/numbers.yml +66 -61
  112. data/resources/locales/ar/plurals.yml +5 -8
  113. data/resources/locales/ar/rbnf.yml +519 -0
  114. data/resources/locales/ar/territories.yml +264 -263
  115. data/resources/locales/be/calendars.yml +238 -237
  116. data/resources/locales/be/currencies.yml +954 -917
  117. data/resources/locales/be/languages.yml +583 -580
  118. data/resources/locales/be/layout.yml +5 -5
  119. data/resources/locales/be/lists.yml +23 -7
  120. data/resources/locales/be/numbers.yml +62 -57
  121. data/resources/locales/be/plurals.yml +7 -4
  122. data/resources/locales/be/rbnf.yml +1288 -0
  123. data/resources/locales/be/territories.yml +264 -263
  124. data/resources/locales/bg/calendars.yml +278 -218
  125. data/resources/locales/bg/currencies.yml +955 -917
  126. data/resources/locales/bg/languages.yml +583 -580
  127. data/resources/locales/bg/layout.yml +5 -5
  128. data/resources/locales/bg/lists.yml +23 -7
  129. data/resources/locales/bg/numbers.yml +62 -57
  130. data/resources/locales/bg/plurals.yml +2 -2
  131. data/resources/locales/bg/rbnf.yml +280 -0
  132. data/resources/locales/bg/territories.yml +264 -263
  133. data/resources/locales/bn/calendars.yml +287 -225
  134. data/resources/locales/bn/currencies.yml +953 -916
  135. data/resources/locales/bn/languages.yml +583 -580
  136. data/resources/locales/bn/layout.yml +5 -5
  137. data/resources/locales/bn/lists.yml +23 -7
  138. data/resources/locales/bn/numbers.yml +62 -57
  139. data/resources/locales/bn/plurals.yml +2 -2
  140. data/resources/locales/bn/rbnf.yml +4 -0
  141. data/resources/locales/bn/territories.yml +264 -263
  142. data/resources/locales/ca/calendars.yml +278 -278
  143. data/resources/locales/ca/currencies.yml +953 -916
  144. data/resources/locales/ca/languages.yml +583 -580
  145. data/resources/locales/ca/layout.yml +5 -5
  146. data/resources/locales/ca/lists.yml +23 -7
  147. data/resources/locales/ca/numbers.yml +62 -57
  148. data/resources/locales/ca/plurals.yml +3 -2
  149. data/resources/locales/ca/rbnf.yml +756 -0
  150. data/resources/locales/ca/territories.yml +264 -263
  151. data/resources/locales/cs/calendars.yml +269 -262
  152. data/resources/locales/cs/currencies.yml +1483 -1172
  153. data/resources/locales/cs/languages.yml +583 -580
  154. data/resources/locales/cs/layout.yml +5 -5
  155. data/resources/locales/cs/lists.yml +23 -7
  156. data/resources/locales/cs/numbers.yml +64 -58
  157. data/resources/locales/cs/plurals.yml +6 -2
  158. data/resources/locales/cs/rbnf.yml +367 -0
  159. data/resources/locales/cs/territories.yml +264 -263
  160. data/resources/locales/cy/calendars.yml +275 -274
  161. data/resources/locales/cy/currencies.yml +1585 -1548
  162. data/resources/locales/cy/languages.yml +583 -580
  163. data/resources/locales/cy/layout.yml +5 -5
  164. data/resources/locales/cy/lists.yml +23 -7
  165. data/resources/locales/cy/numbers.yml +66 -61
  166. data/resources/locales/cy/plurals.yml +4 -3
  167. data/resources/locales/cy/rbnf.yml +298 -0
  168. data/resources/locales/cy/territories.yml +264 -263
  169. data/resources/locales/da/calendars.yml +281 -280
  170. data/resources/locales/da/currencies.yml +954 -916
  171. data/resources/locales/da/languages.yml +583 -580
  172. data/resources/locales/da/layout.yml +5 -5
  173. data/resources/locales/da/lists.yml +23 -7
  174. data/resources/locales/da/numbers.yml +62 -57
  175. data/resources/locales/da/plurals.yml +3 -2
  176. data/resources/locales/da/rbnf.yml +194 -0
  177. data/resources/locales/da/territories.yml +264 -263
  178. data/resources/locales/de/calendars.yml +294 -293
  179. data/resources/locales/de/currencies.yml +954 -916
  180. data/resources/locales/de/languages.yml +583 -580
  181. data/resources/locales/de/layout.yml +5 -5
  182. data/resources/locales/de/lists.yml +23 -7
  183. data/resources/locales/de/numbers.yml +62 -57
  184. data/resources/locales/de/plurals.yml +3 -2
  185. data/resources/locales/de/rbnf.yml +346 -0
  186. data/resources/locales/de/territories.yml +264 -263
  187. data/resources/locales/el/calendars.yml +279 -282
  188. data/resources/locales/el/currencies.yml +954 -916
  189. data/resources/locales/el/languages.yml +583 -580
  190. data/resources/locales/el/layout.yml +5 -5
  191. data/resources/locales/el/lists.yml +23 -7
  192. data/resources/locales/el/numbers.yml +62 -57
  193. data/resources/locales/el/plurals.yml +2 -2
  194. data/resources/locales/el/rbnf.yml +880 -0
  195. data/resources/locales/el/territories.yml +264 -263
  196. data/resources/locales/en/calendars.yml +192 -191
  197. data/resources/locales/en/currencies.yml +953 -915
  198. data/resources/locales/en/languages.yml +583 -580
  199. data/resources/locales/en/layout.yml +5 -5
  200. data/resources/locales/en/lists.yml +23 -7
  201. data/resources/locales/en/numbers.yml +62 -57
  202. data/resources/locales/en/plurals.yml +3 -2
  203. data/resources/locales/en/rbnf.yml +542 -0
  204. data/resources/locales/en/territories.yml +264 -263
  205. data/resources/locales/en-GB/calendars.yml +195 -194
  206. data/resources/locales/en-GB/currencies.yml +953 -915
  207. data/resources/locales/en-GB/languages.yml +583 -580
  208. data/resources/locales/en-GB/layout.yml +5 -5
  209. data/resources/locales/en-GB/lists.yml +23 -7
  210. data/resources/locales/en-GB/numbers.yml +62 -57
  211. data/resources/locales/en-GB/plurals.yml +2 -1
  212. data/resources/locales/en-GB/rbnf.yml +4 -0
  213. data/resources/locales/en-GB/territories.yml +264 -263
  214. data/resources/locales/es/calendars.yml +288 -238
  215. data/resources/locales/es/currencies.yml +953 -922
  216. data/resources/locales/es/languages.yml +583 -580
  217. data/resources/locales/es/layout.yml +5 -5
  218. data/resources/locales/es/lists.yml +23 -7
  219. data/resources/locales/es/numbers.yml +62 -57
  220. data/resources/locales/es/plurals.yml +2 -2
  221. data/resources/locales/es/rbnf.yml +913 -0
  222. data/resources/locales/es/territories.yml +264 -263
  223. data/resources/locales/eu/calendars.yml +277 -218
  224. data/resources/locales/eu/currencies.yml +953 -916
  225. data/resources/locales/eu/languages.yml +583 -580
  226. data/resources/locales/eu/layout.yml +5 -5
  227. data/resources/locales/eu/lists.yml +23 -7
  228. data/resources/locales/eu/numbers.yml +56 -51
  229. data/resources/locales/eu/plurals.yml +2 -2
  230. data/resources/locales/eu/rbnf.yml +4 -0
  231. data/resources/locales/eu/territories.yml +264 -263
  232. data/resources/locales/fa/calendars.yml +294 -293
  233. data/resources/locales/fa/currencies.yml +955 -916
  234. data/resources/locales/fa/languages.yml +583 -580
  235. data/resources/locales/fa/layout.yml +5 -5
  236. data/resources/locales/fa/lists.yml +23 -7
  237. data/resources/locales/fa/numbers.yml +62 -57
  238. data/resources/locales/fa/plurals.yml +2 -2
  239. data/resources/locales/fa/rbnf.yml +157 -0
  240. data/resources/locales/fa/territories.yml +264 -263
  241. data/resources/locales/fi/calendars.yml +284 -283
  242. data/resources/locales/fi/currencies.yml +953 -915
  243. data/resources/locales/fi/languages.yml +583 -580
  244. data/resources/locales/fi/layout.yml +5 -5
  245. data/resources/locales/fi/lists.yml +23 -7
  246. data/resources/locales/fi/numbers.yml +62 -57
  247. data/resources/locales/fi/plurals.yml +3 -2
  248. data/resources/locales/fi/rbnf.yml +206 -0
  249. data/resources/locales/fi/territories.yml +264 -263
  250. data/resources/locales/fil/calendars.yml +281 -230
  251. data/resources/locales/fil/currencies.yml +953 -916
  252. data/resources/locales/fil/languages.yml +583 -580
  253. data/resources/locales/fil/layout.yml +5 -5
  254. data/resources/locales/fil/lists.yml +23 -7
  255. data/resources/locales/fil/numbers.yml +62 -57
  256. data/resources/locales/fil/plurals.yml +3 -2
  257. data/resources/locales/fil/rbnf.yml +158 -0
  258. data/resources/locales/fil/territories.yml +264 -263
  259. data/resources/locales/fr/calendars.yml +297 -296
  260. data/resources/locales/fr/currencies.yml +968 -949
  261. data/resources/locales/fr/languages.yml +583 -580
  262. data/resources/locales/fr/layout.yml +5 -5
  263. data/resources/locales/fr/lists.yml +23 -7
  264. data/resources/locales/fr/numbers.yml +62 -57
  265. data/resources/locales/fr/plurals.yml +2 -2
  266. data/resources/locales/fr/rbnf.yml +621 -0
  267. data/resources/locales/fr/territories.yml +264 -263
  268. data/resources/locales/ga/calendars.yml +192 -191
  269. data/resources/locales/ga/currencies.yml +954 -916
  270. data/resources/locales/ga/languages.yml +583 -580
  271. data/resources/locales/ga/layout.yml +5 -5
  272. data/resources/locales/ga/lists.yml +23 -7
  273. data/resources/locales/ga/numbers.yml +62 -57
  274. data/resources/locales/ga/plurals.yml +4 -3
  275. data/resources/locales/ga/rbnf.yml +615 -0
  276. data/resources/locales/ga/territories.yml +264 -263
  277. data/resources/locales/gl/calendars.yml +283 -217
  278. data/resources/locales/gl/currencies.yml +953 -916
  279. data/resources/locales/gl/languages.yml +583 -580
  280. data/resources/locales/gl/layout.yml +5 -5
  281. data/resources/locales/gl/lists.yml +23 -7
  282. data/resources/locales/gl/numbers.yml +62 -57
  283. data/resources/locales/gl/plurals.yml +3 -2
  284. data/resources/locales/gl/rbnf.yml +4 -0
  285. data/resources/locales/gl/territories.yml +264 -263
  286. data/resources/locales/he/calendars.yml +248 -220
  287. data/resources/locales/he/currencies.yml +992 -932
  288. data/resources/locales/he/languages.yml +583 -580
  289. data/resources/locales/he/layout.yml +5 -5
  290. data/resources/locales/he/lists.yml +23 -7
  291. data/resources/locales/he/numbers.yml +64 -59
  292. data/resources/locales/he/plurals.yml +6 -3
  293. data/resources/locales/he/rbnf.yml +1029 -0
  294. data/resources/locales/he/territories.yml +264 -263
  295. data/resources/locales/hi/calendars.yml +284 -216
  296. data/resources/locales/hi/currencies.yml +953 -915
  297. data/resources/locales/hi/languages.yml +583 -580
  298. data/resources/locales/hi/layout.yml +5 -5
  299. data/resources/locales/hi/lists.yml +23 -7
  300. data/resources/locales/hi/numbers.yml +60 -55
  301. data/resources/locales/hi/plurals.yml +2 -2
  302. data/resources/locales/hi/rbnf.yml +430 -0
  303. data/resources/locales/hi/territories.yml +264 -263
  304. data/resources/locales/hr/calendars.yml +308 -307
  305. data/resources/locales/hr/currencies.yml +1248 -1504
  306. data/resources/locales/hr/languages.yml +583 -580
  307. data/resources/locales/hr/layout.yml +5 -5
  308. data/resources/locales/hr/lists.yml +23 -7
  309. data/resources/locales/hr/numbers.yml +63 -59
  310. data/resources/locales/hr/plurals.yml +12 -4
  311. data/resources/locales/hr/rbnf.yml +599 -0
  312. data/resources/locales/hr/territories.yml +264 -263
  313. data/resources/locales/hu/calendars.yml +285 -284
  314. data/resources/locales/hu/currencies.yml +954 -916
  315. data/resources/locales/hu/languages.yml +583 -580
  316. data/resources/locales/hu/layout.yml +5 -5
  317. data/resources/locales/hu/lists.yml +23 -7
  318. data/resources/locales/hu/numbers.yml +62 -57
  319. data/resources/locales/hu/plurals.yml +2 -2
  320. data/resources/locales/hu/rbnf.yml +363 -0
  321. data/resources/locales/hu/territories.yml +264 -263
  322. data/resources/locales/id/calendars.yml +276 -275
  323. data/resources/locales/id/currencies.yml +954 -916
  324. data/resources/locales/id/languages.yml +583 -580
  325. data/resources/locales/id/layout.yml +5 -5
  326. data/resources/locales/id/lists.yml +23 -7
  327. data/resources/locales/id/numbers.yml +61 -56
  328. data/resources/locales/id/plurals.yml +2 -2
  329. data/resources/locales/id/rbnf.yml +121 -0
  330. data/resources/locales/id/territories.yml +264 -263
  331. data/resources/locales/is/calendars.yml +281 -242
  332. data/resources/locales/is/currencies.yml +954 -916
  333. data/resources/locales/is/languages.yml +583 -580
  334. data/resources/locales/is/layout.yml +5 -5
  335. data/resources/locales/is/lists.yml +23 -7
  336. data/resources/locales/is/numbers.yml +62 -57
  337. data/resources/locales/is/plurals.yml +5 -2
  338. data/resources/locales/is/rbnf.yml +326 -0
  339. data/resources/locales/is/territories.yml +264 -263
  340. data/resources/locales/it/calendars.yml +275 -260
  341. data/resources/locales/it/currencies.yml +953 -920
  342. data/resources/locales/it/languages.yml +583 -580
  343. data/resources/locales/it/layout.yml +5 -5
  344. data/resources/locales/it/lists.yml +23 -7
  345. data/resources/locales/it/numbers.yml +59 -54
  346. data/resources/locales/it/plurals.yml +3 -2
  347. data/resources/locales/it/rbnf.yml +1189 -0
  348. data/resources/locales/it/territories.yml +264 -263
  349. data/resources/locales/ja/calendars.yml +269 -207
  350. data/resources/locales/ja/currencies.yml +953 -915
  351. data/resources/locales/ja/languages.yml +583 -580
  352. data/resources/locales/ja/layout.yml +5 -5
  353. data/resources/locales/ja/lists.yml +23 -7
  354. data/resources/locales/ja/numbers.yml +62 -57
  355. data/resources/locales/ja/plurals.yml +2 -2
  356. data/resources/locales/ja/rbnf.yml +209 -0
  357. data/resources/locales/ja/territories.yml +264 -263
  358. data/resources/locales/ko/calendars.yml +246 -213
  359. data/resources/locales/ko/currencies.yml +953 -915
  360. data/resources/locales/ko/languages.yml +583 -580
  361. data/resources/locales/ko/layout.yml +5 -5
  362. data/resources/locales/ko/lists.yml +23 -7
  363. data/resources/locales/ko/numbers.yml +60 -55
  364. data/resources/locales/ko/plurals.yml +2 -2
  365. data/resources/locales/ko/rbnf.yml +722 -0
  366. data/resources/locales/ko/territories.yml +264 -263
  367. data/resources/locales/lv/calendars.yml +286 -285
  368. data/resources/locales/lv/currencies.yml +1122 -1084
  369. data/resources/locales/lv/languages.yml +583 -580
  370. data/resources/locales/lv/layout.yml +5 -5
  371. data/resources/locales/lv/lists.yml +23 -7
  372. data/resources/locales/lv/numbers.yml +63 -58
  373. data/resources/locales/lv/plurals.yml +11 -3
  374. data/resources/locales/lv/rbnf.yml +238 -0
  375. data/resources/locales/lv/territories.yml +264 -263
  376. data/resources/locales/ms/calendars.yml +280 -279
  377. data/resources/locales/ms/currencies.yml +954 -916
  378. data/resources/locales/ms/languages.yml +583 -580
  379. data/resources/locales/ms/layout.yml +5 -5
  380. data/resources/locales/ms/lists.yml +23 -7
  381. data/resources/locales/ms/numbers.yml +62 -57
  382. data/resources/locales/ms/plurals.yml +2 -2
  383. data/resources/locales/ms/rbnf.yml +130 -0
  384. data/resources/locales/ms/territories.yml +264 -263
  385. data/resources/locales/nb/calendars.yml +284 -283
  386. data/resources/locales/nb/currencies.yml +958 -916
  387. data/resources/locales/nb/languages.yml +583 -580
  388. data/resources/locales/nb/layout.yml +5 -5
  389. data/resources/locales/nb/lists.yml +23 -7
  390. data/resources/locales/nb/numbers.yml +62 -57
  391. data/resources/locales/nb/plurals.yml +2 -2
  392. data/resources/locales/nb/rbnf.yml +191 -0
  393. data/resources/locales/nb/territories.yml +264 -263
  394. data/resources/locales/nl/calendars.yml +285 -284
  395. data/resources/locales/nl/currencies.yml +953 -917
  396. data/resources/locales/nl/languages.yml +583 -580
  397. data/resources/locales/nl/layout.yml +5 -5
  398. data/resources/locales/nl/lists.yml +23 -7
  399. data/resources/locales/nl/numbers.yml +62 -57
  400. data/resources/locales/nl/plurals.yml +3 -2
  401. data/resources/locales/nl/rbnf.yml +320 -0
  402. data/resources/locales/nl/territories.yml +264 -263
  403. data/resources/locales/pl/calendars.yml +288 -287
  404. data/resources/locales/pl/currencies.yml +1326 -1284
  405. data/resources/locales/pl/languages.yml +583 -580
  406. data/resources/locales/pl/layout.yml +5 -5
  407. data/resources/locales/pl/lists.yml +23 -7
  408. data/resources/locales/pl/numbers.yml +64 -59
  409. data/resources/locales/pl/plurals.yml +11 -4
  410. data/resources/locales/pl/rbnf.yml +410 -0
  411. data/resources/locales/pl/territories.yml +264 -263
  412. data/resources/locales/pt/calendars.yml +290 -289
  413. data/resources/locales/pt/currencies.yml +954 -916
  414. data/resources/locales/pt/languages.yml +583 -580
  415. data/resources/locales/pt/layout.yml +5 -5
  416. data/resources/locales/pt/lists.yml +23 -7
  417. data/resources/locales/pt/numbers.yml +62 -57
  418. data/resources/locales/pt/plurals.yml +4 -2
  419. data/resources/locales/pt/rbnf.yml +586 -0
  420. data/resources/locales/pt/territories.yml +264 -263
  421. data/resources/locales/ro/calendars.yml +284 -283
  422. data/resources/locales/ro/currencies.yml +1170 -1132
  423. data/resources/locales/ro/languages.yml +583 -580
  424. data/resources/locales/ro/layout.yml +5 -5
  425. data/resources/locales/ro/lists.yml +23 -7
  426. data/resources/locales/ro/numbers.yml +63 -58
  427. data/resources/locales/ro/plurals.yml +5 -2
  428. data/resources/locales/ro/rbnf.yml +250 -0
  429. data/resources/locales/ro/territories.yml +264 -263
  430. data/resources/locales/ru/calendars.yml +282 -281
  431. data/resources/locales/ru/currencies.yml +1118 -1247
  432. data/resources/locales/ru/languages.yml +583 -580
  433. data/resources/locales/ru/layout.yml +5 -5
  434. data/resources/locales/ru/lists.yml +23 -7
  435. data/resources/locales/ru/numbers.yml +63 -59
  436. data/resources/locales/ru/plurals.yml +8 -4
  437. data/resources/locales/ru/rbnf.yml +385 -0
  438. data/resources/locales/ru/territories.yml +264 -263
  439. data/resources/locales/sk/calendars.yml +254 -251
  440. data/resources/locales/sk/currencies.yml +1174 -1008
  441. data/resources/locales/sk/languages.yml +583 -580
  442. data/resources/locales/sk/layout.yml +5 -5
  443. data/resources/locales/sk/lists.yml +23 -7
  444. data/resources/locales/sk/numbers.yml +64 -58
  445. data/resources/locales/sk/plurals.yml +6 -2
  446. data/resources/locales/sk/rbnf.yml +304 -0
  447. data/resources/locales/sk/territories.yml +264 -263
  448. data/resources/locales/sq/calendars.yml +283 -206
  449. data/resources/locales/sq/currencies.yml +954 -916
  450. data/resources/locales/sq/languages.yml +583 -580
  451. data/resources/locales/sq/layout.yml +5 -5
  452. data/resources/locales/sq/lists.yml +23 -7
  453. data/resources/locales/sq/numbers.yml +62 -57
  454. data/resources/locales/sq/plurals.yml +2 -2
  455. data/resources/locales/sq/rbnf.yml +181 -0
  456. data/resources/locales/sq/territories.yml +264 -263
  457. data/resources/locales/sr/calendars.yml +290 -289
  458. data/resources/locales/sr/currencies.yml +1251 -1508
  459. data/resources/locales/sr/languages.yml +583 -580
  460. data/resources/locales/sr/layout.yml +5 -5
  461. data/resources/locales/sr/lists.yml +23 -7
  462. data/resources/locales/sr/numbers.yml +62 -58
  463. data/resources/locales/sr/plurals.yml +12 -4
  464. data/resources/locales/sr/rbnf.yml +429 -0
  465. data/resources/locales/sr/territories.yml +264 -263
  466. data/resources/locales/sv/calendars.yml +290 -289
  467. data/resources/locales/sv/currencies.yml +960 -930
  468. data/resources/locales/sv/languages.yml +583 -580
  469. data/resources/locales/sv/layout.yml +5 -5
  470. data/resources/locales/sv/lists.yml +23 -7
  471. data/resources/locales/sv/numbers.yml +63 -58
  472. data/resources/locales/sv/plurals.yml +3 -2
  473. data/resources/locales/sv/rbnf.yml +692 -0
  474. data/resources/locales/sv/territories.yml +264 -263
  475. data/resources/locales/ta/calendars.yml +281 -266
  476. data/resources/locales/ta/currencies.yml +953 -915
  477. data/resources/locales/ta/languages.yml +583 -580
  478. data/resources/locales/ta/layout.yml +5 -5
  479. data/resources/locales/ta/lists.yml +23 -7
  480. data/resources/locales/ta/numbers.yml +62 -57
  481. data/resources/locales/ta/plurals.yml +2 -2
  482. data/resources/locales/ta/rbnf.yml +241 -0
  483. data/resources/locales/ta/territories.yml +264 -263
  484. data/resources/locales/th/calendars.yml +278 -289
  485. data/resources/locales/th/currencies.yml +953 -915
  486. data/resources/locales/th/languages.yml +583 -580
  487. data/resources/locales/th/layout.yml +5 -5
  488. data/resources/locales/th/lists.yml +23 -7
  489. data/resources/locales/th/numbers.yml +62 -57
  490. data/resources/locales/th/plurals.yml +2 -2
  491. data/resources/locales/th/rbnf.yml +119 -0
  492. data/resources/locales/th/territories.yml +264 -263
  493. data/resources/locales/tr/calendars.yml +287 -286
  494. data/resources/locales/tr/currencies.yml +953 -916
  495. data/resources/locales/tr/languages.yml +583 -580
  496. data/resources/locales/tr/layout.yml +5 -5
  497. data/resources/locales/tr/lists.yml +23 -7
  498. data/resources/locales/tr/numbers.yml +61 -56
  499. data/resources/locales/tr/plurals.yml +2 -2
  500. data/resources/locales/tr/rbnf.yml +277 -0
  501. data/resources/locales/tr/territories.yml +264 -263
  502. data/resources/locales/uk/calendars.yml +286 -252
  503. data/resources/locales/uk/currencies.yml +1311 -1070
  504. data/resources/locales/uk/languages.yml +583 -580
  505. data/resources/locales/uk/layout.yml +5 -5
  506. data/resources/locales/uk/lists.yml +23 -7
  507. data/resources/locales/uk/numbers.yml +64 -59
  508. data/resources/locales/uk/plurals.yml +10 -4
  509. data/resources/locales/uk/rbnf.yml +430 -0
  510. data/resources/locales/uk/territories.yml +264 -263
  511. data/resources/locales/ur/calendars.yml +267 -228
  512. data/resources/locales/ur/currencies.yml +954 -916
  513. data/resources/locales/ur/languages.yml +583 -580
  514. data/resources/locales/ur/layout.yml +5 -5
  515. data/resources/locales/ur/lists.yml +23 -7
  516. data/resources/locales/ur/numbers.yml +62 -57
  517. data/resources/locales/ur/plurals.yml +3 -2
  518. data/resources/locales/ur/rbnf.yml +4 -0
  519. data/resources/locales/ur/territories.yml +264 -263
  520. data/resources/locales/vi/calendars.yml +256 -236
  521. data/resources/locales/vi/currencies.yml +953 -915
  522. data/resources/locales/vi/languages.yml +583 -580
  523. data/resources/locales/vi/layout.yml +5 -5
  524. data/resources/locales/vi/lists.yml +23 -7
  525. data/resources/locales/vi/numbers.yml +62 -57
  526. data/resources/locales/vi/plurals.yml +2 -2
  527. data/resources/locales/vi/rbnf.yml +164 -0
  528. data/resources/locales/vi/territories.yml +264 -263
  529. data/resources/locales/zh/calendars.yml +266 -265
  530. data/resources/locales/zh/currencies.yml +953 -915
  531. data/resources/locales/zh/languages.yml +583 -580
  532. data/resources/locales/zh/layout.yml +5 -5
  533. data/resources/locales/zh/lists.yml +23 -7
  534. data/resources/locales/zh/numbers.yml +62 -57
  535. data/resources/locales/zh/plurals.yml +2 -2
  536. data/resources/locales/zh/rbnf.yml +689 -0
  537. data/resources/locales/zh/territories.yml +264 -263
  538. data/resources/locales/zh-Hant/calendars.yml +266 -265
  539. data/resources/locales/zh-Hant/currencies.yml +955 -915
  540. data/resources/locales/zh-Hant/languages.yml +583 -580
  541. data/resources/locales/zh-Hant/layout.yml +5 -5
  542. data/resources/locales/zh-Hant/lists.yml +23 -7
  543. data/resources/locales/zh-Hant/numbers.yml +62 -57
  544. data/resources/locales/zh-Hant/plurals.yml +2 -2
  545. data/resources/locales/zh-Hant/rbnf.yml +647 -0
  546. data/resources/locales/zh-Hant/territories.yml +264 -263
  547. data/resources/shared/currency_digits_and_rounding.yml +67 -64
  548. data/resources/shared/numbering_systems.yml +176 -0
  549. data/resources/shared/rbnf_root.yml +1573 -0
  550. data/resources/shared/segments/segments_root.yml +728 -0
  551. data/resources/shared/segments/tailorings/en.yml +8 -0
  552. data/resources/uli/segments/de.yml +128 -0
  553. data/resources/uli/segments/en.yml +154 -0
  554. data/resources/uli/segments/es.yml +112 -0
  555. data/resources/uli/segments/fr.yml +47 -0
  556. data/resources/uli/segments/it.yml +37 -0
  557. data/resources/uli/segments/pt.yml +173 -0
  558. data/resources/uli/segments/ru.yml +10 -0
  559. data/resources/unicode_data/casefolding.yml +4765 -0
  560. data/resources/unicode_data/indices/bidi_class.yml +4572 -0
  561. data/resources/unicode_data/indices/bidi_mirrored.yml +3087 -0
  562. data/resources/unicode_data/indices/category.yml +10918 -0
  563. data/resources/unicode_data/indices/keys.yml +101 -0
  564. data/resources/unicode_data/properties/line_break.yml +9269 -0
  565. data/resources/unicode_data/properties/sentence_break.yml +8067 -0
  566. data/resources/unicode_data/properties/word_break.yml +3001 -0
  567. data/spec/collation/collation_spec.rb +2 -1
  568. data/spec/collation/collator_spec.rb +4 -3
  569. data/spec/collation/tailoring_spec.rb +2 -2
  570. data/spec/collation/tailoring_tests/he.txt +5 -2
  571. data/spec/{tokenizers/calendars → data_readers}/additional_date_format_selector_spec.rb +13 -13
  572. data/spec/data_readers/date_time_data_reader_spec.rb +26 -0
  573. data/spec/data_readers/number_data_reader_spec.rb +18 -0
  574. data/spec/data_readers/timespan_data_reader.rb +22 -0
  575. data/spec/formatters/calendars/datetime_formatter_spec.rb +18 -22
  576. data/spec/formatters/list_formatter_spec.rb +16 -87
  577. data/spec/formatters/numbers/abbreviated/abbreviated_number_formatter_spec.rb +15 -59
  578. data/spec/formatters/numbers/abbreviated/long_decimal_formatter_spec.rb +32 -17
  579. data/spec/formatters/numbers/abbreviated/short_decimal_formatter_spec.rb +33 -17
  580. data/spec/formatters/numbers/currency_formatter_spec.rb +18 -13
  581. data/spec/formatters/numbers/decimal_formatter_spec.rb +16 -18
  582. data/spec/formatters/numbers/number_formatter_spec.rb +40 -31
  583. data/spec/formatters/numbers/percent_formatter_spec.rb +14 -6
  584. data/spec/formatters/numbers/rbnf/allowed_failures.yml +74 -0
  585. data/spec/formatters/numbers/rbnf/locales/af/rbnf_test.yml +706 -0
  586. data/spec/formatters/numbers/rbnf/locales/ar/rbnf_test.yml +706 -0
  587. data/spec/formatters/numbers/rbnf/locales/be/rbnf_test.yml +1174 -0
  588. data/spec/formatters/numbers/rbnf/locales/bg/rbnf_test.yml +706 -0
  589. data/spec/formatters/numbers/rbnf/locales/bn/rbnf_test.yml +1291 -0
  590. data/spec/formatters/numbers/rbnf/locales/ca/rbnf_test.yml +1174 -0
  591. data/spec/formatters/numbers/rbnf/locales/cs/rbnf_test.yml +823 -0
  592. data/spec/formatters/numbers/rbnf/locales/cy/rbnf_test.yml +940 -0
  593. data/spec/formatters/numbers/rbnf/locales/da/rbnf_test.yml +940 -0
  594. data/spec/formatters/numbers/rbnf/locales/de/rbnf_test.yml +940 -0
  595. data/spec/formatters/numbers/rbnf/locales/el/rbnf_test.yml +1174 -0
  596. data/spec/formatters/numbers/rbnf/locales/en/rbnf_test.yml +1291 -0
  597. data/spec/formatters/numbers/rbnf/locales/en-GB/rbnf_test.yml +1291 -0
  598. data/spec/formatters/numbers/rbnf/locales/es/rbnf_test.yml +1642 -0
  599. data/spec/formatters/numbers/rbnf/locales/eu/rbnf_test.yml +1291 -0
  600. data/spec/formatters/numbers/rbnf/locales/fa/rbnf_test.yml +589 -0
  601. data/spec/formatters/numbers/rbnf/locales/fi/rbnf_test.yml +706 -0
  602. data/spec/formatters/numbers/rbnf/locales/fil/rbnf_test.yml +706 -0
  603. data/spec/formatters/numbers/rbnf/locales/fr/rbnf_test.yml +1408 -0
  604. data/spec/formatters/numbers/rbnf/locales/ga/rbnf_test.yml +940 -0
  605. data/spec/formatters/numbers/rbnf/locales/gl/rbnf_test.yml +1291 -0
  606. data/spec/formatters/numbers/rbnf/locales/he/rbnf_test.yml +1057 -0
  607. data/spec/formatters/numbers/rbnf/locales/hi/rbnf_test.yml +823 -0
  608. data/spec/formatters/numbers/rbnf/locales/hr/rbnf_test.yml +1174 -0
  609. data/spec/formatters/numbers/rbnf/locales/hu/rbnf_test.yml +940 -0
  610. data/spec/formatters/numbers/rbnf/locales/id/rbnf_test.yml +706 -0
  611. data/spec/formatters/numbers/rbnf/locales/is/rbnf_test.yml +823 -0
  612. data/spec/formatters/numbers/rbnf/locales/it/rbnf_test.yml +1174 -0
  613. data/spec/formatters/numbers/rbnf/locales/ja/rbnf_test.yml +823 -0
  614. data/spec/formatters/numbers/rbnf/locales/ko/rbnf_test.yml +1408 -0
  615. data/spec/formatters/numbers/rbnf/locales/lv/rbnf_test.yml +706 -0
  616. data/spec/formatters/numbers/rbnf/locales/ms/rbnf_test.yml +706 -0
  617. data/spec/formatters/numbers/rbnf/locales/nb/rbnf_test.yml +940 -0
  618. data/spec/formatters/numbers/rbnf/locales/nl/rbnf_test.yml +706 -0
  619. data/spec/formatters/numbers/rbnf/locales/pl/rbnf_test.yml +823 -0
  620. data/spec/formatters/numbers/rbnf/locales/pt/rbnf_test.yml +1174 -0
  621. data/spec/formatters/numbers/rbnf/locales/ro/rbnf_test.yml +823 -0
  622. data/spec/formatters/numbers/rbnf/locales/ru/rbnf_test.yml +823 -0
  623. data/spec/formatters/numbers/rbnf/locales/sk/rbnf_test.yml +823 -0
  624. data/spec/formatters/numbers/rbnf/locales/sq/rbnf_test.yml +706 -0
  625. data/spec/formatters/numbers/rbnf/locales/sr/rbnf_test.yml +940 -0
  626. data/spec/formatters/numbers/rbnf/locales/sv/rbnf_test.yml +1876 -0
  627. data/spec/formatters/numbers/rbnf/locales/ta/rbnf_test.yml +706 -0
  628. data/spec/formatters/numbers/rbnf/locales/th/rbnf_test.yml +706 -0
  629. data/spec/formatters/numbers/rbnf/locales/tr/rbnf_test.yml +706 -0
  630. data/spec/formatters/numbers/rbnf/locales/uk/rbnf_test.yml +823 -0
  631. data/spec/formatters/numbers/rbnf/locales/ur/rbnf_test.yml +1291 -0
  632. data/spec/formatters/numbers/rbnf/locales/vi/rbnf_test.yml +706 -0
  633. data/spec/formatters/numbers/rbnf/locales/zh/rbnf_test.yml +940 -0
  634. data/spec/formatters/numbers/rbnf/locales/zh-Hant/rbnf_test.yml +940 -0
  635. data/spec/formatters/numbers/rbnf/rbnf_spec.rb +98 -0
  636. data/spec/formatters/plurals/plural_formatter_spec.rb +4 -4
  637. data/spec/formatters/plurals/rules_spec.rb +5 -5
  638. data/spec/localized/localized_date_spec.rb +1 -1
  639. data/spec/localized/localized_datetime_spec.rb +8 -13
  640. data/spec/localized/localized_number_spec.rb +17 -32
  641. data/spec/localized/localized_object_spec.rb +0 -5
  642. data/spec/localized/localized_string_spec.rb +40 -2
  643. data/spec/localized/localized_time_spec.rb +3 -6
  644. data/spec/localized/localized_timespan_spec.rb +144 -0
  645. data/spec/normalization_spec.rb +12 -12
  646. data/spec/parsers/number_parser_spec.rb +5 -5
  647. data/spec/parsers/parser_spec.rb +60 -0
  648. data/spec/parsers/segmentation_parser_spec.rb +96 -0
  649. data/spec/parsers/symbol_table_spec.rb +32 -0
  650. data/spec/parsers/unicode_regex/character_class_spec.rb +117 -0
  651. data/spec/parsers/unicode_regex/character_range_spec.rb +21 -0
  652. data/spec/parsers/unicode_regex/character_set_spec.rb +36 -0
  653. data/spec/parsers/unicode_regex/literal_spec.rb +34 -0
  654. data/spec/parsers/unicode_regex/unicode_string_spec.rb +22 -0
  655. data/spec/parsers/unicode_regex_parser_spec.rb +86 -0
  656. data/spec/readme_spec.rb +8 -269
  657. data/spec/shared/break_iterator_spec.rb +72 -0
  658. data/spec/shared/calendar_spec.rb +5 -4
  659. data/spec/shared/casefolder_spec.rb +30 -0
  660. data/spec/shared/casefolding.txt +251 -0
  661. data/spec/shared/casefolding_expected.txt +251 -0
  662. data/spec/shared/code_point_spec.rb +44 -14
  663. data/spec/shared/numbering_system_spec.rb +41 -0
  664. data/spec/shared/territories_spec.rb +14 -6
  665. data/spec/shared/unicode_regex_spec.rb +203 -0
  666. data/spec/spec_helper.rb +17 -0
  667. data/spec/tokenizers/calendars/date_tokenizer_spec.rb +26 -30
  668. data/spec/tokenizers/calendars/datetime_tokenizer_spec.rb +11 -90
  669. data/spec/tokenizers/calendars/time_tokenizer_spec.rb +5 -5
  670. data/spec/tokenizers/calendars/timespan_tokenizer_spec.rb +17 -7
  671. data/spec/tokenizers/numbers/number_tokenizer_spec.rb +28 -27
  672. data/spec/tokenizers/segmentation/segmentation_tokenizer_spec.rb +40 -0
  673. data/spec/tokenizers/unicode_regex/unicode_regex_tokenizer_spec.rb +190 -0
  674. data/spec/utils/range_set_spec.rb +171 -0
  675. data/spec/utils/yaml/yaml_spec.rb +62 -51
  676. data/twitter_cldr.gemspec +1 -1
  677. metadata +199 -30
  678. data/lib/twitter_cldr/formatters/base.rb +0 -47
  679. data/lib/twitter_cldr/formatters/calendars/date_formatter.rb +0 -19
  680. data/lib/twitter_cldr/formatters/calendars/time_formatter.rb +0 -19
  681. data/lib/twitter_cldr/normalization/base.rb +0 -37
  682. data/lib/twitter_cldr/normalization/hangul.rb +0 -79
  683. data/lib/twitter_cldr/normalization/nfc.rb +0 -24
  684. data/lib/twitter_cldr/normalization/nfd.rb +0 -26
  685. data/lib/twitter_cldr/normalization/nfkc.rb +0 -114
  686. data/lib/twitter_cldr/normalization/nfkd.rb +0 -120
  687. data/lib/twitter_cldr/normalization/quick_check.rb +0 -41
  688. data/lib/twitter_cldr/tokenizers/base.rb +0 -169
  689. data/lib/twitter_cldr/tokenizers/calendars/datetime_tokenizer.rb +0 -131
  690. data/lib/twitter_cldr/utils/territories.rb +0 -56
  691. data/spec/formatters/base_spec.rb +0 -18
  692. data/spec/formatters/calendars/timespan_formatter_spec.rb +0 -112
  693. data/spec/normalization/NormalizationTestShort.txt +0 -602
  694. data/spec/normalization/base_spec.rb +0 -16
  695. data/spec/normalization/hangul_spec.rb +0 -42
  696. data/spec/normalization/normalization_spec.rb +0 -113
  697. data/spec/tokenizers/base_spec.rb +0 -259
  698. data/spec/utils/territories_spec.rb +0 -16
@@ -0,0 +1,259 @@
1
+ # encoding: UTF-8
2
+
3
+ # Copyright 2012 Twitter, Inc
4
+ # http://www.apache.org/licenses/LICENSE-2.0
5
+
6
+ require 'bigdecimal'
7
+
8
+ module TwitterCldr
9
+ module Formatters
10
+ module Rbnf
11
+
12
+ RuleSet = Struct.new(:rules, :name, :access) do
13
+ def rule_for_value(base_value)
14
+ if idx = rule_index_for(base_value)
15
+ rules[idx]
16
+ end
17
+ end
18
+
19
+ def previous_rule_for(rule)
20
+ if idx = rule_index_for(rule.base_value)
21
+ rules[idx - 1] if idx > 0
22
+ end
23
+ end
24
+
25
+ def master_rule
26
+ rule_for_value(Rule::MASTER)
27
+ end
28
+
29
+ def improper_fraction_rule
30
+ rule_for_value(Rule::IMPROPER_FRACTION)
31
+ end
32
+
33
+ def proper_fraction_rule
34
+ rule_for_value(Rule::PROPER_FRACTION)
35
+ end
36
+
37
+ def negative_rule
38
+ rule_for_value(Rule::NEGATIVE)
39
+ end
40
+
41
+ def private?
42
+ access == "private"
43
+ end
44
+
45
+ def public?
46
+ access == "public"
47
+ end
48
+
49
+ def each_numeric_rule
50
+ if block_given?
51
+ search_start_index.upto(rules.size - 1) do |i|
52
+ yield rules[i]
53
+ end
54
+ else
55
+ to_enum(:each_numeric_rule)
56
+ end
57
+ end
58
+
59
+ # fractional: i.e. whether or not to consider the rule set a "fractional" rule set (special rules apply)
60
+ def rule_for(number, fractional = false)
61
+ if fractional
62
+ fractional_rule_for(number)
63
+ else
64
+ normal_rule_for(number)
65
+ end
66
+ end
67
+
68
+ private
69
+
70
+ # Adapted from: http://grepcode.com/file/repo1.maven.org/maven2/com.ibm.icu/icu4j/51.2/com/ibm/icu/text/NFRuleSet.java#NFRuleSet.findFractionRuleSetRule%28double%29
71
+ def fractional_rule_for(number)
72
+ # the obvious way to do this (multiply the value being formatted
73
+ # by each rule's base value until you get an integral result)
74
+ # doesn't work because of rounding error. This method is more
75
+ # accurate
76
+
77
+ # find the least common multiple of the rules' base values
78
+ # and multiply this by the number being formatted. This is
79
+ # all the precision we need, and we can do all of the rest
80
+ # of the math using integer arithmetic
81
+ index = search_start_index
82
+ index += 1 while rules[index].base_value == 0
83
+ least_common_multiple = rules[index].base_value
84
+
85
+ (index + 1).upto(rules.size - 1) do |i|
86
+ least_common_multiple = lcm(least_common_multiple, rules[i].base_value)
87
+ end
88
+
89
+ numerator = (number * least_common_multiple).round
90
+
91
+ # for each rule, do the following...
92
+ difference = 10 ** 30 # some absurdly large number
93
+ winner = 0;
94
+
95
+ index.upto(rules.size - 1) do |i|
96
+ # "numerator" is the numerator of the fraction is the
97
+ # denominator is the LCD. The numerator if the the rule's
98
+ # base value is the denomiator is "numerator" times the
99
+ # base value divided bythe LCD. Here we check to see if
100
+ # that's an integer, and if not, how close it is to being
101
+ # an integer.
102
+ temp_difference = numerator * BigDecimal.new(rules[i].base_value) % least_common_multiple
103
+
104
+ # normalize the result of the above calculation: we want
105
+ # the numerator's distance from the CLOSEST multiple
106
+ # of the LCD
107
+ if (least_common_multiple - temp_difference) < temp_difference
108
+ temp_difference = least_common_multiple - temp_difference
109
+ end
110
+
111
+ # if this is as close as we've come, keep track of how close
112
+ # that is, and the line number of the rule that did it. If
113
+ # we've scored a direct hit, we don't have to look at any more
114
+ # rules
115
+ if temp_difference < difference
116
+ difference = temp_difference
117
+ winner = i
118
+
119
+ break if difference == 0
120
+ end
121
+ end
122
+
123
+ # if we have two successive rules that both have the winning base
124
+ # value, then the first one (the one we found above) is used if
125
+ # the numerator of the fraction is 1 and the second one is used if
126
+ # the numerator of the fraction is anything else (this lets us
127
+ # do things like "one third"/"two thirds" without haveing to define
128
+ # a whole bunch of extra rule sets)
129
+ if (winner + 1) < rules.length && rules[winner + 1].base_value == rules[winner].base_value
130
+ if (number * rules[winner].base_value).round < 1 || (number * rules[winner].base_value).round >= 2
131
+ winner += 1
132
+ end
133
+ end
134
+
135
+ # finally, return the winning rule
136
+ rules[winner]
137
+ end
138
+
139
+ # Adapted from: http://grepcode.com/file/repo1.maven.org/maven2/com.ibm.icu/icu4j/51.2/com/ibm/icu/text/NFRuleSet.java#NFRuleSet.lcm%28long%2Clong%29
140
+ def lcm(x, y)
141
+ # binary gcd algorithm from Knuth, "The Art of Computer Programming,"
142
+ # vol. 2, 1st ed., pp. 298-299
143
+ x1 = x
144
+ y1 = y
145
+ p2 = 0
146
+
147
+ while (x1 & 1) == 0 && (y1 & 1) == 0
148
+ p2 += 1
149
+ x1 >>= 1
150
+ y1 >>= 1
151
+ end
152
+
153
+ t = (x1 & 1) == 1 ? -y1 : x1
154
+
155
+ while t != 0
156
+ t >>= 1 while (t & 1) == 0
157
+ t > 0 ? x1 = t : y1 = -t
158
+ t = x1 - y1
159
+ end
160
+
161
+ gcd = x1 << p2
162
+ x / gcd * y
163
+ end
164
+
165
+ # If the rule set is a regular rule set, do the following:
166
+ #
167
+ # If the rule set includes a master rule (and the number was passed in as a double), use the master rule. (If the number being formatted was passed in as a long, the master rule is ignored.)
168
+ # If the number is negative, use the negative-number rule.
169
+ # If the number has a fractional part and is greater than 1, use the improper fraction rule.
170
+ # If the number has a fractional part and is between 0 and 1, use the proper fraction rule.
171
+ # Binary-search the rule list for the rule with the highest base value less than or equal to the number. If that rule has two substitutions, its base value is not an even multiple of its divisor, and the number is an even multiple of the rule's divisor, use the rule that precedes it in the rule list. Otherwise, use the rule itself.
172
+
173
+ def normal_rule_for(number)
174
+ if rule = master_rule
175
+ rule
176
+ elsif number < 0 && rule = negative_rule
177
+ rule
178
+ elsif contains_fraction?(number) && number > 1 && rule = improper_fraction_rule
179
+ rule
180
+ elsif contains_fraction?(number) && number > 0 && number < 1 && rule = proper_fraction_rule
181
+ rule
182
+ else
183
+ if rule = rule_for_value(number.abs)
184
+ use_prev_rule = rule.substitution_count == 2 &&
185
+ !rule.even_multiple_of?(rule.base_value) &&
186
+ rule.even_multiple_of?(number)
187
+
188
+ if use_prev_rule
189
+ previous_rule_for(rule)
190
+ else
191
+ rule
192
+ end
193
+ else
194
+ rules[search_start_index] || rules.first
195
+ end
196
+ end
197
+ end
198
+
199
+ def contains_fraction?(number)
200
+ number != number.floor
201
+ end
202
+
203
+ def rule_index_for(base_value)
204
+ if rule_index = special_rule_index_for(base_value)
205
+ return rule_index
206
+ end
207
+
208
+ if is_numeric?(base_value)
209
+ # binary search (base_value must be a number for this to work)
210
+ low = search_start_index
211
+ high = rules.size - 1
212
+
213
+ while low <= high
214
+ mid = (low + high) / 2
215
+
216
+ case
217
+ when rules[mid].base_value > base_value
218
+ high = mid - 1
219
+ when rules[mid].base_value < base_value
220
+ low = mid + 1
221
+ else
222
+ break
223
+ end
224
+ end
225
+
226
+ # Binary-search the rule list for the rule with the highest base value less than or equal to the number.
227
+ if rules[mid].base_value <= base_value
228
+ mid
229
+ else
230
+ mid > 0 ? mid - 1 : mid
231
+ end
232
+ end
233
+ end
234
+
235
+ def special_rule_index_for(base_value)
236
+ (0...search_start_index).each do |i|
237
+ if rules[i].base_value == base_value
238
+ return i
239
+ end
240
+ end
241
+ nil
242
+ end
243
+
244
+ def search_start_index
245
+ @search_start_index ||= begin
246
+ rules.find_index do |rule|
247
+ is_numeric?(rule.base_value)
248
+ end || 0
249
+ end
250
+ end
251
+
252
+ def is_numeric?(val)
253
+ !!(val.to_s =~ /\A[\d]+\.?[\d]{0,}\z/)
254
+ end
255
+ end
256
+
257
+ end
258
+ end
259
+ end
@@ -0,0 +1,30 @@
1
+ # encoding: UTF-8
2
+
3
+ # Copyright 2012 Twitter, Inc
4
+ # http://www.apache.org/licenses/LICENSE-2.0
5
+
6
+ module TwitterCldr
7
+ module Formatters
8
+ module Rbnf
9
+
10
+ Substitution = Struct.new(:type, :contents, :length) do
11
+ def description
12
+ @description ||= contents.map(&:value).join
13
+ end
14
+
15
+ def rule_set_reference
16
+ if item = contents.first
17
+ item.value.gsub("%", "") if item.type == :rule
18
+ end
19
+ end
20
+
21
+ def decimal_format
22
+ if item = contents.first
23
+ item.value if item.type == :decimal
24
+ end
25
+ end
26
+ end
27
+
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,127 @@
1
+ # encoding: UTF-8
2
+
3
+ # Copyright 2012 Twitter, Inc
4
+ # http://www.apache.org/licenses/LICENSE-2.0
5
+
6
+ module TwitterCldr
7
+ module Formatters
8
+ module Rbnf
9
+
10
+ [:InvalidRbnfTokenError, :RuleFormatter, :NormalRuleFormatter,
11
+ :NegativeRuleFormatter, :MasterRuleFormatter, :ProperFractionRuleFormatter,
12
+ :ImproperFractionRuleFormatter].each do |formatter|
13
+ autoload formatter, "twitter_cldr/formatters/numbers/rbnf/formatters"
14
+ end
15
+
16
+ autoload :Rule, "twitter_cldr/formatters/numbers/rbnf/rule"
17
+ autoload :RuleSet, "twitter_cldr/formatters/numbers/rbnf/rule_set"
18
+ autoload :RuleGroup, "twitter_cldr/formatters/numbers/rbnf/rule_group"
19
+ autoload :RuleParser, "twitter_cldr/formatters/numbers/rbnf/rule_parser"
20
+ autoload :Substitution, "twitter_cldr/formatters/numbers/rbnf/substitution"
21
+
22
+ class PrivateRuleSetError < StandardError; end
23
+
24
+ class RbnfFormatter
25
+
26
+ DEFAULT_SPELLOUT_OPTIONS = {
27
+ :rule_group => "SpelloutRules",
28
+ :rule_set => "spellout-numbering"
29
+ }
30
+
31
+ attr_reader :locale
32
+
33
+ def initialize(locale = TwitterCldr.locale)
34
+ @locale = TwitterCldr.convert_locale(locale)
35
+ end
36
+
37
+ def format(number, options = {})
38
+ rule_group_name, rule_set_name = *if options[:rule_group].nil? && options[:rule_set].nil?
39
+ [DEFAULT_CARDINAL_OPTIONS[:rule_group], DEFAULT_CARDINAL_OPTIONS[:rule_set]]
40
+ else
41
+ [options[:rule_group], options[:rule_set]]
42
+ end
43
+
44
+ if rule_group = rule_group_by_name(rule_group_name)
45
+ if rule_set = rule_group.rule_set_for(rule_set_name)
46
+ if rule_set.public?
47
+ RuleFormatter.format(number, rule_set, rule_group, locale)
48
+ else
49
+ raise PrivateRuleSetError.new(
50
+ "#{rule_set_name} is a private rule set and cannot be used directly."
51
+ )
52
+ end
53
+ end
54
+ end
55
+ end
56
+
57
+ def group_names
58
+ @group_names ||= resource.map { |g| g[:type] }
59
+ end
60
+
61
+ def rule_set_names_for_group(group_name)
62
+ cache_key = TwitterCldr::Utils.compute_cache_key(locale, group_name)
63
+
64
+ rule_set_name_cache[cache_key] ||= begin
65
+ if rule_group = rule_group_by_name(group_name)
66
+ rule_group.rule_sets.inject([]) do |ret, rule_set|
67
+ ret << rule_set.name if rule_set.public?
68
+ ret
69
+ end
70
+ end
71
+ end
72
+
73
+ rule_set_name_cache[cache_key] || []
74
+ end
75
+
76
+ private
77
+
78
+ def rule_group_by_name(name)
79
+ cache_key = TwitterCldr::Utils.compute_cache_key(locale, name)
80
+
81
+ rule_group_cache[cache_key] ||= begin
82
+ group_data = resource.find do |group|
83
+ group[:type] == name
84
+ end
85
+
86
+ if group_data
87
+ rule_group_from_resource(group_data)
88
+ end
89
+ end
90
+ end
91
+
92
+ def rule_group_cache
93
+ @@rule_group_cache ||= {}
94
+ end
95
+
96
+ def rule_set_name_cache
97
+ @@rule_set_name_cache ||= {}
98
+ end
99
+
100
+ def rule_set_from_resource(rule_set_data)
101
+ RuleSet.new(
102
+ rule_set_data[:rules].map do |rule|
103
+ binding.pry unless rule[:rule].is_a?(String)
104
+ Rule.new(rule[:value], rule[:rule], rule[:radix])
105
+ end,
106
+ rule_set_data[:type],
107
+ rule_set_data[:access] || "public"
108
+ )
109
+ end
110
+
111
+ def rule_group_from_resource(group_data)
112
+ RuleGroup.new(
113
+ group_data[:ruleset].map do |rule_set_data|
114
+ rule_set_from_resource(rule_set_data)
115
+ end,
116
+ group_data[:type]
117
+ )
118
+ end
119
+
120
+ def resource
121
+ @resource ||= TwitterCldr.resources.get_locale_resource(locale, "rbnf")[locale][:rbnf][:grouping]
122
+ end
123
+
124
+ end
125
+ end
126
+ end
127
+ end
@@ -7,17 +7,29 @@ require 'json'
7
7
 
8
8
  module TwitterCldr
9
9
  module Formatters
10
- class PluralFormatter < Base
10
+ class PluralFormatter
11
11
 
12
12
  PLURALIZATION_REGEXP = Regexp.union(
13
- /%\{(\w+?):(\w+?)\}/, # regular pluralization pattern
14
- /%<(\{.*?\})>/ # inline pluralization pattern
13
+ /%\{(\w+?):(\w+?)\}/, # regular pluralization pattern
14
+ /%<(\{.*?\})>/ # inline pluralization pattern
15
15
  )
16
16
 
17
- attr_accessor :locale
17
+ class << self
18
+ def for_locale(locale)
19
+ formatter_cache[locale] ||= PluralFormatter.new(locale)
20
+ end
21
+
22
+ protected
23
+
24
+ def formatter_cache
25
+ @formatter_cache ||= {}
26
+ end
27
+ end
28
+
29
+ attr_reader :locale
18
30
 
19
- def initialize(options = {})
20
- self.locale = extract_locale(options)
31
+ def initialize(locale = TwitterCldr.locale)
32
+ @locale = TwitterCldr.convert_locale(locale)
21
33
  end
22
34
 
23
35
  # Replaces every pluralization token in the +string+ with a phrase formed using a number and a pluralization
@@ -5,11 +5,9 @@
5
5
 
6
6
  module TwitterCldr
7
7
  module Formatters
8
- autoload :Base, 'twitter_cldr/formatters/base'
8
+ autoload :Formatter, 'twitter_cldr/formatters/formatter'
9
9
 
10
- autoload :DateTimeFormatter, 'twitter_cldr/formatters/calendars/datetime_formatter'
11
- autoload :DateFormatter, 'twitter_cldr/formatters/calendars/date_formatter'
12
- autoload :TimeFormatter, 'twitter_cldr/formatters/calendars/time_formatter'
10
+ autoload :DateTimeFormatter, 'twitter_cldr/formatters/calendars/date_time_formatter'
13
11
  autoload :TimespanFormatter, 'twitter_cldr/formatters/calendars/timespan_formatter'
14
12
 
15
13
  autoload :Numbers, 'twitter_cldr/formatters/numbers'
@@ -20,10 +18,11 @@ module TwitterCldr
20
18
  autoload :LongDecimalFormatter, 'twitter_cldr/formatters/numbers/abbreviated/long_decimal_formatter'
21
19
  autoload :CurrencyFormatter, 'twitter_cldr/formatters/numbers/currency_formatter'
22
20
  autoload :PercentFormatter, 'twitter_cldr/formatters/numbers/percent_formatter'
21
+ autoload :Rbnf, 'twitter_cldr/formatters/numbers/rbnf'
23
22
 
24
23
  autoload :Plurals, 'twitter_cldr/formatters/plurals'
25
24
  autoload :PluralFormatter, 'twitter_cldr/formatters/plurals/plural_formatter'
26
25
 
27
26
  autoload :ListFormatter, 'twitter_cldr/formatters/list_formatter'
28
27
  end
29
- end
28
+ end
@@ -31,7 +31,7 @@ module TwitterCldr
31
31
  end
32
32
 
33
33
  def to_sentence
34
- TwitterCldr::Formatters::ListFormatter.new(:locale => locale).format(base_obj)
34
+ TwitterCldr::Formatters::ListFormatter.new(locale).format(base_obj)
35
35
  end
36
36
 
37
37
  def each
@@ -46,10 +46,13 @@ module TwitterCldr
46
46
  timezone_info.utc_to_local(time.is_a?(DateTime) ? time.new_offset(0) : time.utc)
47
47
  end
48
48
 
49
- def formatter_const
50
- TwitterCldr::Formatters::DateFormatter
49
+ def data_reader_for(type)
50
+ TwitterCldr::DataReaders::DateDataReader.new(locale, {
51
+ :calendar_type => calendar_type,
52
+ :type => type
53
+ })
51
54
  end
52
- end
53
55
 
56
+ end
54
57
  end
55
58
  end
@@ -7,22 +7,42 @@ require 'tzinfo'
7
7
 
8
8
  module TwitterCldr
9
9
  module Localized
10
-
11
10
  class LocalizedDateTime < LocalizedObject
11
+
12
12
  attr_reader :calendar_type, :timezone
13
13
 
14
+ class << self
15
+ def types
16
+ TwitterCldr::DataReaders::CalendarDataReader::TYPE_PATHS.keys
17
+ end
18
+ end
19
+
14
20
  def initialize(obj, locale, options = {})
15
21
  super
16
22
  @calendar_type = options[:calendar_type] || TwitterCldr::DEFAULT_CALENDAR_TYPE
17
23
  @timezone = options[:timezone] || "UTC"
18
24
  end
19
25
 
20
- TwitterCldr::Tokenizers::DateTimeTokenizer::VALID_TYPES.each do |format_type|
21
- define_method "to_#{format_type}_s" do
22
- @formatter.format(base_in_timezone, chain_params.merge(:type => format_type.to_sym))
26
+ types.each do |type|
27
+ define_method "to_#{type}_s" do
28
+ # @ TODO: these need to be cheap to create
29
+ data_reader = data_reader_for(type)
30
+ tokens = data_reader.tokenizer.tokenize(data_reader.pattern)
31
+ data_reader.formatter.format(tokens, base_in_timezone)
23
32
  end
24
33
  end
25
34
 
35
+ def to_additional_s(additional_format)
36
+ data_reader = data_reader_for(:additional, {
37
+ :additional_format => additional_format
38
+ })
39
+
40
+ tokens = data_reader.tokenizer.full_tokenize(data_reader.pattern)
41
+ data_reader.formatter.format(tokens, base_in_timezone)
42
+ end
43
+
44
+ alias :to_default_s :to_medium_s
45
+
26
46
  def to_timespan(options = {})
27
47
  base_time = options[:base_time] || Time.now
28
48
  seconds = (self.to_time.base_obj.to_i - base_time.to_i).abs
@@ -43,12 +63,12 @@ module TwitterCldr
43
63
  TwitterCldr::Localized::LocalizedTimespan.new(seconds, options.merge(:locale => @locale))
44
64
  end
45
65
 
46
- def to_s(options = {})
47
- if options[:format]
48
- @formatter.format(base_in_timezone, options.merge(:type => :additional))
49
- else
50
- to_default_s
51
- end
66
+ def additional_formats
67
+ data_reader_for(nil).additional_format_selector.patterns
68
+ end
69
+
70
+ def to_s
71
+ to_default_s
52
72
  end
53
73
 
54
74
  def to_date
@@ -77,6 +97,13 @@ module TwitterCldr
77
97
 
78
98
  protected
79
99
 
100
+ def data_reader_for(type, options = {})
101
+ TwitterCldr::DataReaders::DateTimeDataReader.new(locale, options.merge({
102
+ :calendar_type => calendar_type,
103
+ :type => type
104
+ }))
105
+ end
106
+
80
107
  def chain_params
81
108
  { :calendar_type => @calendar_type, :timezone => @timezone }
82
109
  end
@@ -85,14 +112,10 @@ module TwitterCldr
85
112
  timezone_info.utc_to_local(@base_obj.new_offset(0))
86
113
  end
87
114
 
88
- def formatter_const
89
- TwitterCldr::Formatters::DateTimeFormatter
90
- end
91
-
92
115
  def timezone_info
93
116
  (@@timezone_info ||= {})[@timezone] ||= TZInfo::Timezone.get(@timezone)
94
117
  end
95
- end
96
118
 
119
+ end
97
120
  end
98
121
  end
@@ -5,52 +5,68 @@
5
5
 
6
6
  module TwitterCldr
7
7
  module Localized
8
-
9
8
  class LocalizedNumber < LocalizedObject
10
- DEFAULT_TYPE = :decimal
11
- TYPES = [
12
- :decimal,
13
- :short_decimal,
14
- :long_decimal,
15
- :currency,
16
- :percent,
17
- ]
18
9
 
19
- attr_reader :type
10
+ attr_reader :type, :format
20
11
 
21
12
  def initialize(obj, locale, options = {})
22
- @options = options.dup
23
-
24
- @type = @options.delete(:type) || DEFAULT_TYPE
25
- raise ArgumentError.new("type #{@type} is not supported") unless @type && TYPES.include?(@type.to_sym)
13
+ @type = options[:type]
14
+ @format = options[:format]
15
+ super
16
+ end
26
17
 
27
- super(obj, locale, @options)
18
+ class << self
19
+ def types
20
+ TwitterCldr::DataReaders::NumberDataReader::TYPE_PATHS.keys
21
+ end
28
22
  end
29
23
 
30
- TYPES.each do |type|
24
+ types.each do |type|
31
25
  define_method "to_#{type}" do
32
26
  to_type(type)
33
27
  end
34
28
  end
35
29
 
36
30
  def to_s(options = {})
37
- @formatter.format(@base_obj, options.merge(:type => @type))
31
+ data_reader = TwitterCldr::DataReaders::NumberDataReader.new(locale, {
32
+ :type => @type,
33
+ :format => @format
34
+ })
35
+
36
+ tokens = data_reader.tokenizer.tokenize(data_reader.pattern(base_obj))
37
+ data_reader.formatter.format(tokens, base_obj, options.merge(:type => @type))
38
38
  end
39
39
 
40
40
  def plural_rule
41
- TwitterCldr::Formatters::Plurals::Rules.rule_for(@base_obj, @locale)
41
+ TwitterCldr::Formatters::Plurals::Rules.rule_for(base_obj, locale)
42
42
  end
43
43
 
44
- protected
44
+ def spellout
45
+ rbnf.format(
46
+ base_obj, TwitterCldr::Formatters::Rbnf::RbnfFormatter::DEFAULT_SPELLOUT_OPTIONS
47
+ )
48
+ end
45
49
 
46
- def formatter_const
47
- TwitterCldr::Formatters.const_get("#{@type.to_s.split("_").map(&:capitalize).join}Formatter")
50
+ def to_rbnf_s(group_name, rule_set_name)
51
+ rbnf.format(base_obj, {
52
+ :rule_group => group_name,
53
+ :rule_set => rule_set_name
54
+ })
48
55
  end
49
56
 
57
+ def rbnf
58
+ @rbnf ||= TwitterCldr::Formatters::Rbnf::RbnfFormatter.new(locale)
59
+ end
60
+
61
+ protected
62
+
50
63
  def to_type(target_type)
51
- self.class.new(@base_obj, @locale, @options.merge(:type => target_type))
64
+ self.class.new(base_obj, locale, {
65
+ :type => target_type,
66
+ :format => @format
67
+ })
52
68
  end
53
- end
54
69
 
70
+ end
55
71
  end
56
- end
72
+ end