i18n-translators-tools 0.1.1 → 0.2

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -11,8 +11,8 @@ Interesting features
11
11
  * no database required
12
12
  * merging and changes propagation (adding, removing and changed default text)
13
13
  keeping default file untouched
14
- * creating new locale file based on another (usually default) file
15
- * converting from one format to another (yml <=> rb <=> po)
14
+ * creating new locale file based default file
15
+ * converting from one format to another (yml <=> rb <=> po <=> ts <=> properties)
16
16
  * statistics
17
17
  * built-in simple console translator
18
18
  * support for locales split into sub-directories like:
@@ -61,14 +61,18 @@ WARNING
61
61
  * **po files are supported only partialy.** If you convert from yaml or ruby to
62
62
  po and back you don't have to care even if you are using pluralization.
63
63
  If you are converting from po origin files then you can lose header of the
64
- file, pluralization, extracted comments, some flags (fuzzy will stay) and
65
- previous-context. Strings over multiple lines are supported, however.
66
- * **po files are not compatible with I18n::Gettext.** The main purpose of
67
- enabling conversions to po files is effort to allow usage of many po editors
68
- for ruby projects. It is supposed that you will keep your files in yml (rb)
69
- and conversions will be used only for translators and then you convert it
70
- back. Then you lose nothing.
71
-
64
+ file, pluralization, some flags (fuzzy will stay) and previous-context.
65
+ Strings over multiple lines are supported, however.
66
+ * **po files are not compatible with I18n::Backend::Gettext.** The main purpose
67
+ of enabling conversions to po files is effort to allow usage of many po
68
+ editors for ruby projects. You can either keep all your files in yml and
69
+ convert them only for translators and then back or you can have default in
70
+ yml and other locales in po files. i18-translate tool will take care of it.
71
+ * **QT TS format is not fully supported.** TS format is changing with almost
72
+ every qt release so i18n-translate don't support:
73
+ * extra-po-msgid_plural, extra-po-old_msgid_plural
74
+ * extra-loc-*
75
+ * nested context
72
76
 
73
77
  Installation
74
78
  ------------
@@ -112,6 +116,7 @@ So in your application you should do something like this:
112
116
  I18n::Backend::Simple.send(:include, I18n::Backend::Fallbacks)
113
117
  I18n.default_locale = 'default'
114
118
  I18n.load_path << Dir[ File.expand_path("../locale/*.yml", __FILE__) ]
119
+ I18n.locale = 'cs'
115
120
 
116
121
  and then you can use
117
122
 
@@ -119,6 +124,14 @@ and then you can use
119
124
 
120
125
  as usual.
121
126
 
127
+ Notice that Translator have to be included BEFORE Fallbacks
128
+ otherwise the fallback will get Hash (even with empty translation)
129
+ and won't work.
130
+
131
+ It is hightly recommended to use Fallbacks backend together with
132
+ Translate. If you have experienced nil or empty translations due to
133
+ untranslated strings this can fix the problem.
134
+
122
135
 
123
136
  Examples
124
137
  --------
@@ -145,6 +158,12 @@ with locales 'locale/de_DE.yml', 'locale/cs_CZ.yml' and 'locale/extra/cs_CZ.yml'
145
158
  locale/cs_CZ.yml...65% (650/1000)
146
159
  locale/de_DE.yml...90% (900/1000)
147
160
 
161
+ **PO locales and default.yml**
162
+
163
+ $> i18n-translate merge
164
+ locale/cs_CZ.po...merged
165
+ locale/de_DE.po...merged
166
+
148
167
  **Translate more entries (built-in translator invocation):**
149
168
 
150
169
  $> i18n-translate translate -l cs_CZ
@@ -160,17 +179,43 @@ Supported formats
160
179
 
161
180
  * **po**; supported format looks like
162
181
 
163
- # there is some comment
164
- #, fuzzy, changed
165
- #| msgid Old default
166
- msgctxt "there.is.some.key"
167
- msgid "Default text"
168
- msgstr "Prelozeny defaultni text"
182
+ # there is some comment
183
+ #. extracted-comment
184
+ #: reference
185
+ #, fuzzy, changed
186
+ #| msgid Old default
187
+ msgctxt "there.is.some.key"
188
+ msgid "Default text"
189
+ msgstr "Prelozeny defaultni text"
169
190
 
170
191
  Such po file is pretty usable with po editors.
171
192
 
193
+ To use po files you should include this backend istead of
194
+ I18n::Backend::Gettext
195
+
196
+ I18n::Backend::Simple.send(:include, I18n::Backend::PO)
197
+
198
+ This backend can also work with natural po files. Just set your app.pot
199
+ as default and then you can use it:
200
+
201
+ I18n.t("some text there")
202
+
203
+ or create alias
204
+
205
+ def _(*args); I18n.t(*args); end
206
+ _("some text there")
207
+
172
208
  * **yml**; standard yaml files in I18n simple format
173
209
  * **rb**; typical ruby files in I18n simple format
210
+ * **ts**; QT Linguist TS format. If you are planing to do translation in
211
+ qt linguist, convert to this format rather then to po. Include TS backend
212
+ if you want use this foramat for locales.
213
+
214
+ I18n::Backend::Simple.send(:include, I18n::Backend::TS)
215
+
216
+ * **properties**; support for java properties locales
217
+
218
+ I18n::Backend::Simple.send(:include, I18n::Backend::Properties)
174
219
 
175
220
 
176
221
  New locale files format
@@ -189,10 +234,10 @@ or for pluralization (depends on rules) it can be similar to this:
189
234
  New format looks like:
190
235
 
191
236
  key:
192
- old: "old default string"
237
+ old_default: "old default string"
193
238
  default: "new default string"
194
239
  comment: "translator's comments"
195
- t: "translation itself"
240
+ translation: "translation itself"
196
241
  flag: "one of (ok || incomplete || changed || untranslated)"
197
242
  fuzzy: true # exists only where flag != ok (nice to have when you want
198
243
  edit files manually)
@@ -201,14 +246,14 @@ Pluralized variant should look like:
201
246
 
202
247
  key:
203
248
  one:
204
- old:
249
+ old_default:
205
250
  default:
206
- t:
251
+ translation:
207
252
  ...
208
253
  other:
209
- old:
254
+ old_default:
210
255
  default:
211
- t:
256
+ translation:
212
257
  ...
213
258
 
214
259
  As you can see the old format is string and the new format is hash.
@@ -242,3 +287,8 @@ It is not necessary to use all switches.
242
287
 
243
288
  [1]: http://github.com/pejuko/i18n-web-translator
244
289
 
290
+
291
+ <!--
292
+ vi: filetype=mkd
293
+ -->
294
+
data/Rakefile CHANGED
@@ -2,17 +2,50 @@
2
2
  # vi: fenc=utf-8:expandtab:ts=2:sw=2:sts=2
3
3
  #
4
4
  # @author: Petr Kovar <pejuko@gmail.com>
5
+ $KCODE='UTF8'
5
6
 
6
7
  require 'rake/testtask'
7
8
  require 'rake/gempackagetask'
8
9
  require 'rake/clean'
9
10
 
10
- CLEAN << "coverage" << "pkg"
11
+ CLEAN << "coverage" << "pkg" << "README.html" << "CHANGELOG.html"
11
12
 
12
- task :default => [:test]
13
+ task :default => [:test, :doc, :gem]
13
14
  Rake::TestTask.new(:test) do |t|
14
- t.pattern = File.join(File.dirname(__FILE__), 'test/tc_*.rb')
15
+ t.pattern = File.join(File.dirname(__FILE__), 'test/all.rb')
15
16
  t.verbose = true
16
17
  end
17
18
 
18
19
  Rake::GemPackageTask.new(eval(File.read("i18n-translators-tools.gemspec"))) {|pkg|}
20
+
21
+ desc "Test with rcov"
22
+ task :rcov do |t|
23
+ system "rcov --exclude .rvm,lib/ruby --sort coverage --text-summary --text-coverage-diff -o coverage test/all.rb"
24
+ end
25
+
26
+ begin
27
+ require 'bluecloth'
28
+
29
+ def build_document(mdfile)
30
+ fname = $1 if mdfile =~ /(.*)\.md$/
31
+ raise "Unknown file type" unless fname
32
+
33
+ data = File.read(mdfile)
34
+ md = Markdown.new(data)
35
+ htmlfile = "#{fname}.html"
36
+
37
+ File.open(htmlfile, "w") { |f| f << md.to_html }
38
+ end
39
+
40
+ task :doc => [:readme, :changelog]
41
+
42
+ task :readme do |t|
43
+ build_document("README.md")
44
+ end
45
+
46
+ task :changelog do |t|
47
+ build_document("CHANGELOG.md")
48
+ end
49
+
50
+ rescue
51
+ end
@@ -6,6 +6,8 @@
6
6
 
7
7
  $KCODE="UTF8"
8
8
 
9
+ $:.unshift File.expand_path(File.join(File.dirname(__FILE__), "../lib"))
10
+
9
11
  def print_help
10
12
  print $0
11
13
  puts " <command> [options] [locale directory]"
@@ -45,6 +47,7 @@ options:
45
47
  --locale=<locale>, -l <locale> -- work with specific locale only
46
48
  e.g: create -p locale -l cs_CZ
47
49
  --deep, -r -- scan locale_dir recursively
50
+ --encoding, -e -- set encoding of files (default: utf-8)
48
51
  --quiet, -q -- show less information
49
52
  --verbose, -v -- shows more information during
50
53
  locales processing
@@ -61,7 +64,7 @@ CONFIG FILE
61
64
 
62
65
  Example:
63
66
 
64
- options = {
67
+ {
65
68
  :exclude => ['rules'],
66
69
  :verbose => true,
67
70
  :format => 'yml',
@@ -149,6 +152,7 @@ opts = GetoptLong.new(
149
152
  ["--separator", "-s", GetoptLong::REQUIRED_ARGUMENT],
150
153
  ["--target", "-t", GetoptLong::REQUIRED_ARGUMENT],
151
154
  ["--deep", "-r", GetoptLong::NO_ARGUMENT],
155
+ ["--encoding", "-e", GetoptLong::REQUIRED_ARGUMENT],
152
156
  ["--verbose", "-v", GetoptLong::NO_ARGUMENT],
153
157
  ["--quiet", "-q", GetoptLong::NO_ARGUMENT],
154
158
  ["--locale", "-l", GetoptLong::REQUIRED_ARGUMENT]
@@ -158,7 +162,7 @@ opts = GetoptLong.new(
158
162
  # setting up default options
159
163
  user_config_file = File.join(ENV["HOME"], ".config/ruby/i18n-translate")
160
164
  options = I18n::Translate::Translate::DEFAULT_OPTIONS.dup
161
- options.merge!(eval( File.read(user_config_file) )) if File.exists?(user_config_file)
165
+ options.merge!(I18n::Translate.read_config(user_config_file)) if File.exists?(user_config_file)
162
166
  options[:exclude] ||= []
163
167
 
164
168
 
@@ -195,7 +199,7 @@ end
195
199
  locale_dir = tmp[:locale_dir] ? tmp[:locale_dir] : options[:locale_dir]
196
200
  # reading project locale config options
197
201
  locale_config_file = File.join(locale_dir, ".i18n-translate")
198
- options.merge!(eval( File.read(locale_config_file) )) if File.exists?(locale_config_file)
202
+ options.merge!(I18n::Translate.read_config(locale_config_file)) if File.exists?(locale_config_file)
199
203
 
200
204
  # merge command line arguments
201
205
  options.merge!(tmp)
@@ -219,9 +223,7 @@ when 'create'
219
223
  exit 2
220
224
  end
221
225
 
222
- tr = I18n::Translate::Translate.new(options[:locale], options.merge({:format => format}))
223
- tr.assign(tr.merge)
224
- tr.export!
226
+ tr = I18n::Translate.create_locale(options[:locale], options.merge({:format => format}))
225
227
 
226
228
  puts "#{tr.options[:locale_dir]}/#{tr.lang}...created" unless options[:quiet]
227
229
 
@@ -232,71 +234,12 @@ when 'translate'
232
234
  exit 1
233
235
  end
234
236
 
235
- tr = I18n::Translate::Translate.new(options[:locale], options)
236
- stat = tr.stat
237
- tr.merge.select{|x| x["flag"] != "ok"}.each_with_index do |entry, i|
238
- next_entry = false
239
- while not next_entry
240
- puts ""
241
- puts ""
242
- puts "(#{i+1}/#{stat[:fuzzy]}) #{entry["key"]} (#{entry["flag"]})"
243
- puts "comment: #{entry["comment"]}" unless entry["comment"].empty?
244
- puts "old default: #{entry["old_default"]}" unless entry["old_default"].empty?
245
- puts "old translation: #{entry["old_t"]}" unless entry["old_t"].empty?
246
- puts "default: #{entry["default"]}"
247
- puts "translation: #{entry["t"]}"
248
- puts ""
249
- puts "Actions:"
250
- puts "n (next) t (translate) f (change flag) c (comment) s (save) q (save & quit) x(exit no saving)"
251
- action = STDIN.readline.strip
252
- puts ""
253
- case action
254
- when 'n'
255
- next_entry = true
256
- when 't'
257
- puts "Enter translation:"
258
- entry["t"] = STDIN.readline.strip
259
- entry["flag"] = "ok" unless entry["t"].empty?
260
- tr.assign( [entry] )
261
- puts "Flag sets to #{entry["flag"]}"
262
- when 'f'
263
- puts "Change flag to:"
264
- puts "o (ok), i (incomplete), c (changed), u (untranslated)"
265
- f = STDIN.readline.strip
266
- I18n::Translate::FLAGS.each do |fname|
267
- if fname[0,1] == f
268
- entry["flag"] = fname
269
- break
270
- end
271
- end
272
- tr.assign( [entry] )
273
- puts "Flag sets to #{entry["flag"]}"
274
- when 'c'
275
- puts "Enter comment:"
276
- entry["comment"] = STDIN.readline.strip
277
- tr.assign( [entry] )
278
- puts "Comment has changed."
279
- when 's'
280
- tr.export!
281
- puts "Translation saved"
282
- when 'q'
283
- tr.export!
284
- puts "Translation saved"
285
- exit
286
- when 'x'
287
- exit
288
- end # case
289
- end # while
290
- end # each_with_index
291
-
292
- tr.export!
293
- tr.reload!
237
+ translator = I18n::Translate::Translator.new(options[:locale], options)
238
+ translator.run
239
+
294
240
  else
295
241
 
296
242
  I18n::Translate.scan(options) do |tr|
297
- # skip if not desired locale
298
- next if options[:locale] and (options[:locale] != tr.lang)
299
-
300
243
  process_locale(tr, command, options)
301
244
  end
302
245
 
@@ -9,19 +9,60 @@ require 'find'
9
9
  spec = Gem::Specification.new do |s|
10
10
  s.platform = Gem::Platform::RUBY
11
11
  s.summary = "I18n transation utility which helps to manage files with locales."
12
+ s.homepage = "http://github.com/pejuko/i18n-translators-tools"
12
13
  s.email = "pejuko@gmail.com"
13
14
  s.authors = ["Petr Kovar"]
14
15
  s.name = 'i18n-translators-tools'
15
- s.version = '0.1.1'
16
- s.date = '2010-07-17'
16
+ s.version = '0.2'
17
+ s.date = '2010-07-27'
17
18
  s.add_dependency('i18n', '>= 0.4.1')
18
19
  s.add_dependency('ya2yaml')
19
20
  s.require_path = 'lib'
20
- s.files = ["bin/i18n-translate", "test/tc_translate.rb", "test/locale/src/default.yml", "test/locale/src/cze.yml", "test/locale/src/cze.rb", "test/locale/src/cze.po", "lib/i18n-translate.rb", "lib/i18n/translate.rb", "lib/i18n/processor.rb", "lib/i18n/processor/yaml.rb", "lib/i18n/processor/ruby.rb", "lib/i18n/processor/gettext.rb", "lib/i18n/backend/translate.rb", "README.md", "i18n-translators-tools.gemspec", "Rakefile"]
21
+ s.files = ["bin/i18n-translate", "README.md", "i18n-translators-tools.gemspec", "Rakefile"]
22
+ s.files += Dir["lib/**/*.rb", "test/**/*.{rb,yml,po}"]
21
23
  s.executables = ["i18n-translate"]
24
+ s.post_install_message = <<EOF
25
+ =======================================================================
26
+
27
+ I18N TRANSLATORS TOOLS
28
+
29
+ -----------------------------------------------------------------------
30
+
31
+ Supported formats:
32
+ * yml
33
+ * rb
34
+ * ts
35
+ * po
36
+ * properties
37
+
38
+ Backends:
39
+ * Extended format. i18n-translators-tools bring extended format
40
+ I18n::Backend::Simple.send(:include, I18n::Backend::Translator)
41
+ * Gettext po
42
+ I18n::Backend::Simple.send(:include, I18n::Backend::PO)
43
+ * QT Linguist TS
44
+ I18n::Backend::Simple.send(:include, I18n::Backend::TS)
45
+ * Java Properties files
46
+ I18n::Backend::Simple.send(:include, I18n::Backend::Properties)
47
+
48
+ Functions:
49
+ * merge
50
+ * convert
51
+ * translate (built-in simple console translator)
52
+ * statistics
53
+
54
+ For more information read README.md and CHANGELOG.md
55
+
56
+ -----------------------------------------------------------------------
57
+
58
+ http://github.com/pejuko/i18n-translators-tools
59
+
60
+ =======================================================================
61
+ EOF
22
62
  s.description = <<EOF
23
63
  This package brings you useful utility which can help you to handle locale files
24
64
  and translations in your Ruby projects. Offers also built-in simple console editor.
65
+ Supported formats are YAML, Ruby, Gettext po, QT Linguist TS and Java Properties.
25
66
  Read README.md file and run i18n-translate without parameters for more information.
26
67
  EOF
27
68
  end
@@ -9,5 +9,10 @@ dir = File.expand_path(File.dirname(__FILE__))
9
9
  $:.unshift(dir) unless $:.include?(dir)
10
10
 
11
11
  require 'i18n/backend/translate'
12
+ require 'i18n/backend/po'
13
+ require 'i18n/backend/ts'
14
+ require 'i18n/backend/properties'
12
15
  require 'i18n/translate'
16
+ require 'i18n/processor'
17
+ require 'i18n/translator'
13
18
 
@@ -0,0 +1,20 @@
1
+ # -*- coding: utf-8 -*-
2
+ # vi: fenc=utf-8:expandtab:ts=2:sw=2:sts=2
3
+ #
4
+ # @author: Petr Kovar <pejuko@gmail.com>
5
+
6
+ module I18n::Backend
7
+
8
+ # to use po files generated (e.g: by merge) by i18n-translate you should
9
+ # include this backend istead of I18n::Backend::Gettext
10
+ #
11
+ # I18n::Backend::Simple.send(:include, I18n::Backend::PO)
12
+ module PO
13
+ protected
14
+ def load_po(fname)
15
+ locale = ::File.basename(fname, '.po')
16
+ tr = I18n::Translate::Translate.new(locale, {:empty => true})
17
+ data = I18n::Translate::Processor::Gettext.new(fname, tr).read
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,19 @@
1
+ # -*- coding: utf-8 -*-
2
+ # vi: fenc=utf-8:expandtab:ts=2:sw=2:sts=2
3
+ #
4
+ # @author: Petr Kovar <pejuko@gmail.com>
5
+
6
+ module I18n::Backend
7
+
8
+ # to use Java properties files you should just include this backend
9
+ #
10
+ # I18n::Backend::Simple.send(:include, I18n::Backend::Properties)
11
+ module Properties
12
+ protected
13
+ def load_properties(fname)
14
+ locale = ::File.basename(fname, '.properties')
15
+ tr = I18n::Translate::Translate.new(locale, {:empty => true})
16
+ data = I18n::Translate::Processor::Properties.new(fname, tr).read
17
+ end
18
+ end
19
+ end