class Mustache::Template
def self.recursor(toks, section, &block)
def self.recursor(toks, section, &block) toks.map do |token| next unless token.is_a? Array if token[0] == :mustache new_token, new_section, result, stop = yield(token, section) [ result ] + ( stop ? [] : recursor(new_token, new_section, &block)) else recursor(token, section, &block) end end end
def compile(src = @source)
Does the dirty work of transforming a Mustache template into an
def compile(src = @source) Generator.new.compile(tokens(src)) end
def initialize(source)
Expects a Mustache template as a string along with a template
def initialize(source) @source = source end
def partial_names
def partial_names def recursor(toks) partials = [] toks.each do |token| next unless token.is_a? Array partials += if token[0..1] == [:mustache, :partial] [token[2]] # partial here else recursor(token) end end partials end recursor(tokens).reject(&:nil?).uniq end
def partials
Returns an array of partials
def partials Template.recursor(tokens, []) do |token, section| if token[1] == :partial [ new_token=token, new_section=section, result=token[2], stop=true ] else [ new_token=token, new_section=section, result=nil, stop=false ] end end.flatten.reject(&:nil?).uniq end
def recursor(toks, section)
def recursor(toks, section) toks.map do |token| next unless token.is_a? Array if token[0] == :mustache && [:etag,:utag].include? token[1] (section + [token[2][2][0]]).join '.' elsif token[0] == :mustache && [:section,:inverted_section].include? token[1] recursor(token[4], section + [token[2][2][0]]) else recursor(token, section) end end end
def recursor(toks, section)
def recursor(toks, section) sections = [] toks.each do |token| next unless token.is_a? Array if token[0] == :mustache && [:section,:inverted_section].include? token[1] new_section = section + [token[2][2][0]] sections += [ new_section.join('.') ] + recursor(token[4], new_section) else sections += recursor(token, section) end end sections end
def recursor(toks)
def recursor(toks) partials = [] toks.each do |token| next unless token.is_a? Array partials += if token[0..1] == [:mustache, :partial] [token[2]] # partial here else recursor(token) end end partials end
def render(context)
the compilation step and run the Ruby version of the template
and from then on it is "compiled". Subsequent calls will skip
The first time a template is rendered, this method is overriden
`context`, which should be a simple hash keyed with symbols.
Renders the `@source` Mustache template using the given
def render(context) # Compile our Mustache template into a Ruby string compiled = "def render(ctx) #{compile} end" # Here we rewrite ourself with the interpolated Ruby version of # our Mustache template so subsequent calls are very fast and # can skip the compilation stage. instance_eval(compiled, __FILE__, __LINE__ - 1) # Call the newly rewritten version of #render render(context) end
def section_names
def section_names def recursor(toks, section) sections = [] toks.each do |token| next unless token.is_a? Array if token[0] == :mustache && [:section,:inverted_section].include? token[1] new_section = section + [token[2][2][0]] sections += [ new_section.join('.') ] + recursor(token[4], new_section) else sections += recursor(token, section) end end sections end recursor(tokens,[]).reject(&:nil?).uniq end
def sections
Returns an array of sections
def sections Template.recursor(tokens, []) do |token, section| if [:section, :inverted_section].include?(token[1]) new_section=(section + [token[2][2][0]]) [ new_token=token[4], new_section, result=new_section.join('.'), stop=false ] else [ new_token=token, new_section=section, result=nil, stop=false ] end end.flatten.reject(&:nil?).uniq end
def tags
Returns an array of tags
def tags Template.recursor(tokens, []) do |token, section| if [:etag, :utag].include?(token[1]) [ new_token=nil, new_section=nil, result=((section + [token[2][2][0]]).join('.')), stop=true ] elsif [:section, :inverted_section].include?(token[1]) [ new_token=token[4], new_section=(section + [token[2][2][0]]), result=nil, stop=false ] else [ new_token=token, new_section=section, result=nil, stop=false ] end end.flatten.reject(&:nil?).uniq end
def token_names
def token_names def recursor(toks, section) toks.map do |token| next unless token.is_a? Array if token[0] == :mustache && [:etag,:utag].include? token[1] (section + [token[2][2][0]]).join '.' elsif token[0] == :mustache && [:section,:inverted_section].include? token[1] recursor(token[4], section + [token[2][2][0]]) else recursor(token, section) end end end recursor(tokens, []).flatten.reject(&:nil?).uniq end
def tokens(src = @source)
def tokens(src = @source) Parser.new.compile(src) end