gettext 3.2.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.
- checksums.yaml +4 -4
- data/README.md +276 -198
- data/Rakefile +7 -4
- data/doc/text/news.md +451 -0
- data/gettext.gemspec +10 -7
- data/lib/gettext/locale_path.rb +17 -9
- data/lib/gettext/mo.rb +12 -19
- data/lib/gettext/po.rb +4 -4
- data/lib/gettext/po_entry.rb +47 -27
- data/lib/gettext/po_parser.rb +65 -59
- data/lib/gettext/text_domain.rb +1 -1
- data/lib/gettext/text_domain_manager.rb +6 -5
- data/lib/gettext/tools/msgcat.rb +9 -2
- data/lib/gettext/tools/msginit.rb +226 -54
- data/lib/gettext/tools/msgmerge.rb +24 -6
- data/lib/gettext/tools/parser/erb.rb +9 -1
- data/lib/gettext/tools/parser/erubi.rb +88 -0
- data/lib/gettext/tools/parser/glade.rb +38 -40
- data/lib/gettext/tools/parser/gtk_builder_ui_definitions.rb +129 -0
- data/lib/gettext/tools/parser/ruby.rb +288 -221
- data/lib/gettext/tools/task.rb +4 -5
- data/lib/gettext/tools/xgettext.rb +21 -10
- data/lib/gettext/version.rb +3 -3
- 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/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/bg/gettext.edit.po +81 -572
- data/po/bg/gettext.po +7 -409
- data/po/bs/gettext.edit.po +81 -572
- data/po/bs/gettext.po +7 -409
- data/po/ca/gettext.edit.po +81 -572
- data/po/ca/gettext.po +7 -409
- data/po/cs/gettext.edit.po +81 -572
- data/po/cs/gettext.po +7 -409
- data/po/de/gettext.edit.po +81 -572
- data/po/de/gettext.po +7 -409
- data/po/el/gettext.edit.po +81 -572
- data/po/el/gettext.po +7 -409
- data/po/eo/gettext.edit.po +81 -572
- data/po/eo/gettext.po +7 -409
- data/po/es/gettext.edit.po +81 -572
- data/po/es/gettext.po +7 -409
- data/po/et/gettext.edit.po +81 -572
- data/po/et/gettext.po +7 -409
- data/po/fr/gettext.edit.po +81 -572
- data/po/fr/gettext.po +7 -409
- data/po/gettext.pot +93 -645
- data/po/hr/gettext.edit.po +81 -572
- data/po/hr/gettext.po +7 -409
- data/po/hu/gettext.edit.po +81 -572
- data/po/hu/gettext.po +7 -409
- data/po/it/gettext.edit.po +81 -572
- data/po/it/gettext.po +7 -409
- data/po/ja/gettext.edit.po +83 -574
- data/po/ja/gettext.po +9 -411
- data/po/ko/gettext.edit.po +81 -572
- data/po/ko/gettext.po +7 -409
- data/po/lv/gettext.edit.po +81 -572
- data/po/lv/gettext.po +7 -409
- data/po/nb/gettext.edit.po +81 -572
- data/po/nb/gettext.po +7 -409
- data/po/nl/gettext.edit.po +81 -572
- data/po/nl/gettext.po +7 -409
- data/po/pt_BR/gettext.edit.po +81 -572
- data/po/pt_BR/gettext.po +7 -409
- data/po/ru/gettext.edit.po +81 -572
- data/po/ru/gettext.po +7 -409
- data/po/sr/gettext.edit.po +81 -572
- data/po/sr/gettext.po +7 -409
- data/po/sv/gettext.edit.po +81 -572
- data/po/sv/gettext.po +7 -409
- data/po/uk/gettext.edit.po +81 -572
- data/po/uk/gettext.po +7 -409
- data/po/vi/gettext.edit.po +81 -572
- data/po/vi/gettext.po +7 -409
- data/po/zh/gettext.edit.po +81 -572
- data/po/zh/gettext.po +7 -409
- data/po/zh_TW/gettext.edit.po +81 -572
- data/po/zh_TW/gettext.po +7 -409
- data/samples/cgi/po/helloerb1.pot +3 -3
- data/samples/cgi/po/helloerb2.pot +3 -3
- data/samples/cgi/po/hellolib.pot +3 -3
- data/samples/cgi/po/main.pot +3 -3
- data/samples/po/bg/hello_gtk_builder.edit.po +15 -0
- data/samples/po/bg/hello_gtk_builder.po +12 -0
- data/samples/po/bs/hello_gtk_builder.edit.po +15 -0
- data/samples/po/bs/hello_gtk_builder.po +12 -0
- data/samples/po/ca/hello_gtk_builder.edit.po +15 -0
- data/samples/po/ca/hello_gtk_builder.po +12 -0
- data/samples/po/cs/hello_gtk_builder.edit.po +15 -0
- data/samples/po/cs/hello_gtk_builder.po +12 -0
- data/samples/po/de/hello_gtk_builder.edit.po +15 -0
- data/samples/po/de/hello_gtk_builder.po +12 -0
- data/samples/po/el/hello_gtk_builder.edit.po +15 -0
- data/samples/po/el/hello_gtk_builder.po +12 -0
- data/samples/po/eo/hello_gtk_builder.edit.po +15 -0
- data/samples/po/eo/hello_gtk_builder.po +12 -0
- data/samples/po/es/hello_gtk_builder.edit.po +15 -0
- data/samples/po/es/hello_gtk_builder.po +12 -0
- data/samples/po/fr/hello_gtk_builder.edit.po +15 -0
- data/samples/po/fr/hello_gtk_builder.po +12 -0
- data/samples/po/hello.pot +3 -3
- data/samples/po/hello2.pot +4 -4
- data/samples/po/hello_glade2.pot +8 -5
- data/samples/po/hello_gtk2.pot +4 -4
- data/samples/po/hello_gtk_builder.pot +18 -4
- data/samples/po/hello_noop.pot +4 -4
- data/samples/po/hello_plural.pot +4 -4
- data/samples/po/hello_tk.pot +4 -4
- data/samples/po/hr/hello_gtk_builder.edit.po +15 -0
- data/samples/po/hr/hello_gtk_builder.po +12 -0
- data/samples/po/hu/hello_gtk_builder.edit.po +15 -0
- data/samples/po/hu/hello_gtk_builder.po +12 -0
- data/samples/po/it/hello_gtk_builder.edit.po +15 -0
- data/samples/po/it/hello_gtk_builder.po +12 -0
- data/samples/po/ja/hello_gtk_builder.edit.po +15 -0
- data/samples/po/ja/hello_gtk_builder.po +12 -0
- data/samples/po/ko/hello_gtk_builder.edit.po +15 -0
- data/samples/po/ko/hello_gtk_builder.po +12 -0
- data/samples/po/lv/hello_gtk_builder.edit.po +15 -0
- data/samples/po/lv/hello_gtk_builder.po +12 -0
- data/samples/po/nb/hello_gtk_builder.edit.po +15 -0
- data/samples/po/nb/hello_gtk_builder.po +12 -0
- data/samples/po/nl/hello_gtk_builder.edit.po +15 -0
- data/samples/po/nl/hello_gtk_builder.po +12 -0
- data/samples/po/pt_BR/hello_gtk_builder.edit.po +15 -0
- data/samples/po/pt_BR/hello_gtk_builder.po +12 -0
- data/samples/po/ru/hello_gtk_builder.edit.po +15 -0
- data/samples/po/ru/hello_gtk_builder.po +12 -0
- data/samples/po/sr/hello_gtk_builder.edit.po +15 -0
- data/samples/po/sr/hello_gtk_builder.po +12 -0
- data/samples/po/sv/hello_gtk_builder.edit.po +15 -0
- data/samples/po/sv/hello_gtk_builder.po +12 -0
- data/samples/po/uk/hello_gtk_builder.edit.po +15 -0
- data/samples/po/uk/hello_gtk_builder.po +12 -0
- data/samples/po/vi/hello_gtk_builder.edit.po +15 -0
- data/samples/po/vi/hello_gtk_builder.po +12 -0
- data/samples/po/zh/hello_gtk_builder.edit.po +15 -0
- data/samples/po/zh/hello_gtk_builder.po +12 -0
- data/samples/po/zh_TW/hello_gtk_builder.edit.po +15 -0
- data/samples/po/zh_TW/hello_gtk_builder.po +12 -0
- data/src/po_parser.ry +48 -42
- data/test/fixtures/_/backtick.rb +30 -0
- data/test/fixtures/_/block_parameter.rb +2 -2
- data/test/fixtures/_/double_quote_in_double_quote.rb +2 -2
- data/test/fixtures/_/double_quote_in_single_quote.rb +2 -2
- data/test/fixtures/_/literal_concatenation_with_continuation_line.rb +2 -2
- data/test/fixtures/_/middle_new_line.rb +2 -2
- data/test/fixtures/_/multiple_lines_literal.rb +2 -2
- data/test/fixtures/_/multiple_messages_in_same_line.rb +2 -2
- data/test/fixtures/_/multiple_same_messages.rb +2 -2
- data/test/fixtures/_/one_line.rb +2 -2
- data/test/fixtures/_/one_new_line.rb +2 -2
- data/test/fixtures/_/percent_strings.rb +55 -0
- data/test/fixtures/_/pipe.rb +32 -0
- data/test/{gettext-test-utils.rb → fixtures/_/quoted_symbol.rb} +13 -23
- data/test/fixtures/_.rb +10 -1
- data/test/fixtures/erb/case.rhtml +16 -0
- data/test/fixtures/erb/minus.rhtml +12 -0
- data/test/fixtures/erb/non_ascii.rhtml +1 -0
- data/test/fixtures/glade/3.glade +63 -0
- data/test/fixtures/gtk_builder_ui_definitions.ui +68 -0
- data/test/fixtures/multi_text_domain.rb +12 -12
- data/test/fixtures/np_.rb +1 -1
- data/test/fixtures/ns_/custom.rb +2 -2
- data/test/fixtures/ns_.rb +1 -1
- data/test/fixtures/p_.rb +1 -1
- data/test/fixtures/ruby/percent_lower_i.rb +1 -0
- data/test/fixtures/ruby/percent_lower_w.rb +1 -0
- data/test/fixtures/ruby/percent_upper_i.rb +1 -0
- data/test/fixtures/ruby/percent_upper_w.rb +1 -0
- data/test/fixtures/s_/custom.rb +2 -2
- data/test/fixtures/s_.rb +1 -1
- data/test/fixtures/simple.rb +5 -1
- data/test/fixtures/upper_nn_.rb +77 -0
- data/test/helper.rb +99 -0
- data/test/locale/fr/LC_MESSAGES/plural_error.mo +0 -0
- data/test/locale/fr/LC_MESSAGES/test1.mo +0 -0
- data/test/locale/fr_BE/LC_MESSAGES/test1.mo +0 -0
- data/test/locale/fr_BE_Foo/LC_MESSAGES/test1.mo +0 -0
- data/test/locale/ja/LC_MESSAGES/_.mo +0 -0
- data/test/po/_.pot +28 -4
- data/test/po/backslash.pot +6 -4
- data/test/po/fr/plural_error.po +7 -0
- data/test/po/fr/test1.po +7 -0
- data/test/po/fr_BE/test1.po +24 -0
- data/test/po/fr_BE_Foo/test1.po +20 -0
- data/test/po/hello.pot +3 -3
- data/test/po/ja/_.edit.po +27 -3
- data/test/po/ja/_.po +20 -2
- data/test/po/ja/hello.edit.po +0 -1
- data/test/po/non_ascii.pot +4 -4
- data/test/po/np_.pot +8 -5
- data/test/po/ns_.pot +6 -4
- data/test/po/p_.pot +3 -3
- data/test/po/s_.pot +6 -4
- data/test/po/untranslated.pot +4 -4
- data/test/run-test.rb +2 -3
- data/test/test_class_info.rb +8 -9
- data/test/test_gettext.rb +30 -1
- data/test/test_locale_path.rb +12 -4
- data/test/test_parser.rb +113 -25
- data/test/test_po_entry.rb +21 -17
- data/test/test_po_parser.rb +49 -4
- data/test/test_string.rb +9 -5
- data/test/tools/parser/test_glade.rb +91 -0
- data/test/tools/parser/test_gtk_builder_ui_definitions.rb +63 -0
- data/test/tools/parser/test_ruby.rb +76 -39
- data/test/tools/test_msgcat.rb +21 -1
- data/test/tools/test_msginit.rb +82 -3
- data/test/tools/test_msgmerge.rb +81 -6
- data/test/tools/test_xgettext.rb +106 -5
- metadata +82 -34
- data/lib/gettext/tools/parser/haml.rb +0 -61
- /data/test/fixtures/{gladeparser.glade → glade/2.glade} +0 -0
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# Copyright (C) 2020 Sutou Kouhei <kou@clear-code.com>
|
|
2
|
+
#
|
|
3
|
+
# License: Ruby's or LGPL
|
|
4
|
+
#
|
|
5
|
+
# This library is free software: you can redistribute it and/or modify
|
|
6
|
+
# it under the terms of the GNU Lesser General Public License as published by
|
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
8
|
+
# (at your option) any later version.
|
|
9
|
+
#
|
|
10
|
+
# This library is distributed in the hope that it will be useful,
|
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
+
# GNU Lesser General Public License for more details.
|
|
14
|
+
#
|
|
15
|
+
# You should have received a copy of the GNU Lesser General Public License
|
|
16
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
17
|
+
|
|
18
|
+
require "English"
|
|
19
|
+
require "cgi"
|
|
20
|
+
require "strscan"
|
|
21
|
+
|
|
22
|
+
require "gettext/po_entry"
|
|
23
|
+
|
|
24
|
+
module GetText
|
|
25
|
+
class GtkBuilderUIDefinitionsParser
|
|
26
|
+
@config = {
|
|
27
|
+
:extnames => [".ui", ".glade"]
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
class << self
|
|
31
|
+
# Sets some preferences to parse GtkBuilder UI definitions files.
|
|
32
|
+
# * config: a Hash of the config. It can takes some values below:
|
|
33
|
+
# * :extnames: An Array of target files extension.
|
|
34
|
+
# Default is [".ui", ".glade"].
|
|
35
|
+
def init(config)
|
|
36
|
+
config.each do |k, v|
|
|
37
|
+
@config[k] = v
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def target?(file) # :nodoc:
|
|
42
|
+
@config[:extnames].each do |extname|
|
|
43
|
+
next unless File.extname(file) == extname
|
|
44
|
+
next unless File.read(file).include?("<interface>")
|
|
45
|
+
return true
|
|
46
|
+
end
|
|
47
|
+
false
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def parse(path, options={})
|
|
51
|
+
parser = new(path, options)
|
|
52
|
+
parser.parse
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def initialize(path, options={})
|
|
57
|
+
@path = path
|
|
58
|
+
@options = options
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def parse # :nodoc:
|
|
62
|
+
File.open(@path) do |file|
|
|
63
|
+
po = []
|
|
64
|
+
start_line_no = nil
|
|
65
|
+
property = nil
|
|
66
|
+
file.each_line do |line|
|
|
67
|
+
case line
|
|
68
|
+
when /<property/
|
|
69
|
+
property = $POSTMATCH
|
|
70
|
+
start_line_no = file.lineno
|
|
71
|
+
if /<\/property>/ =~ property
|
|
72
|
+
property << $PREMATCH
|
|
73
|
+
add_po_entry(po, property, start_line_no)
|
|
74
|
+
property = nil
|
|
75
|
+
end
|
|
76
|
+
when /<\/property>/
|
|
77
|
+
property << $PREMATCH
|
|
78
|
+
add_po_entry(po, property, start_line_no)
|
|
79
|
+
property = nil
|
|
80
|
+
else
|
|
81
|
+
property << line if property
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
po
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
private
|
|
89
|
+
def add_po_entry(po, property, line_no)
|
|
90
|
+
raw_attributes, raw_data_and_close_tag = property.split(">", 2)
|
|
91
|
+
raw_data, _close_tag = raw_data_and_close_tag.split("<", 2)
|
|
92
|
+
return if raw_data.empty?
|
|
93
|
+
|
|
94
|
+
attributes = parse_attributes(raw_attributes)
|
|
95
|
+
return unless attributes["translatable"] == "yes"
|
|
96
|
+
|
|
97
|
+
data = CGI.unescapeHTML(raw_data)
|
|
98
|
+
context = attributes["context"]
|
|
99
|
+
if context
|
|
100
|
+
po_entry = POEntry.new(:msgctxt)
|
|
101
|
+
po_entry.msgctxt = context
|
|
102
|
+
else
|
|
103
|
+
po_entry = POEntry.new(:normal)
|
|
104
|
+
end
|
|
105
|
+
po_entry.msgid = data
|
|
106
|
+
po_entry.references << "#{@path}:#{line_no}"
|
|
107
|
+
po << po_entry
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def parse_attributes(raw_attributes)
|
|
111
|
+
scanner = StringScanner.new(raw_attributes)
|
|
112
|
+
attributes = {}
|
|
113
|
+
loop do
|
|
114
|
+
scanner.scan(/\s*/m)
|
|
115
|
+
break if scanner.eos?
|
|
116
|
+
name = scanner.scan(/[^=]+/)
|
|
117
|
+
break if name.nil?
|
|
118
|
+
break unless scanner.scan(/=/)
|
|
119
|
+
quote = scanner.scan(/["']/)
|
|
120
|
+
break if quote.nil?
|
|
121
|
+
value = scanner.scan(/[^#{Regexp.escape(quote)}]+/m)
|
|
122
|
+
break if value.nil?
|
|
123
|
+
break unless scanner.scan(/#{Regexp.escape(quote)}/)
|
|
124
|
+
attributes[name] = CGI.unescapeHTML(value)
|
|
125
|
+
end
|
|
126
|
+
attributes
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
1
|
=begin
|
|
3
2
|
parser/ruby.rb - parser for ruby script
|
|
4
3
|
|
|
5
|
-
Copyright (C) 2013-
|
|
4
|
+
Copyright (C) 2013-2021 Sutou Kouhei <kou@clear-code.com>
|
|
6
5
|
Copyright (C) 2003-2009 Masao Mutoh
|
|
7
6
|
Copyright (C) 2005 speakillof
|
|
8
7
|
Copyright (C) 2001,2002 Yasushi Shoji, Masao Mutoh
|
|
@@ -12,162 +11,324 @@
|
|
|
12
11
|
|
|
13
12
|
=end
|
|
14
13
|
|
|
15
|
-
require "
|
|
14
|
+
require "ripper"
|
|
16
15
|
require "stringio"
|
|
17
|
-
require "gettext/po_entry"
|
|
18
16
|
|
|
19
|
-
require "
|
|
17
|
+
require "gettext/po_entry"
|
|
20
18
|
|
|
21
19
|
module GetText
|
|
22
|
-
class
|
|
23
|
-
class
|
|
20
|
+
class RubyParser
|
|
21
|
+
class POExtractor < Ripper::Filter
|
|
22
|
+
ID = ["gettext", "_", "N_", "sgettext", "s_"]
|
|
23
|
+
PLURAL_ID = ["ngettext", "n_", "Nn_", "ns_", "nsgettext"]
|
|
24
|
+
MSGCTXT_ID = ["pgettext", "p_"]
|
|
25
|
+
MSGCTXT_PLURAL_ID = ["npgettext", "np_"]
|
|
26
|
+
|
|
27
|
+
attr_accessor :use_comment
|
|
28
|
+
attr_accessor :comment_tag
|
|
24
29
|
def initialize(*args)
|
|
25
|
-
super
|
|
30
|
+
super(*args)
|
|
31
|
+
@start_block = false
|
|
32
|
+
@in_block_arguments = false
|
|
33
|
+
@ignore_next_comma = false
|
|
34
|
+
@need_definition_name = false
|
|
35
|
+
@current_po_entry = nil
|
|
36
|
+
@current_po_entry_nth_attribute = 0
|
|
37
|
+
@use_comment = false
|
|
38
|
+
@comment_tag = nil
|
|
39
|
+
@last_comment = ""
|
|
40
|
+
@reset_comment = false
|
|
26
41
|
@string_mark_stack = []
|
|
42
|
+
@string_stack = []
|
|
27
43
|
end
|
|
28
44
|
|
|
29
|
-
def
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
when "\\n"
|
|
36
|
-
"\n"
|
|
37
|
-
when "\\t"
|
|
38
|
-
"\t"
|
|
39
|
-
when "\\\\"
|
|
40
|
-
"\\"
|
|
41
|
-
when "\\\""
|
|
42
|
-
"\""
|
|
43
|
-
when "\\\#"
|
|
44
|
-
"#"
|
|
45
|
-
else
|
|
46
|
-
data
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
|
-
else
|
|
50
|
-
output << token.gsub(/\\./) do |data|
|
|
51
|
-
case data
|
|
52
|
-
when "\\\\"
|
|
53
|
-
"\\"
|
|
54
|
-
when "\\'"
|
|
55
|
-
"'"
|
|
56
|
-
else
|
|
57
|
-
data
|
|
58
|
-
end
|
|
59
|
-
end
|
|
45
|
+
def process_on_op(token, po)
|
|
46
|
+
if @start_block
|
|
47
|
+
@in_block_arguments = (token == "|")
|
|
48
|
+
else
|
|
49
|
+
if @in_block_arguments and token == "|"
|
|
50
|
+
@in_block_arguments = false
|
|
60
51
|
end
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
52
|
+
end
|
|
53
|
+
po
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def process_on_kw(token, po)
|
|
57
|
+
store_po_entry(po)
|
|
58
|
+
case token
|
|
59
|
+
when "do"
|
|
60
|
+
@start_block = true
|
|
61
|
+
end
|
|
62
|
+
po
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def process_on_lbrace(token, po)
|
|
66
|
+
store_po_entry(po)
|
|
67
|
+
@start_block = (state == Ripper::EXPR_BEG)
|
|
68
|
+
po
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def process_on_ident(token, po)
|
|
72
|
+
store_po_entry(po)
|
|
73
|
+
|
|
74
|
+
return po if @in_block_arguments
|
|
75
|
+
return po if state.allbits?(Ripper::EXPR_ENDFN)
|
|
76
|
+
|
|
77
|
+
case token
|
|
78
|
+
when *ID
|
|
79
|
+
@current_po_entry = POEntry.new(:normal)
|
|
80
|
+
when *PLURAL_ID
|
|
81
|
+
@current_po_entry = POEntry.new(:plural)
|
|
82
|
+
when *MSGCTXT_ID
|
|
83
|
+
@current_po_entry = POEntry.new(:msgctxt)
|
|
84
|
+
when *MSGCTXT_PLURAL_ID
|
|
85
|
+
@current_po_entry = POEntry.new(:msgctxt_plural)
|
|
86
|
+
end
|
|
87
|
+
if @current_po_entry
|
|
88
|
+
@current_po_entry.add_comment(@last_comment) unless @last_comment.empty?
|
|
89
|
+
@last_comment = ""
|
|
90
|
+
@current_po_entry.references << "#{filename}:#{lineno}"
|
|
91
|
+
@current_po_entry_nth_attribute = 0
|
|
92
|
+
end
|
|
93
|
+
po
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def process_on_const(token, po)
|
|
97
|
+
case token
|
|
98
|
+
when "N_", "Nn_"
|
|
99
|
+
# TODO: Check the next token is :on_lparen
|
|
100
|
+
process_on_ident(token, po)
|
|
101
|
+
else
|
|
102
|
+
po
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def process_on_comment(token, po)
|
|
107
|
+
@last_comment = "" if @reset_comment
|
|
108
|
+
@reset_comment = false
|
|
109
|
+
if @last_comment.empty?
|
|
110
|
+
content = token.gsub(/\A#\s*/, "").chomp
|
|
111
|
+
if comment_to_be_extracted?(content)
|
|
112
|
+
@last_comment << content
|
|
64
113
|
end
|
|
114
|
+
else
|
|
115
|
+
content = token.gsub(/\A#/, "").chomp
|
|
116
|
+
@last_comment << "\n"
|
|
117
|
+
@last_comment << content
|
|
118
|
+
end
|
|
119
|
+
po
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def process_on_sp(token, po)
|
|
123
|
+
po
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def process_on_tstring_beg(token, po)
|
|
127
|
+
if token.start_with?("%Q")
|
|
128
|
+
@string_mark_stack << "\""
|
|
129
|
+
elsif token.start_with?("%q")
|
|
130
|
+
@string_mark_stack << "'"
|
|
131
|
+
elsif token.start_with?("%")
|
|
132
|
+
@string_mark_stack << "\""
|
|
133
|
+
else
|
|
65
134
|
@string_mark_stack << token
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
135
|
+
end
|
|
136
|
+
@string_stack << ""
|
|
137
|
+
po
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def process_on_tstring_content(token, po)
|
|
141
|
+
case @string_mark_stack.last
|
|
142
|
+
when "\"", "`"
|
|
143
|
+
@string_stack.last << token.gsub(/\\./) do |data|
|
|
144
|
+
case data
|
|
145
|
+
when "\\n"
|
|
146
|
+
"\n"
|
|
147
|
+
when "\\t"
|
|
148
|
+
"\t"
|
|
149
|
+
when "\\\\"
|
|
150
|
+
"\\"
|
|
151
|
+
when "\\\""
|
|
152
|
+
"\""
|
|
153
|
+
when "\\\#"
|
|
154
|
+
"#"
|
|
155
|
+
else
|
|
156
|
+
data
|
|
157
|
+
end
|
|
70
158
|
end
|
|
71
159
|
else
|
|
72
|
-
|
|
73
|
-
|
|
160
|
+
@string_stack.last << token.gsub(/\\./) do |data|
|
|
161
|
+
case data
|
|
162
|
+
when "\\\\"
|
|
163
|
+
"\\"
|
|
164
|
+
when "\\'"
|
|
165
|
+
"'"
|
|
166
|
+
else
|
|
167
|
+
data
|
|
168
|
+
end
|
|
74
169
|
end
|
|
75
170
|
end
|
|
76
|
-
|
|
171
|
+
po
|
|
77
172
|
end
|
|
78
|
-
end
|
|
79
173
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
174
|
+
def process_on_tstring_end(token, po)
|
|
175
|
+
@ignore_next_comma = false
|
|
176
|
+
string_mark = @string_mark_stack.pop
|
|
177
|
+
case string_mark
|
|
178
|
+
when "\"", "'"
|
|
179
|
+
last_string = @string_stack.pop
|
|
180
|
+
if @current_po_entry and last_string
|
|
181
|
+
@current_po_entry[@current_po_entry_nth_attribute] =
|
|
182
|
+
(@current_po_entry[@current_po_entry_nth_attribute] || "") +
|
|
183
|
+
last_string
|
|
87
184
|
end
|
|
185
|
+
end
|
|
186
|
+
po
|
|
187
|
+
end
|
|
88
188
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
189
|
+
def process_on_heredoc_beg(token, po)
|
|
190
|
+
if token.end_with?("'")
|
|
191
|
+
@string_mark_stack << "'"
|
|
192
|
+
else
|
|
193
|
+
@string_mark_stack << "\""
|
|
194
|
+
end
|
|
195
|
+
@string_stack << ""
|
|
196
|
+
po
|
|
197
|
+
end
|
|
92
198
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
s = StringExtractor.new(s).parse("")
|
|
97
|
-
end
|
|
199
|
+
def process_on_heredoc_end(token, po)
|
|
200
|
+
process_on_tstring_end(token, po)
|
|
201
|
+
end
|
|
98
202
|
|
|
99
|
-
|
|
100
|
-
|
|
203
|
+
def process_on_regexp_beg(token, po)
|
|
204
|
+
@string_mark_stack << "\""
|
|
205
|
+
@string_stack << ""
|
|
206
|
+
po
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
def process_on_regexp_end(token, po)
|
|
210
|
+
@string_mark_stack.pop
|
|
211
|
+
@string_stack.pop
|
|
212
|
+
po
|
|
213
|
+
end
|
|
101
214
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
215
|
+
def process_on_embexpr_beg(token, po)
|
|
216
|
+
@current_po_entry = nil
|
|
217
|
+
@current_po_entry_nth_attribute = 0
|
|
218
|
+
po
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
def process_on_int(token, po)
|
|
222
|
+
@ignore_next_comma = true
|
|
223
|
+
po
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
def process_on_comma(token, po)
|
|
227
|
+
unless @ignore_next_comma
|
|
228
|
+
if @current_po_entry
|
|
229
|
+
@current_po_entry_nth_attribute += 1
|
|
109
230
|
end
|
|
110
231
|
end
|
|
232
|
+
po
|
|
233
|
+
end
|
|
111
234
|
|
|
112
|
-
|
|
235
|
+
def process_on_rparen(token, po)
|
|
236
|
+
store_po_entry(po)
|
|
237
|
+
po
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
def process_on_nl(token, po)
|
|
241
|
+
@reset_comment = true
|
|
242
|
+
po
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
def process_on_symbeg(token, po)
|
|
246
|
+
if token.start_with?("%s") or [":'", ":\""].include?(token)
|
|
247
|
+
@string_mark_stack << ":"
|
|
248
|
+
@string_stack << ""
|
|
249
|
+
end
|
|
250
|
+
po
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
def process_on_backtick(token, po)
|
|
254
|
+
@string_mark_stack << "`"
|
|
255
|
+
@string_stack << ""
|
|
256
|
+
po
|
|
113
257
|
end
|
|
114
|
-
return nil
|
|
115
|
-
end
|
|
116
258
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
259
|
+
def process_on_symbols_beg(token, po)
|
|
260
|
+
@string_mark_stack << "\""
|
|
261
|
+
@string_stack << ""
|
|
262
|
+
po
|
|
263
|
+
end
|
|
121
264
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
265
|
+
def process_on_qsymbols_beg(token, po)
|
|
266
|
+
@string_mark_stack << token
|
|
267
|
+
@string_stack << ""
|
|
268
|
+
po
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
def process_on_words_beg(token, po)
|
|
272
|
+
@string_mark_stack << "\""
|
|
273
|
+
@string_stack << ""
|
|
274
|
+
po
|
|
275
|
+
end
|
|
125
276
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
277
|
+
def process_on_qwords_beg(token, po)
|
|
278
|
+
@string_mark_stack << token
|
|
279
|
+
@string_stack << ""
|
|
280
|
+
po
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
def on_default(event, token, po)
|
|
284
|
+
trace(event, token) do
|
|
285
|
+
process_method = "process_#{event}"
|
|
286
|
+
start_block = @start_block
|
|
287
|
+
if respond_to?(process_method)
|
|
288
|
+
po = __send__(process_method, token, po)
|
|
289
|
+
end
|
|
290
|
+
if start_block and event != :on_sp
|
|
291
|
+
@start_block = false
|
|
292
|
+
end
|
|
293
|
+
po
|
|
131
294
|
end
|
|
132
295
|
end
|
|
133
|
-
return Token(TkCOMMENT_WITH_CONTENT, get_readed)
|
|
134
|
-
end
|
|
135
296
|
|
|
136
|
-
|
|
297
|
+
private
|
|
298
|
+
@@debug = ENV["GETTEXT_RUBY_PARSER_DEBUG"]
|
|
299
|
+
def debug?
|
|
300
|
+
@@debug
|
|
301
|
+
end
|
|
137
302
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
303
|
+
def trace(event_name, token)
|
|
304
|
+
if debug?
|
|
305
|
+
status = [
|
|
306
|
+
event_name,
|
|
307
|
+
token,
|
|
308
|
+
state,
|
|
309
|
+
]
|
|
310
|
+
status << :start_block if @start_block
|
|
311
|
+
status << :in_block_arguments if @in_block_arguments
|
|
312
|
+
pp status
|
|
313
|
+
end
|
|
314
|
+
yield
|
|
315
|
+
end
|
|
147
316
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
317
|
+
def store_po_entry(po)
|
|
318
|
+
return if @current_po_entry.nil?
|
|
319
|
+
po << @current_po_entry if @current_po_entry.msgid
|
|
320
|
+
@current_po_entry = nil
|
|
321
|
+
@current_po_entry_nth_attribute = 0
|
|
322
|
+
end
|
|
152
323
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
end
|
|
156
|
-
end
|
|
157
|
-
class POEntry
|
|
158
|
-
include POEntryForRubyParser
|
|
159
|
-
alias :initialize_old :initialize
|
|
160
|
-
def initialize(type)
|
|
161
|
-
initialize_old(type)
|
|
162
|
-
init_param
|
|
163
|
-
end
|
|
164
|
-
end
|
|
324
|
+
def comment_to_be_extracted?(comment)
|
|
325
|
+
return false unless @use_comment
|
|
165
326
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
327
|
+
return true if @comment_tag.nil?
|
|
328
|
+
|
|
329
|
+
comment.start_with?(@comment_tag)
|
|
330
|
+
end
|
|
331
|
+
end
|
|
171
332
|
|
|
172
333
|
class << self
|
|
173
334
|
def target?(file) # :nodoc:
|
|
@@ -282,106 +443,12 @@ module GetText
|
|
|
282
443
|
end
|
|
283
444
|
|
|
284
445
|
def parse_source(source)
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
rl.skip_space = true
|
|
290
|
-
#rl.readed_auto_clean_up = true
|
|
291
|
-
|
|
292
|
-
po_entry = nil
|
|
293
|
-
line_no = nil
|
|
294
|
-
last_comment = ""
|
|
295
|
-
reset_comment = false
|
|
296
|
-
ignore_next_comma = false
|
|
297
|
-
rl.parse do |tk|
|
|
298
|
-
begin
|
|
299
|
-
ignore_current_comma = ignore_next_comma
|
|
300
|
-
ignore_next_comma = false
|
|
301
|
-
case tk
|
|
302
|
-
when RubyToken::TkIDENTIFIER, RubyToken::TkCONSTANT
|
|
303
|
-
if store_po_entry(po, po_entry, line_no, last_comment)
|
|
304
|
-
last_comment = ""
|
|
305
|
-
end
|
|
306
|
-
if ID.include?(tk.name)
|
|
307
|
-
po_entry = POEntry.new(:normal)
|
|
308
|
-
elsif PLURAL_ID.include?(tk.name)
|
|
309
|
-
po_entry = POEntry.new(:plural)
|
|
310
|
-
elsif MSGCTXT_ID.include?(tk.name)
|
|
311
|
-
po_entry = POEntry.new(:msgctxt)
|
|
312
|
-
elsif MSGCTXT_PLURAL_ID.include?(tk.name)
|
|
313
|
-
po_entry = POEntry.new(:msgctxt_plural)
|
|
314
|
-
else
|
|
315
|
-
po_entry = nil
|
|
316
|
-
end
|
|
317
|
-
line_no = tk.line_no.to_s
|
|
318
|
-
when RubyToken::TkBITOR
|
|
319
|
-
po_entry = nil
|
|
320
|
-
when RubyToken::TkSTRING, RubyToken::TkDSTRING
|
|
321
|
-
po_entry.set_current_attribute tk.value if po_entry
|
|
322
|
-
when RubyToken::TkPLUS, RubyToken::TkNL
|
|
323
|
-
#do nothing
|
|
324
|
-
when RubyToken::TkINTEGER
|
|
325
|
-
ignore_next_comma = true
|
|
326
|
-
when RubyToken::TkCOMMA
|
|
327
|
-
unless ignore_current_comma
|
|
328
|
-
po_entry.advance_to_next_attribute if po_entry
|
|
329
|
-
end
|
|
330
|
-
else
|
|
331
|
-
if store_po_entry(po, po_entry, line_no, last_comment)
|
|
332
|
-
po_entry = nil
|
|
333
|
-
last_comment = ""
|
|
334
|
-
end
|
|
335
|
-
end
|
|
336
|
-
rescue
|
|
337
|
-
$stderr.print "\n\nError"
|
|
338
|
-
$stderr.print " parsing #{@path}:#{tk.line_no}\n\t #{source.lines.to_a[tk.line_no - 1]}" if tk
|
|
339
|
-
$stderr.print "\n #{$!.inspect} in\n"
|
|
340
|
-
$stderr.print $!.backtrace.join("\n")
|
|
341
|
-
$stderr.print "\n"
|
|
342
|
-
exit 1
|
|
343
|
-
end
|
|
344
|
-
|
|
345
|
-
case tk
|
|
346
|
-
when RubyToken::TkCOMMENT_WITH_CONTENT
|
|
347
|
-
last_comment = "" if reset_comment
|
|
348
|
-
if last_comment.empty?
|
|
349
|
-
comment1 = tk.value.lstrip
|
|
350
|
-
if comment_to_be_extracted?(comment1)
|
|
351
|
-
last_comment += comment1
|
|
352
|
-
end
|
|
353
|
-
else
|
|
354
|
-
last_comment += "\n"
|
|
355
|
-
last_comment += tk.value
|
|
356
|
-
end
|
|
357
|
-
reset_comment = false
|
|
358
|
-
when RubyToken::TkNL
|
|
359
|
-
else
|
|
360
|
-
reset_comment = true
|
|
361
|
-
end
|
|
446
|
+
extractor = POExtractor.new(source, @path)
|
|
447
|
+
if @options.key?(:comment_tag)
|
|
448
|
+
extractor.use_comment = true
|
|
449
|
+
extractor.comment_tag = @options[:comment_tag]
|
|
362
450
|
end
|
|
363
|
-
|
|
364
|
-
end
|
|
365
|
-
|
|
366
|
-
private
|
|
367
|
-
def store_po_entry(po, po_entry, line_no, last_comment) #:nodoc:
|
|
368
|
-
if po_entry && po_entry.msgid
|
|
369
|
-
po_entry.references << @path + ":" + line_no
|
|
370
|
-
po_entry.add_comment(last_comment) unless last_comment.empty?
|
|
371
|
-
po << po_entry
|
|
372
|
-
true
|
|
373
|
-
else
|
|
374
|
-
false
|
|
375
|
-
end
|
|
376
|
-
end
|
|
377
|
-
|
|
378
|
-
def comment_to_be_extracted?(comment)
|
|
379
|
-
return false unless @options.has_key?(:comment_tag)
|
|
380
|
-
|
|
381
|
-
tag = @options[:comment_tag]
|
|
382
|
-
return true if tag.nil?
|
|
383
|
-
|
|
384
|
-
/\A#{Regexp.escape(tag)}/ === comment
|
|
451
|
+
extractor.parse([])
|
|
385
452
|
end
|
|
386
453
|
end
|
|
387
454
|
end
|