module Gumdrop class Generator attr_reader :filename, :base_path, :params, :pages def initialize(content, site, opts={}) @site= site @content= content if @content.is_a? Proc @filename= "" @base_path= "" else @filename= content.filename || "" @base_path= content.slug || "" end @params= HashObject.new @pages= [] end # This should probably not be accessible to the generators def execute if @content.is_a? Proc instance_eval &@content else instance_eval File.read(@content.path) end end def site @site end def data @site.data end def config @site.config end def set(var_name, value) params[var_name]= value end def page(name, opts={}, &block) name= name[1..-1] if name.starts_with?('/') opts= params.reverse_merge(opts) filepath= if @base_path.empty? File.join @site.src_path, name else File.join @site.src_path, @base_path, @name end content= GeneratedContent.new(filepath, block, @site, opts) if opts.has_key? :template and !opts[:template].nil? content.template = if @site.layouts.has_key?( opts[:template] ) @site.layouts[ opts[:template] ] else @site.layouts[ "#{opts[:template]}.template" ] end.template end content.ignored= site.greylist.any? {|pattern| site.path_match name, pattern } unless content.ignored content.ignored= site.blacklist.any? {|pattern| site.path_match name, pattern } end @site.report " generated: #{content.uri}", :info @site.node_tree[content.uri]= content end # FIXME: Does redirect require abs-paths? def redirect(from, opts={}) if opts[:to] page from do <<-EOF EOF end opts[:from]= from @site.redirects << opts else @site.report "You must specify :to in a redirect", :warning end end def sprockets(name, opts) require 'gumdrop/sprockets_support' # require 'pp' env = Sprockets::Environment.new @site.root_path env.append_path @site.src_path opts[:paths].each do |path| env.append_path(path) end content= env[ opts[:src] ].to_s page name do compress_output(content, opts) end keep_src(name, content, opts) prune_src(name, opts) end def stitch(name, opts) require 'gumdrop/stitch_support' content= Stitch::Package.new(opts).compile page name do compress_output(content, opts) end keep_src(name, content, opts) prune_src(name, opts) end private def compress_output(content, opts) case opts[:compress] when true, :jsmin require 'jsmin' JSMin.minify content when :yuic require "yui/compressor" compressor = YUI::JavaScriptCompressor.new(:munge => opts[:obfuscate]) compressor.compress(content) when :uglify require "uglifier" Uglifier.compile( content, :mangle=>opts[:obfuscate]) when :packr require 'packr' Packr.pack(content, :shrink_vars => true, :base62 => false, :private=>false) when false content else # UNKNOWN Compressor type! @site.report "Unknown javascript compressor type! (#{ opts[:compressor] })", :warning content end end def keep_src(name, content, opts) if opts[:keep_src] or opts[:keep_source] ext= File.extname name page name.gsub(ext, "#{opts.fetch(:source_postfix, '-src')}#{ext}") do content end end end def prune_src(name, opts) if opts[:prune] and opts[:root] sp = File.expand_path( @site.config.source_dir ) rp = File.expand_path(opts[:root]) relative_root = rp.gsub(sp, '')[1..-1] rrlen= relative_root.length - 1 @site.node_tree.keys.each do |path| if path[0..rrlen] == relative_root and name != path @site.node_tree.delete path end end end end end class GeneratedContent < Content # Nothing special, per se... def initialize(path, block, site, params={}) super(path, site, params) @content_block= block @generated= true end def render(context=nil, ignore_layout=false, reset_context=true, locals={}) if @content_block.nil? super(context, ignore_layout, reset_context, locals) else @content_block.call end end def useLayout? !@content_block.nil? or !@template.nil? end end end