balinterdi-i15r 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +5 -0
- data/MIT-LICENSE +20 -0
- data/Manifest +12 -0
- data/README.markdown +32 -0
- data/Rakefile +14 -0
- data/bin/i15r +11 -0
- data/i15r.gemspec +33 -0
- data/init.rb +4 -0
- data/lib/i15r.rb +185 -0
- data/spec/i15r_spec.rb +196 -0
- data/tasks/i15r.rake +6 -0
- data/todos.markdown +35 -0
- metadata +73 -0
data/CHANGELOG
ADDED
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Balint Erdi (balint.erdi@gmail.com)
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Manifest
ADDED
data/README.markdown
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# I15r
|
2
|
+
|
3
|
+
I15r (Internationalizer) searches for all the non-i18n texts in the given files/directory and replaces them with I18n messages. The message string is based on the file in which the text was found and the text itself that was replaced. The script overwrites the file with the new content so to be on the safe side I advise to use a source code management (SCM) tool, like git.
|
4
|
+
|
5
|
+
E.g
|
6
|
+
|
7
|
+
(in file app/views/users/new.html.erb)
|
8
|
+
<label for="user-name">Name</label>
|
9
|
+
<input type="text" id="user-name" name="user[name]" />
|
10
|
+
|
11
|
+
will be replaced by:
|
12
|
+
|
13
|
+
(in file app/views/users/new.html.erb)
|
14
|
+
<label for="user-name"><%= I18n.t("users.new.name") %></label>
|
15
|
+
<input type="text" id="user-name" name="user[name]" />
|
16
|
+
|
17
|
+
and
|
18
|
+
|
19
|
+
(in file app/views/member/users/edit.html.erb)
|
20
|
+
<label for="user-name">Name</label>
|
21
|
+
<input type="text" id="user-name" name="user[name]" />
|
22
|
+
|
23
|
+
will be replaced by
|
24
|
+
|
25
|
+
(in file app/views/member/users/edit.html.erb)
|
26
|
+
<label for="user-name"><%= I18n.t("member.users.edit.name") %></label>
|
27
|
+
<input type="text" id="user-name" name="user[name]" />
|
28
|
+
|
29
|
+
|
30
|
+
## Licensing, contribution
|
31
|
+
|
32
|
+
The source code of this gem can be found at [http://github.com/balinterdi/i15r/](http://github.com/balinterdi/i15r/). It is released under the MIT-LICENSE, so you can basically do anything with it. However, if you think your modifications only make the tool better, and feel like it, please send a pull request or patch and I will probably merge in your changes. Any suggestions or feedback are welcome to <balint@bucionrails.com>.
|
data/Rakefile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'echoe'
|
4
|
+
|
5
|
+
Echoe.new('i15r', '0.2.1') do |p|
|
6
|
+
p.description = "The internationalizer. Replaces plain text strings in your views and replaces them with I18n message strings so you only have to provide the translations."
|
7
|
+
p.url = "http://github.com/balinterdi/i15r"
|
8
|
+
p.author = "Bálint Érdi"
|
9
|
+
p.email = "balint.erdi@gmail.com"
|
10
|
+
p.ignore_pattern = ["tmp/*", "script/*"]
|
11
|
+
p.development_dependencies = []
|
12
|
+
end
|
13
|
+
|
14
|
+
Dir["#{File.dirname(__FILE__)}/tasks/*.rake"].sort.each { |ext| load ext }
|
data/bin/i15r
ADDED
data/i15r.gemspec
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{i15r}
|
5
|
+
s.version = "0.2.1"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["B\303\241lint \303\211rdi"]
|
9
|
+
s.date = %q{2009-05-26}
|
10
|
+
s.default_executable = %q{i15r}
|
11
|
+
s.description = %q{The internationalizer. Replaces plain text strings in your views and replaces them with I18n message strings so you only have to provide the translations.}
|
12
|
+
s.email = %q{balint.erdi@gmail.com}
|
13
|
+
s.executables = ["i15r"]
|
14
|
+
s.extra_rdoc_files = ["bin/i15r", "CHANGELOG", "lib/i15r.rb", "README.markdown", "tasks/i15r.rake"]
|
15
|
+
s.files = ["bin/i15r", "CHANGELOG", "i15r.gemspec", "init.rb", "lib/i15r.rb", "Manifest", "MIT-LICENSE", "Rakefile", "README.markdown", "spec/i15r_spec.rb", "tasks/i15r.rake", "todos.markdown"]
|
16
|
+
s.has_rdoc = true
|
17
|
+
s.homepage = %q{http://github.com/balinterdi/i15r}
|
18
|
+
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "I15r", "--main", "README.markdown"]
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
s.rubyforge_project = %q{i15r}
|
21
|
+
s.rubygems_version = %q{1.3.1}
|
22
|
+
s.summary = %q{The internationalizer. Replaces plain text strings in your views and replaces them with I18n message strings so you only have to provide the translations.}
|
23
|
+
|
24
|
+
if s.respond_to? :specification_version then
|
25
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
26
|
+
s.specification_version = 2
|
27
|
+
|
28
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
29
|
+
else
|
30
|
+
end
|
31
|
+
else
|
32
|
+
end
|
33
|
+
end
|
data/init.rb
ADDED
data/lib/i15r.rb
ADDED
@@ -0,0 +1,185 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require 'optparse'
|
3
|
+
require "ostruct"
|
4
|
+
# require "ruby-debug"
|
5
|
+
|
6
|
+
class AppFolderNotFound < Exception; end
|
7
|
+
|
8
|
+
class I15r
|
9
|
+
|
10
|
+
def parse_options(args)
|
11
|
+
@options = OpenStruct.new
|
12
|
+
@options.prefix = nil
|
13
|
+
opts = OptionParser.new do |opts|
|
14
|
+
opts.banner = "Usage: ruby i15r.rb [options] <path_to_internationalize>"
|
15
|
+
opts.on("--prefix PREFIX",
|
16
|
+
"apply PREFIX to generated I18n messages instead of deriving it from the path") do |prefix|
|
17
|
+
@options.prefix = prefix
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
if args.length.zero?
|
22
|
+
puts opts.banner
|
23
|
+
exit
|
24
|
+
end
|
25
|
+
|
26
|
+
opts.on_tail("-h", "--help", "Show this message") do
|
27
|
+
puts opts
|
28
|
+
exit
|
29
|
+
end
|
30
|
+
|
31
|
+
opts.on_tail("--version", "Show version") do
|
32
|
+
puts "0.0.1"
|
33
|
+
exit
|
34
|
+
end
|
35
|
+
|
36
|
+
opts.parse!(args)
|
37
|
+
# @options
|
38
|
+
end
|
39
|
+
|
40
|
+
def prefix
|
41
|
+
@options.prefix
|
42
|
+
end
|
43
|
+
|
44
|
+
def file_path_to_message_prefix(file)
|
45
|
+
segments = File.expand_path(file).split('/').select { |segment| !segment.empty? }
|
46
|
+
subdir = %w(views helpers controllers models).find do |app_subdir|
|
47
|
+
segments.index(app_subdir)
|
48
|
+
end
|
49
|
+
if subdir.nil?
|
50
|
+
raise AppFolderNotFound, "No app. subfolders were found to determine prefix. Path is #{File.expand_path(file)}"
|
51
|
+
end
|
52
|
+
first_segment_index = segments.index(subdir) + 1
|
53
|
+
file_name_without_extensions = segments.last.split('.')[0..0]
|
54
|
+
path_segments = segments.slice(first_segment_index...-1)
|
55
|
+
(path_segments + file_name_without_extensions).join('.')
|
56
|
+
end
|
57
|
+
|
58
|
+
def get_i18n_message_string(text, prefix)
|
59
|
+
key = text.strip.downcase.gsub(/\s/, '_').gsub(/[\W]/, '')
|
60
|
+
indent = ""
|
61
|
+
(0..prefix.split(".").size).each { |i| indent = " " + indent }
|
62
|
+
silenced_if_testing do
|
63
|
+
puts "#{indent}#{key}: #{text}"
|
64
|
+
end
|
65
|
+
"#{prefix}.#{key}"
|
66
|
+
end
|
67
|
+
|
68
|
+
def get_content_from(file)
|
69
|
+
f = open(File.expand_path(file), "r")
|
70
|
+
content = f.read()
|
71
|
+
f.close()
|
72
|
+
content
|
73
|
+
end
|
74
|
+
|
75
|
+
def write_content_to(file, new_content)
|
76
|
+
f = open(File.expand_path(file), "w")
|
77
|
+
f.write(new_content)
|
78
|
+
f.close()
|
79
|
+
end
|
80
|
+
|
81
|
+
def write_i18ned_file(file)
|
82
|
+
text = get_content_from(file)
|
83
|
+
prefix = self.prefix || file_path_to_message_prefix(file)
|
84
|
+
i18ned_text = replace_non_i18_messages(text, prefix)
|
85
|
+
write_content_to(file, i18ned_text)
|
86
|
+
end
|
87
|
+
|
88
|
+
def replace_in_rails_helpers(text, prefix)
|
89
|
+
text.gsub!(/<%=\s*link_to\s+['"](.*?)['"]\s*/) do |match|
|
90
|
+
i18n_string = get_i18n_message_string($1, prefix)
|
91
|
+
%(<%= link_to I18n.t("#{i18n_string}"))
|
92
|
+
end
|
93
|
+
|
94
|
+
text.gsub!(/<%=(.*)\.label(.*),\s*['"](.*?)['"]/) do |match|
|
95
|
+
i18n_string = get_i18n_message_string($3, prefix)
|
96
|
+
%(<%= #{$1.strip}.label #{$2.strip}, I18n.t("#{i18n_string}"))
|
97
|
+
end
|
98
|
+
|
99
|
+
text.gsub!(/<%=\s*label_tag(.*),\s*['"](.*?)['"]/) do |match|
|
100
|
+
i18n_string = get_i18n_message_string($2, prefix)
|
101
|
+
%(<%= label_tag #{$1.strip}, I18n.t("#{i18n_string}"))
|
102
|
+
end
|
103
|
+
|
104
|
+
text.gsub!(/<%=(.*)\.submit\s*['"](.*?)['"]/) do |match|
|
105
|
+
i18n_string = get_i18n_message_string($2, prefix)
|
106
|
+
%(<%= #{$1.strip}.submit I18n.t("#{i18n_string}"))
|
107
|
+
end
|
108
|
+
|
109
|
+
text.gsub!(/<%=\s*submit_tag\s*['"](.*?)['"]/) do |match|
|
110
|
+
i18n_string = get_i18n_message_string($1, prefix)
|
111
|
+
%(<%= submit_tag I18n.t("#{i18n_string}"))
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
|
116
|
+
def replace_in_tag_content(text, prefix)
|
117
|
+
# TODO: include accented (non-iso-8859-1) word characters
|
118
|
+
# in the words (e.g á or é should be considered such)
|
119
|
+
text = text.gsub!(/>(\s*)(\w[\s\w:'"!?\.,]+)\s*</) do |match|
|
120
|
+
i18n_string = get_i18n_message_string($2, prefix)
|
121
|
+
# readding leading ws and ending punctuation (and ws)
|
122
|
+
# (there must be a way to put this into the regex,
|
123
|
+
# I just did not find it.)
|
124
|
+
leading_whitespace = $1
|
125
|
+
ending_punctuation = $2[/([?.!:\s]*)$/, 1]
|
126
|
+
%(>#{leading_whitespace}<%= I18n.t("#{i18n_string}") %>#{ending_punctuation.to_s}<)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def replace_in_tag_attributes(text, prefix)
|
131
|
+
text = text.gsub!(/(<a\s+.*title=)['"](.*?)['"]/) do |match|
|
132
|
+
i18n_string = get_i18n_message_string($2, prefix)
|
133
|
+
%(#{$1}"<%= I18n.t("#{i18n_string}") %>")
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def returning(value)
|
138
|
+
yield value
|
139
|
+
value
|
140
|
+
end
|
141
|
+
|
142
|
+
def replace_non_i18_messages(text, prefix)
|
143
|
+
#TODO: that's not very nice since it relies on
|
144
|
+
# the replace methods (e.g replace_in_tag_content)
|
145
|
+
# being destructive (banged)
|
146
|
+
|
147
|
+
silenced_if_testing do
|
148
|
+
puts "en:"
|
149
|
+
end
|
150
|
+
prefix_parts = prefix.split(".").each_with_index do |p, i|
|
151
|
+
p = "#{p}:"
|
152
|
+
(0..i).each { |i| p = " " + p }
|
153
|
+
silenced_if_testing do
|
154
|
+
puts "#{p}"
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
returning(text) do |text|
|
159
|
+
replace_in_tag_attributes(text, prefix)
|
160
|
+
replace_in_tag_content(text, prefix)
|
161
|
+
replace_in_rails_helpers(text, prefix)
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
def internationalize!(path)
|
166
|
+
files = path =~ /.erb$/ ? [path] : Dir.glob("#{path}/**/*.erb")
|
167
|
+
files.each { |file| write_i18ned_file(file) }
|
168
|
+
end
|
169
|
+
|
170
|
+
private
|
171
|
+
def silenced_if_testing
|
172
|
+
if testing?
|
173
|
+
orig_stdout = $stdout
|
174
|
+
$stdout = File.new('/dev/null', 'w')
|
175
|
+
end
|
176
|
+
yield
|
177
|
+
if testing?
|
178
|
+
$stdout = orig_stdout
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
def testing?
|
183
|
+
$testing
|
184
|
+
end
|
185
|
+
end
|
data/spec/i15r_spec.rb
ADDED
@@ -0,0 +1,196 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), "..", "lib", "i15r")
|
2
|
+
require "mocha"
|
3
|
+
require "spec"
|
4
|
+
|
5
|
+
# use mocha for mocking instead of
|
6
|
+
# Rspec's own mock framework
|
7
|
+
Spec::Runner.configure do |config|
|
8
|
+
config.mock_with :mocha
|
9
|
+
end
|
10
|
+
|
11
|
+
$testing = true
|
12
|
+
|
13
|
+
describe "i15r" do
|
14
|
+
|
15
|
+
before do
|
16
|
+
@i15r = I15r.new
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "converting file paths to message prefixes" do
|
20
|
+
|
21
|
+
it "should correctly work from app root for views" do
|
22
|
+
@i15r.file_path_to_message_prefix("app/views/users/new.html.erb").should == "users.new"
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should correctly work from app root for helpers" do
|
26
|
+
@i15r.file_path_to_message_prefix("app/helpers/users_helper.rb").should == "users_helper"
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should correctly work from app root for controllers" do
|
30
|
+
@i15r.file_path_to_message_prefix("app/controllers/users_controller.rb").should == "users_controller"
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should correctly work from app root for models" do
|
34
|
+
@i15r.file_path_to_message_prefix("app/models/user.rb").should == "user"
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should correctly work from app root for deep dir. structures" do
|
38
|
+
@i15r.file_path_to_message_prefix("app/views/member/session/users/new.html.erb").should == "member.session.users.new"
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should raise if no app subdirectory is found on the path" do
|
42
|
+
path = "projects/doodle.rb"
|
43
|
+
File.stubs(:expand_path).returns(path)
|
44
|
+
lambda { @i15r.file_path_to_message_prefix(path) }.should raise_error(AppFolderNotFound)
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
describe "turning plain messages into i18n message strings" do
|
50
|
+
|
51
|
+
it "should downcase a single word" do
|
52
|
+
@i15r.get_i18n_message_string("Name", "users.new").should == "users.new.name"
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should replace spaces with underscores" do
|
56
|
+
@i15r.get_i18n_message_string("New name", "users.index").should == "users.index.new_name"
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
describe "message text replacement" do
|
62
|
+
describe "tag contents" do
|
63
|
+
it "should replace a single word" do
|
64
|
+
plain = %(<label for="user-name">Name</label>)
|
65
|
+
i18ned = %(<label for="user-name"><%= I18n.t("users.new.name") %></label>)
|
66
|
+
@i15r.replace_non_i18_messages(plain, "users.new").should == i18ned
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should replace several words" do
|
70
|
+
plain = %(<label for="user-name">Earlier names</label>)
|
71
|
+
i18ned = %(<label for="user-name"><%= I18n.t("users.new.earlier_names") %></label>)
|
72
|
+
@i15r.replace_non_i18_messages(plain, "users.new").should == i18ned
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should remove punctuation from plain strings" do
|
76
|
+
plain = %(<label for="user-name">Got friends? A friend's name</label>)
|
77
|
+
i18ned = %(<label for="user-name"><%= I18n.t("users.new.got_friends_a_friends_name") %></label>)
|
78
|
+
@i15r.replace_non_i18_messages(plain, "users.new").should == i18ned
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should not remove punctuation outside plain strings" do
|
82
|
+
plain = %(<label for="user-name">A friend's name:</label>)
|
83
|
+
i18ned = %(<label for="user-name"><%= I18n.t("users.new.a_friends_name") %>:</label>)
|
84
|
+
@i15r.replace_non_i18_messages(plain, "users.new").should == i18ned
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should preserve whitespace in the content part of the tag" do
|
88
|
+
plain = %(<label for="user-name"> Name </label>)
|
89
|
+
i18ned = %(<label for="user-name"> <%= I18n.t("users.new.name") %> </label>)
|
90
|
+
@i15r.replace_non_i18_messages(plain, "users.new").should == i18ned
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
|
95
|
+
describe "tag attributes" do
|
96
|
+
it "should replace a link's title" do
|
97
|
+
plain = %(<a title="site root" href="/"><img src="site_logo.png" /></a>)
|
98
|
+
i18ned = %(<a title="<%= I18n.t("users.new.site_root") %>" href="/"><img src="site_logo.png" /></a>)
|
99
|
+
@i15r.replace_non_i18_messages(plain, "users.new").should == i18ned
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
describe "rails helper params" do
|
104
|
+
it "should replace a title in a link_to helper" do
|
105
|
+
plain = %(<p class="highlighted"><%= link_to 'New user', new_user_path %></p>)
|
106
|
+
i18ned = %(<p class="highlighted"><%= link_to I18n.t("users.index.new_user"), new_user_path %></p>)
|
107
|
+
@i15r.replace_non_i18_messages(plain, "users.index").should == i18ned
|
108
|
+
end
|
109
|
+
|
110
|
+
it "should replace a title in a link_to helper with html attributes" do
|
111
|
+
plain = %(<p><%= link_to "Create a new user", new_user_path, { :class => "add" } -%></p>)
|
112
|
+
i18ned = %(<p><%= link_to I18n.t("users.index.create_a_new_user"), new_user_path, { :class => "add" } -%></p>)
|
113
|
+
@i15r.replace_non_i18_messages(plain, "users.index").should == i18ned
|
114
|
+
end
|
115
|
+
|
116
|
+
it "should replace the title of a label helper in a form builder" do
|
117
|
+
plain = %(<%= f.label :name, "Name" %>)
|
118
|
+
i18ned = %(<%= f.label :name, I18n.t("users.new.name") %>)
|
119
|
+
@i15r.replace_non_i18_messages(plain, "users.new").should == i18ned
|
120
|
+
end
|
121
|
+
|
122
|
+
it "should replace the title of a label_tag helper" do
|
123
|
+
plain = %(<%= label_tag :name, "Name" %>)
|
124
|
+
i18ned = %(<%= label_tag :name, I18n.t("users.new.name") %>)
|
125
|
+
@i15r.replace_non_i18_messages(plain, "users.new").should == i18ned
|
126
|
+
end
|
127
|
+
|
128
|
+
it "should replace the title of a submit helper in a form builder" do
|
129
|
+
plain = %(<%= f.submit "Create user" %>)
|
130
|
+
i18ned = %(<%= f.submit I18n.t("users.new.create_user") %>)
|
131
|
+
@i15r.replace_non_i18_messages(plain, "users.new").should == i18ned
|
132
|
+
end
|
133
|
+
|
134
|
+
it "should replace the title of a submit_tag helper" do
|
135
|
+
plain = %(<%= submit_tag "Create user" %>)
|
136
|
+
i18ned = %(<%= submit_tag I18n.t("users.new.create_user") %>)
|
137
|
+
@i15r.replace_non_i18_messages(plain, "users.new").should == i18ned
|
138
|
+
end
|
139
|
+
|
140
|
+
end
|
141
|
+
|
142
|
+
end # "message text replacement"
|
143
|
+
|
144
|
+
describe "rewriting files" do
|
145
|
+
describe "when no prefix option was given" do
|
146
|
+
before do
|
147
|
+
@i15r.stubs(:prefix).returns(nil)
|
148
|
+
@file_path = '/app/views/users/new.html.erb'
|
149
|
+
message_prefix = "users.new"
|
150
|
+
@i15r.expects(:file_path_to_message_prefix).with(@file_path).returns(message_prefix)
|
151
|
+
|
152
|
+
@plain_snippet = <<-EOS
|
153
|
+
<label for="user-name">Name</label>
|
154
|
+
<input type="text" id="user-name" name="user[name]" />
|
155
|
+
EOS
|
156
|
+
@i18ned_snippet = <<-EOS
|
157
|
+
<label for="user-name"><%= I18n.t("#{message_prefix}.name") %></label>
|
158
|
+
<input type="text" id="user-name" name="user[name]" />
|
159
|
+
EOS
|
160
|
+
|
161
|
+
@i15r.expects(:get_content_from).with(@file_path).returns(@plain_snippet)
|
162
|
+
@i15r.expects(:write_content_to).with(@file_path, @i18ned_snippet).returns(true)
|
163
|
+
end
|
164
|
+
|
165
|
+
it "should correctly replace plain texts with I18n-ed messages" do
|
166
|
+
# @i15r.replace_non_i18_messages(@plain_snippet).should == @i18ned_snippet
|
167
|
+
@i15r.write_i18ned_file(@file_path)
|
168
|
+
end
|
169
|
+
end # "when no prefix option was given"
|
170
|
+
|
171
|
+
describe "when an explicit prefix option was given" do
|
172
|
+
|
173
|
+
it "should ignore the file path and use the prefix" do
|
174
|
+
@file_path = "app/views/users/new.html.erb"
|
175
|
+
prefix_option = "mysite"
|
176
|
+
@i15r.stubs(:prefix).returns(prefix_option)
|
177
|
+
|
178
|
+
@plain_snippet = <<-EOS
|
179
|
+
<label for="user-name">Name</label>
|
180
|
+
<input type="text" id="user-name" name="user[name]" />
|
181
|
+
EOS
|
182
|
+
@i18ned_snippet = <<-EOS
|
183
|
+
<label for="user-name"><%= I18n.t("#{prefix_option}.name") %></label>
|
184
|
+
<input type="text" id="user-name" name="user[name]" />
|
185
|
+
EOS
|
186
|
+
|
187
|
+
@i15r.expects(:get_content_from).with(@file_path).returns(@plain_snippet)
|
188
|
+
@i15r.expects(:write_content_to).with(@file_path, @i18ned_snippet).returns(true)
|
189
|
+
@i15r.write_i18ned_file(@file_path)
|
190
|
+
end
|
191
|
+
|
192
|
+
end # "when an explicit prefix option was given"
|
193
|
+
|
194
|
+
end # rewriting files
|
195
|
+
|
196
|
+
end
|
data/tasks/i15r.rake
ADDED
data/todos.markdown
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
### 0.1
|
2
|
+
|
3
|
+
* DONE bug: In messages ending in punctuation (e.g No tags.) the punctuation is removed when replaced (e.g <%= I18n.t("users.show.no_tags") %>)
|
4
|
+
|
5
|
+
### 0.1.1
|
6
|
+
|
7
|
+
* DONE bug: indenting whitespace is removed around replaced messages
|
8
|
+
This is easy to fix, the whitespace has to be readded just like the punctuation
|
9
|
+
|
10
|
+
<% tags = @photo.tag_list %>
|
11
|
+
Tags:
|
12
|
+
<% if !tags.blank? %>
|
13
|
+
|
14
|
+
becomes
|
15
|
+
|
16
|
+
<% tags = @photo.tag_list %><%= I18n.t("mysite.tags") %><% if !tags.blank? %>
|
17
|
+
|
18
|
+
### 0.2
|
19
|
+
|
20
|
+
* DONE title of links have to be internationailzed, e.g: <a title="Go back" href="...">
|
21
|
+
* DONE <%= f.label :body, "Question" %>
|
22
|
+
* DONE <%= label_tag :body, "Question" %>
|
23
|
+
* DONE <%= f.submit "Submit question" %>
|
24
|
+
* DONE <%= submit_tag "Submit question" %>
|
25
|
+
* DONE think about which rails helpers could be given text that needs to be internationalized (currently only link_to is scanned)
|
26
|
+
* DONE suppress printing of yaml strings (change by Alberto) when running the specs
|
27
|
+
* DONE make it possible to run i15r on several files
|
28
|
+
|
29
|
+
### 0.?
|
30
|
+
|
31
|
+
* make prefix not replace the inferred message string prefix, but really act as a prefix. (e.g if anetcom is given as a prefix, and the inferred message string is 'users.new' it should not be 'anetcom.name', but 'anetcom.users.new.name')
|
32
|
+
* handle non-ascii characters properly (UTF-8 support) when replacing them. Mañana should become I18n.t("prefix.manana"), for instance. That is, regular expressions should be utf-8 aware.
|
33
|
+
* write the necessary i18n strings back into the yaml file
|
34
|
+
* make interactive mode possible. the user is asked about each message to be replaced. he can choose to replace it, skip it or even edit it. Ideally the message would be shown in its context.
|
35
|
+
* list the files that are about to be changed and ask for confirmation to go ahead
|
metadata
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: balinterdi-i15r
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- "B\xC3\xA1lint \xC3\x89rdi"
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-05-26 00:00:00 -07:00
|
13
|
+
default_executable: i15r
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: The internationalizer. Replaces plain text strings in your views and replaces them with I18n message strings so you only have to provide the translations.
|
17
|
+
email: balint.erdi@gmail.com
|
18
|
+
executables:
|
19
|
+
- i15r
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- bin/i15r
|
24
|
+
- CHANGELOG
|
25
|
+
- lib/i15r.rb
|
26
|
+
- README.markdown
|
27
|
+
- tasks/i15r.rake
|
28
|
+
files:
|
29
|
+
- bin/i15r
|
30
|
+
- CHANGELOG
|
31
|
+
- i15r.gemspec
|
32
|
+
- init.rb
|
33
|
+
- lib/i15r.rb
|
34
|
+
- Manifest
|
35
|
+
- MIT-LICENSE
|
36
|
+
- Rakefile
|
37
|
+
- README.markdown
|
38
|
+
- spec/i15r_spec.rb
|
39
|
+
- tasks/i15r.rake
|
40
|
+
- todos.markdown
|
41
|
+
has_rdoc: true
|
42
|
+
homepage: http://github.com/balinterdi/i15r
|
43
|
+
post_install_message:
|
44
|
+
rdoc_options:
|
45
|
+
- --line-numbers
|
46
|
+
- --inline-source
|
47
|
+
- --title
|
48
|
+
- I15r
|
49
|
+
- --main
|
50
|
+
- README.markdown
|
51
|
+
require_paths:
|
52
|
+
- lib
|
53
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: "0"
|
58
|
+
version:
|
59
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - ">="
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: "1.2"
|
64
|
+
version:
|
65
|
+
requirements: []
|
66
|
+
|
67
|
+
rubyforge_project: i15r
|
68
|
+
rubygems_version: 1.2.0
|
69
|
+
signing_key:
|
70
|
+
specification_version: 2
|
71
|
+
summary: The internationalizer. Replaces plain text strings in your views and replaces them with I18n message strings so you only have to provide the translations.
|
72
|
+
test_files: []
|
73
|
+
|