Class: ActionView::Mustache::Generator

Inherits:
Object
  • Object
show all
Defined in:
lib/action_view/mustache/generator.rb

Overview

Public: Compiles tokens from Mustache::Parser into evaluatable Ruby code.

The code generate targets Rails output buffer and must be evaluated inside an ActionView::Base instance.

See Mustache::Generator for more info.

Instance Method Summary collapse

Instance Method Details

#compile(exp) ⇒ Object

Public: Convert tokens to plain old Ruby.

exp - Array of tokens produced by Mustache::Parser

Returns String of compiled Ruby code.



20
21
22
23
24
25
26
# File 'lib/action_view/mustache/generator.rb', line 20

def compile(exp)
  src = ""
  src << "@output_buffer = output_buffer || ActionView::OutputBuffer.new; "
  src << compile!(exp)
  src << "@output_buffer.to_s;"
  src
end

#compile!(exp) ⇒ Object

Internal: Recursively compile token expression.

exp - Token Array structure

Returns String.



33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/action_view/mustache/generator.rb', line 33

def compile!(exp)
  case exp.first
  when :multi
    exp[1..-1].map { |e| compile!(e) }.join
  when :static
    text(exp[1])
  when :mustache
    send("on_#{exp[1]}", *exp[2..-1])
  else
    raise "Unhandled exp: #{exp.first}"
  end
end

#on_etag(name, offset) ⇒ Object

Internal: Compile escaped tag.

name - String name of tag

Returns String.



90
91
92
# File 'lib/action_view/mustache/generator.rb', line 90

def on_etag(name, offset)
  "v = #{compile!(name)}; ctx._eval_etag(@output_buffer, v); "
end

#on_fetch(names) ⇒ Object

Internal: Compile fetch lookup.

names - Array of names to fetch.

Returns String.



99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/action_view/mustache/generator.rb', line 99

def on_fetch(names)
  names = names.map { |n| n.to_sym }

  if names.length == 0
    "ctx[:to_s]"
  elsif names.length == 1
    "ctx[#{names.first.to_sym.inspect}]"
  else
    initial, *rest = names
    "#{rest.inspect}.inject(ctx[#{initial.inspect}]) { |v, k| v && ctx.find(v, k) }; "
  end
end

#on_inverted_section(name, offset, content, raw, delims) ⇒ Object

Internal: Compile inverted section.

name - String of section name content - Array of section content tokens

Returns String.



62
63
64
# File 'lib/action_view/mustache/generator.rb', line 62

def on_inverted_section(name, offset, content, raw, delims)
  "v = #{compile!(name)}; ctx._eval_inverted_section(@output_buffer, v) {\n#{compile!(content)}\n}; "
end

#on_partial(name, offset, indentation) ⇒ Object

Internal: Compile partial render call.

name - String of partial name indentation - String of indentation level

Returns String.



72
73
74
# File 'lib/action_view/mustache/generator.rb', line 72

def on_partial(name, offset, indentation)
  "@output_buffer.concat(render(:partial => #{name.inspect}));\n"
end

#on_section(name, offset, content, raw, delims) ⇒ Object

Internal: Compile section.

name - String of section name content - Array of section content tokens

Returns String.



52
53
54
# File 'lib/action_view/mustache/generator.rb', line 52

def on_section(name, offset, content, raw, delims)
  "v = #{compile!(name)}; ctx._eval_section(self, @output_buffer, v) {\n#{compile!(content)}\n}; "
end

#on_utag(name, offset) ⇒ Object

Internal: Compile unescaped tag.

name - String name of tag

Returns String.



81
82
83
# File 'lib/action_view/mustache/generator.rb', line 81

def on_utag(name, offset)
  "v = #{compile!(name)}; ctx._eval_utag(@output_buffer, v); "
end

#text(text) ⇒ Object

Internal: Compile static string.

text - String of text.

Returns String.



117
118
119
120
# File 'lib/action_view/mustache/generator.rb', line 117

def text(text)
  text = text.gsub(/['\\]/, '\\\\\&')
  "@output_buffer.safe_concat('#{text}'); "
end