Class: Inverso::Template

Inherits:
Object
  • Object
show all
Defined in:
lib/lydown/inverso.rb

Constant Summary collapse

EMIT_DELIMITER =
'`'.freeze
EMIT_RE =
/#{EMIT_DELIMITER}(((?!#{EMIT_DELIMITER}).)*)#{EMIT_DELIMITER}/m
INTERPOLATION_START =
"{{".freeze
INTERPOLATION_END =
"}}".freeze
INTERPOLATION_RE =
/#{INTERPOLATION_START}([^\?\/](?:(?!#{INTERPOLATION_END}).)*)#{INTERPOLATION_END}/m
IF_START =
"{{?".freeze
IF_END =
"{{/}}".freeze
IF_RE =
/\{\{\?((?:(?!#{INTERPOLATION_END}).)*)#{INTERPOLATION_END}((?:(?!#{IF_END}).)*)#{IF_END}/m
ESCAPED_QUOTE =
'\\"'.freeze
QUOTE =
'"'.freeze
@@templates =

Global template registry

{}

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(templ) ⇒ Template

Returns a new instance of Template.



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/lydown/inverso.rb', line 20

def initialize(templ)
  templ = templ.gsub(EMIT_RE) {|m| convert_literal($1)}
  method_str = <<EOF
  define_method(:render) do |_ = {}, env = {}|
    _.each {|k, v| metaclass.instance_eval {define_method(k) {v}}}
    __buffer__ = env[:buffer] ||= ''
    __emit__ = env[:emit] ||= lambda {|*args| args.each {|s| __buffer__ << s}}
    __render_l__ = env[:render] ||= lambda {|n, o| Template.render(n, o, env)}
    metaclass.instance_eval "define_method(:__render__) {|n, o| __render_l__[n, o]}"
    begin
      #{templ}
    end
    __buffer__.gsub(/^\s+$/, '').gsub(/\n+/m, "\n")
  end
EOF

  metaclass.instance_eval method_str
end

Class Method Details

.load_templates(path) ⇒ Object



65
66
67
68
69
70
71
# File 'lib/lydown/inverso.rb', line 65

def self.load_templates(path)
  Dir["#{path}/*.rb"].each do |fn|
    File.basename(fn) =~ /^(.+)\.rb$/
    name = $1
    set(name, IO.read(fn))
  end
end

.render(name, arg = {}, env = {}) ⇒ Object



77
78
79
80
# File 'lib/lydown/inverso.rb', line 77

def self.render(name, arg = {}, env = {})
  raise unless @@templates[name.to_sym]
  @@templates[name.to_sym].render(arg, env)
end

.set(name, templ) ⇒ Object



73
74
75
# File 'lib/lydown/inverso.rb', line 73

def self.set(name, templ)
  @@templates[name.to_sym] = new(templ)
end

Instance Method Details

#convert_interpolation(s) ⇒ Object



39
40
41
42
43
44
# File 'lib/lydown/inverso.rb', line 39

def convert_interpolation(s)
  s.gsub(INTERPOLATION_RE) do
    code = $1.gsub(ESCAPED_QUOTE, QUOTE)
    "\#{#{code}}"
  end
end

#convert_literal(s) ⇒ Object



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/lydown/inverso.rb', line 46

def convert_literal(s)
  # look for interpolated values, wrap them with #{}
  s = s.inspect.gsub(INTERPOLATION_RE) do
    code = $1.gsub(ESCAPED_QUOTE, QUOTE)
    "\#{#{code}}"
  end

  s = s.gsub(IF_RE) do
    test, code = $1, $2
    test = test.strip.gsub(ESCAPED_QUOTE, QUOTE)
    "\#\{if #{test}; \"#{code}\"; end}"
  end

  "__emit__[#{s}]"
end

#metaclassObject

From the metaid gem



18
# File 'lib/lydown/inverso.rb', line 18

def metaclass; class << self; self; end; end