1
0
Fork 0
mirror of https://github.com/haml/haml.git synced 2022-11-09 12:33:31 -05:00
haml--haml/lib/hamlit/compiler/children_compiler.rb

112 lines
2.7 KiB
Ruby
Raw Normal View History

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_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
2015-11-21 05:09:31 -05:00
when :script, :silent_script
2015-10-25 04:08:34 -04:00
@lineno += 1
2015-11-21 06:24:51 -05:00
when :filter
@lineno += (node.value[:text] || '').split("\n").size
2015-10-25 04:08:34 -04:00
when :tag
node.value[:attributes_hashes].each do |attribute_hash|
@lineno += attribute_hash.count("\n")
end
2015-11-22 09:10:20 -05:00
@lineno += 1 if node.children.empty? && node.value[:parse]
2015-10-25 04:08:34 -04:00
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]
2015-10-25 10:20:28 -04:00
when node.parent.nil?
false
else
nuke_inner_whitespace?(node.parent)
end
2015-10-24 10:39:34 -04:00
end
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