class Temple::Generator

_buf << foo.downcase
foo = “More content”
_buf << “Some content”
# is the same as:
[:dynamic, “foo.downcase”]]
[:capture, “foo”, [:static, “More content”]],
[:static, “Some content”],
[:multi,
Example:
result, it sets the content to the variable given.
Evaluates the Sexp using the rules above, but instead of appending to the
=== [:capture, variable_name, sexp]
Newline causes a newline in the generated code, but not in the result.
=== [:newline]
change the control flow. Any n causes a newline in the generated code.
Block indicates that the given Ruby code should be evaluated, and may
=== [:block, ruby]
it to eval() and it would not raise SyntaxError.
The Ruby code must be a complete expression in the sense that you can pass
appended to the result.
Dynamic indicates that the given Ruby code should be evaluated and then
=== [:dynamic, ruby]
_buf << “HellonWorld”
# is the same as
[:static, “Hello n World”]
_buf << “Hello World”
# is the same as:
[:static, “Hello World”]
Example:
Static indicates that the given string should be appended to the result.
=== [:static, string]
[:dynamic, “@world”]]
[:static, “Hello ”],
[:multi,
several others sexps:
Multi is what glues everything together. It’s simply a sexp which combines
=== [:multi, *sexp]
of view) spits out. It’s what happens if you evaluate the generated code.
Then there’s the result. This is what your engine (from the user’s point
make exceptions report correct line numbers, which is very convenient.
point of view) spits out. If you construct this carefully enough, you can
First we have the generated code. This is what your engine (from Temple’s
When compiling, there’s two different strings we’ll have to think about.
multi, static, dynamic, block, newline and capture.
to. Currently it consists of four essential and two convenient types:
The core abstraction is what every template evetually should be compiled
== The Core Abstraction

def buffer

def buffer
  options[:buffer]
end

def call(exp)

def call(exp)
  [preamble, compile(exp), postamble].join(' ; ')
end

def compile(exp)

def compile(exp)
  type, *args = exp
  if respond_to?("on_#{type}")
    send("on_#{type}", *args)
  else
    raise "Generator supports only core expressions - found #{exp.inspect}"
  end
end

def concat(str)

def concat(str)
  "#{buffer} << (#{str})"
end

def on_capture(name, block)

def on_capture(name, block)
  options[:capture_generator].new(:buffer => name).call(block)
end

def on_multi(*exp)

def on_multi(*exp)
  exp.map { |e| compile(e) }.join(' ; ')
end

def on_newline

def on_newline
  "\n"
end