gettext 3.0.0 → 3.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (441) hide show
  1. data/Rakefile +23 -12
  2. data/doc/text/news.md +31 -0
  3. data/lib/gettext/po.rb +17 -7
  4. data/lib/gettext/po_entry.rb +212 -208
  5. data/lib/gettext/po_format.rb +28 -0
  6. data/lib/gettext/po_parser.rb +25 -25
  7. data/lib/gettext/text_domain.rb +10 -0
  8. data/lib/gettext/tools/msginit.rb +19 -1
  9. data/lib/gettext/tools/msgmerge.rb +122 -68
  10. data/lib/gettext/tools/task.rb +306 -87
  11. data/lib/gettext/tools/xgettext.rb +27 -1
  12. data/lib/gettext/version.rb +1 -1
  13. data/locale/bg/LC_MESSAGES/gettext.mo +0 -0
  14. data/locale/bs/LC_MESSAGES/gettext.mo +0 -0
  15. data/locale/ca/LC_MESSAGES/gettext.mo +0 -0
  16. data/locale/cs/LC_MESSAGES/gettext.mo +0 -0
  17. data/locale/de/LC_MESSAGES/gettext.mo +0 -0
  18. data/locale/el/LC_MESSAGES/gettext.mo +0 -0
  19. data/locale/eo/LC_MESSAGES/gettext.mo +0 -0
  20. data/locale/es/LC_MESSAGES/gettext.mo +0 -0
  21. data/locale/et/LC_MESSAGES/gettext.mo +0 -0
  22. data/locale/fr/LC_MESSAGES/gettext.mo +0 -0
  23. data/locale/hr/LC_MESSAGES/gettext.mo +0 -0
  24. data/locale/hu/LC_MESSAGES/gettext.mo +0 -0
  25. data/locale/it/LC_MESSAGES/gettext.mo +0 -0
  26. data/locale/ja/LC_MESSAGES/gettext.mo +0 -0
  27. data/locale/ko/LC_MESSAGES/gettext.mo +0 -0
  28. data/locale/lv/LC_MESSAGES/gettext.mo +0 -0
  29. data/locale/nb/LC_MESSAGES/gettext.mo +0 -0
  30. data/locale/nl/LC_MESSAGES/gettext.mo +0 -0
  31. data/locale/pt_BR/LC_MESSAGES/gettext.mo +0 -0
  32. data/locale/ru/LC_MESSAGES/gettext.mo +0 -0
  33. data/locale/sr/LC_MESSAGES/gettext.mo +0 -0
  34. data/locale/sv/LC_MESSAGES/gettext.mo +0 -0
  35. data/locale/uk/LC_MESSAGES/gettext.mo +0 -0
  36. data/locale/vi/LC_MESSAGES/gettext.mo +0 -0
  37. data/locale/zh/LC_MESSAGES/gettext.mo +0 -0
  38. data/locale/zh_TW/LC_MESSAGES/gettext.mo +0 -0
  39. data/po/bg/gettext.po +370 -284
  40. data/po/bs/gettext.po +378 -321
  41. data/po/ca/gettext.po +373 -284
  42. data/po/cs/gettext.po +371 -313
  43. data/po/de/gettext.po +380 -282
  44. data/po/el/gettext.po +377 -277
  45. data/po/eo/gettext.po +373 -275
  46. data/po/es/gettext.po +376 -277
  47. data/po/et/gettext.po +374 -274
  48. data/po/fr/gettext.po +380 -279
  49. data/po/gettext.pot +102 -70
  50. data/po/hr/gettext.po +371 -308
  51. data/po/hu/gettext.po +376 -276
  52. data/po/it/gettext.po +362 -269
  53. data/po/ja/gettext.po +338 -216
  54. data/po/ko/gettext.po +392 -266
  55. data/po/lv/gettext.po +377 -310
  56. data/po/nb/gettext.po +377 -278
  57. data/po/nl/gettext.po +371 -274
  58. data/po/pt_BR/gettext.po +376 -277
  59. data/po/ru/gettext.po +380 -311
  60. data/po/sr/gettext.po +378 -310
  61. data/po/sv/gettext.po +331 -258
  62. data/po/uk/gettext.po +380 -311
  63. data/po/vi/gettext.po +374 -275
  64. data/po/zh/gettext.po +397 -266
  65. data/po/zh_TW/gettext.po +397 -266
  66. data/samples/cgi/README +0 -2
  67. data/samples/cgi/locale/bg/LC_MESSAGES/helloerb1.mo +0 -0
  68. data/samples/cgi/locale/bg/LC_MESSAGES/helloerb2.mo +0 -0
  69. data/samples/cgi/locale/bg/LC_MESSAGES/hellolib.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/hellolib.mo +0 -0
  74. data/samples/cgi/locale/bs/LC_MESSAGES/main.mo +0 -0
  75. data/samples/cgi/locale/ca/LC_MESSAGES/helloerb1.mo +0 -0
  76. data/samples/cgi/locale/ca/LC_MESSAGES/helloerb2.mo +0 -0
  77. data/samples/cgi/locale/ca/LC_MESSAGES/hellolib.mo +0 -0
  78. data/samples/cgi/locale/ca/LC_MESSAGES/main.mo +0 -0
  79. data/samples/cgi/locale/cs/LC_MESSAGES/helloerb1.mo +0 -0
  80. data/samples/cgi/locale/cs/LC_MESSAGES/helloerb2.mo +0 -0
  81. data/samples/cgi/locale/cs/LC_MESSAGES/hellolib.mo +0 -0
  82. data/samples/cgi/locale/cs/LC_MESSAGES/main.mo +0 -0
  83. data/samples/cgi/locale/de/LC_MESSAGES/helloerb1.mo +0 -0
  84. data/samples/cgi/locale/de/LC_MESSAGES/helloerb2.mo +0 -0
  85. data/samples/cgi/locale/de/LC_MESSAGES/hellolib.mo +0 -0
  86. data/samples/cgi/locale/de/LC_MESSAGES/main.mo +0 -0
  87. data/samples/cgi/locale/el/LC_MESSAGES/helloerb1.mo +0 -0
  88. data/samples/cgi/locale/el/LC_MESSAGES/helloerb2.mo +0 -0
  89. data/samples/cgi/locale/el/LC_MESSAGES/hellolib.mo +0 -0
  90. data/samples/cgi/locale/el/LC_MESSAGES/main.mo +0 -0
  91. data/samples/cgi/locale/eo/LC_MESSAGES/helloerb1.mo +0 -0
  92. data/samples/cgi/locale/eo/LC_MESSAGES/helloerb2.mo +0 -0
  93. data/samples/cgi/locale/eo/LC_MESSAGES/hellolib.mo +0 -0
  94. data/samples/cgi/locale/eo/LC_MESSAGES/main.mo +0 -0
  95. data/samples/cgi/locale/es/LC_MESSAGES/helloerb1.mo +0 -0
  96. data/samples/cgi/locale/es/LC_MESSAGES/helloerb2.mo +0 -0
  97. data/samples/cgi/locale/es/LC_MESSAGES/hellolib.mo +0 -0
  98. data/samples/cgi/locale/es/LC_MESSAGES/main.mo +0 -0
  99. data/samples/cgi/locale/fr/LC_MESSAGES/helloerb1.mo +0 -0
  100. data/samples/cgi/locale/fr/LC_MESSAGES/helloerb2.mo +0 -0
  101. data/samples/cgi/locale/fr/LC_MESSAGES/hellolib.mo +0 -0
  102. data/samples/cgi/locale/fr/LC_MESSAGES/main.mo +0 -0
  103. data/samples/cgi/locale/hr/LC_MESSAGES/helloerb1.mo +0 -0
  104. data/samples/cgi/locale/hr/LC_MESSAGES/helloerb2.mo +0 -0
  105. data/samples/cgi/locale/hr/LC_MESSAGES/hellolib.mo +0 -0
  106. data/samples/cgi/locale/hr/LC_MESSAGES/main.mo +0 -0
  107. data/samples/cgi/locale/hu/LC_MESSAGES/helloerb1.mo +0 -0
  108. data/samples/cgi/locale/hu/LC_MESSAGES/helloerb2.mo +0 -0
  109. data/samples/cgi/locale/hu/LC_MESSAGES/hellolib.mo +0 -0
  110. data/samples/cgi/locale/hu/LC_MESSAGES/main.mo +0 -0
  111. data/samples/cgi/locale/it/LC_MESSAGES/helloerb1.mo +0 -0
  112. data/samples/cgi/locale/it/LC_MESSAGES/helloerb2.mo +0 -0
  113. data/samples/cgi/locale/it/LC_MESSAGES/hellolib.mo +0 -0
  114. data/samples/cgi/locale/it/LC_MESSAGES/main.mo +0 -0
  115. data/samples/cgi/locale/ja/LC_MESSAGES/helloerb1.mo +0 -0
  116. data/samples/cgi/locale/ja/LC_MESSAGES/helloerb2.mo +0 -0
  117. data/samples/cgi/locale/ja/LC_MESSAGES/hellolib.mo +0 -0
  118. data/samples/cgi/locale/ja/LC_MESSAGES/main.mo +0 -0
  119. data/samples/cgi/locale/ko/LC_MESSAGES/helloerb1.mo +0 -0
  120. data/samples/cgi/locale/ko/LC_MESSAGES/helloerb2.mo +0 -0
  121. data/samples/cgi/locale/ko/LC_MESSAGES/hellolib.mo +0 -0
  122. data/samples/cgi/locale/ko/LC_MESSAGES/main.mo +0 -0
  123. data/samples/cgi/locale/lv/LC_MESSAGES/helloerb1.mo +0 -0
  124. data/samples/cgi/locale/lv/LC_MESSAGES/helloerb2.mo +0 -0
  125. data/samples/cgi/locale/lv/LC_MESSAGES/hellolib.mo +0 -0
  126. data/samples/cgi/locale/lv/LC_MESSAGES/main.mo +0 -0
  127. data/samples/cgi/locale/nb/LC_MESSAGES/helloerb1.mo +0 -0
  128. data/samples/cgi/locale/nb/LC_MESSAGES/helloerb2.mo +0 -0
  129. data/samples/cgi/locale/nb/LC_MESSAGES/hellolib.mo +0 -0
  130. data/samples/cgi/locale/nb/LC_MESSAGES/main.mo +0 -0
  131. data/samples/cgi/locale/nl/LC_MESSAGES/helloerb1.mo +0 -0
  132. data/samples/cgi/locale/nl/LC_MESSAGES/helloerb2.mo +0 -0
  133. data/samples/cgi/locale/nl/LC_MESSAGES/hellolib.mo +0 -0
  134. data/samples/cgi/locale/nl/LC_MESSAGES/main.mo +0 -0
  135. data/samples/cgi/locale/pt_BR/LC_MESSAGES/helloerb1.mo +0 -0
  136. data/samples/cgi/locale/pt_BR/LC_MESSAGES/helloerb2.mo +0 -0
  137. data/samples/cgi/locale/pt_BR/LC_MESSAGES/hellolib.mo +0 -0
  138. data/samples/cgi/locale/pt_BR/LC_MESSAGES/main.mo +0 -0
  139. data/samples/cgi/locale/ru/LC_MESSAGES/helloerb1.mo +0 -0
  140. data/samples/cgi/locale/ru/LC_MESSAGES/helloerb2.mo +0 -0
  141. data/samples/cgi/locale/ru/LC_MESSAGES/hellolib.mo +0 -0
  142. data/samples/cgi/locale/ru/LC_MESSAGES/main.mo +0 -0
  143. data/samples/cgi/locale/sr/LC_MESSAGES/helloerb1.mo +0 -0
  144. data/samples/cgi/locale/sr/LC_MESSAGES/helloerb2.mo +0 -0
  145. data/samples/cgi/locale/sr/LC_MESSAGES/hellolib.mo +0 -0
  146. data/samples/cgi/locale/sr/LC_MESSAGES/main.mo +0 -0
  147. data/samples/cgi/locale/uk/LC_MESSAGES/helloerb1.mo +0 -0
  148. data/samples/cgi/locale/uk/LC_MESSAGES/helloerb2.mo +0 -0
  149. data/samples/cgi/locale/uk/LC_MESSAGES/hellolib.mo +0 -0
  150. data/samples/cgi/locale/uk/LC_MESSAGES/main.mo +0 -0
  151. data/samples/cgi/locale/vi/LC_MESSAGES/helloerb1.mo +0 -0
  152. data/samples/cgi/locale/vi/LC_MESSAGES/helloerb2.mo +0 -0
  153. data/samples/cgi/locale/vi/LC_MESSAGES/hellolib.mo +0 -0
  154. data/samples/cgi/locale/vi/LC_MESSAGES/main.mo +0 -0
  155. data/samples/cgi/locale/zh/LC_MESSAGES/helloerb1.mo +0 -0
  156. data/samples/cgi/locale/zh/LC_MESSAGES/helloerb2.mo +0 -0
  157. data/samples/cgi/locale/zh/LC_MESSAGES/hellolib.mo +0 -0
  158. data/samples/cgi/locale/zh/LC_MESSAGES/main.mo +0 -0
  159. data/samples/cgi/locale/zh_TW/LC_MESSAGES/helloerb1.mo +0 -0
  160. data/samples/cgi/locale/zh_TW/LC_MESSAGES/helloerb2.mo +0 -0
  161. data/samples/cgi/locale/zh_TW/LC_MESSAGES/hellolib.mo +0 -0
  162. data/samples/cgi/locale/zh_TW/LC_MESSAGES/main.mo +0 -0
  163. data/samples/locale/bg/LC_MESSAGES/hello.mo +0 -0
  164. data/samples/locale/bg/LC_MESSAGES/hello2.mo +0 -0
  165. data/samples/locale/bg/LC_MESSAGES/hello_glade2.mo +0 -0
  166. data/samples/locale/bg/LC_MESSAGES/hello_gtk2.mo +0 -0
  167. data/samples/locale/bg/LC_MESSAGES/hello_gtk_builder.mo +0 -0
  168. data/samples/locale/bg/LC_MESSAGES/hello_noop.mo +0 -0
  169. data/samples/locale/bg/LC_MESSAGES/hello_plural.mo +0 -0
  170. data/samples/locale/bg/LC_MESSAGES/hello_tk.mo +0 -0
  171. data/samples/locale/bs/LC_MESSAGES/hello.mo +0 -0
  172. data/samples/locale/bs/LC_MESSAGES/hello2.mo +0 -0
  173. data/samples/locale/bs/LC_MESSAGES/hello_glade2.mo +0 -0
  174. data/samples/locale/bs/LC_MESSAGES/hello_gtk2.mo +0 -0
  175. data/samples/locale/bs/LC_MESSAGES/hello_gtk_builder.mo +0 -0
  176. data/samples/locale/bs/LC_MESSAGES/hello_noop.mo +0 -0
  177. data/samples/locale/bs/LC_MESSAGES/hello_plural.mo +0 -0
  178. data/samples/locale/bs/LC_MESSAGES/hello_tk.mo +0 -0
  179. data/samples/locale/ca/LC_MESSAGES/hello.mo +0 -0
  180. data/samples/locale/ca/LC_MESSAGES/hello2.mo +0 -0
  181. data/samples/locale/ca/LC_MESSAGES/hello_glade2.mo +0 -0
  182. data/samples/locale/ca/LC_MESSAGES/hello_gtk2.mo +0 -0
  183. data/samples/locale/ca/LC_MESSAGES/hello_gtk_builder.mo +0 -0
  184. data/samples/locale/ca/LC_MESSAGES/hello_noop.mo +0 -0
  185. data/samples/locale/ca/LC_MESSAGES/hello_plural.mo +0 -0
  186. data/samples/locale/ca/LC_MESSAGES/hello_tk.mo +0 -0
  187. data/samples/locale/cs/LC_MESSAGES/hello.mo +0 -0
  188. data/samples/locale/cs/LC_MESSAGES/hello2.mo +0 -0
  189. data/samples/locale/cs/LC_MESSAGES/hello_glade2.mo +0 -0
  190. data/samples/locale/cs/LC_MESSAGES/hello_gtk2.mo +0 -0
  191. data/samples/locale/cs/LC_MESSAGES/hello_gtk_builder.mo +0 -0
  192. data/samples/locale/cs/LC_MESSAGES/hello_noop.mo +0 -0
  193. data/samples/locale/cs/LC_MESSAGES/hello_plural.mo +0 -0
  194. data/samples/locale/cs/LC_MESSAGES/hello_tk.mo +0 -0
  195. data/samples/locale/de/LC_MESSAGES/hello.mo +0 -0
  196. data/samples/locale/de/LC_MESSAGES/hello2.mo +0 -0
  197. data/samples/locale/de/LC_MESSAGES/hello_glade2.mo +0 -0
  198. data/samples/locale/de/LC_MESSAGES/hello_gtk2.mo +0 -0
  199. data/samples/locale/de/LC_MESSAGES/hello_gtk_builder.mo +0 -0
  200. data/samples/locale/de/LC_MESSAGES/hello_noop.mo +0 -0
  201. data/samples/locale/de/LC_MESSAGES/hello_plural.mo +0 -0
  202. data/samples/locale/de/LC_MESSAGES/hello_tk.mo +0 -0
  203. data/samples/locale/el/LC_MESSAGES/hello.mo +0 -0
  204. data/samples/locale/el/LC_MESSAGES/hello2.mo +0 -0
  205. data/samples/locale/el/LC_MESSAGES/hello_glade2.mo +0 -0
  206. data/samples/locale/el/LC_MESSAGES/hello_gtk2.mo +0 -0
  207. data/samples/locale/el/LC_MESSAGES/hello_gtk_builder.mo +0 -0
  208. data/samples/locale/el/LC_MESSAGES/hello_noop.mo +0 -0
  209. data/samples/locale/el/LC_MESSAGES/hello_plural.mo +0 -0
  210. data/samples/locale/el/LC_MESSAGES/hello_tk.mo +0 -0
  211. data/samples/locale/eo/LC_MESSAGES/hello.mo +0 -0
  212. data/samples/locale/eo/LC_MESSAGES/hello2.mo +0 -0
  213. data/samples/locale/eo/LC_MESSAGES/hello_glade2.mo +0 -0
  214. data/samples/locale/eo/LC_MESSAGES/hello_gtk2.mo +0 -0
  215. data/samples/locale/eo/LC_MESSAGES/hello_gtk_builder.mo +0 -0
  216. data/samples/locale/eo/LC_MESSAGES/hello_noop.mo +0 -0
  217. data/samples/locale/eo/LC_MESSAGES/hello_plural.mo +0 -0
  218. data/samples/locale/eo/LC_MESSAGES/hello_tk.mo +0 -0
  219. data/samples/locale/es/LC_MESSAGES/hello.mo +0 -0
  220. data/samples/locale/es/LC_MESSAGES/hello2.mo +0 -0
  221. data/samples/locale/es/LC_MESSAGES/hello_glade2.mo +0 -0
  222. data/samples/locale/es/LC_MESSAGES/hello_gtk2.mo +0 -0
  223. data/samples/locale/es/LC_MESSAGES/hello_gtk_builder.mo +0 -0
  224. data/samples/locale/es/LC_MESSAGES/hello_noop.mo +0 -0
  225. data/samples/locale/es/LC_MESSAGES/hello_plural.mo +0 -0
  226. data/samples/locale/es/LC_MESSAGES/hello_tk.mo +0 -0
  227. data/samples/locale/fr/LC_MESSAGES/hello.mo +0 -0
  228. data/samples/locale/fr/LC_MESSAGES/hello2.mo +0 -0
  229. data/samples/locale/fr/LC_MESSAGES/hello_glade2.mo +0 -0
  230. data/samples/locale/fr/LC_MESSAGES/hello_gtk2.mo +0 -0
  231. data/samples/locale/fr/LC_MESSAGES/hello_gtk_builder.mo +0 -0
  232. data/samples/locale/fr/LC_MESSAGES/hello_noop.mo +0 -0
  233. data/samples/locale/fr/LC_MESSAGES/hello_plural.mo +0 -0
  234. data/samples/locale/fr/LC_MESSAGES/hello_tk.mo +0 -0
  235. data/samples/locale/hr/LC_MESSAGES/hello.mo +0 -0
  236. data/samples/locale/hr/LC_MESSAGES/hello2.mo +0 -0
  237. data/samples/locale/hr/LC_MESSAGES/hello_glade2.mo +0 -0
  238. data/samples/locale/hr/LC_MESSAGES/hello_gtk2.mo +0 -0
  239. data/samples/locale/hr/LC_MESSAGES/hello_gtk_builder.mo +0 -0
  240. data/samples/locale/hr/LC_MESSAGES/hello_noop.mo +0 -0
  241. data/samples/locale/hr/LC_MESSAGES/hello_plural.mo +0 -0
  242. data/samples/locale/hr/LC_MESSAGES/hello_tk.mo +0 -0
  243. data/samples/locale/hu/LC_MESSAGES/hello.mo +0 -0
  244. data/samples/locale/hu/LC_MESSAGES/hello2.mo +0 -0
  245. data/samples/locale/hu/LC_MESSAGES/hello_glade2.mo +0 -0
  246. data/samples/locale/hu/LC_MESSAGES/hello_gtk2.mo +0 -0
  247. data/samples/locale/hu/LC_MESSAGES/hello_gtk_builder.mo +0 -0
  248. data/samples/locale/hu/LC_MESSAGES/hello_noop.mo +0 -0
  249. data/samples/locale/hu/LC_MESSAGES/hello_plural.mo +0 -0
  250. data/samples/locale/hu/LC_MESSAGES/hello_tk.mo +0 -0
  251. data/samples/locale/it/LC_MESSAGES/hello.mo +0 -0
  252. data/samples/locale/it/LC_MESSAGES/hello2.mo +0 -0
  253. data/samples/locale/it/LC_MESSAGES/hello_glade2.mo +0 -0
  254. data/samples/locale/it/LC_MESSAGES/hello_gtk2.mo +0 -0
  255. data/samples/locale/it/LC_MESSAGES/hello_gtk_builder.mo +0 -0
  256. data/samples/locale/it/LC_MESSAGES/hello_noop.mo +0 -0
  257. data/samples/locale/it/LC_MESSAGES/hello_plural.mo +0 -0
  258. data/samples/locale/it/LC_MESSAGES/hello_tk.mo +0 -0
  259. data/samples/locale/ja/LC_MESSAGES/hello.mo +0 -0
  260. data/samples/locale/ja/LC_MESSAGES/hello2.mo +0 -0
  261. data/samples/locale/ja/LC_MESSAGES/hello_glade2.mo +0 -0
  262. data/samples/locale/ja/LC_MESSAGES/hello_gtk2.mo +0 -0
  263. data/samples/locale/ja/LC_MESSAGES/hello_gtk_builder.mo +0 -0
  264. data/samples/locale/ja/LC_MESSAGES/hello_noop.mo +0 -0
  265. data/samples/locale/ja/LC_MESSAGES/hello_plural.mo +0 -0
  266. data/samples/locale/ja/LC_MESSAGES/hello_tk.mo +0 -0
  267. data/samples/locale/ko/LC_MESSAGES/hello.mo +0 -0
  268. data/samples/locale/ko/LC_MESSAGES/hello2.mo +0 -0
  269. data/samples/locale/ko/LC_MESSAGES/hello_glade2.mo +0 -0
  270. data/samples/locale/ko/LC_MESSAGES/hello_gtk2.mo +0 -0
  271. data/samples/locale/ko/LC_MESSAGES/hello_gtk_builder.mo +0 -0
  272. data/samples/locale/ko/LC_MESSAGES/hello_noop.mo +0 -0
  273. data/samples/locale/ko/LC_MESSAGES/hello_plural.mo +0 -0
  274. data/samples/locale/ko/LC_MESSAGES/hello_tk.mo +0 -0
  275. data/samples/locale/lv/LC_MESSAGES/hello.mo +0 -0
  276. data/samples/locale/lv/LC_MESSAGES/hello2.mo +0 -0
  277. data/samples/locale/lv/LC_MESSAGES/hello_glade2.mo +0 -0
  278. data/samples/locale/lv/LC_MESSAGES/hello_gtk2.mo +0 -0
  279. data/samples/locale/lv/LC_MESSAGES/hello_gtk_builder.mo +0 -0
  280. data/samples/locale/lv/LC_MESSAGES/hello_noop.mo +0 -0
  281. data/samples/locale/lv/LC_MESSAGES/hello_plural.mo +0 -0
  282. data/samples/locale/lv/LC_MESSAGES/hello_tk.mo +0 -0
  283. data/samples/locale/nb/LC_MESSAGES/hello.mo +0 -0
  284. data/samples/locale/nb/LC_MESSAGES/hello2.mo +0 -0
  285. data/samples/locale/nb/LC_MESSAGES/hello_glade2.mo +0 -0
  286. data/samples/locale/nb/LC_MESSAGES/hello_gtk2.mo +0 -0
  287. data/samples/locale/nb/LC_MESSAGES/hello_gtk_builder.mo +0 -0
  288. data/samples/locale/nb/LC_MESSAGES/hello_noop.mo +0 -0
  289. data/samples/locale/nb/LC_MESSAGES/hello_plural.mo +0 -0
  290. data/samples/locale/nb/LC_MESSAGES/hello_tk.mo +0 -0
  291. data/samples/locale/nl/LC_MESSAGES/hello.mo +0 -0
  292. data/samples/locale/nl/LC_MESSAGES/hello2.mo +0 -0
  293. data/samples/locale/nl/LC_MESSAGES/hello_glade2.mo +0 -0
  294. data/samples/locale/nl/LC_MESSAGES/hello_gtk2.mo +0 -0
  295. data/samples/locale/nl/LC_MESSAGES/hello_gtk_builder.mo +0 -0
  296. data/samples/locale/nl/LC_MESSAGES/hello_noop.mo +0 -0
  297. data/samples/locale/nl/LC_MESSAGES/hello_plural.mo +0 -0
  298. data/samples/locale/nl/LC_MESSAGES/hello_tk.mo +0 -0
  299. data/samples/locale/pt_BR/LC_MESSAGES/hello.mo +0 -0
  300. data/samples/locale/pt_BR/LC_MESSAGES/hello2.mo +0 -0
  301. data/samples/locale/pt_BR/LC_MESSAGES/hello_glade2.mo +0 -0
  302. data/samples/locale/pt_BR/LC_MESSAGES/hello_gtk2.mo +0 -0
  303. data/samples/locale/pt_BR/LC_MESSAGES/hello_gtk_builder.mo +0 -0
  304. data/samples/locale/pt_BR/LC_MESSAGES/hello_noop.mo +0 -0
  305. data/samples/locale/pt_BR/LC_MESSAGES/hello_plural.mo +0 -0
  306. data/samples/locale/pt_BR/LC_MESSAGES/hello_tk.mo +0 -0
  307. data/samples/locale/ru/LC_MESSAGES/hello.mo +0 -0
  308. data/samples/locale/ru/LC_MESSAGES/hello2.mo +0 -0
  309. data/samples/locale/ru/LC_MESSAGES/hello_glade2.mo +0 -0
  310. data/samples/locale/ru/LC_MESSAGES/hello_gtk2.mo +0 -0
  311. data/samples/locale/ru/LC_MESSAGES/hello_gtk_builder.mo +0 -0
  312. data/samples/locale/ru/LC_MESSAGES/hello_noop.mo +0 -0
  313. data/samples/locale/ru/LC_MESSAGES/hello_plural.mo +0 -0
  314. data/samples/locale/ru/LC_MESSAGES/hello_tk.mo +0 -0
  315. data/samples/locale/sr/LC_MESSAGES/hello.mo +0 -0
  316. data/samples/locale/sr/LC_MESSAGES/hello2.mo +0 -0
  317. data/samples/locale/sr/LC_MESSAGES/hello_glade2.mo +0 -0
  318. data/samples/locale/sr/LC_MESSAGES/hello_gtk2.mo +0 -0
  319. data/samples/locale/sr/LC_MESSAGES/hello_gtk_builder.mo +0 -0
  320. data/samples/locale/sr/LC_MESSAGES/hello_noop.mo +0 -0
  321. data/samples/locale/sr/LC_MESSAGES/hello_plural.mo +0 -0
  322. data/samples/locale/sr/LC_MESSAGES/hello_tk.mo +0 -0
  323. data/samples/locale/sv/LC_MESSAGES/hello.mo +0 -0
  324. data/samples/locale/sv/LC_MESSAGES/hello2.mo +0 -0
  325. data/samples/locale/sv/LC_MESSAGES/hello_glade2.mo +0 -0
  326. data/samples/locale/sv/LC_MESSAGES/hello_gtk2.mo +0 -0
  327. data/samples/locale/sv/LC_MESSAGES/hello_gtk_builder.mo +0 -0
  328. data/samples/locale/sv/LC_MESSAGES/hello_noop.mo +0 -0
  329. data/samples/locale/sv/LC_MESSAGES/hello_plural.mo +0 -0
  330. data/samples/locale/sv/LC_MESSAGES/hello_tk.mo +0 -0
  331. data/samples/locale/uk/LC_MESSAGES/hello.mo +0 -0
  332. data/samples/locale/uk/LC_MESSAGES/hello2.mo +0 -0
  333. data/samples/locale/uk/LC_MESSAGES/hello_glade2.mo +0 -0
  334. data/samples/locale/uk/LC_MESSAGES/hello_gtk2.mo +0 -0
  335. data/samples/locale/uk/LC_MESSAGES/hello_gtk_builder.mo +0 -0
  336. data/samples/locale/uk/LC_MESSAGES/hello_noop.mo +0 -0
  337. data/samples/locale/uk/LC_MESSAGES/hello_plural.mo +0 -0
  338. data/samples/locale/uk/LC_MESSAGES/hello_tk.mo +0 -0
  339. data/samples/locale/vi/LC_MESSAGES/hello.mo +0 -0
  340. data/samples/locale/vi/LC_MESSAGES/hello2.mo +0 -0
  341. data/samples/locale/vi/LC_MESSAGES/hello_glade2.mo +0 -0
  342. data/samples/locale/vi/LC_MESSAGES/hello_gtk2.mo +0 -0
  343. data/samples/locale/vi/LC_MESSAGES/hello_gtk_builder.mo +0 -0
  344. data/samples/locale/vi/LC_MESSAGES/hello_noop.mo +0 -0
  345. data/samples/locale/vi/LC_MESSAGES/hello_plural.mo +0 -0
  346. data/samples/locale/vi/LC_MESSAGES/hello_tk.mo +0 -0
  347. data/samples/locale/zh/LC_MESSAGES/hello.mo +0 -0
  348. data/samples/locale/zh/LC_MESSAGES/hello2.mo +0 -0
  349. data/samples/locale/zh/LC_MESSAGES/hello_glade2.mo +0 -0
  350. data/samples/locale/zh/LC_MESSAGES/hello_gtk2.mo +0 -0
  351. data/samples/locale/zh/LC_MESSAGES/hello_gtk_builder.mo +0 -0
  352. data/samples/locale/zh/LC_MESSAGES/hello_noop.mo +0 -0
  353. data/samples/locale/zh/LC_MESSAGES/hello_plural.mo +0 -0
  354. data/samples/locale/zh/LC_MESSAGES/hello_tk.mo +0 -0
  355. data/samples/locale/zh_TW/LC_MESSAGES/hello.mo +0 -0
  356. data/samples/locale/zh_TW/LC_MESSAGES/hello2.mo +0 -0
  357. data/samples/locale/zh_TW/LC_MESSAGES/hello_glade2.mo +0 -0
  358. data/samples/locale/zh_TW/LC_MESSAGES/hello_gtk2.mo +0 -0
  359. data/samples/locale/zh_TW/LC_MESSAGES/hello_gtk_builder.mo +0 -0
  360. data/samples/locale/zh_TW/LC_MESSAGES/hello_noop.mo +0 -0
  361. data/samples/locale/zh_TW/LC_MESSAGES/hello_plural.mo +0 -0
  362. data/samples/locale/zh_TW/LC_MESSAGES/hello_tk.mo +0 -0
  363. data/samples/po/bg/hello_gtk_builder.po +19 -0
  364. data/samples/po/bs/hello_gtk_builder.po +19 -0
  365. data/samples/po/ca/hello_gtk_builder.po +19 -0
  366. data/samples/po/cs/hello_gtk_builder.po +19 -0
  367. data/samples/po/de/hello_gtk_builder.po +19 -0
  368. data/samples/po/el/hello_gtk_builder.po +19 -0
  369. data/samples/po/eo/hello_gtk_builder.po +19 -0
  370. data/samples/po/es/hello_gtk_builder.po +19 -0
  371. data/samples/po/fr/hello_gtk_builder.po +19 -0
  372. data/samples/po/hello.pot +24 -0
  373. data/samples/po/hello2.pot +33 -0
  374. data/samples/po/hello_glade2.pot +31 -0
  375. data/samples/po/hello_gtk2.pot +23 -0
  376. data/samples/po/hello_gtk_builder.pot +20 -0
  377. data/samples/po/hello_noop.pot +27 -0
  378. data/samples/po/hello_plural.pot +27 -0
  379. data/samples/po/hello_tk.pot +23 -0
  380. data/samples/po/hr/hello_gtk_builder.po +19 -0
  381. data/samples/po/hu/hello_gtk_builder.po +19 -0
  382. data/samples/po/it/hello_gtk_builder.po +19 -0
  383. data/samples/po/ja/hello_gtk_builder.po +19 -0
  384. data/samples/po/ko/hello_gtk_builder.po +19 -0
  385. data/samples/po/lv/hello_gtk_builder.po +19 -0
  386. data/samples/po/nb/hello_gtk_builder.po +19 -0
  387. data/samples/po/nl/hello_gtk_builder.po +19 -0
  388. data/samples/po/pt_BR/hello_gtk_builder.po +19 -0
  389. data/samples/po/ru/hello_gtk_builder.po +19 -0
  390. data/samples/po/sr/hello_gtk_builder.po +19 -0
  391. data/samples/po/sv/hello_gtk_builder.po +19 -0
  392. data/samples/po/uk/hello_gtk_builder.po +19 -0
  393. data/samples/po/vi/hello_gtk_builder.po +19 -0
  394. data/samples/po/zh/hello_gtk_builder.po +19 -0
  395. data/samples/po/zh_TW/hello_gtk_builder.po +19 -0
  396. data/src/po_parser.ry +25 -25
  397. data/test/locale/cr/LC_MESSAGES/plural.mo +0 -0
  398. data/test/locale/da/LC_MESSAGES/plural.mo +0 -0
  399. data/test/locale/da/LC_MESSAGES/plural_error.mo +0 -0
  400. data/test/locale/fr/LC_MESSAGES/plural.mo +0 -0
  401. data/test/locale/fr/LC_MESSAGES/plural_error.mo +0 -0
  402. data/test/locale/fr/LC_MESSAGES/test1.mo +0 -0
  403. data/test/locale/fr/LC_MESSAGES/test2.mo +0 -0
  404. data/test/locale/ir/LC_MESSAGES/plural.mo +0 -0
  405. data/test/locale/ja/LC_MESSAGES/_.mo +0 -0
  406. data/test/locale/ja/LC_MESSAGES/backslash.mo +0 -0
  407. data/test/locale/ja/LC_MESSAGES/non_ascii.mo +0 -0
  408. data/test/locale/ja/LC_MESSAGES/np_.mo +0 -0
  409. data/test/locale/ja/LC_MESSAGES/ns_.mo +0 -0
  410. data/test/locale/ja/LC_MESSAGES/p_.mo +0 -0
  411. data/test/locale/ja/LC_MESSAGES/plural.mo +0 -0
  412. data/test/locale/ja/LC_MESSAGES/plural_error.mo +0 -0
  413. data/test/locale/ja/LC_MESSAGES/rubyparser.mo +0 -0
  414. data/test/locale/ja/LC_MESSAGES/s_.mo +0 -0
  415. data/test/locale/ja/LC_MESSAGES/test1.mo +0 -0
  416. data/test/locale/ja/LC_MESSAGES/test2.mo +0 -0
  417. data/test/locale/ja/LC_MESSAGES/test3.mo +0 -0
  418. data/test/locale/ja/LC_MESSAGES/untranslated.mo +0 -0
  419. data/test/locale/la/LC_MESSAGES/plural.mo +0 -0
  420. data/test/locale/la/LC_MESSAGES/plural_error.mo +0 -0
  421. data/test/locale/li/LC_MESSAGES/plural.mo +0 -0
  422. data/test/locale/li/LC_MESSAGES/plural_error.mo +0 -0
  423. data/test/locale/po/LC_MESSAGES/plural.mo +0 -0
  424. data/test/locale/sl/LC_MESSAGES/plural.mo +0 -0
  425. data/test/po/_.pot +162 -0
  426. data/test/po/backslash.pot +23 -0
  427. data/test/po/non_ascii.pot +23 -0
  428. data/test/po/np_.pot +48 -0
  429. data/test/po/ns_.pot +73 -0
  430. data/test/po/p_.pot +50 -0
  431. data/test/po/s_.pot +55 -0
  432. data/test/po/untranslated.pot +23 -0
  433. data/test/test_locale_path.rb +25 -3
  434. data/test/{tools/test_po.rb → test_po.rb} +217 -210
  435. data/test/test_po_entry.rb +107 -53
  436. data/test/test_text_domain.rb +38 -0
  437. data/test/tools/test_msgmerge.rb +206 -5
  438. data/test/tools/test_task.rb +287 -0
  439. data/test/tools/test_xgettext.rb +3 -1
  440. metadata +373 -4
  441. data/samples/cgi/Rakefile +0 -27
data/Rakefile CHANGED
@@ -83,18 +83,21 @@ namespace :test do
83
83
  end
84
84
 
85
85
  xgettext_options = ["--add-comments=TRANSLATORS:"]
86
- GetText::Tools::Task.new(spec) do |task|
86
+ GetText::Tools::Task.define do |task|
87
+ task.spec = spec
87
88
  task.xgettext_options.concat(xgettext_options)
88
89
  end
89
90
 
90
91
  Dir.glob("samples/*.rb") do |target|
91
92
  domain = File.basename(target, ".*")
92
- GetText::Tools::Task.new(spec) do |task|
93
+ GetText::Tools::Task.define do |task|
94
+ task.package_name = domain
95
+ task.package_version = spec.version.to_s
93
96
  task.xgettext_options.concat(xgettext_options)
94
97
  task.domain = domain
95
98
  task.namespace_prefix = "samples:#{domain}"
96
99
  task.po_base_directory = "samples/po"
97
- task.mo_base_directory = "samples"
100
+ task.mo_base_directory = "samples/locale"
98
101
  task.files = Dir.glob(target.gsub(/\..*\z/, ".*"))
99
102
  end
100
103
  task "samples:gettext" => "samples:#{domain}:gettext"
@@ -108,12 +111,14 @@ task "samples:gettext"
108
111
  ["helloerb2", Dir.glob("samples/cgi/helloerb2.cgi")],
109
112
  ["hellolib", Dir.glob("samples/cgi/hellolib.rb")],
110
113
  ].each do |domain, files|
111
- GetText::Tools::Task.new(spec) do |task|
114
+ GetText::Tools::Task.define do |task|
115
+ task.package_name = domain
116
+ task.package_version = spec.version.to_s
112
117
  task.xgettext_options.concat(xgettext_options)
113
118
  task.domain = domain
114
119
  task.namespace_prefix = "samples:cgi:#{domain}"
115
120
  task.po_base_directory = "samples/cgi/po"
116
- task.mo_base_directory = "samples/cgi"
121
+ task.mo_base_directory = "samples/cgi/locale"
117
122
  task.files = files
118
123
  end
119
124
  task "samples:cgi:gettext" => "samples:cgi:#{domain}:gettext"
@@ -124,12 +129,14 @@ task "samples:cgi:gettext"
124
129
  task "samples:gettext" => "samples:cgi:gettext"
125
130
 
126
131
  ["untranslated", "backslash", "non_ascii", "np_", "p_"].each do |domain|
127
- GetText::Tools::Task.new(spec) do |task|
132
+ GetText::Tools::Task.define do |task|
133
+ task.package_name = domain
134
+ task.package_version = spec.version.to_s
128
135
  task.xgettext_options.concat(xgettext_options)
129
136
  task.domain = domain
130
137
  task.namespace_prefix = "test:#{domain}"
131
138
  task.po_base_directory = "test/po"
132
- task.mo_base_directory = "test"
139
+ task.mo_base_directory = "test/locale"
133
140
  task.files = ["test/fixtures/#{domain}.rb"]
134
141
  task.locales = ["ja"]
135
142
  end
@@ -137,12 +144,14 @@ task "samples:gettext" => "samples:cgi:gettext"
137
144
  end
138
145
 
139
146
  ["_", "s_", "ns_"].each do |domain|
140
- GetText::Tools::Task.new(spec) do |task|
147
+ GetText::Tools::Task.define do |task|
148
+ task.package_name = domain
149
+ task.package_version = spec.version.to_s
141
150
  task.xgettext_options.concat(xgettext_options)
142
151
  task.domain = domain
143
152
  task.namespace_prefix = "test:#{domain}"
144
153
  task.po_base_directory = "test/po"
145
- task.mo_base_directory = "test"
154
+ task.mo_base_directory = "test/locale"
146
155
  task.files = ["test/fixtures/#{domain}.rb"]
147
156
  task.files += Dir.glob("test/fixtures/#{domain}/*.rb")
148
157
  task.locales = ["ja"]
@@ -154,13 +163,15 @@ po_only_domains = [
154
163
  "plural", "plural_error", "rubyparser", "test1", "test2", "test3"
155
164
  ]
156
165
  po_only_domains.each do |domain|
157
- GetText::Tools::Task.new(spec) do |task|
166
+ GetText::Tools::Task.define do |task|
167
+ task.package_name = domain
168
+ task.package_version = spec.version.to_s
158
169
  task.xgettext_options.concat(xgettext_options)
159
170
  task.domain = domain
160
171
  task.namespace_prefix = "test:#{domain}"
161
172
  task.po_base_directory = "test/po"
162
- task.mo_base_directory = "test"
163
- task.files = []
173
+ task.mo_base_directory = "test/locale"
174
+ task.enable_po = false
164
175
  task.locales = Dir.glob("test/po/*/#{domain}.po").collect do |po|
165
176
  File.basename(File.dirname(po))
166
177
  end
data/doc/text/news.md CHANGED
@@ -1,5 +1,36 @@
1
1
  # News
2
2
 
3
+ ## <a id="3-0-1">3.0.1</a>: 2013-09-20
4
+
5
+ ### Improvements
6
+
7
+ * Removed an unused file. [GitHub#19] [Reported by Ladislav Slezák]
8
+ * msginit: Added full user name guessing by /etc/passwd.
9
+ * incompatible: {GetText::Tools::Task} no longer require spec.
10
+ * Added {GetText::Tools::Task.define}. It is the recommended API
11
+ rather than {GetText::Tools::Task.new}.
12
+ * Supported "utf8" as a valid charset.
13
+ [GitHub#20][Reported by Antonio Terceiro]
14
+ * Added {GetText::Tools::Task#enable_description=}.
15
+ * Added {GetText::Tools::Task#enable_description?}.
16
+ * Added {GetText::Tools::Task#enable_po=}.
17
+ * Added {GetText::Tools::Task#enable_po?}.
18
+ * Added {GetText::Tools::Task#msgmerge_options=}.
19
+ * Added {GetText::Tools::Task#msgmerge_options}.
20
+ * task: Added `gettext:po:add[LOCALE]` task.
21
+ * msgmerge: add `--sort-output` option.
22
+ * msgmerge: add `--sort-by-file` option.
23
+ * msgmerge: add `--sort-by-msgid` option.
24
+ * msgmerge: add `--no-location` option.
25
+ * msgmerge: add `--width` option.
26
+ * msgmerge: add `--no-wrap` option.
27
+ * msgmerge: add `--update` option.
28
+
29
+ ### Thanks
30
+
31
+ * Ladislav Slezák
32
+ * Antonio Terceiro
33
+
3
34
  ## <a id="3-0-0">3.0.0</a>: 2013-08-31
4
35
 
5
36
  This is a new major version up release!
data/lib/gettext/po.rb CHANGED
@@ -183,36 +183,39 @@ module GetText
183
183
  # them.
184
184
  # @see http://www.gnu.org/software/gettext/manual/html_node/PO-Files.html#PO-Files
185
185
  # The description for Format of PO in GNU gettext manual
186
+ # @param (see POEntry#to_s)
186
187
  # @return [String] Formatted and joined PO entries. It is used for
187
188
  # creating .po files.
188
- def to_s
189
+ def to_s(options={})
189
190
  po_string = ""
190
191
 
191
192
  header_entry = @entries[[nil, ""]]
192
- po_string << header_entry.to_s unless header_entry.nil?
193
+ po_string << header_entry.to_s(options) unless header_entry.nil?
193
194
 
194
195
  content_entries = @entries.reject do |(_, msgid), _|
195
196
  msgid == :last or msgid.empty?
196
197
  end
197
198
 
198
- sort_by_order(content_entries).each do |msgid, entry|
199
- po_string << "\n" << entry.to_s
199
+ sort(content_entries).each do |msgid, entry|
200
+ po_string << "\n" unless po_string.empty?
201
+ po_string << entry.to_s(options)
200
202
  end
201
203
 
202
204
  if @entries.has_key?([nil, :last])
203
- po_string << "\n" << @entries[[nil, :last]].to_s
205
+ po_string << "\n" unless po_string.empty?
206
+ po_string << @entries[[nil, :last]].to_s(options)
204
207
  end
205
208
 
206
209
  po_string
207
210
  end
208
211
 
209
212
  private
210
- def sort_by_order(entries)
213
+ def sort(entries)
211
214
  case @order
212
215
  when :references
213
216
  sorted_entries = sort_by_references(entries)
214
217
  when :msgid
215
- # TODO: sort by msgid alphabetically.
218
+ sorted_entries = sort_by_msgid(entries)
216
219
  else
217
220
  sorted_entries = entries.to_a
218
221
  end
@@ -252,5 +255,12 @@ module GetText
252
255
  [reference, -1]
253
256
  end
254
257
  end
258
+
259
+ def sort_by_msgid(entries)
260
+ entries.sort_by do |msgid_entry|
261
+ # msgid_entry = [[msgctxt, msgid], POEntry]
262
+ msgid_entry[0]
263
+ end
264
+ end
255
265
  end
256
266
  end
@@ -1,6 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  #
3
- # Copyright (C) 2012 Kouhei Sutou <kou@clear-code.com>
3
+ # Copyright (C) 2012-2013 Kouhei Sutou <kou@clear-code.com>
4
4
  # Copyright (C) 2010 masone (Christian Felder) <ema@rh-productions.ch>
5
5
  # Copyright (C) 2009 Masao Mutoh
6
6
  #
@@ -19,6 +19,8 @@
19
19
  # You should have received a copy of the GNU Lesser General Public License
20
20
  # along with this program. If not, see <http://www.gnu.org/licenses/>.
21
21
 
22
+ require "gettext/po_format"
23
+
22
24
  module GetText
23
25
  class ParseError < StandardError
24
26
  end
@@ -45,40 +47,6 @@ module GetText
45
47
  :msgctxt_plural => [:msgctxt, :msgid, :msgid_plural, :msgstr]
46
48
  }
47
49
 
48
- TRANSLATOR_COMMENT_MARK = "# "
49
- EXTRACTED_COMMENT_MARK = "#."
50
- FLAG_MARK = "#,"
51
- PREVIOUS_COMMENT_MARK = "#|"
52
- REFERENCE_COMMENT_MARK = "#:"
53
-
54
- class << self
55
- def escape(string)
56
- string.gsub(/([\\"\t\n])/) do
57
- special_character = $1
58
- case special_character
59
- when "\t"
60
- "\\t"
61
- when "\n"
62
- "\\n"
63
- else
64
- "\\#{special_character}"
65
- end
66
- end
67
- end
68
- end
69
-
70
- @@max_line_length = 70
71
-
72
- # Sets the max line length.
73
- def self.max_line_length=(len)
74
- @@max_line_length = len
75
- end
76
-
77
- # Gets the max line length.
78
- def self.max_line_length
79
- @@max_line_length
80
- end
81
-
82
50
  # Required
83
51
  attr_reader :type # :normal, :plural, :msgctxt, :msgctxt_plural
84
52
  attr_accessor :msgid
@@ -110,19 +78,13 @@ module GetText
110
78
 
111
79
  # Support for extracted comments. Explanation s.
112
80
  # http://www.gnu.org/software/gettext/manual/gettext.html#Names
81
+ # @return [void]
113
82
  def add_comment(new_comment)
114
83
  if (new_comment and ! new_comment.empty?)
115
84
  @extracted_comment ||= ""
116
85
  @extracted_comment << "\n" unless @extracted_comment.empty?
117
86
  @extracted_comment << new_comment
118
87
  end
119
- to_s
120
- end
121
-
122
- # Returns a parameter representation suitable for po-files
123
- # and other purposes.
124
- def escaped(param_name)
125
- escape(send(param_name))
126
88
  end
127
89
 
128
90
  # Checks if the self has same attributes as other.
@@ -161,17 +123,20 @@ module GetText
161
123
  # with the plural wins.
162
124
  def merge(other)
163
125
  return self unless other
164
- raise ParseError, "Translation targets do not match: \n" \
165
- " self: #{self.inspect}\n other: '#{other.inspect}'" unless self.mergeable?(other)
166
- if other.msgid_plural && !self.msgid_plural
126
+ unless mergeable?(other)
127
+ message = "Translation targets do not match: \n" +
128
+ " self: #{self.inspect}\n other: '#{other.inspect}'"
129
+ raise ParseError, message
130
+ end
131
+ if other.msgid_plural && !msgid_plural
167
132
  res = other
168
- unless (res.references.include? self.references[0])
169
- res.references += self.references
170
- res.add_comment(self.extracted_comment)
133
+ unless res.references.include?(references[0])
134
+ res.references += references
135
+ res.add_comment(extracted_comment)
171
136
  end
172
137
  else
173
138
  res = self
174
- unless (res.references.include? other.references[0])
139
+ unless res.references.include?(other.references[0])
175
140
  res.references += other.references
176
141
  res.add_comment(other.extracted_comment)
177
142
  end
@@ -179,204 +144,243 @@ module GetText
179
144
  res
180
145
  end
181
146
 
182
- # Output the po entry for the po-file.
183
- def to_s
147
+ # Format the po entry in PO format.
148
+ #
149
+ # @param [Hash] options
150
+ # @option options (see Formatter#initialize)
151
+ def to_s(options={})
184
152
  raise(NoMsgidError, "msgid is nil.") unless @msgid
185
153
 
186
- str = ""
187
- # extracted comments
188
- if @msgid == :last
189
- return format_obsolete_comment(comment)
190
- end
154
+ formatter = Formatter.new(self, options)
155
+ formatter.format
156
+ end
157
+
158
+ # Returns true if the type is kind of msgctxt.
159
+ def msgctxt?
160
+ [:msgctxt, :msgctxt_plural].include?(@type)
161
+ end
162
+
163
+ # Returns true if the type is kind of plural.
164
+ def plural?
165
+ [:plural, :msgctxt_plural].include?(@type)
166
+ end
167
+
168
+ def [](number)
169
+ param = @param_type[number]
170
+ raise ParseError, 'no more string parameters expected' unless param
171
+ send param
172
+ end
173
+
174
+ private
175
+
176
+ # sets or extends the value of a translation target params like msgid,
177
+ # msgctxt etc.
178
+ # param is symbol with the name of param
179
+ # value - new value
180
+ def set_value(param, value)
181
+ send "#{param}=", (send(param) || '') + value
182
+ end
191
183
 
192
- str << format_translator_comment
193
- str << format_extracted_comment
194
- str << format_reference_comment
195
- str << format_flag_comment
196
- str << format_previous_comment
197
-
198
- # msgctxt, msgid, msgstr
199
- if msgctxt?
200
- if @msgctxt.nil?
201
- no_msgctxt_message = "This POEntry is a kind of msgctxt " +
202
- "but the msgctxt property is nil. " +
203
- "msgid: #{msgid}"
204
- raise(NoMsgctxtError, no_msgctxt_message)
184
+ class Formatter
185
+ class << self
186
+ def escape(string)
187
+ return "" if string.nil?
188
+
189
+ string.gsub(/([\\"\t\n])/) do
190
+ special_character = $1
191
+ case special_character
192
+ when "\t"
193
+ "\\t"
194
+ when "\n"
195
+ "\\n"
196
+ else
197
+ "\\#{special_character}"
198
+ end
199
+ end
205
200
  end
206
- str << "msgctxt " << format_message(msgctxt)
207
201
  end
208
202
 
209
- str << "msgid " << format_message(msgid)
210
- if plural?
211
- if @msgid_plural.nil?
212
- no_plural_message = "This POEntry is a kind of plural " +
213
- "but the msgid_plural property is nil. " +
214
- "msgid: #{msgid}"
215
- raise(NoMsgidPluralError, no_plural_message)
216
- end
203
+ include POFormat
204
+
205
+ DEFAULT_MAX_LINE_WIDTH = 78
206
+
207
+ # @param [POEntry] entry The entry to be formatted.
208
+ # @param [Hash] options
209
+ # @option options [Bool] :include_reference_comment (true)
210
+ # Includes reference comments in formatted string if true.
211
+ # @option options [Integer] :max_line_width (78)
212
+ # Wraps long lines that is longer than the `:max_line_width`.
213
+ # Don't break long lines if `:max_line_width` is less than 0
214
+ # such as `-1`.
215
+ def initialize(entry, options={})
216
+ @entry = entry
217
+ @options = fill_default_option_values(options)
218
+ end
217
219
 
218
- str << "msgid_plural " << format_message(msgid_plural)
220
+ def format
221
+ # extracted comments
222
+ if @entry.msgid == :last
223
+ return format_obsolete_comment(@entry.comment)
224
+ end
219
225
 
220
- if msgstr.nil?
221
- str << "msgstr[0] \"\"\n"
222
- str << "msgstr[1] \"\"\n"
223
- else
224
- msgstrs = msgstr.split("\000", -1)
225
- msgstrs.each_with_index do |msgstr, index|
226
- str << "msgstr[#{index}] " << format_message(msgstr)
226
+ str = ""
227
+ str << format_translator_comment
228
+ str << format_extracted_comment
229
+ if @options[:include_reference_comment]
230
+ str << format_reference_comment
231
+ end
232
+ str << format_flag_comment
233
+ str << format_previous_comment
234
+
235
+ # msgctxt, msgid, msgstr
236
+ if @entry.msgctxt?
237
+ if @entry.msgctxt.nil?
238
+ no_msgctxt_message = "This POEntry is a kind of msgctxt " +
239
+ "but the msgctxt property is nil. " +
240
+ "msgid: #{@entry.msgid}"
241
+ raise(NoMsgctxtError, no_msgctxt_message)
227
242
  end
243
+ str << "msgctxt " << format_message(@entry.msgctxt)
228
244
  end
229
- else
230
- str << "msgstr "
231
- str << format_message(msgstr)
232
- end
233
- str
234
- end
235
245
 
236
- def format_translator_comment
237
- format_comment("#", translator_comment)
238
- end
246
+ str << "msgid " << format_message(@entry.msgid)
247
+ if @entry.plural?
248
+ if @entry.msgid_plural.nil?
249
+ no_plural_message = "This POEntry is a kind of plural " +
250
+ "but the msgid_plural property is nil. " +
251
+ "msgid: #{@entry.msgid}"
252
+ raise(NoMsgidPluralError, no_plural_message)
253
+ end
239
254
 
240
- def format_extracted_comment
241
- format_comment(EXTRACTED_COMMENT_MARK, extracted_comment)
242
- end
255
+ str << "msgid_plural " << format_message(@entry.msgid_plural)
243
256
 
244
- def format_reference_comment
245
- max_line_length = 70
246
- formatted_reference = ""
247
- if not references.nil? and not references.empty?
248
- formatted_reference << REFERENCE_COMMENT_MARK
249
- line_size = 2
250
- references.each do |reference|
251
- if line_size + reference.size > max_line_length
252
- formatted_reference << "\n"
253
- formatted_reference << "#{REFERENCE_COMMENT_MARK} #{reference}"
254
- line_size = 3 + reference.size
257
+ if @entry.msgstr.nil?
258
+ str << "msgstr[0] \"\"\n"
259
+ str << "msgstr[1] \"\"\n"
255
260
  else
256
- formatted_reference << " #{reference}"
257
- line_size += 1 + reference.size
261
+ msgstrs = @entry.msgstr.split("\000", -1)
262
+ msgstrs.each_with_index do |msgstr, index|
263
+ str << "msgstr[#{index}] " << format_message(msgstr)
264
+ end
258
265
  end
266
+ else
267
+ str << "msgstr "
268
+ str << format_message(@entry.msgstr)
259
269
  end
270
+ str
271
+ end
260
272
 
261
- formatted_reference << "\n"
273
+ private
274
+ def fill_default_option_values(options)
275
+ options = options.dup
276
+ if options[:include_reference_comment].nil?
277
+ options[:include_reference_comment] = true
278
+ end
279
+ options[:max_line_width] ||= DEFAULT_MAX_LINE_WIDTH
280
+ options
262
281
  end
263
- formatted_reference
264
- end
265
282
 
266
- def format_flag_comment
267
- format_comment(FLAG_MARK, flag)
268
- end
283
+ def format_translator_comment
284
+ format_comment("#", @entry.translator_comment)
285
+ end
269
286
 
270
- def format_previous_comment
271
- format_comment(PREVIOUS_COMMENT_MARK, previous)
272
- end
287
+ def format_extracted_comment
288
+ format_comment(EXTRACTED_COMMENT_MARK, @entry.extracted_comment)
289
+ end
273
290
 
274
- def format_comment(mark, comment)
275
- return "" if comment.nil?
291
+ def format_reference_comment
292
+ max_line_width = @options[:max_line_width]
293
+ formatted_reference = ""
294
+ if not @entry.references.nil? and not @entry.references.empty?
295
+ formatted_reference << REFERENCE_COMMENT_MARK
296
+ line_width = 2
297
+ @entry.references.each do |reference|
298
+ if max_line_width > 0 and
299
+ line_width + reference.size > max_line_width
300
+ formatted_reference << "\n"
301
+ formatted_reference << "#{REFERENCE_COMMENT_MARK} #{reference}"
302
+ line_width = 3 + reference.size
303
+ else
304
+ formatted_reference << " #{reference}"
305
+ line_width += 1 + reference.size
306
+ end
307
+ end
276
308
 
277
- formatted_comment = ""
278
- comment.each_line do |comment_line|
279
- if comment_line == "\n"
280
- formatted_comment << "#{mark}\n"
281
- else
282
- formatted_comment << "#{mark} #{comment_line.strip}\n"
309
+ formatted_reference << "\n"
283
310
  end
311
+ formatted_reference
284
312
  end
285
- formatted_comment
286
- end
287
313
 
288
- def format_obsolete_comment(comment)
289
- mark = "#~"
290
- return "" if comment.nil?
314
+ def format_flag_comment
315
+ format_comment(FLAG_MARK, @entry.flag)
316
+ end
291
317
 
292
- formatted_comment = ""
293
- comment.each_line do |comment_line|
294
- if /\A#[^~]/ =~ comment_line or comment_line.start_with?(mark)
295
- formatted_comment << comment_line
296
- elsif comment_line == "\n"
297
- formatted_comment << "\n"
298
- else
299
- formatted_comment << "#{mark} #{comment_line.strip}\n"
318
+ def format_previous_comment
319
+ format_comment(PREVIOUS_COMMENT_MARK, @entry.previous)
320
+ end
321
+
322
+ def format_comment(mark, comment)
323
+ return "" if comment.nil?
324
+
325
+ formatted_comment = ""
326
+ comment.each_line do |comment_line|
327
+ if comment_line == "\n"
328
+ formatted_comment << "#{mark}\n"
329
+ else
330
+ formatted_comment << "#{mark} #{comment_line.strip}\n"
331
+ end
300
332
  end
333
+ formatted_comment
301
334
  end
302
- formatted_comment
303
- end
304
335
 
305
- def format_message(message)
306
- formatted_message = ""
307
- if not message.nil? and message.include?("\n")
308
- formatted_message << "\"\"\n"
309
- message.each_line.each do |line|
310
- formatted_message << "\"#{escape(line)}\"\n"
336
+ def format_obsolete_comment(comment)
337
+ mark = "#~"
338
+ return "" if comment.nil?
339
+
340
+ formatted_comment = ""
341
+ comment.each_line do |comment_line|
342
+ if /\A#[^~]/ =~ comment_line or comment_line.start_with?(mark)
343
+ formatted_comment << comment_line
344
+ elsif comment_line == "\n"
345
+ formatted_comment << "\n"
346
+ else
347
+ formatted_comment << "#{mark} #{comment_line.strip}\n"
348
+ end
311
349
  end
312
- else
313
- formatted_message << "\"#{escape(message)}\"\n"
350
+ formatted_comment
314
351
  end
315
- formatted_message
316
- end
317
352
 
318
- # Returns true if the type is kind of msgctxt.
319
- def msgctxt?
320
- [:msgctxt, :msgctxt_plural].include?(@type)
321
- end
353
+ def format_message(message)
354
+ return "\"\"\n" if message.nil?
322
355
 
323
- # Returns true if the type is kind of plural.
324
- def plural?
325
- [:plural, :msgctxt_plural].include?(@type)
326
- end
356
+ chunks = wrap_message(message)
357
+ formatted_message = ""
358
+ formatted_message << "\"\"\n" if chunks.size > 1
359
+ chunks.each do |chunk|
360
+ formatted_message << "\"#{escape(chunk)}\"\n"
361
+ end
362
+ formatted_message
363
+ end
327
364
 
328
- private
365
+ def escape(string)
366
+ self.class.escape(string)
367
+ end
329
368
 
330
- # sets or extends the value of a translation target params like msgid,
331
- # msgctxt etc.
332
- # param is symbol with the name of param
333
- # value - new value
334
- def set_value(param, value)
335
- send "#{param}=", (send(param) || '') + value
336
- end
369
+ def wrap_message(message)
370
+ return [message] if message.empty?
337
371
 
338
- def escape(value)
339
- self.class.escape((value || "").gsub(/\r/, ""))
340
- end
372
+ max_line_width = @options[:max_line_width]
373
+ return [message] if max_line_width <= 0
341
374
 
342
- public
343
- # For backward comatibility. This doesn't support "comment".
344
- # ary = [msgid1, "file1:line1", "file2:line"]
345
- def self.new_from_ary(ary)
346
- ary = ary.dup
347
- msgid = ary.shift
348
- references = ary
349
- type = :normal
350
- msgctxt = nil
351
- msgid_plural = nil
352
-
353
- if msgid.include? "\004"
354
- msgctxt, msgid = msgid.split(/\004/)
355
- type = :msgctxt
356
- end
357
- if msgid.include? "\000"
358
- ids = msgid.split(/\000/)
359
- msgid = ids[0]
360
- msgid_plural = ids[1]
361
- if type == :msgctxt
362
- type = :msgctxt_plural
363
- else
364
- type = :plural
375
+ chunks = []
376
+ message.each_line do |line|
377
+ # TODO: use character width instead of the number of characters
378
+ line.scan(/.{1,#{max_line_width}}/m) do |chunk|
379
+ chunks << chunk
380
+ end
365
381
  end
382
+ chunks
366
383
  end
367
- ret = self.new(type)
368
- ret.msgid = msgid
369
- ret.references = references
370
- ret.msgctxt = msgctxt
371
- ret.msgid_plural = msgid_plural
372
- ret
373
- end
374
-
375
- def [](number)
376
- param = @param_type[number]
377
- raise ParseError, 'no more string parameters expected' unless param
378
- send param
379
384
  end
380
385
  end
381
-
382
386
  end