filter_rename 1.0.0 → 1.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.
@@ -1,9 +1,13 @@
1
- require 'delegate'
1
+ # frozen_string_literal: true
2
2
 
3
- module FilterRename
3
+ require "delegate"
4
+ require "keisan"
4
5
 
6
+ module FilterRename
7
+ #
5
8
  # This is the class which handles the list
6
9
  # of filters.
10
+ #
7
11
  class FilterList
8
12
  attr_reader :filters
9
13
 
@@ -12,35 +16,34 @@ module FilterRename
12
16
  end
13
17
 
14
18
  def expand_macros!(macro)
15
-
16
- @filters.each_with_index do |names , i|
17
-
18
- if FilterRename::MacroConfig == names.keys[0]
19
- z = 1
20
- names.values.pop.each do |n|
21
- macro.get_macro(n).each do |k, v|
22
- if v.nil? # Array
23
- @filters.insert(i + z, k.keys[0].to_s.to_filter => k[k.keys[0]])
24
- else # Hash
25
- @filters.insert(i + z, k.to_s.to_filter => v)
26
- end
27
- z += 1
19
+ @filters.each_with_index do |names, idx|
20
+ next unless names.keys[0] == FilterRename::MacroConfig
21
+
22
+ z = 1
23
+ names.values.pop.each do |n|
24
+ macro.get_macro(n).each do |k, v|
25
+ if v.nil? # Array
26
+ @filters.insert(idx + z, k.keys[0].to_s.to_filter => k[k.keys[0]])
27
+ else # Hash
28
+ @filters.insert(idx + z, k.to_s.to_filter => v)
28
29
  end
29
- @filters[i] = nil
30
+ z += 1
30
31
  end
32
+ @filters[idx] = nil
31
33
  end
32
34
  end
33
35
 
34
36
  @filters.delete_if(&:nil?)
35
37
  end
36
-
37
38
  end
38
39
 
39
-
40
+ #
41
+ # The base class for all type of
42
+ # filters.
43
+ #
40
44
  class FilterBase < SimpleDelegator
41
-
42
45
  def initialize(obj, options)
43
- super obj
46
+ super(obj)
44
47
  @dest = obj # useful for macros
45
48
  @cfg = options[:cfg]
46
49
  @words = options[:words]
@@ -51,15 +54,15 @@ module FilterRename
51
54
  end
52
55
 
53
56
  def set_config(name, value)
54
- raise InvalidFilterSetting, name unless @cfg.instance_variables.include?("@#{name}".to_sym)
57
+ raise InvalidFilterSetting, name unless @cfg.instance_variables.include?(:"@#{name}")
55
58
 
56
- @cfg.instance_variable_set ('@' + name.to_s), value
59
+ @cfg.instance_variable_set "@#{name}", value
57
60
  end
58
61
 
59
62
  def get_config(name)
60
- raise InvalidFilterSetting, name unless @cfg.instance_variables.include?("@#{name}".to_sym)
63
+ raise InvalidFilterSetting, name unless @cfg.instance_variables.include?(:"@#{name}")
61
64
 
62
- @cfg.instance_variable_get '@' + name.to_s
65
+ @cfg.instance_variable_get "@#{name}"
63
66
  end
64
67
 
65
68
  def filter(value)
@@ -67,18 +70,20 @@ module FilterRename
67
70
  end
68
71
 
69
72
  def set_string(value, target = nil)
73
+ return if value.nil?
74
+
70
75
  if target.nil?
71
- super @cfg.target, value
76
+ super(@cfg.target, value)
72
77
  else
73
- super target, value
78
+ super(target, value)
74
79
  end
75
80
  end
76
81
 
77
82
  def get_string(target = nil)
78
83
  if target.nil?
79
- super @cfg.target
84
+ super(@cfg.target)
80
85
  else
81
- super target
86
+ super
82
87
  end
83
88
  end
84
89
 
@@ -91,40 +96,80 @@ module FilterRename
91
96
  str
92
97
  end
93
98
 
99
+ def current_target
100
+ @cfg.target.to_s
101
+ end
94
102
  end
95
103
 
96
-
104
+ #
105
+ # Mixin module for all those filters
106
+ # that make use of indexes.
107
+ #
97
108
  module IndexedParams
109
+ attr_reader :params, :params_expanded, :items
98
110
 
99
- def get_indexes(params, callback)
111
+ def normalize_index(idx)
112
+ max_length = items.length
113
+ raise IndexOutOfRange, [idx, max_length] if idx.to_i > max_length || idx.to_i < -max_length
114
+
115
+ if idx.to_i.positive?
116
+ idx = idx.to_i.pred # % max_length
117
+ elsif idx.to_i.negative?
118
+ idx = idx.to_i + max_length # % max_length
119
+ end
120
+ idx.to_i
121
+ end
122
+
123
+ def indexes
100
124
  indexes = []
101
- params_length = (indexed_params == 0) ? params.length : indexed_params
125
+ params_length = indexed_params.zero? ? params.length : indexed_params
102
126
 
103
127
  params[0..params_length.pred].each do |x|
104
128
  if x =~ /\.\./
105
- indexes = indexes + Range.new(*(x.split('..').map {|y| send(callback, y, get_string) })).map { |i| i }
129
+ indexes += Range.new(*(x.split("..").map { |y| normalize_index(y) })).map { |idx| idx }
130
+ elsif x =~ /:/
131
+ indexes += x.split(":").map { |y| normalize_index(y) }
106
132
  else
107
- indexes << send(callback, x, get_string)
133
+ indexes << normalize_index(x)
108
134
  end
109
-
110
135
  end
111
136
 
112
137
  indexes
113
138
  end
114
139
 
140
+ def string_to_loop
141
+ get_string
142
+ end
143
+
115
144
  def indexed_params
116
145
  1
117
146
  end
118
- end
119
-
120
147
 
121
- class FilterWord < FilterBase
122
- include IndexedParams
148
+ def self_targeted?
149
+ false
150
+ end
123
151
 
124
152
  def filter(params)
125
- super loop_words(get_string, get_indexes(params, :word_idx), params)
153
+ @params = params
154
+ @items = indexed_items
155
+ @params_expanded = indexes
156
+
157
+ res = loop_items
158
+
159
+ if self_targeted?
160
+ super(get_string)
161
+ else
162
+ super(res)
163
+ end
126
164
  end
165
+ end
127
166
 
167
+ #
168
+ # Base class for all the word
169
+ # oriented filters
170
+ #
171
+ class FilterWord < FilterBase
172
+ include IndexedParams
128
173
 
129
174
  private
130
175
 
@@ -132,60 +177,116 @@ module FilterRename
132
177
  get_config(:word_separator)
133
178
  end
134
179
 
135
- def word_idx(idx, str)
136
- if idx.to_i.positive?
137
- idx = idx.to_i.pred
138
- elsif idx.to_i.negative?
139
- idx = idx.to_i + str.split(ws).length
140
- end
141
- idx.to_i
180
+ def indexed_items
181
+ string_to_loop.split(ws)
142
182
  end
143
183
 
144
- def loop_words(str, arr_index, params)
145
- str = str.split(ws)
184
+ def loop_items
185
+ str = items.clone
146
186
 
147
- arr_index.each_with_index do |idx, param_num|
148
- str[idx] = send :filtered_word, str[idx], params, param_num.next
187
+ params_expanded.each_with_index do |idx, param_num|
188
+ str[idx] = send :filtered_word, str[idx], param_num.next
149
189
  end
150
190
 
151
191
  str.delete_if(&:nil?).join(ws)
152
192
  end
153
-
154
193
  end
155
194
 
195
+ #
196
+ # Base class for all the number oriented
197
+ # filters.
198
+ #
156
199
  class FilterNumber < FilterBase
157
-
158
200
  include IndexedParams
159
201
 
160
- def filter(params)
161
- super loop_numbers(get_string, get_indexes(params, :num_idx), params)
162
- end
202
+ def self.calculator(num, expr)
203
+ @@calc ||= Keisan::Calculator.new
204
+ begin
205
+ @@calc.evaluate("gt()")
206
+ rescue StandardError
207
+ @@calc.define_function!(:gt, ->(x) { num > x })
208
+ @@calc.define_function!(:lt, ->(x) { num < x })
209
+ @@calc.define_function!(:gte, ->(x) { num >= x })
210
+ @@calc.define_function!(:lte, ->(x) { num <= x })
211
+ @@calc.define_function!(:inc, ->(x) { num + x })
212
+ @@calc.define_function!(:mult, ->(x) { num * x })
213
+ end
163
214
 
215
+ @@calc.evaluate(expr)
216
+ end
164
217
 
165
218
  private
166
219
 
167
- def num_idx(idx, str)
168
- if idx.to_i < 0
169
- idx = str.scan(/\d+/).length + idx.to_i
170
- elsif idx.to_i > 0
171
- idx = idx.to_i.pred
220
+ def ns
221
+ get_config(:number_separator)
222
+ end
223
+
224
+ def indexed_items
225
+ string_to_loop.numbers
226
+ end
227
+
228
+ def loop_items
229
+ str = string_to_loop
230
+ numbers = items.clone
231
+
232
+ params_expanded.each_with_index do |idx, param_idx|
233
+ numbers[idx] = send :filtered_number, numbers[idx], param_idx.next
234
+ end
235
+ str.map_number_with_index do |_num, idx|
236
+ numbers[idx]
172
237
  end
173
- idx.to_i
174
238
  end
239
+ end
175
240
 
176
- def loop_numbers(str, arr_index, params)
177
- arr_index.each_with_index do |idx, param_idx|
178
- str = str.map_number_with_index do |num, i|
179
- if idx == i
180
- num = self.send :filtered_number, num, params, param_idx.next
181
- end
241
+ #
242
+ # Base class for all the Regexp
243
+ # oriented filters.
244
+ #
245
+ class FilterRegExp < FilterBase
246
+ def filter(params)
247
+ super(loop_regex(get_string, params))
248
+ end
182
249
 
183
- num
250
+ private
251
+
252
+ def loop_regex(str, params)
253
+ str.gsub(Regexp.new(wrap_regex(params[0]), get_config(:ignore_case).to_boolean)) do |_x|
254
+ matches = Regexp.last_match.clone
255
+ send(:filtered_regexp, matches.to_a.delete_if(&:nil?), params).to_s.gsub(/\\([0-9]+)/) do |_y|
256
+ matches[::Regexp.last_match(1).to_i]
184
257
  end
185
258
  end
186
-
187
- str
188
259
  end
189
260
  end
190
261
 
262
+ #
263
+ # Base class for all the occurence
264
+ # oriented filters.
265
+ #
266
+ class FilterOccurrence < FilterBase
267
+ include IndexedParams
268
+
269
+ private
270
+
271
+ def os
272
+ get_config(:occurrence_separator)
273
+ end
274
+
275
+ def indexed_items
276
+ string_to_loop.scan(Regexp.new(params[indexed_params]))
277
+ end
278
+
279
+ def loop_items
280
+ str = string_to_loop
281
+ regexp = Regexp.new(params[indexed_params])
282
+ occurences = items.clone
283
+
284
+ params_expanded.each_with_index do |idx, param_idx|
285
+ occurences[idx] = send :filtered_occurrence, occurences[idx], param_idx.next
286
+ end
287
+ str.gsub(regexp).with_index do |_idxtem, _i|
288
+ occurences[idx]
289
+ end
290
+ end
291
+ end
191
292
  end
@@ -1,5 +1,10 @@
1
- module FilterRename
1
+ # frozen_string_literal: true
2
2
 
3
+ module FilterRename
4
+ #
5
+ # Class that handles the filters
6
+ # applying them one after one.
7
+ #
3
8
  class FilterPipe
4
9
  attr_reader :source, :dest
5
10
 
@@ -8,27 +13,25 @@ module FilterRename
8
13
  @cfg = cfg.filter.clone
9
14
  @source = FilenameFactory.create(fname, cfg.global)
10
15
  @dest = Marshal.load(Marshal.dump(@source))
11
- @filters = (filters.class == Array) ? filters : filters.filters
16
+ @filters = filters.instance_of?(Array) ? filters : filters.filters
12
17
  @words = cfg.words
13
18
  end
14
19
 
15
20
  def changed?
16
- ! unchanged?
21
+ !unchanged?
17
22
  end
18
23
 
19
24
  def unchanged?
20
25
  @source == @dest
21
26
  end
22
- alias_method :identical?, :unchanged?
27
+ alias identical? unchanged?
23
28
 
24
29
  def diff
25
30
  @source.diff(@dest)
26
31
  end
27
32
 
28
33
  def apply
29
-
30
- @filters.each_with_index do |f, i|
31
-
34
+ @filters.each_with_index do |f, _i|
32
35
  filter = f.keys.pop
33
36
  params = f.values.pop
34
37
 
@@ -37,7 +40,6 @@ module FilterRename
37
40
  else
38
41
  filter.new(@dest, cfg: @cfg, words: @words).filter(params) unless skip?
39
42
  end
40
-
41
43
  end
42
44
 
43
45
  self
@@ -50,15 +52,18 @@ module FilterRename
50
52
  private
51
53
 
52
54
  def skip?
53
- if [:full_filename, :full_path, :filename].include? @cfg.grep_target.to_sym
54
- unmatched = instance_variable_get('@' + @cfg.grep_on.to_s).send(@cfg.grep_target.to_sym).match(Regexp.new(@cfg.grep)).nil?
55
- else
56
- unmatched = instance_variable_get('@' + @cfg.grep_on.to_s).get_string(@cfg.grep_target).match(Regexp.new(@cfg.grep)).nil?
57
- end
55
+ grep_on = @cfg.grep_on_dest ? :dest : :source
56
+ unmatched = if %i[full_filename full_path filename].include? @cfg.grep_target.to_sym
57
+ instance_variable_get("@#{grep_on}")
58
+ .send(@cfg.grep_target.to_sym)
59
+ .match(Regexp.new(@cfg.grep)).nil?
60
+ else
61
+ instance_variable_get("@#{grep_on}")
62
+ .get_string(@cfg.grep_target)
63
+ .match(Regexp.new(@cfg.grep)).nil?
64
+ end
58
65
 
59
66
  @cfg.grep_exclude.to_s.to_boolean ? !unmatched : unmatched
60
67
  end
61
-
62
68
  end
63
-
64
69
  end