Fixed ranges and added for loop parser

This commit is contained in:
Tristan Hume 2013-07-29 14:11:47 -04:00
parent 525e1ff195
commit 8ca00982b6
3 changed files with 50 additions and 22 deletions

View File

@ -7,7 +7,9 @@ module Liquid
':' => :colon,
',' => :comma,
'[' => :open_square,
']' => :close_square
']' => :close_square,
'(' => :open_round,
')' => :close_round
}
IDENTIFIER = /[\w\-?!]+/
SINGLE_STRING_LITERAL = /'[^\']*'/

View File

@ -50,21 +50,22 @@ module Liquid
def expression
token = @tokens[@p]
str = if token[0] == :id
if token[0] == :id
variable_signature
elsif [:string, :number].include? token[0]
consume
token[1]
elsif token.first == :open_round
consume
first = expression
consume(:dot)
consume(:dot)
last = expression
consume(:close_round)
"(#{first}..#{last})"
else
raise SyntaxError, "#{token} is not a valid expression."
end
if look(:dot) && look(:dot, 1)
@p += 2
str + expression
else
str
end
end
def argument

View File

@ -47,19 +47,7 @@ module Liquid
Syntax = /\A(#{VariableSegment}+)\s+in\s+(#{QuotedFragment}+)\s*(reversed)?/o
def initialize(tag_name, markup, tokens)
if markup =~ Syntax
@variable_name = $1
@collection_name = $2
@name = "#{$1}-#{$2}"
@reversed = $3
@attributes = {}
markup.scan(TagAttributes) do |key, value|
@attributes[key] = value
end
else
raise SyntaxError.new("Syntax Error in 'for loop' - Valid syntax: for [item] in [collection]")
end
switch_parse(markup)
@nodelist = @for_block = []
super
end
@ -127,6 +115,43 @@ module Liquid
result
end
protected
def lax_parse(markup)
if markup =~ Syntax
@variable_name = $1
@collection_name = $2
@name = "#{$1}-#{$2}"
@reversed = $3
@attributes = {}
markup.scan(TagAttributes) do |key, value|
@attributes[key] = value
end
else
raise SyntaxError.new("Syntax Error in 'for loop' - Valid syntax: for [item] in [collection]")
end
end
def strict_parse(markup)
p = Parser.new(markup)
@variable_name = p.consume(:id)
raise SyntaxError, "For loops require an 'in' clause" unless p.id?('in')
@collection_name = p.expression
@name = "#{@variable_name}-#{@collection_name}"
@reversed = p.id?('reversed')
@attributes = {}
while p.look(:id) && p.look(:colon, 1)
unless attribute = p.id?('limit') || p.id?('offset')
raise SyntaxError, "Invalid attribute in for loop. Valid attributes are limit and offset"
end
p.consume
val = p.expression
@attributes[attribute] = val
end
p.consume(:end_of_string)
end
private
def render_else(context)