ready_for_i18n 0.2.6 → 0.2.7
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +17 -6
- data/VERSION +1 -1
- data/bin/ready_for_i18n +3 -17
- data/lib/base_extractor.rb +6 -9
- data/lib/{label_extractor.rb → erb_helper_extractor.rb} +1 -1
- data/lib/html_attr_extractor.rb +26 -0
- data/lib/{text_extractor.rb → html_text_extractor.rb} +1 -1
- data/lib/i18n_generator.rb +29 -0
- data/lib/locale_dictionary.rb +3 -9
- data/lib/ready_for_i18n.rb +5 -3
- data/ready_for_i18n.gemspec +15 -10
- data/test/fixtures/html_attr.html.erb +7 -0
- data/test/{test_label_extractor.rb → test_erb_helper_extractor.rb} +5 -3
- data/test/test_html_attr_extractor.rb +20 -0
- data/test/{test_text_extrator.rb → test_html_text_extractor.rb} +4 -5
- data/test/test_locale_dictionary.rb +10 -3
- metadata +13 -8
data/README.rdoc
CHANGED
@@ -5,10 +5,13 @@ Ready_for_i18n is handy tool helping you in the first step of getting your local
|
|
5
5
|
It will automatically extract hard-coded text from your ERB view file,
|
6
6
|
then choose a proper key and replace them with the I18n.translate method.
|
7
7
|
|
8
|
-
Currently
|
8
|
+
Currently three extractors are available:
|
9
9
|
|
10
|
-
*
|
11
|
-
*
|
10
|
+
* HtmlTextExtractor will scan all HTML text nodes in you view files, like <b>Hello</b> then replace it with <b><%=t(:text_hello)%></b>.
|
11
|
+
* HtmlAttrExtractor will scan all visible HTML attribute in you view files, like <input type="submit" value="Back"> then replace it with <input type="submit" value="<%=t(:label_back)">.
|
12
|
+
* ErbHelperExtractor will scan all the text in helper methods like link_to('Login'...) and replace with link_to (t(:login)).
|
13
|
+
|
14
|
+
Introduction Blog at: http://zigzag.github.com/2009/12/17/get-your-local-rails-application-ready-for-i18n.html
|
12
15
|
|
13
16
|
== Installation:
|
14
17
|
gem install ready_for_i18n
|
@@ -16,15 +19,23 @@ Currently two extractors are available:
|
|
16
19
|
Hosed at http://www.gemcutter.org/gems/ready_for_i18n
|
17
20
|
|
18
21
|
== Basic Command Line Usage:
|
19
|
-
ready_for_i18n <path to ERB source files>
|
22
|
+
ready_for_i18n <path to ERB source files> [target path]
|
20
23
|
|
21
|
-
Your erb files in source path will be transformed(i18n_ready)
|
22
|
-
|
24
|
+
Your erb files in source path will be transformed(i18n_ready) and copy to target file path.
|
25
|
+
If target path is missing, then ready_for_i18n will do a Dry run and only generated the locale file.
|
23
26
|
|
27
|
+
A locale file will be output to STDOUT,which you can redirect to file like
|
28
|
+
ready_for_i18n <path to ERB source files> [target path] > /temp/en.yml
|
29
|
+
|
24
30
|
Using the following options:
|
25
31
|
--locale [LOCALE] Generating for the specified locale (default locale 'en')
|
26
32
|
--ext [EXTENSION] The file extension name of your views(default '.html.erb')
|
27
33
|
|
34
|
+
== Warning
|
35
|
+
* This tool is used based on the most "conventional" way of HTML and ERB. But I can not guarantee all the text will be extracted correctly.Create an issue in this github project page if you found some thing miss.
|
36
|
+
|
37
|
+
* Only tested when the local language is English. Other languages support is in the TODO list.
|
38
|
+
|
28
39
|
== Note on Patches/Pull Requests
|
29
40
|
|
30
41
|
* Fork the project.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.2.
|
1
|
+
0.2.7
|
data/bin/ready_for_i18n
CHANGED
@@ -42,6 +42,8 @@ opts.parse!
|
|
42
42
|
|
43
43
|
# Get source and destintation from command line
|
44
44
|
case ARGV.size
|
45
|
+
when 1
|
46
|
+
options['source'] = ARGV[0]
|
45
47
|
when 2
|
46
48
|
options['source'] = ARGV[0]
|
47
49
|
options['destination'] = ARGV[1]
|
@@ -50,21 +52,5 @@ case ARGV.size
|
|
50
52
|
exit(1)
|
51
53
|
end
|
52
54
|
|
53
|
-
def excute(src_path,target_path,locale,extension)
|
54
|
-
ext = extension || '.html.erb'
|
55
|
-
dict = ReadyForI18N::LocaleDictionary.new(locale)
|
56
|
-
Dir.glob(File.join(src_path,"**#{File::SEPARATOR}*#{ext}")).each do |f|
|
57
|
-
full_target_path = File.dirname(f).gsub(src_path,target_path)
|
58
|
-
FileUtils.makedirs full_target_path
|
59
|
-
target_file = File.join(full_target_path,File.basename(f))
|
60
|
-
ReadyForI18N::LabelExtractor.new(f,target_file).extract{|k,v| dict[k] = v}
|
61
|
-
ReadyForI18N::TextExtractor.new(target_file,target_file).extract{|k,v| dict[k] = v}
|
62
|
-
puts "i18n ready: #{target_file}"
|
63
|
-
end
|
64
|
-
locale_file = dict.write_to target_path
|
65
|
-
puts "------------------------------------------------------------------------------"
|
66
|
-
puts "Locale file: #{locale_file}"
|
67
|
-
end
|
68
|
-
|
69
55
|
# Run the i18n generating
|
70
|
-
excute(options
|
56
|
+
ReadyForI18N::I18nGenerator.excute(options)
|
data/lib/base_extractor.rb
CHANGED
@@ -1,14 +1,11 @@
|
|
1
|
+
require 'stringio'
|
2
|
+
|
1
3
|
module ReadyForI18N
|
2
4
|
module BaseExtractor
|
3
5
|
VALUE_PATTERN = /\w+/
|
4
|
-
def
|
5
|
-
|
6
|
-
|
7
|
-
end
|
8
|
-
|
9
|
-
def extract
|
10
|
-
buffer = ''
|
11
|
-
File.open(@erb_source).each do |line|
|
6
|
+
def extract(input)
|
7
|
+
buffer = StringIO.new
|
8
|
+
input.each do |line|
|
12
9
|
unless skip_line?(line)
|
13
10
|
values_in_line(line).each do |e|
|
14
11
|
if can_replace?(e)
|
@@ -19,7 +16,7 @@ module ReadyForI18N
|
|
19
16
|
end
|
20
17
|
buffer << line
|
21
18
|
end
|
22
|
-
|
19
|
+
buffer.string
|
23
20
|
end
|
24
21
|
def to_key(s)
|
25
22
|
result = to_value(s).scan(/\w+/).join('_').downcase
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module ReadyForI18N
|
2
|
+
class HtmlAttrExtractor < HtmlTextExtractor
|
3
|
+
LABEL_TAG_ATTR_PATTERN = [[/<img(.*)(\/>|<\/img>)/i,/alt=["'](.*?)["']/i],
|
4
|
+
[/<img(.*)(\/>|<\/img>)/i,/title=["'](.*?)["']/i],
|
5
|
+
[/<input(.*)\s*type\s*=\s*["']submit["']/i,/value\s*=\s*["'](.*?)["']/i],
|
6
|
+
[/<input\s*type\s*=\s*["']submit["'](.*)/i,/value\s*=\s*["'](.*?)["']/i],
|
7
|
+
[/<input(.*)\s*type\s*=\s*["']button["']/i,/value\s*=\s*["'](.*?)["']/i],
|
8
|
+
[/<input\s*type\s*=\s*["']button["'](.*)/i,/value\s*=\s*["'](.*?)["']/i]]
|
9
|
+
SKIP_PATTERN = /<%(.*)%>/
|
10
|
+
protected
|
11
|
+
def values_in_line(line)
|
12
|
+
values = []
|
13
|
+
LABEL_TAG_ATTR_PATTERN.each do |p|
|
14
|
+
attrs = line.match(p[0])[1] if line =~ p[0]
|
15
|
+
if attrs =~ p[1]
|
16
|
+
value = attrs.match(p[1])[1]
|
17
|
+
values << value unless value =~ SKIP_PATTERN
|
18
|
+
end
|
19
|
+
end
|
20
|
+
values
|
21
|
+
end
|
22
|
+
def key_prefix
|
23
|
+
'label'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module ReadyForI18N
|
2
|
+
class I18nGenerator
|
3
|
+
EXTRACTORS = [ErbHelperExtractor,HtmlTextExtractor,HtmlAttrExtractor]
|
4
|
+
def self.excute(opt)
|
5
|
+
@src_path = opt['source']
|
6
|
+
@target_path = opt['destination']
|
7
|
+
if @target_path && (!@target_path.end_with? File::SEPARATOR)
|
8
|
+
@target_path = "#{@target_path}#{File::SEPARATOR}"
|
9
|
+
end
|
10
|
+
@locale = opt['locale']
|
11
|
+
@ext = opt['extension'] || '.html.erb'
|
12
|
+
dict = ReadyForI18N::LocaleDictionary.new(@locale)
|
13
|
+
Dir.glob(File.join(@src_path,"**#{File::SEPARATOR}*#{@ext}")).each do |f|
|
14
|
+
result = EXTRACTORS.inject(File.read(f)) do |buffer,extractor|
|
15
|
+
extractor.new.extract(buffer){|k,v| dict[k] = v}
|
16
|
+
end
|
17
|
+
write_target_file(f,result) if @target_path
|
18
|
+
end
|
19
|
+
dict.write_to STDOUT
|
20
|
+
end
|
21
|
+
private
|
22
|
+
def self.write_target_file(source_file_name,content)
|
23
|
+
full_target_path = File.dirname(source_file_name).gsub(@src_path,@target_path)
|
24
|
+
FileUtils.makedirs full_target_path
|
25
|
+
target_file = File.join(full_target_path,File.basename(source_file_name))
|
26
|
+
File.open(target_file,'w+'){|f| f << content}
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/locale_dictionary.rb
CHANGED
@@ -7,15 +7,9 @@ module ReadyForI18N
|
|
7
7
|
def []=(key,value)
|
8
8
|
@hash[key] = value
|
9
9
|
end
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
File.open(file,'w+') do |f|
|
14
|
-
f.puts "#{@locale}:"
|
15
|
-
@hash.keys.sort{|a,b|a.to_s<=>b.to_s}.each { |k| f.puts " #{k}: #{@hash[k].dump}" }
|
16
|
-
end
|
17
|
-
file
|
10
|
+
def write_to(out)
|
11
|
+
out.puts "#{@locale}:"
|
12
|
+
@hash.keys.sort{|a,b|a.to_s<=>b.to_s}.each { |k| out.puts " #{k}: #{@hash[k].dump}" }
|
18
13
|
end
|
19
|
-
|
20
14
|
end
|
21
15
|
end
|
data/lib/ready_for_i18n.rb
CHANGED
data/ready_for_i18n.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{ready_for_i18n}
|
8
|
-
s.version = "0.2.
|
8
|
+
s.version = "0.2.7"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["zigzag"]
|
12
|
-
s.date = %q{2009-12-
|
12
|
+
s.date = %q{2009-12-21}
|
13
13
|
s.default_executable = %q{ready_for_i18n}
|
14
14
|
s.description = %q{ ready_for_i18n will help you extract visible hard-coded text from your ERB view files,
|
15
15
|
then choose a proper key and replace them with the I18n.translate method like t(:login)
|
@@ -29,20 +29,24 @@ Gem::Specification.new do |s|
|
|
29
29
|
"VERSION",
|
30
30
|
"bin/ready_for_i18n",
|
31
31
|
"lib/base_extractor.rb",
|
32
|
-
"lib/
|
32
|
+
"lib/erb_helper_extractor.rb",
|
33
|
+
"lib/html_attr_extractor.rb",
|
34
|
+
"lib/html_text_extractor.rb",
|
35
|
+
"lib/i18n_generator.rb",
|
33
36
|
"lib/locale_dictionary.rb",
|
34
37
|
"lib/ready_for_i18n.rb",
|
35
|
-
"lib/text_extractor.rb",
|
36
38
|
"ready_for_i18n.gemspec",
|
39
|
+
"test/fixtures/html_attr.html.erb",
|
37
40
|
"test/fixtures/index.html.erb",
|
38
41
|
"test/helper.rb",
|
39
42
|
"test/output/en.yml",
|
40
43
|
"test/output/label.html.erb",
|
41
44
|
"test/output/text.html.erb",
|
42
45
|
"test/test_base_extractor.rb",
|
43
|
-
"test/
|
44
|
-
"test/
|
45
|
-
"test/
|
46
|
+
"test/test_erb_helper_extractor.rb",
|
47
|
+
"test/test_html_attr_extractor.rb",
|
48
|
+
"test/test_html_text_extractor.rb",
|
49
|
+
"test/test_locale_dictionary.rb"
|
46
50
|
]
|
47
51
|
s.homepage = %q{http://github.com/zigzag/ready_for_i18n}
|
48
52
|
s.rdoc_options = ["--charset=UTF-8"]
|
@@ -52,9 +56,10 @@ Gem::Specification.new do |s|
|
|
52
56
|
s.test_files = [
|
53
57
|
"test/helper.rb",
|
54
58
|
"test/test_base_extractor.rb",
|
55
|
-
"test/
|
56
|
-
"test/
|
57
|
-
"test/
|
59
|
+
"test/test_erb_helper_extractor.rb",
|
60
|
+
"test/test_html_attr_extractor.rb",
|
61
|
+
"test/test_html_text_extractor.rb",
|
62
|
+
"test/test_locale_dictionary.rb"
|
58
63
|
]
|
59
64
|
|
60
65
|
if s.respond_to? :specification_version then
|
@@ -0,0 +1,7 @@
|
|
1
|
+
<img src="<%= ApplicationController.root_context -%>/images/print.gif" alt="Print" />
|
2
|
+
<IMG src="<%= ApplicationController.root_context -%>/images/priority/<%= rule_measure.rule_priority -%>.gif" title="Measure"></IMG>
|
3
|
+
<input id="saveBtn" value="Save" onclick="SelectBox.select_all('to');submit();return false;" type="submit">
|
4
|
+
<input type="submit" value="Compare on chart" />
|
5
|
+
<input type="button" name="button_copy" id="copy_<%= u profile.key %>" value="copy" onClick='var name=prompt("Name for the new profile"); if (name!=null) {$("copy_<%= profile.id %>").value=name; submit();} else {return false;}'>
|
6
|
+
<input type="hidden" value="Should not extract">
|
7
|
+
<input type="text" value="<%= should ignore me %>">
|
@@ -1,10 +1,10 @@
|
|
1
1
|
require 'helper'
|
2
2
|
|
3
|
-
class
|
3
|
+
class TestErbHelperExtractor < Test::Unit::TestCase
|
4
4
|
should "extract the label that need i18n from the erb view file" do
|
5
5
|
f = File.join(File.dirname(__FILE__),'fixtures','index.html.erb')
|
6
6
|
result = []
|
7
|
-
ReadyForI18N::
|
7
|
+
ReadyForI18N::ErbHelperExtractor.new.extract(File.read(f)){|k,v| result << v}
|
8
8
|
expected = %w{edit delete select export cancel} << "Add Event"
|
9
9
|
assert_same_elements(expected,result)
|
10
10
|
end
|
@@ -12,7 +12,9 @@ class TestLabelExtractor < Test::Unit::TestCase
|
|
12
12
|
should "replace the label in helper with t method" do
|
13
13
|
source = File.join(File.dirname(__FILE__),'fixtures','index.html.erb')
|
14
14
|
target = File.join(File.dirname(__FILE__),'output','label.html.erb')
|
15
|
-
|
15
|
+
output = nil
|
16
|
+
File.open(source){|f| output = ReadyForI18N::ErbHelperExtractor.new.extract(f)}
|
17
|
+
File.open(target,'w+'){|f| f << output}
|
16
18
|
expected = %w{edit delete select export cancel add_event}
|
17
19
|
expected.each do |e|
|
18
20
|
assert(File.read(target).include?("t(:label_#{e})"), "should found t method with symbol")
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestHtmlAttrExtractor < Test::Unit::TestCase
|
4
|
+
should "extract the Some Attribute that need i18n from the HTML file" do
|
5
|
+
f = File.join(File.dirname(__FILE__),'fixtures','html_attr.html.erb')
|
6
|
+
expected = %w{Print Measure Save copy} << 'Compare on chart'
|
7
|
+
result = []
|
8
|
+
ReadyForI18N::HtmlAttrExtractor.new.extract(File.read(f)){|k,v| result << v}
|
9
|
+
assert_same_elements(expected,result)
|
10
|
+
end
|
11
|
+
|
12
|
+
should "replace the attribut in html with t method" do
|
13
|
+
source = File.join(File.dirname(__FILE__),'fixtures','html_attr.html.erb')
|
14
|
+
output = ReadyForI18N::HtmlAttrExtractor.new.extract(File.read(source))
|
15
|
+
%w{Print Measure Save copy}.each do |e|
|
16
|
+
assert(output.include?("<%=t(:label_#{e.downcase.gsub(':','')})%>"), "should found t method with symbol")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
@@ -1,20 +1,19 @@
|
|
1
1
|
require 'helper'
|
2
2
|
|
3
|
-
class
|
3
|
+
class TestHtmlTextExtractor < Test::Unit::TestCase
|
4
4
|
should "extract the text that need i18n from the erb view file" do
|
5
5
|
f = File.join(File.dirname(__FILE__),'fixtures','index.html.erb')
|
6
6
|
expected = %w{Users Login Name Groups Operations Login: Name: Password: Export} << 'Confirm password:'
|
7
7
|
result = []
|
8
|
-
ReadyForI18N::
|
8
|
+
ReadyForI18N::HtmlTextExtractor.new.extract(File.read(f)){|k,v| result << v}
|
9
9
|
assert_same_elements(expected,result)
|
10
10
|
end
|
11
11
|
|
12
12
|
should "replace the text in helper with t method" do
|
13
13
|
source = File.join(File.dirname(__FILE__),'fixtures','index.html.erb')
|
14
|
-
|
15
|
-
ReadyForI18N::TextExtractor.new(source,target).extract
|
14
|
+
output = ReadyForI18N::HtmlTextExtractor.new.extract(File.read(source))
|
16
15
|
%w{Users Login Name Groups Operations Login: Name: Password: Export}.each do |e|
|
17
|
-
assert(
|
16
|
+
assert(output.include?("<%=t(:text_#{e.downcase.gsub(':','')})%>"), "should found t method with symbol")
|
18
17
|
end
|
19
18
|
end
|
20
19
|
|
@@ -2,17 +2,24 @@ require 'helper'
|
|
2
2
|
|
3
3
|
class TestLocaleDictionary < Test::Unit::TestCase
|
4
4
|
should "save the result hash to yaml file" do
|
5
|
-
|
5
|
+
locale_file = File.join(File.dirname(__FILE__),'output','en.yml')
|
6
|
+
|
6
7
|
dict = ReadyForI18N::LocaleDictionary.new
|
7
8
|
dict['login_key'] = 'Login:'
|
8
9
|
dict['label'] = 'OK'
|
9
10
|
dict['text'] = 'Please Confirm:'
|
10
11
|
dict['with_quote'] = 'It is my "Label"'
|
11
|
-
dict.write_to
|
12
|
+
File.open(locale_file,'w+') {|f| dict.write_to f}
|
12
13
|
|
13
|
-
result = YAML.load_file
|
14
|
+
result = YAML.load_file locale_file
|
14
15
|
assert_equal('Login:', result['en']['login_key'])
|
15
16
|
assert_equal("It is my \"Label\"", result['en']['with_quote'])
|
16
17
|
end
|
17
18
|
|
19
|
+
should "output to STDOUT when write to is nil" do
|
20
|
+
dict = ReadyForI18N::LocaleDictionary.new
|
21
|
+
dict['label'] = 'OK'
|
22
|
+
dict.write_to STDOUT
|
23
|
+
end
|
24
|
+
|
18
25
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ready_for_i18n
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- zigzag
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-12-
|
12
|
+
date: 2009-12-21 00:00:00 +08:00
|
13
13
|
default_executable: ready_for_i18n
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -40,20 +40,24 @@ files:
|
|
40
40
|
- VERSION
|
41
41
|
- bin/ready_for_i18n
|
42
42
|
- lib/base_extractor.rb
|
43
|
-
- lib/
|
43
|
+
- lib/erb_helper_extractor.rb
|
44
|
+
- lib/html_attr_extractor.rb
|
45
|
+
- lib/html_text_extractor.rb
|
46
|
+
- lib/i18n_generator.rb
|
44
47
|
- lib/locale_dictionary.rb
|
45
48
|
- lib/ready_for_i18n.rb
|
46
|
-
- lib/text_extractor.rb
|
47
49
|
- ready_for_i18n.gemspec
|
50
|
+
- test/fixtures/html_attr.html.erb
|
48
51
|
- test/fixtures/index.html.erb
|
49
52
|
- test/helper.rb
|
50
53
|
- test/output/en.yml
|
51
54
|
- test/output/label.html.erb
|
52
55
|
- test/output/text.html.erb
|
53
56
|
- test/test_base_extractor.rb
|
54
|
-
- test/
|
57
|
+
- test/test_erb_helper_extractor.rb
|
58
|
+
- test/test_html_attr_extractor.rb
|
59
|
+
- test/test_html_text_extractor.rb
|
55
60
|
- test/test_locale_dictionary.rb
|
56
|
-
- test/test_text_extrator.rb
|
57
61
|
has_rdoc: true
|
58
62
|
homepage: http://github.com/zigzag/ready_for_i18n
|
59
63
|
licenses: []
|
@@ -85,6 +89,7 @@ summary: ready_for_i18n is a tool helping for the very first step of transfering
|
|
85
89
|
test_files:
|
86
90
|
- test/helper.rb
|
87
91
|
- test/test_base_extractor.rb
|
88
|
-
- test/
|
92
|
+
- test/test_erb_helper_extractor.rb
|
93
|
+
- test/test_html_attr_extractor.rb
|
94
|
+
- test/test_html_text_extractor.rb
|
89
95
|
- test/test_locale_dictionary.rb
|
90
|
-
- test/test_text_extrator.rb
|