translatomatic 0.1.1 → 0.1.2
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.
- checksums.yaml +4 -4
- data/.gitattributes +19 -0
- data/.gitignore +0 -0
- data/.travis.yml +7 -7
- data/.yardopts +9 -0
- data/Gemfile +4 -4
- data/Guardfile +0 -0
- data/README.de.md +61 -16
- data/README.es.md +60 -15
- data/README.fr.md +61 -16
- data/README.it.md +60 -15
- data/README.ja.md +59 -14
- data/README.ko.md +137 -0
- data/README.md +58 -13
- data/README.ms.md +137 -0
- data/README.pt.md +137 -0
- data/README.ru.md +137 -0
- data/README.sv.md +137 -0
- data/README.zh.md +137 -0
- data/bin/setup +8 -8
- data/bin/translatomatic +6 -6
- data/bin/travis +1 -1
- data/config/locales/translatomatic/de.yml +104 -0
- data/config/locales/translatomatic/en.yml +101 -0
- data/config/locales/translatomatic/es.yml +105 -0
- data/config/locales/translatomatic/fr.yml +105 -0
- data/config/locales/translatomatic/it.yml +103 -0
- data/config/locales/translatomatic/ja.yml +102 -0
- data/config/locales/translatomatic/ko.yml +101 -0
- data/config/locales/translatomatic/ms.yml +103 -0
- data/config/locales/translatomatic/pt.yml +105 -0
- data/config/locales/translatomatic/ru.yml +103 -0
- data/config/locales/translatomatic/sv.yml +103 -0
- data/config/locales/translatomatic/zh.yml +102 -0
- data/db/migrate/201712170000_initial.rb +2 -1
- data/lib/translatomatic/cli/base.rb +73 -0
- data/lib/translatomatic/cli/common_options.rb +14 -0
- data/lib/translatomatic/cli/config.rb +81 -0
- data/lib/translatomatic/cli/database.rb +29 -0
- data/lib/translatomatic/cli/main.rb +112 -0
- data/lib/translatomatic/cli/translate.rb +146 -0
- data/lib/translatomatic/cli.rb +8 -216
- data/lib/translatomatic/config.rb +143 -0
- data/lib/translatomatic/converter.rb +196 -149
- data/lib/translatomatic/converter_stats.rb +18 -14
- data/lib/translatomatic/database.rb +35 -37
- data/lib/translatomatic/escaped_unicode.rb +1 -1
- data/lib/translatomatic/extractor/base.rb +2 -0
- data/lib/translatomatic/extractor/ruby.rb +1 -0
- data/lib/translatomatic/extractor.rb +1 -0
- data/lib/translatomatic/http_request.rb +43 -14
- data/lib/translatomatic/locale.rb +28 -4
- data/lib/translatomatic/logger.rb +21 -13
- data/lib/translatomatic/model/locale.rb +5 -1
- data/lib/translatomatic/model/text.rb +2 -0
- data/lib/translatomatic/model.rb +1 -0
- data/lib/translatomatic/option.rb +75 -10
- data/lib/translatomatic/progress_updater.rb +7 -3
- data/lib/translatomatic/resource_file/base.rb +41 -18
- data/lib/translatomatic/resource_file/html.rb +11 -14
- data/lib/translatomatic/resource_file/markdown.rb +13 -12
- data/lib/translatomatic/resource_file/plist.rb +3 -14
- data/lib/translatomatic/resource_file/properties.rb +21 -3
- data/lib/translatomatic/resource_file/resw.rb +1 -0
- data/lib/translatomatic/resource_file/text.rb +1 -0
- data/lib/translatomatic/resource_file/xcode_strings.rb +23 -14
- data/lib/translatomatic/resource_file/xml.rb +34 -22
- data/lib/translatomatic/resource_file/yaml.rb +39 -5
- data/lib/translatomatic/resource_file.rb +7 -5
- data/lib/translatomatic/string.rb +40 -12
- data/lib/translatomatic/tmx/document.rb +11 -12
- data/lib/translatomatic/tmx/translation_unit.rb +5 -1
- data/lib/translatomatic/tmx.rb +2 -0
- data/lib/translatomatic/translation.rb +30 -0
- data/lib/translatomatic/translation_result.rb +45 -45
- data/lib/translatomatic/translator/base.rb +128 -83
- data/lib/translatomatic/translator/frengly.rb +62 -57
- data/lib/translatomatic/translator/google.rb +35 -31
- data/lib/translatomatic/translator/microsoft.rb +41 -33
- data/lib/translatomatic/translator/my_memory.rb +68 -64
- data/lib/translatomatic/translator/yandex.rb +56 -39
- data/lib/translatomatic/translator.rb +99 -63
- data/lib/translatomatic/util.rb +31 -1
- data/lib/translatomatic/version.rb +4 -1
- data/lib/translatomatic.rb +17 -0
- data/translatomatic.gemspec +5 -4
- metadata +56 -16
@@ -1,6 +1,8 @@
|
|
1
1
|
require 'date'
|
2
2
|
|
3
3
|
module Translatomatic::ResourceFile
|
4
|
+
# Properties resource file
|
5
|
+
# @see https://docs.oracle.com/javase/tutorial/essential/environment/properties.html
|
4
6
|
class Properties < Base
|
5
7
|
|
6
8
|
# (see Translatomatic::ResourceFile::Base.extensions)
|
@@ -21,7 +23,7 @@ module Translatomatic::ResourceFile
|
|
21
23
|
out += add_created_by unless options[:no_created_by]
|
22
24
|
properties.each do |key, value|
|
23
25
|
# TODO: maintain original line ending format?
|
24
|
-
value = value.gsub("\n", "\\n") # convert newlines to \n
|
26
|
+
value = value.gsub("\n", "\\n") if value # convert newlines to \n
|
25
27
|
out += "#{key} = #{value}\n"
|
26
28
|
end
|
27
29
|
# escape unicode characters
|
@@ -29,6 +31,21 @@ module Translatomatic::ResourceFile
|
|
29
31
|
target.write(out)
|
30
32
|
end
|
31
33
|
|
34
|
+
# (see Translatomatic::ResourceFile::Base#supports_variable_interpolation?)
|
35
|
+
def supports_variable_interpolation?
|
36
|
+
true
|
37
|
+
end
|
38
|
+
|
39
|
+
# (see Translatomatic::ResourceFile::Base#create_variable)
|
40
|
+
def create_variable(name)
|
41
|
+
return "{#{name}}"
|
42
|
+
end
|
43
|
+
|
44
|
+
# (see Translatomatic::ResourceFile::Base#variable_regex)
|
45
|
+
def variable_regex
|
46
|
+
/\{.*?\}/
|
47
|
+
end
|
48
|
+
|
32
49
|
private
|
33
50
|
|
34
51
|
def add_created_by
|
@@ -52,16 +69,17 @@ module Translatomatic::ResourceFile
|
|
52
69
|
line.strip!
|
53
70
|
next if line.length == 0
|
54
71
|
equal_idx = line.index("=")
|
72
|
+
colon_idx = line.index(":")
|
55
73
|
|
56
74
|
if line[0] == ?! || line[0] == ?#
|
57
75
|
# comment
|
58
76
|
# TODO: translate comments or keep originals?
|
59
77
|
next
|
60
|
-
elsif equal_idx.nil?
|
78
|
+
elsif equal_idx.nil? && colon_idx.nil?
|
61
79
|
@valid = false
|
62
80
|
return {}
|
63
81
|
end
|
64
|
-
name, value = line.split(/\s
|
82
|
+
name, value = line.split(/\s*[=:]\s*/, 2)
|
65
83
|
value = value.gsub("\\n", "\n") # convert \n to newlines
|
66
84
|
result[name] = value
|
67
85
|
end
|
@@ -1,8 +1,26 @@
|
|
1
1
|
module Translatomatic::ResourceFile
|
2
2
|
|
3
|
-
#
|
3
|
+
# @!visibility private
|
4
|
+
module XCodeStringsLocalePath
|
5
|
+
|
6
|
+
# (see Translatomatic::ResourceFile::Base#locale_path)
|
7
|
+
# @note localization files in XCode use the following file name
|
8
|
+
# convention: Project/locale.lproj/filename
|
9
|
+
def locale_path(locale)
|
10
|
+
if path.to_s.match(/\/([-\w]+).lproj\/.+$/)
|
11
|
+
# xcode style
|
12
|
+
filename = path.basename
|
13
|
+
path.parent.parent + (locale.to_s + ".lproj") + filename
|
14
|
+
else
|
15
|
+
super(locale)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# XCode strings resource file
|
4
21
|
# @see https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/LoadingResources/Strings/Strings.html
|
5
22
|
class XCodeStrings < Base
|
23
|
+
include Translatomatic::ResourceFile::XCodeStringsLocalePath
|
6
24
|
|
7
25
|
# (see Translatomatic::ResourceFile::Base.extensions)
|
8
26
|
def self.extensions
|
@@ -16,19 +34,6 @@ module Translatomatic::ResourceFile
|
|
16
34
|
@properties = @path.exist? ? read(@path) : {}
|
17
35
|
end
|
18
36
|
|
19
|
-
# (see Translatomatic::ResourceFile::Base#locale_path)
|
20
|
-
# @note localization files in XCode use the following file name
|
21
|
-
# convention: Project/locale.lproj/filename
|
22
|
-
def locale_path(locale)
|
23
|
-
if path.to_s.match(/\/([-\w]+).lproj\/.+.strings$/)
|
24
|
-
# xcode style
|
25
|
-
filename = path.basename
|
26
|
-
path.parent.parent + (locale.to_s + ".lproj") + filename
|
27
|
-
else
|
28
|
-
super(locale)
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
37
|
# (see Translatomatic::ResourceFile::Base#save)
|
33
38
|
def save(target = path, options = {})
|
34
39
|
out = ""
|
@@ -56,6 +61,10 @@ module Translatomatic::ResourceFile
|
|
56
61
|
key, value = entry
|
57
62
|
result[unescape(key)] = unescape(value)
|
58
63
|
end
|
64
|
+
|
65
|
+
if uncommented.strip.length > 0 && key_values.length == 0
|
66
|
+
@valid = false
|
67
|
+
end
|
59
68
|
result
|
60
69
|
end
|
61
70
|
|
@@ -1,4 +1,5 @@
|
|
1
1
|
module Translatomatic::ResourceFile
|
2
|
+
# XML resource file
|
2
3
|
class XML < Base
|
3
4
|
|
4
5
|
# (see Translatomatic::ResourceFile::Base.extensions)
|
@@ -9,7 +10,8 @@ module Translatomatic::ResourceFile
|
|
9
10
|
# (see Translatomatic::ResourceFile::Base#initialize)
|
10
11
|
def initialize(path, locale = nil)
|
11
12
|
super(path, locale)
|
12
|
-
@valid = true
|
13
|
+
@valid = true
|
14
|
+
@nodemap = {}
|
13
15
|
@properties = @path.exist? ? read(@path) : {}
|
14
16
|
end
|
15
17
|
|
@@ -20,26 +22,36 @@ module Translatomatic::ResourceFile
|
|
20
22
|
end
|
21
23
|
|
22
24
|
# (see Translatomatic::ResourceFile::Base#save)
|
23
|
-
def save(target = path, options = {})
|
24
|
-
if @doc
|
25
|
+
def save(target = path, options = {})
|
26
|
+
if @doc
|
25
27
|
add_created_by unless options[:no_created_by]
|
26
|
-
target.write(@doc.to_xml)
|
28
|
+
target.write(@doc.to_xml)
|
27
29
|
end
|
28
30
|
end
|
29
31
|
|
30
|
-
private
|
31
|
-
|
32
|
-
def comment(text)
|
33
|
-
@doc.create_comment(text)
|
32
|
+
private
|
33
|
+
|
34
|
+
def comment(text)
|
35
|
+
@doc.create_comment(text)
|
34
36
|
end
|
37
|
+
|
38
|
+
def add_created_by
|
39
|
+
@created_by ||= @doc.root.add_previous_sibling(comment(created_by))
|
40
|
+
end
|
35
41
|
|
36
42
|
# initialize nodemap from nokogiri document
|
37
43
|
# returns property hash
|
38
|
-
def init_nodemap(doc)
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
44
|
+
def init_nodemap(doc)
|
45
|
+
if !doc.errors.empty?
|
46
|
+
log.error(doc.errors)
|
47
|
+
@valid = false
|
48
|
+
{}
|
49
|
+
else
|
50
|
+
# map of key1 => node, key2 => node, ...
|
51
|
+
@nodemap = create_nodemap(doc)
|
52
|
+
# map of key => node content
|
53
|
+
@nodemap.transform_values { |v| v.content }
|
54
|
+
end
|
43
55
|
end
|
44
56
|
|
45
57
|
# parse xml
|
@@ -47,9 +59,9 @@ module Translatomatic::ResourceFile
|
|
47
59
|
begin
|
48
60
|
# parse xml with nokogiri
|
49
61
|
@doc = read_doc(path)
|
50
|
-
init_nodemap(@doc)
|
62
|
+
init_nodemap(@doc)
|
51
63
|
rescue Exception => e
|
52
|
-
log.error(e.message)
|
64
|
+
log.error t("resource.error", message: e.message)
|
53
65
|
@valid = false
|
54
66
|
{}
|
55
67
|
end
|
@@ -63,11 +75,11 @@ module Translatomatic::ResourceFile
|
|
63
75
|
|
64
76
|
def create_nodemap(doc)
|
65
77
|
result = {}
|
66
|
-
text_nodes = doc.search(text_nodes_xpath)
|
78
|
+
text_nodes = doc.search(text_nodes_xpath)
|
67
79
|
idx = 1
|
68
|
-
text_nodes.each do |node|
|
80
|
+
text_nodes.each do |node|
|
69
81
|
next if whitespace?(node.content)
|
70
|
-
result["key#{idx}"] = node
|
82
|
+
result["key#{idx}"] = node
|
71
83
|
idx += 1
|
72
84
|
end
|
73
85
|
result
|
@@ -75,10 +87,10 @@ module Translatomatic::ResourceFile
|
|
75
87
|
|
76
88
|
def text_nodes_xpath
|
77
89
|
'//text()'
|
78
|
-
end
|
79
|
-
|
80
|
-
def whitespace?(text)
|
81
|
-
text == nil || text.strip.length == 0
|
90
|
+
end
|
91
|
+
|
92
|
+
def whitespace?(text)
|
93
|
+
text == nil || text.strip.length == 0
|
82
94
|
end
|
83
95
|
end # class
|
84
96
|
end # module
|
@@ -1,6 +1,8 @@
|
|
1
1
|
require 'yaml'
|
2
2
|
|
3
3
|
module Translatomatic::ResourceFile
|
4
|
+
# YAML resource file
|
5
|
+
# @see http://www.yaml.org/
|
4
6
|
class YAML < Base
|
5
7
|
|
6
8
|
# (see Translatomatic::ResourceFile::Base.extensions)
|
@@ -34,7 +36,7 @@ module Translatomatic::ResourceFile
|
|
34
36
|
super(key, value)
|
35
37
|
|
36
38
|
hash = @data
|
37
|
-
path = key.split(/\./)
|
39
|
+
path = key.to_s.split(/\./)
|
38
40
|
last_key = path.pop
|
39
41
|
path.each { |i| hash = (hash[i] ||= {}) }
|
40
42
|
hash[last_key] = value
|
@@ -42,19 +44,51 @@ module Translatomatic::ResourceFile
|
|
42
44
|
|
43
45
|
# (see Translatomatic::ResourceFile::Base#save)
|
44
46
|
def save(target = path, options = {})
|
45
|
-
|
46
|
-
|
47
|
-
|
47
|
+
if @data
|
48
|
+
data = @data
|
49
|
+
data = data.transform_keys { locale.language } if ruby_i18n?
|
50
|
+
out = data.to_yaml
|
51
|
+
out.sub!(/^---\n/m, '')
|
52
|
+
out = comment(created_by) + "\n" + out unless options[:no_created_by]
|
53
|
+
target.write(out)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# (see Translatomatic::ResourceFile::Base#supports_variable_interpolation?)
|
58
|
+
def supports_variable_interpolation?
|
59
|
+
true
|
60
|
+
end
|
61
|
+
|
62
|
+
# (see Translatomatic::ResourceFile::Base#create_variable)
|
63
|
+
def create_variable(name)
|
64
|
+
return "%{#{name}}"
|
65
|
+
end
|
66
|
+
|
67
|
+
# (see Translatomatic::ResourceFile::Base#variable_regex)
|
68
|
+
def variable_regex
|
69
|
+
/\%\s*\{.*?\}/
|
48
70
|
end
|
49
71
|
|
50
72
|
private
|
51
73
|
|
74
|
+
# true if this resource file looks like a ruby i18n data file.
|
75
|
+
def ruby_i18n?
|
76
|
+
if @data && @data.length == 1
|
77
|
+
lang = @data.keys[0]
|
78
|
+
Translatomatic::Locale.new(lang).valid?
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def comment(text)
|
83
|
+
"# #{text}\n"
|
84
|
+
end
|
85
|
+
|
52
86
|
def read
|
53
87
|
begin
|
54
88
|
@data = ::YAML.load_file(@path) || {}
|
55
89
|
flatten_data(@data)
|
56
90
|
rescue Exception => e
|
57
|
-
log.error(e.message)
|
91
|
+
log.error t("resource.error", message: e.message)
|
58
92
|
@valid = false
|
59
93
|
{}
|
60
94
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
|
2
2
|
module Translatomatic
|
3
|
+
# Provides methods to create resource files of various types.
|
3
4
|
module ResourceFile
|
4
5
|
class << self
|
5
6
|
include Translatomatic::Util
|
@@ -8,8 +9,8 @@ module Translatomatic
|
|
8
9
|
# Load a resource file. If locale is not specified, the locale of the
|
9
10
|
# file will be determined from the filename, or else the current default
|
10
11
|
# locale will be used.
|
11
|
-
# @param [String]
|
12
|
-
# @param [String]
|
12
|
+
# @param path [String] Path to the resource file
|
13
|
+
# @param locale [String] Locale of the resource file
|
13
14
|
# @return [Translatomatic::ResourceFile::Base] The resource file, or nil
|
14
15
|
# if the file type is unsupported.
|
15
16
|
def self.load(path, locale = nil)
|
@@ -17,7 +18,8 @@ module Translatomatic
|
|
17
18
|
modules.each do |mod|
|
18
19
|
# match on entire filename to support extensions containing locales
|
19
20
|
if extension_match(mod, path)
|
20
|
-
log.debug("
|
21
|
+
log.debug(t("resource.loading", file: path,
|
22
|
+
name: mod.name.demodulize))
|
21
23
|
file = mod.new(path, locale)
|
22
24
|
return file if file.valid?
|
23
25
|
end
|
@@ -26,7 +28,7 @@ module Translatomatic
|
|
26
28
|
end
|
27
29
|
|
28
30
|
# Find all resource files under the given directory. Follows symlinks.
|
29
|
-
# @param [String, Pathname]
|
31
|
+
# @param path [String, Pathname] The path to search from
|
30
32
|
# @return [Array<Translatomatic::ResourceFile>] Resource files found
|
31
33
|
def self.find(path, options = {})
|
32
34
|
files = []
|
@@ -71,6 +73,6 @@ require 'translatomatic/resource_file/text'
|
|
71
73
|
require 'translatomatic/resource_file/xml'
|
72
74
|
require 'translatomatic/resource_file/html'
|
73
75
|
require 'translatomatic/resource_file/markdown'
|
76
|
+
require 'translatomatic/resource_file/xcode_strings'
|
74
77
|
require 'translatomatic/resource_file/plist'
|
75
78
|
require 'translatomatic/resource_file/resw'
|
76
|
-
require 'translatomatic/resource_file/xcode_strings'
|
@@ -1,4 +1,5 @@
|
|
1
1
|
module Translatomatic
|
2
|
+
# A string object with an associated locale.
|
2
3
|
class String
|
3
4
|
|
4
5
|
# @return [String] The string
|
@@ -16,7 +17,7 @@ module Translatomatic
|
|
16
17
|
attr_reader :offset
|
17
18
|
|
18
19
|
def initialize(value, locale, options = {})
|
19
|
-
@value = value || ''
|
20
|
+
@value = value.to_s || ''
|
20
21
|
@locale = Translatomatic::Locale.parse(locale)
|
21
22
|
@offset = options[:offset] || 0
|
22
23
|
@parent = options[:parent]
|
@@ -27,16 +28,21 @@ module Translatomatic
|
|
27
28
|
@value
|
28
29
|
end
|
29
30
|
|
31
|
+
# @return [Number] The length of the string
|
30
32
|
def length
|
31
33
|
@value.length
|
32
34
|
end
|
33
35
|
|
36
|
+
# @return [boolean] True if the string is empty
|
34
37
|
def empty?
|
35
38
|
@value.empty?
|
36
39
|
end
|
37
40
|
|
38
|
-
|
39
|
-
|
41
|
+
# Invokes value.match
|
42
|
+
# @param pattern [Regexp,String] The regex pattern to match
|
43
|
+
# @return [MatchData] Object describing the match, or nil if no match
|
44
|
+
def match(pattern)
|
45
|
+
@value.match(pattern)
|
40
46
|
end
|
41
47
|
|
42
48
|
# @return [boolean] true if this string is a substring of another string
|
@@ -58,38 +64,49 @@ module Translatomatic
|
|
58
64
|
# Find all sentences in the string
|
59
65
|
# @return [Array<Translatomatic::String] List of sentences
|
60
66
|
def sentences
|
61
|
-
|
67
|
+
substrings(sentence_regex)
|
68
|
+
end
|
69
|
+
|
70
|
+
# Find all substrings matching the given regex
|
71
|
+
# @return [Array<Translatomatic::String] List of substrings
|
72
|
+
def substrings(regex)
|
73
|
+
matches = matches(@value, regex)
|
62
74
|
strings = []
|
63
|
-
|
64
|
-
|
75
|
+
matches.each do |match|
|
76
|
+
substring = match.to_s
|
65
77
|
# find leading and trailing whitespace
|
66
|
-
next if
|
78
|
+
next if substring.length == 0
|
67
79
|
|
68
|
-
parts =
|
80
|
+
parts = substring.match(/\A(\s*)(.*?)(\s*)\z/m).to_a
|
69
81
|
value = parts[2]
|
82
|
+
offset = match.offset(0)[0]
|
70
83
|
offset += parts[1].length # leading whitespace
|
71
84
|
strings << self.class.new(value, locale, offset: offset, parent: self)
|
72
|
-
offset += value.length + parts[3].length
|
73
85
|
end
|
74
86
|
|
75
|
-
# return [self] if there's only one
|
87
|
+
# return [self] if there's only one substring and it's equal to self
|
76
88
|
strings.length == 1 && strings[0].eql?(self) ? [self] : strings
|
77
89
|
end
|
78
90
|
|
91
|
+
# @return [boolean] true if other is a {Translatomatic::String} with
|
92
|
+
# the same value and locale.
|
79
93
|
def eql?(other)
|
80
94
|
other.kind_of?(Translatomatic::String) && other.hash == hash
|
81
95
|
end
|
82
96
|
|
97
|
+
# (see #eql?)
|
83
98
|
def ==(other)
|
84
99
|
eql?(other)
|
85
100
|
end
|
86
101
|
|
102
|
+
# @!visibility private
|
87
103
|
def hash
|
88
104
|
[value, locale].hash
|
89
105
|
end
|
90
106
|
|
91
107
|
private
|
92
108
|
|
109
|
+
# @!visibility private
|
93
110
|
class Script
|
94
111
|
attr_reader :language
|
95
112
|
attr_reader :delimiter # sentence delimiter
|
@@ -141,13 +158,24 @@ module Translatomatic
|
|
141
158
|
@script_data = script_data
|
142
159
|
end
|
143
160
|
|
161
|
+
def matches(s, re)
|
162
|
+
start_at = 0
|
163
|
+
matches = []
|
164
|
+
while(m = s.match(re, start_at))
|
165
|
+
break if m.to_s.empty?
|
166
|
+
matches.push(m)
|
167
|
+
start_at = m.end(0)
|
168
|
+
end
|
169
|
+
matches
|
170
|
+
end
|
171
|
+
|
144
172
|
def sentence_regex
|
145
173
|
script = script_data
|
146
174
|
if script.trailing_space
|
147
|
-
regex = /.*?(?:#{script.delimiter}\s
|
175
|
+
regex = /.*?(?:#{script.delimiter}\s+|\z)/m
|
148
176
|
else
|
149
177
|
# no trailing space after delimiter
|
150
|
-
regex = /.*?(?:#{script.delimiter}
|
178
|
+
regex = /.*?(?:#{script.delimiter}|\z)/m
|
151
179
|
end
|
152
180
|
end
|
153
181
|
|
@@ -3,14 +3,13 @@ module Translatomatic::TMX
|
|
3
3
|
class Document
|
4
4
|
|
5
5
|
# Create a new instance
|
6
|
-
# @param [Array<TranslationUnit>] A list of translation units
|
7
|
-
# @param [Locale] Source locale
|
8
|
-
# @return
|
9
|
-
def initialize(units, source_locale
|
6
|
+
# @param units [Array<TranslationUnit>] A list of translation units
|
7
|
+
# @param source_locale [Locale] Source locale
|
8
|
+
# @return [Translatomatic::TMX::Document] a new TMX object
|
9
|
+
def initialize(units, source_locale)
|
10
10
|
units = [units] unless units.kind_of?(Array)
|
11
11
|
@units = units
|
12
12
|
@source_locale = source_locale
|
13
|
-
@origin = origin
|
14
13
|
end
|
15
14
|
|
16
15
|
# @return [String] An XML string
|
@@ -25,7 +24,7 @@ module Translatomatic::TMX
|
|
25
24
|
segtype: "phrase", # default segtype
|
26
25
|
adminlang: @source_locale.to_s,
|
27
26
|
srclang: @source_locale.to_s,
|
28
|
-
"o-
|
27
|
+
"o-tmf": DEFAULT_OTMF
|
29
28
|
)
|
30
29
|
xml.body { tmx_body(xml) }
|
31
30
|
end
|
@@ -34,20 +33,18 @@ module Translatomatic::TMX
|
|
34
33
|
end
|
35
34
|
|
36
35
|
# Create a TMX document from the given converter
|
37
|
-
# @param [Array<Translatomatic::Model::Text>] List of texts
|
36
|
+
# @param texts [Array<Translatomatic::Model::Text>] List of texts
|
38
37
|
# @return [Translatomatic::TMX::Document] TMX document
|
39
38
|
def self.from_texts(texts)
|
40
39
|
# group texts by from_text_id to create units
|
41
40
|
# source_locale: use from_text.locale
|
42
41
|
# origin: use text.translator
|
43
|
-
origins = texts.collect { |i| i.translator }.compact.uniq
|
44
|
-
raise "Multiple origins in texts" if origins.length > 1
|
45
42
|
sources = texts.select { |i| i.from_text.nil? }
|
46
43
|
source_locales = sources.collect { |i| i.locale }.uniq
|
47
|
-
raise "
|
44
|
+
raise t("tmx.multiple_locales") if source_locales.length > 1
|
48
45
|
units = units_from_texts(texts)
|
49
46
|
|
50
|
-
return new(units, source_locales[0]
|
47
|
+
return new(units, source_locales[0])
|
51
48
|
end
|
52
49
|
|
53
50
|
def self.valid?(xml)
|
@@ -63,6 +60,7 @@ module Translatomatic::TMX
|
|
63
60
|
end
|
64
61
|
|
65
62
|
TMX_DTD = "http://www.ttt.org/oscarstandards/tmx/tmx14.dtd"
|
63
|
+
DEFAULT_OTMF = "Translatomatic"
|
66
64
|
|
67
65
|
def tmx_body(xml)
|
68
66
|
@units.each do |unit|
|
@@ -88,7 +86,8 @@ module Translatomatic::TMX
|
|
88
86
|
|
89
87
|
# create list of Translation Units
|
90
88
|
texts_by_from_id.values.collect do |list|
|
91
|
-
|
89
|
+
strings = list.uniq.collect { |i| string(i.value, i.locale) }
|
90
|
+
tmx_unit(strings)
|
92
91
|
end
|
93
92
|
end
|
94
93
|
|
@@ -1,10 +1,14 @@
|
|
1
1
|
module Translatomatic::TMX
|
2
|
+
# A TMX Translation Unit.
|
3
|
+
# A translation unit contains a list of strings, and is part of a TMX
|
4
|
+
# document.
|
5
|
+
# @see Translatomatic::TMX::Document
|
2
6
|
class TranslationUnit
|
3
7
|
|
4
8
|
# @return [Array<Translatomatic::String>] Strings in this translation unit
|
5
9
|
attr_reader :strings
|
6
10
|
|
7
|
-
# @param [Array<Translatomatic::String>]
|
11
|
+
# @param strings [Array<Translatomatic::String>] List of strings
|
8
12
|
def initialize(strings)
|
9
13
|
@strings = strings || []
|
10
14
|
end
|
data/lib/translatomatic/tmx.rb
CHANGED
@@ -0,0 +1,30 @@
|
|
1
|
+
module Translatomatic
|
2
|
+
# Data object describing a text translation
|
3
|
+
class Translation
|
4
|
+
# @return [Translatomatic::String] original string
|
5
|
+
attr_reader :original
|
6
|
+
|
7
|
+
# @return [Translatomatic::String] translated string
|
8
|
+
attr_accessor :result
|
9
|
+
|
10
|
+
# @return [Symbol] The name of the translator
|
11
|
+
attr_reader :translator
|
12
|
+
|
13
|
+
# @return [boolean] True if this translation came from the database
|
14
|
+
attr_reader :from_database
|
15
|
+
|
16
|
+
def initialize(original, result, translator = nil, from_database = false)
|
17
|
+
@original = original
|
18
|
+
@result = result
|
19
|
+
@translator = translator
|
20
|
+
@from_database = from_database
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def string(string)
|
26
|
+
string.kind_of?(Translatomatic::String) ? string : Translatomatic::String.new(string)
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|