class Mustache::Template

def self.recursor(toks, section, &block)

Simple recursive iterator for tokens
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)

interpolation-friendly Ruby string.
Does the dirty work of transforming a Mustache template into an
def compile(src = @source)
  Generator.new.compile(tokens(src))
end

def initialize(source)

path, which it uses to find partials.
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

Partials that belong to sections are included, but the section name is not preserved
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)

directly.
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

Sections that belong to other sections will be of the form `section1.childsection`
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

Tags that belong to sections will be of the form `section1.tag`
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)

Returns an array of tokens for a given template.
def tokens(src = @source)
  Parser.new.compile(src)
end