orbit-basic/vendor/plugins/liquid/lib/liquid/block.rb

98 lines
2.5 KiB
Ruby

module Liquid
class Block < Tag
def parse(tokens)
@nodelist ||= []
@nodelist.clear
while token = tokens.shift
case token
when /^#{TagStart}/
if token =~ /^#{TagStart}\s*(\w+)\s*(.*)?#{TagEnd}$/
# if we found the proper block delimitor just end parsing here and let the outer block
# proceed
if block_delimiter == $1
end_tag
return
end
# fetch the tag from registered blocks
if tag = Template.tags[$1]
@nodelist << tag.new($1, $2, tokens)
else
# this tag is not registered with the system
# pass it to the current block for special handling or error reporting
unknown_tag($1, $2, tokens)
end
else
raise SyntaxError, "Tag '#{token}' was not properly terminated with regexp: #{TagEnd.inspect} "
end
when /^#{VariableStart}/
@nodelist << create_variable(token)
when ''
# pass
else
@nodelist << token
end
end
# Make sure that its ok to end parsing in the current block.
# Effectively this method will throw and exception unless the current block is
# of type Document
assert_missing_delimitation!
end
def end_tag
end
def unknown_tag(tag, params, tokens)
case tag
when 'else'
raise SyntaxError, "#{block_name} tag does not expect else tag"
when 'end'
raise SyntaxError, "'end' is not a valid delimiter for #{block_name} tags. use #{block_delimiter}"
else
raise SyntaxError, "Unknown tag '#{tag}'"
end
end
def block_delimiter
"end#{block_name}"
end
def block_name
@tag_name
end
def create_variable(token)
token.scan(/^#{VariableStart}(.*)#{VariableEnd}$/) do |content|
return Variable.new(content.first)
end
raise SyntaxError.new("Variable '#{token}' was not properly terminated with regexp: #{VariableEnd.inspect} ")
end
def render(context)
render_all(@nodelist, context)
end
protected
def assert_missing_delimitation!
raise SyntaxError.new("#{block_name} tag was never closed")
end
def render_all(list, context)
list.collect do |token|
begin
token.respond_to?(:render) ? token.render(context) : token
rescue Exception => e
context.handle_error(e)
end
end
end
end
end