curly_bracket_parser 0.1.0 → 1.0.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
  SHA256:
3
- metadata.gz: e2581aa770602a42a73eb9f79f3840dd53609d2905a75db5aaf3a5b0dac1f018
4
- data.tar.gz: 912c7fb9c2285515bf5b7af00da8c629222af329e68dd431f5cd649c20815df4
3
+ metadata.gz: 418d901b8d9fc3ce2ed71432dfd387a94c2748b4800d77db21df617da6211255
4
+ data.tar.gz: 5d996dce7be3078c843b607e5e3aab44ad34ffc382efee8520f0789a9efee8da
5
5
  SHA512:
6
- metadata.gz: 05eba36a79347485fd42db86ecfe49824913b497a89b6f36aa3b2924c4b2b8b6b1fae89b4bb3099708f5b76488706d1d6da4ff035f0c41bbf52cb0633f96a624
7
- data.tar.gz: 56a9306ca6375a6e7c4366781b638eb509918c2a101703de930d0f481a8661ef00e1054925c74ff845c3de0cd2ea51f6b7304f34a259aad27379a8a15fa51c3b
6
+ metadata.gz: b2201ae74405f971a57996c95a3cb45f17e291b670063ba6ada1daf219c6db19a3e8734a6b5577afc959b8a8299efcb6f188dee3ab3ffce702aee7ab7d09dcd0
7
+ data.tar.gz: 19a1a19ad91be2886e256e43c6b7d5a1a49f44cad29195adec1d672650465349c505ada161da6b795e85cbf47b85e8bb028ed465594e58d8fea8925fcd210edd
data/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2020 Matthäus J. N. Beyrle
3
+ Copyright (c) 2020-2021 Matthäus J. N. Beyrle
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -1,14 +1,10 @@
1
1
  # curly_bracket_parser
2
2
 
3
- Simple parser to replace curly brackets `{{like_this}}` inside strings like URLs, texts or even files easily.
3
+ Ruby gem providing a simple parser to replace curly brackets `{{like_this}}` inside strings like URLs, texts or even files easily.
4
4
 
5
5
  Additional support for build-in filters and custom filters make them more powerful. `{{example|my_filter}}`
6
6
 
7
- Using [LuckyCase](https://github.com/magynhard/lucky_case), all its case formats are supported as filter.
8
-
9
- ```diff
10
- - beta version
11
- ```
7
+ Using [LuckyCase](https://github.com/magynhard/lucky_case), all its case formats are supported as filter by default.
12
8
 
13
9
 
14
10
 
@@ -17,7 +13,7 @@ Using [LuckyCase](https://github.com/magynhard/lucky_case), all its case formats
17
13
  # Contents
18
14
 
19
15
  * [Installation](#installation)
20
- * [Usage](#usage)
16
+ * [Usage examples](#usage)
21
17
  * [Documentation](#documentation)
22
18
  * [Contributing](#contributing)
23
19
 
@@ -95,7 +91,7 @@ Use `#parse_file!` instead to write the parsed string directly into the file!
95
91
 
96
92
  You can define default variables, which will be replaced automatically without passing them by parameters, but can be overwritten with parameters.
97
93
 
98
- Because of providing blocks, your variables can dynamically depend on other states.
94
+ Because of providing blocks, your variables can dynamically depend on other states (e.g. current date).
99
95
 
100
96
  ```ruby
101
97
  CurlyBracketParser.register_default_var('version') do
@@ -1,7 +1,11 @@
1
1
  require 'lucky_case'
2
2
 
3
3
  require 'curly_bracket_parser/version'
4
+ require_relative 'custom_errors/filter_already_registered_error'
5
+ require_relative 'custom_errors/invalid_filter_error'
6
+ require_relative 'custom_errors/invalid_variable_error'
4
7
  require_relative 'custom_errors/unresolved_variables_error'
8
+ require_relative 'custom_errors/variable_already_registered_error'
5
9
 
6
10
  #
7
11
  # CurlyBracketParser
@@ -17,8 +21,8 @@ module CurlyBracketParser
17
21
  VARIABLE_DECODER_REGEX = /{{([^{}\|]+)\|?([^{}\|]*)}}/
18
22
  VARIABLE_REGEX = /{{[^{}]+}}/
19
23
 
20
- VALID_FILTERS = [
21
- LuckyCase::CASES.keys.map(&:to_s)
24
+ VALID_DEFAULT_FILTERS = [
25
+ LuckyCase::CASES.keys.map(&:to_s)
22
26
  ].flatten
23
27
 
24
28
  #----------------------------------------------------------------------------------------------------
@@ -28,16 +32,26 @@ module CurlyBracketParser
28
32
  # @param [String] string to parse
29
33
  # @param [Hash<Symbol => String>] variables <key: 'value'>
30
34
  # @param [Symbol] unresolved_vars :raise, :keep, :replace => define how to act when unresolved variables within the string are found.
31
- # @param [String] replace_pattern pattern used when param unresolved_vars is set to :replace. You can include the var name \\1 and filter \\1. Empty string to remove unresolved variables.
35
+ # @param [String] replace_pattern pattern used when param unresolved_vars is set to :replace. You can include the var name \\1 and filter \\2. Empty string to remove unresolved variables.
32
36
  # @return [String, UnresolvedVariablesError] parsed string
33
37
  def self.parse(string, variables, unresolved_vars: :raise, replace_pattern: "##\\1##")
38
+ variables ||= {}
34
39
  result_string = string.clone
35
40
  if CurlyBracketParser.any_variable_included? string
36
41
  loop do
37
42
  variables(string).each do |string_var|
38
- name, filter = decode_variable(string_var)
43
+ dec = decode_variable(string_var)
44
+ name = dec[:name]
45
+ filter = dec[:filter]
39
46
  if variables[name.to_sym]
40
- value = process_filter(variables[name.to_sym], filter)
47
+ value = if filter
48
+ process_filter(filter, variables[name.to_sym])
49
+ else
50
+ variables[name.to_sym]
51
+ end
52
+ result_string.gsub!(string_var, value)
53
+ elsif registered_default_var?(name.to_s)
54
+ value = process_default_var(name)
41
55
  result_string.gsub!(string_var, value)
42
56
  end
43
57
  end
@@ -89,38 +103,147 @@ module CurlyBracketParser
89
103
 
90
104
  # Register your custom filter to the filter list
91
105
  #
92
- # @param [String] name of the filter, also used then in your strings, e.g. {{var_name|my_filter_name}}
106
+ # @param [String] filter name of the filter, also used then in your strings, e.g. {{var_name|my_filter_name}}
93
107
  # @param [Lambda] function of the filter to run the variable against
94
- # @return [Boolean] true if filter was added, false if it already exists
95
- def self.register_filter(name, &block)
96
- raise "NOT IMPLEMENTED YET!"
108
+ # @raise [FilterAlreadyRegisteredError] if filter does already exist
109
+ # @return [Proc] given block
110
+ def self.register_filter(filter, &block)
111
+ @@registered_filters ||= {}
112
+ filter = filter.to_s
113
+ if valid_filter?(filter)
114
+ raise FilterAlreadyRegisteredError, "The given filter name '#{filter}' is already registered"
115
+ else
116
+ @@registered_filters[filter] = block
117
+ end
97
118
  end
98
119
 
99
120
  #----------------------------------------------------------------------------------------------------
100
121
 
101
- def self.register_default_variable(name, &block)
102
- raise "NOT IMPLEMENTED YET!"
122
+ # Process the given value with the given filter
123
+ #
124
+ # @param [String] filter name of the filter, also used then in your strings, e.g. {{var_name|my_filter_name}}
125
+ # @param [String] value string to apply the specified filter on
126
+ # @return [String] converted string with applied filter
127
+ def self.process_filter(filter, value)
128
+ @@registered_filters ||= {}
129
+ filter = filter.to_s
130
+ if @@registered_filters[filter]
131
+ @@registered_filters[filter].call(value)
132
+ elsif VALID_DEFAULT_FILTERS.include?(filter) && LuckyCase.valid_case_type?(filter)
133
+ LuckyCase.convert_case(value, filter)
134
+ else
135
+ message = "Invalid filter '#{filter}'. Valid filters are: #{self.valid_filters.join(' ')}"
136
+ raise InvalidFilterError, message
137
+ end
103
138
  end
104
139
 
105
140
  #----------------------------------------------------------------------------------------------------
106
141
 
107
- def self.process_filter(value, filter)
108
- return value unless filter
109
- if VALID_FILTERS.include? filter
110
- if LuckyCase.valid_case_type? filter
111
- return LuckyCase.convert_case(value, filter)
112
- else
113
- raise "FILTER '#{filter}' NOT IMPLEMENTED YET!"
114
- end
142
+ # Retrieve Array with valid filters
143
+ #
144
+ # @return [Array<String>] of valid filters
145
+ def self.valid_filters
146
+ all_filters = VALID_DEFAULT_FILTERS
147
+ @@registered_filters ||= {}
148
+ all_filters + @@registered_filters.keys.map(&:to_s)
149
+ end
150
+
151
+ #----------------------------------------------------------------------------------------------------
152
+
153
+ # Check if a given filter is valid
154
+ #
155
+ # @param [String] name
156
+ # @return [Boolean] true if filter exists, otherwise false
157
+ def self.valid_filter?(name)
158
+ self.valid_filters.include? name
159
+ end
160
+
161
+ #----------------------------------------------------------------------------------------------------
162
+
163
+ # Register a default variable to be replaced automatically by the given block value in future
164
+ # If the variable exists already, it will raise an VariableAlreadyRegisteredError
165
+ #
166
+ # @param [String] name of the default var
167
+ # @param [Proc] block
168
+ # @raise [VariableAlreadyRegisteredError] if variable is already registered
169
+ # @return [Proc] given block
170
+ def self.register_default_var(name, &block)
171
+ @@registered_default_vars ||= {}
172
+ name = name.to_s
173
+ if registered_default_var?(name)
174
+ raise VariableAlreadyRegisteredError, "The given variable name '#{name}' is already registered. If you want to override that variable explicitly, call #register_default_var! instead!"
175
+ else
176
+ @@registered_default_vars[name] = block
177
+ end
178
+ end
179
+
180
+ #----------------------------------------------------------------------------------------------------
181
+
182
+ # Return the given default variable by returning the result of its block/proc
183
+ #
184
+ # @param [String] name of the variable to return
185
+ # @return [String] value of the variable
186
+ def self.process_default_var(name)
187
+ @@registered_default_vars ||= {}
188
+ name = name.to_s
189
+ if @@registered_default_vars[name]
190
+ @@registered_default_vars[name].call()
115
191
  else
116
- raise "Invalid filter '#{filter}'"
192
+ message = "Invalid default variable '#{name}'. Valid registered default variables are: #{self.registered_default_vars.keys.join(' ')}"
193
+ raise InvalidVariableError, message
117
194
  end
118
195
  end
119
196
 
120
197
  #----------------------------------------------------------------------------------------------------
121
198
 
122
- def self.has_filter?(variable)
123
- decode_variable(variable)[:filter] != nil
199
+ # Register a default variable to be replaced automatically by the given block value in future
200
+ # If the variable exists already, it will be overwritten
201
+ #
202
+ # @param [String] name of the default var
203
+ # @param [Proc] block
204
+ # @raise [VariableAlreadyRegisteredError] if variable is already registered
205
+ # @return [Proc] given block
206
+ def self.register_default_var!(name, &block)
207
+ @@registered_default_vars ||= {}
208
+ name = name.to_s
209
+ @@registered_default_vars[name] = block
210
+ end
211
+
212
+ #----------------------------------------------------------------------------------------------------
213
+
214
+ # Unregister / remove an existing default variable
215
+ #
216
+ # @param [String] name of the variable
217
+ # @return [Boolean] true if variable existed and was unregistered, false if it didn't exist
218
+ def self.unregister_default_var(name)
219
+ @@registered_default_vars ||= {}
220
+ name = name.to_s
221
+ if @@registered_default_vars[name]
222
+ @@registered_default_vars.delete(name)
223
+ true
224
+ else
225
+ false
226
+ end
227
+ end
228
+
229
+ #----------------------------------------------------------------------------------------------------
230
+
231
+ # Return an array of registered default variables
232
+ #
233
+ # @return [Array<String>]
234
+ def self.registered_default_vars
235
+ @@registered_default_vars ||= {}
236
+ @@registered_default_vars.keys.map(&:to_s)
237
+ end
238
+
239
+ #----------------------------------------------------------------------------------------------------
240
+
241
+ # Check if the given variable is a registered default variable
242
+ #
243
+ # @param [String] name of the variable
244
+ # @return [Boolean] true if variable is registered, otherwise false
245
+ def self.registered_default_var?(name)
246
+ self.registered_default_vars.include? name
124
247
  end
125
248
 
126
249
  #----------------------------------------------------------------------------------------------------
@@ -131,26 +254,30 @@ module CurlyBracketParser
131
254
  # '{{var_name|filter_name}}' => { name: 'var_name', filter: 'filter_name' }
132
255
  #
133
256
  # @param [String] variable
134
- # @return [Array(String, String)] name, filter
257
+ # @return [Hash<String => String>] name, filter
135
258
  def self.decode_variable(variable)
136
- var = decoded_variables(variable).first
137
- [var.keys.first, var.values.first]
259
+ decoded_variables(variable).first
138
260
  end
139
261
 
140
262
  #----------------------------------------------------------------------------------------------------
141
263
 
142
- # scans the given url for variables with pattern '{{var}}'
264
+ # Scans the given url for variables with pattern '{{var|optional_filter}}'
265
+ #
266
+ # @example
267
+ # 'The variable {{my_var|my_filter}} is inside this string' => [{ name: "my_var", filter: "my_filter"}]
268
+ #
143
269
  # @param [String] string to scan
144
270
  # @return [Array<Hash<Symbol => String>>] array of variable names and its filters
145
271
  def self.decoded_variables(string)
146
- var_name = 0
147
- var_filter = 1
148
- string.scan(VARIABLE_DECODER_REGEX).map { |e| {"#{e[var_name].strip}": e[var_filter].strip != '' ? e[var_filter].strip : nil } }.flatten
272
+ var_name_index = 0
273
+ var_filter_index = 1
274
+ string.scan(VARIABLE_DECODER_REGEX).map { |e| { name: "#{e[var_name_index].strip}", filter: e[var_filter_index].strip != '' ? e[var_filter_index].strip : nil } }.flatten
149
275
  end
150
276
 
151
277
  #----------------------------------------------------------------------------------------------------
152
278
 
153
- # scans the given url for variables with pattern '{{var}}'
279
+ # Scans the given url for variables with pattern '{{var|optional_filter}}'
280
+ #
154
281
  # @param [String] string to scan
155
282
  # @return [Array<String>] array of variable names and its filters
156
283
  def self.variables(string)
@@ -160,7 +287,8 @@ module CurlyBracketParser
160
287
  #----------------------------------------------------------------------------------------------------
161
288
 
162
289
  # Check if any variable is included in the given string
163
- # @param [Object] string
290
+ #
291
+ # @param [String] string name of variable to check for
164
292
  # @return [Boolean] true if any variable is included in the given string, otherwise false
165
293
  def self.any_variable_included?(string)
166
294
  string.match(VARIABLE_REGEX) != nil
@@ -169,8 +297,9 @@ module CurlyBracketParser
169
297
  #----------------------------------------------------------------------------------------------------
170
298
 
171
299
  # Check if one of the given variable names is included in the given string
300
+ #
172
301
  # @param [Array<String>] variable_names
173
- # @param [String] string
302
+ # @param [String] string name of variable to check for
174
303
  # @return [Boolean] true if one given variable name is included in given the string, otherwise false
175
304
  def self.includes_one_variable_of(variable_names, string)
176
305
  decoded_variables(string).each do |dvar|
@@ -1,3 +1,3 @@
1
1
  module CurlyBracketParser
2
- VERSION = '0.1.0'.freeze
2
+ VERSION = '1.0.0'.freeze
3
3
  end
@@ -0,0 +1,2 @@
1
+ class FilterAlreadyRegisteredError < StandardError
2
+ end
@@ -0,0 +1,2 @@
1
+ class InvalidFilterError < StandardError
2
+ end
@@ -0,0 +1,2 @@
1
+ class InvalidVariableError < StandardError
2
+ end
@@ -0,0 +1,2 @@
1
+ class VariableAlreadyRegisteredError < StandardError
2
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: curly_bracket_parser
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matthäus Beyrle
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-12-22 00:00:00.000000000 Z
11
+ date: 2021-01-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: lucky_case
@@ -85,7 +85,11 @@ files:
85
85
  - curly_bracket_parser.gemspec
86
86
  - lib/curly_bracket_parser.rb
87
87
  - lib/curly_bracket_parser/version.rb
88
+ - lib/custom_errors/filter_already_registered_error.rb
89
+ - lib/custom_errors/invalid_filter_error.rb
90
+ - lib/custom_errors/invalid_variable_error.rb
88
91
  - lib/custom_errors/unresolved_variables_error.rb
92
+ - lib/custom_errors/variable_already_registered_error.rb
89
93
  homepage: https://github.com/magynhard/curly_bracket_parser
90
94
  licenses:
91
95
  - MIT