mirror of
https://github.com/Shopify/liquid.git
synced 2026-09-12 23:40:45 -07:00
Optimize block parsing -- don't recreate delimiter, use strings instead of regex
This commit is contained in:
+37
-36
@@ -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,41 +23,41 @@ module Liquid
|
|||||||
@children = []
|
@children = []
|
||||||
|
|
||||||
while token = tokens.shift
|
while token = tokens.shift
|
||||||
case token
|
unless token.empty?
|
||||||
when IsTag
|
case
|
||||||
if token =~ FullToken
|
when token.start_with?(TAGSTART)
|
||||||
|
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
|
||||||
|
|
||||||
# fetch the tag from registered blocks
|
# fetch the tag from registered blocks
|
||||||
if tag = Template.tags[$1]
|
if tag = Template.tags[$1]
|
||||||
new_tag = tag.parse($1, $2, tokens, @options)
|
new_tag = tag.parse($1, $2, tokens, @options)
|
||||||
@blank &&= new_tag.blank?
|
@blank &&= new_tag.blank?
|
||||||
@nodelist << new_tag
|
@nodelist << new_tag
|
||||||
@children << new_tag
|
@children << new_tag
|
||||||
|
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
|
else
|
||||||
# this tag is not registered with the system
|
raise SyntaxError.new(options[:locale].t("errors.syntax.tag_termination".freeze, :token => token, :tag_end => TagEnd.inspect))
|
||||||
# pass it to the current block for special handling or error reporting
|
|
||||||
unknown_tag($1, $2, tokens)
|
|
||||||
end
|
end
|
||||||
|
when token.start_with?(VARSTART)
|
||||||
|
new_var = create_variable(token)
|
||||||
|
@nodelist << new_var
|
||||||
|
@children << new_var
|
||||||
|
@blank = false
|
||||||
else
|
else
|
||||||
raise SyntaxError.new(options[:locale].t("errors.syntax.tag_termination".freeze, :token => token, :tag_end => TagEnd.inspect))
|
@nodelist << token
|
||||||
|
@blank &&= (token =~ /\A\s*\z/)
|
||||||
end
|
end
|
||||||
when IsVariable
|
|
||||||
new_var = create_variable(token)
|
|
||||||
@nodelist << new_var
|
|
||||||
@children << new_var
|
|
||||||
@blank = false
|
|
||||||
when ''.freeze
|
|
||||||
# pass
|
|
||||||
else
|
|
||||||
@nodelist << token
|
|
||||||
@blank &&= (token =~ /\A\s*\z/)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user