gettext 2.3.9 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.yardopts +1 -0
- data/README.rdoc +28 -23
- data/Rakefile +29 -21
- data/doc/text/news.md +57 -0
- data/gettext.gemspec +1 -1
- data/lib/gettext.rb +13 -29
- data/lib/gettext/cgi.rb +1 -1
- data/lib/gettext/{runtime/class_info.rb → class_info.rb} +1 -1
- data/lib/gettext/{runtime/locale_path.rb → locale_path.rb} +1 -2
- data/lib/gettext/{runtime/mo.rb → mo.rb} +18 -33
- data/lib/gettext/{tools/po.rb → po.rb} +1 -1
- data/lib/gettext/{tools/po_entry.rb → po_entry.rb} +8 -4
- data/lib/gettext/{tools/poparser.rb → po_parser.rb} +41 -44
- data/lib/gettext/{runtime/textdomain.rb → text_domain.rb} +6 -16
- data/lib/gettext/text_domain_group.rb +26 -0
- data/lib/gettext/{runtime/textdomain_manager.rb → text_domain_manager.rb} +40 -40
- data/lib/gettext/tools.rb +1 -182
- data/lib/gettext/tools/msgfmt.rb +1 -1
- data/lib/gettext/tools/msginit.rb +1 -1
- data/lib/gettext/tools/msgmerge.rb +2 -221
- data/lib/gettext/tools/parser/erb.rb +49 -30
- data/lib/gettext/tools/parser/glade.rb +44 -36
- data/lib/gettext/tools/parser/ruby.rb +126 -37
- data/lib/gettext/tools/task.rb +225 -0
- data/lib/gettext/tools/xgettext.rb +25 -28
- data/lib/gettext/version.rb +1 -1
- data/locale/bg/LC_MESSAGES/gettext.mo +0 -0
- data/locale/bs/LC_MESSAGES/gettext.mo +0 -0
- data/locale/ca/LC_MESSAGES/gettext.mo +0 -0
- data/locale/cs/LC_MESSAGES/gettext.mo +0 -0
- data/locale/de/LC_MESSAGES/gettext.mo +0 -0
- data/locale/el/LC_MESSAGES/gettext.mo +0 -0
- data/locale/eo/LC_MESSAGES/gettext.mo +0 -0
- data/locale/es/LC_MESSAGES/gettext.mo +0 -0
- data/locale/et/LC_MESSAGES/gettext.mo +0 -0
- data/locale/fr/LC_MESSAGES/gettext.mo +0 -0
- data/locale/hr/LC_MESSAGES/gettext.mo +0 -0
- data/locale/hu/LC_MESSAGES/gettext.mo +0 -0
- data/locale/it/LC_MESSAGES/gettext.mo +0 -0
- data/locale/ja/LC_MESSAGES/gettext.mo +0 -0
- data/locale/ko/LC_MESSAGES/gettext.mo +0 -0
- data/locale/lv/LC_MESSAGES/gettext.mo +0 -0
- data/locale/nb/LC_MESSAGES/gettext.mo +0 -0
- data/locale/nl/LC_MESSAGES/gettext.mo +0 -0
- data/locale/pt_BR/LC_MESSAGES/gettext.mo +0 -0
- data/locale/ru/LC_MESSAGES/gettext.mo +0 -0
- data/locale/sr/LC_MESSAGES/gettext.mo +0 -0
- data/locale/sv/LC_MESSAGES/gettext.mo +0 -0
- data/locale/uk/LC_MESSAGES/gettext.mo +0 -0
- data/locale/vi/LC_MESSAGES/gettext.mo +0 -0
- data/locale/zh/LC_MESSAGES/gettext.mo +0 -0
- data/locale/zh_TW/LC_MESSAGES/gettext.mo +0 -0
- data/po/gettext.pot +171 -97
- data/samples/hello.rb +3 -2
- data/samples/hello2.rb +2 -1
- data/samples/hello_gtk2.rb +4 -1
- data/samples/hello_gtk_builder.rb +32 -0
- data/samples/hello_gtk_builder.ui +46 -0
- data/samples/hello_noop.rb +2 -1
- data/samples/hello_plural.rb +2 -1
- data/samples/hello_tk.rb +2 -1
- data/src/{poparser.ry → po_parser.ry} +31 -35
- data/test/fixtures/N_.rb +1 -1
- data/test/fixtures/_/double_quote_in_double_quote.rb +32 -0
- data/test/fixtures/_/double_quote_in_single_quote.rb +32 -0
- data/test/fixtures/_/literal_concatenation_with_continuation_line.rb +36 -0
- data/test/fixtures/_/middle_new_line.rb +32 -0
- data/test/fixtures/_/multiple_lines_literal.rb +35 -0
- data/test/fixtures/_/multiple_messages_in_same_line.rb +32 -0
- data/test/fixtures/_/multiple_same_messages.rb +36 -0
- data/{lib/gettext/runtime/mofile.rb → test/fixtures/_/one_new_line.rb} +12 -6
- data/test/fixtures/{multi_textdomain.rb → multi_text_domain.rb} +1 -1
- data/test/fixtures/non_ascii.rb +1 -1
- data/test/fixtures/simple.rb +1 -1
- data/test/fixtures/untranslated.rb +1 -1
- data/test/gettext-test-utils.rb +1 -24
- data/test/po/ja/_.po +63 -13
- data/test/po/ja/non_ascii.po +2 -3
- data/test/po/ja/untranslated.po +1 -1
- data/test/test_class_info.rb +2 -2
- data/test/test_gettext.rb +11 -11
- data/test/test_mo.rb +2 -2
- data/test/test_parser.rb +93 -96
- data/test/test_po_entry.rb +237 -146
- data/test/test_po_parser.rb +107 -98
- data/test/test_string.rb +1 -1
- data/test/{test_textdomain_bind.rb → test_text_domain_bind.rb} +6 -6
- data/test/{test_textdomain_multi.rb → test_text_domain_multi.rb} +5 -5
- data/test/{test_textdomain_toplevel.rb → test_text_domain_toplevel.rb} +1 -1
- data/test/test_thread.rb +1 -1
- data/test/tools/files/simple_translation.rb +1 -1
- data/test/{parser → tools/parser}/test_ruby.rb +110 -14
- data/test/tools/test_msgmerge.rb +17 -276
- data/test/tools/test_po.rb +1 -1
- data/test/tools/test_xgettext.rb +175 -144
- metadata +59 -33
- data/lib/gettext/core_ext/iconv.rb +0 -110
- data/lib/gettext/core_ext/string.rb +0 -91
- data/lib/gettext/parser/erb.rb +0 -5
- data/lib/gettext/parser/glade.rb +0 -5
- data/lib/gettext/parser/ruby.rb +0 -172
- data/lib/gettext/runtime/textdomain_group.rb +0 -26
- data/lib/gettext/task.rb +0 -203
- data/lib/gettext/utils.rb +0 -39
- data/test/test_po_generation.rb +0 -45
- data/test/tools/test_tools.rb +0 -61
data/lib/gettext/tools.rb
CHANGED
@@ -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/
|
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'
|
data/lib/gettext/tools/msgfmt.rb
CHANGED
@@ -23,231 +23,12 @@
|
|
23
23
|
require "optparse"
|
24
24
|
require "text"
|
25
25
|
require "gettext"
|
26
|
-
require "gettext/
|
27
|
-
require "gettext/
|
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
|
-
#
|
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
|
-
|
17
|
-
extend self
|
18
|
-
|
16
|
+
class ErbParser
|
19
17
|
@config = {
|
20
18
|
:extnames => ['.rhtml', '.erb']
|
21
19
|
}
|
22
20
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
config
|
28
|
-
|
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
|
-
|
35
|
-
|
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
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
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
|
-
|
45
|
-
|
46
|
-
end
|
72
|
+
# Remove magic comment prepended by erb in Ruby 1.9.
|
73
|
+
src = src.gsub(MAGIC_COMMENT, "")
|
47
74
|
|
48
|
-
|
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
|
|