module Golf class Compiler require 'find' attr_accessor :golfpath def initialize(golfpath = '.') self.golfpath = "#{golfpath}/golfapp" puts "golf #{Golf::VERSION}: starting compiler in #{@golfpath}..." puts "golf #{Golf::VERSION}: is valid golfapp?: #{Golf::Compiler.valid?(@golfpath)}" end def self.valid?(dir) File.exists?("#{dir}/golfapp/components") end def generate_componentsjs "jQuery.golf.components=#{component_json};;jQuery.golf.res=#{res_json};;jQuery.golf.plugins=#{plugin_json};;jQuery.golf.scripts=#{script_json};;jQuery.golf.styles=#{style_json};;jQuery.golf.setupComponents();" end def component_json traverse("#{@golfpath}/components", "html") end def res_json JSON.dump(compile_res(@golfpath)) end # compile_res: This function creates a hash representation of # the file structure relative to . The values are either # hashes (for directories) or strings (for files). The string # values are the path to the file relative to @golfpath. # # Example: compile_res("#{@golfpath}/dir1") # # @golfpath/ # |--dir1/ # | |--file1 # | |--file2 # | +--dir2/ # | |--file3 # | |--file4 # | +--dir3/ # | |--file5 # | +--file6 # +--dir4/ # # { # file1 => "dir1/file1", # file2 => "dir1/file2", # dir2 => { # file3 => "dir1/dir2/file3", # file4 => "dir1/dir2/file4" # dir3 => { # file5 => "dir1/dir2/dir3/file5", # file6 => "dir1/dir2/dir3/file6" # } # } # } # def compile_res(dir) results = {} mypath = dir.split('').last == "/" ? dir : dir+"/" myroot = @golfpath.split('').last == "/" ? @golfpath : @golfpath+"/" if File.exists?(mypath) Find.find(mypath) do |path| e = path.slice(mypath.length, path.length-mypath.length) r = path.slice(myroot.length, path.length-myroot.length) f = URI.escape(e) g = File.basename(e) h = File.dirname(r) == "." ? [] : File.dirname(r).split("/") if FileTest.directory?(path) next else r2 = results h.each { |i| if ! r2[i] r2[i] = {} end r2 = r2[i] } r2[g] = f end end end results end def plugin_json traverse("#{@golfpath}/plugins", "js") end def script_json traverse("#{@golfpath}/scripts", "js") end def style_json traverse("#{@golfpath}/styles", "css") end def traverse(dir, type) results = {} if File.exists?(dir) and File.directory?(dir) Dir["#{dir}/**/*.#{type}"].sort.reverse.each do |path| if type == "html" name = package_name(path) arr = path.split('/') last_two = arr.slice(arr.length - 2 ,2) next if last_two[0] != last_two[1].gsub('.html','') else name = path.split('/').last.gsub(".#{type}",'') end data = filtered_read(path) results = results.merge({ name => { "name" => name, "#{type}" => data }}) end end JSON.dump(results) end def filtered_read(path) data = File.read(path) if path.split('.').last == 'html' data = filter_by_block(data) end data = filter_by_extension(data) data end def filter_by_block(data) doc = Hpricot(data) if doc unfiltered_elements = doc.search('//*[@filter]') if unfiltered_elements.count == 0 data else unfiltered_elements.each do |element| filter = element.attributes["filter"] filter_name = filter.capitalize.to_sym if Golf::Filter.constants.include?(filter_name) element.raw_string = Golf::Filter.const_get(filter_name).transform(element.to_s) element.remove_attribute("filter") end end return doc.to_s end else data end end def filter_by_extension(data) data end def package_name(path) if path.include?('golfapp/components') path.match(/golfapp\/components\/(.*)/) component_path = $1 component_path.split('/')[0...-1].join('.') end end end end