twitter_cldr 1.9.1 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (403) hide show
  1. data/Gemfile +7 -0
  2. data/History.txt +11 -0
  3. data/README.md +93 -13
  4. data/Rakefile +27 -6
  5. data/lib/twitter_cldr/formatters.rb +15 -12
  6. data/lib/twitter_cldr/formatters/base.rb +1 -1
  7. data/lib/twitter_cldr/formatters/calendars/datetime_formatter.rb +18 -3
  8. data/lib/twitter_cldr/formatters/calendars/timespan_formatter.rb +24 -26
  9. data/lib/twitter_cldr/formatters/numbers/abbreviated/abbreviated_number_formatter.rb +47 -0
  10. data/lib/twitter_cldr/formatters/numbers/abbreviated/long_decimal_formatter.rb +18 -0
  11. data/lib/twitter_cldr/formatters/numbers/abbreviated/short_decimal_formatter.rb +18 -0
  12. data/lib/twitter_cldr/formatters/numbers/currency_formatter.rb +22 -17
  13. data/lib/twitter_cldr/formatters/numbers/decimal_formatter.rb +0 -9
  14. data/lib/twitter_cldr/formatters/numbers/helpers/base.rb +1 -1
  15. data/lib/twitter_cldr/formatters/numbers/number_formatter.rb +25 -10
  16. data/lib/twitter_cldr/formatters/numbers/percent_formatter.rb +9 -6
  17. data/lib/twitter_cldr/localized/localized_datetime.rb +6 -2
  18. data/lib/twitter_cldr/localized/localized_number.rb +9 -3
  19. data/lib/twitter_cldr/localized/localized_timespan.rb +1 -1
  20. data/lib/twitter_cldr/resources.rb +13 -12
  21. data/lib/twitter_cldr/resources/custom_locales_resources_importer.rb +1 -1
  22. data/lib/twitter_cldr/resources/download.rb +1 -1
  23. data/lib/twitter_cldr/resources/locales_resources_importer.rb +10 -6
  24. data/lib/twitter_cldr/shared/bidi.rb +27 -27
  25. data/lib/twitter_cldr/shared/currencies.rb +20 -13
  26. data/lib/twitter_cldr/tokenizers.rb +10 -9
  27. data/lib/twitter_cldr/tokenizers/base.rb +33 -21
  28. data/lib/twitter_cldr/tokenizers/calendars/additional_date_format_selector.rb +86 -0
  29. data/lib/twitter_cldr/tokenizers/calendars/date_tokenizer.rb +20 -11
  30. data/lib/twitter_cldr/tokenizers/calendars/datetime_tokenizer.rb +50 -13
  31. data/lib/twitter_cldr/tokenizers/calendars/time_tokenizer.rb +19 -10
  32. data/lib/twitter_cldr/tokenizers/calendars/timespan_tokenizer.rb +32 -32
  33. data/lib/twitter_cldr/tokenizers/numbers/number_tokenizer.rb +45 -22
  34. data/lib/twitter_cldr/utils.rb +16 -1
  35. data/lib/twitter_cldr/version.rb +1 -1
  36. data/resources/collation/tailoring/af.yml +1 -0
  37. data/resources/collation/tailoring/ar.yml +3 -2
  38. data/resources/collation/tailoring/be.yml +7 -0
  39. data/resources/collation/tailoring/bg.yml +5 -0
  40. data/resources/collation/tailoring/bn.yml +9 -0
  41. data/resources/collation/tailoring/ca.yml +3 -2
  42. data/resources/collation/tailoring/cs.yml +3 -2
  43. data/resources/collation/tailoring/cy.yml +51 -0
  44. data/resources/collation/tailoring/da.yml +3 -2
  45. data/resources/collation/tailoring/de.yml +1 -0
  46. data/resources/collation/tailoring/el.yml +1 -0
  47. data/resources/collation/tailoring/en.yml +1 -0
  48. data/resources/collation/tailoring/es.yml +3 -2
  49. data/resources/collation/tailoring/eu.yml +1 -0
  50. data/resources/collation/tailoring/fa.yml +3 -2
  51. data/resources/collation/tailoring/fi.yml +3 -2
  52. data/resources/collation/tailoring/fil.yml +3 -2
  53. data/resources/collation/tailoring/fr.yml +1 -0
  54. data/resources/collation/tailoring/ga.yml +5 -0
  55. data/resources/collation/tailoring/gl.yml +5 -0
  56. data/resources/collation/tailoring/he.yml +1 -0
  57. data/resources/collation/tailoring/hi.yml +3 -2
  58. data/resources/collation/tailoring/hu.yml +3 -2
  59. data/resources/collation/tailoring/id.yml +1 -0
  60. data/resources/collation/tailoring/it.yml +1 -0
  61. data/resources/collation/tailoring/ja.yml +107 -54
  62. data/resources/collation/tailoring/ko.yml +3 -2
  63. data/resources/collation/tailoring/lv.yml +35 -0
  64. data/resources/collation/tailoring/ms.yml +1 -0
  65. data/resources/collation/tailoring/nb.yml +3 -2
  66. data/resources/collation/tailoring/nl.yml +1 -0
  67. data/resources/collation/tailoring/pl.yml +3 -2
  68. data/resources/collation/tailoring/pt.yml +1 -0
  69. data/resources/collation/tailoring/ro.yml +31 -0
  70. data/resources/collation/tailoring/ru.yml +1 -0
  71. data/resources/collation/tailoring/sk.yml +35 -0
  72. data/resources/collation/tailoring/sq.yml +65 -0
  73. data/resources/collation/tailoring/sr.yml +5 -0
  74. data/resources/collation/tailoring/sv.yml +3 -2
  75. data/resources/collation/tailoring/ta.yml +57 -0
  76. data/resources/collation/tailoring/th.yml +3 -2
  77. data/resources/collation/tailoring/tr.yml +3 -2
  78. data/resources/collation/tailoring/uk.yml +3 -2
  79. data/resources/collation/tailoring/ur.yml +3 -2
  80. data/resources/collation/tailoring/zh-Hant.yml +3 -2
  81. data/resources/collation/tailoring/zh.yml +3 -2
  82. data/resources/collation/tries/be.dump +0 -0
  83. data/resources/collation/tries/bg.dump +0 -0
  84. data/resources/collation/tries/bn.dump +0 -0
  85. data/resources/collation/tries/cy.dump +0 -0
  86. data/resources/collation/tries/ga.dump +0 -0
  87. data/resources/collation/tries/gl.dump +0 -0
  88. data/resources/collation/tries/lv.dump +0 -0
  89. data/resources/collation/tries/ro.dump +0 -0
  90. data/resources/collation/tries/sk.dump +0 -0
  91. data/resources/collation/tries/sq.dump +0 -0
  92. data/resources/collation/tries/sr.dump +0 -0
  93. data/resources/collation/tries/ta.dump +0 -0
  94. data/resources/custom/locales/ar/units.yml +6 -6
  95. data/resources/custom/locales/be/units.yml +27 -0
  96. data/resources/custom/locales/bg/units.yml +19 -0
  97. data/resources/custom/locales/bn/units.yml +7 -0
  98. data/resources/custom/locales/cs/units.yml +3 -3
  99. data/resources/custom/locales/cy/units.yml +35 -0
  100. data/resources/custom/locales/fil/units.yml +2 -2
  101. data/resources/custom/locales/ga/units.yml +24 -0
  102. data/resources/custom/locales/gl/units.yml +19 -0
  103. data/resources/custom/locales/hu/plurals.yml +3 -0
  104. data/resources/custom/locales/hu/units.yml +4 -0
  105. data/resources/custom/locales/lv/units.yml +23 -0
  106. data/resources/custom/locales/ms/units.yml +1 -1
  107. data/resources/custom/locales/ro/units.yml +23 -0
  108. data/resources/custom/locales/sk/units.yml +23 -0
  109. data/resources/custom/locales/sr/units.yml +27 -0
  110. data/resources/custom/locales/ta/units.yml +11 -0
  111. data/resources/custom/locales/th/calendars.yml +14 -0
  112. data/resources/locales/af/calendars.yml +56 -0
  113. data/resources/locales/af/currencies.yml +358 -0
  114. data/resources/locales/af/languages.yml +23 -3
  115. data/resources/locales/af/numbers.yml +22 -8
  116. data/resources/locales/af/units.yml +26 -54
  117. data/resources/locales/ar/calendars.yml +99 -6
  118. data/resources/locales/ar/currencies.yml +1491 -0
  119. data/resources/locales/ar/languages.yml +33 -6
  120. data/resources/locales/ar/numbers.yml +27 -14
  121. data/resources/locales/ar/units.yml +31 -31
  122. data/resources/locales/be/calendars.yml +229 -0
  123. data/resources/locales/be/currencies.yml +66 -0
  124. data/resources/locales/be/languages.yml +149 -0
  125. data/resources/locales/be/layout.yml +4 -0
  126. data/resources/locales/be/lists.yml +7 -0
  127. data/resources/locales/be/numbers.yml +43 -0
  128. data/resources/locales/be/plurals.yml +5 -0
  129. data/resources/locales/be/units.yml +87 -0
  130. data/resources/locales/bg/calendars.yml +220 -0
  131. data/resources/locales/bg/currencies.yml +773 -0
  132. data/resources/locales/bg/languages.yml +513 -0
  133. data/resources/locales/bg/layout.yml +4 -0
  134. data/resources/locales/bg/lists.yml +7 -0
  135. data/resources/locales/bg/numbers.yml +57 -0
  136. data/resources/locales/bg/plurals.yml +3 -0
  137. data/resources/locales/bg/units.yml +108 -0
  138. data/resources/locales/bn/calendars.yml +205 -0
  139. data/resources/locales/bn/currencies.yml +564 -0
  140. data/resources/locales/bn/languages.yml +513 -0
  141. data/resources/locales/bn/layout.yml +4 -0
  142. data/resources/locales/bn/lists.yml +7 -0
  143. data/resources/locales/bn/numbers.yml +57 -0
  144. data/resources/locales/bn/plurals.yml +3 -0
  145. data/resources/locales/bn/units.yml +108 -0
  146. data/resources/locales/ca/calendars.yml +70 -21
  147. data/resources/locales/ca/currencies.yml +904 -0
  148. data/resources/locales/ca/languages.yml +70 -5
  149. data/resources/locales/ca/numbers.yml +19 -6
  150. data/resources/locales/ca/units.yml +0 -28
  151. data/resources/locales/cs/calendars.yml +73 -27
  152. data/resources/locales/cs/currencies.yml +1063 -0
  153. data/resources/locales/cs/languages.yml +113 -31
  154. data/resources/locales/cs/numbers.yml +17 -4
  155. data/resources/locales/cs/units.yml +0 -28
  156. data/resources/locales/cy/calendars.yml +266 -0
  157. data/resources/locales/cy/currencies.yml +54 -0
  158. data/resources/locales/cy/languages.yml +92 -0
  159. data/resources/locales/cy/layout.yml +4 -0
  160. data/resources/locales/cy/lists.yml +7 -0
  161. data/resources/locales/cy/numbers.yml +49 -0
  162. data/resources/locales/cy/plurals.yml +4 -0
  163. data/resources/locales/cy/units.yml +73 -0
  164. data/resources/locales/da/calendars.yml +117 -16
  165. data/resources/locales/da/currencies.yml +814 -0
  166. data/resources/locales/da/languages.yml +66 -5
  167. data/resources/locales/da/numbers.yml +16 -3
  168. data/resources/locales/da/units.yml +21 -35
  169. data/resources/locales/de/calendars.yml +115 -17
  170. data/resources/locales/de/currencies.yml +843 -0
  171. data/resources/locales/de/languages.yml +5 -3
  172. data/resources/locales/de/numbers.yml +18 -5
  173. data/resources/locales/de/units.yml +0 -28
  174. data/resources/locales/el/calendars.yml +61 -8
  175. data/resources/locales/el/currencies.yml +866 -0
  176. data/resources/locales/el/languages.yml +61 -5
  177. data/resources/locales/el/numbers.yml +18 -5
  178. data/resources/locales/el/units.yml +7 -42
  179. data/resources/locales/en/calendars.yml +43 -4
  180. data/resources/locales/en/currencies.yml +912 -0
  181. data/resources/locales/en/languages.yml +26 -6
  182. data/resources/locales/en/numbers.yml +17 -4
  183. data/resources/locales/es/calendars.yml +60 -0
  184. data/resources/locales/es/currencies.yml +820 -0
  185. data/resources/locales/es/languages.yml +66 -1
  186. data/resources/locales/es/numbers.yml +20 -7
  187. data/resources/locales/es/units.yml +0 -28
  188. data/resources/locales/eu/calendars.yml +43 -2
  189. data/resources/locales/eu/currencies.yml +378 -0
  190. data/resources/locales/eu/languages.yml +29 -13
  191. data/resources/locales/eu/numbers.yml +17 -4
  192. data/resources/locales/eu/units.yml +22 -43
  193. data/resources/locales/fa/calendars.yml +57 -0
  194. data/resources/locales/fa/currencies.yml +449 -0
  195. data/resources/locales/fa/languages.yml +8 -3
  196. data/resources/locales/fa/numbers.yml +20 -7
  197. data/resources/locales/fa/units.yml +0 -42
  198. data/resources/locales/fi/calendars.yml +49 -1
  199. data/resources/locales/fi/currencies.yml +903 -0
  200. data/resources/locales/fi/languages.yml +58 -2
  201. data/resources/locales/fi/numbers.yml +25 -12
  202. data/resources/locales/fi/units.yml +0 -28
  203. data/resources/locales/fil/calendars.yml +51 -0
  204. data/resources/locales/fil/currencies.yml +357 -0
  205. data/resources/locales/fil/languages.yml +25 -8
  206. data/resources/locales/fil/numbers.yml +18 -5
  207. data/resources/locales/fil/units.yml +14 -28
  208. data/resources/locales/fr/calendars.yml +114 -12
  209. data/resources/locales/fr/currencies.yml +884 -0
  210. data/resources/locales/fr/languages.yml +43 -9
  211. data/resources/locales/fr/numbers.yml +22 -9
  212. data/resources/locales/fr/units.yml +2 -30
  213. data/resources/locales/ga/calendars.yml +187 -0
  214. data/resources/locales/ga/currencies.yml +513 -0
  215. data/resources/locales/ga/languages.yml +147 -0
  216. data/resources/locales/ga/layout.yml +4 -0
  217. data/resources/locales/ga/lists.yml +7 -0
  218. data/resources/locales/ga/numbers.yml +43 -0
  219. data/resources/locales/ga/plurals.yml +4 -0
  220. data/resources/locales/ga/units.yml +66 -0
  221. data/resources/locales/gl/calendars.yml +216 -0
  222. data/resources/locales/gl/currencies.yml +476 -0
  223. data/resources/locales/gl/languages.yml +213 -0
  224. data/resources/locales/gl/layout.yml +4 -0
  225. data/resources/locales/gl/lists.yml +7 -0
  226. data/resources/locales/gl/numbers.yml +57 -0
  227. data/resources/locales/gl/plurals.yml +3 -0
  228. data/resources/locales/gl/units.yml +108 -0
  229. data/resources/locales/he/calendars.yml +70 -18
  230. data/resources/locales/he/currencies.yml +497 -0
  231. data/resources/locales/he/languages.yml +301 -7
  232. data/resources/locales/he/lists.yml +2 -2
  233. data/resources/locales/he/numbers.yml +23 -8
  234. data/resources/locales/he/plurals.yml +3 -2
  235. data/resources/locales/he/units.yml +72 -30
  236. data/resources/locales/hi/calendars.yml +54 -1
  237. data/resources/locales/hi/currencies.yml +388 -0
  238. data/resources/locales/hi/languages.yml +2 -0
  239. data/resources/locales/hi/numbers.yml +21 -8
  240. data/resources/locales/hi/units.yml +15 -29
  241. data/resources/locales/hu/calendars.yml +52 -5
  242. data/resources/locales/hu/currencies.yml +640 -0
  243. data/resources/locales/hu/languages.yml +60 -4
  244. data/resources/locales/hu/numbers.yml +25 -12
  245. data/resources/locales/hu/units.yml +1 -29
  246. data/resources/locales/id/calendars.yml +125 -21
  247. data/resources/locales/id/currencies.yml +603 -0
  248. data/resources/locales/id/languages.yml +113 -51
  249. data/resources/locales/id/numbers.yml +16 -3
  250. data/resources/locales/id/units.yml +0 -28
  251. data/resources/locales/it/calendars.yml +59 -6
  252. data/resources/locales/it/currencies.yml +722 -0
  253. data/resources/locales/it/languages.yml +77 -5
  254. data/resources/locales/it/numbers.yml +22 -9
  255. data/resources/locales/it/units.yml +0 -14
  256. data/resources/locales/ja/calendars.yml +55 -5
  257. data/resources/locales/ja/currencies.yml +602 -0
  258. data/resources/locales/ja/languages.yml +103 -43
  259. data/resources/locales/ja/numbers.yml +18 -5
  260. data/resources/locales/ja/units.yml +6 -34
  261. data/resources/locales/ko/calendars.yml +50 -0
  262. data/resources/locales/ko/currencies.yml +596 -0
  263. data/resources/locales/ko/languages.yml +75 -8
  264. data/resources/locales/ko/numbers.yml +17 -4
  265. data/resources/locales/ko/units.yml +0 -28
  266. data/resources/locales/lv/calendars.yml +275 -0
  267. data/resources/locales/lv/currencies.yml +765 -0
  268. data/resources/locales/lv/languages.yml +576 -0
  269. data/resources/locales/lv/layout.yml +4 -0
  270. data/resources/locales/lv/lists.yml +7 -0
  271. data/resources/locales/lv/numbers.yml +58 -0
  272. data/resources/locales/lv/plurals.yml +4 -0
  273. data/resources/locales/lv/units.yml +136 -0
  274. data/resources/locales/ms/calendars.yml +86 -4
  275. data/resources/locales/ms/currencies.yml +341 -0
  276. data/resources/locales/ms/languages.yml +25 -3
  277. data/resources/locales/ms/numbers.yml +19 -6
  278. data/resources/locales/ms/units.yml +0 -56
  279. data/resources/locales/nb/calendars.yml +48 -1
  280. data/resources/locales/nb/currencies.yml +846 -0
  281. data/resources/locales/nb/languages.yml +44 -2
  282. data/resources/locales/nb/numbers.yml +16 -3
  283. data/resources/locales/nb/units.yml +6 -28
  284. data/resources/locales/nl/calendars.yml +110 -9
  285. data/resources/locales/nl/currencies.yml +640 -0
  286. data/resources/locales/nl/languages.yml +68 -8
  287. data/resources/locales/nl/numbers.yml +25 -12
  288. data/resources/locales/nl/units.yml +14 -28
  289. data/resources/locales/pl/calendars.yml +53 -6
  290. data/resources/locales/pl/currencies.yml +1100 -0
  291. data/resources/locales/pl/languages.yml +13 -6
  292. data/resources/locales/pl/lists.yml +2 -2
  293. data/resources/locales/pl/numbers.yml +18 -5
  294. data/resources/locales/pl/units.yml +51 -92
  295. data/resources/locales/pt/calendars.yml +121 -9
  296. data/resources/locales/pt/currencies.yml +904 -0
  297. data/resources/locales/pt/languages.yml +5 -3
  298. data/resources/locales/pt/numbers.yml +17 -4
  299. data/resources/locales/pt/units.yml +0 -28
  300. data/resources/locales/ro/calendars.yml +278 -0
  301. data/resources/locales/ro/currencies.yml +946 -0
  302. data/resources/locales/ro/languages.yml +576 -0
  303. data/resources/locales/ro/layout.yml +4 -0
  304. data/resources/locales/ro/lists.yml +7 -0
  305. data/resources/locales/ro/numbers.yml +58 -0
  306. data/resources/locales/ro/plurals.yml +3 -0
  307. data/resources/locales/ro/units.yml +136 -0
  308. data/resources/locales/ru/calendars.yml +72 -12
  309. data/resources/locales/ru/currencies.yml +1061 -0
  310. data/resources/locales/ru/languages.yml +51 -6
  311. data/resources/locales/ru/numbers.yml +21 -5
  312. data/resources/locales/ru/units.yml +0 -28
  313. data/resources/locales/sk/calendars.yml +275 -0
  314. data/resources/locales/sk/currencies.yml +713 -0
  315. data/resources/locales/sk/languages.yml +576 -0
  316. data/resources/locales/sk/layout.yml +4 -0
  317. data/resources/locales/sk/lists.yml +7 -0
  318. data/resources/locales/sk/numbers.yml +58 -0
  319. data/resources/locales/sk/plurals.yml +3 -0
  320. data/resources/locales/sk/units.yml +136 -0
  321. data/resources/locales/sq/calendars.yml +188 -0
  322. data/resources/locales/sq/currencies.yml +56 -0
  323. data/resources/locales/sq/languages.yml +17 -0
  324. data/resources/locales/sq/layout.yml +4 -0
  325. data/resources/locales/sq/lists.yml +7 -0
  326. data/resources/locales/sq/numbers.yml +43 -0
  327. data/resources/locales/sq/plurals.yml +3 -0
  328. data/resources/locales/sq/units.yml +73 -0
  329. data/resources/locales/sr/calendars.yml +285 -0
  330. data/resources/locales/sr/currencies.yml +1494 -0
  331. data/resources/locales/sr/languages.yml +513 -0
  332. data/resources/locales/sr/layout.yml +4 -0
  333. data/resources/locales/sr/lists.yml +7 -0
  334. data/resources/locales/sr/numbers.yml +59 -0
  335. data/resources/locales/sr/plurals.yml +5 -0
  336. data/resources/locales/sr/units.yml +164 -0
  337. data/resources/locales/sv/calendars.yml +59 -1
  338. data/resources/locales/sv/currencies.yml +919 -0
  339. data/resources/locales/sv/languages.yml +47 -2
  340. data/resources/locales/sv/numbers.yml +27 -12
  341. data/resources/locales/sv/units.yml +4 -32
  342. data/resources/locales/ta/calendars.yml +264 -0
  343. data/resources/locales/ta/currencies.yml +346 -0
  344. data/resources/locales/ta/languages.yml +512 -0
  345. data/resources/locales/ta/layout.yml +4 -0
  346. data/resources/locales/ta/lists.yml +7 -0
  347. data/resources/locales/ta/numbers.yml +57 -0
  348. data/resources/locales/ta/plurals.yml +3 -0
  349. data/resources/locales/ta/units.yml +108 -0
  350. data/resources/locales/th/calendars.yml +125 -27
  351. data/resources/locales/th/currencies.yml +602 -0
  352. data/resources/locales/th/languages.yml +70 -5
  353. data/resources/locales/th/numbers.yml +24 -11
  354. data/resources/locales/th/units.yml +0 -28
  355. data/resources/locales/tr/calendars.yml +62 -12
  356. data/resources/locales/tr/currencies.yml +571 -0
  357. data/resources/locales/tr/languages.yml +94 -29
  358. data/resources/locales/tr/numbers.yml +19 -6
  359. data/resources/locales/tr/units.yml +1 -29
  360. data/resources/locales/uk/calendars.yml +52 -0
  361. data/resources/locales/uk/currencies.yml +799 -0
  362. data/resources/locales/uk/languages.yml +57 -2
  363. data/resources/locales/uk/numbers.yml +18 -5
  364. data/resources/locales/uk/units.yml +0 -28
  365. data/resources/locales/ur/calendars.yml +96 -32
  366. data/resources/locales/ur/currencies.yml +360 -0
  367. data/resources/locales/ur/languages.yml +49 -32
  368. data/resources/locales/ur/numbers.yml +13 -13
  369. data/resources/locales/ur/units.yml +28 -56
  370. data/resources/locales/zh-Hant/calendars.yml +59 -1
  371. data/resources/locales/zh-Hant/currencies.yml +602 -0
  372. data/resources/locales/zh-Hant/languages.yml +74 -8
  373. data/resources/locales/zh-Hant/numbers.yml +17 -4
  374. data/resources/locales/zh-Hant/units.yml +0 -28
  375. data/resources/locales/zh/calendars.yml +95 -35
  376. data/resources/locales/zh/currencies.yml +602 -0
  377. data/resources/locales/zh/languages.yml +116 -46
  378. data/resources/locales/zh/numbers.yml +20 -7
  379. data/resources/locales/zh/units.yml +6 -34
  380. data/resources/shared/currency_digits_and_rounding.yml +187 -0
  381. data/spec/bidi/bidi_spec.rb +1 -1
  382. data/spec/collation/tailoring_spec.rb +29 -25
  383. data/spec/formatters/calendars/datetime_formatter_spec.rb +50 -2
  384. data/spec/formatters/calendars/timespan_formatter_spec.rb +52 -8
  385. data/spec/formatters/numbers/abbreviated/abbreviated_number_formatter_spec.rb +81 -0
  386. data/spec/formatters/numbers/abbreviated/long_decimal_formatter_spec.rb +37 -0
  387. data/spec/formatters/numbers/abbreviated/short_decimal_formatter_spec.rb +37 -0
  388. data/spec/formatters/numbers/currency_formatter_spec.rb +10 -1
  389. data/spec/localized/localized_date_spec.rb +11 -11
  390. data/spec/localized/localized_datetime_spec.rb +27 -3
  391. data/spec/localized/localized_number_spec.rb +34 -6
  392. data/spec/localized/localized_time_spec.rb +1 -1
  393. data/spec/readme_spec.rb +24 -3
  394. data/spec/shared/currencies_spec.rb +7 -9
  395. data/spec/spec_helper.rb +7 -0
  396. data/spec/tokenizers/base_spec.rb +71 -21
  397. data/spec/tokenizers/calendars/additional_date_format_selector_spec.rb +131 -0
  398. data/spec/tokenizers/calendars/datetime_tokenizer_spec.rb +54 -27
  399. data/spec/tokenizers/calendars/time_tokenizer_spec.rb +16 -16
  400. data/spec/tokenizers/numbers/number_tokenizer_spec.rb +9 -21
  401. data/spec/utils/yaml/yaml_spec.rb +21 -16
  402. data/spec/utils_spec.rb +6 -2
  403. metadata +218 -37
@@ -6,34 +6,41 @@
6
6
  module TwitterCldr
7
7
  module Shared
8
8
  module Currencies
9
-
10
9
  class << self
11
-
12
10
  def countries
13
- resource.keys.map(&:to_s)
11
+ Kernel.warn("Currencies#countries will be deprecated. Please use Currencies#for_code.")
12
+ resource_countries.keys.map(&:to_s)
14
13
  end
15
14
 
16
- def currency_codes
17
- resource.values.map { |data| data[:code] }
15
+ def currency_codes(locale = :en)
16
+ resource(locale).keys.map { |c| c.to_s }
18
17
  end
19
18
 
20
- def for_country(country_name)
21
- resource[country_name.to_sym]
19
+ def for_country(country_name, locale = :en)
20
+ Kernel.warn("Currencies#for_country will be deprecated. Please use Currencies#for_code.")
21
+ for_code(resource_countries[country_name.to_sym][:code], locale) if resource_countries[country_name.to_sym]
22
22
  end
23
23
 
24
- def for_code(currency_code)
25
- country_name, data = resource.detect { |_, data| data[:code] == currency_code }
26
- { :country => country_name.to_s, :currency => data[:currency], :symbol => data[:symbol] } if data
24
+ def for_code(currency_code, locale = :en)
25
+ currency_code = currency_code.to_sym
26
+ data = resource(locale)[currency_code]
27
+ { :currency => currency_code,
28
+ :name => data[:one],
29
+ :symbol => data[:symbol] } if data
27
30
  end
28
31
 
29
32
  private
30
33
 
31
- def resource
32
- @resource ||= TwitterCldr.get_resource(:shared, :currencies)
34
+ def resource_countries
35
+ @resource_countries ||= TwitterCldr.get_resource(:shared, :currencies)
33
36
  end
34
37
 
38
+ def resource(locale)
39
+ locale = locale.to_sym
40
+ @resource ||= {}
41
+ @resource[locale] ||= TwitterCldr.get_resource(:locales, locale, :currencies)[locale][:currencies]
42
+ end
35
43
  end
36
-
37
44
  end
38
45
  end
39
46
  end
@@ -5,14 +5,15 @@
5
5
 
6
6
  module TwitterCldr
7
7
  module Tokenizers
8
- autoload :Base, 'twitter_cldr/tokenizers/base'
9
- autoload :CompositeToken, 'twitter_cldr/tokenizers/composite_token'
10
- autoload :KeyPath, 'twitter_cldr/tokenizers/key_path'
11
- autoload :Token, 'twitter_cldr/tokenizers/token'
12
- autoload :DateTimeTokenizer, 'twitter_cldr/tokenizers/calendars/datetime_tokenizer'
13
- autoload :DateTokenizer, 'twitter_cldr/tokenizers/calendars/date_tokenizer'
14
- autoload :TimeTokenizer, 'twitter_cldr/tokenizers/calendars/time_tokenizer'
15
- autoload :NumberTokenizer, 'twitter_cldr/tokenizers/numbers/number_tokenizer'
16
- autoload :TimespanTokenizer, 'twitter_cldr/tokenizers/calendars/timespan_tokenizer'
8
+ autoload :Base, 'twitter_cldr/tokenizers/base'
9
+ autoload :CompositeToken, 'twitter_cldr/tokenizers/composite_token'
10
+ autoload :KeyPath, 'twitter_cldr/tokenizers/key_path'
11
+ autoload :Token, 'twitter_cldr/tokenizers/token'
12
+ autoload :DateTimeTokenizer, 'twitter_cldr/tokenizers/calendars/datetime_tokenizer'
13
+ autoload :DateTokenizer, 'twitter_cldr/tokenizers/calendars/date_tokenizer'
14
+ autoload :TimeTokenizer, 'twitter_cldr/tokenizers/calendars/time_tokenizer'
15
+ autoload :NumberTokenizer, 'twitter_cldr/tokenizers/numbers/number_tokenizer'
16
+ autoload :TimespanTokenizer, 'twitter_cldr/tokenizers/calendars/timespan_tokenizer'
17
+ autoload :AdditionalDateFormatSelector, 'twitter_cldr/tokenizers/calendars/additional_date_format_selector'
17
18
  end
18
19
  end
@@ -7,8 +7,8 @@ module TwitterCldr
7
7
  module Tokenizers
8
8
  class Base
9
9
  attr_reader :resource, :locale
10
- attr_reader :token_splitter_regex, :token_type_regexes, :paths
11
- attr_accessor :type, :placeholders
10
+ attr_reader :token_splitter_regexes, :token_type_regexes, :paths
11
+ attr_accessor :type, :format, :placeholders
12
12
 
13
13
  def initialize(options = {})
14
14
  @locale = TwitterCldr.convert_locale(options[:locale] || TwitterCldr::DEFAULT_LOCALE)
@@ -21,33 +21,45 @@ module TwitterCldr
21
21
  # Not to be confused with tokenize_pattern, which pulls out placeholders. Tokenize_format actually splits a completely
22
22
  # expanded format string into whatever parts are defined by the subclass's token type and token splitter regexes.
23
23
  def tokenize_format(text)
24
- final = []
25
- text.split(token_splitter_regex).each_with_index do |token, index|
24
+ text.split(token_splitter_regex_for(type)).each_with_index.inject([]) do |ret, (token, index)|
26
25
  unless index == 0 && token == ""
27
- token_type_regexes.each do |token_type|
28
- if token =~ token_type[:regex]
29
- if token_type[:type] == :composite
30
- content = token.match(token_type[:content])[1]
31
- final << CompositeToken.new(tokenize_format(content))
32
- else
33
- final << Token.new(:value => token, :type => token_type[:type])
34
- end
35
-
36
- break
37
- end
26
+ regexes = token_type_regexes_for(type)
27
+
28
+ token_type = regexes.inject([]) do |match_ret, (token_type, matchers)|
29
+ match_ret << token_type if token =~ matchers[:regex]
30
+ match_ret
31
+ end.min { |a, b| regexes[a][:priority] <=> regexes[b][:priority] }
32
+
33
+ if token_type == :composite
34
+ content = token.match(regexes[token_type][:content])[1]
35
+ ret << CompositeToken.new(tokenize_format(content))
36
+ else
37
+ ret << Token.new(:value => token, :type => token_type)
38
38
  end
39
39
  end
40
+ ret
40
41
  end
41
- final
42
42
  end
43
43
 
44
- def tokens_for(path, type)
44
+ def token_type_regexes_for(type)
45
+ token_type_regexes[type] || token_type_regexes[:else]
46
+ end
47
+
48
+ def token_splitter_regex_for(type)
49
+ token_splitter_regexes[type] || token_splitter_regexes[:else]
50
+ end
51
+
52
+ def tokens_for(path, additional_cache_key_params = [])
53
+ tokens_for_pattern(pattern_for(traverse(path)), path, additional_cache_key_params)
54
+ end
55
+
56
+ def tokens_for_pattern(pattern, path, additional_cache_key_params = [])
45
57
  @@token_cache ||= {}
46
- cache_key = TwitterCldr::Utils.compute_cache_key(@locale, path.join('.'), type)
58
+ cache_key = TwitterCldr::Utils.compute_cache_key(@locale, path.join('.'), type, format || "nil", *additional_cache_key_params)
47
59
 
48
60
  unless @@token_cache.include?(cache_key)
49
61
  result = []
50
- tokens = expand_pattern(pattern_for(traverse(path)), type)
62
+ tokens = expand_pattern(pattern)
51
63
 
52
64
  tokens.each do |token|
53
65
  if token.is_a?(Token) || token.is_a?(CompositeToken)
@@ -108,10 +120,10 @@ module TwitterCldr
108
120
  end
109
121
  end
110
122
 
111
- def expand_pattern(format_str, type)
123
+ def expand_pattern(format_str)
112
124
  if format_str.is_a?(Symbol)
113
125
  # symbols mean another path was given
114
- expand_pattern(pattern_for(traverse(format_str.to_s.split('.').map(&:to_sym))), type)
126
+ expand_pattern(pattern_for(traverse(format_str.to_s.split('.').map(&:to_sym))))
115
127
  else
116
128
  parts = tokenize_pattern(format_str)
117
129
  final = []
@@ -0,0 +1,86 @@
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 Tokenizers
8
+ class AdditionalDateFormatSelector
9
+ attr_reader :pattern_hash
10
+
11
+ def initialize(pattern_hash)
12
+ @pattern_hash = pattern_hash
13
+ end
14
+
15
+ def find_closest(goal_pattern)
16
+ if !goal_pattern || goal_pattern.strip.empty?
17
+ nil
18
+ else
19
+ rank(goal_pattern).min do |(p1, score1), (p2, score2)|
20
+ score1 <=> score2
21
+ end.first
22
+ end
23
+ end
24
+
25
+ def patterns
26
+ @pattern_hash.keys
27
+ end
28
+
29
+ protected
30
+
31
+ def separate(pattern_key)
32
+ last_char = ""
33
+ pattern_key.each_char.each_with_index.inject([]) do |ret, (char, index)|
34
+ char == last_char ? ret[-1] += char : ret << char
35
+ last_char = char
36
+ ret
37
+ end
38
+ end
39
+
40
+ def all_separated_patterns
41
+ @separated_patterns ||= @pattern_hash.map { |pattern, _| separate(pattern.to_s) }
42
+ end
43
+
44
+ def score(entities, goal_entities)
45
+ # weight existence a little more heavily than the others
46
+ score = exist_score(entities, goal_entities) * 2
47
+ score += position_score(entities, goal_entities)
48
+ score + count_score(entities, goal_entities)
49
+ end
50
+
51
+ def position_score(entities, goal_entities)
52
+ goal_entities.each_with_index.inject(0) do |sum, (goal_entity, index)|
53
+ if found = entities.index(goal_entity)
54
+ sum + (found - index).abs
55
+ else
56
+ sum
57
+ end
58
+ end
59
+ end
60
+
61
+ def exist_score(entities, goal_entities)
62
+ goal_entities.count do |goal_entity|
63
+ !entities.any? { |entity| entity[0] == goal_entity[0] }
64
+ end
65
+ end
66
+
67
+ def count_score(entities, goal_entities)
68
+ goal_entities.inject(0) do |sum, goal_entity|
69
+ if found_entity = entities.select { |entity| entity[0] == goal_entity[0] }.first
70
+ sum + (found_entity.size - goal_entity.size).abs
71
+ else
72
+ sum
73
+ end
74
+ end
75
+ end
76
+
77
+ def rank(goal_pattern)
78
+ separated_goal_pattern = separate(goal_pattern)
79
+ all_separated_patterns.inject({}) do |ret, separated_pattern|
80
+ ret[separated_pattern.join] = score(separated_pattern, separated_goal_pattern)
81
+ ret
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
@@ -6,22 +6,31 @@
6
6
  module TwitterCldr
7
7
  module Tokenizers
8
8
  class DateTokenizer < TwitterCldr::Tokenizers::DateTimeTokenizer
9
+ TOKEN_SPLITTER_REGEX = /(\s*\'[\w\s-]+\'\s*|G{1,5}|y+|Y+|Q{1,4}|q{1,5}|M{1,5}|L{1,5}|d{1,2}|F{1}|E{1,5}|e{1,5}|c{1,5}|\#\{[^\}]+\})/
10
+ TOKEN_TYPE_REGEXES = {
11
+ :composite => { :regex => /^\#\{[^\}]+\}/, :content => /^\#\{([^\}]+)\}/, :priority => 1 },
12
+ :pattern => { :regex => /^(?:G{1,5}|y+|Y+|Q{1,4}|q{1,5}|M{1,5}|L{1,5}|d{1,2}|F{1}|E{1,5}|e{1,5}|c{1,5})/, :priority => 2 },
13
+ :plaintext => { :regex => //, :priority => 3 }
14
+ }
15
+
9
16
  def initialize(options = {})
10
17
  super(options)
11
- @token_splitter_regex = /(\s*\'[\w\s-]+\'\s*|G{1,5}|y+|Y+|Q{1,4}|q{1,5}|M{1,5}|L{1,5}|d{1,2}|F{1}|E{1,5}|e{1,5}|c{1,5}|\#\{[^\}]+\})/
12
18
 
13
- @token_type_regexes = [
14
- { :type => :composite, :regex => /^\#\{[^\}]+\}/, :content => /^\#\{([^\}]+)\}/ },
15
- { :type => :pattern, :regex => /^(?:G{1,5}|y+|Y+|Q{1,4}|q{1,5}|M{1,5}|L{1,5}|d{1,2}|F{1}|E{1,5}|e{1,5}|c{1,5})/ },
16
- { :type => :plaintext, :regex => // }
17
- ]
19
+ @token_splitter_regexes = {
20
+ :else => TOKEN_SPLITTER_REGEX
21
+ }
22
+
23
+ @token_type_regexes = {
24
+ :else => TOKEN_TYPE_REGEXES
25
+ }
18
26
 
19
27
  @paths = {
20
- :default => [:formats, :date, :default],
21
- :full => [:formats, :date, :full],
22
- :long => [:formats, :date, :long],
23
- :medium => [:formats, :date, :medium],
24
- :short => [:formats, :date, :short]
28
+ :default => [:formats, :date, :default],
29
+ :full => [:formats, :date, :full],
30
+ :long => [:formats, :date, :long],
31
+ :medium => [:formats, :date, :medium],
32
+ :short => [:formats, :date, :short],
33
+ :additional => [:additional_formats]
25
34
  }
26
35
  end
27
36
 
@@ -8,38 +8,70 @@ module TwitterCldr
8
8
  class DateTimeTokenizer < Base
9
9
  attr_reader :placeholders, :calendar_type
10
10
 
11
- VALID_TYPES = [:default, :full, :long, :medium, :short]
11
+ VALID_TYPES = [:default, :full, :long, :medium, :short, :additional]
12
12
 
13
13
  def initialize(options = {})
14
14
  @calendar_type = options[:calendar_type] || TwitterCldr::DEFAULT_CALENDAR_TYPE
15
+ @type = options[:type] || :default
16
+ @format = options[:format]
17
+
18
+ @token_splitter_regexes = {
19
+ :additional => Regexp.union(
20
+ DateTokenizer::TOKEN_SPLITTER_REGEX,
21
+ TimeTokenizer::TOKEN_SPLITTER_REGEX
22
+ ),
23
+ :else => //
24
+ }
15
25
 
16
- @token_splitter_regex = //
17
- @token_type_regexes = [{ :type => :plaintext, :regex => // }]
26
+ @token_type_regexes = {
27
+ :additional => merge_token_type_regexes(DateTokenizer::TOKEN_TYPE_REGEXES, TimeTokenizer::TOKEN_TYPE_REGEXES),
28
+ :else => {
29
+ :plaintext => { :regex => // }
30
+ }
31
+ }
18
32
 
19
33
  @base_path = [:calendars]
20
34
 
21
35
  @paths = {
22
- :default => [:formats, :datetime, :default],
23
- :full => [:formats, :datetime, :full],
24
- :long => [:formats, :datetime, :long],
25
- :medium => [:formats, :datetime, :medium],
26
- :short => [:formats, :datetime, :short]
36
+ :default => [:formats, :datetime, :default],
37
+ :full => [:formats, :datetime, :full],
38
+ :long => [:formats, :datetime, :long],
39
+ :medium => [:formats, :datetime, :medium],
40
+ :short => [:formats, :datetime, :short],
41
+ :additional => [:additional_formats]
27
42
  }
28
43
 
29
44
  super(options)
30
45
  end
31
46
 
32
47
  def tokens(options = {})
33
- type = options[:type] || :default
34
- tokens_for(full_path_for(paths[type]), type)
48
+ @type = options[:type] || @type || :default
49
+ @format = options[:format] || @format
50
+ tokens_for(full_path_for(paths[@type]))
35
51
  end
36
52
 
37
53
  def calendar
38
54
  @resource[:calendars][@calendar_type]
39
55
  end
40
56
 
57
+ def additional_format_selector
58
+ @additional_format_selector ||= AdditionalDateFormatSelector.new(
59
+ @resource[:calendars][@calendar_type][:additional_formats]
60
+ )
61
+ end
62
+
41
63
  protected
42
64
 
65
+ def merge_token_type_regexes(first, second)
66
+ TwitterCldr::Utils.deep_merge_hash(first, second) do |left, right|
67
+ if right.is_a?(Regexp) && left.is_a?(Regexp)
68
+ Regexp.union(left, right)
69
+ else
70
+ left
71
+ end
72
+ end
73
+ end
74
+
43
75
  def full_path_for(path, calendar_type = @calendar_type)
44
76
  @base_path + [calendar_type] + path
45
77
  end
@@ -71,13 +103,18 @@ module TwitterCldr
71
103
 
72
104
  def init_placeholders
73
105
  @placeholders = [
74
- { :name => :time, :object => TwitterCldr::Tokenizers::TimeTokenizer.new(:locale => @locale, :calendar_type => @calendar_type) },
75
- { :name => :date, :object => TwitterCldr::Tokenizers::DateTokenizer.new(:locale => @locale, :calendar_type => @calendar_type) }
106
+ { :name => :time, :object => TwitterCldr::Tokenizers::TimeTokenizer.new(:locale => @locale, :calendar_type => @calendar_type) },
107
+ { :name => :date, :object => TwitterCldr::Tokenizers::DateTokenizer.new(:locale => @locale, :calendar_type => @calendar_type) }
76
108
  ]
77
109
  end
78
110
 
79
111
  def pattern_for(resource)
80
- resource.is_a?(Hash) ? resource[:pattern] : resource
112
+ case type
113
+ when :additional
114
+ resource[additional_format_selector.find_closest(format).to_sym]
115
+ else
116
+ resource.is_a?(Hash) ? resource[:pattern] : resource
117
+ end
81
118
  end
82
119
  end
83
120
  end
@@ -6,21 +6,30 @@
6
6
  module TwitterCldr
7
7
  module Tokenizers
8
8
  class TimeTokenizer < TwitterCldr::Tokenizers::DateTimeTokenizer
9
+ TOKEN_SPLITTER_REGEX = /(\'[\w\s-]+\'|a{1}|h{1,2}|H{1,2}|K{1,2}|k{1,2}|m{1,2}|s{1,2}|S+|z{1,4}|Z{1,4})/
10
+ TOKEN_TYPE_REGEXES = {
11
+ :pattern => { :regex => /^(a{1}|h{1,2}|H{1,2}|K{1,2}|k{1,2}|m{1,2}|s{1,2}|S+|z{1,4}|Z{1,4})/, :priority => 1 },
12
+ :plaintext => { :regex => //, :priority => 2 }
13
+ }
14
+
9
15
  def initialize(options = {})
10
16
  super(options)
11
- @token_splitter_regex = /(\'[\w\s-]+\'|a{1}|h{1,2}|H{1,2}|K{1,2}|k{1,2}|m{1,2}|s{1,2}|S+|z{1,4}|Z{1,4})/
12
17
 
13
- @token_type_regexes = [
14
- { :type => :pattern, :regex => /^(a{1}|h{1,2}|H{1,2}|K{1,2}|k{1,2}|m{1,2}|s{1,2}|S+|z{1,4}|Z{1,4})/ },
15
- { :type => :plaintext, :regex => // }
16
- ]
18
+ @token_splitter_regexes = {
19
+ :else => TOKEN_SPLITTER_REGEX
20
+ }
21
+
22
+ @token_type_regexes = {
23
+ :else => TOKEN_TYPE_REGEXES
24
+ }
17
25
 
18
26
  @paths = {
19
- :default => [:formats, :time, :default],
20
- :full => [:formats, :time, :full],
21
- :long => [:formats, :time, :long],
22
- :medium => [:formats, :time, :medium],
23
- :short => [:formats, :time, :short]
27
+ :default => [:formats, :time, :default],
28
+ :full => [:formats, :time, :full],
29
+ :long => [:formats, :time, :long],
30
+ :medium => [:formats, :time, :medium],
31
+ :short => [:formats, :time, :short],
32
+ :additional => [:additional_formats]
24
33
  }
25
34
  end
26
35
 
@@ -15,43 +15,43 @@ module TwitterCldr
15
15
  @token_splitter_regex = /([^0*#,\.]*)([0#,\.]+)([^0*#,\.]*)$/ # creates spaces
16
16
 
17
17
  @token_type_regexes = [
18
- { :type => :pattern, :regex => /[0?#,\.]*/ }, # splits token at right places
19
- { :type => :plaintext, :regex => // }
18
+ { :type => :pattern, :regex => /[0?#,\.]*/ }, # splits token at right places
19
+ { :type => :plaintext, :regex => // }
20
20
  ]
21
21
 
22
22
  @base_path = [:units]
23
23
 
24
24
  @paths = {
25
- :ago => {
26
- :default => :'hour-past',
27
- :second => :'second-past',
28
- :minute => :'minute-past',
29
- :hour => :'hour-past',
30
- :day => :'day-past',
31
- :week => :'week-past',
32
- :month => :'month-past',
33
- :year => :'year-past'
34
- },
35
- :until => {
36
- :default => :'hour-future',
37
- :second => :'second-future',
38
- :minute => :'minute-future',
39
- :hour => :'hour-future',
40
- :day => :'day-future',
41
- :week => :'week-future',
42
- :month => :'month-future',
43
- :year => :'year-future'
44
- },
45
- :none => {
46
- :default => :second,
47
- :second => :second,
48
- :minute => :minute,
49
- :hour => :hour,
50
- :day => :day,
51
- :week => :week,
52
- :month => :month,
53
- :year => :year
54
- }
25
+ :ago => {
26
+ :default => :'hour-past',
27
+ :second => :'second-past',
28
+ :minute => :'minute-past',
29
+ :hour => :'hour-past',
30
+ :day => :'day-past',
31
+ :week => :'week-past',
32
+ :month => :'month-past',
33
+ :year => :'year-past'
34
+ },
35
+ :until => {
36
+ :default => :'hour-future',
37
+ :second => :'second-future',
38
+ :minute => :'minute-future',
39
+ :hour => :'hour-future',
40
+ :day => :'day-future',
41
+ :week => :'week-future',
42
+ :month => :'month-future',
43
+ :year => :'year-future'
44
+ },
45
+ :none => {
46
+ :default => :second,
47
+ :second => :second,
48
+ :minute => :minute,
49
+ :hour => :hour,
50
+ :day => :day,
51
+ :week => :week,
52
+ :month => :month,
53
+ :year => :year
54
+ }
55
55
  }
56
56
  end
57
57