i18n_generators 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/History.txt +104 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +104 -0
- data/Rakefile +38 -0
- data/VERSION +1 -0
- data/generators/i18n/USAGE +13 -0
- data/generators/i18n/i18n_generator.rb +85 -0
- data/generators/i18n/lib/yaml.rb +187 -0
- data/generators/i18n/templates/base.yml +0 -0
- data/generators/i18n/templates/i18n_config.rb +5 -0
- data/generators/i18n/templates/translation.yml +1 -0
- data/generators/i18n_locale/USAGE +12 -0
- data/generators/i18n_locale/i18n_locale_command.rb +135 -0
- data/generators/i18n_locale/i18n_locale_generator.rb +9 -0
- data/generators/i18n_locale/lib/cldr.rb +139 -0
- data/generators/i18n_scaffold/i18n_scaffold_generator.rb +3 -0
- data/generators/i18n_scaffold/templates/controller.rb +85 -0
- data/generators/i18n_scaffold/templates/functional_test.rb +45 -0
- data/generators/i18n_scaffold/templates/helper.rb +2 -0
- data/generators/i18n_scaffold/templates/helper_test.rb +4 -0
- data/generators/i18n_scaffold/templates/layout.html.erb +17 -0
- data/generators/i18n_scaffold/templates/style.css +54 -0
- data/generators/i18n_scaffold/templates/view_edit.html.erb +18 -0
- data/generators/i18n_scaffold/templates/view_index.html.erb +24 -0
- data/generators/i18n_scaffold/templates/view_new.html.erb +17 -0
- data/generators/i18n_scaffold/templates/view_show.html.erb +10 -0
- data/generators/i18n_translation/USAGE +9 -0
- data/generators/i18n_translation/i18n_translation_command.rb +121 -0
- data/generators/i18n_translation/i18n_translation_generator.rb +9 -0
- data/generators/i18n_translation/lib/erb_executer.rb +31 -0
- data/generators/i18n_translation/lib/recording_backend.rb +16 -0
- data/generators/i18n_translation/lib/through_ryoku.rb +8 -0
- data/generators/i18n_translation/lib/translator.rb +28 -0
- data/i18n_generators.gemspec +87 -0
- data/spec/cldr_spec.rb +54 -0
- data/spec/data/cldr/ja.html +3112 -0
- data/spec/data/yml/active_record/en-US.yml +54 -0
- data/spec/i18n_locale_command_spec.rb +63 -0
- data/spec/i18n_translation_command_spec.rb +24 -0
- data/spec/spec_helper.rb +39 -0
- data/spec/translator_spec.rb +46 -0
- data/spec/yaml_spec.rb +59 -0
- metadata +114 -0
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
pkg
|
data/History.txt
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
== 0.8.0
|
2
|
+
|
3
|
+
* major enhancements:
|
4
|
+
* Gemify
|
5
|
+
|
6
|
+
== 0.7.0
|
7
|
+
|
8
|
+
* major enhancements:
|
9
|
+
* Fix gettext dependency version
|
10
|
+
* enhancements:
|
11
|
+
* Add more error checks when loading models
|
12
|
+
* Load gettext only when using it
|
13
|
+
|
14
|
+
== 0.6.0
|
15
|
+
|
16
|
+
* bugfixes:
|
17
|
+
* Could not load cldr data with short locale names
|
18
|
+
* major enhancements:
|
19
|
+
* Include AR association names in model attributes translation
|
20
|
+
* Add 'generated' comment mark (#g) for generated lines in YAML (thanks to t-wada-senpai, Shimura-san, Toyofuku-san, Sezutsu-san and oukayuka-san!)
|
21
|
+
* Add --include-timestamps option and change default bahaviour not to include timestamp columns in translation YAML
|
22
|
+
* Add blank line between each blocks (thanks to Sawayanagi-san!)
|
23
|
+
* enhancements:
|
24
|
+
* Avoid generating blank locale file
|
25
|
+
* Change GitHub fetch URL from blob/master/...?raw=true to raw/master
|
26
|
+
|
27
|
+
== 0.5.0
|
28
|
+
|
29
|
+
* bugfixes:
|
30
|
+
* Could not fetch the locale files via GitHub (GitHub changed the URL?)
|
31
|
+
* major enhancements:
|
32
|
+
* Ruby 1.9 ready!
|
33
|
+
* Never connect to CLDR site when the locale file found in Sven's rails-i18n repository
|
34
|
+
* enhancements:
|
35
|
+
* Use Ruby 1.9 built-in JSON parser if Ruby 1.9
|
36
|
+
|
37
|
+
== 0.4.1
|
38
|
+
|
39
|
+
* bugfixes:
|
40
|
+
* i18n_translation abnormally ends when loading a view containing "-%>" (thanks to babie-san!)
|
41
|
+
|
42
|
+
== 0.4.0
|
43
|
+
|
44
|
+
* major enhancements:
|
45
|
+
* translation generator now preserves any existing extra lines in the YAML file (thanks to Iain Hecker-san!)
|
46
|
+
|
47
|
+
== 0.3.4
|
48
|
+
|
49
|
+
* enhancements:
|
50
|
+
* Reduce unnecessary request to CLDR site
|
51
|
+
|
52
|
+
== 0.3.3
|
53
|
+
|
54
|
+
* bugfixes:
|
55
|
+
* Did not work on Ruby 1.8.6 (thanks to akm-san!)
|
56
|
+
|
57
|
+
== 0.3.2
|
58
|
+
|
59
|
+
* bugfixes:
|
60
|
+
* Trim mode in ERB didn't work on some platforms (thanks to valda-san!)
|
61
|
+
|
62
|
+
== 0.3.1
|
63
|
+
|
64
|
+
* enhancements:
|
65
|
+
* Translate all keys simultaneously using thread
|
66
|
+
* Translations with :scope is going to be yamlized with proper hierarchy
|
67
|
+
|
68
|
+
== 0.3.0
|
69
|
+
|
70
|
+
* major enhancements:
|
71
|
+
* Renamed the generators
|
72
|
+
i18n_locales -> i18n_locale (i18n --locale)
|
73
|
+
i18n_models -> i18n_translation (i18n --translation)
|
74
|
+
* Handle all translate keys which appear in view files (thanks to PanosJee-san!)
|
75
|
+
|
76
|
+
== 0.2.0
|
77
|
+
|
78
|
+
* major enhancements:
|
79
|
+
* Implemented i18n_scaffold generator (thanks to Iain Hecker-san!)
|
80
|
+
|
81
|
+
* enhancements:
|
82
|
+
* i18n_models generator can now deal with non AR classes which has content_columns (thanks to Iain Hecker-san!)
|
83
|
+
|
84
|
+
== 0.1.0
|
85
|
+
|
86
|
+
* major enhancements:
|
87
|
+
* Fetch locale YAML file from rails-i18n project repository first
|
88
|
+
|
89
|
+
* bugfixes:
|
90
|
+
* Could not recognize model names with multipie words (thanks to makoto-san!)
|
91
|
+
|
92
|
+
== 0.0.8
|
93
|
+
|
94
|
+
* major enhancements:
|
95
|
+
* Lots of changes for this commit by DHH http://github.com/rails/rails/commit/d9b92ee11b33fed5c7a94a91415fa846705f7dd3
|
96
|
+
|
97
|
+
== 0.0.4
|
98
|
+
|
99
|
+
* Gemified on GitHub
|
100
|
+
|
101
|
+
== 0.0.1
|
102
|
+
|
103
|
+
* Birthday!
|
104
|
+
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2008 [name of plugin creator]
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
= I18n generators
|
2
|
+
|
3
|
+
This gem plugin generates a set of locale files for Rails 2.2 i18n feature.
|
4
|
+
|
5
|
+
* http://github.com/amatsuda/i18n_generators/tree/master
|
6
|
+
|
7
|
+
|
8
|
+
== FEATURES
|
9
|
+
|
10
|
+
This gem/plugin provides following four script/generate commands.
|
11
|
+
|
12
|
+
=== 1. Generate I18n Scaffold
|
13
|
+
|
14
|
+
% ./script/generate i18n_scaffold ja (de-AT, pt-BR, etc.)
|
15
|
+
|
16
|
+
Generates I18n aware scaffold.
|
17
|
+
|
18
|
+
=== 2. Generate Locale Files for ActiveRecord/ActiveSupport/ActionPack
|
19
|
+
|
20
|
+
% ./script/generate i18n_locale ja (de-AT, pt-BR, etc.)
|
21
|
+
|
22
|
+
or
|
23
|
+
|
24
|
+
% ./script/generate i18n --locale ja (de-AT, pt-BR, etc.)
|
25
|
+
|
26
|
+
* A. If The Locale File Exists In Rails-I18n Repository
|
27
|
+
|
28
|
+
Firstly, the generator checks here.
|
29
|
+
http://github.com/svenfuchs/rails-i18n/tree/master/rails/locale
|
30
|
+
If the spacified .yml file exists in the repository, the generator downloads and puts the file into your config/locales directory.
|
31
|
+
Then the generater sets the application default locale to the specified locale.
|
32
|
+
|
33
|
+
This will generate following locale file.
|
34
|
+
|
35
|
+
config/locales/ja.yml
|
36
|
+
|
37
|
+
* B. Else
|
38
|
+
|
39
|
+
The generator copies the en.yml file (bundled inside Rails framework) into config/locales directory, and one-to-one localizes/translates each attribute value into the specified locale/language.
|
40
|
+
Then the generater sets the application default locale to the specified locale.
|
41
|
+
|
42
|
+
For example,
|
43
|
+
|
44
|
+
% ./script/generate i18n_locale zh
|
45
|
+
|
46
|
+
will generate following locale files.
|
47
|
+
|
48
|
+
config/locales/active_support_zh.yml
|
49
|
+
config/locales/active_record_zh.yml
|
50
|
+
config/locales/action_view_zh.yml
|
51
|
+
|
52
|
+
=== 3. Generate Translation YAML File For All Models/Attributes and views/**/*.erb
|
53
|
+
|
54
|
+
% ./script/generate i18n_translation ja (de-AT, pt-BR, etc.)
|
55
|
+
|
56
|
+
or
|
57
|
+
|
58
|
+
% ./script/generate i18n --translation ja (de-AT, pt-BR, etc.)
|
59
|
+
|
60
|
+
This will generate following YAML file.
|
61
|
+
|
62
|
+
config/locales/translation_ja.yml
|
63
|
+
|
64
|
+
The generator scans your app/models directory, and generates a YAML file with all the AR model names and attributes so that you don't have to write the YAML skeleton manually or by copy/paste.
|
65
|
+
In addition, the generator scans all the *.erb files in your app/views/** directory, and picks all the keys for I18n.translate, then adds them to the YAML file.
|
66
|
+
In addition, the generator tries to translate each of them into the specified language.
|
67
|
+
The generator doesn't overwrite the existing value so that you can rerun the generator again and again just like Annotate Model command.
|
68
|
+
|
69
|
+
=== 4. Generate All
|
70
|
+
|
71
|
+
% ./script/generate i18n ja (de-AT, pt-BR, etc.)
|
72
|
+
|
73
|
+
Executes 2 and 3 at once.
|
74
|
+
|
75
|
+
|
76
|
+
== REQUIREMENTS:
|
77
|
+
|
78
|
+
* Ruby on Rails (>= 2.2)
|
79
|
+
* Ruby-GetText-Package ( http://rubyforge.org/projects/gettext/ )
|
80
|
+
* high speed Internet connection
|
81
|
+
|
82
|
+
|
83
|
+
== INSTALL:
|
84
|
+
|
85
|
+
* As a gem
|
86
|
+
|
87
|
+
% sudo gem source http://gems.github.com
|
88
|
+
|
89
|
+
% sudo gem install amatsuda-i18n_generators
|
90
|
+
|
91
|
+
* As a Rails plugin
|
92
|
+
|
93
|
+
% ./script/plugin install git://github.com/amatsuda/i18n_generators.git
|
94
|
+
|
95
|
+
|
96
|
+
== CAUTION
|
97
|
+
|
98
|
+
Current version of this plugin is very very very roughly implemented just for experiment.
|
99
|
+
Every time you execute the generate command, the plugin connects to the Unicode CLDR website and scrapes the huge amount of its contents.
|
100
|
+
Please be careful not to harm your network environment and CLDR website by running this plugin too many times.
|
101
|
+
|
102
|
+
|
103
|
+
Copyright (c) 2008 Akira Matsuda, released under the MIT license
|
104
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'rake/testtask'
|
4
|
+
require 'rake/rdoctask'
|
5
|
+
# require 'spec/rake/spectask'
|
6
|
+
|
7
|
+
desc 'Default: run the specs.'
|
8
|
+
task :default => :spec
|
9
|
+
|
10
|
+
# desc 'Run the specs for i18n_generators.'
|
11
|
+
# Spec::Rake::SpecTask.new(:spec) do |t|
|
12
|
+
# t.spec_opts = ['--colour --format progress --loadby mtime --reverse']
|
13
|
+
# t.spec_files = FileList['spec/**/*_spec.rb']
|
14
|
+
# end
|
15
|
+
|
16
|
+
desc 'Generate documentation for the i18n_generators plugin.'
|
17
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
18
|
+
rdoc.rdoc_dir = 'rdoc'
|
19
|
+
rdoc.title = 'I18nGenerators'
|
20
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
21
|
+
rdoc.rdoc_files.include('README.rdoc')
|
22
|
+
rdoc.rdoc_files.include('generators/**/*.rb')
|
23
|
+
end
|
24
|
+
|
25
|
+
begin
|
26
|
+
require 'jeweler'
|
27
|
+
Jeweler::Tasks.new do |gemspec|
|
28
|
+
gemspec.name = 'i18n_generators'
|
29
|
+
gemspec.summary = 'Generates I18n locale files for Rails 2.2 and 2.3'
|
30
|
+
gemspec.description = 'A Rails generator plugin & gem that generates Rails 2.2 and 2.3 I18n locale files for almost every known locale.'
|
31
|
+
gemspec.email = 'ronnie@dio.jp'
|
32
|
+
gemspec.homepage = 'http://github.com/amatsuda/i18n_generators/'
|
33
|
+
gemspec.authors = ['Akira Matsuda']
|
34
|
+
end
|
35
|
+
Jeweler::GemcutterTasks.new
|
36
|
+
rescue LoadError
|
37
|
+
puts 'Jeweler not available. Install it with: gem install jeweler'
|
38
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.8.0
|
@@ -0,0 +1,13 @@
|
|
1
|
+
Description:
|
2
|
+
Generates a config file and locale files and a model/attributes translation file for Rails i18n feature.
|
3
|
+
|
4
|
+
Example:
|
5
|
+
./script/generate i18n locale_name (ja-JP, de-AT, etc.)
|
6
|
+
|
7
|
+
This will create:
|
8
|
+
config/initializers/i18n_config.rb
|
9
|
+
lib/locale/action_view_ja-JP.yml
|
10
|
+
lib/locale/active_record_ja-JP.yml
|
11
|
+
lib/locale/active_support_ja-JP.yml
|
12
|
+
lib/locale/models_ja-JP.yml
|
13
|
+
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rails_generator'
|
3
|
+
require 'rails_generator/commands'
|
4
|
+
|
5
|
+
class I18nGenerator < Rails::Generator::NamedBase
|
6
|
+
attr_reader :locale_name, :cldr, :translator, :generate_translation_only, :generate_locale_only, :include_timestamps
|
7
|
+
|
8
|
+
def initialize(runtime_args, runtime_options = {})
|
9
|
+
if options[:scaffold]
|
10
|
+
#TODO invoke scaffold generator
|
11
|
+
puts 'please use generate i18n_scaffold command'
|
12
|
+
exit
|
13
|
+
end
|
14
|
+
|
15
|
+
super
|
16
|
+
unless name =~ /^[a-zA-Z]{2}([-_][a-zA-Z]{2})?$/
|
17
|
+
puts 'ERROR: Wrong locale format. Please input in ?? or ??-?? format.'
|
18
|
+
exit
|
19
|
+
end
|
20
|
+
@locale_name = name.length == 5 ? "#{name[0..1].downcase}-#{name[3..4].upcase}" : "#{name[0..1].downcase}"
|
21
|
+
|
22
|
+
unless options[:generate_translation_only]
|
23
|
+
gem 'gettext', '<2'
|
24
|
+
require 'gettext'
|
25
|
+
@cldr = CldrDocument.new @locale_name
|
26
|
+
GetText.bindtextdomain 'rails'
|
27
|
+
GetText.locale = @locale_name
|
28
|
+
end
|
29
|
+
unless options[:generate_locale_only]
|
30
|
+
lang = @locale_name.sub(/-.*$/, '')
|
31
|
+
@translator = Translator.new lang
|
32
|
+
end
|
33
|
+
@include_timestamps = true if options[:include_timestamps]
|
34
|
+
end
|
35
|
+
|
36
|
+
def manifest
|
37
|
+
record do |m|
|
38
|
+
m.directory 'config/locales'
|
39
|
+
unless options[:generate_translation_only]
|
40
|
+
logger.debug 'updating environment.rb ...'
|
41
|
+
m.generate_configuration
|
42
|
+
if defined_in_rails_i18n_repository?
|
43
|
+
logger.debug "fetching #{locale_name}.yml from rails-i18n repository..."
|
44
|
+
m.fetch_from_rails_i18n_repository
|
45
|
+
else
|
46
|
+
logger.debug "generating #{locale_name} YAML files for Rails..."
|
47
|
+
m.active_support_yaml
|
48
|
+
m.active_record_yaml
|
49
|
+
m.action_view_yaml
|
50
|
+
end
|
51
|
+
end
|
52
|
+
unless options[:generate_locale_only]
|
53
|
+
m.translation_yaml
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
protected
|
59
|
+
def add_options!(opt)
|
60
|
+
opt.separator ''
|
61
|
+
opt.separator 'Options:'
|
62
|
+
opt.on('--translation',
|
63
|
+
'Generate translations for all models with their attributes and all translation keys in the view files.') {|v| options[:generate_translation_only] = v}
|
64
|
+
opt.on('--locale', 'Generate locale files.') {|v| options[:generate_locale_only] = v}
|
65
|
+
opt.on('--include-timestamps', 'Include timestamp columns in the YAML translation.') {|v| options[:include_timestamps] = v}
|
66
|
+
opt.on('--include-timestamp', 'Include timestamp columns in the YAML translation.') {|v| options[:include_timestamps] = v}
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
def defined_in_rails_i18n_repository?
|
71
|
+
begin
|
72
|
+
uri = "http://github.com/svenfuchs/rails-i18n/blob/master/rails/locale/#{locale_name}.yml"
|
73
|
+
OpenURI.open_uri(uri) do |res|
|
74
|
+
(res.base_uri.to_s == uri) && (res.status == %w[200 OK])
|
75
|
+
end
|
76
|
+
rescue
|
77
|
+
false
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
require File.join(File.dirname(__FILE__), '../i18n_locale/i18n_locale_command')
|
83
|
+
require File.join(File.dirname(__FILE__), '../i18n_translation/i18n_translation_command')
|
84
|
+
Rails::Generator::Commands::Create.send :include, I18nGenerator::Generator::Commands::Create
|
85
|
+
|
@@ -0,0 +1,187 @@
|
|
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} #g" # g is for 'generated'!
|
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(add_blank_line = false)
|
148
|
+
previous_indent_level = 0
|
149
|
+
@lines.inject('') do |ret, n|
|
150
|
+
ret << "\n" if add_blank_line && (n.indent_level < previous_indent_level) && !n.text.blank? && !ret.ends_with?("\n\n")
|
151
|
+
previous_indent_level = n.indent_level
|
152
|
+
ret << (n.text ? n.text.rstrip : '') + "\n"
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
class Nodes < Array
|
158
|
+
def initialize(parent)
|
159
|
+
super()
|
160
|
+
@parent = parent
|
161
|
+
end
|
162
|
+
|
163
|
+
def [](index)
|
164
|
+
if index.is_a?(String) || index.is_a?(Symbol)
|
165
|
+
return self.detect {|node| node.key == index} || add(index)
|
166
|
+
end
|
167
|
+
super
|
168
|
+
end
|
169
|
+
|
170
|
+
def last_leaf
|
171
|
+
c = @parent
|
172
|
+
loop do
|
173
|
+
return c if c.children.blank?
|
174
|
+
c = c.children.last
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
def add(node_name)
|
179
|
+
target_line = self.last_leaf.line + 1
|
180
|
+
@parent.document.nodes.each {|n| n.line += 1 if n.line >= target_line}
|
181
|
+
node = Node.new(@parent, target_line, node_name)
|
182
|
+
@parent.document.lines << node
|
183
|
+
@parent.document.lines.sort!
|
184
|
+
self << node unless @parent.is_a? YamlDocument
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|