idiom 0.0.1
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/.document +5 -0
- data/.gitignore +25 -0
- data/Gemfile +6 -0
- data/LICENSE +20 -0
- data/README.rdoc +17 -0
- data/Rakefile +55 -0
- data/VERSION +1 -0
- data/lib/idiom.rb +343 -0
- data/spec/idiom_spec.rb +203 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +11 -0
- data/spec/stubs.rb +98 -0
- metadata +108 -0
data/.document
ADDED
data/.gitignore
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
## MAC OS
|
2
|
+
.DS_Store
|
3
|
+
|
4
|
+
## TEXTMATE
|
5
|
+
*.tmproj
|
6
|
+
tmtags
|
7
|
+
|
8
|
+
## EMACS
|
9
|
+
*~
|
10
|
+
\#*
|
11
|
+
.\#*
|
12
|
+
|
13
|
+
## VIM
|
14
|
+
*.swp
|
15
|
+
|
16
|
+
## PROJECT::GENERAL
|
17
|
+
coverage
|
18
|
+
rdoc
|
19
|
+
pkg
|
20
|
+
|
21
|
+
## PROJECT::SPECIFIC
|
22
|
+
|
23
|
+
vendor/bin/*
|
24
|
+
vendor/gems/*
|
25
|
+
!vendor/gems/cache/
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Jeff Coleman
|
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/README.rdoc
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
= idiom
|
2
|
+
|
3
|
+
Description goes here.
|
4
|
+
|
5
|
+
== Note on Patches/Pull Requests
|
6
|
+
|
7
|
+
* Fork the project.
|
8
|
+
* Make your feature addition or bug fix.
|
9
|
+
* Add tests for it. This is important so I don't break it in a
|
10
|
+
future version unintentionally.
|
11
|
+
* Commit, do not mess with rakefile, version, or history.
|
12
|
+
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
13
|
+
* Send me a pull request. Bonus points for topic branches.
|
14
|
+
|
15
|
+
== Copyright
|
16
|
+
|
17
|
+
Copyright (c) 2010 Jeff Coleman. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "idiom"
|
8
|
+
gem.summary = %Q{Translate strings in Google Translate}
|
9
|
+
gem.description = %Q{Takes a set of keys in Yaml format and translates them through Google Translate.}
|
10
|
+
gem.email = "progressions@gmail.com"
|
11
|
+
gem.homepage = "http://github.com/progressions/idiom"
|
12
|
+
gem.authors = ["Jeff Coleman"]
|
13
|
+
gem.add_development_dependency "rspec", ">= 1.2.9"
|
14
|
+
gem.add_runtime_dependency "activesupport", ">= 2.2.2"
|
15
|
+
gem.add_runtime_dependency "sishen-rtranslate", ">= 1.2.9"
|
16
|
+
gem.add_runtime_dependency "yrb", ">= 0"
|
17
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
18
|
+
end
|
19
|
+
Jeweler::GemcutterTasks.new
|
20
|
+
rescue LoadError
|
21
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
22
|
+
end
|
23
|
+
|
24
|
+
require 'spec/rake/spectask'
|
25
|
+
Spec::Rake::SpecTask.new(:spec) do |spec|
|
26
|
+
spec.libs << 'lib' << 'spec'
|
27
|
+
spec.spec_files = FileList['spec/**/*_spec.rb']
|
28
|
+
spec.spec_opts = ['-c']
|
29
|
+
end
|
30
|
+
|
31
|
+
Spec::Rake::SpecTask.new(:rcov) do |spec|
|
32
|
+
spec.libs << 'lib' << 'spec'
|
33
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
34
|
+
spec.rcov_opts = ['--exclude', '.gem,Library,spec', '--sort', 'coverage']
|
35
|
+
spec.rcov = true
|
36
|
+
end
|
37
|
+
|
38
|
+
task :bundle do
|
39
|
+
require 'vendor/gems/environment'
|
40
|
+
Bundler.require_env
|
41
|
+
end
|
42
|
+
|
43
|
+
task :spec => [:bundle, :check_dependencies]
|
44
|
+
|
45
|
+
task :default => :spec
|
46
|
+
|
47
|
+
require 'rake/rdoctask'
|
48
|
+
Rake::RDocTask.new do |rdoc|
|
49
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
50
|
+
|
51
|
+
rdoc.rdoc_dir = 'rdoc'
|
52
|
+
rdoc.title = "translator #{version}"
|
53
|
+
rdoc.rdoc_files.include('README*')
|
54
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
55
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.1
|
data/lib/idiom.rb
ADDED
@@ -0,0 +1,343 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rtranslate'
|
3
|
+
require 'timer'
|
4
|
+
require 'yrb'
|
5
|
+
require 'yaml'
|
6
|
+
|
7
|
+
module Idiom #:nodoc:
|
8
|
+
# Finds English language translation keys which have not been translated
|
9
|
+
# and translates them through Google Translate.
|
10
|
+
#
|
11
|
+
class Base
|
12
|
+
# Mapping of the way I18n country codes with the Google Translate codes.
|
13
|
+
#
|
14
|
+
# The key is the I18n representation, and the value is the code Google Translate would expect.
|
15
|
+
#
|
16
|
+
LOCALES = {
|
17
|
+
"de-DE" => "de",
|
18
|
+
"en-MY" => "en",
|
19
|
+
"en-SG" => "en",
|
20
|
+
"es-MX" => "es",
|
21
|
+
"it-IT" => "it",
|
22
|
+
"vi-VN" => "vi",
|
23
|
+
"zh-Hant-TW" => "zh-TW",
|
24
|
+
"en-AA" => "en",
|
25
|
+
"en-NZ" => "en",
|
26
|
+
"en-US" => "en",
|
27
|
+
"fr-FR" => "fr",
|
28
|
+
"ko-KR" => "ko",
|
29
|
+
"zh-Hans-CN" => "zh-CN",
|
30
|
+
"en-AU" => "en",
|
31
|
+
"en-PH" => "en",
|
32
|
+
"es-ES" => "es",
|
33
|
+
"id-ID" => "id",
|
34
|
+
"pt-BR" => "PORTUGUESE",
|
35
|
+
"zh-Hant-HK" => "zh-CN",
|
36
|
+
}
|
37
|
+
|
38
|
+
# Original filename to translate.
|
39
|
+
#
|
40
|
+
attr_accessor :source
|
41
|
+
|
42
|
+
# Destination directory to output the translated files to.
|
43
|
+
#
|
44
|
+
attr_accessor :destination
|
45
|
+
|
46
|
+
# Write the translated strings into a directory for each language?
|
47
|
+
#
|
48
|
+
attr_accessor :use_dirs
|
49
|
+
|
50
|
+
# Array of languages to translate into.
|
51
|
+
#
|
52
|
+
attr_accessor :languages
|
53
|
+
|
54
|
+
class << self
|
55
|
+
|
56
|
+
def translate(options={})
|
57
|
+
@source = options[:source]
|
58
|
+
@destination = options[:destination]
|
59
|
+
@use_dirs = options[:use_dirs]
|
60
|
+
Timer.new.time do
|
61
|
+
@source.to_a.each do |path|
|
62
|
+
$stdout.puts "Processing #{path}"
|
63
|
+
if path =~ /\.yml$/i
|
64
|
+
Idiom::Yaml.new({:source => path}.merge(options)).generate
|
65
|
+
end
|
66
|
+
if path =~ /\.pres$/i
|
67
|
+
Idiom::Yrb.new({:source => path}.merge(options)).generate
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
def initialize(options={})
|
76
|
+
@source = options[:source]
|
77
|
+
@overwrite = options[:overwrite]
|
78
|
+
@languages = options[:languages]
|
79
|
+
|
80
|
+
# base directory of the source file
|
81
|
+
#
|
82
|
+
source_dir = File.dirname(@source)
|
83
|
+
|
84
|
+
# if they specify the :use_dirs option, use that
|
85
|
+
# if not, detect whether the source path uses directories for each language
|
86
|
+
#
|
87
|
+
if options.has_key?(:use_dirs)
|
88
|
+
@use_dirs = options[:use_dirs]
|
89
|
+
else
|
90
|
+
@use_dirs = source_dir =~ /\/en-US$/
|
91
|
+
end
|
92
|
+
|
93
|
+
if @use_dirs
|
94
|
+
source_dir = File.dirname(@source).gsub(/\/en-US$/, "")
|
95
|
+
end
|
96
|
+
@destination = options[:destination] || source_dir
|
97
|
+
end
|
98
|
+
|
99
|
+
def generate
|
100
|
+
copy_lines_to_all_locales
|
101
|
+
end
|
102
|
+
|
103
|
+
def locales
|
104
|
+
@languages || LOCALES.keys
|
105
|
+
end
|
106
|
+
|
107
|
+
def use_directories?
|
108
|
+
use_dirs
|
109
|
+
end
|
110
|
+
|
111
|
+
def destination_path(lang)
|
112
|
+
output_path = File.basename(source).split(".").first
|
113
|
+
if use_directories?
|
114
|
+
"#{destination}/#{lang}/#{output_path}_#{lang}.#{extension}"
|
115
|
+
else
|
116
|
+
"#{destination}/#{output_path}_#{lang}.#{extension}"
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def non_us_locales
|
121
|
+
@non_us_locales ||= locales.select do |lang|
|
122
|
+
lang != "en-US"
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
def copy_lines_to_all_locales
|
127
|
+
non_us_locales.each do |lang|
|
128
|
+
code = LOCALES[lang]
|
129
|
+
destination = ensure_destination_path_exists(lang)
|
130
|
+
new_content = each_line do |line|
|
131
|
+
copy_and_translate_line(line, lang)
|
132
|
+
end
|
133
|
+
write_content(destination, new_content)
|
134
|
+
clear_all_keys
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
def ensure_destination_path_exists(lang)
|
139
|
+
dest = destination_path(lang)
|
140
|
+
dir = File.dirname(dest)
|
141
|
+
FileUtils.mkdir_p(dir)
|
142
|
+
|
143
|
+
dest
|
144
|
+
end
|
145
|
+
|
146
|
+
def write_content(destination, content)
|
147
|
+
unless content.blank?
|
148
|
+
$stdout.puts "Writing to #{destination}"
|
149
|
+
$stdout.puts content
|
150
|
+
$stdout.puts
|
151
|
+
File.open(destination, "a") do |f|
|
152
|
+
f.puts
|
153
|
+
f.puts new_translation_message
|
154
|
+
f.puts content
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
def new_translation_message
|
160
|
+
now = Time.now
|
161
|
+
|
162
|
+
date = now.day
|
163
|
+
month = now.month
|
164
|
+
year = now.year
|
165
|
+
|
166
|
+
timestamp = "#{month}/#{date}/#{year}"
|
167
|
+
output = []
|
168
|
+
output << "# "
|
169
|
+
output << "# Keys translated automatically on #{timestamp}."
|
170
|
+
output << "# "
|
171
|
+
|
172
|
+
output.join("\n")
|
173
|
+
end
|
174
|
+
|
175
|
+
def each_line
|
176
|
+
output = []
|
177
|
+
@lines ||= File.readlines(source)
|
178
|
+
|
179
|
+
@lines.each do |line|
|
180
|
+
new_line = yield line
|
181
|
+
output << new_line unless line.blank?
|
182
|
+
end
|
183
|
+
output.flatten.join("\n")
|
184
|
+
end
|
185
|
+
|
186
|
+
def parse(p)
|
187
|
+
raise "Define in child"
|
188
|
+
end
|
189
|
+
|
190
|
+
def all_keys(lang)
|
191
|
+
@all_keys ||= parse(destination_path(lang))
|
192
|
+
end
|
193
|
+
|
194
|
+
def clear_all_keys
|
195
|
+
@all_keys = nil
|
196
|
+
end
|
197
|
+
|
198
|
+
def copy_and_translate_line(line, lang)
|
199
|
+
line = line.split("\n").first
|
200
|
+
if comment?(line) || line.blank?
|
201
|
+
nil
|
202
|
+
else
|
203
|
+
translate_new_key(line, lang)
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
def key_is_new?(k, lang)
|
208
|
+
k && !all_keys(lang).has_key?(k)
|
209
|
+
end
|
210
|
+
|
211
|
+
def translate_new_key(line, lang)
|
212
|
+
k, v = key_and_value_from_line(line)
|
213
|
+
if @overwrite || key_is_new?(k, lang)
|
214
|
+
format(k, translate(v, lang))
|
215
|
+
else
|
216
|
+
nil
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
def translate(value, lang)
|
221
|
+
code = LOCALES[lang]
|
222
|
+
value = pre_process(value, lang)
|
223
|
+
translation = Translate.t(value, "ENGLISH", code)
|
224
|
+
post_process(translation, lang)
|
225
|
+
end
|
226
|
+
|
227
|
+
def pre_process(value, lang)
|
228
|
+
vars = []
|
229
|
+
index = 0
|
230
|
+
while value =~ /(\{\d+\})/
|
231
|
+
vars << $1
|
232
|
+
value.sub!(/(\{\d+\})/, "[#{index}]")
|
233
|
+
index += 1
|
234
|
+
end
|
235
|
+
|
236
|
+
if lang !~ /^en/ && value != value.downcase
|
237
|
+
value = value.capitalize
|
238
|
+
end
|
239
|
+
|
240
|
+
value
|
241
|
+
end
|
242
|
+
|
243
|
+
def post_process(value, lang)
|
244
|
+
if lang =~ /zh/
|
245
|
+
value.gsub!("<strong>", "")
|
246
|
+
value.gsub!("</strong>", "")
|
247
|
+
end
|
248
|
+
|
249
|
+
value.gsub!(/^#{194.chr}#{160.chr}/, "")
|
250
|
+
|
251
|
+
value.gsub!(" ]", "]")
|
252
|
+
value.gsub!("«", "\"")
|
253
|
+
value.gsub!("»", "\"")
|
254
|
+
value.gsub!(/\"\.$/, ".\"")
|
255
|
+
value.gsub!(/\\ \"/, "\\\"")
|
256
|
+
value.gsub!(/<\/ /, "<\/")
|
257
|
+
value.gsub!(/(“|”)/, "\"")
|
258
|
+
value.gsub!("<strong> ", "<strong>")
|
259
|
+
value.gsub!(" </strong>", "</strong>")
|
260
|
+
value.gsub!(""", "\"")
|
261
|
+
value.gsub!("'", "\"")
|
262
|
+
value.gsub!("> ", ">")
|
263
|
+
|
264
|
+
value.gsub!("\"", "'")
|
265
|
+
value.gsub!(" \"O", " \\\"O")
|
266
|
+
|
267
|
+
while value =~ /\[(\d)\]/
|
268
|
+
index = $1.to_i
|
269
|
+
value.sub!(/\[#{index}\]/, "{#{index}}")
|
270
|
+
end
|
271
|
+
|
272
|
+
value.gsub!(/\((0)\)/, "{0}")
|
273
|
+
value.gsub!(/\((1)\)/, "{1}")
|
274
|
+
value.gsub!(/\((2)\)/, "{2}")
|
275
|
+
value.gsub!("(0)", "{0}")
|
276
|
+
|
277
|
+
value.strip
|
278
|
+
end
|
279
|
+
|
280
|
+
def format(key, value)
|
281
|
+
raise "Define in child"
|
282
|
+
end
|
283
|
+
|
284
|
+
def key_and_value_from_line(line)
|
285
|
+
raise "Define in child"
|
286
|
+
end
|
287
|
+
|
288
|
+
def comment?(line)
|
289
|
+
line =~ /^[\s]*#/
|
290
|
+
end
|
291
|
+
end
|
292
|
+
|
293
|
+
# Usage:
|
294
|
+
# Translator::Yaml.new().copy
|
295
|
+
#
|
296
|
+
class Yaml < Base
|
297
|
+
def extension
|
298
|
+
"yml"
|
299
|
+
end
|
300
|
+
|
301
|
+
def parse(path)
|
302
|
+
YAML.load_file(path)
|
303
|
+
end
|
304
|
+
|
305
|
+
def format(key, value)
|
306
|
+
"#{key}: #{value}"
|
307
|
+
end
|
308
|
+
|
309
|
+
def key_and_value_from_line(line)
|
310
|
+
if line =~ /^([^\:]+):(.*)/
|
311
|
+
return $1, $2.strip
|
312
|
+
else
|
313
|
+
return nil, nil
|
314
|
+
end
|
315
|
+
end
|
316
|
+
end
|
317
|
+
|
318
|
+
# Usage:
|
319
|
+
# Translator::Yrb.new(:source => "./translations/en-US.pres", :destination => "./translations",
|
320
|
+
# :use_dirs => false).translate
|
321
|
+
#
|
322
|
+
class Yrb < Base
|
323
|
+
def extension
|
324
|
+
"pres"
|
325
|
+
end
|
326
|
+
|
327
|
+
def parse(p)
|
328
|
+
YRB.load_file(p)
|
329
|
+
end
|
330
|
+
|
331
|
+
def format(key, value)
|
332
|
+
"#{key}=#{value}"
|
333
|
+
end
|
334
|
+
|
335
|
+
def key_and_value_from_line(line)
|
336
|
+
if line =~ /^([^\=]+)=(.+)/
|
337
|
+
return $1, $2
|
338
|
+
else
|
339
|
+
return nil, nil
|
340
|
+
end
|
341
|
+
end
|
342
|
+
end
|
343
|
+
end
|
data/spec/idiom_spec.rb
ADDED
@@ -0,0 +1,203 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe "Idiom" do
|
4
|
+
before(:each) do
|
5
|
+
stub_timer
|
6
|
+
stub_yrb
|
7
|
+
stub_yaml
|
8
|
+
stub_screen_io
|
9
|
+
stub_file_io
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "base" do
|
13
|
+
before(:each) do
|
14
|
+
@translator = mock('translator', :generate => true)
|
15
|
+
Idiom::Yrb.stub!(:new).and_return(@translator)
|
16
|
+
Idiom::Yaml.stub!(:new).and_return(@translator)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should create an Idiom for each Yaml file" do
|
20
|
+
Idiom::Yaml.should_receive(:new).and_return(@translator)
|
21
|
+
Idiom::Base.translate(:source => "path.yml")
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should create an Idiom for each YRB file" do
|
25
|
+
Idiom::Yrb.should_receive(:new).and_return(@translator)
|
26
|
+
Idiom::Base.translate(:source => "path.pres")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "yrb" do
|
31
|
+
before(:each) do
|
32
|
+
@yrb_file = <<-YRB
|
33
|
+
FIRST=first key
|
34
|
+
SECOND=second key
|
35
|
+
YRB
|
36
|
+
File.stub!(:readlines).and_return(@yrb_file)
|
37
|
+
Translate.stub!(:t).with("first key", "ENGLISH", anything).and_return("translated first key")
|
38
|
+
Translate.stub!(:t).with("second key", "ENGLISH", anything).and_return("translated second key")
|
39
|
+
@source = "./translations/path.pres"
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should create the destination path if it does not exist" do
|
43
|
+
Idiom::Yrb::LOCALES.each do |lang, code|
|
44
|
+
FileUtils.should_receive(:mkdir_p).with("./translations") unless lang == "en-US"
|
45
|
+
end
|
46
|
+
Idiom::Yrb.new(:source => @source).generate
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should write to the destination path" do
|
50
|
+
Idiom::Yrb::LOCALES.each do |lang, code|
|
51
|
+
File.should_receive(:open).with("./translations/path_#{lang}.pres", "a") unless lang == "en-US"
|
52
|
+
end
|
53
|
+
Idiom::Yrb.new(:source => @source).generate
|
54
|
+
end
|
55
|
+
|
56
|
+
describe "directories" do
|
57
|
+
before(:each) do
|
58
|
+
@source = "./translations/en-US/path.pres"
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should write to directories" do
|
62
|
+
Idiom::Yrb::LOCALES.each do |lang, code|
|
63
|
+
File.should_receive(:open).with("./translations/#{lang}/path_#{lang}.pres", "a") unless lang == "en-US"
|
64
|
+
end
|
65
|
+
Idiom::Yrb.new(:source => @source, :use_dirs => true).generate
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should create the destination path with directories if it does not exist" do
|
69
|
+
Idiom::Yrb::LOCALES.each do |lang, code|
|
70
|
+
FileUtils.should_receive(:mkdir_p).with("./translations/#{lang}") unless lang == "en-US"
|
71
|
+
end
|
72
|
+
Idiom::Yrb.new(:source => @source, :use_dirs => true).generate
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should translate the first string" do
|
77
|
+
@file.should_receive(:puts).with(/FIRST=translated first key/)
|
78
|
+
Idiom::Yrb.new(:source => @source).generate
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should translate the second string" do
|
82
|
+
@file.should_receive(:puts).with(/SECOND=translated second key/)
|
83
|
+
Idiom::Yrb.new(:source => @source).generate
|
84
|
+
end
|
85
|
+
|
86
|
+
describe "key exists" do
|
87
|
+
before(:each) do
|
88
|
+
YRB.stub!(:load_file).and_return({"FIRST" => "old translated first key"})
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should not translate a key that is already translated" do
|
92
|
+
@file.should_not_receive(:puts).with(/FIRST=translated first key/)
|
93
|
+
Idiom::Yrb.new(:source => @source).generate
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should translate a key that is already translated if overwrite is true" do
|
97
|
+
@file.should_receive(:puts).with(/FIRST=translated first key/)
|
98
|
+
Idiom::Yrb.new(:source => @source, :overwrite => true).generate
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
describe "languages" do
|
103
|
+
it "should only translate the specified set of languages" do
|
104
|
+
@languages = ["de-DE", "zh-Hant-HK"]
|
105
|
+
Idiom::Yrb::LOCALES.each do |lang, code|
|
106
|
+
if @languages.include?(lang)
|
107
|
+
File.should_receive(:open).with("./translations/path_#{lang}.pres", "a")
|
108
|
+
else
|
109
|
+
File.should_not_receive(:open).with("./translations/path_#{lang}.pres", "a")
|
110
|
+
end
|
111
|
+
end
|
112
|
+
Idiom::Yrb.new(:source => @source, :languages => @languages).generate
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
describe "yml" do
|
118
|
+
before(:each) do
|
119
|
+
@yml_file = <<-YAML
|
120
|
+
first: first key
|
121
|
+
second: second key
|
122
|
+
YAML
|
123
|
+
File.stub!(:readlines).and_return(@yml_file)
|
124
|
+
Translate.stub!(:t).with("first key", "ENGLISH", anything).and_return("translated first key")
|
125
|
+
Translate.stub!(:t).with("second key", "ENGLISH", anything).and_return("translated second key")
|
126
|
+
@source = "./translations/path.yml"
|
127
|
+
end
|
128
|
+
|
129
|
+
it "should create the destination path if it does not exist" do
|
130
|
+
Idiom::Yaml::LOCALES.each do |lang, code|
|
131
|
+
FileUtils.should_receive(:mkdir_p).with("./translations") unless lang == "en-US"
|
132
|
+
end
|
133
|
+
Idiom::Yaml.new(:source => @source).generate
|
134
|
+
end
|
135
|
+
|
136
|
+
it "should write to the destination path" do
|
137
|
+
Idiom::Yaml::LOCALES.each do |lang, code|
|
138
|
+
File.should_receive(:open).with("./translations/path_#{lang}.yml", "a") unless lang == "en-US"
|
139
|
+
end
|
140
|
+
Idiom::Yaml.new(:source => @source).generate
|
141
|
+
end
|
142
|
+
|
143
|
+
describe "directories" do
|
144
|
+
before(:each) do
|
145
|
+
@source = "./translations/en-US/path.yml"
|
146
|
+
end
|
147
|
+
|
148
|
+
it "should write to directories" do
|
149
|
+
Idiom::Yaml::LOCALES.each do |lang, code|
|
150
|
+
File.should_receive(:open).with("./translations/#{lang}/path_#{lang}.yml", "a") unless lang == "en-US"
|
151
|
+
end
|
152
|
+
Idiom::Yaml.new(:source => @source, :use_dirs => true).generate
|
153
|
+
end
|
154
|
+
|
155
|
+
it "should create the destination path with directories if it does not exist" do
|
156
|
+
Idiom::Yrb::LOCALES.each do |lang, code|
|
157
|
+
FileUtils.should_receive(:mkdir_p).with("./translations/#{lang}") unless lang == "en-US"
|
158
|
+
end
|
159
|
+
Idiom::Yrb.new(:source => @source, :use_dirs => true).generate
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
it "should translate the first string" do
|
164
|
+
@file.should_receive(:puts).with(/first: translated first key/)
|
165
|
+
Idiom::Yaml.new(:source => @source).generate
|
166
|
+
end
|
167
|
+
|
168
|
+
it "should translate the second string" do
|
169
|
+
@file.should_receive(:puts).with(/second: translated second key/)
|
170
|
+
Idiom::Yaml.new(:source => @source).generate
|
171
|
+
end
|
172
|
+
|
173
|
+
describe "key exists" do
|
174
|
+
before(:each) do
|
175
|
+
YAML.stub!(:load_file).and_return({"first" => "old translated first key"})
|
176
|
+
end
|
177
|
+
|
178
|
+
it "should not translate a key that is already translated" do
|
179
|
+
@file.should_not_receive(:puts).with(/first: translated first key/)
|
180
|
+
Idiom::Yaml.new(:source => @source).generate
|
181
|
+
end
|
182
|
+
|
183
|
+
it "should translate a key that is already translated if overwrite is true" do
|
184
|
+
@file.should_receive(:puts).with(/first: translated first key/)
|
185
|
+
Idiom::Yaml.new(:source => @source, :overwrite => true).generate
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
describe "languages" do
|
190
|
+
it "should only translate the specified set of languages" do
|
191
|
+
@languages = ["de-DE", "zh-Hant-HK"]
|
192
|
+
Idiom::Yaml::LOCALES.each do |lang, code|
|
193
|
+
if @languages.include?(lang)
|
194
|
+
File.should_receive(:open).with("./translations/path_#{lang}.yml", "a")
|
195
|
+
else
|
196
|
+
File.should_not_receive(:open).with("./translations/path_#{lang}.yml", "a")
|
197
|
+
end
|
198
|
+
end
|
199
|
+
Idiom::Yaml.new(:source => @source, :languages => @languages).generate
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
data/spec/spec.opts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/spec/spec_helper.rb
ADDED
data/spec/stubs.rb
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
def stub_io
|
2
|
+
stub_screen_io
|
3
|
+
stub_file_io
|
4
|
+
stub_file_utils
|
5
|
+
stub_yaml
|
6
|
+
stub_yrb
|
7
|
+
stub_growl
|
8
|
+
end
|
9
|
+
|
10
|
+
def stub_screen_io
|
11
|
+
$stdout.stub!(:puts)
|
12
|
+
$stdout.stub!(:print)
|
13
|
+
end
|
14
|
+
|
15
|
+
def stub_file_io(unprocessed_file="")
|
16
|
+
@file ||= mock('file').as_null_object
|
17
|
+
@file.stub!(:read).and_return(unprocessed_file)
|
18
|
+
@file.stub!(:write)
|
19
|
+
@file.stub!(:puts)
|
20
|
+
|
21
|
+
File.stub!(:new).and_return(@file)
|
22
|
+
File.stub!(:exists?).and_return(false)
|
23
|
+
File.stub!(:open).and_yield(@file)
|
24
|
+
File.stub!(:read).and_return(unprocessed_file)
|
25
|
+
File.stub!(:readlines).and_return(["first\n", "second\n"])
|
26
|
+
end
|
27
|
+
|
28
|
+
def stub_file_utils
|
29
|
+
FileUtils.stub!(:rm)
|
30
|
+
FileUtils.stub!(:rm_rf)
|
31
|
+
FileUtils.stub!(:cp_r)
|
32
|
+
FileUtils.stub!(:mkdir_p)
|
33
|
+
F.stub!(:concat_files)
|
34
|
+
F.stub!(:get_line_from_file).and_return("")
|
35
|
+
F.stub!(:save_to_file)
|
36
|
+
F.stub!(:save_to_tmp_file)
|
37
|
+
F.stub!(:execute).and_return("")
|
38
|
+
end
|
39
|
+
|
40
|
+
def stub_yaml(output_hash={})
|
41
|
+
YAML.stub!(:load_file).and_return(output_hash)
|
42
|
+
end
|
43
|
+
|
44
|
+
def stub_yrb(output_hash={})
|
45
|
+
YRB.stub!(:load_file).and_return(output_hash)
|
46
|
+
end
|
47
|
+
|
48
|
+
def stub_erb(processed_file="")
|
49
|
+
@erb ||= mock('erb').as_null_object
|
50
|
+
@erb.stub!(:result).and_return(processed_file)
|
51
|
+
ERB.stub!(:new).and_return(@erb)
|
52
|
+
end
|
53
|
+
|
54
|
+
def stub_haml_class
|
55
|
+
eval %(
|
56
|
+
module Haml
|
57
|
+
class Engine
|
58
|
+
end
|
59
|
+
end
|
60
|
+
)
|
61
|
+
end
|
62
|
+
|
63
|
+
def stub_haml(processed_file)
|
64
|
+
@haml = mock('haml').as_null_object
|
65
|
+
@haml.stub!(:render).and_return(processed_file)
|
66
|
+
Haml::Engine.stub!(:new).and_return(@haml)
|
67
|
+
end
|
68
|
+
|
69
|
+
def stub_git_helper
|
70
|
+
@git_helper = mock('git_helper').as_null_object
|
71
|
+
YMDP::GitHelper.stub!(:new).and_return(@git_helper)
|
72
|
+
end
|
73
|
+
|
74
|
+
def stub_timer
|
75
|
+
@timer = mock('timer').as_null_object
|
76
|
+
@timer.stub!(:time).and_yield
|
77
|
+
Timer.stub!(:new).and_return(@timer)
|
78
|
+
end
|
79
|
+
|
80
|
+
def stub_growl
|
81
|
+
@g = Object.new
|
82
|
+
Growl.stub(:new).and_return(@g)
|
83
|
+
@g.stub(:notify).as_null_object
|
84
|
+
end
|
85
|
+
|
86
|
+
def reset_constant(constant, value)
|
87
|
+
Object.send(:remove_const, constant)
|
88
|
+
Object.const_set(constant, value)
|
89
|
+
end
|
90
|
+
|
91
|
+
def stub_config
|
92
|
+
@config = mock('config')
|
93
|
+
@config.stub!(:[]).with("doctype").and_return("HTML 4.0 Transitional")
|
94
|
+
@config.stub!(:validate_html?).and_return(false)
|
95
|
+
@config.stub!(:compress_embedded_js?).and_return(false)
|
96
|
+
@config.stub!(:verbose?).and_return(false)
|
97
|
+
reset_constant(:CONFIG, @config)
|
98
|
+
end
|
metadata
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: idiom
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jeff Coleman
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2010-01-22 00:00:00 -06:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: rspec
|
17
|
+
type: :development
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 1.2.9
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: activesupport
|
27
|
+
type: :runtime
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 2.2.2
|
34
|
+
version:
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: sishen-rtranslate
|
37
|
+
type: :runtime
|
38
|
+
version_requirement:
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 1.2.9
|
44
|
+
version:
|
45
|
+
- !ruby/object:Gem::Dependency
|
46
|
+
name: yrb
|
47
|
+
type: :runtime
|
48
|
+
version_requirement:
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: "0"
|
54
|
+
version:
|
55
|
+
description: Takes a set of keys in Yaml format and translates them through Google Translate.
|
56
|
+
email: progressions@gmail.com
|
57
|
+
executables: []
|
58
|
+
|
59
|
+
extensions: []
|
60
|
+
|
61
|
+
extra_rdoc_files:
|
62
|
+
- LICENSE
|
63
|
+
- README.rdoc
|
64
|
+
files:
|
65
|
+
- .document
|
66
|
+
- .gitignore
|
67
|
+
- Gemfile
|
68
|
+
- LICENSE
|
69
|
+
- README.rdoc
|
70
|
+
- Rakefile
|
71
|
+
- VERSION
|
72
|
+
- lib/idiom.rb
|
73
|
+
- spec/idiom_spec.rb
|
74
|
+
- spec/spec.opts
|
75
|
+
- spec/spec_helper.rb
|
76
|
+
- spec/stubs.rb
|
77
|
+
has_rdoc: true
|
78
|
+
homepage: http://github.com/progressions/idiom
|
79
|
+
licenses: []
|
80
|
+
|
81
|
+
post_install_message:
|
82
|
+
rdoc_options:
|
83
|
+
- --charset=UTF-8
|
84
|
+
require_paths:
|
85
|
+
- lib
|
86
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: "0"
|
91
|
+
version:
|
92
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: "0"
|
97
|
+
version:
|
98
|
+
requirements: []
|
99
|
+
|
100
|
+
rubyforge_project:
|
101
|
+
rubygems_version: 1.3.5
|
102
|
+
signing_key:
|
103
|
+
specification_version: 3
|
104
|
+
summary: Translate strings in Google Translate
|
105
|
+
test_files:
|
106
|
+
- spec/idiom_spec.rb
|
107
|
+
- spec/spec_helper.rb
|
108
|
+
- spec/stubs.rb
|