amatsuda-i18n_generators 0.3.1 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/generators/i18n/i18n_generator.rb +4 -1
- data/generators/i18n/lib/yaml.rb +185 -0
- data/generators/i18n/templates/translation.yml +1 -19
- data/generators/i18n_locale/i18n_locale_command.rb +9 -4
- data/generators/i18n_locale/lib/cldr.rb +9 -5
- data/generators/i18n_translation/i18n_translation_command.rb +64 -44
- data/generators/i18n_translation/lib/erb_executer.rb +3 -1
- data/generators/i18n_translation/lib/recording_backend.rb +2 -1
- data/generators/i18n_translation/lib/through_ryoku.rb +5 -3
- data/spec/i18n_locale_command_spec.rb +1 -1
- data/spec/i18n_translation_command_spec.rb +23 -0
- data/spec/yaml_spec.rb +7 -7
- metadata +4 -3
- data/generators/i18n_locale/lib/yaml.rb +0 -141
@@ -63,7 +63,10 @@ class I18nGenerator < Rails::Generator::NamedBase
|
|
63
63
|
private
|
64
64
|
def defined_in_rails_i18n_repository?
|
65
65
|
begin
|
66
|
-
|
66
|
+
uri = "http://github.com/svenfuchs/rails-i18n/tree/master/rails/locale/#{locale_name}.yml"
|
67
|
+
OpenURI.open_uri(uri) do |res|
|
68
|
+
(res.base_uri.to_s == uri) && (res.status == %w[200 OK])
|
69
|
+
end
|
67
70
|
rescue
|
68
71
|
false
|
69
72
|
end
|
@@ -0,0 +1,185 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module I18nLocaleGeneratorModule
|
4
|
+
class Node
|
5
|
+
attr_reader :document, :indent_level
|
6
|
+
attr_accessor :line
|
7
|
+
|
8
|
+
def initialize(parent, line_index, text)
|
9
|
+
@document, @line, @text = parent.document, line_index, text.to_s
|
10
|
+
@text =~ /(^\s*)/
|
11
|
+
@indent_level = $1.nil? ? 0 : $1.size
|
12
|
+
@yaml = YAML.load(@text.to_s + ' ')
|
13
|
+
end
|
14
|
+
|
15
|
+
def parent
|
16
|
+
@parent ||= document.parent_of self
|
17
|
+
end
|
18
|
+
|
19
|
+
def children
|
20
|
+
@children ||= document.children_of(self)
|
21
|
+
end
|
22
|
+
alias :nodes :children
|
23
|
+
|
24
|
+
def [](node_name)
|
25
|
+
if node = nodes.detect {|n| n.key.to_s == node_name.to_s}
|
26
|
+
node
|
27
|
+
else
|
28
|
+
nodes.add "#{' ' * (@indent_level + 2)}#{node_name}: "
|
29
|
+
nodes.last
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def key
|
34
|
+
@yaml.is_a?(Hash) ? @yaml.keys.first : nil
|
35
|
+
end
|
36
|
+
|
37
|
+
def value
|
38
|
+
@yaml.is_a?(Hash) ? @yaml.values.first : nil
|
39
|
+
end
|
40
|
+
|
41
|
+
def value=(val)
|
42
|
+
if @yaml[self.key] != val
|
43
|
+
@yaml[self.key] = val
|
44
|
+
@changed = true
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def text
|
49
|
+
if @changed
|
50
|
+
v = if self.value.is_a?(Array)
|
51
|
+
"[#{self.value * ', '}]"
|
52
|
+
else
|
53
|
+
%Q["#{self.value}"]
|
54
|
+
end
|
55
|
+
"#{' ' * self.indent_level}#{self.key}: #{v}"
|
56
|
+
else
|
57
|
+
@text
|
58
|
+
end
|
59
|
+
end
|
60
|
+
alias :to_s :text
|
61
|
+
|
62
|
+
def changed?
|
63
|
+
@changed
|
64
|
+
end
|
65
|
+
|
66
|
+
def is_blank_or_comment?
|
67
|
+
@text.sub(/#.*$/, '').gsub(/\s/, '').empty?
|
68
|
+
end
|
69
|
+
|
70
|
+
def path
|
71
|
+
@path ||= "#{self.parent.path}/#{self.key}"
|
72
|
+
end
|
73
|
+
|
74
|
+
def descendant_nodes(&block)
|
75
|
+
yield self if self.value
|
76
|
+
self.children.each {|child| child.descendant_nodes(&block)} if self.children
|
77
|
+
end
|
78
|
+
|
79
|
+
def <=>(other)
|
80
|
+
self.line <=> other.line
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
class YamlDocument < Node
|
85
|
+
attr_accessor :lines
|
86
|
+
alias :nodes :lines
|
87
|
+
|
88
|
+
def initialize(yml_path, locale_name)
|
89
|
+
@locale_name, @lines, @current_line, @indent_level = locale_name, Nodes.new(self), -1, -2
|
90
|
+
if File.exists? yml_path
|
91
|
+
File.open(yml_path) do |file|
|
92
|
+
file.each_with_index do |line_text, i|
|
93
|
+
n = Node.new(self, i, line_text.chomp)
|
94
|
+
@lines << ((((n.key == 'en-US') || (n.key == 'en')) && n.value.blank?) ? Node.new(self, i, "#{locale_name}:") : n)
|
95
|
+
end
|
96
|
+
@lines.delete_at(-1) if @lines[-1].text.blank?
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def next
|
102
|
+
return false if @lines.size == 0
|
103
|
+
@current_line += 1
|
104
|
+
return false if @current_line >= @lines.size
|
105
|
+
@lines[@current_line].is_blank_or_comment? ? self.next : @lines[@current_line]
|
106
|
+
end
|
107
|
+
|
108
|
+
def prev
|
109
|
+
return false if @current_line == 0
|
110
|
+
@current_line -= 1
|
111
|
+
@lines[@current_line].is_blank_or_comment? ? self.prev : @lines[@current_line]
|
112
|
+
end
|
113
|
+
|
114
|
+
def parent_of(child)
|
115
|
+
@current_line = child.line
|
116
|
+
while n = self.prev
|
117
|
+
return n if n.indent_level == child.indent_level - 2
|
118
|
+
end
|
119
|
+
self
|
120
|
+
end
|
121
|
+
|
122
|
+
def children_of(parent)
|
123
|
+
nodes = Nodes.new(parent)
|
124
|
+
@current_line = parent.line
|
125
|
+
while n = self.next
|
126
|
+
if n.indent_level < parent.indent_level + 2
|
127
|
+
break
|
128
|
+
elsif n.indent_level == parent.indent_level + 2
|
129
|
+
nodes << n
|
130
|
+
end
|
131
|
+
end
|
132
|
+
nodes
|
133
|
+
end
|
134
|
+
|
135
|
+
def document
|
136
|
+
self
|
137
|
+
end
|
138
|
+
|
139
|
+
def path
|
140
|
+
''
|
141
|
+
end
|
142
|
+
|
143
|
+
def line
|
144
|
+
@current_line
|
145
|
+
end
|
146
|
+
|
147
|
+
def to_s
|
148
|
+
@lines.inject('') do |ret, n|
|
149
|
+
ret << n.text + "\n"
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
class Nodes < Array
|
155
|
+
def initialize(parent)
|
156
|
+
super()
|
157
|
+
@parent = parent
|
158
|
+
end
|
159
|
+
|
160
|
+
def [](index)
|
161
|
+
if index.is_a?(String) || index.is_a?(Symbol)
|
162
|
+
return self.detect {|node| node.key == index} || add(index)
|
163
|
+
end
|
164
|
+
super
|
165
|
+
end
|
166
|
+
|
167
|
+
def last_leaf
|
168
|
+
c = @parent
|
169
|
+
loop do
|
170
|
+
return c if c.children.blank?
|
171
|
+
c = c.children.last
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
def add(node_name)
|
176
|
+
target_line = self.last_leaf.line + 1
|
177
|
+
@parent.document.nodes.each {|n| n.line += 1 if n.line >= target_line}
|
178
|
+
node = Node.new(@parent, target_line, node_name)
|
179
|
+
@parent.document.lines << node
|
180
|
+
@parent.document.lines.sort!
|
181
|
+
self << node unless @parent.is_a? YamlDocument
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
@@ -1,19 +1 @@
|
|
1
|
-
<%=
|
2
|
-
activerecord:
|
3
|
-
models:
|
4
|
-
<% models.each do |model| -%>
|
5
|
-
<%= "#{model.english_name}: #{model.translated_name}" %>
|
6
|
-
<% end -%>
|
7
|
-
attributes:
|
8
|
-
<% models.each do |model| -%>
|
9
|
-
<%= "#{model.english_name}:" %>
|
10
|
-
<% model.content_columns.each do |col| -%>
|
11
|
-
<% unless %w[created_at updated_at].include?(col.name) -%>
|
12
|
-
<%= "#{col.name}: #{col.translated_name}" %>
|
13
|
-
<% end -%>
|
14
|
-
<% end -%>
|
15
|
-
<% end -%>
|
16
|
-
<% translations.each do |key, value| -%>
|
17
|
-
<%= "#{key}: #{value}" %>
|
18
|
-
<% end -%>
|
19
|
-
|
1
|
+
<%= translations %>
|
@@ -2,7 +2,7 @@ require 'rubygems'
|
|
2
2
|
require 'rails_generator'
|
3
3
|
require 'rails_generator/commands'
|
4
4
|
require 'gettext'
|
5
|
-
require File.join(File.dirname(__FILE__), 'lib/yaml')
|
5
|
+
require File.join(File.dirname(__FILE__), '../i18n/lib/yaml')
|
6
6
|
require File.join(File.dirname(__FILE__), 'lib/cldr')
|
7
7
|
include I18nLocaleGeneratorModule
|
8
8
|
|
@@ -95,8 +95,13 @@ module I18nGenerator::Generator
|
|
95
95
|
return arr.join("\n")
|
96
96
|
end
|
97
97
|
end
|
98
|
-
|
99
|
-
|
98
|
+
arr.each_with_index do |l, i|
|
99
|
+
if l =~ /Rails::Initializer\.run do \|config\|/
|
100
|
+
arr[i] = "Rails::Initializer.run do |config|\n config.i18n.default_locale = '#{locale_name}'"
|
101
|
+
return arr.join("\n")
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end_row = RUBY_VERSION >= '1.8.7' ? arr.rindex {|l| l =~ /^\s*end\s*/} : arr.size - 1
|
100
105
|
((arr[0...end_row] << " config.i18n.default_locale = '#{locale_name}'") + arr[end_row..-1]).join("\n")
|
101
106
|
end
|
102
107
|
|
@@ -104,7 +109,7 @@ module I18nGenerator::Generator
|
|
104
109
|
original_yml = I18n.load_path.detect {|lp| lp =~ /\/lib\/#{filename_base}\/locale\/(en|en-US)\.yml$/}
|
105
110
|
doc = YamlDocument.new(original_yml, locale_name)
|
106
111
|
yield doc
|
107
|
-
file('i18n:base.yml', "config/
|
112
|
+
file('i18n:base.yml', "config/locales/#{filename_base}_#{locale_name}.yml") do |f|
|
108
113
|
doc.to_s
|
109
114
|
end
|
110
115
|
end
|
@@ -6,7 +6,10 @@ module I18nLocaleGeneratorModule
|
|
6
6
|
class CldrDocument
|
7
7
|
def initialize(locale_name)
|
8
8
|
@locale_name = locale_name
|
9
|
-
@summaries = [load_cldr_data(locale_name.tr('-', '_'))
|
9
|
+
@summaries = [load_cldr_data(locale_name.tr('-', '_'))]
|
10
|
+
if locale_name =~ /^[a-zA-Z]{2}[-_][a-zA-Z]{2}$/
|
11
|
+
@summaries << load_cldr_data(locale_name.to(1))
|
12
|
+
end
|
10
13
|
end
|
11
14
|
|
12
15
|
def lookup(path)
|
@@ -108,10 +111,11 @@ module I18nLocaleGeneratorModule
|
|
108
111
|
def search(n1, n2, g)
|
109
112
|
pattern = Regexp.new /<tr><td>\d*<\/td><td class='[ng]'>#{Regexp.quote(n1)}<\/td><td class='[ng]'>#{Regexp.quote(n2)}<\/td><td class='[ng]'>#{Regexp.quote(g)}<\/td>/
|
110
113
|
extract_pattern = /<td class='v'>(?:<span.*?>)?(.*?)(?:<\/span>)?<\/td><td>/
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
114
|
+
@summaries.each do |summary|
|
115
|
+
_, value = *extract_pattern.match(summary.grep(pattern).first)
|
116
|
+
return value unless value.nil?
|
117
|
+
end
|
118
|
+
nil
|
115
119
|
end
|
116
120
|
|
117
121
|
def convert_date_pattern(val)
|
@@ -3,6 +3,7 @@ require 'rails_generator/commands'
|
|
3
3
|
require File.join(File.dirname(__FILE__), 'lib/translator')
|
4
4
|
require File.join(File.dirname(__FILE__), 'lib/recording_backend')
|
5
5
|
require File.join(File.dirname(__FILE__), 'lib/erb_executer')
|
6
|
+
require File.join(File.dirname(__FILE__), '../i18n/lib/yaml')
|
6
7
|
include I18nTranslationGeneratorModule
|
7
8
|
|
8
9
|
module I18nGenerator::Generator
|
@@ -10,56 +11,41 @@ module I18nGenerator::Generator
|
|
10
11
|
module Create
|
11
12
|
def translation_yaml
|
12
13
|
I18n.locale = locale_name
|
13
|
-
threads = []
|
14
|
-
now = Time.now
|
15
14
|
models = model_filenames.map do |model_name|
|
16
15
|
model = begin
|
17
16
|
m = model_name.camelize.constantize
|
18
17
|
next unless m.respond_to?(:content_columns)
|
18
|
+
m.class_eval %Q[def self.english_name; "#{model_name}"; end]
|
19
19
|
m
|
20
20
|
rescue
|
21
21
|
next
|
22
22
|
end
|
23
|
-
threads << Thread.new do
|
24
|
-
Thread.pass
|
25
|
-
registered_t_name = I18n.t("activerecord.models.#{model_name}", :default => model_name, :locale => locale_name)
|
26
|
-
|
27
|
-
model.class_eval <<-END
|
28
|
-
def self.english_name
|
29
|
-
"#{model_name}"
|
30
|
-
end
|
31
|
-
|
32
|
-
def self.translated_name
|
33
|
-
"#{registered_t_name != model_name ? registered_t_name : self.translator.translate(model_name)}"
|
34
|
-
end
|
35
|
-
END
|
36
|
-
model.content_columns.each do |col|
|
37
|
-
next if %w[created_at updated_at].include? col.name
|
38
|
-
registered_t_name = I18n.t("activerecord.attributes.#{model_name}.#{col.name}", :default => col.name, :locale => locale_name)
|
39
|
-
col.class_eval <<-END
|
40
|
-
def translated_name
|
41
|
-
"#{registered_t_name != col.name ? registered_t_name : self.translator.translate(col.name)}"
|
42
|
-
end
|
43
|
-
END
|
44
|
-
end
|
45
|
-
end
|
46
|
-
model
|
47
23
|
end.compact
|
48
|
-
|
49
|
-
|
24
|
+
translation_keys = []
|
25
|
+
translation_keys += models.map {|m| "activerecord.models.#{m.english_name}"}
|
26
|
+
models.each do |model|
|
27
|
+
translation_keys += model.content_columns.map {|c| "activerecord.attributes.#{model.english_name}.#{c.name}"}
|
28
|
+
end
|
29
|
+
logger.debug "#{models.size} models found."
|
30
|
+
|
50
31
|
# pick all translated keywords from view files
|
32
|
+
original_backend = I18n.backend
|
51
33
|
I18n.backend = RecordingBackend.new
|
52
34
|
|
53
35
|
Dir["#{RAILS_ROOT}/app/views/**/*.erb"].each do |f|
|
54
36
|
ErbExecuter.new.exec_erb f
|
55
37
|
end
|
56
|
-
|
57
|
-
|
58
|
-
|
38
|
+
logger.debug "#{I18n.backend.keys.size} translation keys found in views."
|
39
|
+
(translation_keys += I18n.backend.keys).uniq!
|
40
|
+
I18n.backend = original_backend
|
41
|
+
|
42
|
+
# translate all keys and generate the YAML file
|
59
43
|
now = Time.now
|
60
|
-
|
61
|
-
logger.debug "took #{Time.now - now} secs to translate
|
62
|
-
|
44
|
+
translations = translate_all(translation_keys)
|
45
|
+
logger.debug "took #{Time.now - now} secs to translate."
|
46
|
+
|
47
|
+
yaml = generate_yaml(locale_name, translations)
|
48
|
+
template 'i18n:translation.yml', "config/locales/translation_#{locale_name}.yml", :assigns => {:locale_name => locale_name, :translations => yaml.to_s}
|
63
49
|
end
|
64
50
|
|
65
51
|
private
|
@@ -69,22 +55,56 @@ module I18nGenerator::Generator
|
|
69
55
|
end
|
70
56
|
end
|
71
57
|
|
72
|
-
|
73
|
-
|
58
|
+
# mixin translations into existing yaml file
|
59
|
+
def generate_yaml(locale_name, translations)
|
60
|
+
yaml = YamlDocument.new("config/locales/translation_#{locale_name}.yml", locale_name)
|
61
|
+
each_value [], translations do |parents, value|
|
62
|
+
node = parents.inject(yaml[locale_name]) {|node, parent| node[parent]}
|
63
|
+
node.value = value
|
64
|
+
end
|
65
|
+
yaml
|
74
66
|
end
|
75
67
|
|
76
68
|
# receives an array of keys and returns :key => :translation hash
|
77
69
|
def translate_all(keys)
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
70
|
+
returning ActiveSupport::OrderedHash.new do |oh|
|
71
|
+
# fix the order first(for multi thread translating)
|
72
|
+
keys.each do |key|
|
73
|
+
if key.to_s.include? '.'
|
74
|
+
key_prefix, key_suffix = key.to_s.split('.')[0...-1], key.to_s.split('.')[-1]
|
75
|
+
key_prefix.inject(oh) {|h, k| h[k] ||= ActiveSupport::OrderedHash.new}[key_suffix] = nil
|
76
|
+
else
|
77
|
+
oh[key] = nil
|
78
|
+
end
|
79
|
+
end
|
80
|
+
threads = []
|
81
|
+
keys.each do |key|
|
82
|
+
threads << Thread.new do
|
83
|
+
logger.debug "translating #{key} ..."
|
84
|
+
Thread.pass
|
85
|
+
if key.to_s.include? '.'
|
86
|
+
key_prefix, key_suffix = key.to_s.split('.')[0...-1], key.to_s.split('.')[-1]
|
87
|
+
existing_translation = I18n.t(key, :default => key_suffix, :locale => locale_name)
|
88
|
+
key_prefix.inject(oh) {|h, k| h[k]}[key_suffix] = existing_translation != key_suffix ? existing_translation : translator.translate(key_suffix)
|
89
|
+
else
|
90
|
+
existing_translation = I18n.t(key, :default => key, :locale => locale_name)
|
91
|
+
oh[key] = existing_translation != key ? existing_translation : translator.translate(key)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
threads.each {|t| t.join}
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
# iterate through all values
|
100
|
+
def each_value(parents, src, &block)
|
101
|
+
src.each do |k, v|
|
102
|
+
if v.is_a?(ActiveSupport::OrderedHash)
|
103
|
+
each_value parents + [k], v, &block
|
104
|
+
else
|
105
|
+
yield parents + [k], v
|
83
106
|
end
|
84
|
-
hash
|
85
107
|
end
|
86
|
-
threads.each {|t| t.join}
|
87
|
-
ret
|
88
108
|
end
|
89
109
|
end
|
90
110
|
end
|
@@ -9,10 +9,12 @@ module I18nTranslationGeneratorModule
|
|
9
9
|
class Executer
|
10
10
|
extend ERB::DefMethod
|
11
11
|
include ActionView::Helpers::TranslationHelper
|
12
|
-
include ThroughRyoku
|
12
|
+
include I18nTranslationGeneratorModule::ThroughRyoku
|
13
|
+
|
13
14
|
nil.class_eval do
|
14
15
|
def method_missing(method, *args, &block); nil; end
|
15
16
|
end
|
17
|
+
|
16
18
|
def_erb_method 'execute', '#{filename}'
|
17
19
|
end
|
18
20
|
EOS
|
@@ -51,9 +51,9 @@ end"
|
|
51
51
|
it 'adds the default_locale config inside the config block and sets locale_name value' do
|
52
52
|
@command.send(:add_locale_config, @config).should == "
|
53
53
|
Rails::Initializer.run do |config|
|
54
|
+
config.i18n.default_locale = 'ja'
|
54
55
|
something goes here.
|
55
56
|
bla bla bla...
|
56
|
-
config.i18n.default_locale = 'ja'
|
57
57
|
end"
|
58
58
|
end
|
59
59
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '/../generators/i18n_translation/i18n_translation_command')
|
2
|
+
|
3
|
+
describe I18nGenerator::Generator::Commands::Create do
|
4
|
+
before do
|
5
|
+
(@command = Object.new).extend I18nGenerator::Generator::Commands::Create
|
6
|
+
@command.stub!(:locale_name).and_return('ja')
|
7
|
+
end
|
8
|
+
|
9
|
+
describe 'each_value' do
|
10
|
+
it 'iterates through each value' do
|
11
|
+
hash = ActiveSupport::OrderedHash.new
|
12
|
+
hash[:parent1] = ActiveSupport::OrderedHash.new
|
13
|
+
hash[:parent1][:child1] = 'child one'
|
14
|
+
hash[:parent2] = ActiveSupport::OrderedHash.new
|
15
|
+
hash[:parent2][:child2] = 'child two'
|
16
|
+
hash[:parent2][:child3] = 'child three'
|
17
|
+
@command.__send__(:each_value, [], hash) do |parents, value|
|
18
|
+
p "#{parents.join('.')} #{value}"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
data/spec/yaml_spec.rb
CHANGED
@@ -1,20 +1,20 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), '/../generators/
|
1
|
+
require File.join(File.dirname(__FILE__), '/../generators/i18n/lib/yaml')
|
2
2
|
include I18nLocaleGeneratorModule
|
3
3
|
|
4
4
|
describe 'Yaml' do
|
5
|
-
before do
|
6
|
-
@yaml = YamlDocument.new File.join(File.dirname(__FILE__), 'data/yml/active_record/en-US.yml'), 'ja
|
5
|
+
before :each do
|
6
|
+
@yaml = YamlDocument.new File.join(File.dirname(__FILE__), 'data/yml/active_record/en-US.yml'), 'ja'
|
7
7
|
end
|
8
8
|
|
9
9
|
describe YamlDocument do
|
10
10
|
it 'should return the top level node with the square bracket method' do
|
11
|
-
node = @yaml['ja
|
11
|
+
node = @yaml['ja']
|
12
12
|
node.should be_an_instance_of(Node)
|
13
|
-
node.key.should == 'ja
|
13
|
+
node.key.should == 'ja'
|
14
14
|
end
|
15
15
|
|
16
16
|
it 'should generate a path string on the top node' do
|
17
|
-
@yaml['ja
|
17
|
+
@yaml['ja'].path.should == '/ja'
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
@@ -32,7 +32,7 @@ describe 'Yaml' do
|
|
32
32
|
end
|
33
33
|
|
34
34
|
it 'should generate a path string on any node' do
|
35
|
-
@yaml['ja
|
35
|
+
@yaml['ja']['activerecord']['errors']['messages'].path.should == '/ja-JP/activerecord/errors/messages'
|
36
36
|
end
|
37
37
|
end
|
38
38
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: amatsuda-i18n_generators
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Akira Matsuda
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-12-
|
12
|
+
date: 2008-12-17 00:00:00 -08:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -35,6 +35,7 @@ files:
|
|
35
35
|
- Rakefile
|
36
36
|
- generators/i18n/USAGE
|
37
37
|
- generators/i18n/i18n_generator.rb
|
38
|
+
- generators/i18n/lib/yaml.rb
|
38
39
|
- generators/i18n/templates/base.yml
|
39
40
|
- generators/i18n/templates/i18n_config.rb
|
40
41
|
- generators/i18n/templates/translation.yml
|
@@ -42,7 +43,6 @@ files:
|
|
42
43
|
- generators/i18n_locale/i18n_locale_command.rb
|
43
44
|
- generators/i18n_locale/i18n_locale_generator.rb
|
44
45
|
- generators/i18n_locale/lib/cldr.rb
|
45
|
-
- generators/i18n_locale/lib/yaml.rb
|
46
46
|
- generators/i18n_scaffold/i18n_scaffold_generator.rb
|
47
47
|
- generators/i18n_scaffold/templates/controller.rb
|
48
48
|
- generators/i18n_scaffold/templates/functional_test.rb
|
@@ -65,6 +65,7 @@ files:
|
|
65
65
|
- spec/data/cldr/ja.html
|
66
66
|
- spec/data/yml/active_record/en-US.yml
|
67
67
|
- spec/i18n_locale_command_spec.rb
|
68
|
+
- spec/i18n_translation_command_spec.rb
|
68
69
|
- spec/translator_spec.rb
|
69
70
|
- spec/yaml_spec.rb
|
70
71
|
has_rdoc: false
|
@@ -1,141 +0,0 @@
|
|
1
|
-
require 'yaml'
|
2
|
-
|
3
|
-
module I18nLocaleGeneratorModule
|
4
|
-
class YamlDocument
|
5
|
-
def initialize(yml_path, locale_name)
|
6
|
-
@locale_name, @nodes = locale_name, []
|
7
|
-
File.read(yml_path).each_with_index do |line_text, i|
|
8
|
-
n = Node.new(self, i, line_text.chomp)
|
9
|
-
@nodes << (((n.key == 'en-US') || (n.key == 'en')) ? Node.new(self, i, "#{locale_name}:") : n)
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
def next
|
14
|
-
@current_line += 1
|
15
|
-
return false if @current_line == @nodes.size
|
16
|
-
@nodes[@current_line].is_blank_or_comment? ? self.next : @nodes[@current_line]
|
17
|
-
end
|
18
|
-
|
19
|
-
def prev
|
20
|
-
return false if @current_line == 0
|
21
|
-
@current_line -= 1
|
22
|
-
@nodes[@current_line].is_blank_or_comment? ? self.prev : @nodes[@current_line]
|
23
|
-
end
|
24
|
-
|
25
|
-
def parent_of(child)
|
26
|
-
@current_line = child.line
|
27
|
-
while n = self.prev
|
28
|
-
return n if n.indent_level == child.indent_level - 2
|
29
|
-
end
|
30
|
-
self
|
31
|
-
end
|
32
|
-
|
33
|
-
def children_of(parent)
|
34
|
-
nodes = Nodes.new
|
35
|
-
@current_line = parent.line
|
36
|
-
while n = self.next
|
37
|
-
if n.indent_level < parent.indent_level + 2
|
38
|
-
break
|
39
|
-
elsif n.indent_level == parent.indent_level + 2
|
40
|
-
nodes << n
|
41
|
-
end
|
42
|
-
end
|
43
|
-
nodes
|
44
|
-
end
|
45
|
-
|
46
|
-
def [](node_name)
|
47
|
-
@current_line = @nodes.detect {|n| (n.indent_level == 0) && (n.key == node_name)}.line
|
48
|
-
@nodes[@current_line]
|
49
|
-
end
|
50
|
-
|
51
|
-
def document
|
52
|
-
self
|
53
|
-
end
|
54
|
-
|
55
|
-
def path
|
56
|
-
''
|
57
|
-
end
|
58
|
-
|
59
|
-
def to_s
|
60
|
-
@nodes.inject('') do |ret, n|
|
61
|
-
ret << n.text + "\n"
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
class Node
|
67
|
-
attr_reader :line, :indent_level
|
68
|
-
|
69
|
-
def initialize(doc, line_index, text)
|
70
|
-
@doc, @line, @text = doc, line_index, text
|
71
|
-
@text =~ /(^\s*)/
|
72
|
-
@indent_level = $1.nil? ? 0 : $1.size
|
73
|
-
@yaml = YAML.load(@text + ' ')
|
74
|
-
end
|
75
|
-
|
76
|
-
def parent
|
77
|
-
@parent ||= @doc.parent_of self
|
78
|
-
end
|
79
|
-
|
80
|
-
def children
|
81
|
-
@children ||= @doc.children_of(self)
|
82
|
-
end
|
83
|
-
|
84
|
-
def [](node_name)
|
85
|
-
children.detect {|c| c.key == node_name}
|
86
|
-
end
|
87
|
-
|
88
|
-
def key
|
89
|
-
@yaml.is_a?(Hash) ? @yaml.keys.first : nil
|
90
|
-
end
|
91
|
-
|
92
|
-
def value
|
93
|
-
@yaml.is_a?(Hash) ? @yaml.values.first : nil
|
94
|
-
end
|
95
|
-
|
96
|
-
def value=(val)
|
97
|
-
if @yaml[self.key] != val
|
98
|
-
@yaml[self.key] = val
|
99
|
-
@changed = true
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
def text
|
104
|
-
if @changed
|
105
|
-
v = if self.value.is_a?(Array)
|
106
|
-
"[#{self.value * ', '}]"
|
107
|
-
else
|
108
|
-
%Q["#{self.value}"]
|
109
|
-
end
|
110
|
-
"#{' ' * self.indent_level}#{self.key}: #{v}"
|
111
|
-
else
|
112
|
-
@text
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
116
|
-
def changed?
|
117
|
-
@changed
|
118
|
-
end
|
119
|
-
|
120
|
-
def is_blank_or_comment?
|
121
|
-
@text.sub(/#.*$/, '').gsub(/\s/, '').empty?
|
122
|
-
end
|
123
|
-
|
124
|
-
def path
|
125
|
-
@path ||= "#{self.parent.path}/#{self.key}"
|
126
|
-
end
|
127
|
-
|
128
|
-
def descendant_nodes(&block)
|
129
|
-
yield self if self.value
|
130
|
-
self.children.each {|child| child.descendant_nodes(&block)} if self.children
|
131
|
-
end
|
132
|
-
end
|
133
|
-
|
134
|
-
class Nodes < Array
|
135
|
-
def[](index)
|
136
|
-
return detect {|node| node.key == index} if index.is_a?(String)
|
137
|
-
super
|
138
|
-
end
|
139
|
-
end
|
140
|
-
end
|
141
|
-
|