Permalink
Browse files

added more upgraded files

  • Loading branch information...
1 parent 94e53b9 commit fdbec78947620b45dc8e694d286e0ef466c99d3b @stevenhaddox committed Jun 13, 2010
@@ -0,0 +1,7 @@
+class ActionController::Base
+ before_filter :generate_css_from_less
+
+ def generate_css_from_less
+ Less::More.generate_all
+ end
+end
@@ -0,0 +1,142 @@
+# Less::More provides methods for parsing LESS files in a rails application to CSS target files.
+#
+# When Less::More.parse is called, all files in Less::More.source_path will be parsed using LESS
+# and saved as CSS files in Less::More.destination_path. If Less::More.compression is set to true,
+# extra line breaks will be removed to compress the CSS files.
+#
+# By default, Less::More.parse will be called for each request in `development` environment and on
+# application initialization in `production` environment.
+
+begin
+ require 'less'
+rescue LoadError => e
+ e.message << " (You may need to install the less gem)"
+ raise e
+end
+
+class Less::More
+ HEADER = %{/*\n\n\n\n\n\tThis file was auto generated by Less (http://lesscss.org). To change the contents of this file, edit %s instead.\n\n\n\n\n*/}
+
+ class << self
+ # Less::More.compression = true/false --- compress generated css ? (default: false)
+ # Less::More.header = true/false --- insert editing warning into css ? (default: true)
+ # Less::More.destination_path = 'css' --- put css into public/??? (default: stylesheets)
+ # Less::More.source_path = 'public/stylesheets/less' --- where do less files live? (default: app/stylesheets)
+ attr_writer :compression, :header, :destination_path, :source_path
+
+ def header
+ @header.nil? ? true : @header
+ end
+
+ def destination_path
+ @destination_path || 'stylesheets'
+ end
+
+ def source_path
+ @source_path || 'app/stylesheets'
+ end
+
+ def compression
+ @compression
+ end
+
+ # Generates the .css from a .less or .lss file in Less::More.source_path matching
+ # the given parameters.
+ #
+ # Less::More.generate("screen.less")
+ # Less::More.generate("subdirectories/here/homepage.less")
+ def generate(source)
+ generated = to_dot_css(path_to_destination(source))
+ path_to_source = File.join(Rails.root, source_path, source)
+
+ # check if the destination file exists, and compare the modified times to see if it needs to be written
+ if mtime(generated) >= mtime_including_imports(path_to_source)
+ # up to date, nothing to do!
+ else
+ # css file does not exist or is out of date
+ css = if File.extname(path_to_source) == ".css"
+ # vanilla css nothing to do!
+ File.read(path_to_source)
+ else
+ # less or lss file, compile it
+ css = compile(path_to_source)
+ css.delete!("\n") if compression # TODO: use real compression !
+ css = (HEADER % [File.join(source_path, source)]) << css if header
+ css
+ end
+
+ # write the css
+ FileUtils.mkdir_p File.dirname(generated)
+ File.open(generated, "w"){|f| f.write css }
+ end
+ end
+
+ # Generates all the .css files
+ def generate_all
+ all_less_files.each do |path|
+ generate(relative_to_source_path(path))
+ end
+ end
+
+ # Removes all generated css files.
+ def remove_all_generated
+ all_less_files.each do |path|
+ css_path = to_dot_css(relative_to_source_path(path))
+ css_file = path_to_destination(css_path)
+ File.delete(css_file) if File.file?(css_file)
+ end
+ end
+
+ # Array of paths of less source files.
+ def all_less_files
+ all = Dir[File.join(Rails.root, source_path, "**", "*.{css,less,lss}")]
+ all.reject{|path| File.basename(path) =~ /^_/ }
+ end
+
+ private
+
+ def mtime(file)
+ return 0 unless File.file?(file)
+ File.mtime(file).to_i
+ end
+
+ # consider imports for mtime
+ # just 1 level deep so we do not get any looping/nesting errors
+ def mtime_including_imports(file)
+ mtimes = [mtime(file)]
+ File.readlines(file).each do |line|
+ if line =~ /^\s*@import ['"]([^'"]+)/
+ imported = File.join(File.dirname(file), $1)
+ mtimes << if imported =~ /\.le?ss$/ # complete path given ?
+ mtime(imported)
+ else # we need to add .less or .lss
+ [mtime("#{imported}.less"), mtime("#{imported}.lss")].max
+ end
+ end
+ end
+ mtimes.max
+ end
+
+ def compile(file)
+ begin
+ engine = File.open(file){|f| Less::Engine.new(f) }
+ engine.to_css
+ rescue Exception => e
+ e.message << "\nFrom #{file}"
+ raise e
+ end
+ end
+
+ def to_dot_css(path)
+ path.to_s.sub(/(le?|c)ss$/, "css")
+ end
+
+ def path_to_destination(path)
+ File.join(Rails.root, "public", destination_path, path)
+ end
+
+ def relative_to_source_path(path)
+ path.to_s.sub(File.join(Rails.root, source_path), '')[1..-1]
+ end
+ end
+end
@@ -0,0 +1,26 @@
+require 'test_helper'
+
+class ExampleController < ActionController::Base
+ def test
+ render :text => 'OK'
+ end
+end
+
+class ControllerTest < ActionController::TestCase
+ def setup
+ @controller = ExampleController.new
+ @request = ActionController::TestRequest.new
+ @response = ActionController::TestResponse.new
+ setup_for_generate_test
+ end
+
+ def teardown
+ teardown_for_generate_test
+ end
+
+ should "generate less files" do
+ write_less 'xxx.less', 'a{color:red}'
+ get :test
+ assert_equal 'a { color: red; }', read_css('xxx.css').strip
+ end
+end

0 comments on commit fdbec78

Please sign in to comment.