i18nliner 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +151 -104
- data/lib/i18nliner/base.rb +47 -0
- data/lib/i18nliner/call_helpers.rb +39 -13
- data/lib/i18nliner/commands/check.rb +20 -10
- data/lib/i18nliner/commands/dump.rb +17 -0
- data/lib/i18nliner/commands/generic_command.rb +10 -1
- data/lib/i18nliner/errors.rb +11 -1
- data/lib/i18nliner/erubis.rb +12 -0
- data/lib/i18nliner/extensions/controller.rb +25 -0
- data/lib/i18nliner/extensions/core.rb +61 -0
- data/lib/i18nliner/extensions/inferpolation.rb +28 -0
- data/lib/i18nliner/extensions/model.rb +29 -0
- data/lib/i18nliner/extensions/view.rb +28 -0
- data/lib/i18nliner/extractors/ruby_extractor.rb +15 -33
- data/lib/i18nliner/extractors/sexp_helper.rb +38 -0
- data/lib/i18nliner/extractors/translate_call.rb +9 -11
- data/lib/i18nliner/extractors/translation_hash.rb +6 -6
- data/lib/i18nliner/pre_processors/erb_pre_processor.rb +334 -0
- data/lib/i18nliner/processors/abstract_processor.rb +26 -5
- data/lib/i18nliner/processors/erb_processor.rb +19 -3
- data/lib/i18nliner/processors/ruby_processor.rb +16 -5
- data/lib/i18nliner/railtie.rb +27 -0
- data/lib/i18nliner/scope.rb +4 -0
- data/lib/i18nliner.rb +5 -29
- data/lib/tasks/i18nliner.rake +10 -4
- data/spec/commands/check_spec.rb +22 -0
- data/spec/commands/dump_spec.rb +27 -0
- data/spec/extensions/core_spec.rb +71 -0
- data/spec/extensions/inferpolation_spec.rb +41 -0
- data/spec/extensions/view_spec.rb +42 -0
- data/spec/extractors/ruby_extractor_spec.rb +4 -5
- data/spec/extractors/translate_call_spec.rb +29 -2
- data/spec/fixtures/app/models/invalid.rb +5 -0
- data/spec/fixtures/app/models/valid.rb +5 -0
- data/spec/pre_processors/erb_pre_processor_spec.rb +194 -0
- data/spec/processors/erb_processor_spec.rb +28 -0
- metadata +88 -5
data/README.md
CHANGED
@@ -1,15 +1,12 @@
|
|
1
1
|
# I18nliner
|
2
2
|
|
3
|
+
[<img src="https://secure.travis-ci.org/jenseng/i18nliner.png" />](http://travis-ci.org/jenseng/i18nliner)
|
4
|
+
|
3
5
|
yay readme-driven development!
|
4
6
|
|
5
7
|
## TODO
|
6
8
|
|
7
|
-
* inferred placeholders (instance vars and methods)
|
8
|
-
* ERB pre-processor
|
9
|
-
* wrapper inference
|
10
|
-
* helper/placeholder extraction
|
11
9
|
* rake tasks
|
12
|
-
* dump
|
13
10
|
* diff
|
14
11
|
* import
|
15
12
|
|
@@ -19,30 +16,36 @@ I18nliner is I18n made simple.
|
|
19
16
|
|
20
17
|
No .yml files. Inline defaults. Optional keys. Inferred interpolation values.
|
21
18
|
Wrappers and blocks, so your templates look template-y and your translations
|
22
|
-
HTML-free.
|
19
|
+
stay HTML-free.
|
23
20
|
|
24
21
|
## TL;DR
|
25
22
|
|
26
23
|
I18nliner lets you do stuff like this:
|
27
24
|
|
28
|
-
|
29
|
-
|
25
|
+
```ruby
|
26
|
+
t "Ohai %{@user.name}, my default translation is right here in the code. " \
|
27
|
+
"Inferred keys and placeholder values, oh my!"
|
28
|
+
```
|
30
29
|
|
31
30
|
and even this:
|
32
31
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
32
|
+
```erb
|
33
|
+
<%= t do %>
|
34
|
+
Hey <%= amigo %>!
|
35
|
+
Although I am <%= link_to "linking to something", random_path %> and
|
36
|
+
have some <strong>bold text</strong>, the translators will see
|
37
|
+
<strong><em>absolutely no markup</em></strong> and will only have a
|
38
|
+
single string to translate :o
|
39
|
+
<% end %>
|
40
|
+
```
|
40
41
|
|
41
42
|
## Installation
|
42
43
|
|
43
44
|
Add the following to your Gemfile:
|
44
45
|
|
45
|
-
|
46
|
+
```ruby
|
47
|
+
gem 'i18nliner'
|
48
|
+
```
|
46
49
|
|
47
50
|
## Features
|
48
51
|
|
@@ -50,11 +53,15 @@ Add the following to your Gemfile:
|
|
50
53
|
|
51
54
|
Instead of maintaining .yml files and doing stuff like this:
|
52
55
|
|
53
|
-
|
56
|
+
```ruby
|
57
|
+
I18n.t :account_page_title
|
58
|
+
```
|
54
59
|
|
55
60
|
Forget the .yml and just do:
|
56
61
|
|
57
|
-
|
62
|
+
```ruby
|
63
|
+
I18n.t :account_page_title, "My Account"
|
64
|
+
```
|
58
65
|
|
59
66
|
Regular I18n options follow the (optional) default translation, so you can do
|
60
67
|
the usual stuff (placeholders, etc.).
|
@@ -63,7 +70,9 @@ the usual stuff (placeholders, etc.).
|
|
63
70
|
|
64
71
|
Sure, but *you* don't need to write it. Just run:
|
65
72
|
|
66
|
-
|
73
|
+
```bash
|
74
|
+
rake i18nliner:dump
|
75
|
+
```
|
67
76
|
|
68
77
|
This extracts all default translations from your codebase, merges them with any
|
69
78
|
other ones (from rails or pre-existing .yml files), and outputs them to
|
@@ -74,7 +83,9 @@ other ones (from rails or pre-existing .yml files), and outputs them to
|
|
74
83
|
Why waste time coming up with keys that are less descriptive than the default
|
75
84
|
translation? I18nliner makes keys optional, so you can just do this:
|
76
85
|
|
77
|
-
|
86
|
+
```ruby
|
87
|
+
I18n.t "My Account"
|
88
|
+
```
|
78
89
|
|
79
90
|
I18nliner will create a [unique key](CONFIG.md) based on the translation (e.g.
|
80
91
|
`:my_account`), so you don't have to.
|
@@ -91,18 +102,22 @@ Interpolation values may be inferred by I18nliner if not provided. So long as
|
|
91
102
|
it's an instance variable or method (or chain), you don't need to specify its
|
92
103
|
value. So this:
|
93
104
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
105
|
+
```erb
|
106
|
+
<p>
|
107
|
+
<%= t "Hello, %{user}. This request was a %{request_method}.",
|
108
|
+
user: @user.name,
|
109
|
+
request_method: request.method
|
110
|
+
%>
|
111
|
+
</p>
|
112
|
+
```
|
100
113
|
|
101
114
|
Can just be this:
|
102
115
|
|
103
|
-
|
104
|
-
|
105
|
-
|
116
|
+
```erb
|
117
|
+
<p>
|
118
|
+
<%= t "Hello, %{@user.name}. This request was a %{request.method}." %>
|
119
|
+
</p>
|
120
|
+
```
|
106
121
|
|
107
122
|
Note that local variables cannot be inferred.
|
108
123
|
|
@@ -112,19 +127,23 @@ Note that local variables cannot be inferred.
|
|
112
127
|
|
113
128
|
Suppose you have something like this in your ERB:
|
114
129
|
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
130
|
+
```erb
|
131
|
+
<p>
|
132
|
+
You can <%= link_to "lead", new_discussion_path %> a new discussion or
|
133
|
+
<%= link_to "join", discussion_search_path %> an existing one.
|
134
|
+
</p>
|
135
|
+
```
|
119
136
|
|
120
137
|
You might try something like this:
|
121
138
|
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
139
|
+
```erb
|
140
|
+
<p>
|
141
|
+
<%= t("You can %{lead} a new discussion or %{join} an existing one.",
|
142
|
+
lead: link_to(t("lead"), new_discussion_path),
|
143
|
+
join: link_to(t("join"), discussion_search_path)).html_safe
|
144
|
+
%>
|
145
|
+
</p>
|
146
|
+
```
|
128
147
|
|
129
148
|
This is not great, because:
|
130
149
|
|
@@ -136,14 +155,16 @@ This is not great, because:
|
|
136
155
|
|
137
156
|
So you might try this instead:
|
138
157
|
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
158
|
+
```erb
|
159
|
+
<p>
|
160
|
+
<%= t :discussion_html,
|
161
|
+
"You can <a href="%{lead_url}">lead</a> a new discussion or " \
|
162
|
+
"<a href="%{join_url}">join</a> an existing one.",
|
163
|
+
lead_url: new_discussion_path,
|
164
|
+
join_url: discussion_search_path
|
165
|
+
%>
|
166
|
+
</p>
|
167
|
+
```
|
147
168
|
|
148
169
|
This isn't much better, because now you have HTML in your translations. If you
|
149
170
|
want to add a class to the link, you have to go update all the translations.
|
@@ -157,14 +178,16 @@ So what do you do?
|
|
157
178
|
I18nliner lets you specify wrappers, so you can keep HTML out the translations,
|
158
179
|
while still just having a single string needing translation:
|
159
180
|
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
181
|
+
```erb
|
182
|
+
<p>
|
183
|
+
<%= t "You can *lead* a new discussion or **join** an existing one.",
|
184
|
+
wrappers: [
|
185
|
+
link_to('\1', new_discussion_path),
|
186
|
+
link_to('\1', discussion_search_path)
|
187
|
+
]
|
188
|
+
%>
|
189
|
+
</p>
|
190
|
+
```
|
168
191
|
|
169
192
|
Default delimiters are increasing numbers of asterisks, but you can specify
|
170
193
|
any string as a delimiter by using a hash rather than an array.
|
@@ -175,50 +198,60 @@ But wait, there's more!
|
|
175
198
|
|
176
199
|
Perhaps you want your templates to look like, well, templates. Try this:
|
177
200
|
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
201
|
+
```erb
|
202
|
+
<p>
|
203
|
+
<%= t do %>
|
204
|
+
Welcome to the internets, <%= user.name %>
|
205
|
+
<% end %>
|
206
|
+
</p>
|
207
|
+
```
|
183
208
|
|
184
209
|
Or even this:
|
185
210
|
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
211
|
+
```erb
|
212
|
+
<p>
|
213
|
+
<%= t do %>
|
214
|
+
<b>Ohai <%= user.name %>,</b>
|
215
|
+
you can <%= link_to "lead", new_discussion_path %> a new discussion or
|
216
|
+
<%= link_to "join", discussion_search_path %> an existing one.
|
217
|
+
<% end %>
|
218
|
+
</p>
|
219
|
+
```
|
193
220
|
|
194
221
|
In case you're curious about the man behind the curtain, I18nliner adds an ERB
|
195
222
|
pre-processor that turns the second example into something like this right
|
196
223
|
before it hits ERB:
|
197
224
|
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
225
|
+
```erb
|
226
|
+
<p>
|
227
|
+
<%= t :some_unique_key,
|
228
|
+
"*Ohai %{user_name}*, you can **lead** a new discussion or ***join*** an existing one.",
|
229
|
+
user_name: user.name,
|
230
|
+
wrappers: [
|
231
|
+
'<b>\1</b>',
|
232
|
+
link_to('\1', new_discussion_path),
|
233
|
+
link_to('\1', discussion_search_path)
|
234
|
+
]
|
235
|
+
%>
|
236
|
+
</p>
|
237
|
+
```
|
209
238
|
|
210
239
|
In other words, it will infer wrappers from your (balanced) markup and
|
211
240
|
[`link_to` calls](INFERRED_WRAPPERS.md), and will create placeholders for any
|
212
|
-
other ERB expressions. ERB statements (e.g.
|
213
|
-
`<% if some_condition %>...`)
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
241
|
+
other (inline) ERB expressions. ERB statements (e.g.
|
242
|
+
`<% if some_condition %>...`) and block expressions (e.g.
|
243
|
+
`<%= form_for @person do %>...`) are *not* supported within a block
|
244
|
+
translation. The only exception to this rule is nested translation
|
245
|
+
calls, e.g. this is totally fine:
|
246
|
+
|
247
|
+
```erb
|
248
|
+
<%= t do %>
|
249
|
+
Be sure to
|
250
|
+
<a href="/account/" title="<%= t do %>Account Settings<% end %>">
|
251
|
+
set up your account
|
252
|
+
</a>.
|
253
|
+
<% end %>
|
254
|
+
```
|
222
255
|
|
223
256
|
#### HTML Safety
|
224
257
|
|
@@ -232,28 +265,29 @@ escaped.
|
|
232
265
|
Pluralization can be tricky, but [I18n gives you some flexibility](http://guides.rubyonrails.org/i18n.html#pluralization).
|
233
266
|
I18nliner brings this inline with a default translation hash, e.g.
|
234
267
|
|
235
|
-
|
236
|
-
|
268
|
+
```ruby
|
269
|
+
t({one: "There is one light!", other: "There are %{count} lights!"},
|
270
|
+
count: picard.visible_lights.count)
|
271
|
+
```
|
237
272
|
|
238
273
|
Note that the :count interpolation value needs to be explicitly set when doing
|
239
|
-
pluralization.
|
240
|
-
so you can do this:
|
241
|
-
|
242
|
-
<%= pluralize picard.visible_lights.count do %>
|
243
|
-
<% one do %>There is one light!<% end %>
|
244
|
-
<% other do %>There are <%= count %> lights!<% end %>
|
245
|
-
<% end %>
|
274
|
+
pluralization.
|
246
275
|
|
247
276
|
If you just want to pluralize a single word, there's a shortcut:
|
248
277
|
|
249
|
-
|
278
|
+
```ruby
|
279
|
+
t "person", count: users.count
|
280
|
+
```
|
250
281
|
|
251
282
|
This is equivalent to:
|
252
283
|
|
253
|
-
|
254
|
-
|
284
|
+
```ruby
|
285
|
+
t({one: "1 person", other: "%{count} people"},
|
286
|
+
count: users.count)
|
287
|
+
```
|
255
288
|
|
256
|
-
I18nliner uses
|
289
|
+
I18nliner uses [`String#pluralize`](http://edgeguides.rubyonrails.org/active_support_core_extensions.html#pluralize)
|
290
|
+
to determine the default one/other values,
|
257
291
|
so if your `I18n.default_locale` is something other than English, you may need
|
258
292
|
to [add some inflections](https://gist.github.com/838188).
|
259
293
|
|
@@ -271,6 +305,16 @@ Does an i18nliner:check, and then extracts all default translations from your
|
|
271
305
|
codebase, merges them with any other ones (from rails or pre-existing .yml
|
272
306
|
files), and outputs them to `config/locales/generated/en.yml`.
|
273
307
|
|
308
|
+
### Dynamic Translations
|
309
|
+
|
310
|
+
Note that check and dump commands require all translation keys and
|
311
|
+
defaults to be literals. This is because it reads your code, it doesn't
|
312
|
+
run it. If you know what you are doing and want to pass in a variable or
|
313
|
+
other expression, you can use the `t!` (or `translate!`) command. It works
|
314
|
+
the same as `t` at runtime, but signals to the extractor that it shouldn't
|
315
|
+
complain. You should only do this if you are sure that the specified
|
316
|
+
key/string is extracted elsewhere or already in your yml.
|
317
|
+
|
274
318
|
### i18nliner:diff
|
275
319
|
|
276
320
|
Does an i18nliner:dump and creates a diff from a previous one (path or git
|
@@ -294,7 +338,9 @@ though it supports
|
|
294
338
|
If you only want to check a particular file/directory/pattern, you can set the
|
295
339
|
environment variable `ONLY` when you run the command, e.g.
|
296
340
|
|
297
|
-
|
341
|
+
```bash
|
342
|
+
rake i18nliner:check ONLY=/app/**/user*
|
343
|
+
```
|
298
344
|
|
299
345
|
## Compatibility
|
300
346
|
|
@@ -307,7 +353,8 @@ I18nliner requires at least Ruby 1.9.3 and Rails 3.
|
|
307
353
|
|
308
354
|
## What about JavaScript/Handlebars?
|
309
355
|
|
310
|
-
Coming
|
356
|
+
[Coming](https://github.com/jenseng/i18nliner-js) [soon](https://github.com/fivetanley/i18ninliner-handlebars).
|
357
|
+
I18nliner was inspired by some [I18n extensions](https://github.com/instructure/canvas-lms/tree/master/lib/i18n_extraction)
|
311
358
|
I did in [Canvas-LMS](https://github.com/instructure/canvas-lms). While
|
312
359
|
it also has the JavaScript/Handlebars equivalents, they are tightly
|
313
360
|
coupled to Canvas-LMS and are written in Ruby. So basically we're talking
|
@@ -317,4 +364,4 @@ that is js_extractor.
|
|
317
364
|
|
318
365
|
## License
|
319
366
|
|
320
|
-
Copyright (c)
|
367
|
+
Copyright (c) 2014 Jon Jensen, released under the MIT license
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'i18n'
|
2
|
+
|
3
|
+
module I18nliner
|
4
|
+
def self.ignore
|
5
|
+
@ignore ||= begin
|
6
|
+
path = File.join(base_path, ".i18nignore")
|
7
|
+
File.exist?(path) ?
|
8
|
+
File.read(path).split(/\r?\n|\r/) :
|
9
|
+
[]
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.translations
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.manual_translations
|
17
|
+
# TODO: support additional backends
|
18
|
+
I18n.backend.send(:translations)
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.look_up(key)
|
22
|
+
I18n.exists?(I18n.locale, key)
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.setting(key, value)
|
26
|
+
instance_eval <<-CODE
|
27
|
+
def #{key}(value = nil)
|
28
|
+
if value && block_given?
|
29
|
+
begin
|
30
|
+
value_was = @#{key}
|
31
|
+
@#{key} = value
|
32
|
+
yield
|
33
|
+
ensure
|
34
|
+
@#{key} = value_was
|
35
|
+
end
|
36
|
+
else
|
37
|
+
@#{key} = #{value.inspect} if @#{key}.nil?
|
38
|
+
@#{key}
|
39
|
+
end
|
40
|
+
end
|
41
|
+
CODE
|
42
|
+
end
|
43
|
+
|
44
|
+
setting :inferred_key_format, :underscored_crc32
|
45
|
+
setting :infer_interpolation_values, true
|
46
|
+
setting :base_path, "./"
|
47
|
+
end
|
@@ -1,14 +1,14 @@
|
|
1
|
-
require 'iconv'
|
2
1
|
require 'zlib'
|
2
|
+
require 'i18n'
|
3
|
+
require 'i18nliner/base'
|
3
4
|
|
4
5
|
module I18nliner
|
5
6
|
module CallHelpers
|
6
7
|
ALLOWED_PLURALIZATION_KEYS = [:zero, :one, :few, :many, :other]
|
7
8
|
REQUIRED_PLURALIZATION_KEYS = [:one, :other]
|
8
9
|
|
9
|
-
def normalize_key(key, scope
|
10
|
-
key
|
11
|
-
scope.normalize_key(key)
|
10
|
+
def normalize_key(key, scope = Scope.root)
|
11
|
+
scope.normalize_key(key.to_s)
|
12
12
|
end
|
13
13
|
|
14
14
|
def normalize_default(default, translate_options = {})
|
@@ -25,21 +25,22 @@ module I18nliner
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def infer_key(default, translate_options = {})
|
28
|
+
return unless default && (default.is_a?(String) || default.is_a?(Hash))
|
28
29
|
default = default[:other].to_s if default.is_a?(Hash)
|
29
30
|
keyify(normalize_default(default, translate_options))
|
30
31
|
end
|
31
32
|
|
32
33
|
def keyify_underscored(string)
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
34
|
+
key = I18n.transliterate(string, :locale => I18n.default_locale).to_s
|
35
|
+
key.downcase!
|
36
|
+
key.gsub!(/[^a-z0-9_]+/, '_')
|
37
|
+
key.gsub!(/\A_|_\z/, '')
|
38
|
+
key[0..50]
|
38
39
|
end
|
39
40
|
|
40
41
|
def keyify_underscored_crc32(string)
|
41
|
-
checksum = Zlib.crc32(string.size.to_s
|
42
|
-
keyify_underscored(string)
|
42
|
+
checksum = Zlib.crc32("#{string.size.to_s}:#{string}").to_s(16)
|
43
|
+
"#{keyify_underscored(string)}_#{checksum}"
|
43
44
|
end
|
44
45
|
|
45
46
|
def keyify(string)
|
@@ -57,13 +58,38 @@ module I18nliner
|
|
57
58
|
# key, default_hash, options
|
58
59
|
# default_string [, options]
|
59
60
|
# default_hash, options
|
60
|
-
def key_provided?(
|
61
|
+
def key_provided?(key_or_default = nil, default_or_options = nil, maybe_options = nil, *others)
|
61
62
|
return false if key_or_default.is_a?(Hash)
|
62
63
|
return true if key_or_default.is_a?(Symbol)
|
63
64
|
return true if default_or_options.is_a?(String)
|
64
65
|
return true if maybe_options
|
65
|
-
return true if
|
66
|
+
return true if key_or_default =~ /\A\.?(\w+\.)+\w+\z/
|
66
67
|
false
|
67
68
|
end
|
69
|
+
|
70
|
+
def pluralization_hash?(hash)
|
71
|
+
hash.is_a?(Hash) &&
|
72
|
+
hash.size > 0 &&
|
73
|
+
(hash.keys - ALLOWED_PLURALIZATION_KEYS).size == 0
|
74
|
+
end
|
75
|
+
|
76
|
+
def infer_arguments(args)
|
77
|
+
if args.size == 2 && args[1].is_a?(Hash) && args[1][:default]
|
78
|
+
return args
|
79
|
+
end
|
80
|
+
|
81
|
+
has_key = key_provided?(*args)
|
82
|
+
args.unshift infer_key(args[0]) unless has_key
|
83
|
+
|
84
|
+
default_or_options = args[1]
|
85
|
+
if args[2] || default_or_options.is_a?(String) || pluralization_hash?(default_or_options)
|
86
|
+
options = args[2] ||= {}
|
87
|
+
options[:default] = args.delete_at(1) if options.is_a?(Hash)
|
88
|
+
end
|
89
|
+
args << {} if args.size == 1
|
90
|
+
args
|
91
|
+
end
|
92
|
+
|
93
|
+
extend self
|
68
94
|
end
|
69
95
|
end
|
@@ -1,17 +1,25 @@
|
|
1
|
+
require 'i18nliner/commands/generic_command'
|
2
|
+
require 'i18nliner/extractors/translation_hash'
|
3
|
+
require 'active_support/core_ext/enumerable'
|
4
|
+
Dir[File.join(File.dirname(__FILE__), "../processors/*.rb")].each do |file|
|
5
|
+
require "i18nliner/processors/#{File.basename(file)}"
|
6
|
+
end
|
7
|
+
|
1
8
|
module I18nliner
|
2
9
|
module Commands
|
3
10
|
class Check < GenericCommand
|
4
|
-
attr_reader :translations
|
11
|
+
attr_reader :translations, :errors
|
5
12
|
|
6
13
|
def initialize(options)
|
7
14
|
super
|
8
15
|
@errors = []
|
9
|
-
@translations = TranslationHash.new(I18nliner.manual_translations)
|
16
|
+
@translations = I18nliner::Extractors::TranslationHash.new(I18nliner.manual_translations)
|
10
17
|
end
|
11
18
|
|
12
19
|
def processors
|
13
20
|
@processors ||= I18nliner::Processors.all.map do |klass|
|
14
|
-
klass.new
|
21
|
+
klass.new @translations,
|
22
|
+
:only => @options[:only],
|
15
23
|
:translations => @translations,
|
16
24
|
:checker => method(:check_file)
|
17
25
|
end
|
@@ -22,14 +30,16 @@ module I18nliner
|
|
22
30
|
end
|
23
31
|
|
24
32
|
def check_file(file)
|
25
|
-
|
33
|
+
if yield file
|
34
|
+
print green(".") unless @options[:silent]
|
35
|
+
end
|
26
36
|
rescue SyntaxError, StandardError, ExtractionError
|
27
37
|
@errors << "#{$!}\n#{file}"
|
28
|
-
print red("F")
|
38
|
+
print red("F") unless @options[:silent]
|
29
39
|
end
|
30
40
|
|
31
|
-
def
|
32
|
-
@errors.
|
41
|
+
def success?
|
42
|
+
@errors.empty?
|
33
43
|
end
|
34
44
|
|
35
45
|
def print_summary
|
@@ -46,13 +56,13 @@ module I18nliner
|
|
46
56
|
|
47
57
|
print "Finished in #{Time.now - @start} seconds\n\n"
|
48
58
|
summary = "#{file_count} files, #{translation_count} strings, #{@errors.size} failures"
|
49
|
-
puts
|
59
|
+
puts success? ? green(summary) : red(summary)
|
50
60
|
end
|
51
61
|
|
52
62
|
def run
|
53
63
|
check_files
|
54
|
-
print_summary
|
55
|
-
|
64
|
+
print_summary unless @options[:silent]
|
65
|
+
success?
|
56
66
|
end
|
57
67
|
end
|
58
68
|
end
|
@@ -1,7 +1,24 @@
|
|
1
|
+
require 'ya2yaml'
|
2
|
+
require 'fileutils'
|
3
|
+
|
1
4
|
module I18nliner
|
2
5
|
module Commands
|
3
6
|
class Dump < GenericCommand
|
7
|
+
attr_reader :yml_file
|
8
|
+
|
9
|
+
def initialize(options)
|
10
|
+
super
|
11
|
+
@translations = @options[:translations]
|
12
|
+
@yml_file = @options[:file] ||
|
13
|
+
File.join(I18nliner.base_path, "config", "locales", "generated", "#{I18n.default_locale}.yml")
|
14
|
+
end
|
15
|
+
|
4
16
|
def run
|
17
|
+
FileUtils.mkdir_p File.dirname(yml_file)
|
18
|
+
File.open(yml_file, "w") do |file|
|
19
|
+
file.write({I18n.default_locale.to_s => @translations}.ya2yaml(:syck_compatible => true))
|
20
|
+
end
|
21
|
+
puts "Wrote default translations to #{yml_file}" unless @options[:silent]
|
5
22
|
end
|
6
23
|
end
|
7
24
|
end
|
@@ -1,3 +1,6 @@
|
|
1
|
+
require 'i18nliner/commands/basic_formatter'
|
2
|
+
require 'i18nliner/commands/color_formatter'
|
3
|
+
|
1
4
|
module I18nliner
|
2
5
|
module Commands
|
3
6
|
class GenericCommand
|
@@ -9,8 +12,14 @@ module I18nliner
|
|
9
12
|
extend ColorFormatter if $stdout.tty?
|
10
13
|
end
|
11
14
|
|
15
|
+
def success?
|
16
|
+
true
|
17
|
+
end
|
18
|
+
|
12
19
|
def self.run(options)
|
13
|
-
new(options)
|
20
|
+
command = new(options)
|
21
|
+
command.run
|
22
|
+
command
|
14
23
|
end
|
15
24
|
end
|
16
25
|
end
|