2015-10-06 23:14:45 +09:00
|
|
|
require 'temple'
|
|
|
|
require 'hamlit/compiler'
|
|
|
|
require 'hamlit/parser'
|
|
|
|
|
|
|
|
module Hamlit
|
|
|
|
class Engine < Temple::Engine
|
|
|
|
define_options(
|
|
|
|
generator: Temple::Generators::ArrayBuffer,
|
|
|
|
format: :html,
|
2015-10-11 21:26:51 +09:00
|
|
|
html_type: nil,
|
2015-10-06 23:14:45 +09:00
|
|
|
attr_quote: "'",
|
|
|
|
escape_html: true,
|
|
|
|
pretty: false,
|
2015-10-11 21:50:46 +09:00
|
|
|
autoclose: %w(area base basefont br col command embed frame
|
|
|
|
hr img input isindex keygen link menuitem meta
|
|
|
|
param source track wbr),
|
2015-10-13 20:45:07 +09:00
|
|
|
filename: "",
|
2015-10-13 23:10:17 +09:00
|
|
|
indent_tags: [],
|
2015-10-06 23:14:45 +09:00
|
|
|
)
|
|
|
|
|
|
|
|
use Parser
|
|
|
|
use Compiler
|
|
|
|
html :Pretty
|
|
|
|
filter :Escapable
|
|
|
|
filter :ControlFlow
|
|
|
|
filter :MultiFlattener
|
|
|
|
filter :StaticMerger
|
|
|
|
use :Generator, -> { options[:generator] }
|
|
|
|
end
|
2015-10-07 00:18:41 +09:00
|
|
|
|
|
|
|
class HamlEngine
|
|
|
|
def initialize(template, options = {})
|
|
|
|
@template = template
|
|
|
|
@options = options
|
|
|
|
end
|
|
|
|
|
2015-10-11 17:58:11 +09:00
|
|
|
def precompiled
|
2015-10-11 21:08:57 +09:00
|
|
|
Engine.new(temple_options).call(@template)
|
2015-10-11 17:58:11 +09:00
|
|
|
end
|
|
|
|
|
2015-10-07 00:18:41 +09:00
|
|
|
def render(scope = Object.new, locals = {}, &block)
|
2015-10-11 15:31:13 +09:00
|
|
|
scope = wrap_binding(scope)
|
|
|
|
set_locals(locals, scope)
|
2015-10-11 17:58:11 +09:00
|
|
|
eval(precompiled, scope)
|
2015-10-11 15:31:13 +09:00
|
|
|
end
|
2015-10-13 20:45:07 +09:00
|
|
|
alias_method :to_html, :render
|
2015-10-11 15:31:13 +09:00
|
|
|
|
|
|
|
private
|
|
|
|
|
2015-10-11 21:08:57 +09:00
|
|
|
def temple_options
|
|
|
|
@options.dup.tap do |options|
|
|
|
|
options[:pretty] = !options.delete(:ugly)
|
2015-10-11 21:26:51 +09:00
|
|
|
case options[:format]
|
|
|
|
when :html5
|
|
|
|
options[:format] = :html
|
|
|
|
when :html4
|
|
|
|
options[:format] = :html
|
|
|
|
options[:html_type] = 'transitional'
|
|
|
|
end
|
2015-10-11 21:08:57 +09:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2015-10-11 15:31:13 +09:00
|
|
|
def wrap_binding(scope)
|
|
|
|
return scope if scope.is_a?(Binding)
|
|
|
|
scope.instance_eval { binding }
|
|
|
|
end
|
|
|
|
|
|
|
|
def set_locals(locals, scope)
|
|
|
|
set_locals = locals.map { |k, v| "#{k} = #{v.inspect}" }.join("\n")
|
|
|
|
eval(set_locals, scope)
|
2015-10-07 00:18:41 +09:00
|
|
|
end
|
|
|
|
end
|
2015-10-06 23:14:45 +09:00
|
|
|
end
|