poesie 1.3.0 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8f8bff2658b4d9825300ecb79bd1836dec4aa4cb
4
- data.tar.gz: c8a17bc54ad8bcc73bf98c5edaede5aafcba2a4c
3
+ metadata.gz: 3faa652a9f6ad87e650ba88a394d2f5d577e66b3
4
+ data.tar.gz: 40ede2cb29bea6fd4abc16d0b27bb13daf00a308
5
5
  SHA512:
6
- metadata.gz: 31faa35c132decdc0bcc018eca372d767dbe951b5b3ad09c03180f6cb41a3c1fc0fc1d1d6960e39dc1adb716f746a2f51690f77663b174072ff1aeb8b83e0e1b
7
- data.tar.gz: 4d54dbbbc8abbdd960fd4e3af1074d862469e4d0e57cc10788b82882190e8c06e1baff590c88e286f10877b1506b75485484e98bceffaeeb554164d0ec485d78
6
+ metadata.gz: 3d20a015a7232e8973d5a86ff956c5bb35fa1295889db5d3d70af44eee44077aa7d0b5dd9ec238a5a44b14457964baf4db7daeca4cef56a0531e2417b6389548
7
+ data.tar.gz: dc1cfc402b131d401c0f0c0384ec5e06246f7882ce9d87002bc41cf59c19bd705d9a2fd1c7bae5f3d18a3d270e8fe50710106fcc58f20f820a8fff0e30dd79db
data/README.md CHANGED
@@ -29,11 +29,19 @@ Even though POEditor's web interface allows you to export the strings in those f
29
29
 
30
30
  ## Installation
31
31
 
32
+ The easiest solution to install the latest version of `poesie` is to simply run:
33
+
34
+ ```sh
35
+ gem install poesie
36
+ ```
37
+
38
+ Alternatively, the following solutions will allow you to install the latest version from master, so that you can use the newest features even if they haven't been released to RubyGems yet:
39
+
32
40
  <details>
33
- <summary>Solution 1: Clone the repo</summary>
41
+ <summary>Alternate Solution 1: Clone the repo and use it directly</summary>
34
42
 
35
43
  * `git clone` the project on you computer
36
- * Install `bundler` using `gem install bundler` if you don't have it already
44
+ * If you don't have it already, install `bundler` using `gem install bundler`
37
45
  * Install `poesie`'s dependencies by running `bundle install` from the directory where you cloned the repository
38
46
  * Invoke the tool using its full path `<path/where/you/cloned/Poesie>/bin/poesie`.
39
47
 
@@ -42,15 +50,16 @@ You could also add the `<path/where/you/cloned/Poesie>/bin/` path to your `PATH`
42
50
  </details>
43
51
 
44
52
  <details>
45
- <summary>Solution 2: Build and install it as a gem</summary>
53
+ <summary>Alternate Solution 2: Build and install the gem yourself</summary>
46
54
 
47
55
  * `git clone` the project on you computer
48
56
  * Run `gem build poesie.gemspec` to build the gem
49
- * Run `gem install poesie-*.gem` to install the gem you just built (`*` will be the version of the gem)
57
+ * Run `gem install poesie-*.gem` to install the gem you just built (where `*` is the version of the gem)
50
58
  * Now that it's installed in your system, you can invoke the tool using `poesie` from anywhere
51
59
 
52
- </details>
60
+ _This solution has the drawback of being potentially easily confused between versions of `poesie` that you installed yourself vs. official versions though._
53
61
 
62
+ </details>
54
63
 
55
64
  ## Using POEditor properly
56
65
 
@@ -112,7 +121,7 @@ Usage: poesie [options]
112
121
  -a, --android PATH Path of the Android strings.xml file path to generate
113
122
  -c, --context PATH Path of the *.json file to generate for contexts
114
123
  -d, --date Generate the current date in file headers
115
- -r, --replacements FILE Path to a YAML file listing all replacements
124
+ -s, --subst FILE Path to a YAML file listing all text substitutions
116
125
  -h, --help Show this message
117
126
  -v, --version Show version
118
127
  ```
@@ -147,12 +156,12 @@ This can be useful:
147
156
  * Either to use that JSON file directly in your project to do whatever you want with the contexts (e.g. parsing the JSON file at runtime using `JSONSerialization`, and use it as you please)
148
157
  * Or use that JSON file with a template engine (like [Liquid](https://github.com/Shopify/liquid)) to generate code specific to your needs. See the example script in `examples/gen-context-with-liquid.rb`.
149
158
 
150
- ## Providing text replacements
159
+ ## Providing text substitutions
151
160
 
152
- In case you need replacements to be applied to your translations, you can use the `--replacements` flag (`-r` for short) to provide a YAML file listing all replacements to be applied.
161
+ In case you need substitutions to be applied to your translations, you can use the `--subst` flag (`-s` for short) to provide a YAML file listing all substitutions to be applied.
153
162
 
154
163
  ```
155
- $ poesie --token "..." --project "..." --lang fr --ios .../localizable.strings -r replacements.yaml
164
+ $ poesie --token "..." --project "..." --lang fr --ios .../localizable.strings -s substitutions.yaml
156
165
  ```
157
166
 
158
167
  This can be useful:
@@ -163,16 +172,51 @@ This can be useful:
163
172
  * To ensure proper capitalization and orthography of your brand name every time it's spelled in the translations
164
173
  * etc.
165
174
 
166
- The YAML file provided must be of the form of a single Hash of String pairs, for example:
175
+ The YAML file provided must be of the form of a single Hash of String pairs, or an Array listing Hashes of String pairs.
176
+
177
+ * Substitutions will be performed in the given order if listed in an Array.
178
+ * Order of substitutions isn't guaranteed if they are listed in a Hash. That's why it's sometimes preferable to use an Array of key/value pairs rather than a Hash (because an Array is ordered)
179
+ * If a key is surrounded with slashes, it will be interpreted as a regular expression.
180
+
181
+ **Example:**
167
182
 
168
183
  ```yaml
169
- " :": "\u00A0:"
170
- " ;": "\u00A0;"
171
- " !": "\u00A0!"
172
- " ?": "\u00A0?"
173
- "...": "…"
184
+ - " :": "\u00A0:"
185
+ " ;": "\u00A0;"
186
+ " !": "\u00A0!"
187
+ " ?": "\u00A0?"
188
+ - "...": "…"
189
+ - /^\s+/: ""
190
+ /\s+$/: ""
174
191
  ```
175
192
 
176
- _Note: given that the JSON format is a subset of the YAML format, using a JSON file is also possible, as long as it still represents a dictionary with Strings as keys and as values._
193
+ In this example:
194
+
195
+ * The first substitutions to be applied will be the 4 first ones about the `:;!?` punctuation. The order of the substitutions between those 4 is undetermined (as Hashes are unordered).
196
+ * Then the substitution of `...` to `…` will be applied
197
+ * The last two substitutions are interpreted as Regular Expressions, trimming the beginning and end of each text. They will be applied last (but those two will be applied in any order w/r/t each other).
198
+
199
+ <details>
200
+ <summary>_Note: given that the JSON format is a subset of the YAML format, using a JSON file to represent the same substitutions is also possible._</summary>
201
+
202
+ ```json
203
+ [
204
+ {
205
+ " :": " :",
206
+ " ;": " ;",
207
+ " !": " !",
208
+ " ?": " ?"
209
+ },
210
+ {
211
+ "...": "…"
212
+ },
213
+ {
214
+ "/^\\s+/": "",
215
+ "/\\s+$/": ""
216
+ }
217
+ ]
218
+ ```
219
+
220
+ </details>
177
221
 
178
- You can find an example of a YAML file in `examples/replacements.yaml` in this repository.
222
+ You can find an example of a YAML file in `examples/substitutions.yaml` in this repository.
data/bin/poesie CHANGED
@@ -11,7 +11,8 @@ end
11
11
  begin
12
12
  require 'optparse'
13
13
  require 'yaml'
14
- require 'poesie'
14
+ require File.expand_path('../lib/poesie', File.dirname(__FILE__))
15
+ require File.expand_path('../lib/version', File.dirname(__FILE__))
15
16
  rescue LoadError => e
16
17
  abort 'error: missing some dependencies for poesie. Be sure to install it using `gem install` or to run `bundle installl` to install dependencies - ' + e.message
17
18
  end
@@ -24,7 +25,7 @@ options = {
24
25
  :strings_xml => nil,
25
26
  :context_file => nil,
26
27
  :print_date => false,
27
- :replacements => nil
28
+ :substitutions => nil
28
29
  }
29
30
 
30
31
  opts = OptionParser.new do |opts|
@@ -50,16 +51,17 @@ opts = OptionParser.new do |opts|
50
51
  opts.on('-d', '--date', %q(Generate the current date in file headers)) do
51
52
  options[:print_date] = true
52
53
  end
53
- opts.on('-r FILE', '--replacements FILE', %q(Path to a YAML file listing all replacements)) do |path|
54
- Poesie.exit_with_error("The replacements file #{path} was not found") unless File.exists?(path)
54
+ opts.on('-s FILE', '--subst FILE', %q(Path to a YAML file listing all substitutions)) do |path|
55
+ Poesie.exit_with_error("The substitutions file #{path} was not found") unless File.exists?(path)
55
56
  begin
56
- dict = YAML.load_file(path)
57
+ subst = YAML.load_file(path)
57
58
  rescue Psych::SyntaxError => e
58
59
  Poesie.exit_with_error("Invalid YAML file #{e.message}")
59
60
  end
60
- valid = dict.keys.all? { |k| k.is_a?(String) } && dict.values.all? { |k| k.is_a?(String) }
61
- Poesie.exit_with_error("The provided replacements file #{path} should only contain a Dictionary with String keys and values") unless valid
62
- options[:replacements] = dict
61
+ subst = [subst] if subst.is_a?(Hash)
62
+ valid = subst.all? { |hash| hash.keys.all? { |k| k.is_a?(String) } && hash.values.all? { |k| k.is_a?(String) } }
63
+ Poesie.exit_with_error("The provided substitutions file #{path} should only contain a (Array of) Hashes with String keys and values") unless valid
64
+ options[:substitutions] = subst
63
65
  end
64
66
  opts.on_tail('-h', '--help', %q(Show this message)) { puts opts; exit 1 }
65
67
  opts.on_tail('-v', '--version', 'Show version') { puts Poesie::VERSION; exit }
@@ -81,14 +83,14 @@ Poesie.exit_with_error('You need to specify your POEditor project language using
81
83
 
82
84
  # iOS
83
85
  unless options[:localizable_strings].nil?
84
- Log::title('== iOS ==')
86
+ Poesie::Log::title('== iOS ==')
85
87
  exporter.run(options[:lang]) do |terms|
86
88
  # Localizable.strings
87
- Log::subtitle("== Language #{options[:lang]} ==")
89
+ Poesie::Log::subtitle("== Language #{options[:lang]} ==")
88
90
  Poesie::AppleFormatter::write_strings_file(
89
91
  terms,
90
92
  options[:localizable_strings],
91
- replacements: options[:replacements],
93
+ substitutions: options[:substitutions],
92
94
  print_date: options[:print_date]
93
95
  )
94
96
 
@@ -97,13 +99,13 @@ unless options[:localizable_strings].nil?
97
99
  Poesie::AppleFormatter::write_stringsdict_file(
98
100
  terms,
99
101
  strings_dict_path,
100
- replacements: options[:replacements],
102
+ substitutions: options[:substitutions],
101
103
  print_date: options[:print_date]
102
104
  )
103
105
 
104
106
  # Context.json (if specified)
105
107
  if options[:context_file]
106
- Log::subtitle("== Context #{options[:context_file]} ==")
108
+ Poesie::Log::subtitle("== Context #{options[:context_file]} ==")
107
109
  Poesie::AppleFormatter::write_context_json(terms, options[:context_file])
108
110
  end
109
111
  end
@@ -111,14 +113,14 @@ end
111
113
 
112
114
  # Android
113
115
  unless options[:strings_xml].nil?
114
- Log::title('== Android ==')
116
+ Poesie::Log::title('== Android ==')
115
117
  exporter.run(options[:lang]) do |terms|
116
118
  # Strings.xml
117
- Log::subtitle("== Language #{options[:lang]} ==")
119
+ Poesie::Log::subtitle("== Language #{options[:lang]} ==")
118
120
  Poesie::AndroidFormatter::write_strings_xml(
119
121
  terms,
120
122
  options[:strings_xml],
121
- replacements: options[:replacements],
123
+ substitutions: options[:substitutions],
122
124
  print_date: options[:print_date]
123
125
  )
124
126
  end
@@ -9,15 +9,16 @@ module Poesie
9
9
  # The json parsed terms exported by POEditor and sorted alphabetically
10
10
  # @param [String] file
11
11
  # The path to the file to write the content to
12
- # @param [Hash<String,String>] replacements
13
- # The list of replacements to apply to the translations
12
+ # @param [Hash<String,String>] substitutions
13
+ # The list of substitutions to apply to the translations
14
14
  # @param [Bool] print_date
15
15
  # Should we print the date in the header of the generated file
16
16
  #
17
- def self.write_strings_xml(terms, file, replacements: nil, print_date: false)
17
+ def self.write_strings_xml(terms, file, substitutions: nil, print_date: false)
18
+ stats = { :ios => 0, :nil => [], :count => 0 }
19
+
18
20
  Log::info(" - Save to file: #{file}")
19
- fh = File.open(file, "w")
20
- begin
21
+ File.open(file, "w") do |fh|
21
22
  xml_builder = Builder::XmlMarkup.new(:target => fh, :indent => 4)
22
23
  xml_builder.instruct!
23
24
  xml_builder.comment!("Exported from POEditor ")
@@ -26,25 +27,32 @@ module Poesie
26
27
  xml_builder.resources do |resources_node|
27
28
  terms.each do |term|
28
29
  (term, definition, plurals, comment, context) = ['term', 'definition', 'term_plural', 'comment', 'context'].map { |k| term[k] }
29
- # Skip ugly cases if POEditor is buggy for some entries
30
- next if term.nil? || term.empty? || definition.nil?
31
- next if term =~ /_ios$/
30
+
31
+ # Filter terms and update stats
32
+ next if (term.nil? || term.empty? || definition.nil?) && stats[:nil] << term
33
+ next if (term =~ /_ios$/) && stats[:ios] += 1
34
+ stats[:count] += 1
35
+
32
36
  xml_builder.comment!(context) unless context.empty?
33
37
  if plurals.empty?
34
- definition = Poesie::process(definition, replacements).gsub('"', '\\"')
38
+ definition = Poesie::process(definition, substitutions).gsub('"', '\\"')
35
39
  resources_node.string("\"#{definition}\"", :name => term)
36
40
  else
37
41
  resources_node.plurals(:name => plurals) do |plurals_node|
38
42
  definition.each do |plural_quantity, plural_value|
39
- plural_value = Poesie::process(plural_value, replacements).gsub('"', '\\"')
43
+ plural_value = Poesie::process(plural_value, substitutions).gsub('"', '\\"')
40
44
  plurals_node.item("\"#{plural_value}\"", :quantity => plural_quantity)
41
45
  end
42
46
  end
43
47
  end
44
48
  end
45
49
  end
46
- ensure
47
- fh.close
50
+ end
51
+
52
+ Log::info(" [Stats] #{stats[:count]} strings processed (Filtered out #{stats[:ios]} iOS strings)")
53
+ unless stats[:nil].empty?
54
+ Log::error(" Found #{stats[:nil].count} empty value(s) for the following term(s):")
55
+ stats[:nil].each { |key| Log::error(" - #{key.inspect}") }
48
56
  end
49
57
  end
50
58
  end
@@ -9,23 +9,23 @@ module Poesie
9
9
  # JSON returned by the POEditor API
10
10
  # @param [String] file
11
11
  # The path of the file to write
12
- # @param [Hash<String,String>] replacements
13
- # The list of replacements to apply to the translations
12
+ # @param [Hash<String,String>] substitutions
13
+ # The list of substitutions to apply to the translations
14
14
  # @param [Bool] print_date
15
15
  # Should we print the date in the header of the generated file
16
16
  #
17
- def self.write_strings_file(terms, file, replacements: nil, print_date: false)
17
+ def self.write_strings_file(terms, file, substitutions: nil, print_date: false)
18
18
  out_lines = ['/'+'*'*79, ' * Exported from POEditor - https://poeditor.com']
19
19
  out_lines << " * #{Time.now}" if print_date
20
20
  out_lines += [' '+'*'*79+'/', '']
21
21
  last_prefix = ''
22
- stats = { :android => 0, :nil => 0, :count => 0 }
22
+ stats = { :android => 0, :nil => [], :count => 0 }
23
23
 
24
24
  terms.each do |term|
25
25
  (term, definition, comment, context) = ['term', 'definition', 'comment', 'context'].map { |k| term[k] }
26
26
 
27
27
  # Filter terms and update stats
28
- next if (term.nil? || term.empty? || definition.nil? || definition.empty?) && stats[:nil] += 1
28
+ next if (term.nil? || term.empty? || definition.nil? || definition.empty?) && stats[:nil] << term
29
29
  next if (term =~ /_android$/) && stats[:android] += 1 # Remove android-specific strings
30
30
  stats[:count] += 1
31
31
 
@@ -42,7 +42,7 @@ module Poesie
42
42
  definition = definition["one"]
43
43
  end
44
44
 
45
- definition = Poesie::process(definition, replacements)
45
+ definition = Poesie::process(definition, substitutions)
46
46
  .gsub("\u2028", '') # Sometimes inserted by the POEditor exporter
47
47
  .gsub("\n", '\n') # Replace actual CRLF with '\n'
48
48
  .gsub('"', '\\"') # Escape quotes
@@ -53,12 +53,15 @@ module Poesie
53
53
 
54
54
  content = out_lines.join("\n") + "\n"
55
55
 
56
-
57
- Log::info(" [Stats] #{stats[:count]} strings processed (Filtered out #{stats[:android]} android strings, #{stats[:nil]} nil entries)")
58
56
  Log::info(" - Save to file: #{file}")
59
57
  File.open(file, "w") do |fh|
60
58
  fh.write(content)
61
59
  end
60
+ Log::info(" [Stats] #{stats[:count]} strings processed (Filtered out #{stats[:android]} android strings)")
61
+ unless stats[:nil].empty?
62
+ Log::error(" Found #{stats[:nil].count} empty value(s) for the following term(s):")
63
+ stats[:nil].each { |key| Log::error(" - #{key.inspect}") }
64
+ end
62
65
  end
63
66
 
64
67
  # Write the Localizable.stringsdict output file
@@ -67,17 +70,16 @@ module Poesie
67
70
  # JSON returned by the POEditor API
68
71
  # @param [String] file
69
72
  # The path of the file to write
70
- # @param [Hash<String,String>] replacements
71
- # The list of replacements to apply to the translations
73
+ # @param [Hash<String,String>] substitutions
74
+ # The list of substitutions to apply to the translations
72
75
  # @param [Bool] print_date
73
76
  # Should we print the date in the header of the generated file
74
77
  #
75
- def self.write_stringsdict_file(terms, file, replacements: nil, print_date: false)
76
- stats = { :android => 0, :nil => 0, :count => 0 }
78
+ def self.write_stringsdict_file(terms, file, substitutions: nil, print_date: false)
79
+ stats = { :android => 0, :nil => [], :count => 0 }
77
80
 
78
81
  Log::info(" - Save to file: #{file}")
79
- fh = File.open(file, "w")
80
- begin
82
+ File.open(file, "w") do |fh|
81
83
  xml_builder = Builder::XmlMarkup.new(:target => fh, :indent => 4)
82
84
  xml_builder.instruct!
83
85
  xml_builder.comment!("Exported from POEditor ")
@@ -89,14 +91,13 @@ module Poesie
89
91
  (term, term_plural, definition) = ['term', 'term_plural', 'definition'].map { |k| term[k] }
90
92
 
91
93
  # Filter terms and update stats
92
- next if (term.nil? || term.empty? || definition.nil?) && stats[:nil] += 1
94
+ next if (term.nil? || term.empty? || definition.nil?) && stats[:nil] << term
93
95
  next if (term =~ /_android$/) && stats[:android] += 1 # Remove android-specific strings
94
96
  next unless definition.is_a? Hash
95
97
  stats[:count] += 1
96
98
 
97
99
  key = term_plural || term
98
100
 
99
-
100
101
  root_node.key(key)
101
102
  root_node.dict do |dict_node|
102
103
  dict_node.key('NSStringLocalizedFormatKey')
@@ -109,7 +110,8 @@ module Poesie
109
110
  format_node.string('d')
110
111
 
111
112
  definition.each do |(quantity, text)|
112
- text = Poesie::process(text, replacements)
113
+ text = Poesie::process(text, substitutions)
114
+ text = Poesie::process(text, substitutions)
113
115
  .gsub("\u2028", '') # Sometimes inserted by the POEditor exporter
114
116
  .gsub('\n', "\n") # Replace '\n' with actual CRLF
115
117
  .gsub(/%(\d+\$)?s/, '%\1@') # replace %s with %@ for iOS
@@ -121,8 +123,11 @@ module Poesie
121
123
  end
122
124
  end
123
125
  end
124
- ensure
125
- fh.close
126
+ end
127
+ Log::info(" [Stats] #{stats[:count]} strings processed (Filtered out #{stats[:android]} android strings)")
128
+ unless stats[:nil].empty?
129
+ Log::error(" Found #{stats[:nil].count} empty value(s) for the following term(s):")
130
+ stats[:nil].each { |key| Log::error(" - #{key.inspect}") }
126
131
  end
127
132
  end
128
133
 
@@ -162,11 +167,11 @@ module Poesie
162
167
 
163
168
  context_json = JSON.pretty_generate(json_hash)
164
169
 
165
- Log::info(" [Stats] #{stats[:count]} contexts processed (Filtered out #{stats[:android]} android entries, #{stats[:nil]} nil contexts)")
166
170
  Log::info(" - Save to file: #{file}")
167
171
  File.open(file, "w") do |fh|
168
172
  fh.write(context_json)
169
173
  end
174
+ Log::info(" [Stats] #{stats[:count]} contexts processed (Filtered out #{stats[:android]} android entries, #{stats[:nil]} nil contexts)")
170
175
  end
171
176
 
172
177
  end
data/lib/exporter.rb CHANGED
@@ -41,16 +41,15 @@ module Poesie
41
41
  # @return [String] URL of the exported file ready to be downloaded
42
42
  #
43
43
  def generate_export_uri(lang)
44
- uri = URI('https://poeditor.com/api/')
45
- res = Net::HTTP.post_form(uri, 'api_token' => @api_token, 'action' => 'export', 'id' => @project_id, 'type' => 'json', 'language' => lang)
44
+ uri = URI('https://api.poeditor.com/v2/projects/export')
45
+ res = Net::HTTP.post_form(uri, 'api_token' => @api_token, 'id' => @project_id, 'type' => 'json', 'language' => lang)
46
46
  json = JSON.parse(res.body)
47
- if json['response']['status'] != 'success'
47
+ unless json['response']['status'] == 'success'
48
48
  r = json['response']
49
49
  puts "Error #{r['code']} (#{r['status']})\n#{r['message']}"
50
50
  exit 1
51
- else
52
- json['item']
53
51
  end
52
+ json['result']['url']
54
53
  end
55
54
  end
56
55
  end
data/lib/log.rb ADDED
@@ -0,0 +1,24 @@
1
+ module Poesie
2
+ module Log
3
+ @@quiet = false
4
+ def self.quiet=(value)
5
+ @@quiet = value
6
+ end
7
+
8
+ def self.title(str) # bg yellow
9
+ puts "\e[44;37m#{str}\e[0m" unless @@quiet
10
+ end
11
+
12
+ def self.error(str)
13
+ puts "\e[1;31m! #{str}\e[0m" unless @@quiet
14
+ end
15
+
16
+ def self.info(str)
17
+ puts "\e[1;32m√ #{str}\e[0m" unless @@quiet
18
+ end
19
+
20
+ def self.subtitle(str)
21
+ puts "\e[1;33m√ #{str}\e[0m" unless @@quiet
22
+ end
23
+ end
24
+ end
data/lib/poesie.rb CHANGED
@@ -1,5 +1,4 @@
1
- require File.expand_path('utils/log', File.dirname(__FILE__))
2
-
1
+ require File.expand_path('log', File.dirname(__FILE__))
3
2
  require File.expand_path('exporter', File.dirname(__FILE__))
4
3
  require File.expand_path('android_formatter', File.dirname(__FILE__))
5
4
  require File.expand_path('apple_formatter', File.dirname(__FILE__))
@@ -12,18 +11,24 @@ module Poesie
12
11
  exit 1
13
12
  end
14
13
 
15
- # Apply the list of text replacements to the given string
14
+ # Apply the list of text substitutions to the given string
16
15
  #
17
16
  # @param [String] text
18
17
  # The text to process
19
- # @param [Hash<String,String>] replacements
20
- # The replacements to apply
18
+ # @param [Hash<String,String>] substitutions
19
+ # The substitutions to apply
21
20
  #
22
- def self.process(text, replacements)
23
- return text if replacements.nil?
21
+ def self.process(text, substitutions)
22
+ return text if substitutions.nil?
24
23
  replaced = text.dup
25
- replacements.each do |k,v|
26
- replaced.gsub!(k, v)
24
+ list = substitutions
25
+ list = [substitutions] if substitutions.is_a?(Hash)
26
+ list.each do |hash|
27
+ hash.each do |k,v|
28
+ # If the key is surrounding by slashes, interpret as a RegExp
29
+ k = Regexp.new($1) if k =~ %r(^/(.*)/$)
30
+ replaced.gsub!(k, v)
31
+ end
27
32
  end
28
33
  replaced
29
34
  end
data/lib/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Poesie
2
- VERSION = '1.3.0'
2
+ VERSION = '1.4.0'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: poesie
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Olivier Halligon
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2017-02-07 00:00:00.000000000 Z
12
+ date: 2017-02-08 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: net
@@ -67,8 +67,8 @@ files:
67
67
  - lib/android_formatter.rb
68
68
  - lib/apple_formatter.rb
69
69
  - lib/exporter.rb
70
+ - lib/log.rb
70
71
  - lib/poesie.rb
71
- - lib/utils/log.rb
72
72
  - lib/version.rb
73
73
  homepage: https://github.com/NijiDigital/poesie
74
74
  licenses:
@@ -90,9 +90,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
90
90
  version: '0'
91
91
  requirements: []
92
92
  rubyforge_project:
93
- rubygems_version: 2.4.7
93
+ rubygems_version: 2.6.7
94
94
  signing_key:
95
95
  specification_version: 4
96
96
  summary: Automate and post-process the export of POEditor strings
97
97
  test_files: []
98
- has_rdoc:
data/lib/utils/log.rb DELETED
@@ -1,23 +0,0 @@
1
- module Log
2
- @@quiet = false
3
- def self.quiet=(value)
4
- @@quiet = value
5
- end
6
-
7
- def self.title(str) # bg yellow
8
- puts "\e[44;37m#{str}\e[0m" unless @@quiet
9
- end
10
-
11
- def self.error(str)
12
- puts "\e[1;31m! #{str}\e[0m" unless @@quiet
13
- end
14
-
15
- def self.info(str)
16
- puts "\e[1;32m√ #{str}\e[0m" unless @@quiet
17
- end
18
-
19
- def self.subtitle(str)
20
- puts "\e[1;33m√ #{str}\e[0m" unless @@quiet
21
- end
22
-
23
- end