gettext 2.3.9 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (106) hide show
  1. data/.yardopts +1 -0
  2. data/README.rdoc +28 -23
  3. data/Rakefile +29 -21
  4. data/doc/text/news.md +57 -0
  5. data/gettext.gemspec +1 -1
  6. data/lib/gettext.rb +13 -29
  7. data/lib/gettext/cgi.rb +1 -1
  8. data/lib/gettext/{runtime/class_info.rb → class_info.rb} +1 -1
  9. data/lib/gettext/{runtime/locale_path.rb → locale_path.rb} +1 -2
  10. data/lib/gettext/{runtime/mo.rb → mo.rb} +18 -33
  11. data/lib/gettext/{tools/po.rb → po.rb} +1 -1
  12. data/lib/gettext/{tools/po_entry.rb → po_entry.rb} +8 -4
  13. data/lib/gettext/{tools/poparser.rb → po_parser.rb} +41 -44
  14. data/lib/gettext/{runtime/textdomain.rb → text_domain.rb} +6 -16
  15. data/lib/gettext/text_domain_group.rb +26 -0
  16. data/lib/gettext/{runtime/textdomain_manager.rb → text_domain_manager.rb} +40 -40
  17. data/lib/gettext/tools.rb +1 -182
  18. data/lib/gettext/tools/msgfmt.rb +1 -1
  19. data/lib/gettext/tools/msginit.rb +1 -1
  20. data/lib/gettext/tools/msgmerge.rb +2 -221
  21. data/lib/gettext/tools/parser/erb.rb +49 -30
  22. data/lib/gettext/tools/parser/glade.rb +44 -36
  23. data/lib/gettext/tools/parser/ruby.rb +126 -37
  24. data/lib/gettext/tools/task.rb +225 -0
  25. data/lib/gettext/tools/xgettext.rb +25 -28
  26. data/lib/gettext/version.rb +1 -1
  27. data/locale/bg/LC_MESSAGES/gettext.mo +0 -0
  28. data/locale/bs/LC_MESSAGES/gettext.mo +0 -0
  29. data/locale/ca/LC_MESSAGES/gettext.mo +0 -0
  30. data/locale/cs/LC_MESSAGES/gettext.mo +0 -0
  31. data/locale/de/LC_MESSAGES/gettext.mo +0 -0
  32. data/locale/el/LC_MESSAGES/gettext.mo +0 -0
  33. data/locale/eo/LC_MESSAGES/gettext.mo +0 -0
  34. data/locale/es/LC_MESSAGES/gettext.mo +0 -0
  35. data/locale/et/LC_MESSAGES/gettext.mo +0 -0
  36. data/locale/fr/LC_MESSAGES/gettext.mo +0 -0
  37. data/locale/hr/LC_MESSAGES/gettext.mo +0 -0
  38. data/locale/hu/LC_MESSAGES/gettext.mo +0 -0
  39. data/locale/it/LC_MESSAGES/gettext.mo +0 -0
  40. data/locale/ja/LC_MESSAGES/gettext.mo +0 -0
  41. data/locale/ko/LC_MESSAGES/gettext.mo +0 -0
  42. data/locale/lv/LC_MESSAGES/gettext.mo +0 -0
  43. data/locale/nb/LC_MESSAGES/gettext.mo +0 -0
  44. data/locale/nl/LC_MESSAGES/gettext.mo +0 -0
  45. data/locale/pt_BR/LC_MESSAGES/gettext.mo +0 -0
  46. data/locale/ru/LC_MESSAGES/gettext.mo +0 -0
  47. data/locale/sr/LC_MESSAGES/gettext.mo +0 -0
  48. data/locale/sv/LC_MESSAGES/gettext.mo +0 -0
  49. data/locale/uk/LC_MESSAGES/gettext.mo +0 -0
  50. data/locale/vi/LC_MESSAGES/gettext.mo +0 -0
  51. data/locale/zh/LC_MESSAGES/gettext.mo +0 -0
  52. data/locale/zh_TW/LC_MESSAGES/gettext.mo +0 -0
  53. data/po/gettext.pot +171 -97
  54. data/samples/hello.rb +3 -2
  55. data/samples/hello2.rb +2 -1
  56. data/samples/hello_gtk2.rb +4 -1
  57. data/samples/hello_gtk_builder.rb +32 -0
  58. data/samples/hello_gtk_builder.ui +46 -0
  59. data/samples/hello_noop.rb +2 -1
  60. data/samples/hello_plural.rb +2 -1
  61. data/samples/hello_tk.rb +2 -1
  62. data/src/{poparser.ry → po_parser.ry} +31 -35
  63. data/test/fixtures/N_.rb +1 -1
  64. data/test/fixtures/_/double_quote_in_double_quote.rb +32 -0
  65. data/test/fixtures/_/double_quote_in_single_quote.rb +32 -0
  66. data/test/fixtures/_/literal_concatenation_with_continuation_line.rb +36 -0
  67. data/test/fixtures/_/middle_new_line.rb +32 -0
  68. data/test/fixtures/_/multiple_lines_literal.rb +35 -0
  69. data/test/fixtures/_/multiple_messages_in_same_line.rb +32 -0
  70. data/test/fixtures/_/multiple_same_messages.rb +36 -0
  71. data/{lib/gettext/runtime/mofile.rb → test/fixtures/_/one_new_line.rb} +12 -6
  72. data/test/fixtures/{multi_textdomain.rb → multi_text_domain.rb} +1 -1
  73. data/test/fixtures/non_ascii.rb +1 -1
  74. data/test/fixtures/simple.rb +1 -1
  75. data/test/fixtures/untranslated.rb +1 -1
  76. data/test/gettext-test-utils.rb +1 -24
  77. data/test/po/ja/_.po +63 -13
  78. data/test/po/ja/non_ascii.po +2 -3
  79. data/test/po/ja/untranslated.po +1 -1
  80. data/test/test_class_info.rb +2 -2
  81. data/test/test_gettext.rb +11 -11
  82. data/test/test_mo.rb +2 -2
  83. data/test/test_parser.rb +93 -96
  84. data/test/test_po_entry.rb +237 -146
  85. data/test/test_po_parser.rb +107 -98
  86. data/test/test_string.rb +1 -1
  87. data/test/{test_textdomain_bind.rb → test_text_domain_bind.rb} +6 -6
  88. data/test/{test_textdomain_multi.rb → test_text_domain_multi.rb} +5 -5
  89. data/test/{test_textdomain_toplevel.rb → test_text_domain_toplevel.rb} +1 -1
  90. data/test/test_thread.rb +1 -1
  91. data/test/tools/files/simple_translation.rb +1 -1
  92. data/test/{parser → tools/parser}/test_ruby.rb +110 -14
  93. data/test/tools/test_msgmerge.rb +17 -276
  94. data/test/tools/test_po.rb +1 -1
  95. data/test/tools/test_xgettext.rb +175 -144
  96. metadata +59 -33
  97. data/lib/gettext/core_ext/iconv.rb +0 -110
  98. data/lib/gettext/core_ext/string.rb +0 -91
  99. data/lib/gettext/parser/erb.rb +0 -5
  100. data/lib/gettext/parser/glade.rb +0 -5
  101. data/lib/gettext/parser/ruby.rb +0 -172
  102. data/lib/gettext/runtime/textdomain_group.rb +0 -26
  103. data/lib/gettext/task.rb +0 -203
  104. data/lib/gettext/utils.rb +0 -39
  105. data/test/test_po_generation.rb +0 -45
  106. data/test/tools/test_tools.rb +0 -61
@@ -18,189 +18,8 @@
18
18
  # You should have received a copy of the GNU Lesser General Public License
19
19
  # along with this program. If not, see <http://www.gnu.org/licenses/>.
20
20
 
21
- require 'rbconfig'
22
- if /mingw|mswin|mswin32/ =~ RUBY_PLATFORM
23
- ENV['PATH'] = %w(bin lib).collect{|dir|
24
- "#{::RbConfig::CONFIG["prefix"]}\\lib\\GTK\\#{dir};"
25
- }.join('') + ENV['PATH']
26
- end
27
-
28
21
  require 'gettext/tools/xgettext'
29
22
  require 'gettext/tools/msgfmt'
30
23
  require 'gettext/tools/msginit'
31
24
  require 'gettext/tools/msgmerge'
32
- require 'gettext/runtime/mo'
33
- require 'fileutils'
34
-
35
- module GetText
36
- bindtextdomain "gettext"
37
-
38
- BOM_UTF8 = [0xef, 0xbb, 0xbf].pack("c3")
39
-
40
- # Currently, GNU msgmerge doesn't accept BOM.
41
- # This mesthod remove the UTF-8 BOM from the po-file.
42
- def remove_bom(path) #:nodoc:
43
- bom = IO.read(path, 3)
44
- if bom == BOM_UTF8
45
- data = IO.read(path)[3..-1]
46
- File.open(path, "w") {|f| f.write(data)}
47
- end
48
- end
49
-
50
- # Merges two Uniforum style .po files together.
51
- #
52
- # *Note* This function requires "msgmerge" tool included in GNU GetText. So you need to install GNU GetText.
53
- #
54
- # The def.po file is an existing PO file with translations which will be taken
55
- # over to the newly created file as long as they still match; comments will be preserved,
56
- # but extracted comments and file positions will be discarded.
57
- #
58
- # The ref.pot file is the last created PO file with up-to-date source references but
59
- # old translations, or a PO Template file (generally created by rxgettext);
60
- # any translations or comments in the file will be discarded, however dot
61
- # comments and file positions will be preserved. Where an exact match
62
- # cannot be found, fuzzy matching is used to produce better results.
63
- #
64
- # Usually you don't need to call this function directly. Use GetText.update_pofiles instead.
65
- #
66
- # * defpo: a po-file. translations referring to old sources
67
- # * refpo: a po-file. references to new sources
68
- # * app_version: the application information which appears "Project-Id-Version: #{app_version}" in the pot/po-files.
69
- # * Returns: self
70
- def msgmerge(defpo, refpo, app_version, options={})
71
- verbose = options.delete(:verbose)
72
- puts "msgmerge called" if verbose
73
- $stderr.print defpo + " "
74
-
75
- content = merge_po_files(defpo,refpo,options.delete(:msgmerge),verbose)
76
-
77
- if content.empty?
78
- # report failure
79
- failed_filename = refpo + "~"
80
- FileUtils.cp(refpo, failed_filename)
81
- $stderr.puts _("Failed to merge with %{defpo}") % {:defpo => defpo}
82
- $stderr.puts _("New .pot was copied to %{failed_filename}") %{:failed_filename => failed_filename}
83
- raise _("Check these po/pot-files. It may have syntax errors or something wrong.")
84
- else
85
- # update version and save merged data
86
- content.sub!(/(Project-Id-Version\:).*$/, "\\1 #{app_version}\\n\"")
87
- File.open(defpo, "w") {|f|f.write(content)}
88
- end
89
-
90
- self
91
- end
92
-
93
- # Creates mo-files using #{po_root}/#{lang}/*.po an put them to
94
- # #{targetdir}/#{targetdir_rule}/.
95
- #
96
- # This is a convenience function of GetText.rmsgfmt for multiple target files.
97
- # * options: options as a Hash.
98
- # * verbose: true if verbose mode, otherwise false
99
- # * po_root: the root directory of po-files.
100
- # * mo_root: the target root directory where the mo-files are stored.
101
- # * mo_path_rule: the target directory for each mo-files.
102
- def create_mofiles(options = {})
103
- options = {:po_root => "./po"}.merge(options)
104
-
105
- Dir.glob(File.join(options[:po_root], "*/*.po")) do |po_file|
106
- mo_file = mo_file_from_po_file(po_file,options)
107
- $stderr.print %Q[#{po_file} -> #{mo_file} ... ] if options[:verbose]
108
- FileUtils.mkdir_p(File.dirname(mo_file))
109
- Tools::MsgFmt.run(po_file, "-o", mo_file)
110
- $stderr.puts "Done." if options[:verbose]
111
- end
112
- end
113
-
114
-
115
- # At first, this creates the #{po_root}/#{domainname}.pot file using
116
- # GetText::XGetText.run. In the second step, this updates(merges)
117
- # the #{po_root}/#{domainname}.pot and all of the
118
- # #{po_root}/#{lang}/#{domainname}.po files under "po_root" using
119
- # "msgmerge".
120
- #
121
- # *Note* "msgmerge" tool is included in GNU GetText. So you need to install GNU GetText.
122
- #
123
- # See <HOWTO maintain po/mo files(http://www.yotabanana.com/hiki/ruby-gettext-howto-manage.html)> for more detals.
124
- # * domainname: the textdomain name.
125
- # * targetfiles: An Array of target files, that should be parsed for messages (See GetText::XGetText.run for more details).
126
- # * app_version: the application information which appears "Project-Id-Version: #{app_version}" in the pot/po-files.
127
- # * options: a hash with following possible settings
128
- # :lang - update files only for one language - the language specified by this option
129
- # :po_root - the root directory of po-files
130
- # :msgmerge - an array with the options, passed through to the gnu msgmerge tool
131
- # symbols are automatically translated to options with dashes,
132
- # example: [:no_wrap, :no_fuzzy_matching, :sort_output] translated to '--no-fuzzy-matching --sort-output'
133
- # :verbose - true to show verbose messages. default is false.
134
- #
135
- # Example: GetText.update_pofiles("myapp", Dir.glob("lib/*.rb"), "myapp 1.0.0", :verbose => true)
136
- def update_pofiles(textdomain, files, app_version, options = {})
137
- puts options.inspect if options[:verbose]
138
-
139
- #write found messages to tmp.pot
140
- temp_pot = "tmp.pot"
141
- Tools::XGetText.run("-o", temp_pot, *files)
142
-
143
- #merge tmp.pot and existing pot
144
- po_root = options.delete(:po_root) || "po"
145
- FileUtils.mkdir_p(po_root)
146
- msgmerge("#{po_root}/#{textdomain}.pot", temp_pot, app_version, options.dup)
147
-
148
- #update local po-files
149
- only_one_language = options.delete(:lang)
150
- if only_one_language
151
- msgmerge("#{po_root}/#{only_one_language}/#{textdomain}.po", temp_pot, app_version, options.dup)
152
- else
153
- Dir.glob("#{po_root}/*/#{textdomain}.po") do |po_file|
154
- msgmerge(po_file, temp_pot, app_version, options.dup)
155
- end
156
- end
157
-
158
- File.delete(temp_pot)
159
- end
160
-
161
- private
162
-
163
- # Merge 2 po files, using msgmerge
164
- def merge_po_files(po_a,po_b,msgmerge_options=[],verbose=false)
165
- return File.read(po_b) unless FileTest.exist? po_a
166
-
167
- cmd = ENV["MSGMERGE_PATH"] || "msgmerge"
168
- ensure_command_exists(cmd)
169
-
170
- remove_bom(po_a)
171
-
172
- cmd_params = array_to_cli_options(msgmerge_options)
173
- to_run = "#{cmd} #{cmd_params} #{po_a} #{po_b}"
174
- puts "\nrunning #{to_run}" if verbose
175
- `#{to_run}`
176
- end
177
-
178
- # convert an array of String/Symbol to cli options
179
- def array_to_cli_options(array)
180
- [*array].map do |o|
181
- o.kind_of?(Symbol) ? "--#{o}".gsub('_','-') : o.to_s
182
- end.join(' ')
183
- end
184
-
185
- def ensure_command_exists(cmd)
186
- `#{cmd} --help`
187
- unless $? && $?.success?
188
- raise _("`%{cmd}' cannot be found. \nInstall GNU Gettext then set PATH or MSGMERGE_PATH correctly.") % {:cmd => cmd}
189
- end
190
- end
191
-
192
- # where lies the mo file for a given po_file
193
- # generare directory unless it exists
194
- def mo_file_from_po_file(po_file,options)
195
- options = {
196
- :mo_root => "./data/locale",
197
- :mo_path_rule => "%{lang}/LC_MESSAGES"
198
- }.merge(options)
199
-
200
- lang, textdomain = %r[/([^/]+?)/(.*)\.po].match(po_file[options[:po_root].size..-1]).to_a[1,2]
201
-
202
- mo_dir_rule = File.join(options[:mo_root], options[:mo_path_rule])
203
- mo_dir = mo_dir_rule % {:lang => lang}
204
- File.join(mo_dir, "#{textdomain}.mo")
205
- end
206
- end
25
+ require 'gettext/mo'
@@ -22,7 +22,7 @@
22
22
  require "optparse"
23
23
  require "fileutils"
24
24
  require "gettext"
25
- require "gettext/tools/poparser"
25
+ require "gettext/po_parser"
26
26
 
27
27
  module GetText
28
28
  module Tools
@@ -19,7 +19,7 @@
19
19
  # along with this program. If not, see <http://www.gnu.org/licenses/>.
20
20
 
21
21
  require "gettext"
22
- require "gettext/tools/poparser"
22
+ require "gettext/po_parser"
23
23
  require "gettext/tools/msgmerge"
24
24
  require "locale/info"
25
25
  require "optparse"
@@ -23,231 +23,12 @@
23
23
  require "optparse"
24
24
  require "text"
25
25
  require "gettext"
26
- require "gettext/tools/poparser"
27
- require "gettext/tools/po"
26
+ require "gettext/po_parser"
27
+ require "gettext/po"
28
28
 
29
29
  module GetText
30
30
  module Tools
31
31
  class MsgMerge
32
- class PoData #:nodoc:
33
-
34
- attr_reader :po
35
-
36
- def initialize
37
- @po = PO.new
38
- end
39
-
40
- def set_comment(msgid, comments, msgctxt=nil)
41
- entry = generate_entry(msgid)
42
-
43
- if msgid == :last
44
- entry.comment = comments
45
- return
46
- end
47
-
48
- comments.each_line do |_line|
49
- line = _line.chomp
50
- entry = parse_comment(line, entry)
51
- end
52
- end
53
-
54
- def msgstr(msgid)
55
- self[msgid]
56
- end
57
-
58
- def comment(msgid)
59
- msgctxt, msgid, _ = split_msgid(msgid)
60
- id = [msgctxt, msgid]
61
- entry = @po[*id]
62
- return nil if entry.nil?
63
-
64
- formatted_comments = entry.format_translator_comment
65
- formatted_comments << entry.format_extracted_comment
66
- formatted_comments << entry.format_reference_comment
67
- formatted_comments << entry.format_flag_comment
68
- formatted_comments << entry.format_previous_comment
69
-
70
- unless entry.comment.nil?
71
- formatted_comments = entry.format_comment("#", entry.comment)
72
- end
73
-
74
- formatted_comments.chomp
75
- end
76
-
77
- def [](msgid)
78
- msgctxt, msgid, _ = split_msgid(msgid)
79
- @po[msgctxt, msgid].msgstr
80
- end
81
-
82
- def []=(msgid, value)
83
- msgctxt, msgid, msgid_plural = split_msgid(msgid)
84
- id = [msgctxt, msgid]
85
-
86
- if value.instance_of?(POEntry)
87
- @po[*id] = value
88
- return value
89
- end
90
-
91
- msgstr = value
92
- if @po.has_key?(*id)
93
- @po[*id] = msgstr
94
- @po[*id].msgctxt = msgctxt
95
- @po[*id].msgid_plural = msgid_plural
96
- else
97
- type = detect_entry_type(msgctxt, msgid_plural)
98
- entry = POEntry.new(type)
99
- entry.msgctxt = msgctxt
100
- entry.msgid = msgid
101
- entry.msgid_plural = msgid_plural
102
- entry.msgstr = msgstr
103
- @po[*id] = entry
104
- entry
105
- end
106
- end
107
-
108
- def each_msgid
109
- msgids.each do |id|
110
- next if id.kind_of?(Symbol) or id.empty?
111
- yield(id)
112
- end
113
- end
114
-
115
- def msgids
116
- @po.collect do |entry|
117
- msgctxt = entry.msgctxt
118
- msgid = entry.msgid
119
- generate_original_string(msgctxt, msgid)
120
- end
121
- end
122
-
123
- def msgid?(msgid)
124
- return false if msgid.kind_of?(Symbol)
125
- return true if msgid.empty?
126
- msgctxt, msgid, _ = split_msgid(msgid)
127
- @po.has_key?(msgctxt, msgid)
128
- end
129
-
130
- # Is it necessary to implement this method?
131
- def search_msgid_fuzzy(msgid, used_msgids)
132
- nil
133
- end
134
-
135
- def nplurals
136
- return 0 if @po[""].msgstr.nil?
137
-
138
- if /\s*nplurals\s*=\s*(\d+)/ =~ @po[""].msgstr
139
- return $1.to_i
140
- else
141
- return 0
142
- end
143
- end
144
-
145
- def generate_po
146
- @po.to_s
147
- end
148
-
149
- def generate_po_entry(msgid)
150
- msgctxt, msgid, _ = split_msgid(msgid)
151
- @po[msgctxt, msgid].to_s
152
- end
153
-
154
- def __conv(str)
155
- s = ""
156
-
157
- if str.count("\n") > 1
158
- s << '""' << "\n"
159
- str.each_line do |line|
160
- s << '"' << escape(line) << '"' << "\n"
161
- end
162
- else
163
- s << '"' << escape(str) << '"'
164
- end
165
-
166
- s.rstrip
167
- end
168
-
169
- def escape(string)
170
- POEntry.escape(string)
171
- end
172
-
173
- private
174
- def split_msgid(msgid)
175
- return [nil, msgid, nil] if msgid == :last
176
- return [nil, "", nil] if msgid.empty?
177
- msgctxt, msgid = msgid.split("\004", 2)
178
- if msgid.nil?
179
- msgid = msgctxt
180
- msgctxt = nil
181
- end
182
- msgid, msgid_plural = msgid.split("\000", 2)
183
- [msgctxt, msgid, msgid_plural]
184
- end
185
-
186
- def generate_original_string(msgctxt, msgid)
187
- return msgid if msgid == :last
188
- original_string = ""
189
- msgid_plural = @po[msgctxt, msgid].msgid_plural
190
- original_string << "#{msgctxt}\004" unless msgctxt.nil?
191
- original_string << msgid
192
- original_string << "\000#{msgid_plural}" unless msgid_plural.nil?
193
- original_string
194
- end
195
-
196
- def detect_entry_type(msgctxt, msgid_plural)
197
- if msgctxt.nil?
198
- if msgid_plural.nil?
199
- :normal
200
- else
201
- :plural
202
- end
203
- else
204
- if msgid_plural.nil?
205
- :msgctxt
206
- else
207
- :msgctxt_plural
208
- end
209
- end
210
- end
211
-
212
- def generate_entry(msgid)
213
- msgctxt, msgid, _ = split_msgid(msgid)
214
- id = [msgctxt, msgid]
215
- @po[*id] = nil unless @po.has_key?(*id)
216
- entry = @po[*id]
217
-
218
- entry.translator_comment = ""
219
- entry.extracted_comment = ""
220
- entry.references = []
221
- entry.flag = ""
222
- entry.previous = ""
223
- entry
224
- end
225
-
226
- def parse_comment(line, entry)
227
- if line == "#"
228
- entry.translator_comment << ""
229
- elsif /\A(#.)\s*(.*)\z/ =~ line
230
- mark = $1
231
- content = $2
232
- case mark
233
- when POEntry::TRANSLATOR_COMMENT_MARK
234
- entry.translator_comment << "#{content}\n"
235
- when POEntry::EXTRACTED_COMMENT_MARK
236
- entry.extracted_comment << "#{content}\n"
237
- when POEntry::REFERENCE_COMMENT_MARK
238
- entry.references << content
239
- when POEntry::FLAG_MARK
240
- entry.flag << "#{content}\n"
241
- when POEntry::PREVIOUS_COMMENT_MARK
242
- entry.previous << "#{content}\n"
243
- else
244
- entry.comment << line
245
- end
246
- end
247
- entry
248
- end
249
- end
250
-
251
32
  class Merger #:nodoc:
252
33
  # Merge the reference with the definition: take the #. and
253
34
  # #: comments from the reference, take the # comments from
@@ -1,4 +1,4 @@
1
- # encoding: utf-8
1
+ # -*- coding: utf-8 -*-
2
2
 
3
3
  =begin
4
4
  parser/erb.rb - parser for ERB
@@ -13,40 +13,66 @@ require 'erb'
13
13
  require 'gettext/tools/parser/ruby'
14
14
 
15
15
  module GetText
16
- module ErbParser
17
- extend self
18
-
16
+ class ErbParser
19
17
  @config = {
20
18
  :extnames => ['.rhtml', '.erb']
21
19
  }
22
20
 
23
- # Sets some preferences to parse ERB files.
24
- # * config: a Hash of the config. It can takes some values below:
25
- # * :extnames: An Array of target files extension. Default is [".rhtml"].
26
- def init(config)
27
- config.each{|k, v|
28
- @config[k] = v
29
- }
21
+ class << self
22
+ # Sets some preferences to parse ERB files.
23
+ # * config: a Hash of the config. It can takes some values below:
24
+ # * :extnames: An Array of target files extension. Default is [".rhtml"].
25
+ def init(config)
26
+ config.each{|k, v|
27
+ @config[k] = v
28
+ }
29
+ end
30
+
31
+ def target?(file) # :nodoc:
32
+ @config[:extnames].each do |v|
33
+ return true if File.extname(file) == v
34
+ end
35
+ false
36
+ end
37
+
38
+ # Parses eRuby script located at `path`.
39
+ #
40
+ # This is a short cut method. It equals to `new(path,
41
+ # options).parse`.
42
+ #
43
+ # @return [Array<POEntry>] Extracted messages
44
+ # @see #initialize and #parse
45
+ def parse(path, options={})
46
+ parser = new(path, options)
47
+ parser.parse
48
+ end
30
49
  end
31
50
 
32
51
  MAGIC_COMMENT = /\A#coding:.*\n/
33
52
 
34
- def parse(file) # :nodoc:
35
- content = IO.read(file)
53
+ # @param path [String] eRuby script path to be parsed
54
+ # @param options [Hash]
55
+ def initialize(path, options={})
56
+ @path = path
57
+ @options = options
58
+ end
59
+
60
+ # Extracts messages from @path.
61
+ #
62
+ # @return [Array<POEntry>] Extracted messages
63
+ def parse
64
+ content = IO.read(@path)
36
65
  src = ERB.new(content).src
37
66
 
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)
67
+ # Force the src encoding back to the encoding in magic comment
68
+ # or original content.
69
+ encoding = detect_encoding(src) || content.encoding
70
+ src.force_encoding(encoding)
43
71
 
44
- # Remove magic comment prepended by erb in Ruby 1.9.
45
- src = src.gsub(MAGIC_COMMENT, "")
46
- end
72
+ # Remove magic comment prepended by erb in Ruby 1.9.
73
+ src = src.gsub(MAGIC_COMMENT, "")
47
74
 
48
- erb = src.split(/$/)
49
- RubyParser.parse_lines(file, erb)
75
+ RubyParser.new(@path, @options).parse_source(src)
50
76
  end
51
77
 
52
78
  def detect_encoding(erb_source)
@@ -56,13 +82,6 @@ module GetText
56
82
  nil
57
83
  end
58
84
  end
59
-
60
- def target?(file) # :nodoc:
61
- @config[:extnames].each do |v|
62
- return true if File.extname(file) == v
63
- end
64
- false
65
- end
66
85
  end
67
86
  end
68
87