Compare commits

...
2 Commits
Author SHA1 Message Date
Michael Go 9323a5f4ef passing tokenizer unit test 2024-10-24 19:57:02 -03:00
Ian Ker-Seymer b9ac58e31c WIPPPPP 2024-10-24 18:43:02 -04:00
+65 -15
View File
@@ -8,18 +8,22 @@ module Liquid
@source = source @source = source
@line_number = line_number || (line_numbers ? 1 : nil) @line_number = line_number || (line_numbers ? 1 : nil)
@for_liquid_tag = for_liquid_tag @for_liquid_tag = for_liquid_tag
@offset = 0 @offset = 0
@tokens = tokenize @state = :outside
@ss = StringScanner.new(source)
end end
def shift def shift
token = @tokens[@offset] return nil if @ss.eos?
return nil unless token
@offset += 1 token = take_new_next
if @line_number until @state == :outside || @ss.eos?
@line_number += @for_liquid_tag ? 1 : token.count("\n") token << if @state == :inside_variable || @state == :inside_tag
take_inside
else
take_rest
end
end end
token token
@@ -27,19 +31,65 @@ module Liquid
private private
def tokenize def take_rest
return [] if @source.empty? token = @ss.rest
@ss.terminate
@state = :outside
token
end
return @source.split("\n") if @for_liquid_tag def take_new_next
start_pos = @ss.pos
tokens = @source.split(TemplateParser) if (n = @ss.skip_until(VariableStart))
if n == 2
@state = :inside_variable
end_pos = @ss.pos
token = @source.byteslice(start_pos, end_pos - start_pos)
else
@ss.pos -= 2
token = @source.byteslice(start_pos, n - 2)
end
# removes the rogue empty element at the beginning of the array @line_number += @for_liquid_tag ? 1 : token.count("\n") if @line_number
if tokens[0]&.empty? token
@offset += 1 elsif (n = @ss.skip_until(TagStart))
if n == 2
@state = :inside_tag
end_pos = @ss.pos
token = @source.byteslice(start_pos, end_pos - start_pos)
else
@ss.pos -= 2
token = @source.byteslice(start_pos, n - 2)
end
@line_number += @for_liquid_tag ? 1 : token.count("\n") if @line_number
token
else
take_rest
end end
end
tokens def take_inside
start_pos = @ss.pos
if @state == :inside_variable
if (n = @ss.skip_until(VariableEnd))
@state = :outside
token = @source.byteslice(start_pos, n)
@line_number += @for_liquid_tag ? 1 : token.count("\n") if @line_number
token
end
elsif @state == :inside_tag
if (n = @ss.skip_until(TagEnd))
@state = :outside
token = @source.byteslice(start_pos, n)
@line_number += @for_liquid_tag ? 1 : token.count("\n") if @line_number
token
end
else
raise SyntaxError, "Unknown state: #{@state}"
end
end end
end end
end end