ready_for_i18n 0.2.8 → 0.3.0
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.
- 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'} %>
|