Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Transfering from logandk/more. Changing contributor attributions in R…

…EADME and license.
  • Loading branch information...
commit 984ffdd91c31d3214fc15cdd4fd94196ae833472 1 parent 90997b8
@logandk logandk authored
View
20 MIT-LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) 2009 Logan Raarup, August Lilleaas
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
View
0  README
No changes.
View
107 README.markdown
@@ -0,0 +1,107 @@
+`more`: LESS in Rails apps
+==========================
+
+**LESS** is a great gem that extends the standard CSS syntax with lots of good stuff. If you are not already using it, take
+a look at [http://lesscss.org](http://lesscss.org).
+
+By default, **LESS** does not include any Rails specific functionality, which is why you need this Rails plugin. The usage of
+the plugin is very simple and you don't even need to change any of your code. The plugin does the following:
+
+* Recursively looks for **LESS** (.less) files in `app/stylesheets`
+* Ignores partials (prefixed with underscore: `_partial.less`) - these can be included with `@import` in your **LESS** files
+* Saves the resulting CSS files to `public/stylesheets` using the same directory structure as `app/stylesheets`
+
+Of course all this can be configured, see *Configuration* below.
+
+
+Installation
+============
+
+As a Rails Plugin
+-----------------
+
+Use this to install as a plugin in a Ruby on Rails app:
+
+ $ script/plugin install git://github.com/cloudhead/more.git
+
+
+As a Rails Plugin (using git submodules)
+----------------------------------------
+
+Use this if you prefer the idea of being able to easily switch between using edge or a tagged version:
+
+ $ git submodule add git://github.com/cloudhead/more.git vendor/plugins/more
+ $ script/runner vendor/plugins/more/install.rb
+
+
+Usage
+=====
+
+When you have installed this plugin, a new directory will be created in `app/stylesheets`. Put your **LESS** files in
+this directory and they will automatically be parsed on the next request.
+
+Any **LESS** file in `app/stylesheets` will be parsed to an equivalent **CSS** file in `public/stylesheets`. Example:
+
+ app/stylesheets/clients/screen.less => public/stylesheets/clients/screen.css
+
+If you prefix a file with an underscore, it is considered to be a partial, and will not be parsed unless included in another
+file. Example:
+
+ <file: app/stylesheets/clients/partials/_form.less>
+ @text_dark: #222;
+
+ <file: app/stylesheets/clients/screen.less>
+ @import "partials/_form";
+
+ input { color: @text_dark; }
+
+
+Configuration
+-------------
+
+If you want to configure `more` in a specific environment, put these configuration into the environment file, such
+as `config/environments/development.rb`. If you wish to apply the configuration to all environments, put them in `config/environment.rb`.
+
+To set the source path (the location of your **LESS** files)
+
+ Less::More.source_path = "/path/to/less/files"
+
+To set the destination path (the location of the parsed **CSS** files)
+
+ Less::More.destination_path = "/path/to/css/files"
+
+`more` can compress your files by removing extra line breaks. This is enabled by default in the `production` environment. To change
+this setting, set
+
+ Less::More.compression = true
+
+
+Tasks
+=====
+
+`more` provides a couple of Rake tasks to help manage your CSS files.
+
+To parse all LESS files and save the resulting CSS files to the destination path, run
+
+ $ rake more:parse
+
+To delete all generated CSS files, run
+
+ $ rake more:clean
+
+This task will not delete any CSS files from the destination path, that does not have a corresponding LESS file in
+the source path
+
+
+Documentation
+=============
+
+To view the full RDoc documentation, go to [http://rdoc.info/projects/cloudhead/more](http://rdoc.info/projects/cloudhead/more)
+
+For more information about LESS, see [http://lesscss.org](http://lesscss.org)
+
+
+Contributors
+============
+* August Lilleaas
+* Logan Raarup
View
23 Rakefile
@@ -0,0 +1,23 @@
+require 'rake'
+require 'rake/testtask'
+require 'rake/rdoctask'
+
+desc 'Default: run unit tests.'
+task :default => :test
+
+desc 'Test the more plugin.'
+Rake::TestTask.new(:test) do |t|
+ t.libs << 'lib'
+ t.libs << 'test'
+ t.pattern = 'test/**/*_test.rb'
+ t.verbose = true
+end
+
+desc 'Generate documentation for the more plugin.'
+Rake::RDocTask.new(:rdoc) do |rdoc|
+ rdoc.rdoc_dir = 'rdoc'
+ rdoc.title = 'More'
+ rdoc.options << '--line-numbers' << '--inline-source'
+ rdoc.rdoc_files.include('README.markdown')
+ rdoc.rdoc_files.include('lib/**/*.rb')
+end
View
14 init.rb
@@ -0,0 +1,14 @@
+begin
+ require 'less'
+rescue LoadError => e
+ e.message << " (You may need to install the less gem)"
+ raise e
+end
+
+require File.join(File.dirname(__FILE__), 'lib', 'more')
+
+if Rails.env == "production"
+ config.after_initialize { Less::More.parse }
+else
+ ActionController::Base.before_filter { Less::More.parse }
+end
View
4 install.rb
@@ -0,0 +1,4 @@
+require "fileutils"
+include FileUtils::Verbose
+
+mkdir_p File.join(Rails.root, "app", "stylesheets")
View
115 lib/more.rb
@@ -0,0 +1,115 @@
+# 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.
+
+class Less::More
+ class << self
+
+ attr_accessor_with_default :compression, (Rails.env == "production" ? true : false)
+
+ # Returns true if compression is enabled. By default, compression is enabled in the production environment
+ # and disabled in the development and test environments. This value can be changed using:
+ #
+ # Less::More.compression = true
+ #
+ # You can put this line into config/environments/development.rb to enable compression for the development environments
+ def compression?
+ self.compression
+ end
+
+ # Returns the LESS source path, see `source_path=`
+ def source_path
+ @source_path || Rails.root.join("app", "stylesheets")
+ end
+
+ # Sets the source path for LESS files. This directory will be scanned recursively for all *.less files. Files prefixed
+ # with an underscore is considered to be partials and are not parsed directly. These files can be included using `@import`
+ # statements. *Example partial filename: _form.less*
+ #
+ # Default value is app/stylesheets
+ #
+ # Examples:
+ # Less::More.source_path = "/path/to/less/files"
+ # Less::More.source_path = Pathname.new("/other/path")
+ def source_path=(path)
+ @source_path = Pathname.new(path.to_s)
+ end
+
+ # Returns the destination path for the parsed CSS files, see `destination_path=`
+ def destination_path
+ @destination_path || Rails.root.join("public", "stylesheets")
+ end
+
+ # Sets the destination path for the parsed CSS files. The directory structure from the source path will be retained, and
+ # all files, except partials prefixed with underscore, will be available with a .css extension.
+ #
+ # Default value is public/stylesheets
+ #
+ # Examples:
+ # Less::More.destination_path = "/path/to/css/files"
+ # Less::More.destination_path = Pathname.new("/other/path")
+ def destination_path=(path)
+ @destination_path = Pathname.new(path.to_s)
+ end
+
+ # Returns a collection of matching files in the source path, which will be parsed.
+ #
+ # Example:
+ # Less::More.map => [{ :source => #<Pathname:...>, :destination => #<Pathname:...> }, ...]
+ def map
+ files = Pathname.glob(self.source_path.join("**", "*.less")).reject { |f| f.basename.to_s.starts_with? "_" }
+
+ files.collect! do |file|
+ relative_path = file.relative_path_from(self.source_path)
+ { :source => file, :destination => self.destination_path.join(relative_path.dirname, relative_path.basename(relative_path.extname).to_s + ".css") }
+ end
+ end
+
+ # Performs the core functionality of passing the LESS files from the source path through LESS and outputting CSS files to
+ # the destination path. The LESS files will only be parsed if the CSS file is not present, or if the modification time of
+ # the LESS file or any of its included files are newer than the CSS files. Imported files are recursively checked for updated
+ # modification times.
+ #
+ # If `compression` is enabled, extra line breaks will be removed.
+ #
+ # Example:
+ # Less::More.parse
+ def parse
+ self.map.each do |file|
+ file[:destination].dirname.mkpath unless file[:destination].dirname.exist?
+
+ modified = self.read_imports(file[:source]).push(file[:source]).max { |x, y| x.mtime <=> y.mtime }.mtime
+
+ if !file[:destination].exist? || modified > file[:destination].mtime
+ css = Less::Engine.new(file[:source].open).to_css
+ css = css.delete " \n" if self.compression?
+
+ file[:destination].open("w") { |f| f.write css }
+ end
+ end
+ end
+
+ # Recusively reads import statement from less files and returns an array of `Pathname`. It also checks that
+ # the files are present in the filesystem.
+ #
+ # Example:
+ # p = Pathname.new("/path/to/file")
+ # Less::More.read_imports(p) => [#<Pathname:/path/to/include1>, #<Pathname:/path/to/include2>, ...]
+ def read_imports(file)
+ imports = file.read.scan(/@import\s+(['"])(.*?)\1/i)
+
+ imports.collect! do |v|
+ path = file.dirname.join(v.last + ".less")
+ path.exist? ? self.read_imports(path).push(path) : nil
+ end
+
+ imports.flatten.compact.uniq
+ end
+
+ end
+end
View
36 tasks/more_tasks.rake
@@ -0,0 +1,36 @@
+require 'less'
+require File.join(File.dirname(__FILE__), '..', 'lib', 'more')
+
+namespace :more do
+ desc "Generate CSS files from LESS files"
+ task :parse => :environment do
+ files = Less::More.parse
+
+ puts "Successfully parsed files:"
+
+ files.each do |f|
+ puts " - " + f[:source].relative_path_from(Less::More.source_path).to_s
+ end
+
+ puts "\nSaved to: " + Less::More.destination_path.to_s
+ end
+
+ desc "Remove generated CSS files"
+ task :clean => :environment do
+ files = Less::More.map
+
+ puts "Deleting files:"
+
+ files.each do |f|
+ if f[:destination].exist?
+ puts " - " + f[:destination]
+ f[:destination].delete
+
+ if f[:destination].parent.children.empty? and f[:destination].parent != Less::More.destination_path
+ puts " - " + f[:destination].parent
+ f[:destination].parent.delete
+ end
+ end
+ end
+ end
+end
View
2  test/less_files/_global.less
@@ -0,0 +1,2 @@
+@text_light: #ffffff;
+@text_dark: #222222;
View
3  test/less_files/shared/_form.less
@@ -0,0 +1,3 @@
+.allforms {
+ font-size: 110%;
+}
View
11 test/less_files/test.less
@@ -0,0 +1,11 @@
+@import "_global";
+@import "shared/_form";
+
+body {
+ color: @text_dark;
+}
+
+form {
+ .allforms;
+ color: @text_light;
+}
View
40 test/more_test.rb
@@ -0,0 +1,40 @@
+require 'test_helper'
+
+class MoreTest < Test::Unit::TestCase
+ def test_compression
+ Less::More.compression = true
+ assert_equal Less::More.compression?, true
+
+ Less::More.compression = false
+ assert_equal Less::More.compression?, false
+ end
+
+ def test_source_path
+ Less::More.source_path = "/path/to/flaf"
+ assert_equal Less::More.source_path, Pathname.new("/path/to/flaf")
+ end
+
+ def test_destination_path
+ Less::More.destination_path = "/path/to/flaf"
+ assert_equal Less::More.destination_path, Pathname.new("/path/to/flaf")
+ end
+
+ def test_map
+ Less::More.source_path = File.join(File.dirname(__FILE__), 'less_files')
+ Less::More.destination_path = File.join(File.dirname(__FILE__), 'css_files')
+
+ assert_equal Less::More.map, [{ :source => Less::More.source_path.join("test.less"), :destination => Less::More.destination_path.join("test.css") }]
+ end
+
+ def test_parse
+ Less::More.source_path = File.join(File.dirname(__FILE__), 'less_files')
+ Less::More.destination_path = File.join(File.dirname(__FILE__), 'css_files')
+ Less::More.compression = true
+
+ Less::More.parse
+
+ assert_equal Less::More.destination_path.join("test.css").read, ".allforms{font-size:110%;}body{color:#222222;}form{font-size:110%;color:#ffffff;}"
+
+ Less::More.destination_path.join("test.css").delete
+ end
+end
View
17 test/test_helper.rb
@@ -0,0 +1,17 @@
+require 'test/unit'
+
+begin
+ require File.join(File.dirname(__FILE__), '..', '..', '..', '..', 'config', 'environment')
+rescue LoadError => e
+ puts "Please run these tests within a Rails app"
+ exit
+end
+
+begin
+ require 'less'
+rescue LoadError => e
+ e.message << " (You may need to install the less gem)"
+ raise e
+end
+
+require 'more'
Please sign in to comment.
Something went wrong with that request. Please try again.