liquid-render-tag 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Liquid
4
+ class TemplateFactory
5
+ def for(_template_name)
6
+ Liquid::Template.new
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Liquid
4
+ class Tokenizer
5
+ attr_reader :line_number, :for_liquid_tag
6
+
7
+ def initialize(source, line_numbers = false, line_number: nil, for_liquid_tag: false)
8
+ @source = source
9
+ @line_number = line_number || (line_numbers ? 1 : nil)
10
+ @for_liquid_tag = for_liquid_tag
11
+ @tokens = tokenize
12
+ end
13
+
14
+ def shift
15
+ (token = @tokens.shift) || return
16
+
17
+ if @line_number
18
+ @line_number += @for_liquid_tag ? 1 : token.count("\n")
19
+ end
20
+
21
+ token
22
+ end
23
+
24
+ private
25
+
26
+ def tokenize
27
+ return [] if @source.to_s.empty?
28
+
29
+ return @source.split("\n") if @for_liquid_tag
30
+
31
+ tokens = @source.split(TemplateParser)
32
+
33
+ # removes the rogue empty element at the beginning of the array
34
+ tokens.shift if tokens[0]&.empty?
35
+
36
+ tokens
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,170 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Liquid
4
+ # Holds variables. Variables are only loaded "just in time"
5
+ # and are not evaluated as part of the render stage
6
+ #
7
+ # {{ monkey }}
8
+ # {{ user.name }}
9
+ #
10
+ # Variables can be combined with filters:
11
+ #
12
+ # {{ user | link }}
13
+ #
14
+ class Variable
15
+ FilterMarkupRegex = /#{FilterSeparator}\s*(.*)/om
16
+ FilterParser = /(?:\s+|#{QuotedFragment}|#{ArgumentSeparator})+/o
17
+ FilterArgsRegex = /(?:#{FilterArgumentSeparator}|#{ArgumentSeparator})\s*((?:\w+\s*\:\s*)?#{QuotedFragment})/o
18
+ JustTagAttributes = /\A#{TagAttributes}\z/o
19
+ MarkupWithQuotedFragment = /(#{QuotedFragment})(.*)/om
20
+
21
+ attr_accessor :filters, :name, :line_number
22
+ attr_reader :parse_context
23
+ alias_method :options, :parse_context
24
+
25
+ include ParserSwitching
26
+
27
+ def initialize(markup, parse_context)
28
+ @markup = markup
29
+ @name = nil
30
+ @parse_context = parse_context
31
+ @line_number = parse_context.line_number
32
+
33
+ parse_with_selected_parser(markup)
34
+ end
35
+
36
+ def raw
37
+ @markup
38
+ end
39
+
40
+ def markup_context(markup)
41
+ "in \"{{#{markup}}}\""
42
+ end
43
+
44
+ def lax_parse(markup)
45
+ @filters = []
46
+ return unless markup =~ MarkupWithQuotedFragment
47
+
48
+ name_markup = Regexp.last_match(1)
49
+ filter_markup = Regexp.last_match(2)
50
+ @name = Expression.parse(name_markup)
51
+ if filter_markup =~ FilterMarkupRegex
52
+ filters = Regexp.last_match(1).scan(FilterParser)
53
+ filters.each do |f|
54
+ next unless f =~ /\w+/
55
+ filtername = Regexp.last_match(0)
56
+ filterargs = f.scan(FilterArgsRegex).flatten
57
+ @filters << parse_filter_expressions(filtername, filterargs)
58
+ end
59
+ end
60
+ end
61
+
62
+ def strict_parse(markup)
63
+ @filters = []
64
+ p = Parser.new(markup)
65
+
66
+ @name = Expression.parse(p.expression)
67
+ while p.consume?(:pipe)
68
+ filtername = p.consume(:id)
69
+ filterargs = p.consume?(:colon) ? parse_filterargs(p) : []
70
+ @filters << parse_filter_expressions(filtername, filterargs)
71
+ end
72
+ p.consume(:end_of_string)
73
+ end
74
+
75
+ def parse_filterargs(p)
76
+ # first argument
77
+ filterargs = [p.argument]
78
+ # followed by comma separated others
79
+ filterargs << p.argument while p.consume?(:comma)
80
+ filterargs
81
+ end
82
+
83
+ def render(context)
84
+ obj = @filters.inject(context.evaluate(@name)) do |output, (filter_name, filter_args, filter_kwargs)|
85
+ filter_args = evaluate_filter_expressions(context, filter_args, filter_kwargs)
86
+ context.invoke(filter_name, output, *filter_args)
87
+ end
88
+
89
+ obj = context.apply_global_filter(obj)
90
+ taint_check(context, obj)
91
+ obj
92
+ end
93
+
94
+ def render_to_output_buffer(context, output)
95
+ obj = render(context)
96
+
97
+ if obj.is_a?(Array)
98
+ output << obj.join
99
+ elsif obj.nil?
100
+ else
101
+ output << obj.to_s
102
+ end
103
+
104
+ output
105
+ end
106
+
107
+ def disabled?(_context)
108
+ false
109
+ end
110
+
111
+ def disabled_tags
112
+ []
113
+ end
114
+
115
+ private
116
+
117
+ def parse_filter_expressions(filter_name, unparsed_args)
118
+ filter_args = []
119
+ keyword_args = nil
120
+ unparsed_args.each do |a|
121
+ if (matches = a.match(JustTagAttributes))
122
+ keyword_args ||= {}
123
+ keyword_args[matches[1]] = Expression.parse(matches[2])
124
+ else
125
+ filter_args << Expression.parse(a)
126
+ end
127
+ end
128
+ result = [filter_name, filter_args]
129
+ result << keyword_args if keyword_args
130
+ result
131
+ end
132
+
133
+ def evaluate_filter_expressions(context, filter_args, filter_kwargs)
134
+ parsed_args = filter_args.map { |expr| context.evaluate(expr) }
135
+ if filter_kwargs
136
+ parsed_kwargs = {}
137
+ filter_kwargs.each do |key, expr|
138
+ parsed_kwargs[key] = context.evaluate(expr)
139
+ end
140
+ parsed_args << parsed_kwargs
141
+ end
142
+ parsed_args
143
+ end
144
+
145
+ def taint_check(context, obj)
146
+ return if Template.taint_mode == :lax
147
+ return unless obj.tainted?
148
+
149
+ @markup =~ QuotedFragment
150
+ name = Regexp.last_match(0)
151
+
152
+ error = TaintedError.new("variable '#{name}' is tainted and was not escaped")
153
+ error.line_number = line_number
154
+ error.template_name = context.template_name
155
+
156
+ case Template.taint_mode
157
+ when :warn
158
+ context.warnings << error
159
+ when :error
160
+ raise error
161
+ end
162
+ end
163
+
164
+ class ParseTreeVisitor < Liquid::ParseTreeVisitor
165
+ def children
166
+ [@node.name] + @node.filters.flatten
167
+ end
168
+ end
169
+ end
170
+ end
@@ -0,0 +1,3 @@
1
+ module LiquidRenderTag
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,27 @@
1
+
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "liquid-render-tag/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "liquid-render-tag"
8
+ spec.version = LiquidRenderTag::VERSION
9
+ spec.authors = "Bridgetown Team"
10
+ spec.email = "maintainers@bridgetownrb.com"
11
+
12
+ spec.summary = %q{Backported Render tag and related changes from Liquid master to work with 4.0.3}
13
+ spec.description = spec.summary
14
+ spec.homepage = "https://github.com/bridgetownrb/liquid-render-tag"
15
+ spec.license = "MIT"
16
+
17
+ # Specify which files should be added to the gem when it is released.
18
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
19
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
20
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
21
+ end
22
+ spec.require_paths = ["lib"]
23
+
24
+ spec.add_development_dependency "bundler"
25
+ spec.add_development_dependency "rake", "~> 12.0"
26
+ spec.add_development_dependency "liquid", "~> 4.0.3"
27
+ end
metadata ADDED
@@ -0,0 +1,108 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: liquid-render-tag
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Bridgetown Team
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-05-14 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '12.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '12.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: liquid
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 4.0.3
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 4.0.3
55
+ description: Backported Render tag and related changes from Liquid master to work
56
+ with 4.0.3
57
+ email: maintainers@bridgetownrb.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".gitignore"
63
+ - Gemfile
64
+ - LICENSE.txt
65
+ - README.md
66
+ - Rakefile
67
+ - lib/liquid-render-tag.rb
68
+ - lib/liquid-render-tag/block_body.rb
69
+ - lib/liquid-render-tag/context.rb
70
+ - lib/liquid-render-tag/partial_cache.rb
71
+ - lib/liquid-render-tag/register.rb
72
+ - lib/liquid-render-tag/registers/disabled_tags.rb
73
+ - lib/liquid-render-tag/static_registers.rb
74
+ - lib/liquid-render-tag/strainer_factory.rb
75
+ - lib/liquid-render-tag/strainer_template.rb
76
+ - lib/liquid-render-tag/tag.rb
77
+ - lib/liquid-render-tag/tags/render.rb
78
+ - lib/liquid-render-tag/template.rb
79
+ - lib/liquid-render-tag/template_factory.rb
80
+ - lib/liquid-render-tag/tokenizer.rb
81
+ - lib/liquid-render-tag/variable.rb
82
+ - lib/liquid-render-tag/version.rb
83
+ - liquid-render-tag.gemspec
84
+ homepage: https://github.com/bridgetownrb/liquid-render-tag
85
+ licenses:
86
+ - MIT
87
+ metadata: {}
88
+ post_install_message:
89
+ rdoc_options: []
90
+ require_paths:
91
+ - lib
92
+ required_ruby_version: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ required_rubygems_version: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ requirements: []
103
+ rubygems_version: 3.0.6
104
+ signing_key:
105
+ specification_version: 4
106
+ summary: Backported Render tag and related changes from Liquid master to work with
107
+ 4.0.3
108
+ test_files: []