class Middleman::FileRenderer

def self.cache

def self.cache
  @_cache ||= ::Tilt::Cache.new
end

def initialize(app, path)

def initialize(app, path)
  @app = app
  @path = path.to_s
end

def options_for_ext(ext)

def options_for_ext(ext)
  # Read options for extension from config/Tilt or cache
  cache.fetch(:options_for_ext, ext) do
    options = {}
    # Find all the engines which handle this extension in tilt. Look for
    # config variables of that name and merge it
    extension_class = ::Middleman::Util.tilt_class(ext)
    ::Tilt.default_mapping.extensions_for(extension_class).each do |mapping_ext|
      engine_options = @app.config[mapping_ext.to_sym] || {}
      options.merge!(engine_options)
    end
    options
  end
end

def render(locs, opts, context, &block)

def render(locs, opts, context, &block)
  path = @path.dup
  # Detect the remdering engine from the extension
  extension = File.extname(path)
  engine = extension[1..-1].to_sym
  # Store last engine for later (could be inside nested renders)
  context.current_engine, engine_was = engine, context.current_engine
  # Save current buffer for later
  buf_was = context.save_buffer
  # Read from disk or cache the contents of the file
  body = if opts[:template_body]
    opts.delete(:template_body)
  else
    template_data_for_file
  end
  # Merge per-extension options from config
  extension = File.extname(path)
  options = {}.merge!(opts).merge!(options_for_ext(extension))
  options[:outvar] ||= '@_out_buf'
  options[:context] = context
  options.delete(:layout)
  # Overwrite with frontmatter options
  options = options.deep_merge(options[:renderer_options]) if options[:renderer_options]
  template_class = ::Middleman::Util.tilt_class(path)
  # Allow hooks to manipulate the template before render
  body = @app.callbacks_for(:before_render).reduce(body) do |sum, callback|
    callback.call(sum, path, locs, template_class) || sum
  end
  # Read compiled template from disk or cache
  template = ::Tilt.new(path, 1, options) { body.dup }
  # Render using Tilt
  content = template.render(context, locs, &block)
  # Allow hooks to manipulate the result after render
  content = @app.callbacks_for(:after_render).reduce(content) do |sum, callback|
    callback.call(sum, path, locs, template_class) || sum
  end
  output = ::ActiveSupport::SafeBuffer.new ''
  output.safe_concat content
  output
ensure
  # Reset stored buffer
  context.restore_buffer(buf_was)
  context.current_engine = engine_was
end

def template_data_for_file

def template_data_for_file
  file = @app.files.find(:source, @path)
  if @app.extensions[:front_matter] && (file && !file[:types].include?(:no_frontmatter))
    result = @app.extensions[:front_matter].template_data_for_file(@path)
    return result unless result.nil?
  end
  file ? file.read : ::File.read(@path)
end