gettext 2.3.9 → 3.0.0
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.
- 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
|
|