liquid 5.4.0 → 5.6.4

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.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +11 -0
  3. data/README.md +48 -6
  4. data/lib/liquid/block.rb +8 -4
  5. data/lib/liquid/block_body.rb +28 -10
  6. data/lib/liquid/condition.rb +9 -4
  7. data/lib/liquid/const.rb +8 -0
  8. data/lib/liquid/context.rb +24 -14
  9. data/lib/liquid/deprecations.rb +22 -0
  10. data/lib/liquid/drop.rb +4 -0
  11. data/lib/liquid/environment.rb +159 -0
  12. data/lib/liquid/errors.rb +16 -15
  13. data/lib/liquid/expression.rb +101 -22
  14. data/lib/liquid/forloop_drop.rb +2 -5
  15. data/lib/liquid/lexer.rb +155 -44
  16. data/lib/liquid/locales/en.yml +1 -0
  17. data/lib/liquid/parse_context.rb +29 -6
  18. data/lib/liquid/parse_tree_visitor.rb +1 -1
  19. data/lib/liquid/parser.rb +3 -3
  20. data/lib/liquid/partial_cache.rb +12 -3
  21. data/lib/liquid/range_lookup.rb +14 -4
  22. data/lib/liquid/standardfilters.rb +82 -21
  23. data/lib/liquid/tablerowloop_drop.rb +1 -1
  24. data/lib/liquid/tag/disabler.rb +0 -8
  25. data/lib/liquid/tag.rb +13 -3
  26. data/lib/liquid/tags/assign.rb +1 -3
  27. data/lib/liquid/tags/break.rb +1 -3
  28. data/lib/liquid/tags/capture.rb +0 -2
  29. data/lib/liquid/tags/case.rb +1 -3
  30. data/lib/liquid/tags/comment.rb +60 -3
  31. data/lib/liquid/tags/continue.rb +1 -3
  32. data/lib/liquid/tags/cycle.rb +14 -4
  33. data/lib/liquid/tags/decrement.rb +8 -7
  34. data/lib/liquid/tags/echo.rb +2 -4
  35. data/lib/liquid/tags/for.rb +6 -8
  36. data/lib/liquid/tags/if.rb +3 -5
  37. data/lib/liquid/tags/ifchanged.rb +0 -2
  38. data/lib/liquid/tags/include.rb +8 -8
  39. data/lib/liquid/tags/increment.rb +8 -7
  40. data/lib/liquid/tags/inline_comment.rb +0 -15
  41. data/lib/liquid/tags/raw.rb +2 -4
  42. data/lib/liquid/tags/render.rb +14 -12
  43. data/lib/liquid/tags/table_row.rb +18 -6
  44. data/lib/liquid/tags/unless.rb +3 -5
  45. data/lib/liquid/tags.rb +47 -0
  46. data/lib/liquid/template.rb +60 -57
  47. data/lib/liquid/tokenizer.rb +127 -11
  48. data/lib/liquid/variable.rb +14 -8
  49. data/lib/liquid/variable_lookup.rb +13 -5
  50. data/lib/liquid/version.rb +1 -1
  51. data/lib/liquid.rb +15 -16
  52. metadata +37 -10
  53. data/lib/liquid/strainer_factory.rb +0 -41
@@ -61,14 +61,14 @@ module Liquid
61
61
 
62
62
  def strict_parse(markup)
63
63
  @filters = []
64
- p = Parser.new(markup)
64
+ p = @parse_context.new_parser(markup)
65
65
 
66
66
  return if p.look(:end_of_string)
67
67
 
68
68
  @name = parse_context.parse_expression(p.expression)
69
69
  while p.consume?(:pipe)
70
70
  filtername = p.consume(:id)
71
- filterargs = p.consume?(:colon) ? parse_filterargs(p) : []
71
+ filterargs = p.consume?(:colon) ? parse_filterargs(p) : Const::EMPTY_ARRAY
72
72
  @filters << parse_filter_expressions(filtername, filterargs)
73
73
  end
74
74
  p.consume(:end_of_string)
@@ -95,15 +95,21 @@ module Liquid
95
95
 
96
96
  def render_to_output_buffer(context, output)
97
97
  obj = render(context)
98
+ render_obj_to_output(obj, output)
99
+ output
100
+ end
98
101
 
99
- if obj.is_a?(Array)
100
- output << obj.join
101
- elsif obj.nil?
102
- else
102
+ def render_obj_to_output(obj, output)
103
+ case obj
104
+ when NilClass
105
+ # Do nothing
106
+ when Array
107
+ obj.each do |o|
108
+ render_obj_to_output(o, output)
109
+ end
110
+ when
103
111
  output << obj.to_s
104
112
  end
105
-
106
- output
107
113
  end
108
114
 
109
115
  def disabled?(_context)
@@ -6,16 +6,20 @@ module Liquid
6
6
 
7
7
  attr_reader :name, :lookups
8
8
 
9
- def self.parse(markup)
10
- new(markup)
9
+ def self.parse(markup, string_scanner = StringScanner.new(""), cache = nil)
10
+ new(markup, string_scanner, cache)
11
11
  end
12
12
 
13
- def initialize(markup)
13
+ def initialize(markup, string_scanner = StringScanner.new(""), cache = nil)
14
14
  lookups = markup.scan(VariableParser)
15
15
 
16
16
  name = lookups.shift
17
17
  if name&.start_with?('[') && name&.end_with?(']')
18
- name = Expression.parse(name[1..-2])
18
+ name = Expression.parse(
19
+ name[1..-2],
20
+ string_scanner,
21
+ cache,
22
+ )
19
23
  end
20
24
  @name = name
21
25
 
@@ -25,7 +29,11 @@ module Liquid
25
29
  @lookups.each_index do |i|
26
30
  lookup = lookups[i]
27
31
  if lookup&.start_with?('[') && lookup&.end_with?(']')
28
- lookups[i] = Expression.parse(lookup[1..-2])
32
+ lookups[i] = Expression.parse(
33
+ lookup[1..-2],
34
+ string_scanner,
35
+ cache,
36
+ )
29
37
  elsif COMMAND_METHODS.include?(lookup)
30
38
  @command_flags |= 1 << i
31
39
  end
@@ -2,5 +2,5 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module Liquid
5
- VERSION = "5.4.0"
5
+ VERSION = "5.6.4"
6
6
  end
data/lib/liquid.rb CHANGED
@@ -21,6 +21,8 @@
21
21
  # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
22
  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
23
 
24
+ require "strscan"
25
+
24
26
  module Liquid
25
27
  FilterSeparator = /\|/
26
28
  ArgumentSeparator = ','
@@ -41,16 +43,24 @@ module Liquid
41
43
  AnyStartingTag = /#{TagStart}|#{VariableStart}/o
42
44
  PartialTemplateParser = /#{TagStart}.*?#{TagEnd}|#{VariableStart}.*?#{VariableIncompleteEnd}/om
43
45
  TemplateParser = /(#{PartialTemplateParser}|#{AnyStartingTag})/om
44
- VariableParser = /\[[^\]]+\]|#{VariableSegment}+\??/o
46
+ VariableParser = /\[(?>[^\[\]]+|\g<0>)*\]|#{VariableSegment}+\??/o
45
47
 
46
48
  RAISE_EXCEPTION_LAMBDA = ->(_e) { raise }
47
-
48
- singleton_class.send(:attr_accessor, :cache_classes)
49
- self.cache_classes = true
49
+ HAS_STRING_SCANNER_SCAN_BYTE = StringScanner.instance_methods.include?(:scan_byte)
50
50
  end
51
51
 
52
52
  require "liquid/version"
53
+ require "liquid/deprecations"
54
+ require "liquid/const"
55
+ require 'liquid/standardfilters'
56
+ require 'liquid/file_system'
57
+ require 'liquid/parser_switching'
58
+ require 'liquid/tag'
59
+ require 'liquid/block'
53
60
  require 'liquid/parse_tree_visitor'
61
+ require 'liquid/interrupts'
62
+ require 'liquid/tags'
63
+ require "liquid/environment"
54
64
  require 'liquid/lexer'
55
65
  require 'liquid/parser'
56
66
  require 'liquid/i18n'
@@ -61,23 +71,16 @@ require 'liquid/extensions'
61
71
  require 'liquid/errors'
62
72
  require 'liquid/interrupts'
63
73
  require 'liquid/strainer_template'
64
- require 'liquid/strainer_factory'
65
- require 'liquid/expression'
66
74
  require 'liquid/context'
67
- require 'liquid/parser_switching'
68
75
  require 'liquid/tag'
69
- require 'liquid/tag/disabler'
70
- require 'liquid/tag/disableable'
71
- require 'liquid/block'
72
76
  require 'liquid/block_body'
73
77
  require 'liquid/document'
74
78
  require 'liquid/variable'
75
79
  require 'liquid/variable_lookup'
76
80
  require 'liquid/range_lookup'
77
- require 'liquid/file_system'
78
81
  require 'liquid/resource_limits'
82
+ require 'liquid/expression'
79
83
  require 'liquid/template'
80
- require 'liquid/standardfilters'
81
84
  require 'liquid/condition'
82
85
  require 'liquid/utils'
83
86
  require 'liquid/tokenizer'
@@ -86,7 +89,3 @@ require 'liquid/partial_cache'
86
89
  require 'liquid/usage'
87
90
  require 'liquid/registers'
88
91
  require 'liquid/template_factory'
89
-
90
- # Load all the tags of the standard library
91
- #
92
- Dir["#{__dir__}/liquid/tags/*.rb"].each { |f| require f }
metadata CHANGED
@@ -1,15 +1,42 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: liquid
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.4.0
4
+ version: 5.6.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tobias Lütke
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2022-07-29 00:00:00.000000000 Z
10
+ date: 2025-01-14 00:00:00.000000000 Z
12
11
  dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: strscan
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: 3.1.1
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: 3.1.1
26
+ - !ruby/object:Gem::Dependency
27
+ name: bigdecimal
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
13
40
  - !ruby/object:Gem::Dependency
14
41
  name: rake
15
42
  requirement: !ruby/object:Gem::Requirement
@@ -38,7 +65,6 @@ dependencies:
38
65
  - - ">="
39
66
  - !ruby/object:Gem::Version
40
67
  version: '0'
41
- description:
42
68
  email:
43
69
  - tobi@leetsoft.com
44
70
  executables: []
@@ -54,9 +80,12 @@ files:
54
80
  - lib/liquid/block.rb
55
81
  - lib/liquid/block_body.rb
56
82
  - lib/liquid/condition.rb
83
+ - lib/liquid/const.rb
57
84
  - lib/liquid/context.rb
85
+ - lib/liquid/deprecations.rb
58
86
  - lib/liquid/document.rb
59
87
  - lib/liquid/drop.rb
88
+ - lib/liquid/environment.rb
60
89
  - lib/liquid/errors.rb
61
90
  - lib/liquid/expression.rb
62
91
  - lib/liquid/extensions.rb
@@ -77,12 +106,12 @@ files:
77
106
  - lib/liquid/registers.rb
78
107
  - lib/liquid/resource_limits.rb
79
108
  - lib/liquid/standardfilters.rb
80
- - lib/liquid/strainer_factory.rb
81
109
  - lib/liquid/strainer_template.rb
82
110
  - lib/liquid/tablerowloop_drop.rb
83
111
  - lib/liquid/tag.rb
84
112
  - lib/liquid/tag/disableable.rb
85
113
  - lib/liquid/tag/disabler.rb
114
+ - lib/liquid/tags.rb
86
115
  - lib/liquid/tags/assign.rb
87
116
  - lib/liquid/tags/break.rb
88
117
  - lib/liquid/tags/capture.rb
@@ -110,12 +139,11 @@ files:
110
139
  - lib/liquid/variable.rb
111
140
  - lib/liquid/variable_lookup.rb
112
141
  - lib/liquid/version.rb
113
- homepage: http://www.liquidmarkup.org
142
+ homepage: https://shopify.github.io/liquid/
114
143
  licenses:
115
144
  - MIT
116
145
  metadata:
117
146
  allowed_push_host: https://rubygems.org
118
- post_install_message:
119
147
  rdoc_options: []
120
148
  require_paths:
121
149
  - lib
@@ -123,15 +151,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
123
151
  requirements:
124
152
  - - ">="
125
153
  - !ruby/object:Gem::Version
126
- version: 2.7.0
154
+ version: 3.0.0
127
155
  required_rubygems_version: !ruby/object:Gem::Requirement
128
156
  requirements:
129
157
  - - ">="
130
158
  - !ruby/object:Gem::Version
131
159
  version: 1.3.7
132
160
  requirements: []
133
- rubygems_version: 3.3.3
134
- signing_key:
161
+ rubygems_version: 3.6.2
135
162
  specification_version: 4
136
163
  summary: A secure, non-evaling end user template engine with aesthetic markup.
137
164
  test_files: []
@@ -1,41 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Liquid
4
- # StrainerFactory is the factory for the filters system.
5
- module StrainerFactory
6
- extend self
7
-
8
- def add_global_filter(filter)
9
- strainer_class_cache.clear
10
- GlobalCache.add_filter(filter)
11
- end
12
-
13
- def create(context, filters = [])
14
- strainer_from_cache(filters).new(context)
15
- end
16
-
17
- def global_filter_names
18
- GlobalCache.filter_method_names
19
- end
20
-
21
- GlobalCache = Class.new(StrainerTemplate)
22
-
23
- private
24
-
25
- def strainer_from_cache(filters)
26
- if filters.empty?
27
- GlobalCache
28
- else
29
- strainer_class_cache[filters] ||= begin
30
- klass = Class.new(GlobalCache)
31
- filters.each { |f| klass.add_filter(f) }
32
- klass
33
- end
34
- end
35
- end
36
-
37
- def strainer_class_cache
38
- @strainer_class_cache ||= {}
39
- end
40
- end
41
- end