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.
@@ -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.2.8
1
+ 0.3.0
@@ -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
- puts "Invalid options. Run `ready_for_i18n --help` for assistance."
58
- exit(1)
72
+ error_parameter
59
73
  end
60
74
 
61
75
  # Run the i18n generating
@@ -2,13 +2,20 @@ require 'stringio'
2
2
 
3
3
  module ReadyForI18N
4
4
  module ExtractorBase
5
- VALUE_PATTERN = /\w+/
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
- result = to_value(s).scan(/\w+/).join('_').downcase
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.scan(VALUE_PATTERN).length > 0
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)})"
@@ -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*["']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]]
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
- attrs = line.match(p[0])[1] if line =~ p[0]
15
- if attrs =~ p[1]
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
@@ -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 = [/<%(.*?)%>/,/<(.*?)>/,/<(.*)$/,/^(.*)>/,/&nbsp;/]
4
+ SKIP_INLINE_TAG = [/<script>(.*?)<\/script>/i,/<%(.*?)%>/,/<(.*?)>/,/<(.*)$/,/^(.*)>/,/&nbsp;/]
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 true if s.nil? || s.strip.size == 0
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
- if @stack.last
18
+ unless @stack.empty?
19
19
  end_tag_match = s.match(@stack.last)
20
20
  if end_tag_match
21
21
  @stack.pop
@@ -4,27 +4,39 @@ module ReadyForI18N
4
4
  PATH_PATTERN = /\/views\/(.*)/
5
5
 
6
6
  def self.excute(opt)
7
- @src_path = opt['source']
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
@@ -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
@@ -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
- write_out_hash(out,@hash,1)
15
- end
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
@@ -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'
@@ -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"
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-25}
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/test_locale_dictionary.rb"
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/test_locale_dictionary.rb"
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
+
@@ -93,3 +93,7 @@
93
93
  <%= link_to_remote '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>
@@ -1,5 +1,7 @@
1
- en:
2
- label: "OK"
1
+ ---
2
+ en:
3
+ label: OK
3
4
  login_key: "Login:"
4
5
  text: "Please Confirm:"
5
6
  with_quote: "It is my \"Label\""
7
+ 中文: 没问题
@@ -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>
@@ -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 &raquo;'
6
+ expected = %w{Users Login Name Groups Operations Login: Name: Password: Export SkillName:} << 'Confirm password:' << 'select all &raquo;'
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
- assert_equal("en:\n label: \"OK\"\n", out.string)
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
- assert_equal("en:\n my_view:\n label: \"OK\"\n", out.string)
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.2.8
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-25 00:00:00 +08:00
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
@@ -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' %>&nbsp;&nbsp;<%=t(:text_export)%>
87
-
88
- <%= link_to_remote 'Add Event', {:url => { :controller => 'events', :action => "new", :rid => params['rid'] },
89
- :update => "event_form"}, {:class => 'action'} %>