liquid 4.0.0.rc3 → 5.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 +5 -5
- data/History.md +93 -2
- data/README.md +8 -0
- data/lib/liquid.rb +18 -5
- data/lib/liquid/block.rb +47 -20
- data/lib/liquid/block_body.rb +190 -76
- data/lib/liquid/condition.rb +69 -29
- data/lib/liquid/context.rb +122 -76
- data/lib/liquid/document.rb +47 -9
- data/lib/liquid/drop.rb +4 -2
- data/lib/liquid/errors.rb +20 -25
- data/lib/liquid/expression.rb +30 -31
- data/lib/liquid/extensions.rb +8 -0
- data/lib/liquid/file_system.rb +6 -4
- data/lib/liquid/forloop_drop.rb +11 -4
- data/lib/liquid/i18n.rb +5 -3
- data/lib/liquid/interrupts.rb +3 -1
- data/lib/liquid/lexer.rb +35 -26
- data/lib/liquid/locales/en.yml +4 -2
- data/lib/liquid/parse_context.rb +17 -4
- data/lib/liquid/parse_tree_visitor.rb +42 -0
- data/lib/liquid/parser.rb +30 -18
- data/lib/liquid/parser_switching.rb +17 -3
- data/lib/liquid/partial_cache.rb +24 -0
- data/lib/liquid/profiler.rb +67 -86
- data/lib/liquid/profiler/hooks.rb +26 -14
- data/lib/liquid/range_lookup.rb +5 -3
- data/lib/liquid/register.rb +6 -0
- data/lib/liquid/resource_limits.rb +47 -8
- data/lib/liquid/standardfilters.rb +171 -57
- data/lib/liquid/static_registers.rb +44 -0
- data/lib/liquid/strainer_factory.rb +36 -0
- data/lib/liquid/strainer_template.rb +53 -0
- data/lib/liquid/tablerowloop_drop.rb +6 -4
- data/lib/liquid/tag.rb +28 -6
- data/lib/liquid/tag/disableable.rb +22 -0
- data/lib/liquid/tag/disabler.rb +21 -0
- data/lib/liquid/tags/assign.rb +32 -10
- data/lib/liquid/tags/break.rb +8 -3
- data/lib/liquid/tags/capture.rb +11 -8
- data/lib/liquid/tags/case.rb +41 -27
- data/lib/liquid/tags/comment.rb +5 -3
- data/lib/liquid/tags/continue.rb +8 -3
- data/lib/liquid/tags/cycle.rb +35 -16
- data/lib/liquid/tags/decrement.rb +6 -3
- data/lib/liquid/tags/echo.rb +26 -0
- data/lib/liquid/tags/for.rb +79 -47
- data/lib/liquid/tags/if.rb +53 -30
- data/lib/liquid/tags/ifchanged.rb +11 -10
- data/lib/liquid/tags/include.rb +42 -44
- data/lib/liquid/tags/increment.rb +7 -3
- data/lib/liquid/tags/raw.rb +14 -11
- data/lib/liquid/tags/render.rb +84 -0
- data/lib/liquid/tags/table_row.rb +32 -20
- data/lib/liquid/tags/unless.rb +15 -15
- data/lib/liquid/template.rb +60 -71
- data/lib/liquid/template_factory.rb +9 -0
- data/lib/liquid/tokenizer.rb +17 -9
- data/lib/liquid/usage.rb +8 -0
- data/lib/liquid/utils.rb +6 -4
- data/lib/liquid/variable.rb +55 -38
- data/lib/liquid/variable_lookup.rb +14 -6
- data/lib/liquid/version.rb +3 -1
- data/test/integration/assign_test.rb +74 -5
- data/test/integration/blank_test.rb +11 -8
- data/test/integration/block_test.rb +58 -0
- data/test/integration/capture_test.rb +18 -10
- data/test/integration/context_test.rb +608 -5
- data/test/integration/document_test.rb +4 -2
- data/test/integration/drop_test.rb +67 -83
- data/test/integration/error_handling_test.rb +90 -60
- data/test/integration/expression_test.rb +46 -0
- data/test/integration/filter_test.rb +53 -42
- data/test/integration/hash_ordering_test.rb +5 -3
- data/test/integration/output_test.rb +26 -24
- data/test/integration/parsing_quirks_test.rb +24 -8
- data/test/integration/{render_profiling_test.rb → profiler_test.rb} +84 -25
- data/test/integration/security_test.rb +41 -18
- data/test/integration/standard_filter_test.rb +523 -205
- data/test/integration/tag/disableable_test.rb +59 -0
- data/test/integration/tag_test.rb +45 -0
- data/test/integration/tags/break_tag_test.rb +4 -2
- data/test/integration/tags/continue_tag_test.rb +4 -2
- data/test/integration/tags/echo_test.rb +13 -0
- data/test/integration/tags/for_tag_test.rb +109 -53
- data/test/integration/tags/if_else_tag_test.rb +5 -3
- data/test/integration/tags/include_tag_test.rb +83 -52
- data/test/integration/tags/increment_tag_test.rb +4 -2
- data/test/integration/tags/liquid_tag_test.rb +116 -0
- data/test/integration/tags/raw_tag_test.rb +14 -11
- data/test/integration/tags/render_tag_test.rb +213 -0
- data/test/integration/tags/standard_tag_test.rb +38 -31
- data/test/integration/tags/statements_test.rb +23 -21
- data/test/integration/tags/table_row_test.rb +2 -0
- data/test/integration/tags/unless_else_tag_test.rb +4 -2
- data/test/integration/template_test.rb +128 -121
- data/test/integration/trim_mode_test.rb +82 -44
- data/test/integration/variable_test.rb +46 -31
- data/test/test_helper.rb +75 -23
- data/test/unit/block_unit_test.rb +19 -24
- data/test/unit/condition_unit_test.rb +82 -72
- data/test/unit/file_system_unit_test.rb +6 -4
- data/test/unit/i18n_unit_test.rb +7 -5
- data/test/unit/lexer_unit_test.rb +12 -10
- data/test/unit/parse_tree_visitor_test.rb +247 -0
- data/test/unit/parser_unit_test.rb +37 -35
- data/test/unit/partial_cache_unit_test.rb +128 -0
- data/test/unit/regexp_unit_test.rb +17 -15
- data/test/unit/static_registers_unit_test.rb +156 -0
- data/test/unit/strainer_factory_unit_test.rb +100 -0
- data/test/unit/strainer_template_unit_test.rb +82 -0
- data/test/unit/tag_unit_test.rb +5 -3
- data/test/unit/tags/case_tag_unit_test.rb +3 -1
- data/test/unit/tags/for_tag_unit_test.rb +4 -2
- data/test/unit/tags/if_tag_unit_test.rb +3 -1
- data/test/unit/template_factory_unit_test.rb +12 -0
- data/test/unit/template_unit_test.rb +19 -10
- data/test/unit/tokenizer_unit_test.rb +19 -17
- data/test/unit/variable_unit_test.rb +51 -49
- metadata +83 -50
- data/lib/liquid/strainer.rb +0 -65
- data/test/unit/context_unit_test.rb +0 -483
- data/test/unit/strainer_unit_test.rb +0 -136
data/lib/liquid/document.rb
CHANGED
@@ -1,26 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Liquid
|
2
|
-
class Document
|
4
|
+
class Document
|
3
5
|
def self.parse(tokens, parse_context)
|
4
|
-
doc = new
|
6
|
+
doc = new(parse_context)
|
5
7
|
doc.parse(tokens, parse_context)
|
6
8
|
doc
|
7
9
|
end
|
8
10
|
|
9
|
-
|
10
|
-
|
11
|
-
|
11
|
+
attr_reader :parse_context, :body
|
12
|
+
|
13
|
+
def initialize(parse_context)
|
14
|
+
@parse_context = parse_context
|
15
|
+
@body = new_body
|
16
|
+
end
|
17
|
+
|
18
|
+
def nodelist
|
19
|
+
@body.nodelist
|
20
|
+
end
|
21
|
+
|
22
|
+
def parse(tokenizer, parse_context)
|
23
|
+
while parse_body(tokenizer)
|
12
24
|
end
|
25
|
+
@body.freeze
|
13
26
|
rescue SyntaxError => e
|
14
27
|
e.line_number ||= parse_context.line_number
|
15
28
|
raise
|
16
29
|
end
|
17
30
|
|
18
|
-
def unknown_tag(tag,
|
31
|
+
def unknown_tag(tag, _markup, _tokenizer)
|
19
32
|
case tag
|
20
|
-
when 'else'
|
21
|
-
raise SyntaxError
|
33
|
+
when 'else', 'end'
|
34
|
+
raise SyntaxError, parse_context.locale.t("errors.syntax.unexpected_outer_tag", tag: tag)
|
22
35
|
else
|
23
|
-
raise SyntaxError
|
36
|
+
raise SyntaxError, parse_context.locale.t("errors.syntax.unknown_tag", tag: tag)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def render_to_output_buffer(context, output)
|
41
|
+
@body.render_to_output_buffer(context, output)
|
42
|
+
end
|
43
|
+
|
44
|
+
def render(context)
|
45
|
+
render_to_output_buffer(context, +'')
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def new_body
|
51
|
+
parse_context.new_block_body
|
52
|
+
end
|
53
|
+
|
54
|
+
def parse_body(tokenizer)
|
55
|
+
@body.parse(tokenizer, parse_context) do |unknown_tag_name, unknown_tag_markup|
|
56
|
+
if unknown_tag_name
|
57
|
+
unknown_tag(unknown_tag_name, unknown_tag_markup, tokenizer)
|
58
|
+
true
|
59
|
+
else
|
60
|
+
false
|
61
|
+
end
|
24
62
|
end
|
25
63
|
end
|
26
64
|
end
|
data/lib/liquid/drop.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'set'
|
2
4
|
|
3
5
|
module Liquid
|
@@ -25,7 +27,7 @@ module Liquid
|
|
25
27
|
|
26
28
|
# Catch all for the method
|
27
29
|
def liquid_method_missing(method)
|
28
|
-
return nil unless @context
|
30
|
+
return nil unless @context&.strict_variables
|
29
31
|
raise Liquid::UndefinedDropMethod, "undefined method #{method}"
|
30
32
|
end
|
31
33
|
|
@@ -67,7 +69,7 @@ module Liquid
|
|
67
69
|
|
68
70
|
if include?(Enumerable)
|
69
71
|
blacklist += Enumerable.public_instance_methods
|
70
|
-
blacklist -= [:sort, :count, :first, :min, :max
|
72
|
+
blacklist -= [:sort, :count, :first, :min, :max]
|
71
73
|
end
|
72
74
|
|
73
75
|
whitelist = [:to_liquid] + (public_instance_methods - blacklist)
|
data/lib/liquid/errors.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Liquid
|
2
4
|
class Error < ::StandardError
|
3
5
|
attr_accessor :line_number
|
@@ -5,7 +7,7 @@ module Liquid
|
|
5
7
|
attr_accessor :markup_context
|
6
8
|
|
7
9
|
def to_s(with_prefix = true)
|
8
|
-
str = ""
|
10
|
+
str = +""
|
9
11
|
str << message_prefix if with_prefix
|
10
12
|
str << super()
|
11
13
|
|
@@ -17,22 +19,14 @@ module Liquid
|
|
17
19
|
str
|
18
20
|
end
|
19
21
|
|
20
|
-
def self.render(e)
|
21
|
-
if e.is_a?(Liquid::Error)
|
22
|
-
e.to_s
|
23
|
-
else
|
24
|
-
"Liquid error: #{e}"
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
22
|
private
|
29
23
|
|
30
24
|
def message_prefix
|
31
|
-
str = ""
|
32
|
-
if is_a?(SyntaxError)
|
33
|
-
|
25
|
+
str = +""
|
26
|
+
str << if is_a?(SyntaxError)
|
27
|
+
"Liquid syntax error"
|
34
28
|
else
|
35
|
-
|
29
|
+
"Liquid error"
|
36
30
|
end
|
37
31
|
|
38
32
|
if line_number
|
@@ -46,18 +40,19 @@ module Liquid
|
|
46
40
|
end
|
47
41
|
end
|
48
42
|
|
49
|
-
ArgumentError
|
50
|
-
ContextError
|
51
|
-
FileSystemError
|
52
|
-
StandardError
|
53
|
-
SyntaxError
|
54
|
-
StackLevelError
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
UndefinedVariable = Class.new(Error)
|
43
|
+
ArgumentError = Class.new(Error)
|
44
|
+
ContextError = Class.new(Error)
|
45
|
+
FileSystemError = Class.new(Error)
|
46
|
+
StandardError = Class.new(Error)
|
47
|
+
SyntaxError = Class.new(Error)
|
48
|
+
StackLevelError = Class.new(Error)
|
49
|
+
MemoryError = Class.new(Error)
|
50
|
+
ZeroDivisionError = Class.new(Error)
|
51
|
+
FloatDomainError = Class.new(Error)
|
52
|
+
UndefinedVariable = Class.new(Error)
|
60
53
|
UndefinedDropMethod = Class.new(Error)
|
61
|
-
UndefinedFilter
|
54
|
+
UndefinedFilter = Class.new(Error)
|
62
55
|
MethodOverrideError = Class.new(Error)
|
56
|
+
DisabledError = Class.new(Error)
|
57
|
+
InternalError = Class.new(Error)
|
63
58
|
end
|
data/lib/liquid/expression.rb
CHANGED
@@ -1,41 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Liquid
|
2
4
|
class Expression
|
3
|
-
|
4
|
-
|
5
|
+
LITERALS = {
|
6
|
+
nil => nil, 'nil' => nil, 'null' => nil, '' => nil,
|
7
|
+
'true' => true,
|
8
|
+
'false' => false,
|
9
|
+
'blank' => '',
|
10
|
+
'empty' => ''
|
11
|
+
}.freeze
|
5
12
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
13
|
+
SINGLE_QUOTED_STRING = /\A\s*'(.*)'\s*\z/m
|
14
|
+
DOUBLE_QUOTED_STRING = /\A\s*"(.*)"\s*\z/m
|
15
|
+
INTEGERS_REGEX = /\A\s*(-?\d+)\s*\z/
|
16
|
+
FLOATS_REGEX = /\A\s*(-?\d[\d\.]+)\s*\z/
|
10
17
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
end
|
15
|
-
|
16
|
-
LITERALS = {
|
17
|
-
nil => nil, 'nil'.freeze => nil, 'null'.freeze => nil, ''.freeze => nil,
|
18
|
-
'true'.freeze => true,
|
19
|
-
'false'.freeze => false,
|
20
|
-
'blank'.freeze => MethodLiteral.new(:blank?, '').freeze,
|
21
|
-
'empty'.freeze => MethodLiteral.new(:empty?, '').freeze
|
22
|
-
}
|
18
|
+
# Use an atomic group (?>...) to avoid pathological backtracing from
|
19
|
+
# malicious input as described in https://github.com/Shopify/liquid/issues/1357
|
20
|
+
RANGES_REGEX = /\A\s*\(\s*(?>(\S+)\s*\.\.)\s*(\S+)\s*\)\s*\z/
|
23
21
|
|
24
22
|
def self.parse(markup)
|
25
|
-
|
26
|
-
|
23
|
+
case markup
|
24
|
+
when nil
|
25
|
+
nil
|
26
|
+
when SINGLE_QUOTED_STRING, DOUBLE_QUOTED_STRING
|
27
|
+
Regexp.last_match(1)
|
28
|
+
when INTEGERS_REGEX
|
29
|
+
Regexp.last_match(1).to_i
|
30
|
+
when RANGES_REGEX
|
31
|
+
RangeLookup.parse(Regexp.last_match(1), Regexp.last_match(2))
|
32
|
+
when FLOATS_REGEX
|
33
|
+
Regexp.last_match(1).to_f
|
27
34
|
else
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
when /\A"(.*)"\z/m # Double quoted strings
|
32
|
-
$1
|
33
|
-
when /\A(-?\d+)\z/ # Integer and floats
|
34
|
-
$1.to_i
|
35
|
-
when /\A\((\S+)\.\.(\S+)\)\z/ # Ranges
|
36
|
-
RangeLookup.parse($1, $2)
|
37
|
-
when /\A(-?\d[\d\.]+)\z/ # Floats
|
38
|
-
$1.to_f
|
35
|
+
markup = markup.strip
|
36
|
+
if LITERALS.key?(markup)
|
37
|
+
LITERALS[markup]
|
39
38
|
else
|
40
39
|
VariableLookup.parse(markup)
|
41
40
|
end
|
data/lib/liquid/extensions.rb
CHANGED
data/lib/liquid/file_system.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Liquid
|
2
4
|
# A Liquid file system is a way to let your templates retrieve other templates for use with the include tag.
|
3
5
|
#
|
@@ -44,8 +46,8 @@ module Liquid
|
|
44
46
|
class LocalFileSystem
|
45
47
|
attr_accessor :root
|
46
48
|
|
47
|
-
def initialize(root, pattern = "_%s.liquid"
|
48
|
-
@root
|
49
|
+
def initialize(root, pattern = "_%s.liquid")
|
50
|
+
@root = root
|
49
51
|
@pattern = pattern
|
50
52
|
end
|
51
53
|
|
@@ -57,9 +59,9 @@ module Liquid
|
|
57
59
|
end
|
58
60
|
|
59
61
|
def full_path(template_path)
|
60
|
-
raise FileSystemError, "Illegal template name '#{template_path}'" unless
|
62
|
+
raise FileSystemError, "Illegal template name '#{template_path}'" unless %r{\A[^./][a-zA-Z0-9_/]+\z}.match?(template_path)
|
61
63
|
|
62
|
-
full_path = if template_path.include?('/'
|
64
|
+
full_path = if template_path.include?('/')
|
63
65
|
File.join(root, File.dirname(template_path), @pattern % File.basename(template_path))
|
64
66
|
else
|
65
67
|
File.join(root, @pattern % template_path)
|
data/lib/liquid/forloop_drop.rb
CHANGED
@@ -1,13 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Liquid
|
2
4
|
class ForloopDrop < Drop
|
3
5
|
def initialize(name, length, parentloop)
|
4
|
-
@name
|
5
|
-
@length
|
6
|
+
@name = name
|
7
|
+
@length = length
|
6
8
|
@parentloop = parentloop
|
7
|
-
@index
|
9
|
+
@index = 0
|
8
10
|
end
|
9
11
|
|
10
|
-
attr_reader :
|
12
|
+
attr_reader :length, :parentloop
|
13
|
+
|
14
|
+
def name
|
15
|
+
Usage.increment('forloop_drop_name')
|
16
|
+
@name
|
17
|
+
end
|
11
18
|
|
12
19
|
def index
|
13
20
|
@index + 1
|
data/lib/liquid/i18n.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'yaml'
|
2
4
|
|
3
5
|
module Liquid
|
@@ -26,13 +28,13 @@ module Liquid
|
|
26
28
|
def interpolate(name, vars)
|
27
29
|
name.gsub(/%\{(\w+)\}/) do
|
28
30
|
# raise TranslationError, "Undefined key #{$1} for interpolation in translation #{name}" unless vars[$1.to_sym]
|
29
|
-
|
31
|
+
(vars[Regexp.last_match(1).to_sym]).to_s
|
30
32
|
end
|
31
33
|
end
|
32
34
|
|
33
35
|
def deep_fetch_translation(name)
|
34
|
-
name.split('.'
|
35
|
-
level[cur]
|
36
|
+
name.split('.').reduce(locale) do |level, cur|
|
37
|
+
level[cur] || raise(TranslationError, "Translation for #{name} does not exist in locale #{path}")
|
36
38
|
end
|
37
39
|
end
|
38
40
|
end
|
data/lib/liquid/interrupts.rb
CHANGED
@@ -1,10 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Liquid
|
2
4
|
# An interrupt is any command that breaks processing of a block (ex: a for loop).
|
3
5
|
class Interrupt
|
4
6
|
attr_reader :message
|
5
7
|
|
6
8
|
def initialize(message = nil)
|
7
|
-
@message = message || "interrupt"
|
9
|
+
@message = message || "interrupt"
|
8
10
|
end
|
9
11
|
end
|
10
12
|
|
data/lib/liquid/lexer.rb
CHANGED
@@ -1,44 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "strscan"
|
2
4
|
module Liquid
|
3
5
|
class Lexer
|
4
6
|
SPECIALS = {
|
5
|
-
'|'
|
6
|
-
'.'
|
7
|
-
':'
|
8
|
-
','
|
9
|
-
'['
|
10
|
-
']'
|
11
|
-
'('
|
12
|
-
')'
|
13
|
-
'?'
|
14
|
-
'-'
|
15
|
-
}
|
16
|
-
IDENTIFIER
|
7
|
+
'|' => :pipe,
|
8
|
+
'.' => :dot,
|
9
|
+
':' => :colon,
|
10
|
+
',' => :comma,
|
11
|
+
'[' => :open_square,
|
12
|
+
']' => :close_square,
|
13
|
+
'(' => :open_round,
|
14
|
+
')' => :close_round,
|
15
|
+
'?' => :question,
|
16
|
+
'-' => :dash,
|
17
|
+
}.freeze
|
18
|
+
IDENTIFIER = /[a-zA-Z_][\w-]*\??/
|
17
19
|
SINGLE_STRING_LITERAL = /'[^\']*'/
|
18
20
|
DOUBLE_STRING_LITERAL = /"[^\"]*"/
|
19
|
-
NUMBER_LITERAL
|
20
|
-
DOTDOT
|
21
|
-
COMPARISON_OPERATOR
|
21
|
+
NUMBER_LITERAL = /-?\d+(\.\d+)?/
|
22
|
+
DOTDOT = /\.\./
|
23
|
+
COMPARISON_OPERATOR = /==|!=|<>|<=?|>=?|contains(?=\s)/
|
24
|
+
WHITESPACE_OR_NOTHING = /\s*/
|
22
25
|
|
23
26
|
def initialize(input)
|
24
|
-
@ss = StringScanner.new(input
|
27
|
+
@ss = StringScanner.new(input)
|
25
28
|
end
|
26
29
|
|
27
30
|
def tokenize
|
28
31
|
@output = []
|
29
32
|
|
30
33
|
until @ss.eos?
|
31
|
-
@ss.skip(
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
34
|
+
@ss.skip(WHITESPACE_OR_NOTHING)
|
35
|
+
break if @ss.eos?
|
36
|
+
tok = if (t = @ss.scan(COMPARISON_OPERATOR))
|
37
|
+
[:comparison, t]
|
38
|
+
elsif (t = @ss.scan(SINGLE_STRING_LITERAL))
|
39
|
+
[:string, t]
|
40
|
+
elsif (t = @ss.scan(DOUBLE_STRING_LITERAL))
|
41
|
+
[:string, t]
|
42
|
+
elsif (t = @ss.scan(NUMBER_LITERAL))
|
43
|
+
[:number, t]
|
44
|
+
elsif (t = @ss.scan(IDENTIFIER))
|
45
|
+
[:id, t]
|
46
|
+
elsif (t = @ss.scan(DOTDOT))
|
47
|
+
[:dotdot, t]
|
39
48
|
else
|
40
|
-
c
|
41
|
-
if s = SPECIALS[c]
|
49
|
+
c = @ss.getch
|
50
|
+
if (s = SPECIALS[c])
|
42
51
|
[s, c]
|
43
52
|
else
|
44
53
|
raise SyntaxError, "Unexpected character #{c}"
|
data/lib/liquid/locales/en.yml
CHANGED
@@ -14,13 +14,15 @@
|
|
14
14
|
if: "Syntax Error in tag 'if' - Valid syntax: if [expression]"
|
15
15
|
include: "Error in tag 'include' - Valid syntax: include '[template]' (with|for) [object|collection]"
|
16
16
|
unknown_tag: "Unknown tag '%{tag}'"
|
17
|
-
invalid_delimiter: "'
|
17
|
+
invalid_delimiter: "'%{tag}' is not a valid delimiter for %{block_name} tags. use %{block_delimiter}"
|
18
18
|
unexpected_else: "%{block_name} tag does not expect 'else' tag"
|
19
19
|
unexpected_outer_tag: "Unexpected outer '%{tag}' tag"
|
20
20
|
tag_termination: "Tag '%{token}' was not properly terminated with regexp: %{tag_end}"
|
21
21
|
variable_termination: "Variable '%{token}' was not properly terminated with regexp: %{tag_end}"
|
22
22
|
tag_never_closed: "'%{block_name}' tag was never closed"
|
23
|
-
meta_syntax_error: "Liquid syntax error: #{e.message}"
|
24
23
|
table_row: "Syntax Error in 'table_row loop' - Valid syntax: table_row [item] in [collection] cols=3"
|
24
|
+
render: "Syntax error in tag 'render' - Template name must be a quoted string"
|
25
25
|
argument:
|
26
26
|
include: "Argument error in tag 'include' - Illegal template name"
|
27
|
+
disabled:
|
28
|
+
tag: "usage is not allowed in this context"
|