curly_bracket_parser 0.1.0 → 1.0.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.
- checksums.yaml +4 -4
- data/LICENSE +1 -1
- data/README.md +4 -8
- data/lib/curly_bracket_parser.rb +161 -32
- data/lib/curly_bracket_parser/version.rb +1 -1
- data/lib/custom_errors/filter_already_registered_error.rb +2 -0
- data/lib/custom_errors/invalid_filter_error.rb +2 -0
- data/lib/custom_errors/invalid_variable_error.rb +2 -0
- data/lib/custom_errors/variable_already_registered_error.rb +2 -0
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 418d901b8d9fc3ce2ed71432dfd387a94c2748b4800d77db21df617da6211255
|
4
|
+
data.tar.gz: 5d996dce7be3078c843b607e5e3aab44ad34ffc382efee8520f0789a9efee8da
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b2201ae74405f971a57996c95a3cb45f17e291b670063ba6ada1daf219c6db19a3e8734a6b5577afc959b8a8299efcb6f188dee3ab3ffce702aee7ab7d09dcd0
|
7
|
+
data.tar.gz: 19a1a19ad91be2886e256e43c6b7d5a1a49f44cad29195adec1d672650465349c505ada161da6b795e85cbf47b85e8bb028ed465594e58d8fea8925fcd210edd
|
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -1,14 +1,10 @@
|
|
1
1
|
# curly_bracket_parser
|
2
2
|
|
3
|
-
|
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
|
data/lib/curly_bracket_parser.rb
CHANGED
@@ -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
|
-
|
21
|
-
|
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 \\
|
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
|
-
|
43
|
+
dec = decode_variable(string_var)
|
44
|
+
name = dec[:name]
|
45
|
+
filter = dec[:filter]
|
39
46
|
if variables[name.to_sym]
|
40
|
-
value =
|
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
|
-
# @
|
95
|
-
|
96
|
-
|
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
|
-
|
102
|
-
|
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
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
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
|
-
|
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
|
-
|
123
|
-
|
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 [
|
257
|
+
# @return [Hash<String => String>] name, filter
|
135
258
|
def self.decode_variable(variable)
|
136
|
-
|
137
|
-
[var.keys.first, var.values.first]
|
259
|
+
decoded_variables(variable).first
|
138
260
|
end
|
139
261
|
|
140
262
|
#----------------------------------------------------------------------------------------------------
|
141
263
|
|
142
|
-
#
|
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
|
-
|
147
|
-
|
148
|
-
string.scan(VARIABLE_DECODER_REGEX).map { |e| {"#{e[
|
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
|
-
#
|
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
|
-
#
|
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|
|
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:
|
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:
|
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
|