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.
@@ -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'} %>