experteer-gettext 2.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (424) hide show
  1. data/COPYING +55 -0
  2. data/ChangeLog +57 -0
  3. data/ChangeLog-1 +2016 -0
  4. data/NEWS-1 +414 -0
  5. data/README.rdoc +251 -0
  6. data/Rakefile +260 -0
  7. data/VERSION +2 -0
  8. data/bin/rgettext +24 -0
  9. data/bin/rmsgfmt +24 -0
  10. data/bin/rmsgmerge +24 -0
  11. data/gettext.gemspec +494 -0
  12. data/lib/gettext/cgi.rb +39 -0
  13. data/lib/gettext/class_info.rb +67 -0
  14. data/lib/gettext/core_ext/iconv.rb +112 -0
  15. data/lib/gettext/core_ext/string.rb +84 -0
  16. data/lib/gettext/locale_path.rb +123 -0
  17. data/lib/gettext/mofile.rb +330 -0
  18. data/lib/gettext/parser/erb.rb +54 -0
  19. data/lib/gettext/parser/glade.rb +100 -0
  20. data/lib/gettext/parser/ruby.rb +193 -0
  21. data/lib/gettext/poparser.rb +355 -0
  22. data/lib/gettext/textdomain.rb +179 -0
  23. data/lib/gettext/textdomain_group.rb +24 -0
  24. data/lib/gettext/textdomain_manager.rb +212 -0
  25. data/lib/gettext/tools/rgettext.rb +236 -0
  26. data/lib/gettext/tools/rmsgfmt.rb +84 -0
  27. data/lib/gettext/tools/rmsgmerge.rb +498 -0
  28. data/lib/gettext/tools.rb +195 -0
  29. data/lib/gettext/translation_target.rb +93 -0
  30. data/lib/gettext/utils.rb +37 -0
  31. data/lib/gettext/version.rb +12 -0
  32. data/lib/gettext.rb +312 -0
  33. data/po/bg/rgettext.po +130 -0
  34. data/po/bs/rgettext.po +131 -0
  35. data/po/ca/rgettext.po +129 -0
  36. data/po/cs/rgettext.po +132 -0
  37. data/po/de/rgettext.po +137 -0
  38. data/po/el/rgettext.po +128 -0
  39. data/po/eo/rgettext.po +129 -0
  40. data/po/es/rgettext.po +130 -0
  41. data/po/et/rgettext.po +127 -0
  42. data/po/fr/rgettext.po +133 -0
  43. data/po/hr/rgettext.po +131 -0
  44. data/po/hu/rgettext.po +129 -0
  45. data/po/it/rgettext.po +130 -0
  46. data/po/ja/rgettext.po +129 -0
  47. data/po/ko/rgettext.po +129 -0
  48. data/po/lv/rgettext.po +130 -0
  49. data/po/nb/rgettext.po +131 -0
  50. data/po/nl/rgettext.po +130 -0
  51. data/po/pt_BR/rgettext.po +132 -0
  52. data/po/rgettext.pot +121 -0
  53. data/po/ru/rgettext.po +131 -0
  54. data/po/sr/rgettext.po +130 -0
  55. data/po/sv/rgettext.po +123 -0
  56. data/po/ua/rgettext.po +134 -0
  57. data/po/vi/rgettext.po +128 -0
  58. data/po/zh/rgettext.po +129 -0
  59. data/po/zh_TW/rgettext.po +128 -0
  60. data/samples/README +16 -0
  61. data/samples/cgi/README +43 -0
  62. data/samples/cgi/Rakefile +27 -0
  63. data/samples/cgi/cookie.cgi +64 -0
  64. data/samples/cgi/gettext.css +116 -0
  65. data/samples/cgi/helloerb.rhtml +28 -0
  66. data/samples/cgi/helloerb1.cgi +58 -0
  67. data/samples/cgi/helloerb2.cgi +51 -0
  68. data/samples/cgi/hellolib.rb +20 -0
  69. data/samples/cgi/http.rb +51 -0
  70. data/samples/cgi/index.cgi +111 -0
  71. data/samples/cgi/other.rhtml +20 -0
  72. data/samples/cgi/po/bg/helloerb1.po +59 -0
  73. data/samples/cgi/po/bg/helloerb2.po +51 -0
  74. data/samples/cgi/po/bg/hellolib.po +23 -0
  75. data/samples/cgi/po/bg/main.po +83 -0
  76. data/samples/cgi/po/bs/helloerb1.po +59 -0
  77. data/samples/cgi/po/bs/helloerb2.po +51 -0
  78. data/samples/cgi/po/bs/hellolib.po +23 -0
  79. data/samples/cgi/po/bs/main.po +83 -0
  80. data/samples/cgi/po/ca/helloerb1.po +59 -0
  81. data/samples/cgi/po/ca/helloerb2.po +51 -0
  82. data/samples/cgi/po/ca/hellolib.po +23 -0
  83. data/samples/cgi/po/ca/main.po +83 -0
  84. data/samples/cgi/po/cs/helloerb1.po +61 -0
  85. data/samples/cgi/po/cs/helloerb2.po +52 -0
  86. data/samples/cgi/po/cs/hellolib.po +25 -0
  87. data/samples/cgi/po/cs/main.po +85 -0
  88. data/samples/cgi/po/de/helloerb1.po +61 -0
  89. data/samples/cgi/po/de/helloerb2.po +52 -0
  90. data/samples/cgi/po/de/hellolib.po +24 -0
  91. data/samples/cgi/po/de/main.po +86 -0
  92. data/samples/cgi/po/el/helloerb1.po +60 -0
  93. data/samples/cgi/po/el/helloerb2.po +51 -0
  94. data/samples/cgi/po/el/hellolib.po +23 -0
  95. data/samples/cgi/po/el/main.po +84 -0
  96. data/samples/cgi/po/eo/helloerb1.po +60 -0
  97. data/samples/cgi/po/eo/helloerb2.po +52 -0
  98. data/samples/cgi/po/eo/hellolib.po +24 -0
  99. data/samples/cgi/po/eo/main.po +84 -0
  100. data/samples/cgi/po/es/helloerb1.po +59 -0
  101. data/samples/cgi/po/es/helloerb2.po +50 -0
  102. data/samples/cgi/po/es/hellolib.po +22 -0
  103. data/samples/cgi/po/es/main.po +83 -0
  104. data/samples/cgi/po/fr/helloerb1.po +59 -0
  105. data/samples/cgi/po/fr/helloerb2.po +51 -0
  106. data/samples/cgi/po/fr/hellolib.po +22 -0
  107. data/samples/cgi/po/fr/main.po +85 -0
  108. data/samples/cgi/po/helloerb1.pot +60 -0
  109. data/samples/cgi/po/helloerb2.pot +52 -0
  110. data/samples/cgi/po/hellolib.pot +24 -0
  111. data/samples/cgi/po/hr/helloerb1.po +59 -0
  112. data/samples/cgi/po/hr/helloerb2.po +51 -0
  113. data/samples/cgi/po/hr/hellolib.po +23 -0
  114. data/samples/cgi/po/hr/main.po +83 -0
  115. data/samples/cgi/po/hu/helloerb1.po +59 -0
  116. data/samples/cgi/po/hu/helloerb2.po +51 -0
  117. data/samples/cgi/po/hu/hellolib.po +23 -0
  118. data/samples/cgi/po/hu/main.po +82 -0
  119. data/samples/cgi/po/it/helloerb1.po +60 -0
  120. data/samples/cgi/po/it/helloerb2.po +52 -0
  121. data/samples/cgi/po/it/hellolib.po +24 -0
  122. data/samples/cgi/po/it/main.po +84 -0
  123. data/samples/cgi/po/ja/helloerb1.po +60 -0
  124. data/samples/cgi/po/ja/helloerb2.po +52 -0
  125. data/samples/cgi/po/ja/hellolib.po +24 -0
  126. data/samples/cgi/po/ja/main.po +85 -0
  127. data/samples/cgi/po/ko/helloerb1.po +59 -0
  128. data/samples/cgi/po/ko/helloerb2.po +51 -0
  129. data/samples/cgi/po/ko/hellolib.po +23 -0
  130. data/samples/cgi/po/ko/main.po +84 -0
  131. data/samples/cgi/po/lv/helloerb1.po +65 -0
  132. data/samples/cgi/po/lv/helloerb2.po +52 -0
  133. data/samples/cgi/po/lv/hellolib.po +24 -0
  134. data/samples/cgi/po/lv/main.po +77 -0
  135. data/samples/cgi/po/main.pot +80 -0
  136. data/samples/cgi/po/nb/helloerb1.po +60 -0
  137. data/samples/cgi/po/nb/helloerb2.po +52 -0
  138. data/samples/cgi/po/nb/hellolib.po +24 -0
  139. data/samples/cgi/po/nb/main.po +84 -0
  140. data/samples/cgi/po/nl/helloerb1.po +61 -0
  141. data/samples/cgi/po/nl/helloerb2.po +52 -0
  142. data/samples/cgi/po/nl/hellolib.po +24 -0
  143. data/samples/cgi/po/nl/main.po +86 -0
  144. data/samples/cgi/po/pt_BR/helloerb1.po +59 -0
  145. data/samples/cgi/po/pt_BR/helloerb2.po +51 -0
  146. data/samples/cgi/po/pt_BR/hellolib.po +23 -0
  147. data/samples/cgi/po/pt_BR/main.po +84 -0
  148. data/samples/cgi/po/ru/helloerb1.po +58 -0
  149. data/samples/cgi/po/ru/helloerb2.po +50 -0
  150. data/samples/cgi/po/ru/hellolib.po +22 -0
  151. data/samples/cgi/po/ru/main.po +82 -0
  152. data/samples/cgi/po/sr/helloerb1.po +60 -0
  153. data/samples/cgi/po/sr/helloerb2.po +52 -0
  154. data/samples/cgi/po/sr/hellolib.po +24 -0
  155. data/samples/cgi/po/sr/main.po +80 -0
  156. data/samples/cgi/po/ua/helloerb1.po +62 -0
  157. data/samples/cgi/po/ua/helloerb2.po +54 -0
  158. data/samples/cgi/po/ua/hellolib.po +26 -0
  159. data/samples/cgi/po/ua/main.po +84 -0
  160. data/samples/cgi/po/vi/helloerb1.po +65 -0
  161. data/samples/cgi/po/vi/helloerb2.po +52 -0
  162. data/samples/cgi/po/vi/hellolib.po +24 -0
  163. data/samples/cgi/po/vi/main.po +77 -0
  164. data/samples/cgi/po/zh/helloerb1.po +60 -0
  165. data/samples/cgi/po/zh/helloerb2.po +52 -0
  166. data/samples/cgi/po/zh/hellolib.po +24 -0
  167. data/samples/cgi/po/zh/main.po +80 -0
  168. data/samples/cgi/po/zh_TW/helloerb1.po +67 -0
  169. data/samples/cgi/po/zh_TW/helloerb2.po +54 -0
  170. data/samples/cgi/po/zh_TW/hellolib.po +26 -0
  171. data/samples/cgi/po/zh_TW/main.po +79 -0
  172. data/samples/hello.rb +36 -0
  173. data/samples/hello2.rb +23 -0
  174. data/samples/hello_glade2.glade +70 -0
  175. data/samples/hello_glade2.rb +25 -0
  176. data/samples/hello_gtk2.rb +27 -0
  177. data/samples/hello_noop.rb +31 -0
  178. data/samples/hello_plural.rb +26 -0
  179. data/samples/hello_tk.rb +19 -0
  180. data/samples/makemo.rb +4 -0
  181. data/samples/po/bg/hello.po +24 -0
  182. data/samples/po/bg/hello2.po +31 -0
  183. data/samples/po/bg/hello_glade2.po +31 -0
  184. data/samples/po/bg/hello_gtk.po +23 -0
  185. data/samples/po/bg/hello_noop.po +27 -0
  186. data/samples/po/bg/hello_plural.po +25 -0
  187. data/samples/po/bg/hello_tk.po +23 -0
  188. data/samples/po/bs/hello.po +23 -0
  189. data/samples/po/bs/hello2.po +31 -0
  190. data/samples/po/bs/hello_glade2.po +31 -0
  191. data/samples/po/bs/hello_gtk.po +23 -0
  192. data/samples/po/bs/hello_noop.po +27 -0
  193. data/samples/po/bs/hello_plural.po +26 -0
  194. data/samples/po/bs/hello_tk.po +23 -0
  195. data/samples/po/ca/hello.po +23 -0
  196. data/samples/po/ca/hello2.po +31 -0
  197. data/samples/po/ca/hello_glade2.po +31 -0
  198. data/samples/po/ca/hello_gtk.po +23 -0
  199. data/samples/po/ca/hello_noop.po +27 -0
  200. data/samples/po/ca/hello_plural.po +25 -0
  201. data/samples/po/ca/hello_tk.po +23 -0
  202. data/samples/po/cs/hello.po +23 -0
  203. data/samples/po/cs/hello2.po +31 -0
  204. data/samples/po/cs/hello_glade2.po +37 -0
  205. data/samples/po/cs/hello_gtk.po +23 -0
  206. data/samples/po/cs/hello_noop.po +27 -0
  207. data/samples/po/cs/hello_plural.po +26 -0
  208. data/samples/po/cs/hello_tk.po +23 -0
  209. data/samples/po/de/hello.po +20 -0
  210. data/samples/po/de/hello2.po +28 -0
  211. data/samples/po/de/hello_glade2.po +27 -0
  212. data/samples/po/de/hello_gtk.po +20 -0
  213. data/samples/po/de/hello_noop.po +24 -0
  214. data/samples/po/de/hello_plural.po +25 -0
  215. data/samples/po/de/hello_tk.po +20 -0
  216. data/samples/po/el/hello.po +23 -0
  217. data/samples/po/el/hello2.po +31 -0
  218. data/samples/po/el/hello_glade2.po +31 -0
  219. data/samples/po/el/hello_gtk.po +22 -0
  220. data/samples/po/el/hello_noop.po +27 -0
  221. data/samples/po/el/hello_plural.po +25 -0
  222. data/samples/po/el/hello_tk.po +23 -0
  223. data/samples/po/eo/hello.po +23 -0
  224. data/samples/po/eo/hello2.po +31 -0
  225. data/samples/po/eo/hello_glade2.po +32 -0
  226. data/samples/po/eo/hello_gtk.po +23 -0
  227. data/samples/po/eo/hello_noop.po +27 -0
  228. data/samples/po/eo/hello_plural.po +26 -0
  229. data/samples/po/eo/hello_tk.po +24 -0
  230. data/samples/po/es/hello.po +21 -0
  231. data/samples/po/es/hello2.po +28 -0
  232. data/samples/po/es/hello_glade2.po +28 -0
  233. data/samples/po/es/hello_gtk.po +20 -0
  234. data/samples/po/es/hello_noop.po +24 -0
  235. data/samples/po/es/hello_plural.po +23 -0
  236. data/samples/po/es/hello_tk.po +20 -0
  237. data/samples/po/fr/hello.po +18 -0
  238. data/samples/po/fr/hello2.po +26 -0
  239. data/samples/po/fr/hello_glade2.po +27 -0
  240. data/samples/po/fr/hello_gtk.po +18 -0
  241. data/samples/po/fr/hello_noop.po +22 -0
  242. data/samples/po/fr/hello_plural.po +21 -0
  243. data/samples/po/fr/hello_tk.po +18 -0
  244. data/samples/po/hello.pot +23 -0
  245. data/samples/po/hello2.pot +31 -0
  246. data/samples/po/hello_glade2.pot +32 -0
  247. data/samples/po/hello_gtk.pot +23 -0
  248. data/samples/po/hello_noop.pot +27 -0
  249. data/samples/po/hello_plural.pot +26 -0
  250. data/samples/po/hello_tk.pot +24 -0
  251. data/samples/po/hr/hello.po +23 -0
  252. data/samples/po/hr/hello2.po +31 -0
  253. data/samples/po/hr/hello_glade2.po +31 -0
  254. data/samples/po/hr/hello_gtk.po +23 -0
  255. data/samples/po/hr/hello_noop.po +27 -0
  256. data/samples/po/hr/hello_plural.po +26 -0
  257. data/samples/po/hr/hello_tk.po +23 -0
  258. data/samples/po/hu/hello.po +22 -0
  259. data/samples/po/hu/hello2.po +30 -0
  260. data/samples/po/hu/hello_glade2.po +31 -0
  261. data/samples/po/hu/hello_gtk.po +22 -0
  262. data/samples/po/hu/hello_noop.po +26 -0
  263. data/samples/po/hu/hello_plural.po +25 -0
  264. data/samples/po/hu/hello_tk.po +23 -0
  265. data/samples/po/it/hello.po +20 -0
  266. data/samples/po/it/hello2.po +28 -0
  267. data/samples/po/it/hello_glade2.po +28 -0
  268. data/samples/po/it/hello_gtk.po +21 -0
  269. data/samples/po/it/hello_noop.po +24 -0
  270. data/samples/po/it/hello_plural.po +23 -0
  271. data/samples/po/it/hello_tk.po +21 -0
  272. data/samples/po/ja/hello.po +20 -0
  273. data/samples/po/ja/hello2.po +28 -0
  274. data/samples/po/ja/hello_glade2.po +26 -0
  275. data/samples/po/ja/hello_gtk.po +19 -0
  276. data/samples/po/ja/hello_noop.po +23 -0
  277. data/samples/po/ja/hello_plural.po +21 -0
  278. data/samples/po/ja/hello_tk.po +19 -0
  279. data/samples/po/ko/hello.po +18 -0
  280. data/samples/po/ko/hello2.po +26 -0
  281. data/samples/po/ko/hello_glade2.po +29 -0
  282. data/samples/po/ko/hello_gtk.po +18 -0
  283. data/samples/po/ko/hello_noop.po +22 -0
  284. data/samples/po/ko/hello_plural.po +25 -0
  285. data/samples/po/ko/hello_tk.po +19 -0
  286. data/samples/po/lv/hello.po +24 -0
  287. data/samples/po/lv/hello2.po +32 -0
  288. data/samples/po/lv/hello_glade2.po +38 -0
  289. data/samples/po/lv/hello_gtk.po +24 -0
  290. data/samples/po/lv/hello_noop.po +28 -0
  291. data/samples/po/lv/hello_plural.po +26 -0
  292. data/samples/po/lv/hello_tk.po +24 -0
  293. data/samples/po/nb/hello.po +23 -0
  294. data/samples/po/nb/hello2.po +31 -0
  295. data/samples/po/nb/hello_glade2.po +31 -0
  296. data/samples/po/nb/hello_gtk.po +23 -0
  297. data/samples/po/nb/hello_noop.po +27 -0
  298. data/samples/po/nb/hello_plural.po +26 -0
  299. data/samples/po/nb/hello_tk.po +24 -0
  300. data/samples/po/nl/hello.po +24 -0
  301. data/samples/po/nl/hello2.po +32 -0
  302. data/samples/po/nl/hello_glade2.po +31 -0
  303. data/samples/po/nl/hello_gtk.po +24 -0
  304. data/samples/po/nl/hello_noop.po +28 -0
  305. data/samples/po/nl/hello_plural.po +25 -0
  306. data/samples/po/nl/hello_tk.po +24 -0
  307. data/samples/po/pt_BR/hello.po +21 -0
  308. data/samples/po/pt_BR/hello2.po +29 -0
  309. data/samples/po/pt_BR/hello_glade2.po +29 -0
  310. data/samples/po/pt_BR/hello_gtk.po +21 -0
  311. data/samples/po/pt_BR/hello_noop.po +25 -0
  312. data/samples/po/pt_BR/hello_plural.po +23 -0
  313. data/samples/po/pt_BR/hello_tk.po +21 -0
  314. data/samples/po/ru/hello.po +22 -0
  315. data/samples/po/ru/hello2.po +30 -0
  316. data/samples/po/ru/hello_glade2.po +30 -0
  317. data/samples/po/ru/hello_gtk.po +22 -0
  318. data/samples/po/ru/hello_noop.po +26 -0
  319. data/samples/po/ru/hello_plural.po +28 -0
  320. data/samples/po/ru/hello_tk.po +22 -0
  321. data/samples/po/sr/hello.po +22 -0
  322. data/samples/po/sr/hello2.po +30 -0
  323. data/samples/po/sr/hello_glade2.po +32 -0
  324. data/samples/po/sr/hello_gtk.po +22 -0
  325. data/samples/po/sr/hello_noop.po +26 -0
  326. data/samples/po/sr/hello_plural.po +26 -0
  327. data/samples/po/sr/hello_tk.po +24 -0
  328. data/samples/po/sv/hello.po +20 -0
  329. data/samples/po/sv/hello2.po +28 -0
  330. data/samples/po/sv/hello_glade2.po +28 -0
  331. data/samples/po/sv/hello_gtk.po +20 -0
  332. data/samples/po/sv/hello_noop.po +24 -0
  333. data/samples/po/sv/hello_plural.po +23 -0
  334. data/samples/po/sv/hello_tk.po +20 -0
  335. data/samples/po/test.rb +11 -0
  336. data/samples/po/ua/hello.po +22 -0
  337. data/samples/po/ua/hello2.po +30 -0
  338. data/samples/po/ua/hello_glade2.po +34 -0
  339. data/samples/po/ua/hello_gtk.po +22 -0
  340. data/samples/po/ua/hello_noop.po +26 -0
  341. data/samples/po/ua/hello_plural.po +29 -0
  342. data/samples/po/ua/hello_tk.po +26 -0
  343. data/samples/po/vi/hello.po +23 -0
  344. data/samples/po/vi/hello2.po +31 -0
  345. data/samples/po/vi/hello_glade2.po +38 -0
  346. data/samples/po/vi/hello_gtk.po +23 -0
  347. data/samples/po/vi/hello_noop.po +27 -0
  348. data/samples/po/vi/hello_plural.po +26 -0
  349. data/samples/po/vi/hello_tk.po +24 -0
  350. data/samples/po/zh/hello.po +23 -0
  351. data/samples/po/zh/hello2.po +31 -0
  352. data/samples/po/zh/hello_glade2.po +31 -0
  353. data/samples/po/zh/hello_gtk.po +23 -0
  354. data/samples/po/zh/hello_noop.po +27 -0
  355. data/samples/po/zh/hello_plural.po +25 -0
  356. data/samples/po/zh/hello_tk.po +23 -0
  357. data/samples/po/zh_TW/hello.po +26 -0
  358. data/samples/po/zh_TW/hello2.po +34 -0
  359. data/samples/po/zh_TW/hello_glade2.po +40 -0
  360. data/samples/po/zh_TW/hello_gtk.po +25 -0
  361. data/samples/po/zh_TW/hello_noop.po +30 -0
  362. data/samples/po/zh_TW/hello_plural.po +28 -0
  363. data/samples/po/zh_TW/hello_tk.po +26 -0
  364. data/test/README +1 -0
  365. data/test/Rakefile +17 -0
  366. data/test/po/cr/plural.po +23 -0
  367. data/test/po/da/plural.po +22 -0
  368. data/test/po/da/plural_error.po +22 -0
  369. data/test/po/fr/plural.po +28 -0
  370. data/test/po/fr/plural_error.po +20 -0
  371. data/test/po/fr/test1.po +23 -0
  372. data/test/po/fr/test2.po +19 -0
  373. data/test/po/ir/plural.po +23 -0
  374. data/test/po/ja/npgettext.po +46 -0
  375. data/test/po/ja/nsgettext.po +65 -0
  376. data/test/po/ja/pgettext.po +41 -0
  377. data/test/po/ja/plural.po +28 -0
  378. data/test/po/ja/plural_error.po +20 -0
  379. data/test/po/ja/rubyparser.po +43 -0
  380. data/test/po/ja/sgettext.po +47 -0
  381. data/test/po/ja/test1.po +23 -0
  382. data/test/po/ja/test2.po +19 -0
  383. data/test/po/ja/test3.po +19 -0
  384. data/test/po/la/plural.po +23 -0
  385. data/test/po/la/plural_error.po +21 -0
  386. data/test/po/li/plural.po +23 -0
  387. data/test/po/li/plural_error.po +27 -0
  388. data/test/po/po/plural.po +23 -0
  389. data/test/po/sl/plural.po +24 -0
  390. data/test/test_class_info.rb +83 -0
  391. data/test/test_gettext.rb +311 -0
  392. data/test/test_locale_path.rb +50 -0
  393. data/test/test_parser.rb +157 -0
  394. data/test/test_po_generation.rb +20 -0
  395. data/test/test_string.rb +65 -0
  396. data/test/test_textdomain_bind.rb +37 -0
  397. data/test/test_textdomain_multi.rb +80 -0
  398. data/test/test_textdomain_toplevel.rb +42 -0
  399. data/test/test_thread.rb +41 -0
  400. data/test/test_translation_target.rb +29 -0
  401. data/test/testlib/N_.rb +66 -0
  402. data/test/testlib/erb.rhtml +15 -0
  403. data/test/testlib/erb.rxml +16 -0
  404. data/test/testlib/gettext.rb +113 -0
  405. data/test/testlib/gladeparser.glade +183 -0
  406. data/test/testlib/helper.rb +11 -0
  407. data/test/testlib/multi_textdomain.rb +131 -0
  408. data/test/testlib/ngettext.rb +79 -0
  409. data/test/testlib/npgettext.rb +31 -0
  410. data/test/testlib/nsgettext.rb +42 -0
  411. data/test/testlib/pgettext.rb +36 -0
  412. data/test/testlib/sgettext.rb +46 -0
  413. data/test/testlib/simple.rb +14 -0
  414. data/test/tools/files/app.pot +0 -0
  415. data/test/tools/files/de/app.po +0 -0
  416. data/test/tools/files/en/app.po +0 -0
  417. data/test/tools/files/en/test.po +21 -0
  418. data/test/tools/files/simple_1.po +2 -0
  419. data/test/tools/files/simple_2.po +2 -0
  420. data/test/tools/files/simple_translation.rb +1 -0
  421. data/test/tools/files/version.po +7 -0
  422. data/test/tools/test.pot +21 -0
  423. data/test/tools/test_tools.rb +61 -0
  424. metadata +510 -0
@@ -0,0 +1,112 @@
1
+ # encoding: utf-8
2
+ =begin
3
+ iconv.rb - Pseudo Iconv class. Supports Iconv.iconv, Iconv.conv.
4
+
5
+ For Matz Ruby:
6
+ If you don't have iconv but glib2, this library uses glib2 iconv functions.
7
+
8
+ For JRuby:
9
+ Use Java String class to convert strings.
10
+
11
+ Copyright (C) 2004-2007 Masao Mutoh
12
+
13
+ You may redistribute it and/or modify it under the same
14
+ license terms as Ruby.
15
+
16
+ $Id: iconv.rb,v 1.6 2007/11/08 14:21:22 mutoh Exp $
17
+ =end
18
+
19
+ begin
20
+ require 'iconv.so'
21
+ rescue LoadError
22
+ # Pseudo Iconv class
23
+ #
24
+ # ==== For Matz Ruby:
25
+ # If you don't have iconv but Ruby/GLib2, this library uses Ruby/GLib2's
26
+ # iconv functions.
27
+ #
28
+ # Ruby/GLib is a module which is provided from Ruby-GNOME2 Project.
29
+ # You can get binaries for Win32(One-Click Ruby Installer).
30
+ # <URL: http://ruby-gnome2.sourceforge.jp/>
31
+ # ==== For JRuby:
32
+ # Use Java String class to convert strings.
33
+ class Iconv
34
+ module Failure; end
35
+ class InvalidEncoding < ArgumentError; include Failure; end
36
+ class IllegalSequence < ArgumentError; include Failure; end
37
+ class InvalidCharacter < ArgumentError; include Failure; end
38
+
39
+ if RUBY_PLATFORM =~ /java/
40
+ def self.conv(to, from, str)
41
+ raise InvalidCharacter, "the 3rd argument is nil" unless str
42
+ begin
43
+ str = java.lang.String.new(str.unpack("C*").to_java(:byte), from)
44
+ str.getBytes(to).to_ary.pack("C*")
45
+ rescue java.io.UnsupportedEncodingException
46
+ raise InvalidEncoding
47
+ end
48
+ end
49
+ else
50
+ begin
51
+ require 'glib2'
52
+
53
+ def self.check_glib_version?(major, minor, micro) # :nodoc:
54
+ (GLib::BINDING_VERSION[0] > major ||
55
+ (GLib::BINDING_VERSION[0] == major &&
56
+ GLib::BINDING_VERSION[1] > minor) ||
57
+ (GLib::BINDING_VERSION[0] == major &&
58
+ GLib::BINDING_VERSION[1] == minor &&
59
+ GLib::BINDING_VERSION[2] >= micro))
60
+ end
61
+
62
+ if check_glib_version?(0, 11, 0)
63
+ # This is a function equivalent of Iconv.iconv.
64
+ # * to: encoding name for destination
65
+ # * from: encoding name for source
66
+ # * str: strings to be converted
67
+ # * Returns: Returns an Array of converted strings.
68
+ def self.conv(to, from, str)
69
+ begin
70
+ GLib.convert(str, to, from)
71
+ rescue GLib::ConvertError => e
72
+ case e.code
73
+ when GLib::ConvertError::NO_CONVERSION
74
+ raise InvalidEncoding.new(str)
75
+ when GLib::ConvertError::ILLEGAL_SEQUENCE
76
+ raise IllegalSequence.new(str)
77
+ else
78
+ raise InvalidCharacter.new(str)
79
+ end
80
+ end
81
+ end
82
+ else
83
+ def self.conv(to, from, str) # :nodoc:
84
+ begin
85
+ GLib.convert(str, to, from)
86
+ rescue
87
+ raise IllegalSequence.new(str)
88
+ end
89
+ end
90
+ end
91
+ rescue LoadError
92
+ def self.conv(to, from, str) # :nodoc:
93
+ warn "Iconv was not found." if $DEBUG
94
+ str
95
+ end
96
+ end
97
+ end
98
+ def self.iconv(to, from, str)
99
+ conv(to, from, str).split(//)
100
+ end
101
+ end
102
+ end
103
+
104
+ if __FILE__ == $0
105
+ puts Iconv.iconv("EUC-JP", "UTF-8", "ほげ").join
106
+ begin
107
+ puts Iconv.iconv("EUC-JP", "EUC-JP", "ほげ").join
108
+ rescue Iconv::Failure
109
+ puts $!
110
+ puts $!.class
111
+ end
112
+ end
@@ -0,0 +1,84 @@
1
+ =begin
2
+ string.rb - Extension for String.
3
+
4
+ Copyright (C) 2005-2009 Masao Mutoh
5
+
6
+ You may redistribute it and/or modify it under the same
7
+ license terms as Ruby.
8
+ =end
9
+
10
+ # Extension for String class. This feature is included in Ruby 1.9 or later but not occur TypeError.
11
+ #
12
+ # String#% method which accept "named argument". The translator can know
13
+ # the meaning of the msgids using "named argument" instead of %s/%d style.
14
+ class String
15
+
16
+ unless instance_methods.find {|m| m.to_s == 'bytesize'}
17
+ # For older ruby (such as ruby-1.8.5)
18
+ alias :bytesize :size
19
+ end
20
+
21
+ alias :_old_format_m :% # :nodoc:
22
+
23
+ PERCENT_MATCH_RE = Regexp.union(
24
+ /%%/,
25
+ /%\{(.+?)\}/,
26
+ /%<(.+?)>(.*?\d*\.?\d*[bBdiouxXeEfgGcps])/
27
+ )
28
+
29
+ # call-seq:
30
+ # %(arg)
31
+ # %(hash)
32
+ #
33
+ # Format - Uses str as a format specification, and returns the result of applying it to arg.
34
+ # If the format specification contains more than one substitution, then arg must be
35
+ # an Array containing the values to be substituted. See Kernel::sprintf for details of the
36
+ # format string. This is the default behavior of the String class.
37
+ # * arg: an Array or other class except Hash.
38
+ # * Returns: formatted String
39
+ #
40
+ # (e.g.) "%s, %s" % ["Masao", "Mutoh"]
41
+ #
42
+ # Also you can use a Hash as the "named argument". This is recommanded way for Ruby-GetText
43
+ # because the translators can understand the meanings of the msgids easily.
44
+ # * hash: {:key1 => value1, :key2 => value2, ... }
45
+ # * Returns: formatted String
46
+ #
47
+ # (e.g.)
48
+ # For strings.
49
+ # "%{firstname}, %{familyname}" % {:firstname => "Masao", :familyname => "Mutoh"}
50
+ #
51
+ # With field type to specify format such as d(decimal), f(float),...
52
+ # "%<age>d, %<weight>.1f" % {:age => 10, :weight => 43.4}
53
+ def %(args)
54
+ if args.kind_of?(Hash)
55
+ ret = dup
56
+ ret.gsub!(PERCENT_MATCH_RE) {|match|
57
+ if match == '%%'
58
+ '%'
59
+ elsif $1
60
+ key = $1.to_sym
61
+ args.has_key?(key) ? args[key] : match
62
+ elsif $2
63
+ key = $2.to_sym
64
+ args.has_key?(key) ? sprintf("%#{$3}", args[key]) : match
65
+ end
66
+ }
67
+ ret
68
+ else
69
+ ret = gsub(/%([{<])/, '%%\1')
70
+ begin
71
+ ret._old_format_m(args)
72
+ rescue ArgumentError => e
73
+ if $DEBUG
74
+ $stderr.puts " The string:#{ret}"
75
+ $stderr.puts " args:#{args.inspect}"
76
+ puts e.backtrace
77
+ else
78
+ raise ArgumentError, e.message
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
84
+
@@ -0,0 +1,123 @@
1
+ =begin
2
+ locale_path.rb - GetText::LocalePath
3
+
4
+ Copyright (C) 2001-2009 Masao Mutoh
5
+
6
+ You may redistribute it and/or modify it under the same
7
+ license terms as Ruby.
8
+
9
+ =end
10
+
11
+ require 'rbconfig'
12
+ require 'gettext/core_ext/string'
13
+
14
+ module GetText
15
+ # Treats locale-path for mo-files.
16
+ class LocalePath
17
+ include Locale::Util::Memoizable
18
+
19
+ # The default locale paths.
20
+ CONFIG_PREFIX = Config::CONFIG['prefix'].gsub(/\/local/, "")
21
+ DEFAULT_RULES = [
22
+ "./locale/%{lang}/LC_MESSAGES/%{name}.mo",
23
+ "./locale/%{lang}/%{name}.mo",
24
+ "#{Config::CONFIG['datadir']}/locale/%{lang}/LC_MESSAGES/%{name}.mo",
25
+ "#{Config::CONFIG['datadir'].gsub(/\/local/, "")}/locale/%{lang}/LC_MESSAGES/%{name}.mo",
26
+ "#{CONFIG_PREFIX}/share/locale/%{lang}/LC_MESSAGES/%{name}.mo",
27
+ "#{CONFIG_PREFIX}/local/share/locale/%{lang}/LC_MESSAGES/%{name}.mo"
28
+ ].uniq
29
+
30
+ class << self
31
+ include Locale::Util::Memoizable
32
+
33
+ # Add default locale path. Usually you should use GetText.add_default_locale_path instead.
34
+ # * path: a new locale path. (e.g.) "/usr/share/locale/%{lang}/LC_MESSAGES/%{name}.mo"
35
+ # ('locale' => "ja_JP", 'name' => "textdomain")
36
+ # * Returns: the new DEFAULT_LOCALE_PATHS
37
+ def add_default_rule(path)
38
+ DEFAULT_RULES.unshift(path)
39
+ end
40
+
41
+ # Returns path rules as an Array.
42
+ # (e.g.) ["/usr/share/locale/%{lang}/LC_MESSAGES/%{name}.mo", ...]
43
+ def default_path_rules
44
+ default_path_rules = []
45
+
46
+ if ENV["GETTEXT_PATH"]
47
+ ENV["GETTEXT_PATH"].split(/,/).each {|i|
48
+ default_path_rules = ["#{i}/%{lang}/LC_MESSAGES/%{name}.mo", "#{i}/%{lang}/%{name}.mo"]
49
+ }
50
+ end
51
+
52
+ default_path_rules += DEFAULT_RULES
53
+
54
+ load_path = $LOAD_PATH
55
+ if defined? ::Gem
56
+ load_path += Gem.all_load_paths
57
+ end
58
+ load_path.map!{|v| v.match(/(.*?)(\/lib)*?$/); $1}
59
+ load_path.each {|path|
60
+ default_path_rules += [
61
+ "#{path}/data/locale/%{lang}/LC_MESSAGES/%{name}.mo",
62
+ "#{path}/data/locale/%{lang}/%{name}.mo",
63
+ "#{path}/locale/%{lang}/%{name}.mo"]
64
+ }
65
+ # paths existed only.
66
+ default_path_rules = default_path_rules.select{|path|
67
+ Dir.glob(path % {:lang => "*", :name => "*"}).size > 0}.uniq
68
+ default_path_rules
69
+ end
70
+ memoize_dup :default_path_rules
71
+ end
72
+
73
+ attr_reader :locale_paths, :supported_locales
74
+
75
+ # Creates a new GetText::TextDomain.
76
+ # * name: the textdomain name.
77
+ # * topdir: the locale path ("%{topdir}/%{lang}/LC_MESSAGES/%{name}.mo") or nil.
78
+ def initialize(name, topdir = nil)
79
+ @name = name
80
+
81
+ if topdir
82
+ path_rules = ["#{topdir}/%{lang}/LC_MESSAGES/%{name}.mo", "#{topdir}/%{lang}/%{name}.mo"]
83
+ else
84
+ path_rules = self.class.default_path_rules
85
+
86
+ end
87
+
88
+ @locale_paths = {}
89
+ path_rules.each do |rule|
90
+ this_path_rules = rule % {:lang => "([^\/]+)", :name => name}
91
+ Dir.glob(rule %{:lang => "*", :name => name}).each do |path|
92
+ if /#{this_path_rules}/ =~ path
93
+ @locale_paths[$1] = path unless @locale_paths[$1]
94
+ end
95
+ end
96
+ end
97
+ @supported_locales = @locale_paths.keys.sort
98
+ end
99
+
100
+ # Gets the current path.
101
+ # * lang: a Locale::Tag.
102
+ def current_path(lang)
103
+ lang_candidates = lang.to_posix.candidates
104
+ search_files = []
105
+
106
+ lang_candidates.each do |tag|
107
+ path = @locale_paths[tag.to_s]
108
+ warn "GetText::TextDomain#load_mo: mo-file is #{path}" if $DEBUG
109
+ return path if path
110
+ end
111
+
112
+ if $DEBUG
113
+ warn "MO file is not found in"
114
+ @locale_paths.each do |path|
115
+ warn " #{path[1]}"
116
+ end
117
+ end
118
+ nil
119
+ end
120
+ memoize :current_path
121
+
122
+ end
123
+ end
@@ -0,0 +1,330 @@
1
+ =begin
2
+ mofile.rb - A simple class for operating GNU MO file.
3
+
4
+ Copyright (C) 2003-2009 Masao Mutoh
5
+ Copyright (C) 2002 Masahiro Sakai, Masao Mutoh
6
+ Copyright (C) 2001 Masahiro Sakai
7
+
8
+ Masahiro Sakai <s01397ms at sfc.keio.ac.jp>
9
+ Masao Mutoh <mutomasa at gmail.com>
10
+
11
+ You can redistribute this file and/or modify it under the same term
12
+ of Ruby. License of Ruby is included with Ruby distribution in
13
+ the file "README".
14
+
15
+ =end
16
+
17
+ require 'gettext/core_ext/iconv'
18
+ require 'stringio'
19
+
20
+ module GetText
21
+ class MOFile < Hash
22
+ class InvalidFormat < RuntimeError; end;
23
+
24
+ attr_reader :filename
25
+
26
+ Header = Struct.new(:magic,
27
+ :revision,
28
+ :nstrings,
29
+ :orig_table_offset,
30
+ :translated_table_offset,
31
+ :hash_table_size,
32
+ :hash_table_offset)
33
+
34
+ # The following are only used in .mo files
35
+ # with minor revision >= 1.
36
+ class HeaderRev1 < Header
37
+ attr_accessor :n_sysdep_segments,
38
+ :sysdep_segments_offset,
39
+ :n_sysdep_strings,
40
+ :orig_sysdep_tab_offset,
41
+ :trans_sysdep_tab_offset
42
+ end
43
+
44
+ MAGIC_BIG_ENDIAN = "\x95\x04\x12\xde"
45
+ MAGIC_LITTLE_ENDIAN = "\xde\x12\x04\x95"
46
+
47
+ def self.open(arg = nil, output_charset = nil)
48
+ result = self.new(output_charset)
49
+ result.load(arg)
50
+ end
51
+
52
+ def initialize(output_charset = nil)
53
+ @filename = nil
54
+ @last_modified = nil
55
+ @little_endian = true
56
+ @output_charset = output_charset
57
+ @plural_proc = nil
58
+ super()
59
+ end
60
+
61
+ def update!
62
+ if FileTest.exist?(@filename)
63
+ st = File.stat(@filename)
64
+ load(@filename) unless (@last_modified == [st.ctime, st.mtime])
65
+ else
66
+ warn "#{@filename} was lost." if $DEBUG
67
+ clear
68
+ end
69
+ self
70
+ end
71
+
72
+ def load(arg)
73
+ if arg.kind_of? String
74
+ begin
75
+ st = File.stat(arg)
76
+ @last_modified = [st.ctime, st.mtime]
77
+ rescue Exception
78
+ end
79
+ load_from_file(arg)
80
+ else
81
+ load_from_stream(arg)
82
+ end
83
+ @filename = arg
84
+ self
85
+ end
86
+
87
+ def load_from_stream(io)
88
+ magic = io.read(4)
89
+ case magic
90
+ when MAGIC_BIG_ENDIAN
91
+ @little_endian = false
92
+ when MAGIC_LITTLE_ENDIAN
93
+ @little_endian = true
94
+ else
95
+ raise InvalidFormat.new(sprintf("Unknown signature %s", magic.dump))
96
+ end
97
+
98
+ endian_type6 = @little_endian ? 'V6' : 'N6'
99
+ endian_type_astr = @little_endian ? 'V*' : 'N*'
100
+
101
+ header = HeaderRev1.new(magic, *(io.read(4 * 6).unpack(endian_type6)))
102
+
103
+ if header.revision == 1
104
+ # FIXME: It doesn't support sysdep correctly.
105
+ header.n_sysdep_segments = io.read(4).unpack(endian_type6)
106
+ header.sysdep_segments_offset = io.read(4).unpack(endian_type6)
107
+ header.n_sysdep_strings = io.read(4).unpack(endian_type6)
108
+ header.orig_sysdep_tab_offset = io.read(4).unpack(endian_type6)
109
+ header.trans_sysdep_tab_offset = io.read(4).unpack(endian_type6)
110
+ elsif header.revision > 1
111
+ raise InvalidFormat.new(sprintf("file format revision %d isn't supported", header.revision))
112
+ end
113
+ io.pos = header.orig_table_offset
114
+ orig_table_data = io.read((4 * 2) * header.nstrings).unpack(endian_type_astr)
115
+
116
+ io.pos = header.translated_table_offset
117
+ trans_table_data = io.read((4 * 2) * header.nstrings).unpack(endian_type_astr)
118
+
119
+ original_strings = Array.new(header.nstrings)
120
+ for i in 0...header.nstrings
121
+ io.pos = orig_table_data[i * 2 + 1]
122
+ original_strings[i] = io.read(orig_table_data[i * 2 + 0])
123
+ end
124
+
125
+ clear
126
+ for i in 0...header.nstrings
127
+ io.pos = trans_table_data[i * 2 + 1]
128
+ str = io.read(trans_table_data[i * 2 + 0])
129
+
130
+ if (! original_strings[i]) || original_strings[i] == ""
131
+ if str
132
+ @charset = nil
133
+ @nplurals = nil
134
+ @plural = nil
135
+ str.each_line{|line|
136
+ if /^Content-Type:/i =~ line and /charset=((?:\w|-)+)/i =~ line
137
+ @charset = $1
138
+ elsif /^Plural-Forms:\s*nplurals\s*\=\s*(\d*);\s*plural\s*\=\s*([^;]*)\n?/ =~ line
139
+ @nplurals = $1
140
+ @plural = $2
141
+ end
142
+ break if @charset and @nplurals
143
+ }
144
+ @nplurals = "1" unless @nplurals
145
+ @plural = "0" unless @plural
146
+ end
147
+ else
148
+ if @output_charset
149
+ begin
150
+ str = Iconv.conv(@output_charset, @charset, str) if @charset
151
+ rescue Iconv::Failure
152
+ if $DEBUG
153
+ warn "@charset = ", @charset
154
+ warn"@output_charset = ", @output_charset
155
+ warn "msgid = ", original_strings[i]
156
+ warn "msgstr = ", str
157
+ end
158
+ end
159
+ end
160
+ end
161
+ self[original_strings[i]] = str.freeze
162
+ end
163
+ self
164
+ end
165
+
166
+ def prime?(number)
167
+ ('1' * number) !~ /^1?$|^(11+?)\1+$/
168
+ end
169
+
170
+ begin
171
+ require 'prime'
172
+ def next_prime(seed)
173
+ Prime.instance.find{|x| x > seed }
174
+ end
175
+ rescue LoadError
176
+ def next_prime(seed)
177
+ require 'mathn'
178
+ prime = Prime.new
179
+ while current = prime.succ
180
+ return current if current > seed
181
+ end
182
+ end
183
+ end
184
+
185
+ HASHWORDBITS = 32
186
+ # From gettext-0.12.1/gettext-runtime/intl/hash-string.h
187
+ # Defines the so called `hashpjw' function by P.J. Weinberger
188
+ # [see Aho/Sethi/Ullman, COMPILERS: Principles, Techniques and Tools,
189
+ # 1986, 1987 Bell Telephone Laboratories, Inc.]
190
+ def hash_string(str)
191
+ hval = 0
192
+ i = 0
193
+ str.each_byte do |b|
194
+ break if b == '\0'
195
+ hval <<= 4
196
+ hval += b.to_i
197
+ g = hval & (0xf << (HASHWORDBITS - 4))
198
+ if (g != 0)
199
+ hval ^= g >> (HASHWORDBITS - 8)
200
+ hval ^= g
201
+ end
202
+ end
203
+ hval
204
+ end
205
+
206
+ #Save data as little endian format.
207
+ def save_to_stream(io)
208
+ header_size = 4 * 7
209
+ table_size = 4 * 2 * size
210
+
211
+ hash_table_size = next_prime((size * 4) / 3)
212
+ hash_table_size = 3 if hash_table_size <= 2
213
+ header = Header.new(
214
+ MAGIC_LITTLE_ENDIAN, # magic
215
+ 0, # revision
216
+ size, # nstrings
217
+ header_size, # orig_table_offset
218
+ header_size + table_size, # translated_table_offset
219
+ hash_table_size, # hash_table_size
220
+ header_size + table_size * 2 # hash_table_offset
221
+ )
222
+ io.write(header.to_a.pack('a4V*'))
223
+
224
+ ary = to_a
225
+ ary.sort!{|a, b| a[0] <=> b[0]} # sort by original string
226
+
227
+ pos = header.hash_table_size * 4 + header.hash_table_offset
228
+
229
+ orig_table_data = Array.new()
230
+ ary.each{|item, _|
231
+ orig_table_data.push(item.bytesize)
232
+ orig_table_data.push(pos)
233
+ pos += item.bytesize + 1 # +1 is <NUL>
234
+ }
235
+ io.write(orig_table_data.pack('V*'))
236
+
237
+ trans_table_data = Array.new()
238
+ ary.each{|_, item|
239
+ trans_table_data.push(item.bytesize)
240
+ trans_table_data.push(pos)
241
+ pos += item.bytesize + 1 # +1 is <NUL>
242
+ }
243
+ io.write(trans_table_data.pack('V*'))
244
+
245
+ hash_tab = Array.new(hash_table_size)
246
+ j = 0
247
+ ary[0...size].each {|key, _|
248
+ hash_val = hash_string(key)
249
+ idx = hash_val % hash_table_size
250
+ if hash_tab[idx] != nil
251
+ incr = 1 + (hash_val % (hash_table_size - 2))
252
+ begin
253
+ if (idx >= hash_table_size - incr)
254
+ idx -= hash_table_size - incr
255
+ else
256
+ idx += incr
257
+ end
258
+ end until (hash_tab[idx] == nil)
259
+ end
260
+ hash_tab[idx] = j + 1
261
+ j += 1
262
+ }
263
+ hash_tab.collect!{|i| i ? i : 0}
264
+
265
+ io.write(hash_tab.pack('V*'))
266
+
267
+ ary.each{|item, _| io.write(item); io.write("\0") }
268
+ ary.each{|_, item| io.write(item); io.write("\0") }
269
+
270
+ self
271
+ end
272
+
273
+ def load_from_file(filename)
274
+ @filename = filename
275
+ begin
276
+ File.open(filename, 'rb'){|f| load_from_stream(f)}
277
+ rescue => e
278
+ e.set_backtrace("File: #{@filename}")
279
+ raise e
280
+ end
281
+ end
282
+
283
+ def save_to_file(filename)
284
+ File.open(filename, 'wb'){|f| save_to_stream(f)}
285
+ end
286
+
287
+ def set_comment(msgid_or_sym, comment)
288
+ #Do nothing
289
+ end
290
+
291
+ def plural_as_proc
292
+ unless @plural_proc
293
+ @plural_proc = Proc.new{|n| eval(@plural)}
294
+ begin
295
+ @plural_proc.call(1)
296
+ rescue
297
+ @plural_proc = Proc.new{|n| 0}
298
+ end
299
+ end
300
+ @plural_proc
301
+ end
302
+
303
+ attr_accessor :little_endian, :path, :last_modified
304
+ attr_reader :charset, :nplurals, :plural
305
+ end
306
+
307
+ end
308
+
309
+ # Test
310
+
311
+ if $0 == __FILE__
312
+ if (ARGV.include? "-h") or (ARGV.include? "--help")
313
+ STDERR.puts("mo.rb [filename.mo ...]")
314
+ exit
315
+ end
316
+
317
+ ARGV.each{ |item|
318
+ mo = GetText::MOFile.open(item)
319
+ puts "------------------------------------------------------------------"
320
+ puts "charset = \"#{mo.charset}\""
321
+ puts "nplurals = \"#{mo.nplurals}\""
322
+ puts "plural = \"#{mo.plural}\""
323
+ puts "------------------------------------------------------------------"
324
+ mo.each do |key, value|
325
+ puts "original message = #{key.inspect}"
326
+ puts "translated message = #{value.inspect}"
327
+ puts "--------------------------------------------------------------------"
328
+ end
329
+ }
330
+ end
@@ -0,0 +1,54 @@
1
+ =begin
2
+ parser/erb.rb - parser for ERB
3
+
4
+ Copyright (C) 2005 Masao Mutoh
5
+
6
+ You may redistribute it and/or modify it under the same
7
+ license terms as Ruby.
8
+
9
+ $Id: erb.rb,v 1.5 2007/08/01 01:39:14 mutoh Exp $
10
+ =end
11
+
12
+ require 'erb'
13
+ require 'gettext/parser/ruby.rb'
14
+
15
+ module GetText
16
+ module ErbParser
17
+ extend self
18
+
19
+ @config = {
20
+ :extnames => ['.rhtml', '.erb','.html','.plain']
21
+ }
22
+
23
+ # Sets some preferences to parse ERB files.
24
+ # * config: a Hash of the config. It can takes some values below:
25
+ # * :extnames: An Array of target files extension. Default is [".rhtml"].
26
+ def init(config)
27
+ config.each{|k, v|
28
+ @config[k] = v
29
+ }
30
+ end
31
+
32
+ def parse(file, targets = []) # :nodoc:
33
+ src = ERB.new(IO.readlines(file).join).src
34
+ # Remove magic comment prepended by erb in Ruby 1.9.
35
+ src.sub!(/\A#.*?coding[:=].*?\n/, '') if src.respond_to?(:encode)
36
+ erb = src.split(/$/)
37
+ RubyParser.parse_lines(file, erb, targets)
38
+ end
39
+
40
+ def target?(file) # :nodoc:
41
+ @config[:extnames].each do |v|
42
+ return true if File.extname(file) == v
43
+ end
44
+ false
45
+ end
46
+ end
47
+ end
48
+
49
+ if __FILE__ == $0
50
+ # ex) ruby glade.rhtml foo.rhtml bar.rhtml
51
+ ARGV.each do |file|
52
+ p GetText::ErbParser.parse(file)
53
+ end
54
+ end