module Stack class Generator attr_accessor :parent attr_accessor :source, :target attr_accessor :children attr_accessor :layouts attr_accessor :articles attr_accessor :pages attr_accessor :remove_first attr_accessor :processed_at, :transformed_at def initialize(source, target, parent = nil) self.source = source self.target = target self.parent = parent self.remove_first = false self.layouts = (parent) ? parent.layouts.dup : { } self.articles = (parent) ? parent.articles.dup : { } self.children = [ ] # read layouts # read pages # write pages process! end def process! self.processed_at = Time.now read_articles 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_articles if File.exists?(File.join(self.source, "_articles")) @articles = @articles.merge(read_pages_from_directory("_articles", Stack::Templates::Article)) 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| gen = Stack::Generator.new(File.join(self.source, dir), File.join(self.target, dir), self) #gen.process! self.children.push(gen) end end def transform!(match_only = nil) if self.remove_first FileUtils.rm_r self.target end self.transformed_at = Time.now self.articles.each do |name, article| if (match_only) match_only.each { |m| if File.dirname(m.path) == File.dirname(article.path) && File.basename(m.path) == article.basename article.write! end } else article.write! end end self.pages.each do |name, page| if (match_only) match_only.each { |m| if File.dirname(m.path) == File.dirname(page.path) && File.basename(m.path) == page.basename page.write! end } else page.write! end end transform_assets self.children.each { |c| c.transform!(match_only) } 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, :articles => self.articles_payload } end def articles_payload a = Array.new self.articles.each { |name, article| article.inspect a.push(article.payload) } a 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