module Stack class Generator attr_accessor :parent attr_accessor :source, :target attr_accessor :children attr_accessor :layouts attr_accessor :pages attr_accessor :processed_at, :transformed_at def initialize(source, target, parent = nil) self.source = source self.target = target self.parent = parent self.layouts = (parent) ? parent.layouts.dup : { } self.children = [ ] # read layouts # read pages # write pages process! end def process! self.processed_at = Time.now read_layouts read_pages read_children end def read_layouts if File.exists?(File.join(self.source, "_layouts")) @layouts = @layouts.merge(read_pages_from_directory("_layouts", Stack::Templates::Layout)) end end def read_pages @pages = read_pages_from_directory(self.source, Stack::Templates::Page) end def read_children entries = Dir.entries(self.source) directories = entries.select { |e| File.directory?(File.join(self.source, e)) } directories = directories.reject { |d| d[0..0]=~/\.|_/ or d[-1..-1]=="~" } directories.each do |dir| self.children.push(Stack::Generator.new(File.join(self.source, dir), File.join(self.target, dir), self)) end end def transform! self.transformed_at = Time.now self.pages.each do |name, page| page.write! end transform_assets self.children.each { |c| c.transform! } end def transform_assets files = Dir.entries(self.source) files = files.reject { |e| File.directory?(File.join(self.source, e)) } files = files.reject { |e| e[0..0]=~/\.|_/ or e[-1..-1]=="~" } files = files.reject { |e| (%w(.yaml .yml)+Stack::EXTENSIONS).include?(File.extname(e)) } # Exception cases FileUtils.mkdir_p(self.target) files.each do |f| FileUtils.cp(File.join(self.source, File.basename(f)), File.join(self.target, File.basename(f))) end end def to_hash { :processed_at => self.processed_at, :transformed_at => self.transformed_at, :time => Time.now } end private def read_pages_from_directory(folder, transformable_klass) pages = { } begin path = (folder == self.source) ? folder : File.join(self.source, folder) folder = (folder == self.source) ? folder : "" entries = Dir.entries(path) files = entries.reject { |e| File.directory?(File.join(path, e)) } files = files.reject { |e| e[0..0]=~/\.|_/ or e[-1..-1]=="~" } files = files.select { |e| Stack::EXTENSIONS.include?(File.extname(e)) } files.each do |f| trans = transformable_klass.new(File.join(path, f), self) pages["#{f.split(".").first}"] = trans end rescue Errno::ENOENT => e # Ignore puts e.to_str end return pages end end end