i18n-translators-tools 0.2.2 → 0.2.3
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/README.md +44 -7
- data/bin/i18n-translate +34 -10
- data/i18n-translators-tools.gemspec +12 -5
- data/lib/i18n/backend/translate.rb +3 -1
- data/lib/i18n/processor.rb +32 -9
- data/lib/i18n/translate.rb +12 -1
- data/test/backend.rb +4 -0
- data/test/locale/src/default.yml +2 -0
- metadata +15 -8
data/README.md
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
I18n translation and locales management utility
|
2
2
|
===============================================
|
3
3
|
|
4
|
-
This package brings you useful utility which can help you to handle
|
5
|
-
and translations in your Ruby projects.
|
4
|
+
This package brings you useful utility and library which can help you to handle
|
5
|
+
locale files and translations in your Ruby projects.
|
6
6
|
|
7
7
|
|
8
8
|
Interesting features
|
@@ -11,7 +11,7 @@ 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 default file
|
14
|
+
* creating new locale file based on default file
|
15
15
|
* converting from one format to another (yml <=> rb <=> po <=> ts <=> properties)
|
16
16
|
* statistics
|
17
17
|
* built-in simple console translator
|
@@ -58,6 +58,35 @@ WARNING
|
|
58
58
|
put all your rules to separate file and use exclude (repeatable) argument
|
59
59
|
or create configuration file for your project in locales directory including
|
60
60
|
exclude array.
|
61
|
+
* **in your set of keys in leaf can't be ALL keys reserved words**
|
62
|
+
this is ok:
|
63
|
+
|
64
|
+
en:
|
65
|
+
my:
|
66
|
+
key:
|
67
|
+
message: "some message"
|
68
|
+
reference: "http://..."
|
69
|
+
|
70
|
+
but this is NOT
|
71
|
+
|
72
|
+
en:
|
73
|
+
my:
|
74
|
+
key:
|
75
|
+
reference: "http://..."
|
76
|
+
|
77
|
+
**Reserved keywords are: **
|
78
|
+
* comment
|
79
|
+
* default
|
80
|
+
* extracted_comment
|
81
|
+
* file
|
82
|
+
* flag
|
83
|
+
* fuzzy
|
84
|
+
* line
|
85
|
+
* old
|
86
|
+
* old_default
|
87
|
+
* reference
|
88
|
+
* t
|
89
|
+
* translation
|
61
90
|
* **po files are supported only partialy.** If you convert from yaml or ruby to
|
62
91
|
po and back you don't have to care even if you are using pluralization.
|
63
92
|
If you are converting from po origin files then you can lose header of the
|
@@ -105,8 +134,7 @@ can native speakers put their polished english. I think it is good thing
|
|
105
134
|
to put all default strings into separate file(s). If you need to change
|
106
135
|
some text you don't have to touch source code.
|
107
136
|
|
108
|
-
Default files
|
109
|
-
is only for locales.
|
137
|
+
_(Default files can be now in enhanced format.)_
|
110
138
|
|
111
139
|
So in your application you should do something like this:
|
112
140
|
|
@@ -136,6 +164,11 @@ untranslated strings this can fix the problem.
|
|
136
164
|
Examples
|
137
165
|
--------
|
138
166
|
|
167
|
+
**Simple conversion from one file format to another:**
|
168
|
+
|
169
|
+
$> i18n-translate cze.yml cze.po
|
170
|
+
$> i18n-translate cze.po cze.properties
|
171
|
+
|
139
172
|
Suppose we have our locales in 'locale/' directory without sub-directories and
|
140
173
|
default values are inside 'locale/default.yml' file. And we have two files
|
141
174
|
with locales 'locale/de_DE.yml', 'locale/cs_CZ.yml' and 'locale/extra/cs_CZ.yml'
|
@@ -237,6 +270,10 @@ New format looks like:
|
|
237
270
|
old_default: "old default string"
|
238
271
|
default: "new default string"
|
239
272
|
comment: "translator's comments"
|
273
|
+
extracted_comment: "po extracted comment"
|
274
|
+
reference: "po's reference"
|
275
|
+
file: "file parsed from reference"
|
276
|
+
line: "line parsed from po reference"
|
240
277
|
translation: "translation itself"
|
241
278
|
flag: "one of (ok || incomplete || changed || untranslated)"
|
242
279
|
fuzzy: true # exists only where flag != ok (nice to have when you want
|
@@ -258,8 +295,8 @@ Pluralized variant should look like:
|
|
258
295
|
|
259
296
|
As you can see the old format is string and the new format is hash.
|
260
297
|
If you use lambdas and procs objects, you should save them in separate
|
261
|
-
file(s) because i18n-translate utility can't
|
262
|
-
can.
|
298
|
+
file(s) in different (sub)directory because i18n-translate utility can't
|
299
|
+
handle them but Translate backend can.
|
263
300
|
|
264
301
|
|
265
302
|
Configure file format
|
data/bin/i18n-translate
CHANGED
@@ -82,16 +82,6 @@ CONFIG FILE
|
|
82
82
|
end
|
83
83
|
|
84
84
|
|
85
|
-
COMMANDS = %w(list stat create merge convert strip translate)
|
86
|
-
command = ARGV.shift
|
87
|
-
|
88
|
-
unless COMMANDS.include?(command)
|
89
|
-
print_help()
|
90
|
-
exit
|
91
|
-
end
|
92
|
-
|
93
|
-
|
94
|
-
|
95
85
|
begin
|
96
86
|
require 'rubygems'
|
97
87
|
rescue
|
@@ -101,6 +91,40 @@ require 'i18n'
|
|
101
91
|
require 'i18n-translate'
|
102
92
|
|
103
93
|
|
94
|
+
# converts from one file format to another
|
95
|
+
def convert(src, trg)
|
96
|
+
fname = File.basename(src)
|
97
|
+
tfname = File.basename(trg)
|
98
|
+
lang, format = $1, $2 if fname =~ /(.*)\.([^\.]*)$/
|
99
|
+
raise "bad file name '#{src}'" unless lang and format
|
100
|
+
tlang, tformat = $1, $2 if fname =~ /(.*)\.([^\.]*)$/
|
101
|
+
raise "bad file name '#{src}'" unless tlang and tformat
|
102
|
+
|
103
|
+
dir = File.dirname(src)
|
104
|
+
opts = {:locale_dir => dir, :locale => lang, :format => format, :default => lang}
|
105
|
+
tr = I18n::Translate::Translate.new(lang, opts)
|
106
|
+
data = {tlang => tr.target}
|
107
|
+
I18n::Translate::Processor.write(trg, data, tr)
|
108
|
+
end
|
109
|
+
|
110
|
+
|
111
|
+
COMMANDS = %w(list stat create merge convert strip translate)
|
112
|
+
command = ARGV.shift
|
113
|
+
|
114
|
+
unless COMMANDS.include?(command)
|
115
|
+
if (ARGV.size == 1) and File.exists?(command)
|
116
|
+
if File.exists?(ARGV[0])
|
117
|
+
puts "!!! convert fails: file #{ARGV[0]} exists"
|
118
|
+
exit
|
119
|
+
end
|
120
|
+
convert(command, ARGV[0])
|
121
|
+
exit
|
122
|
+
end
|
123
|
+
print_help()
|
124
|
+
exit
|
125
|
+
end
|
126
|
+
|
127
|
+
|
104
128
|
def process_locale(tr, command, opts)
|
105
129
|
options = opts.dup
|
106
130
|
options.delete(:quiet) if command == 'list'
|
@@ -13,7 +13,7 @@ spec = Gem::Specification.new do |s|
|
|
13
13
|
s.email = "pejuko@gmail.com"
|
14
14
|
s.authors = ["Petr Kovar"]
|
15
15
|
s.name = 'i18n-translators-tools'
|
16
|
-
s.version = '0.2.
|
16
|
+
s.version = '0.2.3'
|
17
17
|
s.date = Time.now.strftime("%Y-%m-%d")
|
18
18
|
s.add_dependency('i18n', '>= 0.4.1')
|
19
19
|
s.add_dependency('ya2yaml')
|
@@ -61,6 +61,12 @@ Changelog:
|
|
61
61
|
* fix: for default format autodetection works again
|
62
62
|
* merge can be more verbose
|
63
63
|
|
64
|
+
v0.2.3
|
65
|
+
* fix: hash_to_keys can work with enhanced format => default can be in
|
66
|
+
enchanced format
|
67
|
+
* i18n-translate <source file> <target file>
|
68
|
+
automaticlay perform convert action from one file to another
|
69
|
+
|
64
70
|
For more information read README.md and CHANGELOG.md
|
65
71
|
|
66
72
|
-----------------------------------------------------------------------------
|
@@ -70,10 +76,11 @@ http://github.com/pejuko/i18n-translators-tools
|
|
70
76
|
=============================================================================
|
71
77
|
EOF
|
72
78
|
s.description = <<EOF
|
73
|
-
This package brings you useful utility which can help you to handle
|
74
|
-
and translations in your Ruby projects. Offers also built-in simple
|
75
|
-
Supported formats are YAML, Ruby, Gettext po, QT Linguist TS and
|
76
|
-
Read README.md file and run i18n-translate without parameters
|
79
|
+
This package brings you useful utility and library which can help you to handle
|
80
|
+
locale files and translations in your Ruby projects. Offers also built-in simple
|
81
|
+
console editor. Supported formats are YAML, Ruby, Gettext po, QT Linguist TS and
|
82
|
+
Java Properties. Read README.md file and run i18n-translate without parameters
|
83
|
+
for more information.
|
77
84
|
EOF
|
78
85
|
end
|
79
86
|
|
@@ -21,9 +21,11 @@ module I18n
|
|
21
21
|
result = super(locale, key, options)
|
22
22
|
return nil if result.kind_of?(String) and result.empty?
|
23
23
|
return result unless result.kind_of?(Hash)
|
24
|
-
return nil unless result[:t] or result[:translation]
|
24
|
+
return nil unless result[:t] or result[:translation] or result[:default]
|
25
25
|
|
26
26
|
tr = result[:translation] || result[:t]
|
27
|
+
tr = result[:default] if tr.to_s.empty?
|
28
|
+
|
27
29
|
return nil if tr.to_s.empty?
|
28
30
|
|
29
31
|
values = options.except(*I18n::Backend::Base::RESERVED_KEYS)
|
data/lib/i18n/processor.rb
CHANGED
@@ -12,10 +12,12 @@ module I18n::Translate
|
|
12
12
|
attr_reader :processors
|
13
13
|
end
|
14
14
|
|
15
|
+
# append processor to the registry
|
15
16
|
def self.<<(processor)
|
16
17
|
@processors << processor
|
17
18
|
end
|
18
19
|
|
20
|
+
# find processor for fname and use it to read data
|
19
21
|
def self.read(fname, tr)
|
20
22
|
processor = find_processor(fname)
|
21
23
|
raise "Unknown file format" unless processor
|
@@ -23,6 +25,7 @@ module I18n::Translate
|
|
23
25
|
worker.read
|
24
26
|
end
|
25
27
|
|
28
|
+
# find processor for fname and use it to save data
|
26
29
|
def self.write(fname, data, tr)
|
27
30
|
processor = find_processor(fname)
|
28
31
|
raise "Unknown file format `#{fname}'" unless processor
|
@@ -30,6 +33,7 @@ module I18n::Translate
|
|
30
33
|
worker.write(data)
|
31
34
|
end
|
32
35
|
|
36
|
+
# find appropriate processor for given file name
|
33
37
|
def self.find_processor(fname)
|
34
38
|
@processors.each do |processor|
|
35
39
|
return processor if processor.can_handle?(fname)
|
@@ -37,6 +41,7 @@ module I18n::Translate
|
|
37
41
|
nil
|
38
42
|
end
|
39
43
|
|
44
|
+
# register formats from all known processors
|
40
45
|
def self.init(default='yml')
|
41
46
|
@processors.each do |processor|
|
42
47
|
processor.register(default)
|
@@ -44,15 +49,19 @@ module I18n::Translate
|
|
44
49
|
end
|
45
50
|
|
46
51
|
|
52
|
+
# this is abstract class for processors. processors should mainly implement
|
53
|
+
# protected methdos import and export
|
47
54
|
class Template
|
48
55
|
FORMAT = []
|
49
56
|
|
57
|
+
# register new processor
|
50
58
|
def self.inherited(processor)
|
51
59
|
Processor << processor
|
52
60
|
end
|
53
61
|
|
54
62
|
attr_reader :filename, :translate
|
55
63
|
|
64
|
+
# initialize new processor
|
56
65
|
def initialize(fname, tr)
|
57
66
|
@filename = fname
|
58
67
|
@translate = tr
|
@@ -60,6 +69,7 @@ module I18n::Translate
|
|
60
69
|
@lang = $1.to_s.strip
|
61
70
|
end
|
62
71
|
|
72
|
+
# register proessors's formats
|
63
73
|
def self.register(default='yml')
|
64
74
|
self::FORMAT.each do |format|
|
65
75
|
unless I18n::Translate::FORMATS.include?(format)
|
@@ -73,6 +83,7 @@ module I18n::Translate
|
|
73
83
|
end
|
74
84
|
end
|
75
85
|
|
86
|
+
# read file into hash
|
76
87
|
def read
|
77
88
|
data = File.open(@filename, mode("r")) do |f|
|
78
89
|
f.flock File::LOCK_SH
|
@@ -81,6 +92,7 @@ module I18n::Translate
|
|
81
92
|
import(data)
|
82
93
|
end
|
83
94
|
|
95
|
+
# write hash to file
|
84
96
|
def write(data)
|
85
97
|
File.open(@filename, mode("w")) do |f|
|
86
98
|
f.flock File::LOCK_EX
|
@@ -88,6 +100,7 @@ module I18n::Translate
|
|
88
100
|
end
|
89
101
|
end
|
90
102
|
|
103
|
+
# check if processor can handle this file
|
91
104
|
def self.can_handle?(fname)
|
92
105
|
fname =~ %r{\.([^\.]+)$}i
|
93
106
|
self::FORMAT.include?($1)
|
@@ -95,14 +108,17 @@ module I18n::Translate
|
|
95
108
|
|
96
109
|
protected
|
97
110
|
|
111
|
+
# converts raw data from file to hash
|
98
112
|
def import(data)
|
99
113
|
data
|
100
114
|
end
|
101
115
|
|
116
|
+
# converts hash to raw
|
102
117
|
def export(data)
|
103
118
|
data
|
104
119
|
end
|
105
120
|
|
121
|
+
# converts inspected string back into normal string
|
106
122
|
def uninspect(str)
|
107
123
|
return nil unless str
|
108
124
|
str.gsub(%r!\\([\\#"abefnrstvx]|u\d{4}|u\{[^\}]+\}|\d{1,3}|x\d{1,2}|cx|C-[a-zA-Z]|M-[a-zA-Z])!) do |m|
|
@@ -116,22 +132,29 @@ module I18n::Translate
|
|
116
132
|
end
|
117
133
|
end
|
118
134
|
|
119
|
-
# convert old
|
135
|
+
# convert old, t shorthand fields
|
120
136
|
def migrate(data)
|
121
137
|
keys = I18n::Translate.hash_to_keys(data, @translate.options[:separator])
|
122
138
|
keys.each do |key|
|
123
|
-
|
124
|
-
next unless
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
139
|
+
entry = I18n::Translate.find(key, data, @translate.options[:separator])
|
140
|
+
next unless I18n::Translate.is_enhanced?(entry)
|
141
|
+
%w(old t).each do |prop|
|
142
|
+
next unless entry[prop]
|
143
|
+
value = entry.delete(prop)
|
144
|
+
prop = case(prop)
|
145
|
+
when "old"
|
146
|
+
"old_default"
|
147
|
+
when "t"
|
148
|
+
"translation"
|
149
|
+
end
|
150
|
+
entry[prop] = value
|
151
|
+
end
|
152
|
+
I18n::Translate.set(key, entry, data, @translate.options[:separator])
|
131
153
|
end
|
132
154
|
data
|
133
155
|
end
|
134
156
|
|
157
|
+
# in ruby 1.9 it sets encoding for opening IOs
|
135
158
|
def mode(m)
|
136
159
|
mode = m.dup
|
137
160
|
mode << ":" << @translate.options[:encoding] if defined?(Encoding)
|
data/lib/i18n/translate.rb
CHANGED
@@ -53,6 +53,7 @@ module I18n::Translate
|
|
53
53
|
# function I18n::Translate::Processor.init will register known
|
54
54
|
# formats
|
55
55
|
FORMATS = %w() # the first one is preferred if :format => auto
|
56
|
+
RESERVED_WORDS = %w(comment extracted_comment reference file line default old_default fuzzy flag translation old t)
|
56
57
|
|
57
58
|
# read configuration file
|
58
59
|
# config format is ruby file which returns hash
|
@@ -60,12 +61,22 @@ module I18n::Translate
|
|
60
61
|
eval File.read(filename)
|
61
62
|
end
|
62
63
|
|
64
|
+
# checks if all keys are reserved keywords
|
65
|
+
def self.is_enhanced?(hash)
|
66
|
+
return false unless hash.kind_of?(Hash)
|
67
|
+
hash.keys.each do |key|
|
68
|
+
return false unless I18n::Translate::RESERVED_WORDS.include?(key)
|
69
|
+
end
|
70
|
+
true
|
71
|
+
end
|
72
|
+
|
63
73
|
# returns flat array of all keys e.g. ["system.message.ok", "system.message.error", ...]
|
64
74
|
def self.hash_to_keys(hash, separator=".", prefix="")
|
65
75
|
res = []
|
66
76
|
hash.keys.each do |key|
|
67
77
|
str = prefix.empty? ? key : "#{prefix}#{separator}#{key}"
|
68
|
-
|
78
|
+
enhanced = I18n::Translate.is_enhanced?(hash[key])
|
79
|
+
if hash[key].kind_of?(Hash) and (not enhanced)
|
69
80
|
str = hash_to_keys( hash[key], separator, str )
|
70
81
|
end
|
71
82
|
res << str
|
data/test/backend.rb
CHANGED
data/test/locale/src/default.yml
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: i18n-translators-tools
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 17
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 2
|
9
|
-
-
|
10
|
-
version: 0.2.
|
9
|
+
- 3
|
10
|
+
version: 0.2.3
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Petr Kovar
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-07-
|
18
|
+
date: 2010-07-30 00:00:00 +02:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -49,10 +49,11 @@ dependencies:
|
|
49
49
|
type: :runtime
|
50
50
|
version_requirements: *id002
|
51
51
|
description: |
|
52
|
-
This package brings you useful utility which can help you to handle
|
53
|
-
and translations in your Ruby projects. Offers also built-in simple
|
54
|
-
Supported formats are YAML, Ruby, Gettext po, QT Linguist TS and
|
55
|
-
Read README.md file and run i18n-translate without parameters
|
52
|
+
This package brings you useful utility and library which can help you to handle
|
53
|
+
locale files and translations in your Ruby projects. Offers also built-in simple
|
54
|
+
console editor. Supported formats are YAML, Ruby, Gettext po, QT Linguist TS and
|
55
|
+
Java Properties. Read README.md file and run i18n-translate without parameters
|
56
|
+
for more information.
|
56
57
|
|
57
58
|
email: pejuko@gmail.com
|
58
59
|
executables:
|
@@ -147,6 +148,12 @@ post_install_message: |
|
|
147
148
|
* fix: for default format autodetection works again
|
148
149
|
* merge can be more verbose
|
149
150
|
|
151
|
+
v0.2.3
|
152
|
+
* fix: hash_to_keys can work with enhanced format => default can be in
|
153
|
+
enchanced format
|
154
|
+
* i18n-translate <source file> <target file>
|
155
|
+
automaticlay perform convert action from one file to another
|
156
|
+
|
150
157
|
For more information read README.md and CHANGELOG.md
|
151
158
|
|
152
159
|
-----------------------------------------------------------------------------
|