gettext 2.3.0 → 2.3.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 (74) hide show
  1. data/.yardopts +6 -0
  2. data/Rakefile +7 -6
  3. data/doc/text/news.md +51 -2
  4. data/gettext.gemspec +1 -0
  5. data/lib/gettext/runtime/locale_path.rb +0 -1
  6. data/lib/gettext/runtime/mofile.rb +8 -2
  7. data/lib/gettext/runtime/textdomain.rb +19 -21
  8. data/lib/gettext/runtime/textdomain_manager.rb +0 -1
  9. data/lib/gettext/tools/msginit.rb +19 -9
  10. data/lib/gettext/tools/msgmerge.rb +28 -15
  11. data/lib/gettext/tools/parser/erb.rb +25 -5
  12. data/lib/gettext/tools/parser/glade.rb +4 -3
  13. data/lib/gettext/tools/parser/ruby.rb +23 -5
  14. data/lib/gettext/tools/poparser.rb +2 -1
  15. data/lib/gettext/tools/xgettext.rb +187 -136
  16. data/lib/gettext/version.rb +1 -1
  17. data/po/ja/gettext.po +82 -41
  18. data/samples/cgi/locale/bg/LC_MESSAGES/main.mo +0 -0
  19. data/samples/cgi/locale/bs/LC_MESSAGES/main.mo +0 -0
  20. data/samples/cgi/locale/ca/LC_MESSAGES/main.mo +0 -0
  21. data/samples/cgi/locale/cs/LC_MESSAGES/main.mo +0 -0
  22. data/samples/cgi/locale/de/LC_MESSAGES/main.mo +0 -0
  23. data/samples/cgi/locale/el/LC_MESSAGES/main.mo +0 -0
  24. data/samples/cgi/locale/eo/LC_MESSAGES/main.mo +0 -0
  25. data/samples/cgi/locale/es/LC_MESSAGES/main.mo +0 -0
  26. data/samples/po/hello.pot +3 -3
  27. data/samples/po/hello2.pot +3 -3
  28. data/samples/po/hello_glade2.pot +3 -3
  29. data/samples/po/hello_gtk2.pot +3 -3
  30. data/samples/po/hello_noop.pot +3 -3
  31. data/samples/po/hello_plural.pot +3 -3
  32. data/samples/po/hello_tk.pot +3 -3
  33. data/src/poparser.ry +1 -0
  34. data/test/fixtures/_.rb +4 -4
  35. data/test/fixtures/{erb.rhtml → erb/ascii.rhtml} +0 -0
  36. data/test/fixtures/{erb.rxml → erb/ascii.rxml} +0 -0
  37. data/test/fixtures/erb/non_ascii.rhtml +13 -0
  38. data/test/fixtures/untranslated.rb +12 -0
  39. data/test/gettext-test-utils.rb +23 -0
  40. data/test/locale/ja/LC_MESSAGES/untranslated.mo +0 -0
  41. data/test/parser/test_ruby.rb +48 -1
  42. data/test/po/_.pot +4 -4
  43. data/test/po/ascii.pot +23 -0
  44. data/test/po/backslash.pot +3 -3
  45. data/test/po/ja/untranslated.po +22 -0
  46. data/test/po/no_exist_msgid.pot +20 -0
  47. data/test/po/non_ascii.pot +3 -3
  48. data/test/po/not_existed_msgid.pot +20 -0
  49. data/test/po/np_.pot +3 -3
  50. data/test/po/ns_.pot +3 -3
  51. data/test/po/p_.pot +3 -3
  52. data/test/po/s_.pot +3 -3
  53. data/test/po/untranslated.pot +23 -0
  54. data/test/run-test.rb +1 -1
  55. data/test/test_gettext.rb +2 -2
  56. data/test/test_mofile.rb +10 -0
  57. data/test/test_parser.rb +45 -19
  58. data/test/test_po_parser.rb +14 -1
  59. data/test/tools/test_msginit.rb +52 -36
  60. data/test/tools/test_msgmerge.rb +44 -6
  61. data/test/tools/test_xgettext.rb +203 -5
  62. metadata +143 -146
  63. data/po/de/gettext.po +0 -668
  64. data/po/de/gettext.po.bak +0 -589
  65. data/po/el/gettext.po +0 -571
  66. data/po/fr/gettext.po +0 -589
  67. data/po/gettext.pot +0 -638
  68. data/po/gettext.pot~ +0 -638
  69. data/po/it/gettext.po +0 -589
  70. data/po/uk/gettext.po +0 -571
  71. data/test/locale/ja/LC_MESSAGES/npgettext.mo +0 -0
  72. data/test/locale/ja/LC_MESSAGES/nsgettext.mo +0 -0
  73. data/test/locale/ja/LC_MESSAGES/pgettext.mo +0 -0
  74. data/test/locale/ja/LC_MESSAGES/sgettext.mo +0 -0
data/.yardopts ADDED
@@ -0,0 +1,6 @@
1
+ --protected
2
+ --no-private
3
+ --output doc/reference/en
4
+ --title "gettext API Reference"
5
+ -
6
+ doc/text/*
data/Rakefile CHANGED
@@ -44,13 +44,15 @@ poparser_rb_path = "lib/gettext/tools/poparser.rb"
44
44
  desc "Create #{poparser_rb_path}"
45
45
  task :poparser => poparser_rb_path
46
46
 
47
+ def fix_racc_output_indent(racc_output)
48
+ racc_output.gsub(/^ (end\s*\# module GetText)$/, '\1')
49
+ end
50
+
47
51
  poparser_ry_path = "src/poparser.ry"
48
52
  file poparser_rb_path => poparser_ry_path do
49
53
  racc = File.join(Gem.bindir, "racc")
50
54
  tempfile = Tempfile.new("gettext-poparser")
51
- command_line = "#{racc} -g #{poparser_ry_path} -o #{tempfile.path}"
52
- ruby(command_line)
53
- $stderr.puts("ruby #{command_line}")
55
+ ruby(racc, "-g", poparser_ry_path, "-o", tempfile.path)
54
56
 
55
57
  File.open(poparser_rb_path, "w") do |poparser_rb|
56
58
  poparser_rb.puts(<<-EOH)
@@ -66,9 +68,8 @@ file poparser_rb_path => poparser_ry_path do
66
68
 
67
69
  EOH
68
70
 
69
- poparser_rb.puts(tempfile.read)
71
+ poparser_rb.puts(fix_racc_output_indent(tempfile.read))
70
72
  end
71
- $stderr.puts "Create #{poparser_rb_path}."
72
73
  end
73
74
 
74
75
  desc "Run all tests"
@@ -117,7 +118,7 @@ task "samples:cgi:gettext"
117
118
 
118
119
  task "samples:gettext" => "samples:cgi:gettext"
119
120
 
120
- ["backslash", "non_ascii", "np_", "p_"].each do |domain|
121
+ ["untranslated", "backslash", "non_ascii", "np_", "p_"].each do |domain|
121
122
  GetText::Task.new(spec) do |task|
122
123
  task.domain = domain
123
124
  task.namespace_prefix = "test:#{domain}"
data/doc/text/news.md CHANGED
@@ -1,4 +1,53 @@
1
1
  # News
2
+ ## <a id="2-3-1">2.3.1</a>: 2012-09-13
3
+
4
+ It's a Bug and package fix release.
5
+ Then, it's also encoding support release, only if you use Ruby 1.9.
6
+
7
+ ### Improvements
8
+
9
+ * [xgettext] Added backword compatibility method
10
+ (GetText::RGetText.run).
11
+ [Suggested by Fotos Georgiadis]
12
+ * [xgettext] Removed deprecated parse argument support.
13
+ * [erb parer] Assumed the encoding in the magic comment of the
14
+ input file as the encoding of it.
15
+ * [ruby parser] Assumed the encoding in the magic comment of the
16
+ input file as the encoding of it.
17
+ * [xgettext] Added the "--output-encoding" option to set encoding of
18
+ output pot file.
19
+ * [xgettext] Used UTF-8 as the default encoding of output pot file.
20
+ * [xgettext] Supported multiple encoding sources.
21
+
22
+ ### Changes
23
+
24
+ * [MoFile] Returned nil instead of "" as msgstr when its msgid isn't
25
+ translated (when this msgstr is "").
26
+ * [PoParser] Converted msgstr from "" to nil when parsing.
27
+
28
+ ### Fixes
29
+
30
+ * Added missing .yardopts file. [Reported by Takahiro Kambe]
31
+ * [news] Fixed Eddie Lau name instead of github name.
32
+ * [msginit] Added the "Plural-Forms:" entry to the header even if a
33
+ pot file doesn't have it.
34
+ * [msgmerge] Fixed the bug the new line between a header and
35
+ contents doesn't exist.
36
+ * [msginit] Fixed the bug that msgstr with msgid_plural aren't
37
+ generated in output po file.
38
+ * [xgettext] Supported class based xgettext parser add API.
39
+ [GitHub #10] [Suggested by Michael Grosser]
40
+ * [erb parer] Fixed erb parser bug with unicode msgid in Ruby 1.9
41
+ ERB templates.
42
+ [Github #9] [Patch by Fotos Georgiadis]
43
+ * Added missing documents for GetText::Tools::XGetText.
44
+
45
+ ### Thanks
46
+
47
+ * Takahiro Kambe
48
+ * Michael Grosser
49
+ * Fotos Georgiadis
50
+
2
51
  ## <a id="2-3-0">2.3.0</a>: 2012-08-28
3
52
 
4
53
  Various improvements, changes and fixes release.
@@ -23,7 +72,7 @@ Various improvements, changes and fixes release.
23
72
 
24
73
  * Renamed the package name from "Ruby-GetText-Package" to "gettext".
25
74
  * Renamed RGetText to XGetText, RMsgMerge to MsgMerge, RMsgFmt to MsgFmt.
26
- * Renamed rgettext to rxgettext, rmsgmerge to msgmerge, rmsgfmt to msgfmt.
75
+ * Renamed rgettext to rxgettext.
27
76
  * Defined tools(XGetText, MsgMerge, MsgFmt) as Class under GetText::Tools
28
77
  module.
29
78
  * Removed shortcuts for tools in GetText module.
@@ -57,7 +106,7 @@ Various improvements, changes and fixes release.
57
106
  * Francesco Poli (wintermute)
58
107
  * 375gnu
59
108
  * Michael Grosser
60
- * 3dd13
109
+ * Eddie Lau
61
110
  * Yves-Eric Martin
62
111
 
63
112
  ## <a id="2-2-0">2.2.0</a>: 2012-03-11
data/gettext.gemspec CHANGED
@@ -21,6 +21,7 @@ So you can use GNU gettext tools for maintaining.
21
21
  Dir.chdir(base_dir) do
22
22
  s.files = Dir.glob("{bin,data,doc/text,lib,po,samples,src,test}/**/*")
23
23
  s.files += ["COPYING", "README.rdoc", "Rakefile", "gettext.gemspec"]
24
+ s.files += [".yardopts"]
24
25
  s.executables = Dir.chdir("bin") do
25
26
  Dir.glob("*")
26
27
  end
@@ -100,7 +100,6 @@ module GetText
100
100
  # * lang: a Locale::Tag.
101
101
  def current_path(lang)
102
102
  lang_candidates = lang.to_posix.candidates
103
- search_files = []
104
103
 
105
104
  lang_candidates.each do |tag|
106
105
  path = @locale_paths[tag.to_s]
@@ -152,7 +152,10 @@ module GetText
152
152
  @plural = "0" unless @plural
153
153
  end
154
154
  else
155
- msgstr = convert_encoding(msgstr, msgid)
155
+ msgstr = nil if msgstr.empty?
156
+ unless msgstr.nil?
157
+ msgstr = convert_encoding(msgstr, msgid)
158
+ end
156
159
  end
157
160
  self[convert_encoding(msgid, msgid)] = msgstr.freeze
158
161
  end
@@ -185,7 +188,6 @@ module GetText
185
188
  # 1986, 1987 Bell Telephone Laboratories, Inc.]
186
189
  def hash_string(str)
187
190
  hval = 0
188
- i = 0
189
191
  str.each_byte do |b|
190
192
  break if b == '\0'
191
193
  hval <<= 4
@@ -218,6 +220,10 @@ module GetText
218
220
  io.write(header.to_a.pack('a4V*'))
219
221
 
220
222
  ary = to_a
223
+ ary = ary.collect do |msgid, msgstr|
224
+ msgstr ||= ""
225
+ [msgid, msgstr]
226
+ end
221
227
  ary.sort!{|a, b| a[0] <=> b[0]} # sort by original string
222
228
 
223
229
  pos = header.hash_table_size * 4 + header.hash_table_offset
@@ -84,42 +84,40 @@ module GetText
84
84
  return nil
85
85
  end
86
86
 
87
- msgstr = mofile[msgid]
88
- if not msgstr.nil?
89
- if msgstr.empty?
90
- nil
91
- else
92
- msgstr
93
- end
94
- elsif msgid.include?("\000")
87
+ return mofile[msgid] if mofile.has_key?(msgid)
88
+
89
+ ret = nil
90
+ if msgid.include?("\000")
95
91
  # Check "aaa\000bbb" and show warning but return the singular part.
96
- ret = nil
97
92
  msgid_single = msgid.split("\000")[0]
98
93
  msgid_single_prefix_re = /^#{Regexp.quote(msgid_single)}\000/
99
- mofile.each{|key, val|
100
- if key =~ msgid_single_prefix_re
94
+ mofile.each do |key, val|
95
+ if msgid_single_prefix_re =~ key
101
96
  # Usually, this is not caused to make po-files from rgettext.
102
- warn %Q[Warning: n_("#{msgid_single}", "#{msgid.split("\000")[1]}") and n_("#{key.gsub(/\000/, '", "')}") are duplicated.]
97
+ separated_msgid = msgid.gsub(/\000/, '", "')
98
+ duplicated_msgid = key.gsub(/\000/, '", "')
99
+ warn("Warning: " +
100
+ "n_(\"#{separated_msgid}\") and " +
101
+ "n_(\"#{duplicated_msgid}\") " +
102
+ "are duplicated.")
103
103
  ret = val
104
104
  break
105
105
  end
106
- }
107
- ret
106
+ end
108
107
  else
109
- ret = nil
110
108
  msgid_prefix_re = /^#{Regexp.quote(msgid)}\000/
111
- mofile.each{|key, val|
112
- if key =~ msgid_prefix_re
109
+ mofile.each do |key, val|
110
+ if msgid_prefix_re =~ key
113
111
  ret = val.split("\000")[0]
114
112
  break
115
113
  end
116
- }
117
- ret
114
+ end
118
115
  end
116
+ ret
119
117
  end
120
118
 
121
- DEFAULT_PLURAL_CALC = Proc.new{|n| n != 1}
122
- DEFAULT_SINGLE_CALC = Proc.new{|n| 0}
119
+ DEFAULT_PLURAL_CALC = Proc.new {|n| n != 1}
120
+ DEFAULT_SINGLE_CALC = Proc.new {|n| 0}
123
121
 
124
122
  # Translates the translated string.
125
123
  # * lang: Locale::Tag::Simple's subclass.
@@ -79,7 +79,6 @@ module GetText
79
79
  def each_textdomains(klass) #:nodoc:
80
80
  lang = Locale.candidates[0]
81
81
  ClassInfo.related_classes(klass, @@gettext_classes).each do |target|
82
- msg = nil
83
82
  if group = @@textdomain_group_pool[target]
84
83
  group.textdomains.each do |textdomain|
85
84
  yield textdomain, lang
@@ -109,7 +109,7 @@ module GetText
109
109
  @locale = loc
110
110
  end
111
111
 
112
- parser.on("-h", "--help", _("Dispray this help and exit")) do
112
+ parser.on("-h", "--help", _("Display this help and exit")) do
113
113
  puts(parser.help)
114
114
  exit(true)
115
115
  end
@@ -254,9 +254,6 @@ module GetText
254
254
  POT_REVISION_DATE_KEY = /^(PO-Revision-Date:).+/
255
255
 
256
256
  def replace_pot_revision_date #:nodoc:
257
- date = Time.now
258
- revision_date = date.strftime("%Y-%m-%d %H:%M%z")
259
-
260
257
  @entry = @entry.gsub(POT_REVISION_DATE_KEY,
261
258
  "\\1 #{revision_date}")
262
259
  end
@@ -274,7 +271,12 @@ module GetText
274
271
  /^(Plural-Forms:) nplurals=INTEGER; plural=EXPRESSION;$/
275
272
 
276
273
  def replace_plural_forms #:nodoc:
277
- @entry = @entry.gsub(PLURAL_FORMS, "\\1 #{plural_forms(@language)}")
274
+ plural_entry = plural_forms(@language)
275
+ if PLURAL_FORMS =~ @entry
276
+ @entry = @entry.gsub(PLURAL_FORMS, "\\1 #{plural_entry}")
277
+ else
278
+ @entry << "Plural-Forms: #{plural_entry}"
279
+ end
278
280
  end
279
281
 
280
282
  def plural_forms(language) #:nodoc:
@@ -343,8 +345,6 @@ module GetText
343
345
  LAST_TRANSLATOR_KEY = /^(Last-Translator:) FULL NAME <#{EMAIL}>$/
344
346
 
345
347
  def replace_first_author #:nodoc:
346
- year = Time.now.year
347
-
348
348
  @comment = @comment.gsub(YEAR_KEY, "\\1 #{year}.")
349
349
  unless @translator.nil?
350
350
  @comment = @comment.gsub(FIRST_AUTHOR_KEY,
@@ -354,9 +354,19 @@ module GetText
354
354
 
355
355
  COPYRIGHT_KEY = /(\s*#\s* Copyright \(C\)) YEAR (THE PACKAGE'S COPYRIGHT HOLDER)$/
356
356
  def replace_copyright_year #:nodoc:
357
- date = Time.now
357
+ @comment = @comment.gsub(COPYRIGHT_KEY, "\\1 #{year} \\2")
358
+ end
359
+
360
+ def now
361
+ @now ||= Time.now
362
+ end
363
+
364
+ def revision_date
365
+ now.strftime("%Y-%m-%d %H:%M%z")
366
+ end
358
367
 
359
- @comment = @comment.gsub(COPYRIGHT_KEY, "\\1 #{date.year} \\2")
368
+ def year
369
+ now.year
360
370
  end
361
371
  end
362
372
  end
@@ -57,7 +57,7 @@ module GetText
57
57
 
58
58
  def []=(msgid, msgstr)
59
59
  # Retain the order
60
- if @msgid2msgstr[msgid].nil?
60
+ unless @msgid2msgstr.has_key?(msgid)
61
61
  @msgids << msgid
62
62
  end
63
63
 
@@ -98,6 +98,7 @@ module GetText
98
98
  def generate_po
99
99
  str = ""
100
100
  str << generate_po_header
101
+ str << "\n"
101
102
 
102
103
  po_entries = []
103
104
  self.each_msgid do |id|
@@ -120,7 +121,7 @@ module GetText
120
121
  str << 'msgstr ""' << "\n"
121
122
  msgstr = @msgid2msgstr[""].gsub(/"/, '\"').gsub(/\r/, "")
122
123
  msgstr = msgstr.gsub(/^(.*)$/, '"\1\n"')
123
- str << msgstr
124
+ str << msgstr.chomp
124
125
  str << "\n"
125
126
 
126
127
  str
@@ -134,7 +135,12 @@ module GetText
134
135
  end
135
136
 
136
137
  id = msgid.gsub(/\r/, "")
137
- msgstr = @msgid2msgstr[msgid].gsub(/\r/, "")
138
+ msgstr = @msgid2msgstr[msgid]
139
+ if msgstr.nil?
140
+ msgstr = ""
141
+ else
142
+ msgstr = msgstr.gsub(/\r/, "")
143
+ end
138
144
 
139
145
  if id.include?("\004")
140
146
  ids = id.split(/\004/)
@@ -150,8 +156,14 @@ module GetText
150
156
  str << "msgid_plural " << __conv(single_id) << "\n"
151
157
  end
152
158
 
153
- msgstr.split("\000", -1).each_with_index do |m, n|
154
- str << "msgstr[#{n}] " << __conv(m) << "\n"
159
+ if msgstr.empty?
160
+ nplurals.times do |id_count|
161
+ str << "msgstr[#{id_count}] " << '""' << "\n"
162
+ end
163
+ else
164
+ msgstr.split("\000", -1).each_with_index do |m, n|
165
+ str << "msgstr[#{n}] " << __conv(m) << "\n"
166
+ end
155
167
  end
156
168
  else
157
169
  str << "msgid " << __conv(id) << "\n"
@@ -199,6 +211,16 @@ module GetText
199
211
  POT_DATE_RE = /POT-Creation-Date:.*?$/
200
212
 
201
213
  def merge(definition, reference)
214
+ definition.each_msgid do |msgid|
215
+ msgstr = definition[msgid] || ""
216
+ definition[msgid] = msgstr
217
+ end
218
+
219
+ reference.each_msgid do |msgid|
220
+ msgstr = reference[msgid] || ""
221
+ reference[msgid] = msgstr
222
+ end
223
+
202
224
  # deep copy
203
225
  result = Marshal.load( Marshal.dump(reference) )
204
226
 
@@ -422,15 +444,6 @@ module GetText
422
444
  def check_command_line_options(*options) #:nodoc:
423
445
  options, output = parse_arguments(*options)
424
446
 
425
- if output.nil?
426
- output = nil
427
- else
428
- if not FileTest.exist?(output)
429
- $stderr.puts(_("File '%s' has already existed.") % out)
430
- exit(false)
431
- end
432
- end
433
-
434
447
  config = Config.new
435
448
  config.output = output
436
449
  config.defpo = options[0]
@@ -469,7 +482,7 @@ module GetText
469
482
 
470
483
  #parser.on("-F", "--fuzzy-matching")
471
484
 
472
- parser.on("-h", "--help", _("Dispray this help and exit")) do
485
+ parser.on("-h", "--help", _("Display this help and exit")) do
473
486
  puts(parser.help)
474
487
  exit(true)
475
488
  end
@@ -29,12 +29,32 @@ module GetText
29
29
  }
30
30
  end
31
31
 
32
- def parse(file, targets = []) # :nodoc:
33
- src = ERB.new(IO.readlines(file).join).src
34
- # Remove magic comment prepended by erb in Ruby 1.9.
35
- src.sub!(/\A#.*?coding[:=].*?\n/, '') if src.respond_to?(:encode)
32
+ MAGIC_COMMENT = /\A#coding:.*\n/
33
+
34
+ def parse(file) # :nodoc:
35
+ content = IO.read(file)
36
+ src = ERB.new(content).src
37
+
38
+ if src.respond_to?(:encode)
39
+ # Force the src encoding back to the encoding in magic comment
40
+ # or original content.
41
+ encoding = detect_encoding(src) || content.encoding
42
+ src.force_encoding(encoding)
43
+
44
+ # Remove magic comment prepended by erb in Ruby 1.9.
45
+ src = src.gsub(MAGIC_COMMENT, "")
46
+ end
47
+
36
48
  erb = src.split(/$/)
37
- RubyParser.parse_lines(file, erb, targets)
49
+ RubyParser.parse_lines(file, erb)
50
+ end
51
+
52
+ def detect_encoding(erb_source)
53
+ if /\A#coding:(.*)\n/ =~ erb_source
54
+ $1
55
+ else
56
+ nil
57
+ end
38
58
  end
39
59
 
40
60
  def target?(file) # :nodoc:
@@ -22,13 +22,14 @@ module GetText
22
22
  TARGET1 = /<property.*translatable="yes">(.*)/
23
23
  TARGET2 = /(.*)<\/property>/
24
24
 
25
- def parse(file, targets = []) # :nodoc:
25
+ def parse(file) # :nodoc:
26
26
  lines = IO.readlines(file)
27
- parse_lines(file, lines, targets)
27
+ parse_lines(file, lines)
28
28
  end
29
29
 
30
30
  #from ary of lines.
31
- def parse_lines(file, lines, targets) # :nodoc:
31
+ def parse_lines(file, lines) # :nodoc:
32
+ targets = []
32
33
  cnt = 0
33
34
  target = false
34
35
  line_no = 0