2015-10-24 10:39:34 -04:00
|
|
|
module Hamlit
|
|
|
|
class Compiler
|
|
|
|
class ChildrenCompiler
|
2015-10-24 14:08:09 -04:00
|
|
|
def initialize
|
|
|
|
@lineno = 1
|
|
|
|
end
|
|
|
|
|
2015-10-24 10:39:34 -04:00
|
|
|
def compile(node, &block)
|
|
|
|
temple = [:multi]
|
|
|
|
return temple if node.children.empty?
|
|
|
|
|
|
|
|
temple << :whitespace if prepend_whitespace?(node)
|
|
|
|
node.children.each do |n|
|
|
|
|
rstrip_whitespace!(temple) if nuke_outer_whitespace?(n)
|
2015-10-24 14:08:09 -04:00
|
|
|
insert_newlines!(temple, n)
|
2015-10-24 10:39:34 -04:00
|
|
|
temple << yield(n)
|
|
|
|
temple << :whitespace if insert_whitespace?(n)
|
|
|
|
end
|
|
|
|
rstrip_whitespace!(temple) if nuke_inner_whitespace?(node)
|
|
|
|
confirm_whitespace(temple)
|
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
|
2015-10-24 14:08:09 -04:00
|
|
|
def insert_newlines!(temple, node)
|
2015-10-25 02:35:09 -04:00
|
|
|
(node.line - @lineno).times do
|
2015-10-24 14:08:09 -04:00
|
|
|
temple << [:newline]
|
|
|
|
end
|
|
|
|
@lineno = node.line
|
2015-10-25 02:35:09 -04:00
|
|
|
@lineno += 1 if newline_inserted_by_compiler?(node)
|
2015-10-24 14:08:09 -04:00
|
|
|
end
|
|
|
|
|
2015-10-25 01:50:24 -04:00
|
|
|
def newline_inserted_by_compiler?(node)
|
2015-10-25 02:35:09 -04:00
|
|
|
node.type == :script
|
2015-10-25 01:50:24 -04:00
|
|
|
end
|
|
|
|
|
2015-10-24 10:39:34 -04:00
|
|
|
def confirm_whitespace(temple)
|
|
|
|
temple.map do |exp|
|
|
|
|
case exp
|
|
|
|
when :whitespace
|
|
|
|
[:static, "\n"]
|
|
|
|
else
|
|
|
|
exp
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def prepend_whitespace?(node)
|
|
|
|
return false unless %i[comment tag].include?(node.type)
|
|
|
|
!nuke_inner_whitespace?(node)
|
|
|
|
end
|
|
|
|
|
|
|
|
def nuke_inner_whitespace?(node)
|
|
|
|
return false if node.type != :tag
|
|
|
|
node.value[:nuke_inner_whitespace]
|
|
|
|
end
|
|
|
|
|
|
|
|
def nuke_outer_whitespace?(node)
|
|
|
|
return false if node.type != :tag
|
|
|
|
node.value[:nuke_outer_whitespace]
|
|
|
|
end
|
|
|
|
|
|
|
|
def rstrip_whitespace!(temple)
|
|
|
|
if temple[-1] == :whitespace
|
|
|
|
temple.delete_at(-1)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def insert_whitespace?(node)
|
|
|
|
return false if nuke_outer_whitespace?(node)
|
|
|
|
|
|
|
|
case node.type
|
|
|
|
when :doctype
|
|
|
|
node.value[:type] != 'xml'
|
2015-10-25 01:50:24 -04:00
|
|
|
when :comment, :filter, :plain, :tag
|
2015-10-24 10:39:34 -04:00
|
|
|
true
|
2015-10-25 01:50:24 -04:00
|
|
|
when :script
|
|
|
|
node.children.empty?
|
2015-10-24 10:39:34 -04:00
|
|
|
else
|
|
|
|
false
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|