translatomatic 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
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