ready_for_i18n 0.2.8 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.textile +1 -1
- data/Rakefile +2 -0
- data/VERSION +1 -1
- data/bin/ready_for_i18n +16 -2
- data/lib/extractor_base.rb +11 -3
- data/lib/html_attr_extractor.rb +4 -7
- data/lib/html_text_extractor.rb +3 -3
- data/lib/i18n_generator.rb +25 -13
- data/lib/key_mapper.rb +15 -0
- data/lib/locale_dictionary.rb +3 -16
- data/lib/no_key_dictionary.rb +14 -0
- data/lib/ready_for_i18n.rb +5 -0
- data/ready_for_i18n.gemspec +13 -5
- data/test/fixtures/html_attr.html.erb +4 -1
- data/test/fixtures/index.html.erb +4 -0
- data/test/output/en.yml +4 -2
- data/test/output/label.html.erb +4 -0
- data/test/test_extractor_base.rb +13 -0
- data/test/test_html_attr_extractor.rb +2 -2
- data/test/test_html_text_extractor.rb +2 -2
- data/test/test_key_mapper.rb +26 -0
- data/test/test_locale_dictionary.rb +15 -2
- data/test/test_nokey_dictionary.rb +33 -0
- metadata +18 -3
- data/test/output/text.html.erb +0 -89
data/README.textile
CHANGED
@@ -36,11 +36,11 @@ Using the following options:
|
|
36
36
|
|
37
37
|
| |@--locale [LOCALE]@|@Generating for the specified locale (default locale 'en')@|
|
38
38
|
| |@--ext [EXTENSION]@|@The file extension name of your views(default '.html.erb')@|
|
39
|
+
| |@--dot@|@Generate a structured dictionary file and support `Lazy` Lookup of Rails > 2.3@|
|
39
40
|
|
40
41
|
h2. Warning
|
41
42
|
|
42
43
|
* 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.
|
43
|
-
* Only tested when the local language is English. Other languages support is in the TODO list.
|
44
44
|
|
45
45
|
h2. Note on Patches/Pull Requests
|
46
46
|
|
data/Rakefile
CHANGED
@@ -15,6 +15,8 @@ END_OF_DESC
|
|
15
15
|
gem.homepage = "http://github.com/zigzag/ready_for_i18n"
|
16
16
|
gem.authors = ["zigzag"]
|
17
17
|
gem.add_development_dependency "thoughtbot-shoulda", ">= 0"
|
18
|
+
gem.add_dependency("ya2yaml", [">= 0.26"])
|
19
|
+
|
18
20
|
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
19
21
|
end
|
20
22
|
Jeweler::GemcutterTasks.new
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.3.0
|
data/bin/ready_for_i18n
CHANGED
@@ -25,6 +25,11 @@ HELP
|
|
25
25
|
require 'optparse'
|
26
26
|
require 'fileutils'
|
27
27
|
require 'ready_for_i18n'
|
28
|
+
|
29
|
+
def error_parameter
|
30
|
+
puts "Invalid options. Run `ready_for_i18n --help` for assistance."
|
31
|
+
exit(1)
|
32
|
+
end
|
28
33
|
|
29
34
|
options = {}
|
30
35
|
opts = OptionParser.new do |opts|
|
@@ -40,7 +45,17 @@ opts = OptionParser.new do |opts|
|
|
40
45
|
opts.on("--dot","Generate a structured dictionary file and support `Lazy` Lookup of Rails > 2.3 ") do |dot|
|
41
46
|
options['dot'] = true
|
42
47
|
end
|
48
|
+
|
49
|
+
opts.on("--nokey",
|
50
|
+
"Output only the text found in your view files but not generate the keys. Normally used for the non-english project") do |nokey|
|
51
|
+
options['nokey'] = true
|
52
|
+
end
|
43
53
|
|
54
|
+
opts.on('--keymap <extracted_locale_text_file>:<english_key_file>',
|
55
|
+
"Using two files for the key mapping from locale text extracted(with --nokey) to english. Separated by the colon ':'") do |mapper|
|
56
|
+
error_parameter if mapper.split(':').size != 2
|
57
|
+
options['keymap'] = mapper
|
58
|
+
end
|
44
59
|
end
|
45
60
|
|
46
61
|
# Read command line options into `options` hash
|
@@ -54,8 +69,7 @@ case ARGV.size
|
|
54
69
|
options['source'] = ARGV[0]
|
55
70
|
options['destination'] = ARGV[1]
|
56
71
|
else
|
57
|
-
|
58
|
-
exit(1)
|
72
|
+
error_parameter
|
59
73
|
end
|
60
74
|
|
61
75
|
# Run the i18n generating
|
data/lib/extractor_base.rb
CHANGED
@@ -2,13 +2,20 @@ require 'stringio'
|
|
2
2
|
|
3
3
|
module ReadyForI18N
|
4
4
|
module ExtractorBase
|
5
|
-
|
5
|
+
|
6
6
|
def self.use_dot(on_off)
|
7
7
|
@use_dot = on_off
|
8
8
|
end
|
9
9
|
def self.use_dot?
|
10
10
|
@use_dot
|
11
11
|
end
|
12
|
+
def self.key_mapper=(mapper)
|
13
|
+
@key_mapper = mapper
|
14
|
+
end
|
15
|
+
def self.key_mapper
|
16
|
+
@key_mapper
|
17
|
+
end
|
18
|
+
|
12
19
|
def extract(input)
|
13
20
|
buffer = StringIO.new
|
14
21
|
input.each do |line|
|
@@ -25,11 +32,12 @@ module ReadyForI18N
|
|
25
32
|
buffer.string
|
26
33
|
end
|
27
34
|
def to_key(s)
|
28
|
-
|
35
|
+
val = to_value(s)
|
36
|
+
result = (ExtractorBase.key_mapper) ? ExtractorBase.key_mapper.key_for(val) : val.scan(/\w+/).join('_').downcase
|
29
37
|
key_prefix ? "#{key_prefix}_#{result}" : result
|
30
38
|
end
|
31
39
|
def can_replace?(e)
|
32
|
-
e.
|
40
|
+
e.strip.size > 1
|
33
41
|
end
|
34
42
|
def t_method(val,wrap=false)
|
35
43
|
m = ExtractorBase.use_dot? ? "t('.#{to_key(val)}')" : "t(:#{to_key(val)})"
|
data/lib/html_attr_extractor.rb
CHANGED
@@ -2,18 +2,15 @@ module ReadyForI18N
|
|
2
2
|
class HtmlAttrExtractor < HtmlTextExtractor
|
3
3
|
LABEL_TAG_ATTR_PATTERN = [[/<img(.*)(\/>|<\/img>)/i,/alt=["'](.*?)["']/i],
|
4
4
|
[/<img(.*)(\/>|<\/img>)/i,/title=["'](.*?)["']/i],
|
5
|
-
[/<input(.*)\s*type\s*=\s*["']submit["']/i,/value\s*=\s*["'](.*?)["']/i],
|
6
|
-
[/<input\s*type\s*=\s*["']
|
7
|
-
[/<input(.*)\s*type\s*=\s*["']button["']/i,/value\s*=\s*["'](.*?)["']/i],
|
8
|
-
[/<input\s*type\s*=\s*["']button["'](.*)/i,/value\s*=\s*["'](.*?)["']/i]]
|
5
|
+
[/<input(.*)\s*type\s*=\s*["']submit["'](.*)/i,/value\s*=\s*["'](.*?)["']/i],
|
6
|
+
[/<input(.*)\s*type\s*=\s*["']button["'](.*)/i,/value\s*=\s*["'](.*?)["']/i]]
|
9
7
|
SKIP_PATTERN = /<%(.*)%>/
|
10
8
|
protected
|
11
9
|
def values_in_line(line)
|
12
10
|
values = []
|
13
11
|
LABEL_TAG_ATTR_PATTERN.each do |p|
|
14
|
-
|
15
|
-
|
16
|
-
value = attrs.match(p[1])[1]
|
12
|
+
if line =~ p[0] && line =~ p[1]
|
13
|
+
value = line.match(p[1])[1]
|
17
14
|
values << value unless value =~ SKIP_PATTERN
|
18
15
|
end
|
19
16
|
end
|
data/lib/html_text_extractor.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module ReadyForI18N
|
2
2
|
class HtmlTextExtractor
|
3
3
|
SKIP_TAGS = [[/<script/i,/<\/script>/i],[/<%/,/%>/],[/<style/i,/\/style>/i]]
|
4
|
-
SKIP_INLINE_TAG = [
|
4
|
+
SKIP_INLINE_TAG = [/<script>(.*?)<\/script>/i,/<%(.*?)%>/,/<(.*?)>/,/<(.*)$/,/^(.*)>/,/ /]
|
5
5
|
SEPERATOR = '_@@@_'
|
6
6
|
|
7
7
|
include ReadyForI18N::ExtractorBase
|
@@ -12,10 +12,10 @@ module ReadyForI18N
|
|
12
12
|
end
|
13
13
|
def skip_line?(s)
|
14
14
|
@stack ||= []
|
15
|
-
return
|
15
|
+
return false if s.nil? || s.strip.size == 0
|
16
16
|
jump_in_tag = SKIP_TAGS.find{ |start_tag,end_tag| s =~ start_tag}
|
17
17
|
@stack.push jump_in_tag[1] if jump_in_tag
|
18
|
-
|
18
|
+
unless @stack.empty?
|
19
19
|
end_tag_match = s.match(@stack.last)
|
20
20
|
if end_tag_match
|
21
21
|
@stack.pop
|
data/lib/i18n_generator.rb
CHANGED
@@ -4,27 +4,39 @@ module ReadyForI18N
|
|
4
4
|
PATH_PATTERN = /\/views\/(.*)/
|
5
5
|
|
6
6
|
def self.excute(opt)
|
7
|
-
|
8
|
-
@target_path = opt['destination']
|
9
|
-
if @target_path && (!@target_path.end_with? File::SEPARATOR)
|
10
|
-
@target_path = "#{@target_path}#{File::SEPARATOR}"
|
11
|
-
end
|
12
|
-
@locale = opt['locale']
|
13
|
-
@ext = opt['extension'] || '.html.erb'
|
14
|
-
|
15
|
-
ReadyForI18N::ExtractorBase.use_dot(true) if opt['dot']
|
16
|
-
|
17
|
-
dict = ReadyForI18N::LocaleDictionary.new(@locale)
|
7
|
+
setupOptions(opt)
|
18
8
|
Dir.glob(File.join(@src_path,"**#{File::SEPARATOR}*#{@ext}")).each do |f|
|
19
9
|
path = f.match(PATH_PATTERN)[1].gsub(/#{@ext}$/,'').split '/' if opt['dot'] && f =~ PATH_PATTERN
|
20
10
|
result = EXTRACTORS.inject(File.read(f)) do |buffer,extractor|
|
21
|
-
extractor.new.extract(buffer){|k,v| dict.push(k,v,path)}
|
11
|
+
extractor.new.extract(buffer){|k,v| @dict.push(k,v,path)}
|
22
12
|
end
|
23
13
|
write_target_file(f,result) if @target_path
|
24
14
|
end
|
25
|
-
dict.write_to STDOUT
|
15
|
+
@dict.write_to STDOUT
|
26
16
|
end
|
17
|
+
|
27
18
|
private
|
19
|
+
def self.setupOptions(opt)
|
20
|
+
@src_path = opt['source']
|
21
|
+
@locale = opt['locale']
|
22
|
+
if opt['nokey']
|
23
|
+
@dict = NoKeyDictionary.new(@locale)
|
24
|
+
else
|
25
|
+
@dict = LocaleDictionary.new(@locale)
|
26
|
+
@target_path = opt['destination']
|
27
|
+
if @target_path && (!@target_path.end_with? File::SEPARATOR)
|
28
|
+
@target_path = "#{@target_path}#{File::SEPARATOR}"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
@ext = opt['extension'] || '.html.erb'
|
32
|
+
ExtractorBase.use_dot(true) if opt['dot']
|
33
|
+
if opt['keymap']
|
34
|
+
files_content = opt['keymap'].split(':').map{|f| File.read(f)}
|
35
|
+
ReadyForI18N::ExtractorBase.key_mapper = KeyMapper.new(*files_content)
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
28
40
|
def self.write_target_file(source_file_name,content)
|
29
41
|
full_target_path = File.dirname(source_file_name).gsub(@src_path,@target_path)
|
30
42
|
FileUtils.makedirs full_target_path
|
data/lib/key_mapper.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
module ReadyForI18N
|
2
|
+
class KeyMapper
|
3
|
+
def initialize(text1,text2)
|
4
|
+
@hash = {}
|
5
|
+
arr1 = text1.split("\n")
|
6
|
+
arr2 = text2.split("\n")
|
7
|
+
raise 'Mapper files should contain the same number of lines' if arr1.size != arr2.size
|
8
|
+
arr1.each_with_index { |text,i| @hash[text] = arr2[i] }
|
9
|
+
end
|
10
|
+
def key_for(text)
|
11
|
+
possible_key = @hash[text] ? @hash[text] : @hash.invert[text]
|
12
|
+
possible_key.scan(/\w+/).join('_').downcase
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/locale_dictionary.rb
CHANGED
@@ -10,22 +10,9 @@ module ReadyForI18N
|
|
10
10
|
h[key] = value
|
11
11
|
end
|
12
12
|
def write_to(out)
|
13
|
-
out.puts "#{@locale}:"
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
private
|
18
|
-
def write_out_hash(out,hash,intent)
|
19
|
-
hash.keys.sort{|a,b|a.to_s<=>b.to_s}.each do |k|
|
20
|
-
key_with_indent = "#{' '*intent}#{k}:"
|
21
|
-
val = hash[k]
|
22
|
-
if (val.is_a? Hash)
|
23
|
-
out.puts(key_with_indent)
|
24
|
-
write_out_hash(out, val, intent + 1)
|
25
|
-
else
|
26
|
-
out.puts("#{key_with_indent} #{val.dump}" )
|
27
|
-
end
|
28
|
-
end
|
13
|
+
# out.puts "#{@locale}:"
|
14
|
+
$KCODE = 'UTF8'
|
15
|
+
out.puts({"#{@locale}" => @hash}.ya2yaml)
|
29
16
|
end
|
30
17
|
end
|
31
18
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'set'
|
2
|
+
module ReadyForI18N
|
3
|
+
class NoKeyDictionary
|
4
|
+
def initialize(locale = nil)
|
5
|
+
@set = Set.new
|
6
|
+
end
|
7
|
+
def push(key,value,path = nil)
|
8
|
+
@set << value if value && !value.strip.empty?
|
9
|
+
end
|
10
|
+
def write_to(out)
|
11
|
+
@set.each { |e| out.puts e }
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
data/lib/ready_for_i18n.rb
CHANGED
@@ -1,6 +1,11 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'ya2yaml'
|
3
|
+
|
1
4
|
require 'extractor_base'
|
2
5
|
require 'html_text_extractor'
|
3
6
|
require 'html_attr_extractor'
|
4
7
|
require 'erb_helper_extractor'
|
5
8
|
require 'locale_dictionary'
|
9
|
+
require 'no_key_dictionary'
|
10
|
+
require 'key_mapper'
|
6
11
|
require 'i18n_generator'
|
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.
|
8
|
+
s.version = "0.3.0"
|
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-30}
|
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)
|
@@ -33,7 +33,9 @@ Gem::Specification.new do |s|
|
|
33
33
|
"lib/html_attr_extractor.rb",
|
34
34
|
"lib/html_text_extractor.rb",
|
35
35
|
"lib/i18n_generator.rb",
|
36
|
+
"lib/key_mapper.rb",
|
36
37
|
"lib/locale_dictionary.rb",
|
38
|
+
"lib/no_key_dictionary.rb",
|
37
39
|
"lib/ready_for_i18n.rb",
|
38
40
|
"ready_for_i18n.gemspec",
|
39
41
|
"test/fixtures/html_attr.html.erb",
|
@@ -41,12 +43,13 @@ Gem::Specification.new do |s|
|
|
41
43
|
"test/helper.rb",
|
42
44
|
"test/output/en.yml",
|
43
45
|
"test/output/label.html.erb",
|
44
|
-
"test/output/text.html.erb",
|
45
46
|
"test/test_erb_helper_extractor.rb",
|
46
47
|
"test/test_extractor_base.rb",
|
47
48
|
"test/test_html_attr_extractor.rb",
|
48
49
|
"test/test_html_text_extractor.rb",
|
49
|
-
"test/
|
50
|
+
"test/test_key_mapper.rb",
|
51
|
+
"test/test_locale_dictionary.rb",
|
52
|
+
"test/test_nokey_dictionary.rb"
|
50
53
|
]
|
51
54
|
s.homepage = %q{http://github.com/zigzag/ready_for_i18n}
|
52
55
|
s.rdoc_options = ["--charset=UTF-8"]
|
@@ -59,7 +62,9 @@ Gem::Specification.new do |s|
|
|
59
62
|
"test/test_extractor_base.rb",
|
60
63
|
"test/test_html_attr_extractor.rb",
|
61
64
|
"test/test_html_text_extractor.rb",
|
62
|
-
"test/
|
65
|
+
"test/test_key_mapper.rb",
|
66
|
+
"test/test_locale_dictionary.rb",
|
67
|
+
"test/test_nokey_dictionary.rb"
|
63
68
|
]
|
64
69
|
|
65
70
|
if s.respond_to? :specification_version then
|
@@ -68,11 +73,14 @@ Gem::Specification.new do |s|
|
|
68
73
|
|
69
74
|
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
70
75
|
s.add_development_dependency(%q<thoughtbot-shoulda>, [">= 0"])
|
76
|
+
s.add_runtime_dependency(%q<ya2yaml>, [">= 0.26"])
|
71
77
|
else
|
72
78
|
s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
|
79
|
+
s.add_dependency(%q<ya2yaml>, [">= 0.26"])
|
73
80
|
end
|
74
81
|
else
|
75
82
|
s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
|
83
|
+
s.add_dependency(%q<ya2yaml>, [">= 0.26"])
|
76
84
|
end
|
77
85
|
end
|
78
86
|
|
@@ -4,4 +4,7 @@
|
|
4
4
|
<input type="submit" value="Compare on chart" />
|
5
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
6
|
<input type="hidden" value="Should not extract">
|
7
|
-
<input type="text" value="<%= should ignore me %>">
|
7
|
+
<input type="text" value="<%= should ignore me %>">
|
8
|
+
|
9
|
+
<input id="sub_But" type="button" value="save2" class="submit">
|
10
|
+
|
data/test/output/en.yml
CHANGED
data/test/output/label.html.erb
CHANGED
@@ -93,3 +93,7 @@
|
|
93
93
|
<%= link_to_remote t(:label_add_event), {:url => { :controller => 'events', :action => "new", :rid => params['rid'] },
|
94
94
|
:update => "event_form"}, {:class => 'action'} %>
|
95
95
|
|
96
|
+
<td>
|
97
|
+
SkillName:<%=@skill_name%>
|
98
|
+
</td>
|
99
|
+
<script>inlineScriptShouldIgnore();</script>
|
data/test/test_extractor_base.rb
CHANGED
@@ -36,5 +36,18 @@ class TestExtractorBase < Test::Unit::TestCase
|
|
36
36
|
assert_equal("t('.label_login')", c.t_method('Login:'))
|
37
37
|
assert_equal("<%=t('.label_login')%>", c.t_method('Login:',true))
|
38
38
|
end
|
39
|
+
|
40
|
+
should "using keymapper when set" do
|
41
|
+
mapper = Object.new
|
42
|
+
def mapper.key_for(text); 'keeey' ;end
|
43
|
+
ReadyForI18N::ExtractorBase.key_mapper = mapper
|
44
|
+
c = Object.new
|
45
|
+
def c.key_prefix; 'label' ;end
|
46
|
+
def c.to_value(s); s ;end
|
47
|
+
c.extend ReadyForI18N::ExtractorBase
|
48
|
+
assert_equal('label_keeey', c.to_key('Login:'))
|
49
|
+
assert_equal("t(:label_keeey)", c.t_method('Login:'))
|
50
|
+
ReadyForI18N::ExtractorBase.key_mapper = nil
|
51
|
+
end
|
39
52
|
|
40
53
|
end
|
@@ -3,7 +3,7 @@ require 'helper'
|
|
3
3
|
class TestHtmlAttrExtractor < Test::Unit::TestCase
|
4
4
|
should "extract the Some Attribute that need i18n from the HTML file" do
|
5
5
|
f = File.join(File.dirname(__FILE__),'fixtures','html_attr.html.erb')
|
6
|
-
expected = %w{Print Measure Save copy} << 'Compare on chart'
|
6
|
+
expected = %w{Print Measure Save copy save2} << 'Compare on chart'
|
7
7
|
result = []
|
8
8
|
ReadyForI18N::HtmlAttrExtractor.new.extract(File.read(f)){|k,v| result << v}
|
9
9
|
assert_same_elements(expected,result)
|
@@ -12,7 +12,7 @@ class TestHtmlAttrExtractor < Test::Unit::TestCase
|
|
12
12
|
should "replace the attribut in html with t method" do
|
13
13
|
source = File.join(File.dirname(__FILE__),'fixtures','html_attr.html.erb')
|
14
14
|
output = ReadyForI18N::HtmlAttrExtractor.new.extract(File.read(source))
|
15
|
-
%w{Print Measure Save copy}.each do |e|
|
15
|
+
%w{Print Measure Save copy save2}.each do |e|
|
16
16
|
assert(output.include?("<%=t(:label_#{e.downcase.gsub(':','')})%>"), "should found t method with symbol")
|
17
17
|
end
|
18
18
|
end
|
@@ -3,7 +3,7 @@ require 'helper'
|
|
3
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
|
-
expected = %w{Users Login Name Groups Operations Login: Name: Password: Export} << 'Confirm password:' << 'select all »'
|
6
|
+
expected = %w{Users Login Name Groups Operations Login: Name: Password: Export SkillName:} << 'Confirm password:' << 'select all »'
|
7
7
|
result = []
|
8
8
|
ReadyForI18N::HtmlTextExtractor.new.extract(File.read(f)){|k,v| result << v}
|
9
9
|
assert_same_elements(expected,result)
|
@@ -12,7 +12,7 @@ class TestHtmlTextExtractor < Test::Unit::TestCase
|
|
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
14
|
output = ReadyForI18N::HtmlTextExtractor.new.extract(File.read(source))
|
15
|
-
%w{Users Login Name Groups Operations Login: Name: Password: Export}.each do |e|
|
15
|
+
%w{Users Login Name Groups Operations Login: Name: Password: Export SkillName:}.each do |e|
|
16
16
|
assert(output.include?("<%=t(:text_#{e.downcase.gsub(':','')})%>"), "should found t method with symbol")
|
17
17
|
end
|
18
18
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require 'stringio'
|
3
|
+
|
4
|
+
class TestKeyMapper < Test::Unit::TestCase
|
5
|
+
|
6
|
+
should "Find the key of the specified text according to mapper string" do
|
7
|
+
text_en = "key one\nkey two\n"
|
8
|
+
text_cn = "jian yi\njian er\n"
|
9
|
+
|
10
|
+
mapper = ReadyForI18N::KeyMapper.new(text_en,text_cn)
|
11
|
+
assert_equal("key_one", mapper.key_for("jian yi"))
|
12
|
+
assert_equal("jian_yi", mapper.key_for("key one"))
|
13
|
+
end
|
14
|
+
|
15
|
+
should "Raise an Error when two file are in different line numbers" do
|
16
|
+
text_en = "key one\nkey two\n"
|
17
|
+
text_cn = "jian yi\njian er"
|
18
|
+
assert_nothing_raised(Exception) { mapper = ReadyForI18N::KeyMapper.new(text_en,text_cn) }
|
19
|
+
|
20
|
+
text_en = "key one\nkey two\n"
|
21
|
+
text_cn = "jian yi\n"
|
22
|
+
assert_raise(RuntimeError) { mapper = ReadyForI18N::KeyMapper.new(text_en,text_cn) }
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
end
|
@@ -10,6 +10,8 @@ class TestLocaleDictionary < Test::Unit::TestCase
|
|
10
10
|
dict.push 'label','OK'
|
11
11
|
dict.push 'text','Please Confirm:'
|
12
12
|
dict.push 'with_quote','It is my "Label"'
|
13
|
+
dict.push '中文','没问题'
|
14
|
+
|
13
15
|
File.open(locale_file,'w+') {|f| dict.write_to f}
|
14
16
|
|
15
17
|
result = YAML.load_file locale_file
|
@@ -22,7 +24,8 @@ class TestLocaleDictionary < Test::Unit::TestCase
|
|
22
24
|
dict.push 'label','OK'
|
23
25
|
out = StringIO.new
|
24
26
|
dict.write_to out
|
25
|
-
|
27
|
+
hash = YAML.load out.string
|
28
|
+
assert_equal("OK", hash['en']['label'])
|
26
29
|
end
|
27
30
|
|
28
31
|
should "should intent output when path is given" do
|
@@ -30,7 +33,17 @@ class TestLocaleDictionary < Test::Unit::TestCase
|
|
30
33
|
dict.push 'label','OK',['my_view']
|
31
34
|
out = StringIO.new
|
32
35
|
dict.write_to out
|
33
|
-
|
36
|
+
hash = YAML.load out.string
|
37
|
+
assert_equal("OK",hash['en']['my_view']['label'])
|
38
|
+
end
|
39
|
+
|
40
|
+
should "handle Chinese character as well" do
|
41
|
+
dict = ReadyForI18N::LocaleDictionary.new('zh_CN')
|
42
|
+
dict.push '中文','没问题'
|
43
|
+
out = StringIO.new
|
44
|
+
dict.write_to out
|
45
|
+
hash = YAML.load out.string
|
46
|
+
assert_equal("没问题",hash['zh_CN']['中文'])
|
34
47
|
end
|
35
48
|
|
36
49
|
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require 'stringio'
|
3
|
+
|
4
|
+
class TestNoKeyDictionary < Test::Unit::TestCase
|
5
|
+
|
6
|
+
should "output to STDOUT when write to is nil" do
|
7
|
+
dict = ReadyForI18N::NoKeyDictionary.new
|
8
|
+
dict.push 'label','OK'
|
9
|
+
out = StringIO.new
|
10
|
+
dict.write_to out
|
11
|
+
assert_equal("OK\n", out.string)
|
12
|
+
end
|
13
|
+
|
14
|
+
should "two same string will only generate one line" do
|
15
|
+
dict = ReadyForI18N::NoKeyDictionary.new
|
16
|
+
dict.push 'Key 1','Same Value:'
|
17
|
+
dict.push 'Key 2','Same Value:'
|
18
|
+
dict.push 'key 3','Different Value:'
|
19
|
+
out = StringIO.new
|
20
|
+
dict.write_to out
|
21
|
+
assert_equal("Same Value:\nDifferent Value:\n", out.string)
|
22
|
+
end
|
23
|
+
|
24
|
+
should "skip the empty string" do
|
25
|
+
dict = ReadyForI18N::NoKeyDictionary.new
|
26
|
+
dict.push 'Key 1','Some Value'
|
27
|
+
dict.push 'Key 2',' '
|
28
|
+
out = StringIO.new
|
29
|
+
dict.write_to out
|
30
|
+
assert_equal("Some Value\n", out.string)
|
31
|
+
end
|
32
|
+
|
33
|
+
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.
|
4
|
+
version: 0.3.0
|
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-30 00:00:00 +08:00
|
13
13
|
default_executable: ready_for_i18n
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -22,6 +22,16 @@ dependencies:
|
|
22
22
|
- !ruby/object:Gem::Version
|
23
23
|
version: "0"
|
24
24
|
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: ya2yaml
|
27
|
+
type: :runtime
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: "0.26"
|
34
|
+
version:
|
25
35
|
description: " ready_for_i18n will help you extract visible hard-coded text from your ERB view files,\n then choose a proper key and replace them with the I18n.translate method like t(:login)\n"
|
26
36
|
email: zigzag.chen@gmail.com
|
27
37
|
executables:
|
@@ -44,7 +54,9 @@ files:
|
|
44
54
|
- lib/html_attr_extractor.rb
|
45
55
|
- lib/html_text_extractor.rb
|
46
56
|
- lib/i18n_generator.rb
|
57
|
+
- lib/key_mapper.rb
|
47
58
|
- lib/locale_dictionary.rb
|
59
|
+
- lib/no_key_dictionary.rb
|
48
60
|
- lib/ready_for_i18n.rb
|
49
61
|
- ready_for_i18n.gemspec
|
50
62
|
- test/fixtures/html_attr.html.erb
|
@@ -52,12 +64,13 @@ files:
|
|
52
64
|
- test/helper.rb
|
53
65
|
- test/output/en.yml
|
54
66
|
- test/output/label.html.erb
|
55
|
-
- test/output/text.html.erb
|
56
67
|
- test/test_erb_helper_extractor.rb
|
57
68
|
- test/test_extractor_base.rb
|
58
69
|
- test/test_html_attr_extractor.rb
|
59
70
|
- test/test_html_text_extractor.rb
|
71
|
+
- test/test_key_mapper.rb
|
60
72
|
- test/test_locale_dictionary.rb
|
73
|
+
- test/test_nokey_dictionary.rb
|
61
74
|
has_rdoc: true
|
62
75
|
homepage: http://github.com/zigzag/ready_for_i18n
|
63
76
|
licenses: []
|
@@ -92,4 +105,6 @@ test_files:
|
|
92
105
|
- test/test_extractor_base.rb
|
93
106
|
- test/test_html_attr_extractor.rb
|
94
107
|
- test/test_html_text_extractor.rb
|
108
|
+
- test/test_key_mapper.rb
|
95
109
|
- test/test_locale_dictionary.rb
|
110
|
+
- test/test_nokey_dictionary.rb
|
data/test/output/text.html.erb
DELETED
@@ -1,89 +0,0 @@
|
|
1
|
-
<table width="100%">
|
2
|
-
<tr>
|
3
|
-
<td valign="top">
|
4
|
-
<h1><%=t(:text_users)%></h1>
|
5
|
-
<br/>
|
6
|
-
<table class="data sortable" id="users">
|
7
|
-
<thead>
|
8
|
-
<tr>
|
9
|
-
<th class="left"><%=t(:text_login)%></th>
|
10
|
-
<th class="left"><%=t(:text_name)%></th>
|
11
|
-
<th class="left nosort"><%=t(:text_groups)%></th>
|
12
|
-
<th class="left nosort" nowrap><%=t(:text_operations)%></th>
|
13
|
-
</tr>
|
14
|
-
</thead>
|
15
|
-
<tbody >
|
16
|
-
<% @users.each do |user|%>
|
17
|
-
<% clazz = cycle("even", "odd", :name => 'index_user') %>
|
18
|
-
<tr id="user-<%= u user.login -%>">
|
19
|
-
<td class="left" valign="top"><%=user.login %></td>
|
20
|
-
<td class="left" valign="top"><%=user.name %></td>
|
21
|
-
<td class="left" valign="top">
|
22
|
-
<%= user.groups.sort.map(&:name).join(', ') %> (<%= link_to "select", {:action => 'select_group', :id => user.id}, :id => "select-#{u user.login}" %>)
|
23
|
-
</td>
|
24
|
-
<td class="left" valign="top">
|
25
|
-
<%= link_to "edit", { :id => user.id, :action => 'edit'}, :id => "edit-#{u user.login}" %> |
|
26
|
-
<%= link_to "delete", {:action => 'destroy', :id => user.id}, {:confirm => "Warning : are you sure to delete this user ?", :method => 'delete', :id => "delete-#{u user.login}"} %>
|
27
|
-
</td>
|
28
|
-
</tr>
|
29
|
-
<% end %>
|
30
|
-
</tbody>
|
31
|
-
</table>
|
32
|
-
</td>
|
33
|
-
<td class="sep"> </td>
|
34
|
-
<td valign="top" align="right" width="210">
|
35
|
-
<%
|
36
|
-
action_name = 'create'
|
37
|
-
title='Add new user'
|
38
|
-
if @user.id
|
39
|
-
action_name = 'update'
|
40
|
-
title='Edit user'
|
41
|
-
end
|
42
|
-
%>
|
43
|
-
<% form_for :user, @user, :url => { :id => @user.id, :action => action_name}, :html => { :method => @user.id.nil?? :post : :put } do |f| %>
|
44
|
-
<table class="admintable" width="100%">
|
45
|
-
<tr>
|
46
|
-
<td class="left" valign="top"><h1><%= title %></h1></td>
|
47
|
-
</tr>
|
48
|
-
<tr>
|
49
|
-
<td class="left" valign="top"><%=t(:text_login)%>
|
50
|
-
<% if @user.id %>
|
51
|
-
<%= @user.login %>
|
52
|
-
<%= f.hidden_field :login %>
|
53
|
-
|
54
|
-
<% else %>
|
55
|
-
<br/><%= f.text_field :login, :size => 30, :maxLength => 40 %>
|
56
|
-
<% end %>
|
57
|
-
</td>
|
58
|
-
</tr>
|
59
|
-
<tr>
|
60
|
-
<td class="left" valign="top"><%=t(:text_name)%><br/><%= f.text_field :name, :size => 30, :maxLength => 200 %></td>
|
61
|
-
</tr>
|
62
|
-
<tr>
|
63
|
-
<td class="left" valign="top"><%=t(:text_password)%><br/><%= f.password_field :password, :size => 30, :maxLength => 50 %></td>
|
64
|
-
</tr>
|
65
|
-
<tr>
|
66
|
-
<td class="left" valign="top"><%=t(:text_confirm_password)%><br/><%= f.password_field :password_confirmation, :size => 30, :maxLength => 50 %></td>
|
67
|
-
</tr>
|
68
|
-
<tr>
|
69
|
-
<td class="left" nowrap="nowrap" valign="top" colspan="2">
|
70
|
-
<%= submit_tag @user.id.nil?? 'Create':'Update' %>
|
71
|
-
<%= link_to 'cancel', { :controller => 'users', :action => 'index'}, { :class => 'action' } %><br/>
|
72
|
-
</td>
|
73
|
-
</tr>
|
74
|
-
|
75
|
-
</table>
|
76
|
-
<% end %>
|
77
|
-
</td>
|
78
|
-
</tr>
|
79
|
-
</table>
|
80
|
-
|
81
|
-
<%= link_to "export",
|
82
|
-
url_for(:controller => 'api/rules', :action => 'index', :language => @profile.language, :profile => @profile.name,
|
83
|
-
:plugins => @plugins.join(','),
|
84
|
-
:status => @status, :searchtext => @searchtext, :priorities => @priorities.join(','), :categories => @categories.join(','),
|
85
|
-
:format => 'csv'),
|
86
|
-
:class => 'action' %> <%=t(:text_export)%>
|
87
|
-
|
88
|
-
<%= link_to_remote 'Add Event', {:url => { :controller => 'events', :action => "new", :rid => params['rid'] },
|
89
|
-
:update => "event_form"}, {:class => 'action'} %>
|