curly_bracket_parser 0.9.9 → 1.1.6

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: c287b3fc82c91116b7c0ca2f982b81bac5c37e4ca286cd1ea8606de75e0c214f
4
- data.tar.gz: 04f59765b1f59ea540d1e152bbc88c0294ca5adc681f30bf1efed3a117cb3afa
3
+ metadata.gz: 40d43493980369bc381be05ab5ba6b68051555646e5d04c6baaaf0fb90e947a1
4
+ data.tar.gz: f51aaa5658b30890774a4aa8027e702ada49cabdf575192cdfb4913b9bd1c63e
5
5
  SHA512:
6
- metadata.gz: 685345c3a8551e0749742550f2dae6784501fefa07318b8e76b2b30fd743c96d1571d2550bee0731a1c1609d82055ec39ff943a6aebf3c39db435d4686d8e01c
7
- data.tar.gz: a19c4ffb4fe23ce4945023604aeb34ee28a88bd6f89cf2df08f5eab63151fbb0f1ec6b7ec337f6cc8c0b8d2b57c8dacbfec19cbec7b70b22d68cc8b4caf965c6
6
+ metadata.gz: 9ca8945a471c2404407c0c19fbbdcc7b19f5a65631f0c8b55d617c24713193c93ebd2a07b57b81e0ae517cd5e4a5ea3483c4006ab0dc64b157f8a88144c5595a
7
+ data.tar.gz: 14251164b9fcce7ce7f0721c5275655135387a7fd8688ad2f1651cc9b3e52a4f98d8ed411591d505fbefa63f64018bd58daf0dbedb99945522d6b8b94701dbb5
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,6 +1,9 @@
1
1
  # curly_bracket_parser
2
+ ![Gem](https://img.shields.io/gem/v/curly_bracket_parser?color=default&style=plastic&logo=ruby&logoColor=red)
3
+ ![Gem](https://img.shields.io/gem/dt/curly_bracket_parser?color=blue&style=plastic)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-gold.svg?style=plastic&logo=mit)](LICENSE)
2
5
 
3
- Ruby gem providing a simple parser to replace curly brackets `{{like_this}}` inside strings like URLs, texts or even files easily.
6
+ > Ruby gem providing a simple parser to replace curly brackets `{{like_this}}` inside strings like URLs, texts or even files easily.
4
7
 
5
8
  Additional support for build-in filters and custom filters make them more powerful. `{{example|my_filter}}`
6
9
 
@@ -47,15 +50,25 @@ You can either parse variables inside strings or even directly in files.
47
50
 
48
51
  ```ruby
49
52
  url = "https://my-domain.com/items/{{item_id}}"
50
- final_url = CurlyBracketParser.parse url, item_id: 123
53
+ final_url = CurlyBracketParser.parse url, { item_id: 123 }
51
54
  # => "https://my-domain.com/items/123"
52
55
  ```
53
56
 
57
+ Nested variables are supported as well:
58
+ ```ruby
59
+ tmpl = "This is my template with {{my_nested_variable}}";
60
+ my_nested_variable = "my {{nested}} variable";
61
+ parsed_tmpl = CurlyBracketParser.parse tmpl, { my_nested_variable: my_nested_variable, nested: 'pizza'}
62
+ # => "This is my template with my pizza variable"
63
+ ```
64
+
65
+
66
+
54
67
  ### Filters
55
68
 
56
69
  ```ruby
57
70
  url = "https://my-domain.com/catalog/{{item_name|snake_case}}"
58
- final_url = CurlyBracketParser.parse url, item_name: 'MegaSuperItem'
71
+ final_url = CurlyBracketParser.parse url, { item_name: 'MegaSuperItem' }
59
72
  # => "https://my-domain.com/catalog/mega_super_item"
60
73
  ```
61
74
 
@@ -69,10 +82,26 @@ For a list of built-in filters visit [LuckyCase](https://github.com/magynhard/lu
69
82
  end
70
83
 
71
84
  text = "Paul went out and screamed: A{{scream|7times}}h"
72
- final_text = CurlyBracketParser.parse text, scream: 'a'
85
+ final_text = CurlyBracketParser.parse text, { scream: 'a' }
73
86
  # => "Paul went out and screamed: Aaaaaaaah"
74
87
  ```
75
88
 
89
+
90
+ ### Value variables
91
+
92
+ For special cases you can directly define or set variables inside the template - usually it does only make sense, if you combine them with custom filters.
93
+
94
+ You can either use quotes to define a string or numbers (integer or floating point) directly.
95
+
96
+ Empty values are possible as well. They are equal to a empty string.
97
+
98
+ ```ruby
99
+ tmpl = %Q(This is a {{'string'|pascal_case}} and today is {{"today"|date_filter}}. Peter is {{'1990-10-05'|iso_date_age}} years old. His girlfriends name is {{girl|pascal_case}} and she is {{16|double_number}} years old. This article has been written at {{|date_now_formatted}}`)
100
+ parsed = CurlyBracketParser.parse tmpl, { girl: "anna" }
101
+ # => "This is a String and today is 2022-06-27. Peter is 32 years old. His girlfriends name is Anna and she is 32 years old. This article has been written at 6/28/2022, 12:46:40 PM."
102
+ ```
103
+
104
+
76
105
  ### Files
77
106
 
78
107
  <ins>test.html</ins>
@@ -81,7 +110,7 @@ For a list of built-in filters visit [LuckyCase](https://github.com/magynhard/lu
81
110
  ```
82
111
 
83
112
  ```ruby
84
- parsed_file = CurlyBracketParser.parse_file './test.html', title: 'WelcomeAtHome'
113
+ parsed_file = CurlyBracketParser.parse_file './test.html', { title: 'WelcomeAtHome' }
85
114
  # => "<h1>Welcome at home</h1>"
86
115
  ```
87
116
 
@@ -101,7 +130,7 @@ Because of providing blocks, your variables can dynamically depend on other stat
101
130
  text = "You are running version {{version}}"
102
131
  CurlyBracketParser.parse text
103
132
  # => "You are running version 1.0.2"
104
- CurlyBracketParser.parse text, version: '0.7.0'
133
+ CurlyBracketParser.parse text, { version: '0.7.0' }
105
134
  # => "You are running version 0.7.0"
106
135
  ```
107
136
 
@@ -1,3 +1,3 @@
1
1
  module CurlyBracketParser
2
- VERSION = '0.9.9'.freeze
2
+ VERSION = '1.1.6'.freeze
3
3
  end
@@ -18,8 +18,8 @@ require_relative 'custom_errors/variable_already_registered_error'
18
18
  module CurlyBracketParser
19
19
 
20
20
  # {{variable_name|optional_filter}}
21
- VARIABLE_DECODER_REGEX = /{{([^{}\|]+)\|?([^{}\|]*)}}/
22
- VARIABLE_REGEX = /{{[^{}]+}}/
21
+ VARIABLE_DECODER_REGEX = /{{([^{}\|]*)\|?([^{}\|]*)}}/
22
+ VARIABLE_REGEX = /{{[^{}]*}}/
23
23
 
24
24
  VALID_DEFAULT_FILTERS = [
25
25
  LuckyCase::CASES.keys.map(&:to_s)
@@ -31,40 +31,54 @@ module CurlyBracketParser
31
31
  #
32
32
  # @param [String] string to parse
33
33
  # @param [Hash<Symbol => String>] variables <key: 'value'>
34
- # @param [Symbol] unresolved_vars :raise, :keep, :replace => define how to act when unresolved variables within the string are found.
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.
34
+ # @param [Hash] options
35
+ # @param [Symbol] options.unresolved_vars :raise, :keep, :replace => define how to act when unresolved variables within the string are found.
36
+ # @param [String] options.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.
36
37
  # @return [String, UnresolvedVariablesError] parsed string
37
- def self.parse(string, variables, unresolved_vars: :raise, replace_pattern: "##\\1##")
38
+ def self.parse(string, variables = {}, options = { unresolved_vars: :raise, replace_pattern: "##\\1##" })
38
39
  variables ||= {}
40
+ options ||= {}
41
+ options[:unresolved_vars] = :raise unless options[:unresolved_vars]
42
+ options[:replace_pattern] = "##\\1##" unless options[:replace_pattern]
39
43
  result_string = string.clone
44
+ # symbolize keys
45
+ variables = variables.map { |key, value| [key.to_sym, value] }.to_h
40
46
  if CurlyBracketParser.any_variable_included? string
41
47
  loop do
42
- variables(string).each do |string_var|
48
+ variables(result_string).each do |string_var|
43
49
  dec = decode_variable(string_var)
44
- name = dec[:name]
50
+ name = !dec[:name] || dec[:name] == '' ? "''" : dec[:name]
45
51
  filter = dec[:filter]
46
- if variables[name.to_sym]
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)
52
+ value = nil
53
+ is_single_quoted = name.start_with?("'") && name.end_with?("'")
54
+ is_double_quoted = name.start_with?('"') && name.end_with?('"')
55
+ # When the name itself is quoted as string or is a number, we use it as a value itself
56
+ if is_single_quoted || is_double_quoted
57
+ value = name[1...-1]
58
+ elsif CurlyBracketParser.number_string? name
59
+ value = eval(name)
60
+ elsif variables[name.to_sym]
61
+ value = variables[name.to_sym]
53
62
  elsif registered_default_var?(name.to_s)
54
63
  value = process_default_var(name)
55
- result_string.gsub!(string_var, value)
64
+ end
65
+ if value
66
+ value = process_filter(filter, value) if filter
67
+ result_string.gsub!(string_var, value.to_s)
56
68
  end
57
69
  end
58
70
  # break if no more given variable is available
59
- break unless any_variable_included?(string) && includes_one_variable_of(variables, string)
71
+ unless any_variable_included?(result_string) && includes_one_variable_of(variables.keys, result_string)
72
+ break
73
+ end
60
74
  end
61
- case unresolved_vars
75
+ case options[:unresolved_vars]
62
76
  when :raise
63
77
  if any_variable_included? result_string
64
78
  raise UnresolvedVariablesError, "There are unresolved variables in the given string: #{variables(result_string)}"
65
79
  end
66
80
  when :replace
67
- result_string.gsub!(VARIABLE_DECODER_REGEX, replace_pattern)
81
+ result_string.gsub!(VARIABLE_DECODER_REGEX, options[:replace_pattern])
68
82
  end
69
83
  end
70
84
  result_string
@@ -303,11 +317,39 @@ module CurlyBracketParser
303
317
  # @return [Boolean] true if one given variable name is included in given the string, otherwise false
304
318
  def self.includes_one_variable_of(variable_names, string)
305
319
  decoded_variables(string).each do |dvar|
306
- return true if variable_names.include?(dvar[:name])
320
+ return true if variable_names.map(&:to_sym).include?(dvar[:name].to_sym)
307
321
  end
308
322
  false
309
323
  end
310
324
 
311
325
  #----------------------------------------------------------------------------------------------------
312
326
 
327
+ #
328
+ # Check if given variable is a valid number inside a string that evaluates to a number in Ruby.
329
+ #
330
+ # @example
331
+ # # valid number strings
332
+ # '200'
333
+ # '25.75'
334
+ # '500_000'
335
+ # '0x1fF'
336
+ #
337
+ # @param [String] name
338
+ # @return [Boolean]
339
+ def self.number_string?(name)
340
+ number_regex = /(^[0-9]+[0-9_]*([.][0-9_]*[0-9]+)?$|^0[xX][0-9A-Fa-f]+$)/
341
+ if (name =~ number_regex) != nil
342
+ begin
343
+ eval name
344
+ true
345
+ rescue StandardError, SyntaxError => e
346
+ false
347
+ end
348
+ else
349
+ false
350
+ end
351
+ end
352
+
353
+ #----------------------------------------------------------------------------------------------------
354
+
313
355
  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.9.9
4
+ version: 1.1.6
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: 2021-01-10 00:00:00.000000000 Z
11
+ date: 2022-07-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: lucky_case
@@ -110,7 +110,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
110
110
  - !ruby/object:Gem::Version
111
111
  version: '0'
112
112
  requirements: []
113
- rubygems_version: 3.0.8
113
+ rubygems_version: 3.1.4
114
114
  signing_key:
115
115
  specification_version: 4
116
116
  summary: Simple parser to replace variables inside templates/strings and files