gettext 3.3.9 → 3.4.9

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 (164) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/Rakefile +1 -3
  4. data/doc/text/news.md +121 -0
  5. data/gettext.gemspec +4 -2
  6. data/lib/gettext/mo.rb +5 -14
  7. data/lib/gettext/po_entry.rb +31 -21
  8. data/lib/gettext/po_parser.rb +65 -59
  9. data/lib/gettext/text_domain_manager.rb +6 -5
  10. data/lib/gettext/tools/msgcat.rb +9 -2
  11. data/lib/gettext/tools/msgmerge.rb +11 -6
  12. data/lib/gettext/tools/parser/erubi.rb +88 -0
  13. data/lib/gettext/tools/task.rb +3 -5
  14. data/lib/gettext/tools/xgettext.rb +15 -4
  15. data/lib/gettext/version.rb +3 -3
  16. data/locale/ja/LC_MESSAGES/gettext.mo +0 -0
  17. data/po/bg/gettext.edit.po +65 -60
  18. data/po/bg/gettext.po +6 -0
  19. data/po/bs/gettext.edit.po +65 -60
  20. data/po/bs/gettext.po +6 -0
  21. data/po/ca/gettext.edit.po +65 -60
  22. data/po/ca/gettext.po +6 -0
  23. data/po/cs/gettext.edit.po +65 -60
  24. data/po/cs/gettext.po +6 -0
  25. data/po/de/gettext.edit.po +65 -60
  26. data/po/de/gettext.po +6 -0
  27. data/po/el/gettext.edit.po +65 -60
  28. data/po/el/gettext.po +6 -0
  29. data/po/eo/gettext.edit.po +65 -60
  30. data/po/eo/gettext.po +6 -0
  31. data/po/es/gettext.edit.po +65 -60
  32. data/po/es/gettext.po +6 -0
  33. data/po/et/gettext.edit.po +65 -60
  34. data/po/et/gettext.po +6 -0
  35. data/po/fr/gettext.edit.po +65 -60
  36. data/po/fr/gettext.po +6 -0
  37. data/po/gettext.pot +77 -68
  38. data/po/hr/gettext.edit.po +65 -60
  39. data/po/hr/gettext.po +6 -0
  40. data/po/hu/gettext.edit.po +65 -60
  41. data/po/hu/gettext.po +6 -0
  42. data/po/it/gettext.edit.po +65 -60
  43. data/po/it/gettext.po +6 -0
  44. data/po/ja/gettext.edit.po +66 -61
  45. data/po/ja/gettext.po +7 -1
  46. data/po/ko/gettext.edit.po +65 -60
  47. data/po/ko/gettext.po +6 -0
  48. data/po/lv/gettext.edit.po +65 -60
  49. data/po/lv/gettext.po +6 -0
  50. data/po/nb/gettext.edit.po +65 -60
  51. data/po/nb/gettext.po +6 -0
  52. data/po/nl/gettext.edit.po +65 -60
  53. data/po/nl/gettext.po +6 -0
  54. data/po/pt_BR/gettext.edit.po +65 -60
  55. data/po/pt_BR/gettext.po +6 -0
  56. data/po/ru/gettext.edit.po +65 -60
  57. data/po/ru/gettext.po +6 -0
  58. data/po/sr/gettext.edit.po +65 -60
  59. data/po/sr/gettext.po +6 -0
  60. data/po/sv/gettext.edit.po +65 -57
  61. data/po/sv/gettext.po +6 -0
  62. data/po/uk/gettext.edit.po +65 -60
  63. data/po/uk/gettext.po +6 -0
  64. data/po/vi/gettext.edit.po +65 -60
  65. data/po/vi/gettext.po +6 -0
  66. data/po/zh/gettext.edit.po +65 -60
  67. data/po/zh/gettext.po +6 -0
  68. data/po/zh_TW/gettext.edit.po +65 -60
  69. data/po/zh_TW/gettext.po +6 -0
  70. data/samples/cgi/po/helloerb1.pot +3 -3
  71. data/samples/cgi/po/helloerb2.pot +3 -3
  72. data/samples/cgi/po/hellolib.pot +3 -3
  73. data/samples/cgi/po/main.pot +3 -3
  74. data/samples/po/bg/hello_gtk_builder.edit.po +15 -0
  75. data/samples/po/bg/hello_gtk_builder.po +12 -0
  76. data/samples/po/bs/hello_gtk_builder.edit.po +15 -0
  77. data/samples/po/bs/hello_gtk_builder.po +12 -0
  78. data/samples/po/ca/hello_gtk_builder.edit.po +15 -0
  79. data/samples/po/ca/hello_gtk_builder.po +12 -0
  80. data/samples/po/cs/hello_gtk_builder.edit.po +15 -0
  81. data/samples/po/cs/hello_gtk_builder.po +12 -0
  82. data/samples/po/de/hello_gtk_builder.edit.po +15 -0
  83. data/samples/po/de/hello_gtk_builder.po +12 -0
  84. data/samples/po/el/hello_gtk_builder.edit.po +15 -0
  85. data/samples/po/el/hello_gtk_builder.po +12 -0
  86. data/samples/po/eo/hello_gtk_builder.edit.po +15 -0
  87. data/samples/po/eo/hello_gtk_builder.po +12 -0
  88. data/samples/po/es/hello_gtk_builder.edit.po +15 -0
  89. data/samples/po/es/hello_gtk_builder.po +12 -0
  90. data/samples/po/fr/hello_gtk_builder.edit.po +15 -0
  91. data/samples/po/fr/hello_gtk_builder.po +12 -0
  92. data/samples/po/hello.pot +3 -3
  93. data/samples/po/hello2.pot +4 -4
  94. data/samples/po/hello_glade2.pot +8 -5
  95. data/samples/po/hello_gtk2.pot +4 -4
  96. data/samples/po/hello_gtk_builder.pot +18 -4
  97. data/samples/po/hello_noop.pot +4 -4
  98. data/samples/po/hello_plural.pot +4 -4
  99. data/samples/po/hello_tk.pot +4 -4
  100. data/samples/po/hr/hello_gtk_builder.edit.po +15 -0
  101. data/samples/po/hr/hello_gtk_builder.po +12 -0
  102. data/samples/po/hu/hello_gtk_builder.edit.po +15 -0
  103. data/samples/po/hu/hello_gtk_builder.po +12 -0
  104. data/samples/po/it/hello_gtk_builder.edit.po +15 -0
  105. data/samples/po/it/hello_gtk_builder.po +12 -0
  106. data/samples/po/ja/hello_gtk_builder.edit.po +15 -0
  107. data/samples/po/ja/hello_gtk_builder.po +12 -0
  108. data/samples/po/ko/hello_gtk_builder.edit.po +15 -0
  109. data/samples/po/ko/hello_gtk_builder.po +12 -0
  110. data/samples/po/lv/hello_gtk_builder.edit.po +15 -0
  111. data/samples/po/lv/hello_gtk_builder.po +12 -0
  112. data/samples/po/nb/hello_gtk_builder.edit.po +15 -0
  113. data/samples/po/nb/hello_gtk_builder.po +12 -0
  114. data/samples/po/nl/hello_gtk_builder.edit.po +15 -0
  115. data/samples/po/nl/hello_gtk_builder.po +12 -0
  116. data/samples/po/pt_BR/hello_gtk_builder.edit.po +15 -0
  117. data/samples/po/pt_BR/hello_gtk_builder.po +12 -0
  118. data/samples/po/ru/hello_gtk_builder.edit.po +15 -0
  119. data/samples/po/ru/hello_gtk_builder.po +12 -0
  120. data/samples/po/sr/hello_gtk_builder.edit.po +15 -0
  121. data/samples/po/sr/hello_gtk_builder.po +12 -0
  122. data/samples/po/sv/hello_gtk_builder.edit.po +15 -0
  123. data/samples/po/sv/hello_gtk_builder.po +12 -0
  124. data/samples/po/uk/hello_gtk_builder.edit.po +15 -0
  125. data/samples/po/uk/hello_gtk_builder.po +12 -0
  126. data/samples/po/vi/hello_gtk_builder.edit.po +15 -0
  127. data/samples/po/vi/hello_gtk_builder.po +12 -0
  128. data/samples/po/zh/hello_gtk_builder.edit.po +15 -0
  129. data/samples/po/zh/hello_gtk_builder.po +12 -0
  130. data/samples/po/zh_TW/hello_gtk_builder.edit.po +15 -0
  131. data/samples/po/zh_TW/hello_gtk_builder.po +12 -0
  132. data/src/po_parser.ry +48 -42
  133. data/test/fixtures/erb/case.rhtml +16 -0
  134. data/test/fixtures/simple.rb +4 -0
  135. data/test/locale/fr/LC_MESSAGES/test1.mo +0 -0
  136. data/test/locale/fr_BE/LC_MESSAGES/test1.mo +0 -0
  137. data/test/locale/fr_BE_Foo/LC_MESSAGES/test1.mo +0 -0
  138. data/test/locale/ja/LC_MESSAGES/_.mo +0 -0
  139. data/test/po/_.pot +3 -3
  140. data/test/po/backslash.pot +6 -4
  141. data/test/po/fr/test1.po +7 -0
  142. data/test/po/fr_BE/test1.po +24 -0
  143. data/test/po/fr_BE_Foo/test1.po +20 -0
  144. data/test/po/hello.pot +3 -3
  145. data/test/po/ja/_.edit.po +3 -3
  146. data/test/po/ja/_.po +15 -0
  147. data/test/po/ja/hello.edit.po +0 -1
  148. data/test/po/non_ascii.pot +4 -4
  149. data/test/po/np_.pot +3 -3
  150. data/test/po/ns_.pot +3 -3
  151. data/test/po/p_.pot +3 -3
  152. data/test/po/s_.pot +3 -3
  153. data/test/po/untranslated.pot +4 -4
  154. data/test/test_gettext.rb +23 -0
  155. data/test/test_locale_path.rb +12 -4
  156. data/test/test_parser.rb +62 -0
  157. data/test/test_po_entry.rb +20 -4
  158. data/test/test_po_parser.rb +44 -1
  159. data/test/tools/test_msgcat.rb +21 -1
  160. data/test/tools/test_msginit.rb +7 -2
  161. data/test/tools/test_msgmerge.rb +41 -3
  162. data/test/tools/test_xgettext.rb +100 -3
  163. metadata +48 -14
  164. data/test/fixtures/gtk_builder_ui_definitions.ui~ +0 -68
@@ -1,15 +1,15 @@
1
1
  # SOME DESCRIPTIVE TITLE.
2
2
  # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
3
- # This file is distributed under the same license as the gettext package.
3
+ # This file is distributed under the same license as the untranslated package.
4
4
  # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
5
5
  #
6
6
  #, fuzzy
7
7
  msgid ""
8
8
  msgstr ""
9
- "Project-Id-Version: gettext 3.0.0\n"
9
+ "Project-Id-Version: untranslated 3.4.4\n"
10
10
  "Report-Msgid-Bugs-To: \n"
11
- "POT-Creation-Date: 2013-08-30 22:00+0900\n"
12
- "PO-Revision-Date: 2013-08-30 22:00+0900\n"
11
+ "POT-Creation-Date: 2023-06-11 06:20+0900\n"
12
+ "PO-Revision-Date: 2023-06-11 06:20+0900\n"
13
13
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14
14
  "Language-Team: LANGUAGE <LL@li.org>\n"
15
15
  "Language: \n"
data/test/test_gettext.rb CHANGED
@@ -59,6 +59,29 @@ class TestGetText < Test::Unit::TestCase
59
59
  assert_equal("nomsgstr", _("nomsgstr"))
60
60
  end
61
61
 
62
+ def test_fallbacks
63
+ bindtextdomain("test1", "locale")
64
+ test = Simple.new
65
+
66
+ # Translation present in all candidates
67
+ GetText.set_current_locale("fr_BE_Foo")
68
+ assert_equal("french-Belgium-Foo", test.test)
69
+ GetText.set_current_locale("fr_BE")
70
+ assert_equal("french-Belgium", test.test)
71
+ GetText.set_current_locale("fr")
72
+ assert_equal("french", test.test)
73
+
74
+ # Translation Missing in fr_BE_Foo (fallback to fr_BE)
75
+ GetText.set_current_locale("fr_BE_Foo")
76
+ assert_equal("FRENCH-BELGIUM:ONE IS 1.", test.test_formatted_string)
77
+
78
+ # Translation Missing in fr_BE_Foo *and* fr_BE (both languages fallback to fr)
79
+ GetText.set_current_locale("fr_BE_Foo")
80
+ assert_equal("FRENCH:Il y a 5 pommes.", test.test_plural)
81
+ GetText.set_current_locale("fr_BE")
82
+ assert_equal("FRENCH:Il y a 5 pommes.", test.test_plural)
83
+ end
84
+
62
85
  def test_empty
63
86
  bindtextdomain("test1", "locale")
64
87
  assert_equal("japanese", gettext("language"))
@@ -53,9 +53,11 @@ class TestLocalePath < Test::Unit::TestCase
53
53
  testdir = File.dirname(File.expand_path(__FILE__))
54
54
  path = GetText::LocalePath.new("test1", "#{testdir}/locale")
55
55
  assert_equal({
56
- "ja" => "#{testdir}/locale/ja/LC_MESSAGES/test1.mo",
57
- "fr" => "#{testdir}/locale/fr/LC_MESSAGES/test1.mo",
58
- "zh_Hant" => "#{testdir}/locale/zh_Hant/LC_MESSAGES/test1.mo"
56
+ "ja" => "#{testdir}/locale/ja/LC_MESSAGES/test1.mo",
57
+ "fr" => "#{testdir}/locale/fr/LC_MESSAGES/test1.mo",
58
+ "fr_BE" => "#{testdir}/locale/fr_BE/LC_MESSAGES/test1.mo",
59
+ "fr_BE_Foo" => "#{testdir}/locale/fr_BE_Foo/LC_MESSAGES/test1.mo",
60
+ "zh_Hant" => "#{testdir}/locale/zh_Hant/LC_MESSAGES/test1.mo"
59
61
  },
60
62
  path.locale_paths)
61
63
  assert_equal("#{testdir}/locale/ja/LC_MESSAGES/test1.mo",
@@ -66,6 +68,12 @@ class TestLocalePath < Test::Unit::TestCase
66
68
  path.current_path(Locale::Tag.parse("ja_JP.UTF-8")))
67
69
  assert_equal(nil,
68
70
  path.current_path(Locale::Tag.parse("en")))
71
+ assert_equal("#{testdir}/locale/fr/LC_MESSAGES/test1.mo",
72
+ path.current_path(Locale::Tag.parse("fr")))
73
+ assert_equal("#{testdir}/locale/fr_BE/LC_MESSAGES/test1.mo",
74
+ path.current_path(Locale::Tag.parse("fr-BE")))
75
+ assert_equal("#{testdir}/locale/fr_BE_Foo/LC_MESSAGES/test1.mo",
76
+ path.current_path(Locale::Tag.parse("fr-BE-Foo")))
69
77
  assert_equal("#{testdir}/locale/zh_Hant/LC_MESSAGES/test1.mo",
70
78
  path.current_path(Locale::Tag.parse("zh-Hant")))
71
79
  end
@@ -73,7 +81,7 @@ class TestLocalePath < Test::Unit::TestCase
73
81
  def test_supported_locales
74
82
  testdir = File.dirname(File.expand_path(__FILE__))
75
83
  path = GetText::LocalePath.new("test1", "#{testdir}/locale")
76
- assert_equal ["fr", "ja", "zh_Hant"], path.supported_locales
84
+ assert_equal ["fr", "fr_BE", "fr_BE_Foo", "ja", "zh_Hant"], path.supported_locales
77
85
 
78
86
  path = GetText::LocalePath.new("plural", "#{testdir}/locale")
79
87
  assert_equal ["cr", "da", "fr", "ir", "ja", "la", "li", "po", "sl"], path.supported_locales
data/test/test_parser.rb CHANGED
@@ -24,6 +24,7 @@
24
24
  require "tempfile"
25
25
  require "gettext/tools/parser/ruby"
26
26
  require "gettext/tools/parser/erb"
27
+ require "gettext/tools/parser/erubi"
27
28
 
28
29
  require "gettext/tools/xgettext"
29
30
 
@@ -215,6 +216,67 @@ class TestGetTextParser < Test::Unit::TestCase
215
216
 
216
217
  assert_target("Hello", ["#{path}:8"])
217
218
  end
219
+
220
+ def test_case
221
+ path = fixture_path("erb", "case.rhtml")
222
+ @ary = GetText::ErbParser.parse(path)
223
+
224
+ if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('3.0.0')
225
+ assert_target("Hello", ["#{path}:11"])
226
+ assert_target("World", ["#{path}:14"])
227
+ else
228
+ assert_target("Hello", ["#{path}:11"])
229
+ assert_nil(@ary.detect {|elem| elem.msgid == 'World'}) # Not detected. see PR #91
230
+ end
231
+ end
232
+ end
233
+
234
+ class TestErubiParser < self
235
+ include Helper::Path
236
+
237
+ def test_detect_encoding
238
+ euc_file = Tempfile.new("euc-jp.rhtml")
239
+ euc_file.open
240
+ euc_file.puts("<%#-*- coding: euc-jp -*-%>")
241
+ euc_file.close
242
+
243
+ euc_file_content = File.read(euc_file.path)
244
+ encoding = GetText::ErubiParser.new(euc_file.path).detect_encoding(euc_file_content)
245
+
246
+ assert_equal("EUC-JP", encoding)
247
+ end
248
+
249
+ def test_ascii
250
+ path = fixture_path("erb", "ascii.rhtml")
251
+ @ary = GetText::ErubiParser.parse(path)
252
+
253
+ assert_target 'aaa', ["#{path}:8"]
254
+ assert_target "aaa\n", ["#{path}:11"]
255
+ assert_target 'bbb', ["#{path}:12"]
256
+ assert_plural_target "ccc1", "ccc2", ["#{path}:13"]
257
+ end
258
+
259
+ def test_non_ascii
260
+ path = fixture_path("erb", "non_ascii.rhtml")
261
+ @ary = GetText::ErubiParser.parse(path)
262
+
263
+ assert_target('わたし', ["#{path}:12"])
264
+ end
265
+
266
+ def test_minus
267
+ path = fixture_path("erb", "minus.rhtml")
268
+ @ary = GetText::ErubiParser.parse(path)
269
+
270
+ assert_target("Hello", ["#{path}:8"])
271
+ end
272
+
273
+ def test_case
274
+ path = fixture_path("erb", "case.rhtml")
275
+ @ary = GetText::ErubiParser.parse(path)
276
+
277
+ assert_target("Hello", ["#{path}:11"])
278
+ assert_target("World", ["#{path}:14"]) # Detected with Erubi
279
+ end
218
280
  end
219
281
 
220
282
  def test_xgettext_parse
@@ -233,13 +233,15 @@ EOE
233
233
  class TestEscape < self
234
234
  def test_normal
235
235
  entry = GetText::POEntry.new(:normal)
236
- entry.msgid = "He said \"hello.\""
237
- entry.msgstr = "Il a dit \"bonjour.\""
236
+ entry.msgid = "He said \"hello.\"\r\n"
237
+ entry.msgstr = "Il a dit \"bonjour.\"\r\n"
238
238
  entry.references = ["file1:1", "file2:10"]
239
239
  expected_po = <<-EOE
240
240
  #: file1:1 file2:10
241
- msgid "He said \\"hello.\\""
242
- msgstr "Il a dit \\"bonjour.\\""
241
+ msgid ""
242
+ "He said \\"hello.\\"\\r\\n"
243
+ msgstr ""
244
+ "Il a dit \\"bonjour.\\"\\r\\n"
243
245
  EOE
244
246
  assert_equal(expected_po, entry.to_s)
245
247
  end
@@ -342,6 +344,20 @@ EOP
342
344
  assert_equal(expected_po, entry.to_s)
343
345
  end
344
346
 
347
+ def test_multiple_flags
348
+ entry = GetText::POEntry.new(:normal)
349
+ entry.msgid = "msgid"
350
+ entry.msgstr = "msgstr"
351
+ entry.flags = ["It's the flag.", "fuzzy"]
352
+
353
+ expected_po = <<-EOP
354
+ #, It's the flag., fuzzy
355
+ msgid "msgid"
356
+ msgstr "msgstr"
357
+ EOP
358
+ assert_equal(expected_po, entry.to_s)
359
+ end
360
+
345
361
  def test_previous
346
362
  entry = GetText::POEntry.new(:normal)
347
363
  entry.msgid = "msgid"
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2012-2020 Sutou Kouhei <kou@clear-code.com>
1
+ # Copyright (C) 2012-2023 Sutou Kouhei <kou@clear-code.com>
2
2
  # Copyright (C) 2012 Haruka Yoshihara <yoshihara@clear-code.com>
3
3
  #
4
4
  # License: Ruby's or LGPL
@@ -62,6 +62,16 @@ EOP
62
62
  class TestPO < self
63
63
  include Helper::Warning
64
64
 
65
+ def test_msgid_escape
66
+ po_file = create_po_file(<<-'EOP')
67
+ msgid "\\\\r \\r \t \r \n"
68
+ msgstr "\\\\r \\r \t \r \n"
69
+ EOP
70
+ entries = parse_po_file(po_file)
71
+ assert_equal("\\\\r \\r \t \r \n",
72
+ entries["\\\\r \\r \t \r \n"].msgstr)
73
+ end
74
+
65
75
  def test_msgstr
66
76
  po_file = create_po_file(<<-EOP)
67
77
  # This is the comment.
@@ -228,6 +238,39 @@ EOP
228
238
  assert_equal("fuzzy", entries["hello"].flag)
229
239
  end
230
240
 
241
+ def test_fuzzy_ignore
242
+ po_file = create_po_file(<<-PO)
243
+ #, fuzzy
244
+ #: file.rb:10
245
+ msgid "hello"
246
+ msgstr "bonjour"
247
+
248
+ #, c-format, fuzzy , no-sh-format
249
+ #: file.rb:11
250
+ msgid "world"
251
+ msgstr "monde"
252
+
253
+ # This is not fuzzy
254
+ msgid "non-fuzzy"
255
+ msgstr "non-fuzzy string"
256
+ PO
257
+ entries = suppress_warning do
258
+ parse_po_file(po_file)
259
+ end
260
+
261
+ actual = entries.collect do |entry|
262
+ [
263
+ entry.msgid,
264
+ entry.msgstr,
265
+ entry.flags,
266
+ ]
267
+ end
268
+ assert_equal([
269
+ ["non-fuzzy", "non-fuzzy string", []],
270
+ ],
271
+ actual)
272
+ end
273
+
231
274
  private
232
275
  def parse_po_file(po_file, options={:ignore_fuzzy => true})
233
276
  ignore_fuzzy = options[:ignore_fuzzy]
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2014-2018 Kouhei Sutou <kou@clear-code.com>
1
+ # Copyright (C) 2014-2023 Sutou Kouhei <kou@clear-code.com>
2
2
  #
3
3
  # License: Ruby's or LGPL
4
4
  #
@@ -243,6 +243,7 @@ msgstr ""
243
243
  @po = <<-PO
244
244
  # translator comment
245
245
  #: a.rb:1
246
+ #: a.rb:2
246
247
  msgid "Hello"
247
248
  msgstr ""
248
249
  PO
@@ -252,6 +253,25 @@ msgstr ""
252
253
  assert_equal(<<-PO, run_msgcat([@po], "--no-location"))
253
254
  # translator comment
254
255
  msgid "Hello"
256
+ msgstr ""
257
+ PO
258
+ end
259
+
260
+ def test_wrap
261
+ assert_equal(<<-PO, run_msgcat([@po], "--wrap"))
262
+ # translator comment
263
+ #: a.rb:1 a.rb:2
264
+ msgid "Hello"
265
+ msgstr ""
266
+ PO
267
+ end
268
+
269
+ def test_use_one_line_per_reference
270
+ assert_equal(<<-PO, run_msgcat([@po], "--wrap", "--use-one-line-per-reference"))
271
+ # translator comment
272
+ #: a.rb:1
273
+ #: a.rb:2
274
+ msgid "Hello"
255
275
  msgstr ""
256
276
  PO
257
277
  end
@@ -1,5 +1,5 @@
1
1
  # Copyright (C) 2012 Haruka Yoshihara <yoshihara@clear-code.com>
2
- # Copyright (C) 2012-2021 Sutou Kouhei <kou@clear-code.com>
2
+ # Copyright (C) 2012-2023 Sutou Kouhei <kou@clear-code.com>
3
3
  #
4
4
  # License: Ruby's or LGPL
5
5
  #
@@ -312,6 +312,11 @@ EOF
312
312
  end
313
313
 
314
314
  class TestPluralForms < self
315
+ def setup
316
+ super
317
+ omit("Red Datasets is required") unless defined?(Datasets::CLDRPlurals)
318
+ end
319
+
315
320
  def run_msginit(pot_header_options={})
316
321
  create_pot_file("test.pot", pot_header_options)
317
322
  po_file_path = "output.po"
@@ -359,7 +364,7 @@ EOF
359
364
  def test_ro
360
365
  assert_equal("nplurals=3; " +
361
366
  "plural=(n == 1) ? 0 : " +
362
- "(n == 0) || ((n % 100) >= 2 && (n % 100) <= 19) ? 1 : 2;",
367
+ "(n == 0) || (n != 1) && ((n % 100) >= 1 && (n % 100) <= 19) ? 1 : 2;",
363
368
  @msginit.__send__(:plural_forms, "ro"))
364
369
  end
365
370
 
@@ -1,6 +1,4 @@
1
- # -*- coding: utf-8 -*-
2
- #
3
- # Copyright (C) 2012-2020 Sutou Kouhei <kou@clear-code.com>
1
+ # Copyright (C) 2012-2023 Sutou Kouhei <kou@clear-code.com>
4
2
  # Copyright (C) 2010 Eddie Lau <tatonlto@gmail.com>
5
3
  #
6
4
  # License: Ruby's or LGPL
@@ -654,6 +652,46 @@ msgstr ""
654
652
  end
655
653
  end
656
654
 
655
+ class TestUseOneLinePerReference < self
656
+ def pot_content
657
+ super + <<-POT
658
+
659
+ #: hello.rb:10
660
+ #: hello.rb:20
661
+ #: hello.rb:30
662
+ msgid "Good morning"
663
+ msgstr ""
664
+ POT
665
+ end
666
+
667
+ def test_with_wrap
668
+ @msgmerge.run("--update",
669
+ "--wrap",
670
+ "--use-one-line-per-reference",
671
+ @po_file_path, @pot_file_path)
672
+ assert_equal(<<-PO, File.read(@po_file_path))
673
+ #{po_header(@pot_formatted_time, @po_formatted_time)}
674
+ #: hello.rb:1
675
+ msgid "Hello"
676
+ msgstr ""
677
+
678
+ #: hello.rb:2
679
+ msgid "World"
680
+ msgstr "Translated World"
681
+
682
+ #: hello.rb:3
683
+ msgid "Good-bye"
684
+ msgstr ""
685
+
686
+ #: hello.rb:10
687
+ #: hello.rb:20
688
+ #: hello.rb:30
689
+ msgid "Good morning"
690
+ msgstr ""
691
+ PO
692
+ end
693
+ end
694
+
657
695
  class TestWidth < self
658
696
  def pot_content
659
697
  <<-POT
@@ -1,6 +1,4 @@
1
- # -*- coding: utf-8 -*-
2
- #
3
- # Copyright (C) 2012-2020 Sutou Kouhei <kou@clear-code.com>
1
+ # Copyright (C) 2012-2023 Sutou Kouhei <kou@clear-code.com>
4
2
  # Copyright (C) 2012 Haruka Yoshihara <yoshihara@clear-code.com>
5
3
  #
6
4
  # License: Ruby's or LGPL
@@ -116,6 +114,105 @@ msgid "Hello"
116
114
  msgstr ""
117
115
  EOP
118
116
  end
117
+
118
+ def test_use_one_line_per_reference
119
+ pot_content = generate(<<-RUBY, "--use-one-line-per-reference")
120
+ _("Hello")
121
+ _("Hello")
122
+ RUBY
123
+ assert_equal(<<-POT, pot_content)
124
+ #{header}
125
+ #: ../lib/xgettext.rb:1
126
+ #: ../lib/xgettext.rb:2
127
+ msgid "Hello"
128
+ msgstr ""
129
+ POT
130
+ end
131
+ end
132
+
133
+ class TestParser < self
134
+ # Default ERB parser (don't find anything after "case")
135
+ def test_erb
136
+ rhtml = <<-EOR
137
+ <div>
138
+ <%= _('Hello') %>
139
+ <% case 1 %>
140
+ <% end %>
141
+ <%= _('World') %>
142
+ </div>
143
+ EOR
144
+
145
+ File.open(@rhtml_file_path, "w") do |rhtml_file|
146
+ rhtml_file.puts(rhtml)
147
+ end
148
+
149
+ @xgettext.run(
150
+ "--output", @pot_file_path,
151
+ @rhtml_file_path
152
+ )
153
+
154
+ pot_content = File.read(@pot_file_path)
155
+
156
+ if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('3.0.0')
157
+ expected_content = <<-EOP
158
+ #{header}
159
+ #: ../templates/xgettext.rhtml:2
160
+ msgid "Hello"
161
+ msgstr ""
162
+
163
+ #: ../templates/xgettext.rhtml:5
164
+ msgid "World"
165
+ msgstr ""
166
+ EOP
167
+ else
168
+ # "World" not detected. see PR #91
169
+ expected_content = <<-EOP
170
+ #{header}
171
+ #: ../templates/xgettext.rhtml:2
172
+ msgid "Hello"
173
+ msgstr ""
174
+ EOP
175
+ end
176
+
177
+ assert_equal(expected_content, pot_content)
178
+ end
179
+
180
+ # Optional Erubi parser (find text after "case")
181
+ def test_erubi
182
+ rhtml = <<-EOR
183
+ <div>
184
+ <%= _('Hello') %>
185
+ <% case 1 %>
186
+ <% end %>
187
+ <%= _('World') %>
188
+ </div>
189
+ EOR
190
+
191
+ File.open(@rhtml_file_path, "w") do |rhtml_file|
192
+ rhtml_file.puts(rhtml)
193
+ end
194
+
195
+ @xgettext.run(
196
+ "--output", @pot_file_path,
197
+ '--require', 'gettext/tools/parser/erubi',
198
+ '--parser', 'GetText::ErubiParser',
199
+ @rhtml_file_path
200
+ )
201
+
202
+ pot_content = File.read(@pot_file_path)
203
+ expected_content = <<-EOP
204
+ #{header}
205
+ #: ../templates/xgettext.rhtml:2
206
+ msgid "Hello"
207
+ msgstr ""
208
+
209
+ #: ../templates/xgettext.rhtml:5
210
+ msgid "World"
211
+ msgstr ""
212
+ EOP
213
+
214
+ assert_equal(expected_content, pot_content)
215
+ end
119
216
  end
120
217
 
121
218
  class TestEncoding < self
metadata CHANGED
@@ -1,16 +1,30 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gettext
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.3.9
4
+ version: 3.4.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kouhei Sutou
8
8
  - Masao Mutoh
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2021-08-25 00:00:00.000000000 Z
12
+ date: 2023-10-21 00:00:00.000000000 Z
13
13
  dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: erubi
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ">="
19
+ - !ruby/object:Gem::Version
20
+ version: '0'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ version: '0'
14
28
  - !ruby/object:Gem::Dependency
15
29
  name: locale
16
30
  requirement: !ruby/object:Gem::Requirement
@@ -26,27 +40,27 @@ dependencies:
26
40
  - !ruby/object:Gem::Version
27
41
  version: 2.0.5
28
42
  - !ruby/object:Gem::Dependency
29
- name: text
43
+ name: prime
30
44
  requirement: !ruby/object:Gem::Requirement
31
45
  requirements:
32
46
  - - ">="
33
47
  - !ruby/object:Gem::Version
34
- version: 1.3.0
48
+ version: '0'
35
49
  type: :runtime
36
50
  prerelease: false
37
51
  version_requirements: !ruby/object:Gem::Requirement
38
52
  requirements:
39
53
  - - ">="
40
54
  - !ruby/object:Gem::Version
41
- version: 1.3.0
55
+ version: '0'
42
56
  - !ruby/object:Gem::Dependency
43
- name: kramdown
57
+ name: racc
44
58
  requirement: !ruby/object:Gem::Requirement
45
59
  requirements:
46
60
  - - ">="
47
61
  - !ruby/object:Gem::Version
48
62
  version: '0'
49
- type: :development
63
+ type: :runtime
50
64
  prerelease: false
51
65
  version_requirements: !ruby/object:Gem::Requirement
52
66
  requirements:
@@ -54,7 +68,21 @@ dependencies:
54
68
  - !ruby/object:Gem::Version
55
69
  version: '0'
56
70
  - !ruby/object:Gem::Dependency
57
- name: racc
71
+ name: text
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: 1.3.0
77
+ type: :runtime
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: 1.3.0
84
+ - !ruby/object:Gem::Dependency
85
+ name: kramdown
58
86
  requirement: !ruby/object:Gem::Requirement
59
87
  requirements:
60
88
  - - ">="
@@ -184,6 +212,7 @@ files:
184
212
  - lib/gettext/tools/msginit.rb
185
213
  - lib/gettext/tools/msgmerge.rb
186
214
  - lib/gettext/tools/parser/erb.rb
215
+ - lib/gettext/tools/parser/erubi.rb
187
216
  - lib/gettext/tools/parser/glade.rb
188
217
  - lib/gettext/tools/parser/gtk_builder_ui_definitions.rb
189
218
  - lib/gettext/tools/parser/ruby.rb
@@ -1531,12 +1560,12 @@ files:
1531
1560
  - test/fixtures/backslash.rb
1532
1561
  - test/fixtures/erb/ascii.rhtml
1533
1562
  - test/fixtures/erb/ascii.rxml
1563
+ - test/fixtures/erb/case.rhtml
1534
1564
  - test/fixtures/erb/minus.rhtml
1535
1565
  - test/fixtures/erb/non_ascii.rhtml
1536
1566
  - test/fixtures/glade/2.glade
1537
1567
  - test/fixtures/glade/3.glade
1538
1568
  - test/fixtures/gtk_builder_ui_definitions.ui
1539
- - test/fixtures/gtk_builder_ui_definitions.ui~
1540
1569
  - test/fixtures/hello.rb
1541
1570
  - test/fixtures/lower_n_.rb
1542
1571
  - test/fixtures/multi_text_domain.rb
@@ -1563,6 +1592,8 @@ files:
1563
1592
  - test/locale/fr/LC_MESSAGES/plural_error.mo
1564
1593
  - test/locale/fr/LC_MESSAGES/test1.mo
1565
1594
  - test/locale/fr/LC_MESSAGES/test2.mo
1595
+ - test/locale/fr_BE/LC_MESSAGES/test1.mo
1596
+ - test/locale/fr_BE_Foo/LC_MESSAGES/test1.mo
1566
1597
  - test/locale/ir/LC_MESSAGES/plural.mo
1567
1598
  - test/locale/ja/LC_MESSAGES/_.mo
1568
1599
  - test/locale/ja/LC_MESSAGES/backslash.mo
@@ -1595,6 +1626,8 @@ files:
1595
1626
  - test/po/fr/plural_error.po
1596
1627
  - test/po/fr/test1.po
1597
1628
  - test/po/fr/test2.po
1629
+ - test/po/fr_BE/test1.po
1630
+ - test/po/fr_BE_Foo/test1.po
1598
1631
  - test/po/hello.pot
1599
1632
  - test/po/ir/plural.po
1600
1633
  - test/po/ja/_.edit.po
@@ -1677,9 +1710,10 @@ files:
1677
1710
  - test/tools/test_xgettext.rb
1678
1711
  homepage: https://ruby-gettext.github.io/
1679
1712
  licenses:
1680
- - Ruby or LGPLv3+
1713
+ - Ruby
1714
+ - LGPL-3.0+
1681
1715
  metadata: {}
1682
- post_install_message:
1716
+ post_install_message:
1683
1717
  rdoc_options: []
1684
1718
  require_paths:
1685
1719
  - lib
@@ -1694,8 +1728,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
1694
1728
  - !ruby/object:Gem::Version
1695
1729
  version: '0'
1696
1730
  requirements: []
1697
- rubygems_version: 3.3.0.dev
1698
- signing_key:
1731
+ rubygems_version: 3.5.0.dev
1732
+ signing_key:
1699
1733
  specification_version: 4
1700
1734
  summary: Gettext is a pure Ruby libary and tools to localize messages.
1701
1735
  test_files: