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.
Files changed (87) hide show
  1. checksums.yaml +4 -4
  2. data/.gitattributes +19 -0
  3. data/.gitignore +0 -0
  4. data/.travis.yml +7 -7
  5. data/.yardopts +9 -0
  6. data/Gemfile +4 -4
  7. data/Guardfile +0 -0
  8. data/README.de.md +61 -16
  9. data/README.es.md +60 -15
  10. data/README.fr.md +61 -16
  11. data/README.it.md +60 -15
  12. data/README.ja.md +59 -14
  13. data/README.ko.md +137 -0
  14. data/README.md +58 -13
  15. data/README.ms.md +137 -0
  16. data/README.pt.md +137 -0
  17. data/README.ru.md +137 -0
  18. data/README.sv.md +137 -0
  19. data/README.zh.md +137 -0
  20. data/bin/setup +8 -8
  21. data/bin/translatomatic +6 -6
  22. data/bin/travis +1 -1
  23. data/config/locales/translatomatic/de.yml +104 -0
  24. data/config/locales/translatomatic/en.yml +101 -0
  25. data/config/locales/translatomatic/es.yml +105 -0
  26. data/config/locales/translatomatic/fr.yml +105 -0
  27. data/config/locales/translatomatic/it.yml +103 -0
  28. data/config/locales/translatomatic/ja.yml +102 -0
  29. data/config/locales/translatomatic/ko.yml +101 -0
  30. data/config/locales/translatomatic/ms.yml +103 -0
  31. data/config/locales/translatomatic/pt.yml +105 -0
  32. data/config/locales/translatomatic/ru.yml +103 -0
  33. data/config/locales/translatomatic/sv.yml +103 -0
  34. data/config/locales/translatomatic/zh.yml +102 -0
  35. data/db/migrate/201712170000_initial.rb +2 -1
  36. data/lib/translatomatic/cli/base.rb +73 -0
  37. data/lib/translatomatic/cli/common_options.rb +14 -0
  38. data/lib/translatomatic/cli/config.rb +81 -0
  39. data/lib/translatomatic/cli/database.rb +29 -0
  40. data/lib/translatomatic/cli/main.rb +112 -0
  41. data/lib/translatomatic/cli/translate.rb +146 -0
  42. data/lib/translatomatic/cli.rb +8 -216
  43. data/lib/translatomatic/config.rb +143 -0
  44. data/lib/translatomatic/converter.rb +196 -149
  45. data/lib/translatomatic/converter_stats.rb +18 -14
  46. data/lib/translatomatic/database.rb +35 -37
  47. data/lib/translatomatic/escaped_unicode.rb +1 -1
  48. data/lib/translatomatic/extractor/base.rb +2 -0
  49. data/lib/translatomatic/extractor/ruby.rb +1 -0
  50. data/lib/translatomatic/extractor.rb +1 -0
  51. data/lib/translatomatic/http_request.rb +43 -14
  52. data/lib/translatomatic/locale.rb +28 -4
  53. data/lib/translatomatic/logger.rb +21 -13
  54. data/lib/translatomatic/model/locale.rb +5 -1
  55. data/lib/translatomatic/model/text.rb +2 -0
  56. data/lib/translatomatic/model.rb +1 -0
  57. data/lib/translatomatic/option.rb +75 -10
  58. data/lib/translatomatic/progress_updater.rb +7 -3
  59. data/lib/translatomatic/resource_file/base.rb +41 -18
  60. data/lib/translatomatic/resource_file/html.rb +11 -14
  61. data/lib/translatomatic/resource_file/markdown.rb +13 -12
  62. data/lib/translatomatic/resource_file/plist.rb +3 -14
  63. data/lib/translatomatic/resource_file/properties.rb +21 -3
  64. data/lib/translatomatic/resource_file/resw.rb +1 -0
  65. data/lib/translatomatic/resource_file/text.rb +1 -0
  66. data/lib/translatomatic/resource_file/xcode_strings.rb +23 -14
  67. data/lib/translatomatic/resource_file/xml.rb +34 -22
  68. data/lib/translatomatic/resource_file/yaml.rb +39 -5
  69. data/lib/translatomatic/resource_file.rb +7 -5
  70. data/lib/translatomatic/string.rb +40 -12
  71. data/lib/translatomatic/tmx/document.rb +11 -12
  72. data/lib/translatomatic/tmx/translation_unit.rb +5 -1
  73. data/lib/translatomatic/tmx.rb +2 -0
  74. data/lib/translatomatic/translation.rb +30 -0
  75. data/lib/translatomatic/translation_result.rb +45 -45
  76. data/lib/translatomatic/translator/base.rb +128 -83
  77. data/lib/translatomatic/translator/frengly.rb +62 -57
  78. data/lib/translatomatic/translator/google.rb +35 -31
  79. data/lib/translatomatic/translator/microsoft.rb +41 -33
  80. data/lib/translatomatic/translator/my_memory.rb +68 -64
  81. data/lib/translatomatic/translator/yandex.rb +56 -39
  82. data/lib/translatomatic/translator.rb +99 -63
  83. data/lib/translatomatic/util.rb +31 -1
  84. data/lib/translatomatic/version.rb +4 -1
  85. data/lib/translatomatic.rb +17 -0
  86. data/translatomatic.gemspec +5 -4
  87. metadata +56 -16
@@ -2,24 +2,38 @@ require 'securerandom'
2
2
  require 'net/http'
3
3
 
4
4
  module Translatomatic
5
+ # HTTP request
6
+ # wrapper for Net::HTTP functionality
5
7
  class HTTPRequest
6
8
 
9
+ # @return [String] the text to use to denote multipart boundaries. By
10
+ # default, a random hexadecimal string is used.
7
11
  attr_accessor :multipart_boundary
8
12
 
13
+ # @param url [String,URI] URL of the request
14
+ # @return [Translatomatic::HTTPRequest] Create a new request
9
15
  def initialize(url)
10
16
  @uri = url.respond_to?(:host) ? url : URI.parse(url)
11
17
  @multipart_boundary = SecureRandom.hex(16)
12
18
  end
13
19
 
20
+ # Start the HTTP request. Yields a http object.
21
+ # @param options [Hash<Symbol,Object>] Request options
22
+ # @return [Object] Result of the block
14
23
  def start(options = {})
15
24
  options = options.merge(use_ssl: @uri.scheme == "https")
25
+ result = nil
16
26
  Net::HTTP.start(@uri.host, @uri.port, options) do |http|
17
27
  @http = http
18
- yield http
28
+ result = yield http
19
29
  end
20
30
  @http = nil
31
+ result
21
32
  end
22
33
 
34
+ # Send a HTTP GET request
35
+ # @param query [Hash<String,String>] Optional query parameters
36
+ # @return [Net::HTTP::Response]
23
37
  def get(query = nil)
24
38
  uri = @uri
25
39
  if query
@@ -31,6 +45,9 @@ module Translatomatic
31
45
  send_request(request)
32
46
  end
33
47
 
48
+ # Send an HTTP POST request
49
+ # @param body [String,Hash] Body of the request
50
+ # @return [Net::HTTP::Response]
34
51
  def post(body, options = {})
35
52
  request = Net::HTTP::Post.new(@uri)
36
53
  request['User-Agent'] = USER_AGENT
@@ -40,6 +57,7 @@ module Translatomatic
40
57
  content_type = "multipart/form-data; boundary=#{@multipart_boundary}"
41
58
  request.body = multipartify(body)
42
59
  elsif body.kind_of?(Hash)
60
+ # set_form_data does url encoding
43
61
  request.set_form_data(body)
44
62
  else
45
63
  request.body = body
@@ -49,10 +67,14 @@ module Translatomatic
49
67
  send_request(request)
50
68
  end
51
69
 
70
+ # Create a file parameter for a multipart POST request
71
+ # @return [FileParam] A new file parameter
52
72
  def file(*args)
53
73
  FileParam.new(*args)
54
74
  end
55
75
 
76
+ # Create a parameter for a multipart POST request
77
+ # @return [Param] A new parameter
56
78
  def param(*args)
57
79
  Param.new(*args)
58
80
  end
@@ -65,17 +87,19 @@ module Translatomatic
65
87
  class Param
66
88
  attr_accessor :key, :value
67
89
 
68
- def initialize(key:, value:)
69
- @key = key
70
- @value = value
71
- end
72
-
90
+ # @return [String] Representation of this parameter as it appears
91
+ # within a multipart post request.
73
92
  def to_s
74
93
  return header(header_data) + "\r\n#{value}\r\n"
75
94
  end
76
95
 
77
96
  private
78
97
 
98
+ def initialize(key:, value:)
99
+ @key = key
100
+ @value = value
101
+ end
102
+
79
103
  def header_data
80
104
  name = CGI::escape(key.to_s)
81
105
  { "Content-Disposition": "form-data", name: %Q("#{name}") }
@@ -97,13 +121,7 @@ module Translatomatic
97
121
  class FileParam < Param
98
122
  attr_accessor :filename, :content, :mime_type
99
123
 
100
- def initialize(key:, filename:, content:, mime_type:)
101
- @key = key
102
- @filename = filename
103
- @content = content
104
- @mime_type = mime_type
105
- end
106
-
124
+ # (see Param#to_s)
107
125
  def to_s
108
126
  return header(header_data) +
109
127
  header("Content-Type": mime_type) + "\r\n#{content}\r\n"
@@ -111,6 +129,13 @@ module Translatomatic
111
129
 
112
130
  private
113
131
 
132
+ def initialize(key:, filename:, content:, mime_type:)
133
+ @key = key
134
+ @filename = filename
135
+ @content = content
136
+ @mime_type = mime_type
137
+ end
138
+
114
139
  def header_data
115
140
  super.merge({ filename: %Q("#{filename}") })
116
141
  end
@@ -124,7 +149,11 @@ module Translatomatic
124
149
  end
125
150
 
126
151
  def send_request(req)
127
- response = @http.request(req)
152
+ if @http
153
+ response = @http.request(req)
154
+ else
155
+ response = start { |http| http.request(req) }
156
+ end
128
157
  raise response.body unless response.kind_of? Net::HTTPSuccess
129
158
  response
130
159
  end
@@ -1,18 +1,37 @@
1
+ # Represents a locale
2
+ # @see https://en.wikipedia.org/wiki/Locale_(computer_software)
1
3
  class Translatomatic::Locale
2
4
 
5
+ # @return [String] ISO 639-1 language
3
6
  attr_reader :language
7
+
8
+ # @return [String] ISO 15924 script
4
9
  attr_reader :script
10
+
11
+ # @return [String] ISO 3166-1 alpha-2 country code
5
12
  attr_reader :region
6
13
 
14
+ # Parse the given tag
15
+ # @param tag [String] A string representing a locale
16
+ # @param validate [boolean] If true, return nil if the locale is invalid
17
+ # @return [Locale] A locale object
7
18
  def self.parse(tag, validate = true)
8
- locale = tag.kind_of?(Translatomatic::Locale) ? tag : new(tag)
19
+ return nil if tag.nil?
20
+
21
+ locale = tag
22
+ unless tag.kind_of?(Translatomatic::Locale)
23
+ tag = tag.to_s.gsub(/_/, '-')
24
+ locale = new(tag)
25
+ end
9
26
  validate && !locale.valid? ? nil : locale
10
27
  end
11
28
 
29
+ # @return [Locale] the default locale
12
30
  def self.default
13
- DEFAULT_LOCALE
31
+ parse(Translatomatic::Config.instance.default_locale)
14
32
  end
15
33
 
34
+ # @return [Locale] create a new locale object
16
35
  def initialize(tag)
17
36
  data = I18n::Locale::Tag::Rfc4646.tag(tag)
18
37
  if data
@@ -22,23 +41,29 @@ class Translatomatic::Locale
22
41
  end
23
42
  end
24
43
 
44
+ # @return true if language is a valid ISO 639-1 language
25
45
  def valid?
26
- # test if lang is a valid ISO 639-1 language
27
46
  VALID_LANGUAGES.include?(language)
28
47
  end
29
48
 
49
+ # @return [String] Locale as a string
30
50
  def to_s
31
51
  [language, script, region].compact.join("-")
32
52
  end
33
53
 
54
+ # @param other [Object] Another object
55
+ # @return [boolean] true if the other object is a {Translatomatic::Locale}
56
+ # object and has equal language, script and region.
34
57
  def eql?(other)
35
58
  other.kind_of?(Translatomatic::Locale) && other.hash == hash
36
59
  end
37
60
 
61
+ # (see #eql?)
38
62
  def ==(other)
39
63
  eql?(other)
40
64
  end
41
65
 
66
+ # @!visibility private
42
67
  def hash
43
68
  [language, script, region].hash
44
69
  end
@@ -47,6 +72,5 @@ class Translatomatic::Locale
47
72
 
48
73
  # list of 2 letter country codes
49
74
  VALID_LANGUAGES = ::I18nData.languages.keys.collect { |i| i.downcase }.sort
50
- DEFAULT_LOCALE = parse(I18n.default_locale)
51
75
 
52
76
  end
@@ -1,6 +1,10 @@
1
- class Translatomatic::Logger
1
+ # Logging
2
+ class Translatomatic::Logger
3
+
4
+ # @return [ProgressBar] A progress bar
2
5
  attr_accessor :progressbar
3
-
6
+
7
+ # @return [Translatomatic::Logger] create a new logger instance
4
8
  def initialize
5
9
  @logger = Logger.new(STDOUT)
6
10
  @logger.level = ENV['DEBUG'] ? Logger::DEBUG : Logger::INFO
@@ -9,20 +13,24 @@ class Translatomatic::Logger
9
13
  end
10
14
  end
11
15
 
12
- def method_missing(name, *args)
13
- handle_logger_method(name, args) if @logger.respond_to?(name)
14
- end
15
-
16
- def finish
17
- @progressbar.finish if @progressbar
16
+ # Called at the end of translatomatic to clear the progress bar.
17
+ def finish
18
+ @finished ||= begin
19
+ @progressbar.finish if @progressbar
20
+ true
21
+ end
18
22
  end
19
23
 
20
- private
24
+ private
21
25
 
22
- def handle_logger_method(name, args)
23
- @progressbar.clear if @progressbar
24
- @logger.send(name, *args)
25
- @progressbar.refresh(force: true) if @progressbar && !@progressbar.stopped?
26
+ def method_missing(name, *args)
27
+ handle_logger_method(name, args) if @logger.respond_to?(name)
26
28
  end
27
29
 
30
+ def handle_logger_method(name, args)
31
+ @progressbar.clear if @progressbar
32
+ @logger.send(name, *args)
33
+ @progressbar.refresh(force: true) if @progressbar && !@progressbar.stopped?
34
+ end
35
+
28
36
  end
@@ -1,11 +1,14 @@
1
1
  module Translatomatic
2
2
  module Model
3
+ # Locale database record.
4
+ # Used to store translations in the database.
3
5
  class Locale < ActiveRecord::Base
4
6
  has_many :texts, class_name: "Translatomatic::Model::Text"
5
7
  validates_presence_of :language
6
8
  validates_uniqueness_of :language, scope: [:script, :region]
7
9
 
8
- # create a locale record from an I18n::Locale::Tag object or string
10
+ # Create a locale record from an I18n::Locale::Tag object or string
11
+ # @return [Translatomatic::Model::Locale] Locale record
9
12
  def self.from_tag(tag)
10
13
  tag = Translatomatic::Locale.parse(tag)
11
14
  find_or_create_by!({
@@ -13,6 +16,7 @@ module Translatomatic
13
16
  })
14
17
  end
15
18
 
19
+ # @return [String] Locale as string
16
20
  def to_s
17
21
  [language, script, region].compact.join("-")
18
22
  end
@@ -1,5 +1,7 @@
1
1
  module Translatomatic
2
2
  module Model
3
+ # Text database record.
4
+ # Used to store translations in the database.
3
5
  class Text < ActiveRecord::Base
4
6
  belongs_to :locale, class_name: "Translatomatic::Model::Locale"
5
7
  belongs_to :from_text, class_name: "Translatomatic::Model::Text"
@@ -1,3 +1,4 @@
1
+ # Contains classes that interface to records in the translatomatic database
1
2
  module Translatomatic::Model; end
2
3
 
3
4
  require 'translatomatic/model/locale'
@@ -1,24 +1,89 @@
1
1
  module Translatomatic
2
- class Option
3
- attr_reader :name, :required, :use_env, :description
4
-
2
+ # Stores details about command line and object constructor options
3
+ class Option
4
+ # @return [String] Name of the option
5
+ attr_reader :name
6
+
7
+ # @return [boolean] True if this option is required
8
+ attr_reader :required
9
+
10
+ # @return [boolean] If true, the option can be set via an environment
11
+ # variable corresponding to the uppercased version of {name}.
12
+ attr_reader :use_env
13
+
14
+ # @return [String] Description of the option
15
+ attr_reader :description
16
+
17
+ # @return [boolean] If true, the option does not appear on the command line
18
+ # but it can be used in configuration settings
19
+ attr_reader :hidden
20
+
21
+ # @return [Symbol] Type of option, one of:
22
+ # :string, :hash, :array, :numeric, or :boolean
23
+ attr_reader :type
24
+
25
+ # @return [Object] The default value for this option
26
+ attr_reader :default
27
+
28
+ # Create a new option
29
+ # @param data [Hash<Symbol,Object>] Attributes as above
30
+ # @return [Translatomatic::Option] A new option instance
5
31
  def initialize(data = {})
6
32
  @name = data[:name]
7
33
  @required = data[:required]
8
34
  @use_env = data[:use_env]
9
- @description = data[:desc]
35
+ @description = data[:desc]
36
+ @hidden = data[:hidden]
37
+ @default = data[:default]
38
+ @type = data[:type] || :string
10
39
  @data = data
11
40
  end
12
-
13
- def to_hash
14
- @data
41
+
42
+ # @return [Hash] Option data as a hash
43
+ def to_hash
44
+ @data
45
+ end
46
+
47
+ # Retrieve all options from an object or list of objects.
48
+ # @param object [#options,Array<#options>] Options source
49
+ # @return [Array<Translatomatic::Option>] options
50
+ def self.options_from_object(object)
51
+ options = []
52
+ if object.respond_to?(:options)
53
+ options += options_from_object(object.options)
54
+ elsif object.kind_of?(Array)
55
+ object.each do |item|
56
+ if item.kind_of?(Translatomatic::Option)
57
+ options << item
58
+ elsif item.respond_to?(:options)
59
+ options += options_from_object(item.options)
60
+ end
61
+ end
62
+ end
63
+ options
15
64
  end
16
65
  end
66
+
67
+ private
17
68
 
69
+ # @!visibility private
18
70
  module DefineOptions
19
- private
20
- def define_options(*options)
21
- @options = options.collect { |i| Translatomatic::Option.new(i) }
71
+
72
+ # @!visibility private
73
+ module ClassMethods
74
+ attr_reader :options
75
+
76
+ private
77
+
78
+ def define_options(*options)
79
+ @options = options.collect { |i| Translatomatic::Option.new(i) }
80
+ end
81
+ end
82
+
83
+ private
84
+
85
+ def self.included(klass)
86
+ klass.extend(ClassMethods)
22
87
  end
23
88
  end
24
89
  end
@@ -1,15 +1,19 @@
1
1
  # implements Converter listener
2
2
  class Translatomatic::ProgressUpdater
3
+ # Create a new progress updater
4
+ # @param progressbar [Progressbar] A ruby-progressbar object
3
5
  def initialize(progressbar)
4
6
  @progressbar = progressbar
5
7
  end
6
8
 
9
+ # @return [Number] the number of translated strings
7
10
  def translated_texts(texts)
8
- @progressbar.progress += texts.length
11
+ @progressbar.progress += texts.length
9
12
  end
10
-
13
+
14
+ # @return [Number] the number of untranslated strings
11
15
  def untranslated_texts(texts)
12
- @progressbar.total -= texts.length
16
+ @progressbar.total -= texts.length
13
17
  end
14
18
 
15
19
  end
@@ -1,3 +1,4 @@
1
+ # Base class for resource file implementations
1
2
  # @abstract Subclasses implement different types of resource files
2
3
  class Translatomatic::ResourceFile::Base
3
4
 
@@ -15,13 +16,13 @@ class Translatomatic::ResourceFile::Base
15
16
  # Create a new resource file.
16
17
  # If locale is unspecified, attempts to determine the locale of the file
17
18
  # automatically, and if that fails, uses the default locale.
18
- # @param [String] path Path to the file
19
- # @param [String] locale Locale of the file contents
19
+ # @param path [String] Path to the file
20
+ # @param locale [String] Locale of the file contents
20
21
  # @return [Translatomatic::ResourceFile::Base] the resource file.
21
22
  def initialize(path, locale = nil)
22
23
  @path = path.kind_of?(Pathname) ? path : Pathname.new(path)
23
- @locale = locale || detect_locale || Translatomatic::Locale.default
24
- raise "unable to determine locale" unless @locale && @locale.language
24
+ @locale = Translatomatic::Locale.parse(locale || detect_locale || Translatomatic::Locale.default)
25
+ raise t("resource.unknown_locale") unless @locale && @locale.language
25
26
  @valid = false
26
27
  @properties = {}
27
28
  end
@@ -32,7 +33,7 @@ class Translatomatic::ResourceFile::Base
32
33
  end
33
34
 
34
35
  # Create a path for the current resource file with a given locale
35
- # @param [String] locale for the path
36
+ # @param locale [String] The target locale
36
37
  # @return [Pathname] The path of this resource file modified for the given locale
37
38
  def locale_path(locale)
38
39
  basename = path.sub_ext('').basename.to_s
@@ -54,7 +55,7 @@ class Translatomatic::ResourceFile::Base
54
55
  end
55
56
 
56
57
  # Set all properties
57
- # @param [Hash<String,String>] properties New properties
58
+ # @param properties [Hash<String,String>] New properties
58
59
  def properties=(properties)
59
60
  # use set rather that set @properties directly as subclasses override set()
60
61
  properties.each do |key, value|
@@ -63,18 +64,18 @@ class Translatomatic::ResourceFile::Base
63
64
  end
64
65
 
65
66
  # Get the value of a property
66
- # @param [String] name The name of the property
67
+ # @param key [String] The name of the property
67
68
  # @return [String] The value of the property
68
- def get(name)
69
- @properties[name]
69
+ def get(key)
70
+ @properties[key]
70
71
  end
71
72
 
72
73
  # Set a property
73
- # @param [String] key The name of the property
74
- # @param [String] value The new value of the property
74
+ # @param key [String] The name of the property
75
+ # @param value [String] The new value of the property
75
76
  # @return [String] The new value of the property
76
- def set(name, value)
77
- @properties[name] = value
77
+ def set(key, value)
78
+ @properties[key] = value
78
79
  end
79
80
 
80
81
  # Test if the current resource file is valid
@@ -84,8 +85,8 @@ class Translatomatic::ResourceFile::Base
84
85
  end
85
86
 
86
87
  # Save the resource file.
87
- # @param [Pathname] target The destination path
88
- # @param [Hash<Symbol, Object>] options Output format options
88
+ # @param target [Pathname] The destination path
89
+ # @param options [Hash<Symbol, Object>] Output format options
89
90
  # @return [void]
90
91
  def save(target = path, options = {})
91
92
  raise "save(path) must be implemented by subclass"
@@ -93,9 +94,10 @@ class Translatomatic::ResourceFile::Base
93
94
 
94
95
  # @return [String] String representation of this file
95
96
  def to_s
96
- "#{path.basename.to_s} (#{locale})"
97
+ path.basename.to_s
97
98
  end
98
99
 
100
+ # @return [Array<String>] All property values split into sentences
99
101
  def sentences
100
102
  sentences = []
101
103
  properties.values.each do |value|
@@ -105,13 +107,34 @@ class Translatomatic::ResourceFile::Base
105
107
  sentences
106
108
  end
107
109
 
110
+ # @return [boolean] true if this resource file supports variable interpolation
111
+ def supports_variable_interpolation?
112
+ false
113
+ end
114
+
115
+ # Create an interpolated variable string.
116
+ # @return [String] A string representing the interpolated variable, or
117
+ # nil if this resource file doesn't support variable interpolation.
118
+ def create_variable(name)
119
+ return nil unless supports_variable_interpolation?
120
+ raise "create_variable(name) must be implemented by subclass"
121
+ end
122
+
123
+ # @return [Regexp] A regexp used to match interpolated variables
124
+ def variable_regex
125
+ return nil unless supports_variable_interpolation?
126
+ raise "variable_regex must be implemented by subclass"
127
+ end
128
+
108
129
  private
109
130
 
110
131
  include Translatomatic::Util
111
132
 
112
133
  def created_by
113
- date = DateTime.now.strftime("%Y-%m-%d %H:%M")
114
- "Created by Translatomatic #{Translatomatic::VERSION} #{date}"
134
+ t("resource.created_by", app: "Translatomatic",
135
+ version: Translatomatic::VERSION, date: I18n.l(DateTime.now),
136
+ locale: locale.language
137
+ )
115
138
  end
116
139
 
117
140
  # detect locale from filename
@@ -1,4 +1,5 @@
1
1
  module Translatomatic::ResourceFile
2
+ # HTML resource file
2
3
  class HTML < XML
3
4
 
4
5
  # (see Translatomatic::ResourceFile::Base.extensions)
@@ -17,30 +18,26 @@ module Translatomatic::ResourceFile
17
18
  return strip_extensions.sub_ext("." + new_extension)
18
19
  else
19
20
  # add locale extension
20
- ext = path.extname
21
+ ext = path.extname
21
22
  # TODO: need configurable order for locale & ext here?
22
- #path.sub_ext("#{ext}." + locale.to_s)
23
+ #path.sub_ext("#{ext}." + locale.to_s)
23
24
  path.sub_ext("." + locale.to_s + ext)
24
25
  end
25
26
  end
26
27
 
27
28
  # (see Translatomatic::ResourceFile::Base#save)
28
- def save(target = path, options = {})
29
- if @doc
30
- add_created_by unless options[:no_created_by]
31
- target.write(@doc.to_html)
29
+ def save(target = path, options = {})
30
+ if @doc
31
+ add_created_by unless options[:no_created_by]
32
+ target.write(@doc.to_html)
32
33
  end
33
34
  end
34
35
 
35
36
  private
36
-
37
- def text_nodes_xpath
38
- '//*[not(self::code)]/text()'
39
- end
40
-
41
- def add_created_by
42
- @created_by ||= @doc.root.add_previous_sibling(comment(created_by))
43
- end
37
+
38
+ def text_nodes_xpath
39
+ '//*[not(self::code)]/text()'
40
+ end
44
41
 
45
42
  def read_doc(path)
46
43
  Nokogiri::HTML(path.open) do |config|
@@ -2,6 +2,7 @@ require 'kramdown'
2
2
  require 'reverse_markdown'
3
3
 
4
4
  module Translatomatic::ResourceFile
5
+ # Markdown resource file
5
6
  class Markdown < HTML
6
7
 
7
8
  # (see Translatomatic::ResourceFile::Base.extensions)
@@ -10,17 +11,17 @@ module Translatomatic::ResourceFile
10
11
  end
11
12
 
12
13
  # (see Translatomatic::ResourceFile::Base#save)
13
- def save(target = path, options = {})
14
- if @doc
15
- begin
16
- add_created_by unless options[:no_created_by]
17
- html = @doc.to_html
18
- # convert html back to markdown
19
- markdown = ReverseMarkdown.convert(html, unknown_tags: :bypass)
20
- target.write(markdown.chomp)
21
- rescue Exception => e
22
- puts "error: #{e.message}"
23
- end
14
+ def save(target = path, options = {})
15
+ if @doc
16
+ begin
17
+ add_created_by unless options[:no_created_by]
18
+ html = @doc.to_html
19
+ # convert html back to markdown
20
+ markdown = ReverseMarkdown.convert(html, unknown_tags: :bypass)
21
+ target.write(markdown.chomp)
22
+ rescue Exception => e
23
+ log.error t("resource.error", message: e.message)
24
+ end
24
25
  end
25
26
  end
26
27
 
@@ -44,7 +45,7 @@ module Translatomatic::ResourceFile
44
45
  end
45
46
  init_nodemap(@doc)
46
47
  rescue Exception => e
47
- log.error(e.message)
48
+ log.error t("resource.error", message: e.message)
48
49
  @valid = false
49
50
  {}
50
51
  end
@@ -1,25 +1,14 @@
1
1
  module Translatomatic::ResourceFile
2
+ # Property list resource file
3
+ # @see https://en.wikipedia.org/wiki/Property_list
2
4
  class Plist < XML
5
+ include Translatomatic::ResourceFile::XCodeStringsLocalePath
3
6
 
4
7
  # (see Translatomatic::ResourceFile::Base.extensions)
5
8
  def self.extensions
6
9
  %w{plist}
7
10
  end
8
11
 
9
- # (see Translatomatic::ResourceFile::Base#locale_path)
10
- # @note localization files in XCode use the following file name
11
- # convention: Project/locale.lproj/filename
12
- # @todo refactor this and xcode_strings.rb to use the same code
13
- def locale_path(locale)
14
- if path.to_s.match(/\/([-\w]+).lproj\/.+.plist$/)
15
- # xcode style
16
- filename = path.basename
17
- path.parent.parent + (locale.to_s + ".lproj") + filename
18
- else
19
- super(locale)
20
- end
21
- end
22
-
23
12
  private
24
13
 
25
14
  def text_nodes_xpath