Optimize block parsing -- don't recreate delimiter, use strings instead of regex

This commit is contained in:
Jason Hiltz-Laforge
2014-07-22 02:43:20 +00:00
parent 0e56cf99ab
commit 3c2de7737d
2 changed files with 38 additions and 37 deletions
+14 -13
View File
@@ -1,9 +1,14 @@
module Liquid module Liquid
class Block < Tag class Block < Tag
IsTag = /\A#{TagStart}/o
IsVariable = /\A#{VariableStart}/o
FullToken = /\A#{TagStart}\s*(\w+)\s*(.*)?#{TagEnd}\z/om FullToken = /\A#{TagStart}\s*(\w+)\s*(.*)?#{TagEnd}\z/om
ContentOfVariable = /\A#{VariableStart}(.*)#{VariableEnd}\z/om ContentOfVariable = /\A#{VariableStart}(.*)#{VariableEnd}\z/om
TAGSTART = "{%".freeze
VARSTART = "{{".freeze
def initialize(tag_name, markup, options)
super
@block_delimiter = "end#{tag_name}"
end
def blank? def blank?
@blank || false @blank || false
@@ -18,13 +23,14 @@ module Liquid
@children = [] @children = []
while token = tokens.shift while token = tokens.shift
case token unless token.empty?
when IsTag case
when token.start_with?(TAGSTART)
if token =~ FullToken if token =~ FullToken
# if we found the proper block delimiter just end parsing here and let the outer block # if we found the proper block delimiter just end parsing here and let the outer block
# proceed # proceed
if block_delimiter == $1 if @block_delimiter == $1
end_tag end_tag
return return
end end
@@ -43,18 +49,17 @@ module Liquid
else else
raise SyntaxError.new(options[:locale].t("errors.syntax.tag_termination".freeze, :token => token, :tag_end => TagEnd.inspect)) raise SyntaxError.new(options[:locale].t("errors.syntax.tag_termination".freeze, :token => token, :tag_end => TagEnd.inspect))
end end
when IsVariable when token.start_with?(VARSTART)
new_var = create_variable(token) new_var = create_variable(token)
@nodelist << new_var @nodelist << new_var
@children << new_var @children << new_var
@blank = false @blank = false
when ''.freeze
# pass
else else
@nodelist << token @nodelist << token
@blank &&= (token =~ /\A\s*\z/) @blank &&= (token =~ /\A\s*\z/)
end end
end end
end
# Make sure that it's ok to end parsing in the current block. # Make sure that it's ok to end parsing in the current block.
# Effectively this method will throw an exception unless the current block is # Effectively this method will throw an exception unless the current block is
@@ -85,16 +90,12 @@ module Liquid
when 'end'.freeze when 'end'.freeze
raise SyntaxError.new(options[:locale].t("errors.syntax.invalid_delimiter".freeze, raise SyntaxError.new(options[:locale].t("errors.syntax.invalid_delimiter".freeze,
:block_name => block_name, :block_name => block_name,
:block_delimiter => block_delimiter)) :block_delimiter => @block_delimiter))
else else
raise SyntaxError.new(options[:locale].t("errors.syntax.unknown_tag".freeze, :tag => tag)) raise SyntaxError.new(options[:locale].t("errors.syntax.unknown_tag".freeze, :tag => tag))
end end
end end
def block_delimiter
"end#{block_name}"
end
def block_name def block_name
@tag_name @tag_name
end end
+1 -1
View File
@@ -8,7 +8,7 @@ module Liquid
while token = tokens.shift while token = tokens.shift
if token =~ FullTokenPossiblyInvalid if token =~ FullTokenPossiblyInvalid
@nodelist << $1 if $1 != "".freeze @nodelist << $1 if $1 != "".freeze
if block_delimiter == $2 if @block_delimiter == $2
end_tag end_tag
return return
end end