gettext 3.0.0 → 3.0.1

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 (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