2006-06-30 11:14:44 -04:00
|
|
|
module HAML
|
|
|
|
|
|
|
|
class TemplateEngine
|
|
|
|
|
|
|
|
def initialize(base)
|
|
|
|
@base = base
|
|
|
|
@tab_index = ["", " "]
|
|
|
|
#pre-build the tab index up to 9
|
|
|
|
10.times do |num|
|
|
|
|
@tab_index << @tab_index.last + " "
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def render(template = "", locals = {})
|
2006-06-30 17:40:07 -04:00
|
|
|
puts @base.inspect
|
|
|
|
|
|
|
|
|
2006-06-30 11:14:44 -04:00
|
|
|
@pony_land = HappyMagicPonyLand.new(@base, locals)
|
|
|
|
@result = ""
|
|
|
|
@to_close_queue = []
|
|
|
|
|
|
|
|
#main loop handling line reading
|
|
|
|
#and interpretation
|
|
|
|
template.each_line do |line|
|
|
|
|
count, line = count_levels(line)
|
2006-06-30 17:40:07 -04:00
|
|
|
if count < @to_close_queue.size
|
2006-06-30 11:14:44 -04:00
|
|
|
close_tag
|
|
|
|
end
|
|
|
|
case line.first
|
|
|
|
when '.', '#'
|
|
|
|
render_div(line)
|
2006-06-30 17:40:07 -04:00
|
|
|
when '%'
|
|
|
|
render_tag(line)
|
2006-06-30 11:14:44 -04:00
|
|
|
when '/'
|
|
|
|
render_comment(line)
|
|
|
|
when '='
|
|
|
|
add template_eval(line[1, line.length])
|
|
|
|
else
|
2006-06-30 17:40:07 -04:00
|
|
|
add_single line
|
2006-06-30 11:14:44 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
@to_close_queue.each { close_tag }
|
|
|
|
@result
|
|
|
|
end
|
2006-06-30 17:40:07 -04:00
|
|
|
|
2006-06-30 11:14:44 -04:00
|
|
|
def add(line)
|
2006-06-30 17:40:07 -04:00
|
|
|
return nil if line.nil?
|
|
|
|
if (list = line.to_a).size > 1
|
|
|
|
list.each { |me| add(me) }
|
|
|
|
else
|
|
|
|
#bleh, stupid line to make sure a \n isn't on the end... dumb.
|
|
|
|
add_single(line)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def add_single(line)
|
2006-06-30 11:14:44 -04:00
|
|
|
@result << tabify(@to_close_queue.size) + line + "\n"
|
|
|
|
end
|
|
|
|
|
|
|
|
def tabify(times)
|
|
|
|
@tab_index[times]
|
|
|
|
end
|
|
|
|
|
|
|
|
def open_tag(name, attributes = {})
|
|
|
|
attribute_array = []
|
|
|
|
attributes.each do |attr_name, val|
|
|
|
|
attribute_array << attr_name.to_s + "='" + val + "'"
|
|
|
|
end
|
|
|
|
add "<#{name.to_s}#{attribute_array.empty? ? "" : " "}#{attribute_array.join(" ")}>"
|
|
|
|
@to_close_queue.push(name)
|
|
|
|
end
|
|
|
|
|
|
|
|
def close_tag
|
|
|
|
add "</#{@to_close_queue.pop}>"
|
|
|
|
end
|
|
|
|
|
|
|
|
def render_div(line)
|
|
|
|
open_tag("div", parse_attributes(line))
|
|
|
|
end
|
|
|
|
|
|
|
|
def render_comment(line)
|
|
|
|
add "<!-- #{line} -->"
|
|
|
|
end
|
|
|
|
|
2006-06-30 17:40:07 -04:00
|
|
|
def render_tag(line)
|
|
|
|
line.scan(/[%]([a-zA-Z]+)([a-zA-Z.\#]*)([=]?)([^\n]*)/).each do |tag_name, attributes, action, value|
|
|
|
|
#puts "tag = " + tag_name + " " + attributes + " " + action + " " + value
|
2006-06-30 11:14:44 -04:00
|
|
|
open_tag(tag_name, parse_attributes(attributes))
|
|
|
|
unless value.empty?
|
|
|
|
if(action == '=')
|
|
|
|
add(value)
|
|
|
|
else
|
|
|
|
add(template_eval(value))
|
|
|
|
end
|
|
|
|
close_tag
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def template_eval(code)
|
|
|
|
@pony_land.instance_eval(code) || ""
|
|
|
|
end
|
|
|
|
|
|
|
|
def parse_attributes(list)
|
|
|
|
attributes = {}
|
|
|
|
list.scan(/([#.])([-a-zA-Z_()]+)/).each do |type, property|
|
|
|
|
case type
|
|
|
|
when "."
|
|
|
|
attributes[:class] = property
|
|
|
|
when "#"
|
|
|
|
attributes[:id] = property
|
|
|
|
end
|
|
|
|
end
|
|
|
|
attributes
|
|
|
|
end
|
|
|
|
|
|
|
|
def count_levels(line)
|
|
|
|
[line.index(/[^ ]/), line.strip]
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
class HappyMagicPonyLand
|
|
|
|
|
|
|
|
def initialize(base, attributes = {})
|
|
|
|
@_action_view = base
|
|
|
|
@table = attributes
|
|
|
|
end
|
|
|
|
|
|
|
|
def method_missing(name, *args, &block)
|
|
|
|
name_as_string = name.to_s
|
|
|
|
if name_as_string.last == "="
|
|
|
|
@table[name_as_string.scan(/[^=]+/).first.to_sym] = args.first
|
|
|
|
elsif @table.has_key? name.to_sym
|
|
|
|
@table[name.to_sym]
|
|
|
|
elsif @_action_view.respond_to? name
|
|
|
|
@_action_view.send(name, *args, &block)
|
2006-06-30 17:40:07 -04:00
|
|
|
elsif @_action_view.respond_to? name.to_s[1, name.length].to_sym
|
2006-06-30 11:14:44 -04:00
|
|
|
else
|
|
|
|
nil
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|