liquid-tag-parser 1.9.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +5 -4
- data/lib/liquid-tag-parser.rb +6 -0
- data/lib/liquid/tag/parser.rb +114 -122
- data/lib/liquid/tag/parser/version.rb +2 -2
- metadata +23 -23
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3f793bd6e940a4bb73c68c1db50d5e702526e46e37c1b2cea3be739ec6b077df
|
4
|
+
data.tar.gz: ac8132ca543f70e5a2f5624e3f32b27941463180330a21676097a7daa79e2a71
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: def93bb9961d3281023246070b8d4fa8bfe7d402b19d1678ba3ab31c191ae6fca4343596287c2782c793c9ca0309cdb16977751fcb531c57065a777c420ad02e
|
7
|
+
data.tar.gz: fcaa8a00be1c9ef020d3d8eb5a51ad0cb3e2f3d9957d2cfb287e897c30b815865c1c4e4e4a56838fbbf11850e92f30687631bac2e155b54d0f6acf0c953d5471
|
data/Gemfile
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
# Frozen-string-literal: true
|
2
|
-
# Copyright: 2017
|
2
|
+
# Copyright: 2017 - 2020 - ISC License
|
3
|
+
# Author: Jordon Bedwell
|
3
4
|
# Encoding: utf-8
|
4
5
|
|
5
|
-
source
|
6
|
+
source 'https://rubygems.org'
|
6
7
|
gemspec
|
7
8
|
|
8
|
-
if ENV
|
9
|
-
gem
|
9
|
+
if ENV.key?('LIQUID_VERSION')
|
10
|
+
gem 'liquid', ENV['LIQUID_VERSION']
|
10
11
|
end
|
data/lib/liquid/tag/parser.rb
CHANGED
@@ -1,58 +1,51 @@
|
|
1
1
|
# Frozen-string-literal: true
|
2
|
-
# Copyright: 2017 -
|
2
|
+
# Copyright: 2017 - 2020 - ISC License
|
3
3
|
# Author: Jordon Bedwell
|
4
4
|
# Encoding: utf-8
|
5
5
|
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require "liquid"
|
6
|
+
require 'extras/hash'
|
7
|
+
require 'liquid'
|
9
8
|
|
10
9
|
module Liquid
|
11
10
|
class Tag
|
12
11
|
class Parser
|
13
12
|
attr_reader :args
|
14
|
-
extend Forwardable::Extended
|
15
13
|
alias raw_args args
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
# --
|
39
|
-
FALSE =
|
40
|
-
FLOAT = %r!\A\d+\.\d+\Z
|
41
|
-
QUOTE = %r!("
|
42
|
-
SPECIAL = %r{(?<!\\)(
|
43
|
-
BOOL = %r{\A(?<!\\)(
|
44
|
-
UNQUOTED_SPECIAL = %r{(?<!\\)(://)}
|
45
|
-
SPECIAL_ESCAPED = %r{\\(
|
46
|
-
KEY = %r{\b(?<!\\):}
|
47
|
-
INT = %r!^\d
|
48
|
-
TRUE =
|
49
|
-
|
50
|
-
|
51
|
-
SHELLSPLIT = %r!\G\s*(?>([^\s\\\'\"]+)|'([^\']*)'|"((?:[^\"\\]|
|
52
|
-
\\.)*)"|(\\.?)|(\S))(\s|\z)?!mx
|
53
|
-
|
54
|
-
# --
|
55
|
-
def initialize(raw, defaults: {}, sep: "=")
|
14
|
+
extend Forwardable
|
15
|
+
|
16
|
+
def_delegator :@args, :each
|
17
|
+
def_delegator :@args, :key?
|
18
|
+
def_delegator :@args, :to_h
|
19
|
+
def_delegator :@args, :each_key
|
20
|
+
def_delegator :@args, :each_with_object
|
21
|
+
def_delegator :@args, :each_value
|
22
|
+
def_delegator :@args, :values_at
|
23
|
+
def_delegator :@args, :to_enum
|
24
|
+
def_delegator :@args, :map
|
25
|
+
def_delegator :@args, :[]=
|
26
|
+
def_delegator :@args, :[]
|
27
|
+
def_delegator :@args, :merge
|
28
|
+
def_delegator :@args, :merge!
|
29
|
+
def_delegator :@args, :deep_merge
|
30
|
+
def_delegator :@args, :deep_merge!
|
31
|
+
def_delegator :@args, :update
|
32
|
+
def_delegator :@args, :select
|
33
|
+
def_delegator :@args, :find
|
34
|
+
def_delegator :@args, :dig
|
35
|
+
|
36
|
+
# --
|
37
|
+
FALSE = '!'
|
38
|
+
FLOAT = %r!\A\d+\.\d+\Z!.freeze
|
39
|
+
QUOTE = %r!(["'])([^\1]*)(\1)!.freeze
|
40
|
+
SPECIAL = %r{(?<!\\)([@!:=])}.freeze
|
41
|
+
BOOL = %r{\A(?<!\\)([!@])([\w:]+)\z}.freeze
|
42
|
+
UNQUOTED_SPECIAL = %r{(?<!\\)(://)}.freeze
|
43
|
+
SPECIAL_ESCAPED = %r{\\([@!:=])}.freeze
|
44
|
+
KEY = %r{\b(?<!\\):}.freeze
|
45
|
+
INT = %r!^\d+$!.freeze
|
46
|
+
TRUE = '@'
|
47
|
+
|
48
|
+
def initialize(raw, defaults: {}, sep: '=')
|
56
49
|
@sep = sep
|
57
50
|
@unescaped_sep = sep
|
58
51
|
@rsep = Regexp.escape(sep)
|
@@ -65,84 +58,107 @@ module Liquid
|
|
65
58
|
parse
|
66
59
|
end
|
67
60
|
|
68
|
-
#
|
61
|
+
#
|
69
62
|
# Consumes a block and wraps around reusably on arguments.
|
70
63
|
# @return [Hash<Symbol,Object>,Array<String>]
|
71
|
-
#
|
64
|
+
#
|
72
65
|
def skippable_loop(skip: [], hash: false)
|
73
|
-
@args.each_with_object(hash ? {} : []) do |(
|
74
|
-
skip_in_html?(
|
66
|
+
@args.each_with_object(hash ? {} : []) do |(key, val), obj|
|
67
|
+
next obj if skip_in_html?(key: key, val: val, skips: skip)
|
68
|
+
yield(
|
69
|
+
[
|
70
|
+
key,
|
71
|
+
val
|
72
|
+
],
|
73
|
+
obj
|
74
|
+
)
|
75
75
|
end
|
76
76
|
end
|
77
77
|
|
78
|
-
#
|
78
|
+
#
|
79
79
|
# @param [Array<Symbol>] skip keys to skip.
|
80
80
|
# Converts the arguments into an HTML attribute string.
|
81
81
|
# @return [String]
|
82
|
-
#
|
82
|
+
#
|
83
83
|
def to_html(skip: [])
|
84
84
|
skippable_loop(skip: skip, hash: false) do |(k, v), o|
|
85
85
|
o << (v == true ? k.to_s : "#{k}=\"#{v}\"")
|
86
|
-
end.join(
|
86
|
+
end.join(' ')
|
87
87
|
end
|
88
88
|
|
89
|
-
#
|
89
|
+
#
|
90
|
+
# indifferent args as a hash
|
91
|
+
# @note this will require you to have ActiveSupport
|
92
|
+
# @return [HashWithIndifferentAccess]
|
93
|
+
#
|
94
|
+
def args_with_indifferent_access
|
95
|
+
@args.send(
|
96
|
+
:with_indifferent_access
|
97
|
+
)
|
98
|
+
end
|
99
|
+
|
100
|
+
#
|
90
101
|
# @param [Array<Symbol>] skip keys to skip.
|
91
|
-
# @param [true,false]
|
102
|
+
# @param [true,false] html skip non-html values.
|
92
103
|
# Converts arguments into an HTML hash (or to arguments).
|
93
|
-
# @return [Hash]
|
94
|
-
#
|
104
|
+
# @return [Hash<Object>,Array<String>]
|
105
|
+
#
|
95
106
|
def to_h(skip: [], html: false)
|
96
107
|
return @args unless html
|
108
|
+
|
97
109
|
skippable_loop(skip: skip, hash: true) do |(k, v), o|
|
98
110
|
o[k] = v
|
99
111
|
end
|
100
112
|
end
|
101
113
|
|
102
|
-
#
|
103
|
-
# @param [String]
|
104
|
-
# @param [Object]
|
114
|
+
#
|
115
|
+
# @param [String] key the key
|
116
|
+
# @param [Object] val the value
|
105
117
|
# @param [Array<Symbol>] skips personal skips.
|
106
118
|
# Determines if we should skip in HTML.
|
107
119
|
# @return [true,false]
|
108
|
-
#
|
120
|
+
#
|
109
121
|
private
|
110
|
-
def skip_in_html?(
|
111
|
-
|
112
|
-
||
|
122
|
+
def skip_in_html?(key:, val:, skips: [])
|
123
|
+
key == :argv1 || val.is_a?(Array) || skips.include?(key) \
|
124
|
+
|| val.is_a?(Hash) || val == false
|
113
125
|
end
|
114
126
|
|
115
|
-
#
|
127
|
+
#
|
116
128
|
# @return [true,nil] a truthy value.
|
117
|
-
# @param [Integer]
|
129
|
+
# @param [Integer] idx the current iteration.
|
118
130
|
# @param [String] keys the keys that will be split.
|
119
131
|
# @param [String] val the value.
|
120
|
-
#
|
132
|
+
#
|
121
133
|
private
|
122
|
-
def argv1(
|
123
|
-
if
|
124
|
-
@args[:argv1] = unescape(
|
134
|
+
def argv1(idx:, keys:, val:)
|
135
|
+
if idx.zero? && keys.empty? && val !~ BOOL && val !~ @sep_regexp
|
136
|
+
@args[:argv1] = unescape(
|
137
|
+
convert(
|
138
|
+
val
|
139
|
+
)
|
140
|
+
)
|
125
141
|
end
|
126
142
|
end
|
127
143
|
|
128
|
-
#
|
144
|
+
#
|
129
145
|
# @return [Array<String,true|false>]
|
130
146
|
# Allows you to flip a value based on condition.
|
131
|
-
# @param [String]
|
132
|
-
#
|
147
|
+
# @param [String] val the value.
|
148
|
+
#
|
133
149
|
private
|
134
|
-
def flip_kv_bool(
|
150
|
+
def flip_kv_bool(val)
|
135
151
|
[
|
136
|
-
|
137
|
-
|
152
|
+
val.gsub(BOOL, '\2'),
|
153
|
+
val.start_with?(TRUE) ? true : false
|
138
154
|
]
|
139
155
|
end
|
140
156
|
|
141
|
-
#
|
157
|
+
#
|
142
158
|
# @param [Array<Symbol>] keys the keys.
|
143
159
|
# Builds a sub-hash or returns parent hash.
|
144
160
|
# @return [Hash]
|
145
|
-
#
|
161
|
+
#
|
146
162
|
private
|
147
163
|
def build_hash(keys)
|
148
164
|
out = @args
|
@@ -160,86 +176,62 @@ module Liquid
|
|
160
176
|
private
|
161
177
|
def unescape(val)
|
162
178
|
return unless val
|
179
|
+
|
163
180
|
val.gsub(@escaped_sep_regexp, @unescaped_sep).gsub(
|
164
|
-
SPECIAL_ESCAPED,
|
181
|
+
SPECIAL_ESCAPED, '\1')
|
165
182
|
end
|
166
183
|
|
167
|
-
# --
|
168
184
|
private
|
169
185
|
def parse
|
170
186
|
from_shellwords.each_with_index do |k, i|
|
171
187
|
keys, _, val = k.rpartition(@sep_regexp)
|
172
|
-
next if argv1(
|
188
|
+
next if argv1(idx: i, keys: keys, val: val)
|
173
189
|
|
174
190
|
val = unescape(val)
|
175
191
|
keys, val = flip_kv_bool(val) if val =~ BOOL && keys.empty?
|
176
192
|
keys, val = val, nil if keys.empty?
|
177
193
|
keys = keys.split(KEY).map(&:to_sym)
|
178
194
|
|
179
|
-
set_val(
|
180
|
-
|
195
|
+
set_val(
|
196
|
+
val: convert(val),
|
181
197
|
hash: build_hash(keys),
|
182
|
-
|
183
|
-
|
198
|
+
key: keys.last
|
199
|
+
)
|
184
200
|
end
|
185
201
|
end
|
186
202
|
|
187
|
-
# --
|
188
203
|
private
|
189
|
-
def set_val(
|
190
|
-
hash[
|
191
|
-
hash[
|
192
|
-
hash[
|
204
|
+
def set_val(key:, val:, hash:)
|
205
|
+
hash[key] << val if hash[key].is_a?(Array)
|
206
|
+
hash[key] = [hash[key]].flatten << val if hash[key] && !hash[key].is_a?(Array)
|
207
|
+
hash[key] = val unless hash[key]
|
193
208
|
end
|
194
209
|
|
195
|
-
#
|
210
|
+
#
|
196
211
|
# @return [true,false,Float,Integer]
|
197
212
|
# Convert a value to a native value.
|
198
|
-
#
|
213
|
+
#
|
199
214
|
private
|
200
215
|
def convert(val)
|
216
|
+
return if val.nil?
|
217
|
+
return val if [true, false].include?(val)
|
201
218
|
return val.to_f if val =~ FLOAT
|
202
219
|
return val.to_i if val =~ INT
|
220
|
+
|
203
221
|
val
|
204
222
|
end
|
205
223
|
|
206
|
-
#
|
224
|
+
#
|
207
225
|
# Wraps into `#shellsplit`, and first substitutes some values.
|
208
226
|
# @return [Array<String>]
|
209
|
-
#
|
227
|
+
#
|
210
228
|
private
|
211
229
|
def from_shellwords
|
212
|
-
shellsplit(
|
213
|
-
@raw.gsub(SPECIAL,
|
214
|
-
.gsub(UNQUOTED_SPECIAL,
|
230
|
+
Shellwords.shellsplit(
|
231
|
+
@raw.gsub(SPECIAL, '\1')
|
232
|
+
.gsub(UNQUOTED_SPECIAL, '\1')
|
215
233
|
.gsub(@sep_regexp, @escaped_sep))
|
216
234
|
end
|
217
|
-
|
218
|
-
# --
|
219
|
-
# @see Shellwords.shellsplit
|
220
|
-
# Because Shellwords.shellwords on < 2.4 has problems with
|
221
|
-
# quotes and \\, we ported this back, this pretty much the
|
222
|
-
# same thing except we replace some of the questionable
|
223
|
-
# code like `String.new`
|
224
|
-
# --
|
225
|
-
private
|
226
|
-
def shellsplit(line)
|
227
|
-
out, field = [], ""
|
228
|
-
|
229
|
-
# rubocop:disable Metrics/ParameterLists
|
230
|
-
line.scan(SHELLSPLIT) do |w, s, d, e, g, se|
|
231
|
-
raise ArgumentError, "Unmatched double quote: #{line.inspect}" if g
|
232
|
-
field = field + (w || s || (d&.gsub(%r!\\([$`"\\\n])!,
|
233
|
-
'\\1')) || e.gsub(%r!\\(.)!, '\\1'))
|
234
|
-
|
235
|
-
if se
|
236
|
-
out << field
|
237
|
-
field = ""
|
238
|
-
end
|
239
|
-
end
|
240
|
-
|
241
|
-
out
|
242
|
-
end
|
243
235
|
end
|
244
236
|
end
|
245
237
|
end
|
@@ -1,12 +1,12 @@
|
|
1
1
|
# Frozen-string-literal: true
|
2
|
-
# Copyright: 2017 -
|
2
|
+
# Copyright: 2017 - 2020 - ISC License
|
3
3
|
# Author: Jordon Bedwell
|
4
4
|
# Encoding: utf-8
|
5
5
|
|
6
6
|
module Liquid
|
7
7
|
class Tag
|
8
8
|
class Parser
|
9
|
-
VERSION =
|
9
|
+
VERSION = '2.0.0'
|
10
10
|
end
|
11
11
|
end
|
12
12
|
end
|
metadata
CHANGED
@@ -1,29 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: liquid-tag-parser
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jordon Bedwell
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-03-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: rake
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - "~>"
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '12'
|
20
|
-
type: :development
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - "~>"
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '12'
|
27
13
|
- !ruby/object:Gem::Dependency
|
28
14
|
name: pry
|
29
15
|
requirement: !ruby/object:Gem::Requirement
|
@@ -39,19 +25,19 @@ dependencies:
|
|
39
25
|
- !ruby/object:Gem::Version
|
40
26
|
version: '0.11'
|
41
27
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
28
|
+
name: rake
|
43
29
|
requirement: !ruby/object:Gem::Requirement
|
44
30
|
requirements:
|
45
|
-
- -
|
31
|
+
- - "~>"
|
46
32
|
- !ruby/object:Gem::Version
|
47
|
-
version: '0
|
33
|
+
version: '13.0'
|
48
34
|
type: :development
|
49
35
|
prerelease: false
|
50
36
|
version_requirements: !ruby/object:Gem::Requirement
|
51
37
|
requirements:
|
52
|
-
- -
|
38
|
+
- - "~>"
|
53
39
|
- !ruby/object:Gem::Version
|
54
|
-
version: '0
|
40
|
+
version: '13.0'
|
55
41
|
- !ruby/object:Gem::Dependency
|
56
42
|
name: simplecov
|
57
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -86,6 +72,20 @@ dependencies:
|
|
86
72
|
- - "<"
|
87
73
|
- !ruby/object:Gem::Version
|
88
74
|
version: '4'
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
name: envygeeks-rubocop
|
77
|
+
requirement: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - '='
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '1'
|
82
|
+
type: :development
|
83
|
+
prerelease: false
|
84
|
+
version_requirements: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - '='
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '1'
|
89
89
|
- !ruby/object:Gem::Dependency
|
90
90
|
name: luna-rspec-formatters
|
91
91
|
requirement: !ruby/object:Gem::Requirement
|
@@ -142,6 +142,7 @@ extensions: []
|
|
142
142
|
extra_rdoc_files: []
|
143
143
|
files:
|
144
144
|
- Gemfile
|
145
|
+
- lib/liquid-tag-parser.rb
|
145
146
|
- lib/liquid/tag/parser.rb
|
146
147
|
- lib/liquid/tag/parser/version.rb
|
147
148
|
homepage: http://github.com/envygeeks/liquid-tag-parser
|
@@ -163,8 +164,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
163
164
|
- !ruby/object:Gem::Version
|
164
165
|
version: '0'
|
165
166
|
requirements: []
|
166
|
-
|
167
|
-
rubygems_version: 2.7.6
|
167
|
+
rubygems_version: 3.1.2
|
168
168
|
signing_key:
|
169
169
|
specification_version: 4
|
170
170
|
summary: Parse liquid tags like a professional
|