gettext 2.2.1 → 2.3.0

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 (500) hide show
  1. data/COPYING +2 -1
  2. data/README.rdoc +9 -9
  3. data/Rakefile +94 -149
  4. data/bin/rmsgfmt +23 -20
  5. data/bin/rmsginit +29 -0
  6. data/bin/rmsgmerge +22 -20
  7. data/bin/rxgettext +24 -0
  8. data/doc/text/news.md +60 -0
  9. data/gettext.gemspec +7 -4
  10. data/lib/gettext.rb +3 -3
  11. data/lib/gettext/core_ext/string.rb +2 -1
  12. data/lib/gettext/runtime/locale_path.rb +6 -4
  13. data/lib/gettext/runtime/textdomain.rb +14 -8
  14. data/lib/gettext/runtime/textdomain_manager.rb +3 -3
  15. data/lib/gettext/task.rb +203 -0
  16. data/lib/gettext/tools.rb +33 -24
  17. data/lib/gettext/tools/msgfmt.rb +104 -0
  18. data/lib/gettext/tools/msginit.rb +363 -0
  19. data/lib/gettext/tools/msgmerge.rb +510 -0
  20. data/lib/gettext/tools/parser/ruby.rb +12 -17
  21. data/lib/gettext/tools/pomessage.rb +37 -4
  22. data/lib/gettext/tools/poparser.rb +27 -24
  23. data/lib/gettext/tools/xgettext.rb +327 -0
  24. data/lib/gettext/version.rb +2 -2
  25. data/po/bg/rgettext.po +2 -2
  26. data/po/bs/rgettext.po +2 -2
  27. data/po/ca/rgettext.po +2 -2
  28. data/po/cs/rgettext.po +2 -2
  29. data/po/de/gettext.po +668 -0
  30. data/po/de/gettext.po.bak +589 -0
  31. data/po/de/rgettext.po +2 -2
  32. data/po/el/gettext.po +571 -0
  33. data/po/el/rgettext.po +2 -2
  34. data/po/eo/rgettext.po +2 -2
  35. data/po/es/rgettext.po +2 -2
  36. data/po/et/rgettext.po +2 -2
  37. data/po/fr/gettext.po +589 -0
  38. data/po/fr/rgettext.po +2 -2
  39. data/po/gettext.pot +638 -0
  40. data/po/gettext.pot~ +638 -0
  41. data/po/hr/rgettext.po +2 -2
  42. data/po/hu/rgettext.po +2 -2
  43. data/po/it/gettext.po +589 -0
  44. data/po/it/rgettext.po +2 -2
  45. data/po/ja/gettext.po +591 -0
  46. data/po/ja/rgettext.po +112 -69
  47. data/po/ko/rgettext.po +2 -2
  48. data/po/lv/rgettext.po +2 -2
  49. data/po/nb/rgettext.po +2 -2
  50. data/po/nl/rgettext.po +2 -2
  51. data/po/pt_BR/rgettext.po +2 -2
  52. data/po/ru/rgettext.po +2 -2
  53. data/po/sr/rgettext.po +2 -2
  54. data/po/sv/rgettext.po +2 -2
  55. data/po/uk/gettext.po +571 -0
  56. data/po/uk/rgettext.po +2 -2
  57. data/po/vi/rgettext.po +2 -2
  58. data/po/zh/rgettext.po +2 -2
  59. data/po/zh_TW/rgettext.po +2 -2
  60. data/samples/README +2 -4
  61. data/samples/cgi/README +1 -1
  62. data/samples/cgi/cookie.cgi +1 -1
  63. data/samples/cgi/gettext.css +1 -1
  64. data/samples/cgi/helloerb.rhtml +1 -1
  65. data/samples/cgi/hellolib.rb +1 -1
  66. data/samples/cgi/http.rb +2 -2
  67. data/samples/cgi/index.cgi +1 -1
  68. data/samples/cgi/locale/bg/LC_MESSAGES/helloerb1.mo +0 -0
  69. data/samples/cgi/locale/bg/LC_MESSAGES/helloerb2.mo +0 -0
  70. data/samples/cgi/locale/bg/LC_MESSAGES/main.mo +0 -0
  71. data/samples/cgi/locale/bs/LC_MESSAGES/helloerb1.mo +0 -0
  72. data/samples/cgi/locale/bs/LC_MESSAGES/helloerb2.mo +0 -0
  73. data/samples/cgi/locale/bs/LC_MESSAGES/main.mo +0 -0
  74. data/samples/cgi/locale/ca/LC_MESSAGES/helloerb1.mo +0 -0
  75. data/samples/cgi/locale/ca/LC_MESSAGES/helloerb2.mo +0 -0
  76. data/samples/cgi/locale/ca/LC_MESSAGES/main.mo +0 -0
  77. data/samples/cgi/locale/cs/LC_MESSAGES/helloerb1.mo +0 -0
  78. data/samples/cgi/locale/cs/LC_MESSAGES/helloerb2.mo +0 -0
  79. data/samples/cgi/locale/cs/LC_MESSAGES/main.mo +0 -0
  80. data/samples/cgi/locale/de/LC_MESSAGES/helloerb1.mo +0 -0
  81. data/samples/cgi/locale/de/LC_MESSAGES/helloerb2.mo +0 -0
  82. data/samples/cgi/locale/de/LC_MESSAGES/main.mo +0 -0
  83. data/samples/cgi/locale/el/LC_MESSAGES/helloerb1.mo +0 -0
  84. data/samples/cgi/locale/el/LC_MESSAGES/helloerb2.mo +0 -0
  85. data/samples/cgi/locale/el/LC_MESSAGES/main.mo +0 -0
  86. data/samples/cgi/locale/eo/LC_MESSAGES/helloerb1.mo +0 -0
  87. data/samples/cgi/locale/eo/LC_MESSAGES/helloerb2.mo +0 -0
  88. data/samples/cgi/locale/eo/LC_MESSAGES/main.mo +0 -0
  89. data/samples/cgi/locale/es/LC_MESSAGES/helloerb1.mo +0 -0
  90. data/samples/cgi/locale/es/LC_MESSAGES/helloerb2.mo +0 -0
  91. data/samples/cgi/locale/es/LC_MESSAGES/main.mo +0 -0
  92. data/samples/cgi/locale/fr/LC_MESSAGES/helloerb1.mo +0 -0
  93. data/samples/cgi/locale/fr/LC_MESSAGES/helloerb2.mo +0 -0
  94. data/samples/cgi/locale/fr/LC_MESSAGES/main.mo +0 -0
  95. data/samples/cgi/locale/hr/LC_MESSAGES/helloerb1.mo +0 -0
  96. data/samples/cgi/locale/hr/LC_MESSAGES/helloerb2.mo +0 -0
  97. data/samples/cgi/locale/hr/LC_MESSAGES/main.mo +0 -0
  98. data/samples/cgi/locale/hu/LC_MESSAGES/helloerb1.mo +0 -0
  99. data/samples/cgi/locale/hu/LC_MESSAGES/helloerb2.mo +0 -0
  100. data/samples/cgi/locale/hu/LC_MESSAGES/main.mo +0 -0
  101. data/samples/cgi/locale/it/LC_MESSAGES/helloerb1.mo +0 -0
  102. data/samples/cgi/locale/it/LC_MESSAGES/helloerb2.mo +0 -0
  103. data/samples/cgi/locale/it/LC_MESSAGES/main.mo +0 -0
  104. data/samples/cgi/locale/ja/LC_MESSAGES/helloerb1.mo +0 -0
  105. data/samples/cgi/locale/ja/LC_MESSAGES/helloerb2.mo +0 -0
  106. data/samples/cgi/locale/ja/LC_MESSAGES/main.mo +0 -0
  107. data/samples/cgi/locale/ko/LC_MESSAGES/helloerb1.mo +0 -0
  108. data/samples/cgi/locale/ko/LC_MESSAGES/helloerb2.mo +0 -0
  109. data/samples/cgi/locale/ko/LC_MESSAGES/main.mo +0 -0
  110. data/samples/cgi/locale/lv/LC_MESSAGES/helloerb1.mo +0 -0
  111. data/samples/cgi/locale/lv/LC_MESSAGES/helloerb2.mo +0 -0
  112. data/samples/cgi/locale/lv/LC_MESSAGES/main.mo +0 -0
  113. data/samples/cgi/locale/nb/LC_MESSAGES/helloerb1.mo +0 -0
  114. data/samples/cgi/locale/nb/LC_MESSAGES/helloerb2.mo +0 -0
  115. data/samples/cgi/locale/nb/LC_MESSAGES/main.mo +0 -0
  116. data/samples/cgi/locale/nl/LC_MESSAGES/helloerb1.mo +0 -0
  117. data/samples/cgi/locale/nl/LC_MESSAGES/helloerb2.mo +0 -0
  118. data/samples/cgi/locale/nl/LC_MESSAGES/main.mo +0 -0
  119. data/samples/cgi/locale/pt_BR/LC_MESSAGES/helloerb1.mo +0 -0
  120. data/samples/cgi/locale/pt_BR/LC_MESSAGES/helloerb2.mo +0 -0
  121. data/samples/cgi/locale/pt_BR/LC_MESSAGES/main.mo +0 -0
  122. data/samples/cgi/locale/ru/LC_MESSAGES/helloerb1.mo +0 -0
  123. data/samples/cgi/locale/ru/LC_MESSAGES/helloerb2.mo +0 -0
  124. data/samples/cgi/locale/ru/LC_MESSAGES/main.mo +0 -0
  125. data/samples/cgi/locale/sr/LC_MESSAGES/helloerb1.mo +0 -0
  126. data/samples/cgi/locale/sr/LC_MESSAGES/helloerb2.mo +0 -0
  127. data/samples/cgi/locale/sr/LC_MESSAGES/main.mo +0 -0
  128. data/samples/cgi/locale/uk/LC_MESSAGES/helloerb1.mo +0 -0
  129. data/samples/cgi/locale/uk/LC_MESSAGES/helloerb2.mo +0 -0
  130. data/samples/cgi/locale/uk/LC_MESSAGES/main.mo +0 -0
  131. data/samples/cgi/locale/vi/LC_MESSAGES/helloerb1.mo +0 -0
  132. data/samples/cgi/locale/vi/LC_MESSAGES/helloerb2.mo +0 -0
  133. data/samples/cgi/locale/vi/LC_MESSAGES/main.mo +0 -0
  134. data/samples/cgi/locale/zh/LC_MESSAGES/helloerb1.mo +0 -0
  135. data/samples/cgi/locale/zh/LC_MESSAGES/helloerb2.mo +0 -0
  136. data/samples/cgi/locale/zh/LC_MESSAGES/main.mo +0 -0
  137. data/samples/cgi/locale/zh_TW/LC_MESSAGES/helloerb1.mo +0 -0
  138. data/samples/cgi/locale/zh_TW/LC_MESSAGES/helloerb2.mo +0 -0
  139. data/samples/cgi/locale/zh_TW/LC_MESSAGES/main.mo +0 -0
  140. data/samples/cgi/other.rhtml +1 -1
  141. data/samples/cgi/po/bg/helloerb1.po +4 -4
  142. data/samples/cgi/po/bg/helloerb2.po +4 -4
  143. data/samples/cgi/po/bg/hellolib.po +2 -2
  144. data/samples/cgi/po/bg/main.po +4 -4
  145. data/samples/cgi/po/bs/helloerb1.po +3 -3
  146. data/samples/cgi/po/bs/helloerb2.po +3 -3
  147. data/samples/cgi/po/bs/hellolib.po +2 -2
  148. data/samples/cgi/po/bs/main.po +3 -3
  149. data/samples/cgi/po/ca/helloerb1.po +4 -4
  150. data/samples/cgi/po/ca/helloerb2.po +4 -4
  151. data/samples/cgi/po/ca/hellolib.po +2 -2
  152. data/samples/cgi/po/ca/main.po +4 -4
  153. data/samples/cgi/po/cs/helloerb1.po +4 -4
  154. data/samples/cgi/po/cs/helloerb2.po +4 -4
  155. data/samples/cgi/po/cs/hellolib.po +2 -2
  156. data/samples/cgi/po/cs/main.po +4 -4
  157. data/samples/cgi/po/de/helloerb1.po +3 -3
  158. data/samples/cgi/po/de/helloerb2.po +3 -3
  159. data/samples/cgi/po/de/hellolib.po +2 -2
  160. data/samples/cgi/po/de/main.po +3 -3
  161. data/samples/cgi/po/el/helloerb1.po +3 -3
  162. data/samples/cgi/po/el/helloerb2.po +3 -3
  163. data/samples/cgi/po/el/hellolib.po +2 -2
  164. data/samples/cgi/po/el/main.po +3 -3
  165. data/samples/cgi/po/eo/helloerb1.po +3 -3
  166. data/samples/cgi/po/eo/helloerb2.po +3 -3
  167. data/samples/cgi/po/eo/hellolib.po +2 -2
  168. data/samples/cgi/po/eo/main.po +3 -3
  169. data/samples/cgi/po/es/helloerb1.po +4 -4
  170. data/samples/cgi/po/es/helloerb2.po +4 -4
  171. data/samples/cgi/po/es/hellolib.po +2 -2
  172. data/samples/cgi/po/es/main.po +4 -4
  173. data/samples/cgi/po/fr/helloerb1.po +4 -4
  174. data/samples/cgi/po/fr/helloerb2.po +4 -4
  175. data/samples/cgi/po/fr/hellolib.po +2 -2
  176. data/samples/cgi/po/fr/main.po +4 -4
  177. data/samples/cgi/po/hr/helloerb1.po +3 -3
  178. data/samples/cgi/po/hr/helloerb2.po +3 -3
  179. data/samples/cgi/po/hr/hellolib.po +2 -2
  180. data/samples/cgi/po/hr/main.po +3 -3
  181. data/samples/cgi/po/hu/helloerb1.po +4 -4
  182. data/samples/cgi/po/hu/helloerb2.po +4 -4
  183. data/samples/cgi/po/hu/hellolib.po +2 -2
  184. data/samples/cgi/po/hu/main.po +4 -4
  185. data/samples/cgi/po/it/helloerb1.po +3 -3
  186. data/samples/cgi/po/it/helloerb2.po +3 -3
  187. data/samples/cgi/po/it/hellolib.po +2 -2
  188. data/samples/cgi/po/it/main.po +3 -3
  189. data/samples/cgi/po/ja/helloerb1.po +4 -4
  190. data/samples/cgi/po/ja/helloerb2.po +4 -4
  191. data/samples/cgi/po/ja/hellolib.po +2 -2
  192. data/samples/cgi/po/ja/main.po +3 -3
  193. data/samples/cgi/po/ko/helloerb1.po +3 -3
  194. data/samples/cgi/po/ko/helloerb2.po +3 -3
  195. data/samples/cgi/po/ko/hellolib.po +2 -2
  196. data/samples/cgi/po/ko/main.po +3 -3
  197. data/samples/cgi/po/lv/helloerb1.po +4 -4
  198. data/samples/cgi/po/lv/helloerb2.po +4 -4
  199. data/samples/cgi/po/lv/hellolib.po +2 -2
  200. data/samples/cgi/po/lv/main.po +4 -4
  201. data/samples/cgi/po/nb/helloerb1.po +3 -3
  202. data/samples/cgi/po/nb/helloerb2.po +3 -3
  203. data/samples/cgi/po/nb/hellolib.po +2 -2
  204. data/samples/cgi/po/nb/main.po +3 -3
  205. data/samples/cgi/po/nl/helloerb1.po +4 -4
  206. data/samples/cgi/po/nl/helloerb2.po +4 -4
  207. data/samples/cgi/po/nl/hellolib.po +2 -2
  208. data/samples/cgi/po/nl/main.po +4 -4
  209. data/samples/cgi/po/pt_BR/helloerb1.po +4 -4
  210. data/samples/cgi/po/pt_BR/helloerb2.po +4 -4
  211. data/samples/cgi/po/pt_BR/hellolib.po +2 -2
  212. data/samples/cgi/po/pt_BR/main.po +4 -4
  213. data/samples/cgi/po/ru/helloerb1.po +4 -4
  214. data/samples/cgi/po/ru/helloerb2.po +4 -4
  215. data/samples/cgi/po/ru/hellolib.po +2 -2
  216. data/samples/cgi/po/ru/main.po +4 -4
  217. data/samples/cgi/po/sr/helloerb1.po +4 -4
  218. data/samples/cgi/po/sr/helloerb2.po +4 -4
  219. data/samples/cgi/po/sr/hellolib.po +2 -2
  220. data/samples/cgi/po/sr/main.po +4 -4
  221. data/samples/cgi/po/uk/helloerb1.po +4 -4
  222. data/samples/cgi/po/uk/helloerb2.po +4 -4
  223. data/samples/cgi/po/uk/hellolib.po +2 -2
  224. data/samples/cgi/po/uk/main.po +4 -4
  225. data/samples/cgi/po/vi/helloerb1.po +3 -3
  226. data/samples/cgi/po/vi/helloerb2.po +3 -3
  227. data/samples/cgi/po/vi/hellolib.po +2 -2
  228. data/samples/cgi/po/vi/main.po +3 -3
  229. data/samples/cgi/po/zh/helloerb1.po +4 -4
  230. data/samples/cgi/po/zh/helloerb2.po +4 -4
  231. data/samples/cgi/po/zh/hellolib.po +2 -2
  232. data/samples/cgi/po/zh/main.po +4 -4
  233. data/samples/cgi/po/zh_TW/helloerb1.po +4 -4
  234. data/samples/cgi/po/zh_TW/helloerb2.po +4 -4
  235. data/samples/cgi/po/zh_TW/hellolib.po +2 -2
  236. data/samples/cgi/po/zh_TW/main.po +4 -4
  237. data/samples/hello.rb +1 -1
  238. data/samples/hello2.rb +1 -1
  239. data/samples/hello_glade2.rb +1 -1
  240. data/samples/hello_gtk2.rb +2 -2
  241. data/samples/hello_noop.rb +1 -1
  242. data/samples/hello_plural.rb +1 -1
  243. data/samples/hello_tk.rb +1 -1
  244. data/samples/locale/bg/LC_MESSAGES/hello_gtk2.mo +0 -0
  245. data/samples/locale/bs/LC_MESSAGES/hello_gtk2.mo +0 -0
  246. data/samples/locale/ca/LC_MESSAGES/hello_gtk2.mo +0 -0
  247. data/samples/locale/cs/LC_MESSAGES/hello_gtk2.mo +0 -0
  248. data/samples/locale/de/LC_MESSAGES/hello_gtk2.mo +0 -0
  249. data/samples/locale/el/LC_MESSAGES/hello_gtk2.mo +0 -0
  250. data/samples/locale/eo/LC_MESSAGES/hello_gtk2.mo +0 -0
  251. data/samples/locale/es/LC_MESSAGES/hello_gtk2.mo +0 -0
  252. data/samples/locale/fr/LC_MESSAGES/hello_gtk2.mo +0 -0
  253. data/samples/locale/hr/LC_MESSAGES/hello_gtk2.mo +0 -0
  254. data/samples/locale/hu/LC_MESSAGES/hello_gtk2.mo +0 -0
  255. data/samples/locale/it/LC_MESSAGES/hello_gtk2.mo +0 -0
  256. data/samples/locale/ja/LC_MESSAGES/hello_gtk2.mo +0 -0
  257. data/samples/locale/ko/LC_MESSAGES/hello_gtk2.mo +0 -0
  258. data/samples/locale/lv/LC_MESSAGES/hello_gtk2.mo +0 -0
  259. data/samples/locale/nb/LC_MESSAGES/hello_gtk2.mo +0 -0
  260. data/samples/locale/nl/LC_MESSAGES/hello_gtk2.mo +0 -0
  261. data/samples/locale/pt_BR/LC_MESSAGES/hello_gtk2.mo +0 -0
  262. data/samples/locale/ru/LC_MESSAGES/hello_gtk2.mo +0 -0
  263. data/samples/locale/sr/LC_MESSAGES/hello_gtk2.mo +0 -0
  264. data/samples/locale/sv/LC_MESSAGES/hello_gtk2.mo +0 -0
  265. data/samples/locale/uk/LC_MESSAGES/hello_gtk2.mo +0 -0
  266. data/samples/locale/vi/LC_MESSAGES/hello_gtk2.mo +0 -0
  267. data/samples/locale/zh/LC_MESSAGES/hello_gtk2.mo +0 -0
  268. data/samples/locale/zh_TW/LC_MESSAGES/hello_gtk2.mo +0 -0
  269. data/samples/po/bg/hello.po +2 -2
  270. data/samples/po/bg/hello2.po +1 -1
  271. data/samples/po/bg/hello_glade2.po +1 -1
  272. data/samples/po/bg/{hello_gtk.po → hello_gtk2.po} +1 -1
  273. data/samples/po/bg/hello_noop.po +1 -1
  274. data/samples/po/bg/hello_plural.po +1 -1
  275. data/samples/po/bg/hello_tk.po +1 -1
  276. data/samples/po/bs/hello.po +2 -2
  277. data/samples/po/bs/hello2.po +1 -1
  278. data/samples/po/bs/hello_glade2.po +1 -1
  279. data/samples/po/bs/{hello_gtk.po → hello_gtk2.po} +1 -1
  280. data/samples/po/bs/hello_noop.po +1 -1
  281. data/samples/po/bs/hello_plural.po +1 -1
  282. data/samples/po/bs/hello_tk.po +1 -1
  283. data/samples/po/ca/hello.po +2 -2
  284. data/samples/po/ca/hello2.po +1 -1
  285. data/samples/po/ca/hello_glade2.po +1 -1
  286. data/samples/po/ca/{hello_gtk.po → hello_gtk2.po} +1 -1
  287. data/samples/po/ca/hello_noop.po +1 -1
  288. data/samples/po/ca/hello_plural.po +1 -1
  289. data/samples/po/ca/hello_tk.po +1 -1
  290. data/samples/po/cs/hello.po +1 -1
  291. data/samples/po/cs/hello_glade2.po +1 -1
  292. data/samples/po/cs/{hello_gtk.po → hello_gtk2.po} +0 -0
  293. data/samples/po/cs/hello_plural.po +1 -1
  294. data/samples/po/de/hello.po +1 -1
  295. data/samples/po/de/{hello_gtk.po → hello_gtk2.po} +0 -0
  296. data/samples/po/de/hello_plural.po +1 -1
  297. data/samples/po/el/hello.po +2 -2
  298. data/samples/po/el/hello2.po +1 -1
  299. data/samples/po/el/hello_glade2.po +1 -1
  300. data/samples/po/el/{hello_gtk.po → hello_gtk2.po} +1 -1
  301. data/samples/po/el/hello_noop.po +1 -1
  302. data/samples/po/el/hello_plural.po +1 -1
  303. data/samples/po/el/hello_tk.po +1 -1
  304. data/samples/po/eo/hello.po +2 -2
  305. data/samples/po/eo/hello2.po +1 -1
  306. data/samples/po/eo/hello_glade2.po +1 -1
  307. data/samples/po/eo/{hello_gtk.po → hello_gtk2.po} +1 -1
  308. data/samples/po/eo/hello_noop.po +1 -1
  309. data/samples/po/eo/hello_plural.po +1 -1
  310. data/samples/po/eo/hello_tk.po +1 -1
  311. data/samples/po/es/{hello_gtk.po → hello_gtk2.po} +0 -0
  312. data/samples/po/fr/{hello_gtk.po → hello_gtk2.po} +0 -0
  313. data/samples/po/hello.pot +13 -13
  314. data/samples/po/hello2.pot +17 -17
  315. data/samples/po/hello_glade2.pot +12 -13
  316. data/{test/pot/backslash.pot → samples/po/hello_gtk2.pot} +8 -6
  317. data/samples/po/hello_noop.pot +13 -13
  318. data/samples/po/hello_plural.pot +14 -15
  319. data/samples/po/hello_tk.pot +9 -10
  320. data/samples/po/hr/hello.po +2 -2
  321. data/samples/po/hr/hello2.po +1 -1
  322. data/samples/po/hr/hello_glade2.po +1 -1
  323. data/samples/po/hr/{hello_gtk.po → hello_gtk2.po} +1 -1
  324. data/samples/po/hr/hello_noop.po +1 -1
  325. data/samples/po/hr/hello_plural.po +1 -1
  326. data/samples/po/hr/hello_tk.po +1 -1
  327. data/samples/po/hu/hello.po +2 -2
  328. data/samples/po/hu/hello2.po +1 -1
  329. data/samples/po/hu/hello_glade2.po +1 -1
  330. data/samples/po/hu/{hello_gtk.po → hello_gtk2.po} +1 -1
  331. data/samples/po/hu/hello_noop.po +1 -1
  332. data/samples/po/hu/hello_plural.po +1 -1
  333. data/samples/po/hu/hello_tk.po +1 -1
  334. data/samples/po/it/hello.po +1 -1
  335. data/samples/po/it/{hello_gtk.po → hello_gtk2.po} +0 -0
  336. data/samples/po/ja/{hello_gtk.po → hello_gtk2.po} +0 -0
  337. data/samples/po/ko/{hello_gtk.po → hello_gtk2.po} +0 -0
  338. data/samples/po/ko/hello_plural.po +1 -1
  339. data/samples/po/lv/hello.po +2 -2
  340. data/samples/po/lv/hello2.po +1 -1
  341. data/samples/po/lv/hello_glade2.po +1 -1
  342. data/samples/po/lv/{hello_gtk.po → hello_gtk2.po} +1 -1
  343. data/samples/po/lv/hello_noop.po +1 -1
  344. data/samples/po/lv/hello_plural.po +1 -1
  345. data/samples/po/lv/hello_tk.po +1 -1
  346. data/samples/po/nb/hello.po +2 -2
  347. data/samples/po/nb/hello2.po +1 -1
  348. data/samples/po/nb/hello_glade2.po +1 -1
  349. data/samples/po/nb/{hello_gtk.po → hello_gtk2.po} +1 -1
  350. data/samples/po/nb/hello_noop.po +1 -1
  351. data/samples/po/nb/hello_plural.po +1 -1
  352. data/samples/po/nb/hello_tk.po +1 -1
  353. data/samples/po/nl/hello.po +2 -2
  354. data/samples/po/nl/hello2.po +1 -1
  355. data/samples/po/nl/hello_glade2.po +1 -1
  356. data/samples/po/nl/{hello_gtk.po → hello_gtk2.po} +1 -1
  357. data/samples/po/nl/hello_noop.po +1 -1
  358. data/samples/po/nl/hello_plural.po +1 -1
  359. data/samples/po/nl/hello_tk.po +1 -1
  360. data/samples/po/pt_BR/{hello_gtk.po → hello_gtk2.po} +0 -0
  361. data/samples/po/ru/hello.po +2 -2
  362. data/samples/po/ru/hello2.po +1 -1
  363. data/samples/po/ru/hello_glade2.po +1 -1
  364. data/samples/po/ru/{hello_gtk.po → hello_gtk2.po} +1 -1
  365. data/samples/po/ru/hello_noop.po +1 -1
  366. data/samples/po/ru/hello_plural.po +1 -1
  367. data/samples/po/ru/hello_tk.po +1 -1
  368. data/samples/po/sr/hello.po +2 -2
  369. data/samples/po/sr/hello2.po +1 -1
  370. data/samples/po/sr/hello_glade2.po +1 -1
  371. data/samples/po/sr/{hello_gtk.po → hello_gtk2.po} +1 -1
  372. data/samples/po/sr/hello_noop.po +1 -1
  373. data/samples/po/sr/hello_plural.po +1 -1
  374. data/samples/po/sr/hello_tk.po +1 -1
  375. data/samples/po/sv/{hello_gtk.po → hello_gtk2.po} +0 -0
  376. data/samples/po/uk/hello.po +2 -2
  377. data/samples/po/uk/hello2.po +1 -1
  378. data/samples/po/uk/hello_glade2.po +1 -1
  379. data/samples/po/uk/{hello_gtk.po → hello_gtk2.po} +1 -1
  380. data/samples/po/uk/hello_noop.po +1 -1
  381. data/samples/po/uk/hello_plural.po +1 -1
  382. data/samples/po/uk/hello_tk.po +1 -1
  383. data/samples/po/vi/hello.po +2 -2
  384. data/samples/po/vi/hello2.po +1 -1
  385. data/samples/po/vi/hello_glade2.po +1 -1
  386. data/samples/po/vi/{hello_gtk.po → hello_gtk2.po} +1 -1
  387. data/samples/po/vi/hello_noop.po +1 -1
  388. data/samples/po/vi/hello_plural.po +1 -1
  389. data/samples/po/vi/hello_tk.po +1 -1
  390. data/samples/po/zh/hello.po +2 -2
  391. data/samples/po/zh/hello2.po +1 -1
  392. data/samples/po/zh/hello_glade2.po +1 -1
  393. data/samples/po/zh/{hello_gtk.po → hello_gtk2.po} +1 -1
  394. data/samples/po/zh/hello_noop.po +1 -1
  395. data/samples/po/zh/hello_plural.po +1 -1
  396. data/samples/po/zh/hello_tk.po +1 -1
  397. data/samples/po/zh_TW/hello.po +2 -2
  398. data/samples/po/zh_TW/hello2.po +1 -1
  399. data/samples/po/zh_TW/hello_glade2.po +1 -1
  400. data/samples/po/zh_TW/{hello_gtk.po → hello_gtk2.po} +1 -1
  401. data/samples/po/zh_TW/hello_noop.po +1 -1
  402. data/samples/po/zh_TW/hello_plural.po +1 -1
  403. data/samples/po/zh_TW/hello_tk.po +1 -1
  404. data/src/poparser.ry +18 -14
  405. data/test/{testlib → fixtures}/N_.rb +0 -0
  406. data/test/{testlib/gettext.rb → fixtures/_.rb} +27 -1
  407. data/test/fixtures/_/one_line.rb +32 -0
  408. data/test/fixtures/backslash.rb +29 -0
  409. data/test/{testlib → fixtures}/erb.rhtml +0 -0
  410. data/test/{testlib → fixtures}/erb.rxml +0 -0
  411. data/test/{testlib → fixtures}/gladeparser.glade +0 -0
  412. data/test/{testlib → fixtures}/multi_textdomain.rb +0 -0
  413. data/test/{testlib/ngettext.rb → fixtures/n_.rb} +20 -1
  414. data/test/{testlib → fixtures}/non_ascii.rb +0 -0
  415. data/test/fixtures/np_.rb +51 -0
  416. data/test/{testlib/nsgettext.rb → fixtures/ns_.rb} +20 -2
  417. data/test/fixtures/ns_/custom.rb +32 -0
  418. data/test/fixtures/p_.rb +57 -0
  419. data/test/fixtures/s_.rb +66 -0
  420. data/test/fixtures/s_/custom.rb +32 -0
  421. data/test/{testlib → fixtures}/simple.rb +0 -0
  422. data/test/gettext-test-utils.rb +44 -0
  423. data/test/locale/ja/LC_MESSAGES/_.mo +0 -0
  424. data/test/locale/ja/LC_MESSAGES/backslash.mo +0 -0
  425. data/test/locale/ja/LC_MESSAGES/np_.mo +0 -0
  426. data/test/locale/ja/LC_MESSAGES/ns_.mo +0 -0
  427. data/test/locale/ja/LC_MESSAGES/p_.mo +0 -0
  428. data/test/locale/ja/LC_MESSAGES/s_.mo +0 -0
  429. data/test/parser/test_ruby.rb +121 -0
  430. data/test/po/_.pot +109 -0
  431. data/test/{pot/sgettext.pot → po/backslash.pot} +10 -4
  432. data/test/po/ja/_.po +114 -0
  433. data/test/po/ja/backslash.po +3 -3
  434. data/test/po/ja/non_ascii.po +1 -1
  435. data/test/po/ja/{npgettext.po → np_.po} +6 -6
  436. data/test/po/ja/{nsgettext.po → ns_.po} +16 -10
  437. data/test/po/ja/{pgettext.po → p_.po} +5 -5
  438. data/test/po/ja/{sgettext.po → s_.po} +0 -0
  439. data/test/{pot → po}/non_ascii.pot +7 -5
  440. data/test/{pot/npgettext.pot → po/np_.pot} +10 -9
  441. data/test/{pot/nsgettext.pot → po/ns_.pot} +20 -12
  442. data/test/{pot/pgettext.pot → po/p_.pot} +12 -10
  443. data/test/po/s_.pot +55 -0
  444. data/test/run-test.rb +5 -0
  445. data/test/test_class_info.rb +0 -1
  446. data/test/test_gettext.rb +49 -12
  447. data/test/test_locale_path.rb +1 -4
  448. data/test/test_mofile.rb +0 -1
  449. data/test/test_parser.rb +119 -88
  450. data/test/test_po_generation.rb +32 -9
  451. data/test/{test_pomessage.rb → test_po_message.rb} +18 -1
  452. data/test/test_po_parser.rb +117 -0
  453. data/test/test_string.rb +0 -2
  454. data/test/test_textdomain_bind.rb +0 -2
  455. data/test/test_textdomain_multi.rb +1 -2
  456. data/test/test_textdomain_toplevel.rb +0 -1
  457. data/test/test_thread.rb +0 -1
  458. data/test/tools/test_msginit.rb +351 -0
  459. data/test/tools/test_msgmerge.rb +202 -0
  460. data/test/tools/test_tools.rb +0 -2
  461. data/test/tools/test_xgettext.rb +154 -0
  462. metadata +822 -753
  463. data/bin/rgettext +0 -23
  464. data/data/locale/bg/LC_MESSAGES/rgettext.mo +0 -0
  465. data/data/locale/bs/LC_MESSAGES/rgettext.mo +0 -0
  466. data/data/locale/ca/LC_MESSAGES/rgettext.mo +0 -0
  467. data/data/locale/cs/LC_MESSAGES/rgettext.mo +0 -0
  468. data/data/locale/de/LC_MESSAGES/rgettext.mo +0 -0
  469. data/data/locale/el/LC_MESSAGES/rgettext.mo +0 -0
  470. data/data/locale/eo/LC_MESSAGES/rgettext.mo +0 -0
  471. data/data/locale/es/LC_MESSAGES/rgettext.mo +0 -0
  472. data/data/locale/et/LC_MESSAGES/rgettext.mo +0 -0
  473. data/data/locale/fr/LC_MESSAGES/rgettext.mo +0 -0
  474. data/data/locale/hr/LC_MESSAGES/rgettext.mo +0 -0
  475. data/data/locale/hu/LC_MESSAGES/rgettext.mo +0 -0
  476. data/data/locale/it/LC_MESSAGES/rgettext.mo +0 -0
  477. data/data/locale/ja/LC_MESSAGES/rgettext.mo +0 -0
  478. data/data/locale/ko/LC_MESSAGES/rgettext.mo +0 -0
  479. data/data/locale/lv/LC_MESSAGES/rgettext.mo +0 -0
  480. data/data/locale/nb/LC_MESSAGES/rgettext.mo +0 -0
  481. data/data/locale/nl/LC_MESSAGES/rgettext.mo +0 -0
  482. data/data/locale/pt_BR/LC_MESSAGES/rgettext.mo +0 -0
  483. data/data/locale/ru/LC_MESSAGES/rgettext.mo +0 -0
  484. data/data/locale/sr/LC_MESSAGES/rgettext.mo +0 -0
  485. data/data/locale/sv/LC_MESSAGES/rgettext.mo +0 -0
  486. data/data/locale/uk/LC_MESSAGES/rgettext.mo +0 -0
  487. data/data/locale/vi/LC_MESSAGES/rgettext.mo +0 -0
  488. data/data/locale/zh/LC_MESSAGES/rgettext.mo +0 -0
  489. data/data/locale/zh_TW/LC_MESSAGES/rgettext.mo +0 -0
  490. data/lib/gettext/tools/rgettext.rb +0 -251
  491. data/lib/gettext/tools/rmsgfmt.rb +0 -86
  492. data/lib/gettext/tools/rmsgmerge.rb +0 -500
  493. data/samples/makemo.rb +0 -6
  494. data/samples/po/hello_gtk.pot +0 -23
  495. data/samples/po/test.rb +0 -13
  496. data/test/testlib/backslash.rb +0 -12
  497. data/test/testlib/helper.rb +0 -13
  498. data/test/testlib/npgettext.rb +0 -33
  499. data/test/testlib/pgettext.rb +0 -38
  500. data/test/testlib/sgettext.rb +0 -48
@@ -1,4 +1,3 @@
1
- #!/usr/bin/ruby
2
1
  =begin
3
2
  parser/ruby.rb - parser for ruby script
4
3
 
@@ -21,7 +20,7 @@ module GetText
21
20
  def parse
22
21
  until ( (tk = token).kind_of?(RubyToken::TkEND_OF_SCRIPT) && !@continue or tk.nil? )
23
22
  s = get_readed
24
- if RubyToken::TkSTRING === tk
23
+ if RubyToken::TkSTRING === tk or RubyToken::TkDSTRING === tk
25
24
  def tk.value
26
25
  @value
27
26
  end
@@ -44,7 +43,7 @@ module GetText
44
43
  end
45
44
 
46
45
  if $DEBUG
47
- if tk.is_a? TkSTRING
46
+ if tk.is_a? TkSTRING or tk.is_a? TkDSTRING
48
47
  $stderr.puts("#{tk}: #{tk.value}")
49
48
  elsif tk.is_a? TkIDENTIFIER
50
49
  $stderr.puts("#{tk}: #{tk.name}")
@@ -136,8 +135,11 @@ module GetText
136
135
  line_no = nil
137
136
  last_comment = ''
138
137
  reset_comment = false
138
+ ignore_next_comma = false
139
139
  rl.parse do |tk|
140
140
  begin
141
+ ignore_current_comma = ignore_next_comma
142
+ ignore_next_comma = false
141
143
  case tk
142
144
  when RubyToken::TkIDENTIFIER, RubyToken::TkCONSTANT
143
145
  store_pomessage(pomessages, pomessage, path, line_no, last_comment)
@@ -153,15 +155,20 @@ module GetText
153
155
  pomessage = nil
154
156
  end
155
157
  line_no = tk.line_no.to_s
156
- when RubyToken::TkSTRING
158
+ when RubyToken::TkSTRING, RubyToken::TkDSTRING
157
159
  pomessage.set_current_attribute tk.value if pomessage
158
160
  when RubyToken::TkPLUS, RubyToken::TkNL
159
161
  #do nothing
162
+ when RubyToken::TkINTEGER
163
+ ignore_next_comma = true
160
164
  when RubyToken::TkCOMMA
161
- pomessage.advance_to_next_attribute if pomessage
165
+ unless ignore_current_comma
166
+ pomessage.advance_to_next_attribute if pomessage
167
+ end
162
168
  else
163
169
  if store_pomessage(pomessages, pomessage, path, line_no, last_comment)
164
170
  pomessage = nil
171
+ last_comment = ""
165
172
  end
166
173
  end
167
174
  rescue
@@ -212,15 +219,3 @@ module GetText
212
219
  end
213
220
  end
214
221
  end
215
-
216
- if __FILE__ == $0
217
- require 'pp'
218
- ARGV.each do |path|
219
- pp GetText::RubyParser.parse(path)
220
- end
221
-
222
- #rl = GetText::RubyLexX.new; rl.set_input(ARGF)
223
- #rl.parse do |tk|
224
- #p tk
225
- #end
226
- end
@@ -1,4 +1,23 @@
1
- # encoding: utf-8
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # Copyright (C) 2012 Kouhei Sutou <kou@clear-code.com>
4
+ # Copyright (C) 2010 masone (Christian Felder) <ema@rh-productions.ch>
5
+ # Copyright (C) 2009 Masao Mutoh
6
+ #
7
+ # License: Ruby's or LGPL
8
+ #
9
+ # This library is free software: you can redistribute it and/or modify
10
+ # it under the terms of the GNU Lesser General Public License as published by
11
+ # the Free Software Foundation, either version 3 of the License, or
12
+ # (at your option) any later version.
13
+ #
14
+ # This library is distributed in the hope that it will be useful,
15
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
16
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
+ # GNU Lesser General Public License for more details.
18
+ #
19
+ # You should have received a copy of the GNU Lesser General Public License
20
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
2
21
 
3
22
  module GetText
4
23
  class ParseError < StandardError
@@ -8,12 +27,25 @@ module GetText
8
27
  # is to be translated.
9
28
  class PoMessage
10
29
  PARAMS = {
11
- :normal => [:msgid],
12
- :plural => [:msgid, :msgid_plural],
30
+ :normal => [:msgid, :separator],
31
+ :plural => [:msgid, :msgid_plural, :separator],
13
32
  :msgctxt => [:msgctxt, :msgid],
14
33
  :msgctxt_plural => [:msgctxt, :msgid, :msgid_plural]
15
34
  }
16
35
 
36
+ class << self
37
+ def escape(string)
38
+ string.gsub(/([\\"\n])/) do
39
+ special_character = $1
40
+ if special_character == "\n"
41
+ "\\n"
42
+ else
43
+ "\\#{special_character}"
44
+ end
45
+ end
46
+ end
47
+ end
48
+
17
49
  @@max_line_length = 70
18
50
 
19
51
  # Sets the max line length.
@@ -31,6 +63,7 @@ module GetText
31
63
  attr_accessor :msgid
32
64
  # Options
33
65
  attr_accessor :msgid_plural
66
+ attr_accessor :separator
34
67
  attr_accessor :msgctxt
35
68
  attr_accessor :sources # ["file1:line1", "file2:line2", ...]
36
69
  attr_accessor :comment
@@ -56,7 +89,7 @@ module GetText
56
89
  # and other purposes.
57
90
  def escaped(param_name)
58
91
  orig = self.send param_name
59
- orig.gsub(/"/, '\"').gsub(/\r/, '')
92
+ self.class.escape(orig.gsub(/\r/, ""))
60
93
  end
61
94
 
62
95
  # Checks if the other translation target is mergeable with
@@ -10,7 +10,7 @@
10
10
 
11
11
  #
12
12
  # DO NOT MODIFY!!!!
13
- # This file is automatically generated by Racc 1.4.8
13
+ # This file is automatically generated by Racc 1.4.9
14
14
  # from Racc grammer file "".
15
15
  #
16
16
 
@@ -18,7 +18,7 @@ require 'racc/parser.rb'
18
18
  module GetText
19
19
  class PoParser < Racc::Parser
20
20
 
21
- module_eval(<<'...end poparser.ry/module_eval...', 'poparser.ry', 114)
21
+ module_eval(<<'...end poparser.ry/module_eval...', 'poparser.ry', 119)
22
22
  if GetText.respond_to?(:bindtextdomain)
23
23
  include GetText
24
24
  GetText.bindtextdomain("rgettext")
@@ -123,10 +123,9 @@ module_eval(<<'...end poparser.ry/module_eval...', 'poparser.ry', 114)
123
123
  end
124
124
 
125
125
  def on_message(msgid, msgstr)
126
- if msgstr.size > 0
127
- @data[msgid] = msgstr
128
- @data.set_comment(msgid, @comments.join("\n"))
129
- end
126
+ @data[msgid] = msgstr
127
+ @data.set_comment(msgid, @comments.join("\n"))
128
+
130
129
  @comments.clear
131
130
  @msgctxt = ""
132
131
  end
@@ -279,7 +278,7 @@ Racc_debug_parser = true
279
278
 
280
279
  # reduce 4 omitted
281
280
 
282
- module_eval(<<'.,.,', 'poparser.ry', 25)
281
+ module_eval(<<'.,.,', 'poparser.ry', 26)
283
282
  def _reduce_5(val, _values, result)
284
283
  @msgctxt = unescape(val[1]) + "\004"
285
284
 
@@ -291,30 +290,34 @@ module_eval(<<'.,.,', 'poparser.ry', 25)
291
290
 
292
291
  # reduce 7 omitted
293
292
 
294
- module_eval(<<'.,.,', 'poparser.ry', 37)
293
+ module_eval(<<'.,.,', 'poparser.ry', 38)
295
294
  def _reduce_8(val, _values, result)
296
- if @fuzzy and ignore_fuzzy?
297
- if val[1] != ""
298
- if report_warning?
295
+ msgid_raw = val[1]
296
+ msgid = unescape(msgid_raw)
297
+ msgstr = unescape(val[3])
298
+ use_message_p = true
299
+ if @fuzzy and not msgid.empty?
300
+ use_message_p = (not ignore_fuzzy?)
301
+ if report_warning?
302
+ if ignore_fuzzy?
299
303
  $stderr.print _("Warning: fuzzy message was ignored.\n")
300
- $stderr.print " #{@po_file}: msgid '#{val[1]}'\n"
304
+ else
305
+ $stderr.print _("Warning: fuzzy message was used.\n")
301
306
  end
302
- else
303
- on_message('', unescape(val[3]))
307
+ $stderr.print " #{@po_file}: msgid '#{msgid_raw}'\n"
304
308
  end
305
- @fuzzy = false
306
- else
307
- on_message(@msgctxt + unescape(val[1]), unescape(val[3]))
308
309
  end
310
+ @fuzzy = false
311
+ on_message(@msgctxt + msgid, msgstr) if use_message_p
309
312
  result = ""
310
313
 
311
314
  result
312
315
  end
313
316
  .,.,
314
317
 
315
- module_eval(<<'.,.,', 'poparser.ry', 56)
318
+ module_eval(<<'.,.,', 'poparser.ry', 61)
316
319
  def _reduce_9(val, _values, result)
317
- if @fuzzy and $ignore_fuzzy
320
+ if @fuzzy and ignore_fuzzy?
318
321
  if val[1] != ""
319
322
  if report_warning?
320
323
  $stderr.print _("Warning: fuzzy message was ignored.\n")
@@ -333,7 +336,7 @@ module_eval(<<'.,.,', 'poparser.ry', 56)
333
336
  end
334
337
  .,.,
335
338
 
336
- module_eval(<<'.,.,', 'poparser.ry', 76)
339
+ module_eval(<<'.,.,', 'poparser.ry', 81)
337
340
  def _reduce_10(val, _values, result)
338
341
  if val[0].size > 0
339
342
  result = val[0] + "\000" + val[1]
@@ -347,7 +350,7 @@ module_eval(<<'.,.,', 'poparser.ry', 76)
347
350
 
348
351
  # reduce 11 omitted
349
352
 
350
- module_eval(<<'.,.,', 'poparser.ry', 88)
353
+ module_eval(<<'.,.,', 'poparser.ry', 93)
351
354
  def _reduce_12(val, _values, result)
352
355
  result = val[2]
353
356
 
@@ -355,7 +358,7 @@ module_eval(<<'.,.,', 'poparser.ry', 88)
355
358
  end
356
359
  .,.,
357
360
 
358
- module_eval(<<'.,.,', 'poparser.ry', 95)
361
+ module_eval(<<'.,.,', 'poparser.ry', 100)
359
362
  def _reduce_13(val, _values, result)
360
363
  on_comment(val[0])
361
364
 
@@ -363,7 +366,7 @@ module_eval(<<'.,.,', 'poparser.ry', 95)
363
366
  end
364
367
  .,.,
365
368
 
366
- module_eval(<<'.,.,', 'poparser.ry', 103)
369
+ module_eval(<<'.,.,', 'poparser.ry', 108)
367
370
  def _reduce_14(val, _values, result)
368
371
  result = val.delete_if{|item| item == ""}.join
369
372
 
@@ -371,7 +374,7 @@ module_eval(<<'.,.,', 'poparser.ry', 103)
371
374
  end
372
375
  .,.,
373
376
 
374
- module_eval(<<'.,.,', 'poparser.ry', 107)
377
+ module_eval(<<'.,.,', 'poparser.ry', 112)
375
378
  def _reduce_15(val, _values, result)
376
379
  result = val[0]
377
380
 
@@ -0,0 +1,327 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # Copyright (C) 2012 Haruka Yoshihara <yoshihara@clear-code.com>
4
+ # Copyright (C) 2012 Kouhei Sutou <kou@clear-code.com>
5
+ # Copyright (C) 2003-2010 Masao Mutoh
6
+ # Copyright (C) 2001,2002 Yasushi Shoji, Masao Mutoh
7
+ #
8
+ # License: Ruby's or LGPL
9
+ #
10
+ # This library is free software: you can redistribute it and/or modify
11
+ # it under the terms of the GNU Lesser General Public License as published by
12
+ # the Free Software Foundation, either version 3 of the License, or
13
+ # (at your option) any later version.
14
+ #
15
+ # This library is distributed in the hope that it will be useful,
16
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
17
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
+ # GNU Lesser General Public License for more details.
19
+ #
20
+ # You should have received a copy of the GNU Lesser General Public License
21
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
22
+
23
+ require "pathname"
24
+ require "optparse"
25
+ require "gettext"
26
+
27
+ module GetText
28
+ module Tools
29
+ class XGetText #:nodoc:
30
+ class << self
31
+ def run(*arguments)
32
+ new.run(*arguments)
33
+ end
34
+ end
35
+
36
+ include GetText
37
+
38
+ bindtextdomain("rgettext")
39
+
40
+ def initialize #:nodoc:
41
+ @ex_parsers = []
42
+ parsers = [
43
+ ["glade.rb", "GladeParser"],
44
+ ["erb.rb", "ErbParser"],
45
+ # ["ripper.rb", "RipperParser"],
46
+ ["ruby.rb", "RubyParser"] # Default parser.
47
+ ]
48
+ parsers.each do |f, klass|
49
+ begin
50
+ require "gettext/tools/parser/#{f}"
51
+ @ex_parsers << GetText.const_get(klass)
52
+ rescue
53
+ $stderr.puts(_("'%{klass}' is ignored.") % {:klass => klass})
54
+ $stderr.puts($!) if $DEBUG
55
+ end
56
+ end
57
+
58
+ @input_files = nil
59
+ @output = nil
60
+
61
+ @package_name = nil
62
+ @package_version = nil
63
+ @msgid_bugs_address = nil
64
+ @copyright_holder = nil
65
+ end
66
+
67
+ # How to add your option parser
68
+ # The option parser module requires to have target?(file) and
69
+ # parser(file, ary) method.
70
+ #
71
+ # require "gettext/tools/xgettext"
72
+ # module FooParser
73
+ # module_function
74
+ # def target?(file)
75
+ # File.extname(file) == ".foo" # *.foo file only.
76
+ # end
77
+ # def parse(file)
78
+ # :
79
+ # ary = []
80
+ # # Simple message
81
+ # po = PoMessage.new(:normal)
82
+ # po.msgid = "hello"
83
+ # po.sources = ["foo.rb:200", "bar.rb:300"]
84
+ # po.add_comment("Comment for the message")
85
+ # ary << po
86
+ # # Plural message
87
+ # po = PoMessage.new(:plural)
88
+ # po.msgid = "An apple"
89
+ # po.msgid_plural = "Apples"
90
+ # po.sources = ["foo.rb:200", "bar.rb:300"]
91
+ # ary << po
92
+ # # Simple message with the message context
93
+ # po = PoMessage.new(:msgctxt)
94
+ # po.msgctxt = "context"
95
+ # po.msgid = "hello"
96
+ # po.sources = ["foo.rb:200", "bar.rb:300"]
97
+ # ary << po
98
+ # # Plural message with the message context.
99
+ # po = PoMessage.new(:msgctxt_plural)
100
+ # po.msgctxt = "context"
101
+ # po.msgid = "An apple"
102
+ # po.msgid_plural = "Apples"
103
+ # po.sources = ["foo.rb:200", "bar.rb:300"]
104
+ # ary << po
105
+ # return ary
106
+ # end
107
+ # end
108
+ #
109
+ # GetText::XGetText.add_parser(FooParser)
110
+ def add_parser(klass)
111
+ @ex_parsers.insert(0, klass)
112
+ end
113
+
114
+ def generate_pot_header # :nodoc:
115
+ time = now.strftime("%Y-%m-%d %H:%M%z")
116
+
117
+ <<EOH
118
+ # SOME DESCRIPTIVE TITLE.
119
+ # Copyright (C) YEAR #{@copyright_holder}
120
+ # This file is distributed under the same license as the #{@package_name} package.
121
+ # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
122
+ #
123
+ #, fuzzy
124
+ msgid ""
125
+ msgstr ""
126
+ "Project-Id-Version: #{@package_name} #{@package_version}\\n"
127
+ "Report-Msgid-Bugs-To: #{@msgid_bugs_address}\\n"
128
+ "POT-Creation-Date: #{time}\\n"
129
+ "PO-Revision-Date: #{time}\\n"
130
+ "Last-Translator: FULL NAME <EMAIL@ADDRESS>\\n"
131
+ "Language-Team: LANGUAGE <LL@li.org>\\n"
132
+ "Language: \\n"
133
+ "MIME-Version: 1.0\\n"
134
+ "Content-Type: text/plain; charset=UTF-8\\n"
135
+ "Content-Transfer-Encoding: 8bit\\n"
136
+ "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\\n"
137
+ EOH
138
+ end
139
+
140
+ def generate_pot(paths) # :nodoc:
141
+ pomessages = parse(paths)
142
+ str = ""
143
+ pomessages.each do |target|
144
+ str << target.to_po_str
145
+ end
146
+ str
147
+ end
148
+
149
+ def parse(paths) # :nodoc:
150
+ pomessages = []
151
+ paths = [paths] if paths.kind_of?(String)
152
+ paths.each do |path|
153
+ begin
154
+ @ex_parsers.each do |klass|
155
+ next unless klass.target?(path)
156
+
157
+ if klass.method(:parse).arity == 1
158
+ targets = klass.parse(path)
159
+ else
160
+ # For backward compatibility
161
+ targets = klass.parse(path, [])
162
+ end
163
+
164
+ targets.each do |pomessage|
165
+ if pomessage.kind_of?(Array)
166
+ pomessage = PoMessage.new_from_ary(pomessage)
167
+ end
168
+
169
+ if pomessage.msgid.empty?
170
+ warn _("Warning: The empty \"\" msgid is reserved by " +
171
+ "gettext. So gettext(\"\") doesn't returns " +
172
+ "empty string but the header entry in po file.")
173
+ # TODO: add pommesage.source to the pot header as below:
174
+ # # SOME DESCRIPTIVE TITLE.
175
+ # # Copyright (C) YEAR THE COPYRIGHT HOLDER
176
+ # # This file is distributed under the same license as the PACKAGE package.
177
+ # # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
178
+ # #
179
+ # #: test/test_gettext.rb:65
180
+ # #, fuzzy
181
+ # "#: test/test_gettext.rb:65" line is added.
182
+ next
183
+ end
184
+
185
+ if @output.is_a?(String)
186
+ base_path = Pathname.new(@output).dirname.expand_path
187
+ pomessage.sources = pomessage.sources.collect do |source|
188
+ path, line, = source.split(/:(\d+)\z/, 2)
189
+ absolute_path = Pathname.new(path).expand_path
190
+ begin
191
+ path = absolute_path.relative_path_from(base_path).to_s
192
+ rescue ArgumentError
193
+ raise # Should we ignore it?
194
+ end
195
+ "#{path}:#{line}"
196
+ end
197
+ end
198
+
199
+ # Save the previous target
200
+ if pomessages.empty?
201
+ existing = nil
202
+ else
203
+ message = pomessages.find {|t| t == pomessage}
204
+ existing = pomessages.index(message)
205
+ end
206
+
207
+ if existing
208
+ pomessage = pomessages[existing].merge(pomessage)
209
+ pomessages[existing] = pomessage
210
+ else
211
+ pomessages << pomessage
212
+ end
213
+ end
214
+ break
215
+ end
216
+ rescue
217
+ puts(_("Error parsing %{path}") % {:path => path})
218
+ raise
219
+ end
220
+ end
221
+ pomessages
222
+ end
223
+
224
+ # constant values
225
+ VERSION = GetText::VERSION
226
+
227
+ def check_command_line_options(*options) # :nodoc:
228
+ input_files, output = parse_arguments(*options)
229
+
230
+ if input_files.empty?
231
+ raise ArgumentError, _("no input files")
232
+ end
233
+
234
+ output ||= STDOUT
235
+
236
+ @input_files = input_files
237
+ @output = output
238
+
239
+ @package_name ||= "PACKAGE"
240
+ @package_version ||= "VERSION"
241
+ @msgid_bugs_address ||= ""
242
+ @copyright_holder ||= "THE PACKAGE'S COPYRIGHT HOLDER"
243
+ end
244
+
245
+ def parse_arguments(*options) #:nodoc:
246
+ output = nil
247
+
248
+ parser = OptionParser.new
249
+ banner = _("Usage: %s input.rb [-r parser.rb] [-o output.pot]") % $0
250
+ parser.banner = banner
251
+ parser.separator("")
252
+ description = _("Extract translatable strings from given input files.")
253
+ parser.separator(description)
254
+ parser.separator("")
255
+ parser.separator(_("Specific options:"))
256
+
257
+ parser.on("-o", "--output=FILE",
258
+ _("write output to specified file")) do |out|
259
+ output = out
260
+ end
261
+
262
+ parser.on("--package-name=PACKAGE",
263
+ _("set package name in output")) do |out|
264
+ @package_name = out
265
+ end
266
+
267
+ parser.on("--package-version=VERSION",
268
+ _("set package version in output")) do |out|
269
+ @package_version = out
270
+ end
271
+
272
+ parser.on("--msgid-bugs-address=EMAIL",
273
+ _("set report address for msgid bugs")) do |out|
274
+ @msgid_bugs_address = out
275
+ end
276
+
277
+ parser.on("--copyright-holder=STRING",
278
+ _("set copyright holder in output")) do |out|
279
+ @copyright_holder = out
280
+ end
281
+
282
+ parser.on("-r", "--require=library",
283
+ _("require the library before executing xgettext")) do |out|
284
+ require out
285
+ end
286
+
287
+ parser.on("-d", "--debug", _("run in debugging mode")) do
288
+ $DEBUG = true
289
+ end
290
+
291
+ parser.on("-h", "--help", _("display this help and exit")) do
292
+ puts(parser.help)
293
+ exit(true)
294
+ end
295
+
296
+ parser.on_tail("--version", _("display version information and exit")) do
297
+ puts(VERSION)
298
+ exit(true)
299
+ end
300
+
301
+ parser.parse!(options)
302
+
303
+ [options, output]
304
+ end
305
+
306
+ def run(*options) # :nodoc:
307
+ check_command_line_options(*options)
308
+
309
+ if @output.is_a?(String)
310
+ File.open(File.expand_path(@output), "w+") do |file|
311
+ file.puts(generate_pot_header)
312
+ file.puts(generate_pot(@input_files))
313
+ end
314
+ else
315
+ @output.puts(generate_pot_header)
316
+ @output.puts(generate_pot(@input_files))
317
+ end
318
+ self
319
+ end
320
+
321
+ private
322
+ def now
323
+ Time.now
324
+ end
325
+ end
326
+ end
327
+ end