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|
|
2015-10-25 10:01:17 -04:00
|
|
|
rstrip_whitespace!(temple) if nuke_prev_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 04:08:34 -04:00
|
|
|
case node.type
|
|
|
|
when :script
|
|
|
|
@lineno += 1
|
|
|
|
when :tag
|
|
|
|
node.value[:attributes_hashes].each do |attribute_hash|
|
|
|
|
@lineno += attribute_hash.count("\n")
|
|
|
|
end
|
|
|
|
else
|
|
|
|
end
|
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)
|
2015-10-25 10:20:28 -04:00
|
|
|
case
|
|
|
|
when node.type == :tag
|
|
|
|
node.value[:nuke_inner_whitespace] ||
|
|
|
|
(node.parent && nuke_inner_whitespace?(node.parent))
|
|
|
|
when node.parent.nil?
|
|
|
|
false
|
|
|
|
else
|
|
|
|
nuke_inner_whitespace?(node.parent)
|
|
|
|
end
|
2015-10-24 10:39:34 -04:00
|
|
|
end
|
|
|
|
|
2015-10-25 10:01:17 -04:00
|
|
|
def nuke_prev_whitespace?(node)
|
|
|
|
case node.type
|
|
|
|
when :tag
|
|
|
|
node.value[:nuke_outer_whitespace]
|
|
|
|
when :silent_script
|
|
|
|
!node.children.empty? && nuke_prev_whitespace?(node.children.first)
|
|
|
|
else
|
|
|
|
false
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2015-10-24 10:39:34 -04:00
|
|
|
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-26 10:04:02 -04:00
|
|
|
when :comment, :plain, :tag
|
2015-10-24 10:39:34 -04:00
|
|
|
true
|
2015-10-25 01:50:24 -04:00
|
|
|
when :script
|
2015-10-25 10:20:28 -04:00
|
|
|
node.children.empty? && !nuke_inner_whitespace?(node)
|
2015-10-26 10:04:02 -04:00
|
|
|
when :filter
|
2015-10-28 09:45:54 -04:00
|
|
|
!%w[ruby].freeze.include?(node.value[:name])
|
2015-10-24 10:39:34 -04:00
|
|
|
else
|
|
|
|
false
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|