translatomatic 0.1.3 → 0.2.0
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 +5 -5
- data/.gitattributes +20 -20
- data/.gitignore +19 -15
- data/.rspec +3 -3
- data/.rubocop.yml +28 -0
- data/.translatomatic/config.yml +4 -0
- data/.travis.yml +4 -6
- data/.yardopts +9 -9
- data/Gemfile +8 -4
- data/Guardfile +4 -5
- data/README.de.md +55 -50
- data/README.en.md +177 -0
- data/README.es.md +53 -48
- data/README.fr.md +53 -48
- data/README.it.md +54 -49
- data/README.ja.md +63 -58
- data/README.ko.md +59 -54
- data/README.md +17 -13
- data/README.ms.md +50 -45
- data/README.pt.md +54 -49
- data/README.ru.md +57 -52
- data/README.sv.md +51 -46
- data/README.zh.md +60 -55
- data/Rakefile +3 -3
- data/TODO.txt +6 -0
- data/bin/console +3 -3
- data/bin/translatomatic +4 -2
- data/config/i18n-tasks.yml +130 -0
- data/config/locales/translatomatic/de.yml +141 -99
- data/config/locales/translatomatic/en.yml +129 -89
- data/config/locales/translatomatic/es.yml +136 -99
- data/config/locales/translatomatic/fr.yml +139 -100
- data/config/locales/translatomatic/it.yml +135 -97
- data/config/locales/translatomatic/ja.yml +137 -98
- data/config/locales/translatomatic/ko.yml +138 -98
- data/config/locales/translatomatic/ms.yml +138 -100
- data/config/locales/translatomatic/pt.yml +137 -101
- data/config/locales/translatomatic/ru.yml +136 -98
- data/config/locales/translatomatic/sv.yml +134 -96
- data/config/locales/translatomatic/zh.yml +136 -97
- data/db/migrate/201712170000_initial.rb +2 -3
- data/lib/translatomatic.rb +40 -25
- data/lib/translatomatic/cli.rb +5 -1
- data/lib/translatomatic/cli/base.rb +61 -58
- data/lib/translatomatic/cli/common_options.rb +14 -11
- data/lib/translatomatic/cli/config.rb +96 -91
- data/lib/translatomatic/cli/database.rb +85 -23
- data/lib/translatomatic/cli/main.rb +158 -104
- data/lib/translatomatic/cli/thor.rb +29 -0
- data/lib/translatomatic/cli/translate.rb +134 -157
- data/lib/translatomatic/config.rb +10 -301
- data/lib/translatomatic/config/display.rb +78 -0
- data/lib/translatomatic/config/files.rb +60 -0
- data/lib/translatomatic/config/location_settings.rb +133 -0
- data/lib/translatomatic/config/options.rb +68 -0
- data/lib/translatomatic/config/selector.rb +127 -0
- data/lib/translatomatic/config/settings.rb +148 -0
- data/lib/translatomatic/converter.rb +40 -28
- data/lib/translatomatic/database.rb +127 -110
- data/lib/translatomatic/define_options.rb +4 -5
- data/lib/translatomatic/escaped_unicode.rb +86 -76
- data/lib/translatomatic/extractor.rb +5 -2
- data/lib/translatomatic/extractor/base.rb +12 -12
- data/lib/translatomatic/extractor/ruby.rb +7 -6
- data/lib/translatomatic/file_translator.rb +101 -244
- data/lib/translatomatic/flattenation.rb +39 -0
- data/lib/translatomatic/http.rb +13 -0
- data/lib/translatomatic/http/client.rb +144 -0
- data/lib/translatomatic/http/exception.rb +43 -0
- data/lib/translatomatic/http/file_param.rb +27 -0
- data/lib/translatomatic/http/param.rb +37 -0
- data/lib/translatomatic/http/request.rb +91 -0
- data/lib/translatomatic/i18n.rb +43 -0
- data/lib/translatomatic/locale.rb +71 -59
- data/lib/translatomatic/logger.rb +43 -28
- data/lib/translatomatic/metadata.rb +58 -0
- data/lib/translatomatic/model.rb +4 -2
- data/lib/translatomatic/model/locale.rb +5 -5
- data/lib/translatomatic/model/text.rb +5 -5
- data/lib/translatomatic/option.rb +57 -34
- data/lib/translatomatic/path_utils.rb +126 -0
- data/lib/translatomatic/progress_updater.rb +13 -16
- data/lib/translatomatic/provider.rb +101 -0
- data/lib/translatomatic/provider/base.rb +136 -0
- data/lib/translatomatic/provider/frengly.rb +55 -0
- data/lib/translatomatic/provider/google.rb +78 -0
- data/lib/translatomatic/provider/google_web.rb +50 -0
- data/lib/translatomatic/provider/microsoft.rb +144 -0
- data/lib/translatomatic/provider/my_memory.rb +75 -0
- data/lib/translatomatic/provider/yandex.rb +61 -0
- data/lib/translatomatic/resource_file.rb +59 -53
- data/lib/translatomatic/resource_file/base.rb +171 -237
- data/lib/translatomatic/resource_file/csv.rb +176 -24
- data/lib/translatomatic/resource_file/html.rb +21 -42
- data/lib/translatomatic/resource_file/key_value_support.rb +117 -0
- data/lib/translatomatic/resource_file/markdown.rb +36 -38
- data/lib/translatomatic/resource_file/plist.rb +121 -126
- data/lib/translatomatic/resource_file/po.rb +104 -82
- data/lib/translatomatic/resource_file/properties.rb +48 -77
- data/lib/translatomatic/resource_file/properties.treetop +87 -0
- data/lib/translatomatic/resource_file/resw.rb +56 -41
- data/lib/translatomatic/resource_file/subtitle.rb +86 -54
- data/lib/translatomatic/resource_file/text.rb +18 -18
- data/lib/translatomatic/resource_file/xcode_strings.rb +32 -63
- data/lib/translatomatic/resource_file/xcode_strings.treetop +85 -0
- data/lib/translatomatic/resource_file/xml.rb +94 -81
- data/lib/translatomatic/resource_file/yaml.rb +54 -68
- data/lib/translatomatic/retry_executor.rb +37 -0
- data/lib/translatomatic/slurp.rb +32 -0
- data/lib/translatomatic/string_batcher.rb +50 -0
- data/lib/translatomatic/string_escaping.rb +61 -0
- data/lib/translatomatic/text.rb +263 -0
- data/lib/translatomatic/text_collection.rb +66 -0
- data/lib/translatomatic/tmx.rb +5 -3
- data/lib/translatomatic/tmx/document.rb +107 -82
- data/lib/translatomatic/tmx/translation_unit.rb +19 -18
- data/lib/translatomatic/translation.rb +8 -28
- data/lib/translatomatic/translation/collection.rb +199 -0
- data/lib/translatomatic/translation/fetcher.rb +123 -0
- data/lib/translatomatic/translation/munging.rb +112 -0
- data/lib/translatomatic/translation/result.rb +50 -0
- data/lib/translatomatic/translation/sharer.rb +32 -0
- data/lib/translatomatic/translation/stats.rb +44 -0
- data/lib/translatomatic/translator.rb +91 -88
- data/lib/translatomatic/type_cast.rb +63 -0
- data/lib/translatomatic/util.rb +37 -33
- data/lib/translatomatic/version.rb +2 -2
- data/translatomatic.gemspec +57 -46
- metadata +136 -59
- data/lib/translatomatic/http_request.rb +0 -162
- data/lib/translatomatic/string.rb +0 -188
- data/lib/translatomatic/translation_result.rb +0 -86
- data/lib/translatomatic/translation_stats.rb +0 -31
- data/lib/translatomatic/translator/base.rb +0 -128
- data/lib/translatomatic/translator/frengly.rb +0 -62
- data/lib/translatomatic/translator/google.rb +0 -37
- data/lib/translatomatic/translator/microsoft.rb +0 -41
- data/lib/translatomatic/translator/my_memory.rb +0 -68
- data/lib/translatomatic/translator/yandex.rb +0 -56
@@ -0,0 +1,66 @@
|
|
1
|
+
module Translatomatic
|
2
|
+
# A collection of texts
|
3
|
+
class TextCollection
|
4
|
+
attr_reader :originals
|
5
|
+
|
6
|
+
def initialize(texts = [])
|
7
|
+
texts = [texts] unless texts.is_a?(Array)
|
8
|
+
texts = texts.select { |i| translatable?(i) }
|
9
|
+
texts = textify(texts) # convert to Text objects
|
10
|
+
@originals = texts
|
11
|
+
@sentences = find_sentences(texts) # convert to sentences
|
12
|
+
contexts = find_contexts(texts)
|
13
|
+
@all_texts = @sentences + contexts
|
14
|
+
group_by_locale(@all_texts)
|
15
|
+
end
|
16
|
+
|
17
|
+
# Iterate over texts in the collection grouped by locale
|
18
|
+
def each_locale
|
19
|
+
@by_locale.each do |locale, list|
|
20
|
+
yield locale, list
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# @return [Number] The total number of texts in the collection,
|
25
|
+
# equal to the number of sentences and context strings.
|
26
|
+
def count
|
27
|
+
@all_texts.length
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def translatable?(text)
|
33
|
+
# don't translate numbers
|
34
|
+
text && !text.match(/\A\s*\z/) && !text.match(/\A[\d,]+\z/)
|
35
|
+
end
|
36
|
+
|
37
|
+
def textify(texts)
|
38
|
+
texts.collect { |i| build_text(i) }
|
39
|
+
end
|
40
|
+
|
41
|
+
def find_sentences(texts)
|
42
|
+
texts.collect(&:sentences).flatten.uniq
|
43
|
+
end
|
44
|
+
|
45
|
+
def find_contexts(texts)
|
46
|
+
texts.collect { |i| build_text(i.context) }.flatten.uniq.compact
|
47
|
+
end
|
48
|
+
|
49
|
+
def group_by_locale(texts)
|
50
|
+
@by_locale = {}
|
51
|
+
texts.each do |text|
|
52
|
+
list = @by_locale[text.locale] ||= []
|
53
|
+
list << text
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def build_text(value, locale = Locale.default)
|
58
|
+
return nil if value.nil?
|
59
|
+
if value.is_a?(Translatomatic::Text)
|
60
|
+
value
|
61
|
+
else
|
62
|
+
Translatomatic::Text.new(value, locale)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
data/lib/translatomatic/tmx.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
|
-
|
2
|
-
#
|
3
|
-
|
1
|
+
module Translatomatic
|
2
|
+
# Translation Memory Exchange
|
3
|
+
# @see https://en.wikipedia.org/wiki/Translation_Memory_eXchange
|
4
|
+
module TMX; end
|
5
|
+
end
|
4
6
|
|
5
7
|
require 'translatomatic/tmx/translation_unit'
|
6
8
|
require 'translatomatic/tmx/document'
|
@@ -1,99 +1,124 @@
|
|
1
|
-
module Translatomatic
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
1
|
+
module Translatomatic
|
2
|
+
module TMX
|
3
|
+
# Translation Memory Exchange document
|
4
|
+
class Document
|
5
|
+
# Create a new instance
|
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
|
+
units = [units] unless units.is_a?(Array)
|
11
|
+
@units = units
|
12
|
+
@source_locale = source_locale
|
13
|
+
end
|
14
14
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
segtype: "phrase", # default segtype
|
25
|
-
adminlang: @source_locale.to_s,
|
26
|
-
srclang: @source_locale.to_s,
|
27
|
-
"o-tmf": DEFAULT_OTMF
|
28
|
-
)
|
29
|
-
xml.body { tmx_body(xml) }
|
15
|
+
# @return [String] An XML string
|
16
|
+
def to_xml(options = {})
|
17
|
+
builder = Nokogiri::XML::Builder.new do |xml|
|
18
|
+
dtd = options[:dtd] || TMX_DTD
|
19
|
+
xml.doc.create_internal_subset('tmx', nil, dtd)
|
20
|
+
xml.tmx(version: '1.4') do
|
21
|
+
xml.header(tmx_header)
|
22
|
+
xml.body { tmx_body(xml) }
|
23
|
+
end
|
30
24
|
end
|
25
|
+
builder.to_xml
|
31
26
|
end
|
32
|
-
builder.to_xml
|
33
|
-
end
|
34
27
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
return new(units, source_locales[0])
|
48
|
-
end
|
28
|
+
# Create a TMX document from the given converter
|
29
|
+
# @param texts [Array<Translatomatic::Model::Text>] List of texts
|
30
|
+
# @return [Translatomatic::TMX::Document] TMX document
|
31
|
+
def self.from_texts(texts)
|
32
|
+
# group texts by from_text_id to create units
|
33
|
+
# source_locale: use from_text.locale
|
34
|
+
# origin: use text.provider
|
35
|
+
sources = texts.select { |i| i.from_text.nil? }
|
36
|
+
source_locales = sources.collect(&:locale).uniq
|
37
|
+
raise t('tmx.multiple_locales') if source_locales.length > 1
|
38
|
+
units = units_from_texts(texts)
|
49
39
|
|
50
|
-
|
51
|
-
|
52
|
-
doc = Nokogiri::XML::Document.parse(xml, nil, nil, options)
|
53
|
-
doc.internal_subset.validate(doc)
|
54
|
-
end
|
40
|
+
new(units, source_locales[0])
|
41
|
+
end
|
55
42
|
|
56
|
-
|
43
|
+
# Create a TMX document from a translation collection
|
44
|
+
# @param collection [Translatomatic::Translation::Collection]
|
45
|
+
# Translation collection
|
46
|
+
# @return [Translatomatic::TMX::Document] TMX document
|
47
|
+
def self.from_collection(collection)
|
48
|
+
originals = collection.translations.collect(&:original)
|
49
|
+
source_locales = originals.collect(&:locale)
|
50
|
+
raise t('tmx.multiple_locales') if source_locales.length > 1
|
51
|
+
units = units_from_collection(collection)
|
57
52
|
|
58
|
-
|
59
|
-
|
60
|
-
end
|
53
|
+
new(units, source_locales[0])
|
54
|
+
end
|
61
55
|
|
62
|
-
|
63
|
-
|
56
|
+
def self.valid?(xml)
|
57
|
+
options = Nokogiri::XML::ParseOptions::DTDVALID
|
58
|
+
doc = Nokogiri::XML::Document.parse(xml, nil, nil, options)
|
59
|
+
doc.internal_subset.validate(doc)
|
60
|
+
end
|
64
61
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
62
|
+
private
|
63
|
+
|
64
|
+
class << self
|
65
|
+
include Translatomatic::Util
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
# @return [Array<Translatomatic::TMX::TranslationUnit]
|
70
|
+
# translation unit list
|
71
|
+
def units_from_texts(texts)
|
72
|
+
# group texts by from_text_id
|
73
|
+
texts_by_from_id = {}
|
74
|
+
texts.each do |text|
|
75
|
+
id = text.from_text_id || text.id
|
76
|
+
list = (texts_by_from_id[id] ||= [])
|
77
|
+
list << text
|
78
|
+
end
|
79
|
+
|
80
|
+
# create list of Translation Units
|
81
|
+
texts_by_from_id.values.collect do |list|
|
82
|
+
strings = list.uniq.collect { |i| build_text(i.value, i.locale) }
|
83
|
+
tmx_unit(strings)
|
72
84
|
end
|
73
85
|
end
|
74
|
-
end
|
75
|
-
end
|
76
86
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
list << text
|
87
|
+
# @return [Array<Translatomatic::TMX::TranslationUnit]
|
88
|
+
# translation unit list
|
89
|
+
def units_from_collection(collection); end
|
90
|
+
|
91
|
+
def tmx_unit(strings)
|
92
|
+
Translatomatic::TMX::TranslationUnit.new(strings)
|
93
|
+
end
|
85
94
|
end
|
86
95
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
96
|
+
TMX_DTD = 'http://www.ttt.org/oscarstandards/tmx/tmx14.dtd'.freeze
|
97
|
+
DEFAULT_OTMF = 'Translatomatic'.freeze
|
98
|
+
|
99
|
+
def tmx_header
|
100
|
+
{
|
101
|
+
creationtool: 'Translatomatic',
|
102
|
+
creationtoolversion: Translatomatic::VERSION,
|
103
|
+
datatype: 'PlainText',
|
104
|
+
segtype: 'phrase', # default segtype
|
105
|
+
adminlang: @source_locale.to_s,
|
106
|
+
srclang: @source_locale.to_s,
|
107
|
+
'o-tmf' => DEFAULT_OTMF
|
108
|
+
}
|
91
109
|
end
|
92
|
-
end
|
93
110
|
|
94
|
-
|
95
|
-
|
111
|
+
def tmx_body(xml)
|
112
|
+
@units.each do |unit|
|
113
|
+
xml.tu('segtype' => unit.strings[0].type) do
|
114
|
+
unit.strings.each do |string|
|
115
|
+
xml.tuv('xml:lang' => string.locale.to_s) do
|
116
|
+
xml.seg string.value
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
96
122
|
end
|
97
|
-
|
98
|
-
|
99
|
-
end # module
|
123
|
+
end
|
124
|
+
end
|
@@ -1,23 +1,24 @@
|
|
1
|
-
module Translatomatic
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
1
|
+
module Translatomatic
|
2
|
+
module TMX
|
3
|
+
# A TMX Translation Unit.
|
4
|
+
# A translation unit contains a list of strings, and is part of a TMX
|
5
|
+
# document.
|
6
|
+
# @see Translatomatic::TMX::Document
|
7
|
+
class TranslationUnit
|
8
|
+
# @return [Array<Translatomatic::Text>] Strings in this translation unit
|
9
|
+
attr_reader :strings
|
7
10
|
|
8
|
-
|
9
|
-
|
11
|
+
# @param strings [Array<Translatomatic::Text>] List of strings
|
12
|
+
def initialize(strings)
|
13
|
+
@strings = strings || []
|
14
|
+
end
|
10
15
|
|
11
|
-
|
12
|
-
|
13
|
-
@
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
# A translation unit must contain at least two strings.
|
18
|
-
# @return [boolean] true if this translation unit is valid
|
19
|
-
def valid?
|
20
|
-
@strings.length >= 2
|
16
|
+
# Test translation unit validity.
|
17
|
+
# A translation unit must contain at least two strings.
|
18
|
+
# @return [boolean] true if this translation unit is valid
|
19
|
+
def valid?
|
20
|
+
@strings.length >= 2
|
21
|
+
end
|
21
22
|
end
|
22
23
|
end
|
23
24
|
end
|
@@ -1,30 +1,10 @@
|
|
1
1
|
module Translatomatic
|
2
|
-
#
|
3
|
-
|
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
|
2
|
+
# Classes for translating strings
|
3
|
+
module Translation; end
|
30
4
|
end
|
5
|
+
|
6
|
+
require 'translatomatic/translation/collection'
|
7
|
+
require 'translatomatic/translation/munging'
|
8
|
+
require 'translatomatic/translation/fetcher'
|
9
|
+
require 'translatomatic/translation/result'
|
10
|
+
require 'translatomatic/translation/stats'
|
@@ -0,0 +1,199 @@
|
|
1
|
+
require 'set'
|
2
|
+
|
3
|
+
module Translatomatic
|
4
|
+
module Translation
|
5
|
+
# Stores results of translations.
|
6
|
+
# For each original text, there may be zero or more translations from
|
7
|
+
# one or more providers.
|
8
|
+
class Collection
|
9
|
+
# Create a translation collection
|
10
|
+
def initialize
|
11
|
+
# by_provider[provider] = [Result, ...]
|
12
|
+
@by_provider = {}
|
13
|
+
# by_original[text] = [Result, ...]
|
14
|
+
@by_original = {}
|
15
|
+
end
|
16
|
+
|
17
|
+
# @param string [String,Text] Original string
|
18
|
+
# @return [Array<Result>] All translations for the given string
|
19
|
+
def [](string)
|
20
|
+
@by_original[string.to_s]
|
21
|
+
end
|
22
|
+
|
23
|
+
def empty?
|
24
|
+
@by_original.empty?
|
25
|
+
end
|
26
|
+
|
27
|
+
# @param string [String,Text] Original string
|
28
|
+
# @param locale [Locale] Target locale
|
29
|
+
# @return [Result] The best translation for the given string
|
30
|
+
def get(string, locale)
|
31
|
+
locale = build_locale(locale)
|
32
|
+
list = @by_original[string.to_s] || []
|
33
|
+
list = sort_by_best_match(list)
|
34
|
+
if string.is_a?(Translatomatic::Text) && string.context
|
35
|
+
# string has a context
|
36
|
+
list = sort_by_context_match(list, string.context, locale)
|
37
|
+
end
|
38
|
+
list.find { |i| i.result.locale == locale }
|
39
|
+
end
|
40
|
+
|
41
|
+
# Add a list of translations to the collection
|
42
|
+
# @param translations [Array<Result>] Translation results
|
43
|
+
# @return [void]
|
44
|
+
def add(translations)
|
45
|
+
translations = [translations] unless translations.is_a?(Array)
|
46
|
+
translations.each do |tr|
|
47
|
+
next if tr.result.nil?
|
48
|
+
add_to_list(@by_provider, tr.provider, tr)
|
49
|
+
add_to_list(@by_original, tr.original, tr)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# @return [Number] The number of translations
|
54
|
+
def count
|
55
|
+
translations.length
|
56
|
+
end
|
57
|
+
|
58
|
+
# @return [Boolean] True if there is one or more translations
|
59
|
+
def present?
|
60
|
+
count > 0
|
61
|
+
end
|
62
|
+
|
63
|
+
# Get translations from this collection. If provider is specified,
|
64
|
+
# returns only translations from the given provider, otherwise all
|
65
|
+
# translations are returned.
|
66
|
+
# @param provider [String] Optional name of a provider.
|
67
|
+
# @return [Array<Result>] Translation results
|
68
|
+
def translations(provider = nil)
|
69
|
+
if provider.nil?
|
70
|
+
@by_provider.values.flatten
|
71
|
+
else
|
72
|
+
@by_provider[provider.to_s] || []
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# Get a list of the best sentence translations for the given
|
77
|
+
# parent string.
|
78
|
+
# @param parent [Text] Parent text
|
79
|
+
# @param locale [Locale] Target locale
|
80
|
+
# @return [Array<Result>] Substring translation results
|
81
|
+
def sentences(parent, locale)
|
82
|
+
parent.sentences.collect do |sentence|
|
83
|
+
# get translation for sentence
|
84
|
+
translation = get(sentence, locale)
|
85
|
+
# create a new translation with the sentence as the original
|
86
|
+
# string, so that we can rely on the offset value.
|
87
|
+
if translation
|
88
|
+
Result.new(sentence, translation.result, translation.provider,
|
89
|
+
from_database: translation.from_database)
|
90
|
+
end
|
91
|
+
end.compact
|
92
|
+
end
|
93
|
+
|
94
|
+
# Return a new collection with only the translations that came from
|
95
|
+
# providers (not from the database).
|
96
|
+
# @return [Collection] The collection result
|
97
|
+
def from_providers
|
98
|
+
result = self.class.new
|
99
|
+
provider_translations = translations.reject(&:from_database)
|
100
|
+
result.add(provider_translations)
|
101
|
+
result
|
102
|
+
end
|
103
|
+
|
104
|
+
# @return [Array<Result>] Best translations for each string
|
105
|
+
# @param locale [Locale] Target locale
|
106
|
+
def best_translations(locale)
|
107
|
+
@by_original.keys.collect { |i| get(i, locale) }
|
108
|
+
end
|
109
|
+
|
110
|
+
# @return [Array<String>] A list of providers that translations were
|
111
|
+
# sourced from.
|
112
|
+
def providers
|
113
|
+
@by_provider.keys
|
114
|
+
end
|
115
|
+
|
116
|
+
# Combine this collection with another
|
117
|
+
# @param other [Collection] Another collection
|
118
|
+
# @return [Collection] The collection result
|
119
|
+
def +(other)
|
120
|
+
result = self.class.new
|
121
|
+
@by_provider.each_value { |i| result.add(i) }
|
122
|
+
other.translations.each { |i| result.add(i) }
|
123
|
+
result
|
124
|
+
end
|
125
|
+
|
126
|
+
# @param string [String,Text] Original string
|
127
|
+
# @param provider [String] Provider name
|
128
|
+
# @return [boolean] True if there is a translation for the given string.
|
129
|
+
def translated?(string, provider)
|
130
|
+
list = @by_provider[provider.to_s] || []
|
131
|
+
list.any? { |tr| tr.original.to_s == string.to_s }
|
132
|
+
end
|
133
|
+
|
134
|
+
# @return [String] String description of all translations
|
135
|
+
def description
|
136
|
+
translations.collect(&:description).join("\n")
|
137
|
+
end
|
138
|
+
|
139
|
+
private
|
140
|
+
|
141
|
+
include Translatomatic::Util
|
142
|
+
|
143
|
+
# sort the list of translations by comparing to the translation for
|
144
|
+
# the string context.
|
145
|
+
# for example:
|
146
|
+
# context is 'go right' with a translation of 'Geh rechts'.
|
147
|
+
# translation of 'right' is 'rechts', and 'richtig'.
|
148
|
+
# translation 'rechts' will be ordered first, as 'rechts' is in
|
149
|
+
# the translated context string (and is longer than 'recht').
|
150
|
+
def sort_by_context_match(list, context, locale)
|
151
|
+
return list if list.blank?
|
152
|
+
context_results = context_translation_results(list, context, locale)
|
153
|
+
# log.debug("context translations: #{context_results}")
|
154
|
+
# put translations that include the context string(s) first.
|
155
|
+
# also put longer translations that include the context string first.
|
156
|
+
# (fixes matching 'rechts' before 'recht')
|
157
|
+
list.sort_by do |tr|
|
158
|
+
tr_result = tr.result.downcase
|
159
|
+
ctx_match = context_results.any? { |ctx| ctx.include?(tr_result) }
|
160
|
+
ctx_match ? -tr_result.length : 1
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
# sort the list of translations by finding the most common
|
165
|
+
# translation. if there is an equal number of different translations
|
166
|
+
# use the first most common translation (first provider).
|
167
|
+
def sort_by_best_match(list)
|
168
|
+
by_count = {}
|
169
|
+
list.each do |tr|
|
170
|
+
key = tr.result.downcase
|
171
|
+
by_count[key] = (by_count[key] || 0) + 1
|
172
|
+
end
|
173
|
+
|
174
|
+
# not using sort_by to maintain original sort order
|
175
|
+
# unless count is different.
|
176
|
+
list.sort do |tr1, tr2|
|
177
|
+
by_count[tr1.result.downcase] <=> by_count[tr2.result.downcase]
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
# @param list [Array<Result>] translations
|
182
|
+
# @param context [Array<String>] context(s)
|
183
|
+
# @return [Array<String>] lowercased context translation strings
|
184
|
+
def context_translation_results(list, context, locale)
|
185
|
+
context_locale = list[0].original.locale
|
186
|
+
context = [context] unless context.is_a?(Array)
|
187
|
+
context.collect do |ctx|
|
188
|
+
context_tr = get(Text[ctx, context_locale], locale)
|
189
|
+
context_tr.result.downcase if context_tr
|
190
|
+
end.compact
|
191
|
+
end
|
192
|
+
|
193
|
+
def add_to_list(hash, key, value)
|
194
|
+
list = hash[key.to_s] ||= []
|
195
|
+
list << value
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|