1.0.3~dfsg/ 0000755 0000000 0000000 00000000000 12456054517 011266 5 ustar root root 1.0.3~dfsg/Guardfile 0000644 0000000 0000000 00000000742 12456054517 013116 0 ustar root root group :tests do
guard :test do
watch(%r{^lib/(.+)\.rb$}) { |m| "test/#{m[1]}_test.rb" }
watch(%r{^test/.+_test\.rb$})
watch(%r{^test/units/.+_test\.rb$})
watch('test/test_helper.rb') { "test" }
end
end
group :features do
guard :cucumber do
watch(%r{^features/.+\.feature$})
watch(%r{^features/support/.+$}) { 'features' }
watch(%r{^features/step_definitions/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'features' }
end
end 1.0.3~dfsg/test_all.sh 0000755 0000000 0000000 00000000524 12456054517 013435 0 ustar root root #!/bin/sh
cd core && bundle install --quiet && bundle exec rake test && cd .. &&
cd cli && bundle install --quiet && bundle exec rake && cd .. &&
cd import-once && bundle install --quiet && bundle exec rake test && cd .. &&
cd import-once && (BUNDLE_GEMFILE=Gemfile_sass_3_2 bundle install --quiet && bundle exec rake test) && cd ..
1.0.3~dfsg/cli/ 0000755 0000000 0000000 00000000000 12456054517 012035 5 ustar root root 1.0.3~dfsg/cli/lib/ 0000755 0000000 0000000 00000000000 12456054517 012603 5 ustar root root 1.0.3~dfsg/cli/lib/compass.rb 0000644 0000000 0000000 00000001244 12456054517 014576 0 ustar root root module Compass
end
%w(core
deprecation
dependencies
sass_extensions
version
errors
quick_cache
logger
actions
).each do |lib|
require "compass/#{lib}"
end
require 'sass/callbacks'
module Compass
def base_directory
File.expand_path(File.join(File.dirname(__FILE__), '..'))
end
def lib_directory
File.expand_path(File.join(File.dirname(__FILE__)))
end
module_function :base_directory, :lib_directory
extend QuickCache
end
%w(configuration/helpers
configuration/comments
configuration/serialization
configuration/file_data
app_integration
compiler
sprite_importer
).each do |lib|
require "compass/#{lib}"
end
1.0.3~dfsg/cli/lib/compass/ 0000755 0000000 0000000 00000000000 12456054517 014250 5 ustar root root 1.0.3~dfsg/cli/lib/compass/app_integration/ 0000755 0000000 0000000 00000000000 12456054517 017433 5 ustar root root 1.0.3~dfsg/cli/lib/compass/app_integration/stand_alone.rb 0000644 0000000 0000000 00000000631 12456054517 022247 0 ustar root root %w(configuration_defaults installer).each do |lib|
require "compass/app_integration/stand_alone/#{lib}"
end
module Compass
module AppIntegration
module StandAlone
extend self
def installer(*args)
Installer.new(*args)
end
def configuration
Compass::Configuration::Data.new('stand_alone').
extend(ConfigurationDefaults)
end
end
end
end
1.0.3~dfsg/cli/lib/compass/app_integration/stand_alone/ 0000755 0000000 0000000 00000000000 12456054517 021722 5 ustar root root 1.0.3~dfsg/cli/lib/compass/app_integration/stand_alone/configuration_defaults.rb 0000644 0000000 0000000 00000001050 12456054517 027001 0 ustar root root module Compass
module AppIntegration
module StandAlone
module ConfigurationDefaults
def default_project_type
:stand_alone
end
def sass_dir_without_default
"sass"
end
def javascripts_dir_without_default
"javascripts"
end
def css_dir_without_default
"stylesheets"
end
def images_dir_without_default
"images"
end
def default_cache_dir
".sass-cache"
end
end
end
end
end
1.0.3~dfsg/cli/lib/compass/app_integration/stand_alone/installer.rb 0000644 0000000 0000000 00000004712 12456054517 024250 0 ustar root root module Compass
module Installers
class Base
end
class ManifestInstaller < Base
end
end
module AppIntegration
module StandAlone
class Installer < Compass::Installers::ManifestInstaller
def init
directory targetize("")
super
end
def write_configuration_files(config_file = nil)
config_file ||= targetize('config.rb')
write_file config_file, config_contents
end
def config_files_exist?
File.exists? targetize('config.rb')
end
def config_contents
project_path, Compass.configuration.project_path = Compass.configuration.project_path, nil
Compass.configuration.serialize
ensure
Compass.configuration.project_path = project_path
end
def prepare
write_configuration_files unless config_files_exist? || !@manifest.generate_config?
end
def completed_configuration
nil
end
def finalize(options = {})
if options[:create] && !manifest.welcome_message_options[:replace]
puts <<-NEXTSTEPS
*********************************************************************
Congratulations! Your compass project has been created.
You may now add and edit sass stylesheets in the #{Compass.configuration.sass_dir} subdirectory of your project.
Sass files beginning with an underscore are called partials and won't be
compiled to CSS, but they can be imported into other sass stylesheets.
You can configure your project by editing the config.rb configuration file.
You must compile your sass stylesheets into CSS when they change.
This can be done in one of the following ways:
1. To compile on demand:
compass compile [path/to/project]
2. To monitor your project for changes and automatically recompile:
compass watch [path/to/project]
More Resources:
* Website: http://compass-style.org/
* Sass: http://sass-lang.com
* Community: http://groups.google.com/group/compass-users/
NEXTSTEPS
end
puts manifest.welcome_message if manifest.welcome_message
if manifest.has_stylesheet? && !manifest.welcome_message_options[:replace]
puts "\nTo import your new stylesheets add the following lines of HTML (or equivalent) to your webpage:"
puts stylesheet_links
end
end
def compilation_required?
@manifest.compile?
end
end
end
end
end
1.0.3~dfsg/cli/lib/compass/sass_extensions.rb 0000644 0000000 0000000 00000000560 12456054517 020026 0 ustar root root unless Sass::Script::Functions.methods.grep(/\Adeclare\Z/).any?
raise LoadError, "It looks like you've got an incompatible version of Sass. This often happens when you have an old haml gem installed. Please upgrade Haml to v3.1 or above."
end
module Compass::SassExtensions
end
require 'compass/sass_extensions/functions'
require 'compass/sass_extensions/sprites'
1.0.3~dfsg/cli/lib/compass/sass_compiler.rb 0000644 0000000 0000000 00000011111 12456054517 017433 0 ustar root root require 'sass/plugin'
class Compass::SassCompiler
include Compass::Actions
attr_writer :logger
attr_reader :quiet
attr_reader :error_count
attr_accessor :config
attr_accessor :display_compilation_times
attr_accessor :working_path
attr_accessor :only_sass_files
def initialize(options = {}, config = Compass.configuration)
options = options.dup
self.config = config
self.display_compilation_times = options.delete(:time)
self.working_path = options.delete(:working_path) || Dir.pwd
self.only_sass_files = options.delete(:only_sass_files) || []
@quiet = options[:quiet]
plugin_options = config.to_sass_plugin_options.merge(options)
if only_sass_files.any?
plugin_options[:template_location] = []
plugin_options[:load_paths] = config.sass_load_paths
end
plugin_options[:always_update] = true if options.delete(:force)
plugin_options[:compass] ||= {}
plugin_options[:compass][:logger] = logger
@compiler = Sass::Plugin::Compiler.new(plugin_options)
@start_times = {}
@error_count = 0
public_methods(true).grep(/^when_/).each do |callback|
@compiler.send(callback.to_s.sub(/^when_/, 'on_')) {|*args| send(callback, *args) }
end
end
def compile!
@compiler.update_stylesheets(individual_files)
end
def watch!(options = {}, &block)
skip_initial_update = options.fetch(:skip_initial_update, false)
begin
@compiler.watch(individual_files, options.merge(:skip_initial_update => skip_initial_update), &block)
rescue Sass::SyntaxError => e
skip_initial_update = true
retry
end
end
def individual_files
only_sass_files.map {|sass_file| [sass_file, corresponding_css_file(sass_file)]}
end
def clean!
@compiler.clean(individual_files)
end
def file_list
@compiler.file_list(individual_files)
end
def when_updating_stylesheets(individual_files)
@start_times = {}
@error_count = 0
end
def when_compilation_starting(sass_file, css, sourcemap)
@start_times[sass_file] = Time.now
end
def when_template_created(sass_file)
logger.record :created, relativize(sass_file)
end
def when_template_deleted(sass_file)
logger.record :deleted, relativize(sass_file)
end
def when_template_modified(sass_file)
logger.record :modified, relativize(sass_file)
end
def when_updated_stylesheet(sass_file, css, sourcemap)
if css && display_compilation_times && @start_times[sass_file]
duration = ((Time.now - @start_times[sass_file]) * 1000).round / 1000.0
logger.record :write, "#{relativize(css)} (#{duration}s)"
else
logger.record :write, relativize(css) if css
end
config.run_stylesheet_saved(css) if css
logger.record :write, relativize(sourcemap) if sourcemap
config.run_sourcemap_saved(sourcemap) if sourcemap
end
def when_creating_directory(dirname)
logger.record :directory, relativize(dirname)
end
def when_deleting_css(filename)
logger.record :delete, relativize(filename)
config.run_stylesheet_removed(filename) if filename
end
def when_deleting_sourcemap(filename)
logger.record :delete, relativize(filename)
config.run_sourcemap_removed(filename) if filename
end
def when_compilation_error(error, sass_file, css_file, sourcemap_file)
@error_count += 1
if error.respond_to?(:sass_filename)
error_filename = error.sass_filename || sass_file
if relativize(error_filename) == relativize(sass_file)
logger.record :error, "#{relativize(sass_file)} (Line #{error.sass_line}: #{error.message})"
else
logger.record :error, "#{relativize(sass_file)} (Line #{error.sass_line} of #{relativize(error_filename)}: #{error.message})"
end
else
logger.record :error, "#{relativize(sass_file)} (#{error.backtrace.first}: #{error.message})"
end
config.run_stylesheet_error(sass_file, error.message)
end
def logger
@logger ||= Compass::Logger.new(:quiet => quiet)
end
def corresponding_css_file(sass_file)
"#{config.css_path}/#{stylesheet_name(sass_file)}.css"
end
def stylesheet_name(sass_file)
if sass_file.index(config.sass_path) == 0
sass_file[(config.sass_path.length + 1)..-6].sub(/\.css$/,'')
else
raise Compass::Error, "Individual stylesheets must be in the sass directory."
end
end
def sass_files(options = {})
@compiler.template_location_array.map do |(sass_dir, css_dir)|
glob = options[:include_partials] ?
File.join("**","*.s[ac]ss*") :
File.join("**","[^_]*.s[ac]ss*")
Dir.glob(File.join(sass_dir, glob))
end.flatten
end
end
1.0.3~dfsg/cli/lib/compass/actions.rb 0000644 0000000 0000000 00000006765 12456054517 016253 0 ustar root root module Compass
module Actions
attr_writer :logger
def logger
@logger ||= ::Compass::Logger.new
end
# copy/process a template in the compass template directory to the project directory.
def copy(from, to, options = nil, binary = false)
options ||= self.options if self.respond_to?(:options)
if binary
contents = File.new(from,"rb").read
else
contents = File.new(from).read
end
write_file to, contents, options, binary
end
# create a directory and all the directories necessary to reach it.
def directory(dir, options = nil)
options ||= self.options if self.respond_to?(:options)
options ||= {}
if File.exists?(dir) && File.directory?(dir)
# do nothing
elsif File.exists?(dir)
msg = "#{basename(dir)} already exists and is not a directory."
raise Compass::FilesystemConflict.new(msg)
else
log_action :directory, separate("#{basename(dir)}/"), options
FileUtils.mkdir_p(dir)
end
end
# Write a file given the file contents as a string
def write_file(file_name, contents, options = nil, binary = false)
options ||= self.options if self.respond_to?(:options)
skip_write = false
contents = process_erb(contents, options[:erb]) if options[:erb]
if File.exists?(file_name)
existing_contents = IO.read(file_name)
if existing_contents == contents
log_action :identical, basename(file_name), options
skip_write = true
elsif options[:force]
log_action :overwrite, basename(file_name), options
else
msg = "File #{basename(file_name)} already exists. Run with --force to force overwrite."
raise Compass::FilesystemConflict.new(msg)
end
else
log_action :create, basename(file_name), options
end
if skip_write
FileUtils.touch file_name
else
mode = "w"
mode << "b" if binary
open(file_name, mode) do |file|
file.write(contents)
end
end
end
def process_erb(contents, ctx = nil)
ctx = Object.new.instance_eval("binding") unless ctx.is_a? Binding
ERB.new(contents).result(ctx)
end
def remove(file_name)
file_name ||= ''
if File.directory?(file_name)
FileUtils.rm_rf file_name
log_action :remove, basename(file_name)+"/", options
elsif File.exists?(file_name)
File.unlink file_name
log_action :remove, basename(file_name), options
end
end
def basename(file)
relativize(file) {|f| File.basename(file)}
end
def relativize(path)
path = File.expand_path(path)
if path.index(working_path+File::SEPARATOR) == 0
path[(working_path+File::SEPARATOR).length..-1]
elsif block_given?
yield path
else
path
end
end
# Write paths like we're on unix and then fix it
def separate(path)
path.gsub(%r{/}, File::SEPARATOR)
end
# Removes the trailing separator, if any, from a path.
def strip_trailing_separator(path)
(path[-1..-1] == File::SEPARATOR) ? path[0..-2] : path
end
def log_action(action, file, options)
quiet = !!options[:quiet]
quiet = false if options[:loud] && options[:loud] == true
quiet = false if options[:loud] && options[:loud].is_a?(Array) && options[:loud].include?(action)
unless quiet
logger.record(action, file, options[:extra].to_s)
end
end
end
end
1.0.3~dfsg/cli/lib/compass/sass_extensions/ 0000755 0000000 0000000 00000000000 12456054517 017500 5 ustar root root 1.0.3~dfsg/cli/lib/compass/sass_extensions/sprites/ 0000755 0000000 0000000 00000000000 12456054517 021171 5 ustar root root 1.0.3~dfsg/cli/lib/compass/sass_extensions/sprites/sprite_map.rb 0000644 0000000 0000000 00000005151 12456054517 023663 0 ustar root root module Compass
module SassExtensions
module Sprites
class SpriteMap < Sass::Script::Value::Base
attr_accessor :image_names, :path, :name, :map, :kwargs
attr_accessor :images, :width, :height, :engine
include SpriteMethods
include ImageMethods
include LayoutMethods
include Sass::Script::Value::Helpers
# Initialize a new sprite object from a relative file path
# the path is relative to the images_path confguration option
def self.from_uri(uri, context, kwargs)
uri = uri.value
path, name = Compass::SpriteImporter.path_and_name(uri)
files = Compass::SpriteImporter.files(uri)
sprites = files.map do |sprite|
relative_name(sprite)
end
new(sprites, path, name, context, kwargs)
end
def self.relative_name(sprite)
sprite = File.expand_path(sprite)
Compass.configuration.sprite_load_path.each do |path|
path_with_slash = "#{File.expand_path(path)}/"
if sprite.include?(path_with_slash)
return sprite.gsub(path_with_slash, '')
end
end
end
def initialize(sprites, path, name, context, kwargs)
@image_names = sprites
@path = path
@name = name
@kwargs = kwargs
@kwargs['cleanup'] ||= bool(true)
@kwargs['layout'] ||= identifier('vertical')
@kwargs['sort_by'] ||= identifier('none')
@images = nil
@width = nil
@height = nil
@engine = nil
@evaluation_context = context
compute_image_metadata!
end
def sort_method
@kwargs['sort_by'].value
end
def inspect
puts 'images'
@images.each do |img|
puts img.file
end
puts "options"
@kwargs.each do |k,v|
puts "#{k}:#{v}"
end
end
def to_s(kwargs = self.kwargs)
sprite_url(self).value
end
def respond_to?(meth)
super || @evaluation_context.respond_to?(meth)
end
def method_missing(meth, *args, &block)
if @evaluation_context.respond_to?(meth)
@evaluation_context.send(meth, *args, &block)
else
super
end
end
private
def modulize
@modulize ||= Compass::configuration.sprite_engine.to_s.scan(/([^_.]+)/).flatten.map {|chunk| "#{chunk[0].chr.upcase}#{chunk[1..-1]}" }.join
end
end
end
end
end
1.0.3~dfsg/cli/lib/compass/sass_extensions/sprites/image_row.rb 0000644 0000000 0000000 00000001675 12456054517 023500 0 ustar root root require 'forwardable'
module Compass
module SassExtensions
module Sprites
class ImageRow
extend Forwardable
attr_reader :images, :max_width
def_delegators :@images, :last, :delete, :empty?, :length
def initialize(max_width)
@images = []
@max_width = max_width
end
def add(image)
return false if !will_fit?(image)
@images << image
true
end
alias :<< :add
def height
images.map(&:height).max
end
def width
images.map(&:width).max
end
def total_width
images.inject(0) {|sum, img| sum + img.width }
end
def efficiency
1 - (total_width.to_f / max_width.to_f)
end
def will_fit?(image)
(total_width + image.width) <= max_width
end
end
end
end
end 1.0.3~dfsg/cli/lib/compass/sass_extensions/sprites/layout/ 0000755 0000000 0000000 00000000000 12456054517 022506 5 ustar root root 1.0.3~dfsg/cli/lib/compass/sass_extensions/sprites/layout/vertical.rb 0000644 0000000 0000000 00000004255 12456054517 024652 0 ustar root root module Compass
module SassExtensions
module Sprites
module Layout
class Vertical < SpriteLayout
def layout!
calculate_width!
calculate_positions!
calculate_height!
tile_images_that_repeat!
end
private # ===========================================================================================>
def calculate_width!
@width = @images.map { |image| image.width + image.offset }.max
if repeating_images?
calculate_repeat_extra_width!
end
@width
end
def calculate_height!
last = @images.last
@height = last.top + last.height
end
def repeating_images?
@repeating_images ||= @images.any?(&:repeat_x?)
end
def calculate_repeat_extra_width!
m = @images.inject(1) {|m,img| img.repeat_x? ? m.lcm(img.width) : m }
remainder = @width % m
@width += (m - remainder) unless remainder.zero?
end
def calculate_positions!
@images.each_with_index do |image, index|
image.left = (image.position.unit_str == "%" ? (@width - image.width) * (image.position.value / 100.0) : image.position.value).to_i
next if index == 0
last_image = @images[index-1]
image.top = last_image.top + last_image.height + [image.spacing, last_image.spacing].max
end #each_with_index
end #method
def tile_images_that_repeat!
return unless repeating_images?
@images.map {|img| img if img.repeat_x?}.compact.each do |image|
x = image.left - (image.left / image.width).ceil * image.width
while x < @width do
begin
img = image.dup
img.top = image.top
img.left = x.to_i
@images << img
x += image.width
end #begin
end #while
end #map
end #method
end #Vertical
end #Layout
end #Sprites
end #SassExtensions
end #Compass 1.0.3~dfsg/cli/lib/compass/sass_extensions/sprites/layout/diagonal.rb 0000644 0000000 0000000 00000002120 12456054517 024604 0 ustar root root module Compass
module SassExtensions
module Sprites
module Layout
class Diagonal < SpriteLayout
def layout!
calculate_width!
calculate_height!
calculate_positions!
end
private # ===========================================================================================>
def calculate_width!
@width = @images.inject(0) {|sum, img| sum + img.width}
end
def calculate_height!
@height = @images.inject(0) {|sum, img| sum + img.height}
end
def calculate_positions!
previous = nil
@images.each_with_index do |image, index|
if previous.nil?
previous = image
image.top = @height - image.height
image.left = 0
next
end
image.top = previous.top - image.height
image.left = previous.left + previous.width
previous = image
end
end
end
end
end
end
end
1.0.3~dfsg/cli/lib/compass/sass_extensions/sprites/layout/horizontal.rb 0000644 0000000 0000000 00000004041 12456054517 025223 0 ustar root root module Compass
module SassExtensions
module Sprites
module Layout
class Horizontal < SpriteLayout
def layout!
calculate_height!
calculate_width!
calculate_positions!
tile_images_that_repeat!
end
private # ===========================================================================================>
def calculate_height!
@height = @images.map {|image| image.height + image.offset}.max
if repeating_images?
calculate_repeat_extra_height!
end
@height
end
def calculate_width!
@width = @images.inject(0) { |sum, image| sum += (image.width + image.spacing) }
end
def repeating_images?
@repeating_images ||= @images.any?(&:repeat_y?)
end
def calculate_repeat_extra_height!
m = @images.inject(1) {|m,img| img.repeat_y? ? m.lcm(img.height) : m }
remainder = @height % m
@height += (m - remainder) unless remainder.zero?
end
def calculate_positions!
@images.each_with_index do |image, index|
image.top = image.position.unit_str == '%' ? (@height - image.height) * (image.position.value / 100.0) : image.position.value
next if index == 0
last_image = @images[index-1]
image.left = last_image.left + last_image.width + [image.spacing, last_image.spacing].max
end
end
def tile_images_that_repeat!
return unless repeating_images?
@images.map {|img| img if img.repeat_y?}.compact.each do |image|
y = (image.top + image.height)
while y < @height do
begin
img = image.dup
img.top = y.to_i
@images << img
y += image.height
end
end #while
end
end
end
end
end
end
end
1.0.3~dfsg/cli/lib/compass/sass_extensions/sprites/layout/smart.rb 0000644 0000000 0000000 00000001555 12456054517 024167 0 ustar root root module Compass
module SassExtensions
module Sprites
module Layout
class Smart < SpriteLayout
def layout!
calculate_positions!
end
private # ===========================================================================================>
def calculate_positions!
fitter = ::Compass::SassExtensions::Sprites::RowFitter.new(@images)
current_y = 0
fitter.fit!.each do |row|
current_x = 0
row.images.each_with_index do |image, index|
image.left = current_x
image.top = current_y
current_x += image.width
end
current_y += row.height
end
@width = fitter.width
@height = fitter.height
end
end
end
end
end
end
1.0.3~dfsg/cli/lib/compass/sass_extensions/sprites/row_fitter.rb 0000644 0000000 0000000 00000004115 12456054517 023703 0 ustar root root require 'forwardable'
module Compass
module SassExtensions
module Sprites
class RowFitter
extend Forwardable
attr_reader :images, :rows
def_delegators :rows, :[]
def initialize(images)
@images = images.sort do |a,b|
if a.height == b.height
b.width <=> a.width
else
a.height <=> b.height
end
end
@rows = []
end
def fit!(style = :scan)
send("#{style}_fit")
@rows
end
def width
@width ||= @images.collect(&:width).max
end
def height
@height ||= @rows.inject(0) {|sum, row| sum += row.height}
end
def efficiency
@rows.inject(0) { |sum, row| sum += row.efficiency } ** @rows.length
end
private
def new_row(image = nil)
row = Compass::SassExtensions::Sprites::ImageRow.new(width)
row.add(image) if image
row
end
def fast_fit
row = new_row
@images.each do |image|
if !row.add(image)
@rows << row
row = new_row(image)
end
end
@rows << row
end
def scan_fit
fast_fit
moved_images = []
begin
removed = false
catch :done do
@rows.each do |row|
(@rows - [ row ]).each do |other_row|
other_row.images.each do |image|
if !moved_images.include?(image)
if row.will_fit?(image)
other_row.delete(image)
row << image
@rows.delete(other_row) if other_row.empty?
removed = true
moved_images << image
throw :done
end
end
end
end
end
end
end while removed
end
end
end
end
end 1.0.3~dfsg/cli/lib/compass/sass_extensions/sprites/image.rb 0000644 0000000 0000000 00000007763 12456054517 022615 0 ustar root root module Compass
module SassExtensions
module Sprites
class Image
include Sass::Script::Value::Helpers
ACTIVE = %r{[_-]active$}
TARGET = %r{[_-]target$}
HOVER = %r{[_-]hover$}
FOCUS = %r{[_-]focus$}
PARENT = %r{(.+)[-_](.+)$}
REPEAT_X = 'repeat-x'
REPEAT_Y = 'repeat-y'
NO_REPEAT = 'no-repeat'
VALID_REPEATS = [REPEAT_Y, REPEAT_X, NO_REPEAT]
attr_reader :relative_file, :options, :base, :name
attr_accessor :top, :left
def initialize(base, relative_file, options)
@base, @relative_file, @options = base, relative_file, options
@left = @top = 0
@name = File.basename(relative_file, '.png')
end
# The Full path to the image
def file
@file ||= find_file
end
def find_file
Compass.configuration.sprite_load_path.compact.each do |path|
f = File.join(path, relative_file)
if File.exists?(f)
return f
end
end
end
# Width of the image
def width
dimensions.first
end
def size
@size ||= File.size(file)
end
# Height of the image
def height
dimensions.last
end
def get_var_file(var)
options.get_var "#{base.name}_#{name}_#{var}"
end
# Value of $#{name}-repeat or $repeat
def repeat
@repeat ||= begin
rep = (get_var_file("repeat") || options.get_var("repeat") || identifier(NO_REPEAT)).value
unless VALID_REPEATS.include? rep
raise SpriteException, "Invalid option for repeat \"#{rep}\" - valid options are #{VALID_REPEATS.join(', ')}"
end
rep
end
end
def repeat_x?
repeat == REPEAT_X
end
def repeat_y?
repeat == REPEAT_Y
end
def no_repeat?
repeat == NO_REPEAT
end
# Value of $#{name}-position or $position defaults to 0px
def position
@position ||= get_var_file("position") || options.get_var("position") || number(0, "px")
end
# Offset within the sprite
def offset
@offset ||= (position.unitless? || position.unit_str == "px") ? position.value : 0
end
# Spacing between this image and the next
def spacing
@spacing ||= (get_var_file("spacing") || options.get_var("spacing") || number(0, 'px')).value
end
# MD5 hash of this file
def digest
Digest::MD5.file(file).hexdigest
end
# mtime of this file
def mtime
File.mtime(file)
end
# Is hover selector
def hover?
name =~ HOVER
end
# Hover selector Image object if exsists
def hover
base.get_magic_selector_image(name, 'hover')
end
# Is target selector
def target?
name =~ TARGET
end
# Target selector Image object if exsists
def target
base.get_magic_selector_image(name, 'target')
end
# Is active selector
def active?
name =~ ACTIVE
end
# Active selector Image object if exsists
def active
base.get_magic_selector_image(name, 'active')
end
# Is active selector
def focus?
name =~ FOCUS
end
# Active selector Image object if exsists
def focus
base.get_magic_selector_image(name, 'focus')
end
def parent
if [hover?, target?, active?, focus?].any?
PARENT.match name
base.image_for($1)
end
end
private
def dimensions
@dimensions ||= Compass::Core::SassExtensions::Functions::ImageSize::ImageProperties.new(file).size
end
end
end
end
end
1.0.3~dfsg/cli/lib/compass/sass_extensions/sprites/layout_methods.rb 0000644 0000000 0000000 00000003012 12456054517 024552 0 ustar root root module Compass
module SassExtensions
module Sprites
module LayoutMethods
HORIZONTAL = 'horizontal'
DIAGONAL = 'diagonal'
SMART = 'smart'
VERTICAL = 'vertical'
def smart?
layout == SMART
end
def horizontal?
layout == HORIZONTAL
end
def diagonal?
layout == DIAGONAL
end
def vertical?
layout == VERTICAL
end
def layout
@layout ||= @kwargs.get_var('layout').value
end
# Calculates the overal image dimensions
# collects image sizes and input parameters for each sprite
def compute_image_positions!
case layout
when SMART
require 'compass/sass_extensions/sprites/layout/smart'
@images, @width, @height = Layout::Smart.new(@images, @kwargs).properties
when DIAGONAL
require 'compass/sass_extensions/sprites/layout/diagonal'
@images, @width, @height = Layout::Diagonal.new(@images, @kwargs).properties
when HORIZONTAL
require 'compass/sass_extensions/sprites/layout/horizontal'
@images, @width, @height = Layout::Horizontal.new(@images, @kwargs).properties
else
require 'compass/sass_extensions/sprites/layout/vertical'
@images, @width, @height = Layout::Vertical.new(@images, @kwargs).properties
end
end
end
end
end
end
1.0.3~dfsg/cli/lib/compass/sass_extensions/sprites/sprite_methods.rb 0000644 0000000 0000000 00000010046 12456054517 024550 0 ustar root root module Compass
module SassExtensions
module Sprites
module SpriteMethods
# Changing this string will invalidate all previously generated sprite images.
# We should do so only when the packing algorithm changes
SPRITE_VERSION = "2"
# Calculates the overal image dimensions
# collects image sizes and input parameters for each sprite
# Calculates the height
def compute_image_metadata!
@width = 0
init_images
compute_image_positions!
init_engine
end
def init_engine
@engine = eval("::Compass::SassExtensions::Sprites::#{modulize}Engine.new(nil, nil, nil)")
@engine.width = @width
@engine.height = @height
@engine.images = @images
end
# Creates the Sprite::Image objects for each image and calculates the width
def init_images
@images = Images.new
image_names.each do |relative_file|
@images << Image.new(self, relative_file, kwargs)
end
unless sort_method == 'none'
@images.sort_by! sort_method
end
end
def name_and_hash
"#{path}-s#{uniqueness_hash}.png"
end
# The on-the-disk filename of the sprite
def filename
File.join(Compass.configuration.generated_images_path, name_and_hash)
end
def relativize(path)
Pathname.new(path).relative_path_from(Pathname.new(Dir.pwd)).to_s rescue path
end
# Generate a sprite image if necessary
def generate
if generation_required?
if kwargs.get_var('cleanup').value
cleanup_old_sprites
end
engine.construct_sprite
Compass.configuration.run_sprite_generated(engine.canvas)
save!
else
log :unchanged, filename
end
end
def cleanup_old_sprites
Sass::Util.glob(File.join(Compass.configuration.generated_images_path, "#{path}-s*.png")).each do |file|
log :remove, file
FileUtils.rm file
Compass.configuration.run_sprite_removed(file)
end
end
# Does this sprite need to be generated
def generation_required?
!File.exists?(filename) || outdated? || options[:force]
end
# Returns the uniqueness hash for this sprite object
def uniqueness_hash
@uniqueness_hash ||= begin
sum = Digest::MD5.new
sum << SPRITE_VERSION
sum << path
sum << layout
images.each do |image|
[:relative_file, :height, :width, :repeat, :spacing, :position, :digest].each do |attr|
sum << image.send(attr).to_s
end
end
sum.hexdigest[0...10]
end
@uniqueness_hash
end
# Saves the sprite engine
def save!
FileUtils.mkdir_p(File.dirname(filename))
saved = engine.save(filename)
log :create, filename
Compass.configuration.run_sprite_saved(filename)
@mtime = nil if saved
saved
end
# All the full-path filenames involved in this sprite
def image_filenames
@images.map(&:file)
end
# Checks whether this sprite is outdated
def outdated?
if File.exists?(filename)
return @images.any? {|image| image.mtime.to_i > self.mtime.to_i }
end
true
end
# Mtime of the sprite file
def mtime
@mtime ||= File.mtime(filename)
end
# Calculate the size of the sprite
def size
[width, height]
end
def log(action, filename, *extra)
if options[:compass] && options[:compass][:logger] && !options[:quiet]
options[:compass][:logger].record(action, relativize(filename), *extra)
end
end
end
end
end
end
1.0.3~dfsg/cli/lib/compass/sass_extensions/sprites/engines/ 0000755 0000000 0000000 00000000000 12456054517 022621 5 ustar root root 1.0.3~dfsg/cli/lib/compass/sass_extensions/sprites/engines/chunky_png_engine.rb 0000644 0000000 0000000 00000001744 12456054517 026646 0 ustar root root begin
require 'oily_png'
rescue LoadError
require 'chunky_png'
end
module Compass
module SassExtensions
module Sprites
class ChunkyPngEngine < Compass::SassExtensions::Sprites::Engine
def construct_sprite
@canvas = ChunkyPNG::Image.new(width, height, ChunkyPNG::Color::TRANSPARENT)
images.each do |image|
input_png = begin
ChunkyPNG::Image.from_file(image.file)
rescue ChunkyPNG::SignatureMismatch
raise Compass::SpriteException, "You have provided a file that does not have a PNG signature. Only PNG files are supported by the default sprite engine"
end
canvas.replace! input_png, image.left, image.top
end
end
def save(filename)
if canvas.nil?
construct_sprite
end
canvas.save(filename, Compass.configuration.chunky_png_options)
end
end
end
end
end 1.0.3~dfsg/cli/lib/compass/sass_extensions/sprites/images.rb 0000644 0000000 0000000 00000001251 12456054517 022762 0 ustar root root module Compass
module SassExtensions
module Sprites
class Images < Array
def sort_by!(method)
invert = false
if method.to_s[0] == '!'[0] # have todo this for 1.8.7 compat
method = method.to_s[1..-1]
invert = true
end
method = method.to_sym
self.sort! do |a, b|
unless a.send(method) == b.send(method)
a.send(method) <=> b.send(method)
else
other = ([:size, :name] - [method]).first
a.send(other) <=> b.send(other)
end
end
self.reverse! if invert
end
end
end
end
end 1.0.3~dfsg/cli/lib/compass/sass_extensions/sprites/layout.rb 0000644 0000000 0000000 00000001625 12456054517 023037 0 ustar root root require 'rational'
module Compass
module SassExtensions
module Sprites
module Layout
class SpriteLayout
attr_reader :images, :options
attr_accessor :height, :width
def initialize(images, kwargs={})
@images = images
@options = kwargs
@height = 0
@width = 0
layout!
end
def layout!
raise Compass::SpriteException, "You must impliment layout!"
end
def properties
if @width.zero?
raise Compass::SpriteException, "You must set the width fetching the properties"
end
if @height.zero?
raise Compass::SpriteException, "You must set the height fetching the properties"
end
[@images, @width, @height]
end
end
end
end
end
end 1.0.3~dfsg/cli/lib/compass/sass_extensions/sprites/image_methods.rb 0000644 0000000 0000000 00000003003 12456054517 024317 0 ustar root root module Compass
module SassExtensions
module Sprites
module ImageMethods
# Fetches the Sprite::Image object for the supplied name
def image_for(name)
if name.is_a?(Sass::Script::Value::String)
name = name.value
end
name = name.to_s
@images.detect { |img| img.name.downcase == name.downcase}
end
# Returns true if the image name has a hover selector image
def has_hover?(name)
!get_magic_selector_image(name, 'hover').nil?
end
# Returns true if the image name has a target selector image
def has_target?(name)
!get_magic_selector_image(name, 'target').nil?
end
# Returns true if the image name has a focus selector image
def has_focus?(name)
!get_magic_selector_image(name, 'focus').nil?
end
# Returns true if the image name has an active selector image
def has_active?(name)
!get_magic_selector_image(name, 'active').nil?
end
SEPERATORS = ['_', '-']
def get_magic_selector_image(name, selector)
SEPERATORS.each do |seperator|
file = image_for("#{name}#{seperator}#{selector}")
return file if !file.nil?
end
nil
end
# Return and array of image names that make up this sprite
def sprite_names
image_names.map { |f| File.basename(f, '.png') }
end
end
end
end
end
1.0.3~dfsg/cli/lib/compass/sass_extensions/sprites/engines.rb 0000644 0000000 0000000 00000001155 12456054517 023150 0 ustar root root module Compass
module SassExtensions
module Sprites
class Engine
attr_accessor :width, :height, :images, :canvas
def initialize(width, height, images)
@width, @height, @images = width, height, images
@canvas = nil
end
def construct_sprite
raise ::Compass::Error, "You must implement construct_sprite"
end
def save(filename)
raise ::Compass::Error, "You must implement save(filename)"
end
end
end
end
end
require 'compass/sass_extensions/sprites/engines/chunky_png_engine'
1.0.3~dfsg/cli/lib/compass/sass_extensions/functions.rb 0000644 0000000 0000000 00000000517 12456054517 022040 0 ustar root root module Compass::SassExtensions::Functions
module SassDeclarationHelper
def declare(*args)
Sass::Script::Functions.declare(*args)
end
end
end
%w(sprites).each do |func|
require "compass/sass_extensions/functions/#{func}"
end
module Sass::Script::Functions
include Compass::SassExtensions::Functions::Sprites
end
1.0.3~dfsg/cli/lib/compass/sass_extensions/sprites.rb 0000644 0000000 0000000 00000001222 12456054517 021513 0 ustar root root require 'digest/md5'
require 'compass/sprite_importer'
module Compass
module SassExtensions
module Sprites
end
end
end
require 'compass/sass_extensions/sprites/images'
require 'compass/sass_extensions/sprites/layout'
require 'compass/sass_extensions/sprites/image_row'
require 'compass/sass_extensions/sprites/row_fitter'
require 'compass/sass_extensions/sprites/image'
require 'compass/sass_extensions/sprites/layout_methods'
require 'compass/sass_extensions/sprites/sprite_methods'
require 'compass/sass_extensions/sprites/image_methods'
require 'compass/sass_extensions/sprites/sprite_map'
require 'compass/sass_extensions/sprites/engines'
1.0.3~dfsg/cli/lib/compass/sass_extensions/functions/ 0000755 0000000 0000000 00000000000 12456054517 021510 5 ustar root root 1.0.3~dfsg/cli/lib/compass/sass_extensions/functions/sprites.rb 0000644 0000000 0000000 00000024466 12456054517 023542 0 ustar root root module Compass::SassExtensions::Functions::Sprites
extend Compass::SassExtensions::Functions::SassDeclarationHelper
extend Sass::Script::Value::Helpers
include Sass::Script::Value::Helpers
ZERO = number(0)
BOOL_FALSE = bool(false)
VALID_SELECTORS = %w(hover active target focus)
# Provides a consistent interface for getting a variable in ruby
# from a keyword argument hash that accounts for underscores/dash equivalence
# and allows the caller to pass a symbol instead of a string.
module VariableReader
def get_var(variable_name)
self[variable_name.to_s.gsub(/-/,"_")]
end
end
# Returns the width of the generated sprite map
def sprite_width(map, sprite=nil)
verify_map(map, 'sprite-width')
file = get_sprite_file(map, sprite)
width, _ = image_dimensions(file)
number(width, "px")
end
declare :sprite_width, [:map]
declare :sprite_width, [:map, :sprite]
# Returns the height of the generated sprite map
def sprite_height(map, sprite=nil)
verify_map(map, 'sprite-height')
file = get_sprite_file(map, sprite)
_, height = image_dimensions(file)
number(height, "px")
end
declare :sprite_height, [:map]
declare :sprite_height, [:map, :sprite]
# Returns a list of all sprite names
def sprite_names(map)
verify_map(map, 'sprite-names')
list(map.sprite_names.map { |f| identifier(f) }, :comma)
end
declare :sprite_names, [:map]
# Returns the system path of the sprite file
def sprite_path(map)
verify_map(map, 'sprite-path')
identifier(map.filename)
end
declare :sprite_path, [:map]
# Returns the sprite file as an inline image
# @include "icon/*.png";
# #{$icon-sprite-base-class} {
# background-image: inline-sprite($icon-sprites);
# }
def inline_sprite(map)
verify_map(map, "sprite-url")
map.generate
path = map.filename
inline_image_string(data(path), compute_mime_type(path))
end
declare :inline_sprite, [:map]
# Creates a Compass::SassExtensions::Sprites::SpriteMap object. A sprite map, when used in a property is the same
# as calling sprite-url. So the following background properties are equivalent:
#
# $icons: sprite-map("icons/*.png");
# background: sprite-url($icons) no-repeat;
# background: $icons no-repeat;
#
# The sprite map object will generate the sprite map image, if necessary,
# the first time it is converted to a url. Simply constructing it has no side-effects.
def sprite_map(glob, kwargs = {})
kwargs.extend VariableReader
Compass::SassExtensions::Sprites::SpriteMap.from_uri(glob, self, kwargs)
end
declare :sprite_map, [:glob], :var_kwargs => true
# Returns the image and background position for use in a single shorthand property:
#
# $icons: sprite-map("icons/*.png"); // contains icons/new.png among others.
# background: sprite($icons, new) no-repeat;
#
# Becomes:
#
# background: url('/images/icons.png?12345678') 0 -24px no-repeat;
#
# If the `use_percentages` parameter is passed as true, percentages will be
# used to position the sprite. Example output:
#
# background: url('/images/icons.png?12345678') 0 50% no-repeat;
#
def sprite(map, sprite, offset_x = ZERO, offset_y = ZERO, use_percentages = BOOL_FALSE)
sprite = convert_sprite_name(sprite)
verify_map(map)
verify_sprite(sprite)
url = sprite_url(map)
position = sprite_position(map, sprite, offset_x, offset_y, use_percentages)
list([url] + position.value, :space)
end
declare :sprite, [:map, :sprite]
declare :sprite, [:map, :sprite, :offset_x]
declare :sprite, [:map, :sprite, :offset_x, :offset_y]
declare :sprite, [:map, :sprite, :offset_x, :offset_y, :use_percentages]
# Returns the name of a sprite map
# The name is derived from the folder than contains the sprites.
def sprite_map_name(map)
verify_map(map, "sprite-map-name")
identifier(map.name)
end
declare :sprite_name, [:sprite]
# Returns the path to the original image file for the sprite with the given name
def sprite_file(map, sprite)
sprite = convert_sprite_name(sprite)
verify_map(map, "sprite")
verify_sprite(sprite)
if image = map.image_for(sprite.value)
image_path = Pathname.new(File.expand_path(image.file))
images_path = Pathname.new(File.expand_path(Compass.configuration.images_path))
quoted_string(image_path.relative_path_from(images_path).to_s)
else
missing_image!(map, sprite)
end
end
declare :sprite_file, [:map, :sprite]
# Returns boolean if sprite has a parent
def sprite_does_not_have_parent(map, sprite)
sprite = convert_sprite_name(sprite)
verify_map map
verify_sprite sprite
bool(map.image_for(sprite.value).parent.nil?)
end
declare :sprite_does_not_have_parent, [:map, :sprite]
#return the name of the selector file
def sprite_selector_file(map, sprite, selector)
sprite = convert_sprite_name(sprite)
image = map.image_for(sprite)
if map.send(:"has_#{selector.value}?", sprite.value)
return identifier(image.send(selector.value).name)
end
raise Sass::SyntaxError, "Sprite: #{sprite.value} does not have a #{selector} state"
end
declare :sprite_selector_file, [:map, :sprite, :selector]
# Returns boolean if sprite has the selector
def sprite_has_selector(map, sprite, selector)
sprite = convert_sprite_name(sprite)
verify_map map
verify_sprite sprite
unless VALID_SELECTORS.include?(selector.value)
raise Sass::SyntaxError, "Invalid Selctor did you mean one of: #{VALID_SELECTORS.join(', ')}"
end
bool map.send(:"has_#{selector.value}?", sprite.value)
end
declare :sprite_has_selector, [:map, :sprite, :selector]
# Determines if the CSS selector is valid
IDENTIFIER_RX = /\A#{Sass::SCSS::RX::IDENT}\Z/
def sprite_has_valid_selector(selector)
unless selector.value =~ IDENTIFIER_RX
raise Sass::SyntaxError, "#{selector} must be a legal css identifier"
end
bool true
end
# Returns a url to the sprite image.
def sprite_url(map)
verify_map(map, "sprite-url")
map.generate
generated_image_url(identifier("#{map.path}-s#{map.uniqueness_hash}.png"))
end
declare :sprite_url, [:map]
# Returns the position for the original image in the sprite.
# This is suitable for use as a value to background-position:
#
# $icons: sprite-map("icons/*.png");
# background-position: sprite-position($icons, new);
#
# Might generate something like:
#
# background-position: 0 -34px;
#
# You can adjust the background relative to this position by passing values for
# `$offset-x` and `$offset-y`:
#
# $icons: sprite-map("icons/*.png");
# background-position: sprite-position($icons, new, 3px, -2px);
#
# Would change the above output to:
#
# background-position: 3px -36px;
#
# If you set the `use_percentages` parameter to true, the position will be
# expressed in percentages. An example:
#
# background-position: sprite-position($icons, new, 0, 0, true);
#
# Would result in something like this:
#
# background-position: 0 42%;
#
def sprite_position(map, sprite = nil, offset_x = ZERO, offset_y = ZERO, use_percentages = BOOL_FALSE)
assert_type offset_x, :Number
assert_type offset_y, :Number
sprite = convert_sprite_name(sprite)
verify_map(map, "sprite-position")
unless sprite.is_a?(Sass::Script::Value::String) || sprite.is_a?(Sass::Script::Value::Number)
raise Sass::SyntaxError, %Q(The second argument to sprite-position must be a sprite name. See http://beta.compass-style.org/help/tutorials/spriting/ for more information.)
end
image = map.image_for(sprite.value)
unless image
missing_image!(map, sprite)
end
if use_percentages.value
xdivis = map.width - image.width;
x = (offset_x.value + image.left.to_f) / (xdivis.nonzero? || 1) * 100
x = x == 0 ? number(x) : number(x, "%")
ydivis = map.height - image.height;
y = (offset_y.value + image.top.to_f) / (ydivis.nonzero? || 1) * 100
y = y == 0 ? number(y) : number(y, "%")
else
if offset_x.unit_str == "%"
x = offset_x # CE: Shouldn't this be a percentage of the total width?
else
x = offset_x.value - image.left
x = x == 0 ? number(x) : number(x, "px")
end
y = offset_y.value - image.top
y = y == 0 ? number(y) : number(y, "px")
end
list(x, y, :space)
end
declare :sprite_position, [:map]
declare :sprite_position, [:map, :sprite]
declare :sprite_position, [:map, :sprite, :offset_x]
declare :sprite_position, [:map, :sprite, :offset_x, :offset_y]
declare :sprite_position, [:map, :sprite, :offset_x, :offset_y, :use_percentages]
protected
def get_sprite_file(map, sprite=nil)
if sprite
map.image_for(sprite).file
else
map.filename
end
end
def reversed_color_names
if Sass::Script::Value::Color.const_defined?(:HTML4_COLORS_REVERSE)
Sass::Script::Value::Color::HTML4_COLORS_REVERSE
else
Sass::Script::Value::Color::COLOR_NAMES_REVERSE
end
end
def convert_sprite_name(sprite)
case sprite
when Sass::Script::Value::Color
rgb = if reversed_color_names.keys.first.size == 3
sprite.rgb
else
# Sass 3.3 includes the alpha channel
sprite.rgba
end
identifier(reversed_color_names[rgb])
when Sass::Script::Value::Bool
identifier(sprite.to_s)
else
sprite
end
end
def verify_map(map, error = "sprite")
unless map.is_a?(Compass::SassExtensions::Sprites::SpriteMap)
missing_sprite!(error)
end
end
def verify_sprite(sprite)
unless sprite.is_a?(Sass::Script::Value::String) || sprite.is_a?(Sass::Script::Value::Number)
raise Sass::SyntaxError, %Q(The second argument to sprite() must be a sprite name. See http://beta.compass-style.org/help/tutorials/spriting/ for more information.)
end
end
def missing_image!(map, sprite)
raise Sass::SyntaxError, "No sprite called #{sprite} found in sprite map #{map.path}/#{map.name}. Did you mean one of: #{map.sprite_names.join(", ")}"
end
def missing_sprite!(function_name)
raise Sass::SyntaxError, %Q(The first argument to #{function_name}() must be a sprite map. See http://beta.compass-style.org/help/tutorials/spriting/ for more information.)
end
end
1.0.3~dfsg/cli/lib/compass/configuration/ 0000755 0000000 0000000 00000000000 12456054517 017117 5 ustar root root 1.0.3~dfsg/cli/lib/compass/configuration/serialization.rb 0000644 0000000 0000000 00000006326 12456054517 022330 0 ustar root root module Compass
module Configuration
# The serialization module manages reading and writing the configuration file(s).
module Serialization
def parse(config_file)
raise Compass::Error, "Compass.configuration.parse(filename) has been removed. Please call Compass.add_project_configuration(filename) instead."
end
# parses a configuration file which is a ruby script
def _parse(config_file)
unless File.readable?(config_file)
raise Compass::Error, "Configuration file, #{config_file}, not found or not readable."
end
open(config_file) do |f|
parse_string(f.read, config_file)
end
end
def get_binding
binding
end
def parse_string(contents, filename)
bind = get_binding
eval(contents, bind, filename)
local_vars_set = eval("local_variables", bind)
local_vars_set.each do |local_var|
if (ATTRIBUTES+ARRAY_ATTRIBUTES).include?(local_var.to_sym)
value = eval(local_var.to_s, bind)
value = value.to_s if value.is_a?(Pathname)
self.send("#{local_var}=", value)
end
end
if @added_import_paths
@added_import_paths.each do |p|
self.additional_import_paths << p unless self.additional_import_paths.include?(p)
end
end
issue_deprecation_warnings
end
def serialize
contents = ""
(required_libraries || []).each do |lib|
contents << %Q{require '#{lib}'\n}
end
unless (required_libraries || []).include?("compass/import-once/activate") ||
(required_libraries || []).include?("compass/import-once")
contents << "require 'compass/import-once/activate'\n"
end
(loaded_frameworks || []).each do |lib|
contents << %Q{load '#{lib}'\n}
end
(framework_path || []).each do |lib|
contents << %Q{discover '#{lib}'\n}
end
contents << "# Require any additional compass plugins here.\n"
contents << "\n" if (required_libraries || []).any?
(ATTRIBUTES + ARRAY_ATTRIBUTES).each do |prop|
value = send("#{prop}_without_default")
if value.is_a?(Proc)
$stderr.puts "WARNING: #{prop} is code and cannot be written to a file. You'll need to copy it yourself."
end
if respond_to?("comment_for_#{prop}")
contents << "\n"
contents << send("comment_for_#{prop}")
end
if block_given? && (to_emit = yield(prop, value))
contents << to_emit
else
contents << serialize_property(prop, value) unless value.nil?
end
end
contents
end
def serialize_property(prop, value)
if value.respond_to?(:serialize_to_config)
value.serialize_to_config(prop) + "\n"
else
%Q(#{prop} = #{value.inspect}\n)
end
end
def issue_deprecation_warnings
if http_images_path == :relative
$stderr.puts "DEPRECATION WARNING: Please set relative_assets = true to enable relative paths."
end
end
end
class Data
include Serialization
end
end
end
1.0.3~dfsg/cli/lib/compass/configuration/comments.rb 0000644 0000000 0000000 00000003345 12456054517 021276 0 ustar root root module Compass
module Configuration
# Comments are emitted into the configuration file when serialized and make it easier to understand for new users.
module Comments
def comment_for_http_path
unless top_level.http_path_without_default
"# Set this to the root of your project when deployed:\nhttp_path = #{top_level.http_path.to_s.inspect}\n"
else
""
end
end
def comment_for_relative_assets
unless top_level.relative_assets
%q{# To enable relative paths to assets via compass helper functions. Uncomment:
# relative_assets = true
}
else
""
end
end
def comment_for_line_comments
if top_level.line_comments
%q{# To disable debugging comments that display the original location of your selectors. Uncomment:
# line_comments = false
}
else
""
end
end
def comment_for_output_style
unless top_level.output_style_without_default
%Q{# You can select your preferred output style here (can be overridden via the command line):
# output_style = :expanded or :nested or :compact or :compressed
}
else
""
end
end
def comment_for_preferred_syntax
if top_level.preferred_syntax_without_default.nil? && top_level.sass_dir
%Q{
# If you prefer the indented syntax, you might want to regenerate this
# project again passing --syntax sass, or you can uncomment this:
# preferred_syntax = :sass
# and then run:
# sass-convert -R --from scss --to sass #{top_level.sass_dir} scss && rm -rf sass && mv scss sass
}
else
""
end
end
end
class Data
include Comments
end
end
end
1.0.3~dfsg/cli/lib/compass/configuration/file_data.rb 0000644 0000000 0000000 00000000766 12456054517 021365 0 ustar root root module Compass
module Configuration
class FileData < Data
def self.new_from_file(config_file, defaults = nil)
data = new(config_file)
data.with_defaults(defaults) do
data._parse(config_file)
end
data
end
def self.new_from_string(contents, filename, defaults = nil)
data = new(filename)
data.with_defaults(defaults) do
data.parse_string(contents, filename)
end
data
end
end
end
end
1.0.3~dfsg/cli/lib/compass/configuration/helpers.rb 0000644 0000000 0000000 00000010237 12456054517 021111 0 ustar root root module Compass
module Configuration
@callbacks_loaded = false
# The helpers are available as methods on the Compass module. E.g. Compass.configuration
module Helpers
def configuration_for(config, filename = nil, defaults = nil)
if config.nil?
nil
elsif config.is_a?(Compass::Configuration::Data)
config
elsif config.instance_of?(Hash)
Compass::Configuration::Data.new(filename, config)
elsif config.respond_to?(:read)
filename ||= config.to_s if config.is_a?(Pathname)
Compass::Configuration::FileData.new_from_string(config.read, filename, defaults)
elsif config.is_a?(Hash)
Compass::Configuration::Data.new(filename, config)
elsif config.is_a?(String)
Compass::Configuration::FileData.new_from_file(config, defaults)
elsif config.is_a?(Symbol)
Compass::AppIntegration.lookup(config).configuration
else
raise "I don't know what to do with: #{config.inspect}"
end
end
def sass_plugin_configuration
configuration.to_sass_plugin_options
end
def configure_sass_plugin!
require 'sass/plugin'
config = sass_plugin_configuration
locations = config.delete(:template_location)
Sass::Plugin.options.merge!(config)
locations.each do |sass_dir, css_dir|
unless Sass::Plugin.engine_options[:load_paths].include?(sass_dir)
Sass::Plugin.add_template_location sass_dir, css_dir
end
end
unless @callbacks_loaded
on_saved = Proc.new do |sass_file, css_file|
Compass.configuration.run_stylesheet_saved(css_file)
end
if Sass::Plugin.respond_to?(:on_updated_stylesheet)
Sass::Plugin.on_updated_stylesheet(&on_saved)
else
Sass::Plugin.on_updating_stylesheet(&on_saved)
end
Sass::Plugin.on_compilation_error do |e, filename, css|
Compass.configuration.run_stylesheet_error(filename, e.message)
end
@callbacks_loaded = true
end
end
def sass_engine_options
configuration.to_sass_engine_options
end
# Read the configuration file for this project
def add_project_configuration(*args)
options = args.last.is_a?(Hash) ? args.pop : {}
configuration_file_path = args.shift || detect_configuration_file
raise ArgumentError, "Too many arguments" if args.any?
if AppIntegration.default? && data = configuration_for(configuration_file_path, nil, configuration_for(options[:defaults]))
if data.raw_project_type
add_configuration(data.raw_project_type.to_sym)
elsif options[:project_type]
add_configuration(options[:project_type])
else
add_configuration(:stand_alone)
end
add_configuration(data)
else
add_configuration(options[:project_type] || configuration.project_type_without_default || (yield if block_given?) || :stand_alone)
end
end
# TODO: Deprecate the src/config.rb location.
KNOWN_CONFIG_LOCATIONS = ['config/compass.rb', ".compass/config.rb", "config/compass.config", "config.rb", "src/config.rb"]
# Finds the configuration file, if it exists in a known location.
def detect_configuration_file(project_path = nil)
possible_files = KNOWN_CONFIG_LOCATIONS.map{|f| projectize(f, project_path) }
possible_files.detect{|f| File.exists?(f)}
end
def handle_configuration_change!
if (compiler = Compass.compiler).new_config?
compiler.clean!
end
end
# @deprecated
def compiler
Compass::Deprecation.deprecated!(:compiler_accessor,
"Compass.compiler is deprecated. Use Compass.sass_compiler instead.")
Compass::Deprecation.mark_as_issued(:compass_compiler_constructor)
Compass::Compiler.new(*Compass.configuration.to_compiler_arguments)
end
def sass_compiler(*args)
Compass::SassCompiler.new(*args)
end
end
end
extend Configuration::Helpers
end
1.0.3~dfsg/cli/lib/compass/validator.rb 0000644 0000000 0000000 00000000715 12456054517 016565 0 ustar root root begin
require 'rubygems'
require 'compass-validator'
rescue LoadError => e
if e.message =~ /core_ext/
raise Compass::MissingDependency, <<-ERRORMSG
The Compass CSS Validator is out of date. Please upgrade it:
sudo gem install compass-validator --version ">= 3.0.1"
ERRORMSG
else
raise Compass::MissingDependency, <<-ERRORMSG
The Compass CSS Validator could not be loaded. Please install it:
sudo gem install compass-validator
ERRORMSG
end
end
1.0.3~dfsg/cli/lib/compass/version.rb 0000644 0000000 0000000 00000002367 12456054517 016272 0 ustar root root require 'compass/generated_version'
module Compass
module Version
def scope(file) # :nodoc:
File.join(File.dirname(__FILE__), '..', '..', file)
end
def parse_version(version, name)
nil_or_int = lambda{|i| i.nil? ? nil : i.to_i}
segments = version.split(".")
{
:string => version,
:name => name,
:major => nil_or_int.call(segments.shift),
:minor => nil_or_int.call(segments.shift),
:patch => nil_or_int.call(segments.shift),
:state => segments.shift,
:iteration => nil_or_int.call(segments.shift)
}
end
# Returns a hash representing the version.
# The :major, :minor, and :teeny keys have their respective numbers.
# The :string key contains a human-readable string representation of the version.
# The :rev key will have the current revision hash.
#
# This method swiped from Haml and then modified, some credit goes to Nathan Weizenbaum
def version
Compass::VERSION_DETAILS
end
end
extend Compass::Version
unless defined?(::Compass::VERSION)
VERSION = File.read(scope("VERSION")).strip
VERSION_NAME = File.read(scope("VERSION_NAME")).strip
end
VERSION_DETAILS = parse_version(VERSION, VERSION_NAME)
end
1.0.3~dfsg/cli/lib/compass/generated_version.rb 0000644 0000000 0000000 00000000201 12456054517 020271 0 ustar root root module Compass
# This file intentionall does nothing.
# The compass build scripts put the release VERSION constant here.
end
1.0.3~dfsg/cli/lib/compass/quick_cache.rb 0000644 0000000 0000000 00000000665 12456054517 017043 0 ustar root root module QuickCache
# cache a value in memory for just a few seconds
# This can speed up reads of values that change relatively infrequently
# but might be read many times in a short burst of reads.
def quick_cache(key, ttl = 1)
@quick_cache ||= {}
if @quick_cache[key] && @quick_cache[key].first > Time.now - ttl
@quick_cache[key].last
else
(@quick_cache[key] = [Time.now, yield]).last
end
end
end
1.0.3~dfsg/cli/lib/compass/dependencies.rb 0000644 0000000 0000000 00000000371 12456054517 017224 0 ustar root root begin
require 'sass'
rescue LoadError
require 'rubygems'
begin
require 'sass'
rescue LoadError
puts "Unable to load Sass. Please install it with one of the following commands:"
puts " gem install sass --pre"
raise
end
end
1.0.3~dfsg/cli/lib/compass/commands.rb 0000644 0000000 0000000 00000000655 12456054517 016404 0 ustar root root module Compass::Commands
end
require 'compass/commands/registry'
%w(base project_base default help list_frameworks
update_project watch_project create_project clean_project extension_command
imports installer_command print_version project_stats stamp_pattern
sprite validate_project write_configuration interactive unpack_extension
).each do |lib|
require "compass/commands/#{lib}"
end
Compass.discover_extensions! 1.0.3~dfsg/cli/lib/compass/exec.rb 0000644 0000000 0000000 00000001002 12456054517 015512 0 ustar root root require 'compass/dependencies'
require 'optparse'
require 'compass/logger'
require 'compass/errors'
require 'compass/actions'
require 'compass/installers'
require 'compass/commands'
require 'rbconfig'
require 'pathname'
begin
require 'win32console' if RbConfig::CONFIG['host_os'] =~ /mswin|mingw/
rescue LoadError
$boring = true
end
module Compass::Exec
end
%w(helpers sub_command_ui
global_options_parser project_options_parser
command_option_parser).each do |lib|
require "compass/exec/#{lib}"
end
1.0.3~dfsg/cli/lib/compass/sprite_importer.rb 0000644 0000000 0000000 00000006507 12456054517 020034 0 ustar root root require 'erb'
require 'compass/sprite_importer/binding'
module Compass
class SpriteImporter < Sass::Importers::Base
VAILD_FILE_NAME = /\A#{Sass::SCSS::RX::IDENT}\Z/
SPRITE_IMPORTER_REGEX = %r{((.+/)?([^\*.]+))/(.+?)\.png}
VALID_EXTENSIONS = ['.png']
TEMPLATE_FOLDER = File.join(File.expand_path('../', __FILE__), 'sprite_importer')
CONTENT_TEMPLATE_FILE = File.join(TEMPLATE_FOLDER, 'content.erb')
CONTENT_TEMPLATE = ERB.new(File.read(CONTENT_TEMPLATE_FILE))
# finds all sprite files
def self.find_all_sprite_map_files(path)
hex = "[0-9a-f]"
glob = "*-s#{hex*10}{#{VALID_EXTENSIONS.join(",")}}"
Sass::Util.glob(File.join(path, "**", glob))
end
def find(uri, options)
if uri =~ SPRITE_IMPORTER_REGEX
return self.class.sass_engine(uri, self.class.sprite_name(uri), self, options)
end
nil
end
def find_relative(uri, base, options)
nil
end
def to_s
self.class.name
end
def hash
self.class.name.hash
end
def eql?(other)
other.class == self.class
end
def mtime(uri, options)
self.class.files(uri).sort.inject(Time.at(0)) do |max_time, file|
(t = File.mtime(file)) > max_time ? t : max_time
end
end
def key(uri, options={})
[self.class.name + ":sprite:" + File.dirname(File.expand_path(uri)), File.basename(uri)]
end
def public_url(*args)
nil
end
def self.path_and_name(uri)
if uri =~ SPRITE_IMPORTER_REGEX
[$1, $3]
else
raise Compass::Error, "invalid sprite path"
end
end
# Name of this spite
def self.sprite_name(uri)
_, name = path_and_name(uri)
name
end
# The on-disk location of this sprite
def self.path(uri)
path, _ = path_and_name(uri)
path
end
# Returns the Glob of image files for the uri
def self.files(uri)
Compass.configuration.sprite_load_path.compact.each do |folder|
files = Sass::Util.glob(File.join(folder, uri)).sort
next if files.empty?
return files
end
path = Compass.configuration.sprite_load_path.to_a.join(', ')
raise Compass::SpriteException, %Q{No files were found in the load path matching "#{uri}". Your current load paths are: #{path}}
end
# Returns an Array of image names without the file extension
def self.sprite_names(uri)
files(uri).collect do |file|
File.basename(file, '.png')
end
end
# Returns the sass_options for this sprite
def self.sass_options(uri, importer, options)
options.merge!(:filename => uri.gsub(%r{\*/},"*\\/"), :syntax => :scss, :importer => importer)
end
# Returns a Sass::Engine for this sprite object
def self.sass_engine(uri, name, importer, options)
content = content_for_images(uri, name, options[:skip_overrides])
Sass::Engine.new(content, sass_options(uri, importer, options))
end
# Generates the Sass for this sprite file
def self.content_for_images(uri, name, skip_overrides = false)
binder = Compass::Sprites::Binding.new(:name => name, :uri => uri, :skip_overrides => skip_overrides, :sprite_names => sprite_names(uri), :files => files(uri))
CONTENT_TEMPLATE.result(binder.get_binding)
end
end
end
1.0.3~dfsg/cli/lib/compass/errors.rb 0000644 0000000 0000000 00000000242 12456054517 016107 0 ustar root root require 'compass/error'
module Compass
class FilesystemConflict < Error
end
class MissingDependency < Error
end
class SpriteException < Error; end
end
1.0.3~dfsg/cli/lib/compass/installers.rb 0000644 0000000 0000000 00000000171 12456054517 016754 0 ustar root root %w(manifest template_context base manifest_installer bare_installer).each do |f|
require "compass/installers/#{f}"
end
1.0.3~dfsg/cli/lib/compass/rails.rb 0000644 0000000 0000000 00000000103 12456054517 015701 0 ustar root root # Rails requires compass by requiring this file.
require 'compass'
1.0.3~dfsg/cli/lib/compass/app_integration.rb 0000644 0000000 0000000 00000001454 12456054517 017764 0 ustar root root require "compass/app_integration/stand_alone"
module Compass
module AppIntegration
module Helpers
#attr_accessor :project_types
DEAFULT_PROJECT_TYPES = {
:stand_alone => "Compass::AppIntegration::StandAlone"
}
def init
@project_types ||= DEAFULT_PROJECT_TYPES.dup
end
def project_types
@project_types
end
def default?
@project_types.keys === DEAFULT_PROJECT_TYPES.keys
end
def lookup(type)
unless @project_types[type].nil?
eval @project_types[type]
else
raise Compass::Error, "No application integration exists for #{type}"
end
end
def register(type, klass)
@project_types[type] = klass
end
end
extend Helpers
init
end
end
1.0.3~dfsg/cli/lib/compass/sprite_importer/ 0000755 0000000 0000000 00000000000 12456054517 017477 5 ustar root root 1.0.3~dfsg/cli/lib/compass/sprite_importer/binding.rb 0000644 0000000 0000000 00000000231 12456054517 021432 0 ustar root root require 'ostruct'
module Compass
module Sprites
class Binding < OpenStruct
def get_binding
binding
end
end
end
end 1.0.3~dfsg/cli/lib/compass/sprite_importer/content.erb 0000644 0000000 0000000 00000010540 12456054517 021643 0 ustar root root @import "compass/utilities/sprites/base";
// General Sprite Defaults
// You can override them before you import this file.
$<%= name %>-sprite-dimensions : false !default;
$<%= name %>-use-percentages : false !default;
$<%= name %>-position : 0% !default;
$<%= name %>-spacing : 0 !default;
$<%= name %>-repeat : no-repeat !default;
$<%= name %>-prefix : '' !default;
$<%= name %>-clean-up : true !default;
$<%= name %>-layout : vertical !default;
$<%= name %>-inline : false !default;
$<%= name %>-sort-by : 'none' !default;
$<%= name %>-class-separator : $default-sprite-separator !default;
$<%= name %>-sprite-base-class : ".<%= name %>#{$<%= name %>-class-separator}sprite" !default;
<% if skip_overrides %>
$<%= name %>-sprites: sprite-map("<%= uri %>", $layout: $<%= name %>-layout, $cleanup: $<%= name %>-clean-up, $spacing: $<%= name %>-spacing, $position : $<%= name %>-position);
<% else %>
// These variables control the generated sprite output
// You can override them selectively before you import this file.
<% sprite_names.each do |sprite_name| %>
$<%= name %>-<%= sprite_name %>-position: $<%= name %>-position !default;
$<%= name %>-<%= sprite_name %>-spacing: $<%= name %>-spacing !default;
$<%= name %>-<%= sprite_name %>-repeat: $<%= name %>-repeat !default;
<% end %>
$<%= name %>-sprites: sprite-map("<%= uri %>",
<% sprite_names.each do |sprite_name| %>
$<%= name %>-<%= sprite_name %>-position: $<%= name %>-<%= sprite_name %>-position,
$<%= name %>-<%= sprite_name %>-spacing: $<%= name %>-<%= sprite_name %>-spacing,
$<%= name %>-<%= sprite_name %>-repeat: $<%= name %>-<%= sprite_name %>-repeat,
<% end %>
$layout : $<%= name %>-layout,
$cleanup : $<%= name %>-clean-up,
$spacing : $<%= name %>-spacing,
$position : $<%= name %>-position,
$sort-by : $<%= name %>-sort-by
);
<% end %>
// All sprites should extend this class
// The <%= name %>-sprite mixin will do so for you.
@if $<%= name %>-inline {
#{$<%= name %>-sprite-base-class} {
background-image: inline-sprite($<%= name %>-sprites);
}
} @else {
#{$<%= name %>-sprite-base-class} {
background-image: sprite-url($<%= name %>-sprites);
background-repeat: no-repeat;
}
}
//sass functions to return the dimensions of a sprite image as units
<% [:width, :height].each do |dimension| %>
@function <%= name %>-sprite-<%= dimension %>($name) {
@return sprite-<%= dimension %>($<%= name %>-sprites, $name);
}
<% end %>
// Use this to set the dimensions of an element
// based on the size of the original image.
@mixin <%= name %>-sprite-dimensions($name) {
@include sprite-dimensions($<%= name %>-sprites, $name)
}
// Move the background position to display the sprite.
@mixin <%= name %>-sprite-position($name, $offset-x: 0, $offset-y: 0, $use-percentages: $<%= name %>-use-percentages) {
@include sprite-background-position($<%= name %>-sprites, $name, $offset-x, $offset-y, $use-percentages)
}
// Extends the sprite base class and set the background position for the desired sprite.
// It will also apply the image dimensions if $dimensions is true.
@mixin <%= name %>-sprite($name, $dimensions: $<%= name %>-sprite-dimensions, $offset-x: 0, $offset-y: 0, $use-percentages: $<%= name %>-use-percentages, $separator: $<%= name %>-class-separator) {
@extend #{$<%= name %>-sprite-base-class};
@include sprite($<%= name %>-sprites, $name, $dimensions, $offset-x, $offset-y, $use-percentages, $separator: $separator);
}
@mixin <%= name %>-sprites($sprite-names, $dimensions: $<%= name %>-sprite-dimensions, $prefix: sprite-map-name($<%= name %>-sprites), $offset-x: 0, $offset-y: 0, $use-percentages: $<%= name %>-use-percentages, $separator: $<%= name %>-class-separator) {
@include sprites($<%= name %>-sprites, $sprite-names, $<%= name %>-sprite-base-class, $dimensions, $prefix, $offset-x, $offset-y, $use-percentages, $separator: $separator)
}
// Generates a class for each sprited image.
@mixin all-<%= name %>-sprites($dimensions: $<%= name %>-sprite-dimensions, $prefix: sprite-map-name($<%= name %>-sprites), $offset-x: 0, $offset-y: 0, $use-percentages: $<%= name %>-use-percentages, $separator: $<%= name %>-class-separator) {
@include <%= name %>-sprites(<%= sprite_names.join(" ") %>, $dimensions, $prefix, $offset-x, $offset-y, $use-percentages, $separator: $separator);
}
1.0.3~dfsg/cli/lib/compass/commands/ 0000755 0000000 0000000 00000000000 12456054517 016051 5 ustar root root 1.0.3~dfsg/cli/lib/compass/commands/clean_project.rb 0000644 0000000 0000000 00000004073 12456054517 021212 0 ustar root root require 'compass/commands/project_base'
require 'compass/compiler'
module Compass
module Commands
module CleanProjectOptionsParser
def set_options(opts)
opts.banner = %Q{
Usage: compass clean [path/to/project] [options]
Description:
Remove generated files and the sass cache.
Options:
}.split("\n").map{|l| l.gsub(/^ */,'')}.join("\n")
super
end
end
class CleanProject < UpdateProject
register :clean
def initialize(working_path, options)
super
assert_project_directory_exists!
end
def perform
compiler = new_compiler_instance
compiler.clean!
Compass::SpriteImporter.find_all_sprite_map_files(Compass.configuration.generated_images_path).each do |sprite|
remove sprite
end
end
def determine_cache_location
Compass.configuration.cache_path || Sass::Plugin.options[:cache_location] || File.join(working_path, ".sass-cache")
end
class << self
def option_parser(arguments)
parser = Compass::Exec::CommandOptionParser.new(arguments)
parser.extend(Compass::Exec::GlobalOptionsParser)
parser.extend(Compass::Exec::ProjectOptionsParser)
parser.extend(CleanProjectOptionsParser)
end
def usage
option_parser([]).to_s
end
def primary; true; end
def description(command)
"Remove generated files and the sass cache"
end
def parse!(arguments)
parser = option_parser(arguments)
parser.parse!
parse_arguments!(parser, arguments)
parser.options
end
def parse_arguments!(parser, arguments)
if arguments.size > 0
parser.options[:project_name] = arguments.shift if File.directory?(arguments.first)
unless arguments.empty?
parser.options[:sass_files] = arguments.dup
parser.options[:force] = true
end
end
end
end
end
end
end
1.0.3~dfsg/cli/lib/compass/commands/default.rb 0000644 0000000 0000000 00000002470 12456054517 020025 0 ustar root root module Compass
module Commands
module DefaultOptionsParser
def set_options(opts)
opts.on("--trace") do
self.options[:trace] = true
end
opts.on("-?", "-h", "--help") do
self.options[:command] = Proc.new do
Help.new(working_path, options.merge(:help_command => "help"))
end
end
opts.on("-q", "--quiet") do
self.options[:quiet] = true
end
opts.on("-v", "--version") do
self.options[:command] = Proc.new do
PrintVersion.new(working_path, options)
end
end
super
end
end
class Default < Base
class << self
def option_parser(arguments)
parser = Compass::Exec::CommandOptionParser.new(arguments)
parser.extend(DefaultOptionsParser)
end
# def usage
# $stderr.puts caller.join("\n")
# "XXX"
# end
def parse!(arguments)
parser = option_parser(arguments)
parser.parse!
parser.options[:command] ||= Proc.new do
Help.new(working_path, options.merge(:help_command => "help"))
end
parser.options
end
end
def execute
instance_eval(&options[:command]).execute
end
end
end
end
1.0.3~dfsg/cli/lib/compass/commands/project_structure.rb 0000644 0000000 0000000 00000005171 12456054517 022170 0 ustar root root require 'compass/commands/project_base'
require 'compass/commands/update_project'
module Compass
module Commands
module StructureOptionsParser
def set_options(opts)
opts.banner = %Q{
Usage: compass structure [path/to/project] [options]
Description:
Display the import structure of your stylesheets.
Options:
}.strip.split("\n").map{|l| l.gsub(/^ {0,10}/,'')}.join("\n")
super
end
end
class ProjectStats < UpdateProject
register :structure
def initialize(working_path, options)
super
assert_project_directory_exists!
end
def perform
@compiler = new_compiler_instance
(options[:sass_files] || sorted_sass_files).each do |sass_file|
print_tree(Compass.projectize(sass_file))
end
end
def print_tree(file, depth = 0, importer = @compiler.importer)
puts ((depth > 0 ? "| " : " ") * depth) + "+- " + Compass.deprojectize(file)
@compiler.staleness_checker.send(:compute_dependencies, file, importer).each do |(dep, dep_importer)|
print_tree(dep, depth + 1, dep_importer)# unless Compass.deprojectize(dep)[0...1] == "/"
end
end
def sorted_sass_files
sass_files = @compiler.sass_files
sass_files.map! do |s|
filename = Compass.deprojectize(s, File.join(Compass.configuration.project_path, Compass.configuration.sass_dir))
[s, File.dirname(filename), File.basename(filename)]
end
sass_files = sass_files.sort_by do |s,d,f|
File.join(d, f[0] == ?_ ? f[1..-1] : f)
end
sass_files.map!{|s,d,f| s}
end
class << self
def option_parser(arguments)
parser = Compass::Exec::CommandOptionParser.new(arguments)
parser.extend(Compass::Exec::GlobalOptionsParser)
parser.extend(Compass::Exec::ProjectOptionsParser)
parser.extend(StructureOptionsParser)
end
def usage
option_parser([]).to_s
end
def description(command)
"Report statistics about your stylesheets"
end
def primary; false; end
def parse!(arguments)
parser = option_parser(arguments)
parser.parse!
parse_arguments!(parser, arguments)
parser.options
end
def parse_arguments!(parser, arguments)
if arguments.size > 0
parser.options[:project_name] = arguments.shift if File.directory?(arguments.first)
parser.options[:sass_files] = arguments
end
end
end
end
end
end
1.0.3~dfsg/cli/lib/compass/commands/project_stats.rb 0000644 0000000 0000000 00000014313 12456054517 021264 0 ustar root root require 'compass/commands/project_base'
require 'compass/commands/update_project'
module Compass
module Commands
module StatsOptionsParser
def set_options(opts)
opts.banner = %Q{
Usage: compass stats [path/to/project] [options]
Description:
Compile project at the path specified (or the current
directory if not specified) and then compute statistics
for the sass and css files in the project.
Options:
}.strip.split("\n").map{|l| l.gsub(/^ {0,10}/,'')}.join("\n")
super
end
end
class ProjectStats < UpdateProject
register :stats
def initialize(working_path, options)
super
assert_project_directory_exists!
end
def perform
super
require 'compass/stats'
compiler = new_compiler_instance
sass_files = sorted_sass_files(compiler)
total_label = "Total (#{sass_files.size} files):"
rows = [[ :-, :-, :-, :-, :-, :-, :-, :-, :- ],
[ 'Filename', 'Rules', 'Properties', 'Mixins Defs', 'Mixins Used', 'Filesize', 'CSS Selectors', 'CSS Properties', 'CSS Filesize' ],
[ :-, :-, :-, :-, :-, :-, :-, :-, :- ]]
maximums = [ total_label.length, 5, 10, 14, 11, 13, 13, 14, 14 ]
alignments = [ :left, :right, :right, :right, :right, :right, :right, :right, :right ]
delimiters = [ ['| ', ' |'], [' ', ' |'], [' ', ' |'], [' ', ' |'], [' ', ' |'], [' ', ' |'], [' ', ' |'], [' ', ' |'], [' ', ' |'] ]
formatters = [ nil, nil, nil, nil, nil, :kb, nil, nil, :kb ]
totals = [ total_label, 0, 0, 0, 0, 0, 0, 0, 0 ]
columns = rows.first.size
sass_files.each do |sass_file|
css_file = compiler.corresponding_css_file(sass_file) unless sass_file[0..0] == '_'
row = filename_columns(sass_file)
row += sass_columns(sass_file)
row += css_columns(css_file)
row.each_with_index do |c, i|
maximums[i] = [maximums[i].to_i, c.size].max
totals[i] = totals[i] + c.to_i if i > 0
end
rows << row
end
rows << [:-] * columns
rows << totals.map{|t| t.to_s}
rows << [:-] * columns
rows.each do |row|
row.each_with_index do |col, i|
print pad(col, maximums[i], :align => alignments[i], :left => delimiters[i].first, :right => delimiters[i].last, :formatter => formatters[i])
end
print "\n"
end
if @missing_css_parser
puts "\nInstall #{@missing_css_parser} to enable stats on your css files:\n\n\tgem install #{@missing_css_parser}"
end
end
def pad(c, max, options = {})
options[:align] ||= :left
if c == :-
filler = '-'
c = ''
else
filler = ' '
end
c = send(:"format_#{options[:formatter]}", c) if options[:formatter]
spaces = max - c.size
filled = filler * [spaces,0].max
"#{options[:left]}#{filled if options[:align] == :right}#{c}#{filled if options[:align] == :left}#{options[:right]}"
end
def format_kb(v)
return v unless v =~ /^\d+$/
v = Integer(v)
if v < 1024
"#{v} B"
else
v = v / 1024.0
"#{v.ceil} KB"
end
end
def sorted_sass_files(compiler)
sass_files = compiler.sass_files
sass_files.map! do |s|
filename = Compass.deprojectize(s, File.join(Compass.configuration.project_path, Compass.configuration.sass_dir))
[s, File.dirname(filename), File.basename(filename)]
end
sass_files = sass_files.sort_by do |s,d,f|
File.join(d, f[0] == ?_ ? f[1..-1] : f)
end
sass_files.map!{|s,d,f| s}
end
def filename_columns(sass_file)
filename = Compass.deprojectize(sass_file, working_path)
[filename]
end
def sass_columns(sass_file)
sf = Compass::Stats::SassFile.new(sass_file)
sf.analyze!
%w(rule_count prop_count mixin_def_count mixin_count file_size).map do |t|
sf.send(t).to_s
end
end
def css_columns(css_file)
if File.exists?(css_file)
cf = Compass::Stats::CssFile.new(css_file)
cf.analyze!
%w(selector_count prop_count file_size).map do |t|
cf.send(t).to_s
end
else
return [ '--', '--' , '--']
end
rescue LoadError => e
@missing_css_parser = e.message =~ /iconv/ ? "iconv" : "css_parser"
return [ 'DISABLED', 'DISABLED', 'DISABLED' ]
end
class << self
def option_parser(arguments)
parser = Compass::Exec::CommandOptionParser.new(arguments)
parser.extend(Compass::Exec::GlobalOptionsParser)
parser.extend(Compass::Exec::ProjectOptionsParser)
parser.extend(StatsOptionsParser)
end
def usage
option_parser([]).to_s
end
def description(command)
"Report statistics about your stylesheets"
end
def primary; false; end
def parse!(arguments)
parser = option_parser(arguments)
parser.parse!
parse_arguments!(parser, arguments)
parser.options
end
def parse_arguments!(parser, arguments)
if arguments.size == 1
parser.options[:project_name] = arguments.shift
elsif arguments.size == 0
# default to the current directory.
else
raise Compass::Error, "Too many arguments were specified."
end
end
end
end
end
end
1.0.3~dfsg/cli/lib/compass/commands/list_frameworks.rb 0000644 0000000 0000000 00000001776 12456054517 021624 0 ustar root root module Compass
module Commands
class ListFrameworks < ProjectBase
attr_accessor :options
register :frameworks
def initialize(working_path, options)
super
end
def execute
if options[:quiet]
Compass::Frameworks::ALL.each do |framework|
puts framework.name unless framework.name =~ /^_/
end
else
puts "Available Frameworks & Patterns:\n\n"
puts Compass::Frameworks.pretty_print
end
end
class << self
def option_parser(arguments)
parser = Compass::Exec::CommandOptionParser.new(arguments)
parser.extend(Compass::Exec::GlobalOptionsParser)
end
def usage
option_parser([]).to_s
end
def description(command)
"List the available frameworks"
end
def parse!(arguments)
parser = option_parser(arguments)
parser.parse!
parser.options
end
end
end
end
end 1.0.3~dfsg/cli/lib/compass/commands/unpack_extension.rb 0000644 0000000 0000000 00000007525 12456054517 021764 0 ustar root root require 'compass/commands/project_base'
require 'fileutils'
module Compass
module Commands
module ExtensionOptionsParser
def set_options(opts)
opts.banner = %Q{
Usage: compass unpack EXTENSION
Description:
Copy an extension into your extensions folder for easy access to the source code.
This makes it easier to peruse the source in unfamiliar projects. It is not recommended
that you change other extensions' source -- this makes it hard to take updates from
the original author. The following extensions are available:
FRAMEWORKS
Options:
}.strip.split("\n").map{|l| l.gsub(/^ {0,10}/,'')}.join("\n")
opts.banner.gsub!(/FRAMEWORKS/,Compass::Frameworks.pretty_print(true))
super
end
end
class UnpackExtension < ProjectBase
register :unpack
def initialize(working_path, options)
super
assert_project_directory_exists!
end
def perform
framework = Compass::Frameworks[options[:framework]]
unless framework
raise Compass::Error, "No extension named \"#{options[:framework]}\" was found."
end
files = Dir["#{framework.path}/**/*"]
extension_dir = File.join(Compass.configuration.extensions_path, framework.name)
FileUtils.rm_rf extension_dir
FileUtils.mkdir_p extension_dir
write_file File.join(extension_dir, "DO_NOT_MODIFY"), readme(framework)
files.each do |f|
next if File.directory?(f)
ending = f[(framework.path.size+1)..-1]
destination = File.join(extension_dir, ending)
FileUtils.mkdir_p(File.dirname(destination))
copy f, destination
end
puts "\nYou have unpacked \"#{framework.name}\""
puts
puts readme(framework)
end
def readme(framework)
%Q{| This is a copy of the "#{framework.name}" extension.
|
| It now overrides the original which was found here:
|
| #{framework.path}
|
| Unpacking an extension is useful when you need to easily peruse the
| extension's source. You might find yourself tempted to change the
| stylesheets here. If you do this, you'll find it harder to take
| updates from the original author. Sometimes this seems like a good
| idea at the time, but in a few months, you'll probably regret it.
|
| In the future, if you take an update of this framework, you'll need to run
|
| compass unpack #{framework.name}
|
| again or remove this unpacked extension.
|}.gsub(/^\s*\| ?/,"")
end
def skip_extension_discovery?
true
end
class << self
def option_parser(arguments)
parser = Compass::Exec::CommandOptionParser.new(arguments)
parser.extend(Compass::Exec::GlobalOptionsParser)
parser.extend(Compass::Exec::ProjectOptionsParser)
parser.extend(ExtensionOptionsParser)
end
def usage
option_parser([]).to_s
end
def description(command)
"Copy an extension into your extensions folder."
end
def parse!(arguments)
parser = option_parser(arguments)
parser.parse!
parse_arguments!(parser, arguments)
parser.options
end
def parse_arguments!(parser, arguments)
if arguments.size == 1
parser.options[:framework] = arguments.shift
elsif arguments.size == 0
raise Compass::Error, "Please specify an extension to unpack."
else
raise Compass::Error, "Too many arguments were specified."
end
end
end
end
end
end
1.0.3~dfsg/cli/lib/compass/commands/interactive.rb 0000644 0000000 0000000 00000002444 12456054517 020717 0 ustar root root
require 'compass/commands/project_base'
require 'compass/commands/update_project'
module Compass
module Commands
module InteractiveOptionsParser
def set_options(opts)
opts.banner = %Q{
Usage: compass interactive [path/to/project] [options]
Description:
Interactively evaluate SassScript
Options:
}.strip.split("\n").map{|l| l.gsub(/^ {0,10}/,'')}.join("\n")
super
end
end
class Interactive < ProjectBase
register :interactive
def initialize(working_path, options)
super
end
def perform
require 'sass/repl'
Sass::Repl.new.run
end
class << self
def option_parser(arguments)
parser = Compass::Exec::CommandOptionParser.new(arguments)
parser.extend(Compass::Exec::GlobalOptionsParser)
parser.extend(Compass::Exec::ProjectOptionsParser)
parser.extend(InteractiveOptionsParser)
end
def usage
option_parser([]).to_s
end
def description(command)
"Interactively evaluate SassScript"
end
def parse!(arguments)
parser = option_parser(arguments)
parser.parse!
parser.options
end
end
end
end
end
1.0.3~dfsg/cli/lib/compass/commands/help.rb 0000644 0000000 0000000 00000005140 12456054517 017326 0 ustar root root module Compass
module Commands
module HelpOptionsParser
def set_options(opts)
banner = %Q{Usage: compass help [command]
Description:
The Compass Stylesheet Authoring Framework helps you
build and maintain your stylesheets and makes it easy
for you to use stylesheet libraries provided by others.
Donating:
Compass is charityware. If you find it useful please make
a tax deductable donation: http://umdf.org/compass
To get help on a particular command please specify the command.
}
primary_commands = Compass::Commands.all.select do |c|
cmd = Compass::Commands[c]
cmd.respond_to?(:primary) && cmd.primary
end
other_commands = Compass::Commands.all - primary_commands
banner << command_list("Primary Commands:", primary_commands)
banner << command_list("Other Commands:", other_commands)
banner << "\nAvailable Frameworks & Patterns:\n\n"
banner << Compass::Frameworks.pretty_print
banner << "\nGlobal Options:\n"
opts.banner = banner
super
end
def command_list(header, commands)
list = "#{header}\n"
commands.sort_by{|c| c.to_s}.each do |command|
list << " * #{command}"
if Compass::Commands[command].respond_to? :description
list << "\t- #{Compass::Commands[command].description(command)}"
end
list << "\n"
end
list
end
end
class Help < Base
register :help
class << self
def option_parser(arguments)
parser = Compass::Exec::CommandOptionParser.new(arguments)
parser.extend(Compass::Exec::GlobalOptionsParser)
parser.extend(HelpOptionsParser)
end
def usage
option_parser([]).to_s
end
def description(command)
"Get help on a compass command or extension"
end
def parse!(arguments)
parser = option_parser(arguments)
parser.parse!
parser.options[:help_command] = arguments.shift || 'help'
parser.options
end
end
def execute
if Compass::Commands.command_exists? options[:help_command]
$command = options[:help_command]
puts Compass::Commands[options[:help_command]].usage
$command = "help"
elsif Compass::Frameworks.template_exists? options[:help_command]
puts Compass::Frameworks.template_usage(options[:help_command])
else
raise OptionParser::ParseError, "No such command: #{options[:help_command]}"
end
end
end
end
end
1.0.3~dfsg/cli/lib/compass/commands/registry.rb 0000644 0000000 0000000 00000002156 12456054517 020252 0 ustar root root module Compass::Commands
module Registry
def register(name, command_class)
@commands ||= Hash.new
@commands[name.to_sym] = command_class
end
def get(name)
return unless name
@commands ||= Hash.new
@commands[name.to_sym] || @commands[abbreviation_of(name)]
end
def abbreviation_of(name)
re = /^#{Regexp.escape(name)}/
matching = @commands.keys.select{|k| k.to_s =~ re}
if matching.size == 1
matching.first
elsif name =~ /^-/
nil
elsif matching.size > 1
raise Compass::Error, "Ambiguous abbreviation '#{name}'. Did you mean one of: #{matching.join(", ")}"
else
raise Compass::Error, "Command not found: #{name}"
end
end
def abbreviation?(name)
re = /^#{Regexp.escape(name)}/
@commands.keys.detect{|k| k.to_s =~ re}
end
def command_exists?(name)
@commands ||= Hash.new
name && (@commands.has_key?(name.to_sym) || abbreviation?(name))
end
def all
@commands.keys
end
alias_method :[], :get
alias_method :[]=, :register
end
extend Registry
end
1.0.3~dfsg/cli/lib/compass/commands/validate_project.rb 0000644 0000000 0000000 00000003726 12456054517 021725 0 ustar root root require 'compass/commands/project_base'
require 'compass/commands/update_project'
module Compass
module Commands
module ValidationOptionsParser
def set_options(opts)
opts.banner = %Q{
Usage: compass validate [path/to/project] [options]
Description:
Compile project at the path specified or the current
directory if not specified and then validate the
generated CSS.
Options:
}.strip.split("\n").map{|l| l.gsub(/^ {0,10}/,'')}.join("\n")
super
end
end
class ValidateProject < ProjectBase
register :validate
def initialize(working_path, options)
super
assert_project_directory_exists!
end
def perform
require 'compass/validator'
UpdateProject.new(working_path, options).perform
Dir.chdir Compass.configuration.project_path do
Validator.new(project_css_subdirectory).validate()
end
end
class << self
def option_parser(arguments)
parser = Compass::Exec::CommandOptionParser.new(arguments)
parser.extend(Compass::Exec::GlobalOptionsParser)
parser.extend(Compass::Exec::ProjectOptionsParser)
parser.extend(ValidationOptionsParser)
end
def usage
option_parser([]).to_s
end
def description(command)
"Validate your generated css."
end
def parse!(arguments)
parser = option_parser(arguments)
parser.parse!
parse_arguments!(parser, arguments)
parser.options
end
def parse_arguments!(parser, arguments)
if arguments.size == 1
parser.options[:project_name] = arguments.shift
elsif arguments.size == 0
# default to the current directory.
else
raise Compass::Error, "Too many arguments were specified."
end
end
end
end
end
end
1.0.3~dfsg/cli/lib/compass/commands/extension_command.rb 0000644 0000000 0000000 00000002536 12456054517 022116 0 ustar root root require 'fileutils'
require 'compass/commands/base'
module Compass
module Commands
module ExtensionsOptionParser
def set_options(opts)
opts.banner = %Q{
Usage: compass extension install EXTENSION_NAME [options]
compass extension uninstall EXTENSION_NAME [options]
compass extension list
Description:
Manage the list of extensions on your system.
Compass to all of your compass projects.
Example:
compass extension install sassy-buttons
compass extension uninstall sassy-buttons
}
super
end
end
class ExtensionCommand < Base
register :extension
class << self
def option_parser(arguments)
parser = Compass::Exec::CommandOptionParser.new(arguments)
parser.extend(ExtensionsOptionParser)
end
def usage
option_parser([]).to_s
end
def description(command)
"Manage the list of compass extensions on your system"
end
def parse!(arguments)
{:arguments => arguments}
end
end
include InstallerCommand
def initialize(working_path, options)
super(working_path, options)
end
# all commands must implement perform
def perform
require 'rubygems/gem_runner'
Gem::GemRunner.new.run(options[:arguments])
end
end
end
end
1.0.3~dfsg/cli/lib/compass/commands/watch_project.rb 0000644 0000000 0000000 00000007237 12456054517 021243 0 ustar root root # encoding: UTF-8
require 'fileutils'
require 'pathname'
require 'compass/commands/update_project'
require "compass/sass_compiler"
module Compass
module Commands
module WatchProjectOptionsParser
def set_options(opts)
super
opts.banner = %Q{
Usage: compass watch [path/to/project] [path/to/project/src/file.sass ...] [options]
Description:
watch the project for changes and recompile when they occur.
Options:
}.split("\n").map{|l| l.gsub(/^ */,'')}.join("\n")
opts.on("--poll", :NONE, "Check periodically if there's been changes.") do
self.options[:poll] = 1 # check every 1 second.
end
end
end
class WatchProject < UpdateProject
register :watch
attr_accessor :last_update_time, :last_sass_files
def perform
compiler = new_compiler_instance
compiler.logger.time = true if options[:time]
prepare_project!(compiler)
compiler.logger.log ">>> #{compiler.logger.color(:green)}Compass is watching for changes.#{compiler.logger.color(:clear)} #{compiler.logger.color(:red)}Press Ctrl-C to Stop.#{compiler.logger.color(:clear)}"
begin
compiler.watch!(:additional_watch_paths => additional_watch_paths, &method(:notify_watches))
happy_styling!(compiler.logger)
rescue Interrupt
happy_styling!(compiler.logger)
end
end
def happy_styling!(logger)
logger.log "\n#{logger.color(:yellow)}★★★ #{logger.color(:blue)}Happy Styling!#{logger.color(:yellow)} ★★★#{logger.color(:clear)}"
end
def compiler_options
super.merge(:poll => options[:poll], :full_exception => true)
end
def additional_watch_paths
Compass.configuration.watches.map do |watch|
pathname = Pathname.new(File.join(Compass.configuration.project_path, watch.glob))
real_path = nil
pathname.ascend do |p|
if p.exist?
real_path = p
break
end
end
real_path
end.compact.uniq
end
def notify_watches(modified, added, removed)
project_path = Compass.configuration.project_path
files = {:modified => modified,
:added => added,
:removed => removed}
run_once, run_each = Compass.configuration.watches.partition {|w| w.run_once_per_changeset?}
run_once.each do |watcher|
if file = files.values.flatten.detect{|f| watcher.match?(f) }
action = files.keys.detect{|k| files[k].include?(file) }
watcher.run_callback(project_path, relative_to(file, project_path), action)
end
end
run_each.each do |watcher|
files.each do |action, list|
list.each do |file|
if watcher.match?(file)
watcher.run_callback(project_path, relative_to(file, project_path), action)
end
end
end
end
end
def relative_to(f, dir)
Pathname.new(f).relative_path_from(Pathname.new(dir))
rescue ArgumentError # does not share a common path.
f
end
class << self
def description(command)
"Compile Sass stylesheets to CSS when they change"
end
def option_parser(arguments)
parser = Compass::Exec::CommandOptionParser.new(arguments)
parser.extend(Compass::Exec::GlobalOptionsParser)
parser.extend(Compass::Exec::ProjectOptionsParser)
parser.extend(CompileProjectOptionsParser)
parser.extend(WatchProjectOptionsParser)
end
end
end
end
end
1.0.3~dfsg/cli/lib/compass/commands/sprite.rb 0000644 0000000 0000000 00000005446 12456054517 017715 0 ustar root root require 'compass/commands/project_base'
require 'compass/commands/update_project'
module Compass
module Commands
module SpriteOptionsParser
def set_options(opts)
opts.on("-f SPRITE_FILE") do |output_file|
self.options[:output_file] = output_file
end
opts.on("--skip-overrides", "Skip the generation of sprite overrides") do |skip_overrides|
self.options[:skip_overrides] = skip_overrides
end
opts.banner = %Q{
Usage: compass sprite [options] "images/path/to/sprites/*.png"
Description:
Generate a sprite import based on the given sprite directory.
Alternatively, you can simply do this in your sass files:
@import "sprite-folder/*.png"
And a magical, custom made sprite file will be imported.
Options:
}.strip.split("\n").map{|l| l.gsub(/^ {0,10}/,'')}.join("\n")
super
end
end
class Sprite < ProjectBase
register :sprite
def initialize(working_path, options)
super
assert_project_directory_exists!
end
def perform
relative_uri = options[:uri].gsub(/^#{Compass.configuration.images_dir}\//, '')
name = Compass::SpriteImporter.sprite_name(relative_uri)
sprites = Compass::SpriteImporter.new
options[:output_file] ||= File.join(Compass.configuration.sass_path, "sprites", "_#{name}.#{Compass.configuration.preferred_syntax}")
options[:skip_overrides] ||= false
contents = Compass::SpriteImporter.content_for_images(relative_uri, name, options[:skip_overrides])
if options[:output_file][-4..-1] != "scss"
contents = Sass::Engine.new(contents, Compass.sass_engine_options.merge(:syntax => :scss)).to_tree.to_sass
end
directory File.dirname(options[:output_file])
write_file options[:output_file], contents
end
class << self
def option_parser(arguments)
parser = Compass::Exec::CommandOptionParser.new(arguments)
parser.extend(Compass::Exec::GlobalOptionsParser)
parser.extend(Compass::Exec::ProjectOptionsParser)
parser.extend(SpriteOptionsParser)
end
def usage
option_parser([]).to_s
end
def description(command)
"Generate an import for your sprites."
end
def parse!(arguments)
parser = option_parser(arguments)
parser.parse!
parse_arguments!(parser, arguments)
parser.options
end
def parse_arguments!(parser, arguments)
parser.options[:uri] = arguments.shift
unless arguments.size == 0
raise Compass::Error, "Please specify at least one image to sprite."
end
end
end
end
end
end
1.0.3~dfsg/cli/lib/compass/commands/imports.rb 0000644 0000000 0000000 00000001755 12456054517 020103 0 ustar root root module Compass
module Commands
class Imports < ProjectBase
attr_accessor :options
register :imports
def initialize(working_path, options)
super
end
def execute
print ::Compass::Frameworks::ALL.map{|f|
"-I #{f.stylesheets_directory}"
}.join(' ')
end
class << self
def description(command)
"Emit an imports suitable for passing to the sass command-line."
end
def usage
"Usage: compass imports\n\n" +
"Prints out the imports known to compass.\n"+
"Useful for passing imports to the sass command line:\n" +
" sass -r compass `compass imports` a_file_using_compass.sass"
end
def parse!(arguments)
if arguments.join("").strip.size > 0
raise OptionParser::ParseError, "This command takes no options or arguments."
else
{}
end
end
end
end
end
end
1.0.3~dfsg/cli/lib/compass/commands/stamp_pattern.rb 0000644 0000000 0000000 00000005153 12456054517 021263 0 ustar root root require 'fileutils'
require 'compass/commands/base'
require 'compass/commands/update_project'
module Compass
module Commands
module StampPatternOptionsParser
def set_options(opts)
opts.banner = %Q{Usage: compass install extension/pattern [path/to/project] [options]
Description:
Install an extension's pattern into your compass project
Example:
compass install blueprint/buttons
Options:
}
opts.on("-x", "--syntax SYNTAX", [:sass, :scss], "Specify the syntax to use when generating stylesheets.", "One of sass or scss. Defaults to scss.") do |syntax|
self.options[:preferred_syntax] = syntax
end
super
end
end
class StampPattern < ProjectBase
register :install
class << self
def option_parser(arguments)
parser = Compass::Exec::CommandOptionParser.new(arguments)
parser.extend(Compass::Exec::GlobalOptionsParser)
parser.extend(Compass::Exec::ProjectOptionsParser)
parser.extend(StampPatternOptionsParser)
end
def usage
option_parser([]).to_s
end
def description(command)
"Install an extension's pattern into your compass project"
end
def parse!(arguments)
parser = option_parser(arguments)
parser.parse!
parse_arguments!(parser, arguments)
parser.options
end
def parse_arguments!(parser, arguments)
if arguments.size == 0
raise OptionParser::ParseError, "Please specify a pattern."
end
pattern = arguments.shift.split('/', 2)
parser.options[:framework] = pattern[0]
parser.options[:pattern] = pattern[1]
if arguments.size > 0
parser.options[:project_name] = arguments.shift
end
if arguments.size > 0
raise OptionParser::ParseError, "Unexpected trailing arguments: #{arguments.join(" ")}"
end
end
end
include InstallerCommand
def initialize(working_path, options)
super(working_path, options)
end
# all commands must implement perform
def perform
installer.init
installer.run(:skip_finalization => true, :skip_preparation => !is_project_creation?)
UpdateProject.new(working_path, options).perform if installer.compilation_required?
installer.finalize(options.merge(:create => is_project_creation?))
end
def is_project_creation?
false
end
def template_directory(pattern)
File.join(framework.templates_directory, pattern)
end
end
end
end
1.0.3~dfsg/cli/lib/compass/commands/base.rb 0000644 0000000 0000000 00000001520 12456054517 017306 0 ustar root root module Compass
module Commands
class Base
def self.register(command_name)
Compass::Commands[command_name] = self
end
include Actions
attr_accessor :working_path, :options
def initialize(working_path, options)
self.working_path = working_path.to_s
self.options = options
end
def execute
perform
end
def perform
raise StandardError.new("Not Implemented")
end
def successful?
!@failed
end
def failed!
@failed = true
end
protected
def framework
unless Compass::Frameworks[options[:framework]]
raise Compass::Error.new("No such framework: #{options[:framework].inspect}")
end
Compass::Frameworks[options[:framework]]
end
end
end
end
1.0.3~dfsg/cli/lib/compass/commands/print_version.rb 0000644 0000000 0000000 00000005134 12456054517 021302 0 ustar root root module Compass
module Commands
module VersionOptionsParser
def set_options(opts)
opts.banner = %Q{Usage: compass version [options]
Options:
}
opts.on_tail("-?", "-h", "--help", "Print out this message.") do
puts opts
exit
end
opts.on("-q", "--quiet", "Just print the version string.") do
self.options[:quiet] = true
end
opts.on("--major", "Print the major version number") do
self.options[:major] = true
self.options[:custom] = true
end
opts.on("--minor", "Print up to the minor version number") do
self.options[:major] = true
self.options[:minor] = true
self.options[:custom] = true
end
opts.on("--patch", "Print up to the patch version number") do
self.options[:major] = true
self.options[:minor] = true
self.options[:patch] = true
self.options[:custom] = true
end
end
end
class PrintVersion < Base
register :version
class << self
def option_parser(arguments)
parser = Compass::Exec::CommandOptionParser.new(arguments)
parser.extend(VersionOptionsParser)
end
def usage
option_parser([]).to_s
end
def description(command)
"Print out version information"
end
def parse!(arguments)
parser = option_parser(arguments)
parser.parse!
parser.options
end
def long_output_string
lines = []
lines << "Compass #{::Compass.version[:string]}"
if name = ::Compass.version[:name]
lines.last << " (#{name})"
end
lines << "Copyright (c) 2008-#{Time.now.year} Chris Eppstein"
lines << "Released under the MIT License."
lines << "Compass is charityware."
lines << "Please make a tax deductable donation for a worthy cause: http://umdf.org/compass"
lines.join("\n")
end
end
attr_accessor :options
def initialize(working_path, options)
self.options = options
end
def execute
if options[:custom]
version = ""
version << "#{Compass.version[:major]}" if options[:major]
version << ".#{Compass.version[:minor]}" if options[:minor]
version << ".#{Compass.version[:patch]}" if options[:patch]
puts version
elsif options[:quiet]
puts ::Compass.version[:string]
else
puts self.class.long_output_string
end
end
end
end
end
1.0.3~dfsg/cli/lib/compass/commands/update_project.rb 0000644 0000000 0000000 00000010647 12456054517 021416 0 ustar root root require 'compass/commands/project_base'
require 'compass/compiler'
module Compass
module Commands
module CompileProjectOptionsParser
def set_options(opts)
opts.banner = %Q{
Usage: compass compile [path/to/project] [path/to/project/src/file.sass ...] [options]
Description:
compile project at the path specified or the current directory if not specified.
Options:
}.split("\n").map{|l| l.gsub(/^ */,'')}.join("\n")
opts.on("--[no-]sourcemap", "Generate a sourcemap during compilation.") do |sm|
self.options[:sourcemap] = sm
end
opts.on("--time", "Display compilation times.") do
self.options[:time] = true
end
opts.on("--debug-info", "Turns on sass's debuging information") do
self.options[:debug_info]= true
end
opts.on("--no-debug-info", "Turns off sass's debuging information") do
self.options[:debug_info]= false
end
super
end
end
class UpdateProject < ProjectBase
register :compile
def initialize(working_path, options)
super
assert_project_directory_exists!
end
def perform
compiler = new_compiler_instance
check_for_sass_files!(compiler)
prepare_project!(compiler)
compiler.compile!
if compiler.error_count > 0
compiler.logger.red do
compiler.logger.log "Compilation failed in #{compiler.error_count} files."
end
failed!
end
end
def prepare_project!(compiler)
if options[:project_name]
Compass.configuration.project_path = File.expand_path(options[:project_name])
end
if config_file = new_config?(compiler)
compiler.logger.record :modified, relativize(config_file)
compiler.logger.record :clean, relativize(Compass.configuration.css_path)
compiler.clean!
end
end
# Determines if the configuration file is newer than any css file
def new_config?(compiler)
config_file = Compass.detect_configuration_file
return false unless config_file
config_mtime = File.mtime(config_file)
compiler.file_list.each do |(_, css_filename, _)|
return config_file if File.exists?(css_filename) && config_mtime > File.mtime(css_filename)
end
nil
end
def check_for_sass_files!(compiler)
file_list = compiler.file_list
if file_list.empty?
message = "Compass can't find any Sass files to compile.\nIs your compass configuration correct?.\nIf you're trying to start a new project, you have left off the directory argument.\n"
message << "Run \"compass -h\" to get help."
raise Compass::Error, message
elsif missing = file_list.find {|(sass_file, _, _)| !File.exist?(sass_file)}
raise Compass::Error, "File not found: #{missing[0]}"
end
end
def new_compiler_instance
Compass::SassCompiler.new(compiler_options)
end
def compiler_options
transfer_options(options, {}, :time, :debug_info, :only_sass_files, :force, :quiet)
end
def transfer_options(from, to, *keys)
keys.each do |k|
to[k] = from[k] unless from[k].nil?
end
to
end
class << self
def option_parser(arguments)
parser = Compass::Exec::CommandOptionParser.new(arguments)
parser.extend(Compass::Exec::GlobalOptionsParser)
parser.extend(Compass::Exec::ProjectOptionsParser)
parser.extend(CompileProjectOptionsParser)
end
def usage
option_parser([]).to_s
end
def primary; true; end
def description(command)
"Compile Sass stylesheets to CSS"
end
def parse!(arguments)
parser = option_parser(arguments)
parser.parse!
parse_arguments!(parser, arguments)
parser.options
end
def parse_arguments!(parser, arguments)
if arguments.size > 0
parser.options[:project_name] = arguments.shift if File.directory?(arguments.first)
unless arguments.empty?
parser.options[:only_sass_files] = absolutize(*arguments)
end
end
end
def absolutize(*paths)
paths.map {|path| File.expand_path(path) }
end
end
end
end
end
1.0.3~dfsg/cli/lib/compass/commands/project_base.rb 0000644 0000000 0000000 00000005532 12456054517 021043 0 ustar root root require 'fileutils'
require 'pathname'
require 'compass/commands/base'
require 'compass/commands/installer_command'
module Compass
module Commands
class ProjectBase < Base
attr_accessor :project_directory, :project_name, :options
def initialize(working_path, options = {})
super(working_path, options)
self.project_name = determine_project_name(working_path, options)
Compass.add_configuration({:project_path => determine_project_directory(working_path, options)}, "implied")
configure!
end
def execute
super
end
protected
def configure!
add_project_configuration
Compass.add_configuration(options, "command_line")
Compass.discover_extensions! unless skip_extension_discovery?
end
def add_project_configuration
defaults = Compass.configuration_for(options, "cli_defaults")
if options[:project_type]
project_type_config = Compass.configuration_for(options[:project_type])
project_type_config.inherit_from!(Compass.default_configuration)
defaults.inherit_from!(project_type_config)
end
Compass.add_project_configuration(options[:configuration_file], :defaults => defaults) do
options[:project_type]
end
end
def projectize(path)
Compass.projectize(path)
end
def project_directory
Compass.configuration.project_path
end
def project_css_subdirectory
Compass.configuration.css_dir
end
def project_src_subdirectory
Compass.configuration.sass_dir
end
def project_images_subdirectory
Compass.configuration.images_dir
end
def assert_project_directory_exists!
if File.exists?(project_directory) && !File.directory?(project_directory)
raise Compass::FilesystemConflict.new("#{project_directory} is not a directory.")
elsif !File.directory?(project_directory)
raise Compass::Error.new("#{project_directory} does not exist.")
end
end
private
def determine_project_name(working_path, options)
if options[:project_name]
File.basename(strip_trailing_separator(options[:project_name]))
else
File.basename(working_path)
end
end
def determine_project_directory(working_path, options)
if options[:project_name]
if absolute_path?(options[:project_name])
options[:project_name]
else
File.join(working_path, options[:project_name])
end
else
working_path
end
end
def absolute_path?(path)
# Pretty basic implementation
path.index(File::SEPARATOR) == 0 || path.index(':') == 1
end
def skip_extension_discovery?
false
end
end
end
end
1.0.3~dfsg/cli/lib/compass/commands/write_configuration.rb 0000644 0000000 0000000 00000007667 12456054517 022477 0 ustar root root require 'compass/commands/project_base'
module Compass
module Commands
module ConfigurationOptionsParser
def set_options(opts)
opts.banner = %Q{
Usage: compass config [path/to/config_file.rb] [options]
Description:
Generate a configuration file for the options specified.
Compass will recognize configuration files in the
following locations relative to the project root:
* #{Compass::Configuration::Helpers::KNOWN_CONFIG_LOCATIONS.join("
* ")}
Any other location, and you'll need to specify it when working with the command line tool using the -c option.
Options:
}.strip.split("\n").map{|l| l.gsub(/^ {0,10}/,'')}.join("\n")
opts.on("--debug [PROPERTY]", "Debug your configuration by printing out details.") do |prop|
self.options[:debug] = prop.nil? ? true : prop.to_sym
end
opts.on("-p PROPERTY", "--property PROPERTY", "Print out the value of a particular configuration property") do |prop|
self.options[:display] = prop.to_sym
end
super
end
end
class WriteConfiguration < ProjectBase
register :config
include InstallerCommand
def initialize(working_path, options)
super
assert_project_directory_exists!
end
def add_project_configuration
Compass.add_project_configuration
end
def perform
if options[:display]
if Compass.configuration.respond_to?(options[:display])
puts Compass.configuration.send(options[:display])
else
raise Compass::Error, "ERROR: configuration property '#{options[:display]}' does not exist"
end
elsif options[:debug]
puts "Configuration sources:"
c = Compass.configuration
while c
print c.name
c = c.inherited_data
print ", " if c
end
print "\n"
Compass.configuration.debug.each do |prop, values|
if options[:debug].is_a?(Symbol)
next unless prop == options[:debug]
end
puts "***** #{prop} = #{values.first[:resolved].inspect} *****"
[:default, :value, :raw, :resolved].each do |kind|
puts "#{kind}: " + values.inject([]){|m, v| m << v[kind]}.map{|v| v.nil? ? '-' : v.inspect}.join(", ")
end
end
else
config_file = options[:configuration_file]
config_file ||= Compass.detect_configuration_file
config_file ||= Compass::Configuration::Helpers::KNOWN_CONFIG_LOCATIONS.first
directory File.dirname(config_file)
installer.write_configuration_files(config_file)
end
end
def installer_args
[nil, project_directory, options]
end
def explicit_config_file_must_be_readable?
false
end
class << self
def option_parser(arguments)
parser = Compass::Exec::CommandOptionParser.new(arguments)
parser.extend(Compass::Exec::GlobalOptionsParser)
parser.extend(Compass::Exec::ProjectOptionsParser)
parser.extend(ConfigurationOptionsParser)
end
def usage
option_parser([]).to_s
end
def description(command)
"Generate a configuration file for the provided command line options."
end
def parse!(arguments)
parser = option_parser(arguments)
parser.parse!
parse_arguments!(parser, arguments)
parser.options
end
def parse_arguments!(parser, arguments)
if arguments.size == 1
parser.options[:configuration_file] = arguments.shift
elsif arguments.size == 0
# default to the current directory.
else
raise Compass::Error, "Too many arguments were specified."
end
end
end
end
end
end
1.0.3~dfsg/cli/lib/compass/commands/installer_command.rb 0000644 0000000 0000000 00000001471 12456054517 022074 0 ustar root root require 'compass/installers'
module Compass
module Commands
module InstallerCommand
include Compass::Installers
def configure!
add_project_configuration
Compass.add_configuration(options, 'command_line')
Compass.discover_extensions!
Compass.add_configuration(installer.completed_configuration, 'installer')
end
def app
@app ||= Compass::AppIntegration.lookup(Compass.configuration.project_type)
end
def installer
@installer ||= if options[:bare]
Compass::Installers::BareInstaller.new(*installer_args)
else
app.installer(*installer_args)
end
end
def installer_args
[template_directory(options[:pattern] || "project"), project_directory, options]
end
end
end
end
1.0.3~dfsg/cli/lib/compass/commands/create_project.rb 0000644 0000000 0000000 00000007310 12456054517 021370 0 ustar root root require 'fileutils'
require 'compass/commands/stamp_pattern'
module Compass
module Commands
module CreateProjectOptionsParser
def set_options(opts)
if $command == "create"
opts.banner = %Q{
Usage: compass create path/to/project [options]
Description:
Create a new compass project at the path specified.
Options:
}.split("\n").map{|l| l.gsub(/^ */,'')}.join("\n")
opts.on_tail("--bare", "Don't generate any Sass or CSS files.") do
self.options[:bare] = true
end
else
opts.banner = %Q{
Usage: compass init project_type path/to/project [options]
Description:
Initialize an existing project at the path specified.
Supported Project Types:
* rails
Options:
}.split("\n").map{|l| l.gsub(/^ */,'')}.join("\n").strip
end
opts.on("--using PATTERN", "A framework's pattern to use when creating the project.") do |framework|
framework = framework.split('/', 2)
self.options[:framework] = framework[0]
self.options[:pattern] = framework[1]
end
opts.on("-x", "--syntax SYNTAX", [:sass, :scss], "Specify the syntax to use when generating stylesheets.", "One of sass or scss. Defaults to scss.") do |syntax|
self.options[:preferred_syntax] = syntax
end
opts.on("--prepare", "Prepare the project by only creating configuration files.") do
self.options[:prepare] = true
end
super
end
end
class CreateProject < StampPattern
register :create
register :init
class << self
def option_parser(arguments)
parser = Compass::Exec::CommandOptionParser.new(arguments)
parser.extend(Compass::Exec::GlobalOptionsParser)
parser.extend(Compass::Exec::ProjectOptionsParser)
parser.extend(CreateProjectOptionsParser)
end
def usage
option_parser([]).to_s
end
def description(command)
if command.to_sym == :create
"Create a new compass project"
else
"Add compass to an existing project"
end
end
def primary; true; end
def parse!(arguments)
parser = option_parser(arguments)
parse_options!(parser, arguments)
parse_arguments!(parser, arguments)
if parser.options[:framework] && parser.options[:bare]
raise Compass::Error, "A bare project cannot be created when a framework is specified."
end
set_default_arguments(parser)
parser.options
end
def parse_init!(arguments)
parser = option_parser(arguments)
parse_options!(parser, arguments)
if arguments.size > 0
parser.options[:project_type] = arguments.shift.to_sym
end
parse_arguments!(parser, arguments)
set_default_arguments(parser)
parser.options
end
def parse_options!(parser, arguments)
parser.parse!
parser
end
def parse_arguments!(parser, arguments)
if arguments.size == 1
parser.options[:project_name] = arguments.shift
elsif arguments.size == 0
# default to the current directory.
else
raise Compass::Error, "Too many arguments were specified."
end
end
def set_default_arguments(parser)
parser.options[:framework] ||= :compass
parser.options[:pattern] ||= "project"
end
end
def is_project_creation?
true
end
end
end
end
1.0.3~dfsg/cli/lib/compass/deprecation.rb 0000644 0000000 0000000 00000000742 12456054517 017075 0 ustar root root module Compass
module Deprecation
class << self
attr_accessor :issued_deprecations
end
self.issued_deprecations = {}
def self.deprecated!(identifier, message)
return if Deprecation.issued_deprecations[identifier]
Deprecation.issued_deprecations[identifier] = true
warn message
warn "Called from #{caller[1]}"
end
def self.mark_as_issued(identifier)
Deprecation.issued_deprecations[identifier] = true
end
end
end
1.0.3~dfsg/cli/lib/compass/stats.rb 0000644 0000000 0000000 00000005250 12456054517 015735 0 ustar root root module Compass
module Stats
class StatsVisitor
attr_accessor :rule_count, :prop_count, :mixin_def_count, :mixin_count
def initialize
self.rule_count = 0
self.prop_count = 0
self.mixin_def_count = 0
self.mixin_count = 0
end
def visit(node)
self.prop_count += 1 if node.is_a?(Sass::Tree::PropNode) && !node.children.any?
if node.is_a?(Sass::Tree::RuleNode)
self.rule_count += node.rule.reject{|r| r.is_a?(Sass::Script::Tree::Node)}.map{|r| r.split(/,/)}.flatten.compact.size
end
self.mixin_def_count += 1 if node.is_a?(Sass::Tree::MixinDefNode)
self.mixin_count += 1 if node.is_a?(Sass::Tree::MixinNode)
end
def up(node)
end
def down(node)
end
def import?(node)
return false
full_filename = node.send(:import)
full_filename != Compass.deprojectize(full_filename)
end
end
class CssFile
attr_accessor :path, :css
attr_accessor :selector_count, :prop_count
attr_accessor :file_size
def initialize(path)
require 'css_parser'
self.path = path
self.css = CssParser::Parser.new
self.css.add_block!(contents)
self.selector_count = 0
self.prop_count = 0
end
def contents
@contents ||= File.read(path)
end
def lines
contents.inject(0){|m,c| m + 1 }
end
def analyze!
self.file_size = File.size(path)
css.each_selector do |selector, declarations, specificity|
sels = selector.split(/,/).size
props = declarations.split(/;/).size
self.selector_count += sels
self.prop_count += props
end
end
end
class SassFile
attr_accessor :path
attr_reader :visitor
attr_accessor :file_size
def initialize(path)
self.path = path
end
def contents
@contents ||= File.read(path)
end
def tree
opts = Compass.configuration.to_sass_engine_options
opts[:syntax] = path[-4..-1].to_sym
@tree = Sass::Engine.new(contents, opts).to_tree
end
def visit_tree!
@visitor = StatsVisitor.new
tree.visit_depth_first(@visitor)
@visitor
end
def analyze!
self.file_size = File.size(path)
visit_tree!
end
def lines
contents.inject(0){|m,c| m + 1 }
end
def rule_count
visitor.rule_count
end
def prop_count
visitor.prop_count
end
def mixin_def_count
visitor.mixin_def_count
end
def mixin_count
visitor.mixin_count
end
end
end
end
1.0.3~dfsg/cli/lib/compass/compiler.rb 0000644 0000000 0000000 00000022202 12456054517 016405 0 ustar root root require 'pathname'
module Compass
class Compiler
include Actions
attr_accessor :working_path, :from, :to, :options, :sass_options, :staleness_checker, :importer
def initialize(working_path, from, to, options)
Compass::Deprecation.deprecated!(:compass_compiler_constructor,
"Compass::Compiler is deprecated. Use Compass::SassCompiler instead.")
self.working_path = working_path.to_s
self.from, self.to = File.expand_path(from), to
self.logger = options.delete(:logger)
sass_opts = options.delete(:sass) || {}
self.options = options
self.sass_options = options.dup
self.sass_options.delete(:quiet)
self.sass_options.update(sass_opts)
self.sass_options[:cache_location] ||= determine_cache_location
self.sass_options[:filesystem_importer] ||= Sass::Importers::Filesystem
self.sass_options[:importer] = self.importer = self.sass_options[:filesystem_importer].new(from)
self.sass_options[:compass] ||= {}
self.sass_options[:compass][:logger] = self.logger
self.sass_options[:compass][:environment] = Compass.configuration.environment
self.sass_options[:compass][:compiler_in_use] = true
reset_staleness_checker!
end
def reset_staleness_checker!
self.staleness_checker = nil
#Sass::Plugin::StalenessChecker.dependencies_cache = {}
self.staleness_checker = Sass::Plugin::StalenessChecker.new(sass_options)
end
def determine_cache_location
Compass.configuration.cache_path || Sass::Plugin.options[:cache_location] || File.join(working_path, ".sass-cache")
end
def sass_files(options = {})
exclude_partials = options.fetch(:exclude_partials, true)
@sass_files = self.options[:sass_files] || Dir.glob(separate("#{from}/**/#{'[^_]' if exclude_partials}*.s[ac]ss"))
end
def relative_stylesheet_name(sass_file)
sass_file[(from.length + 1)..-1]
end
def stylesheet_name(sass_file)
if sass_file.index(from) == 0
sass_file[(from.length + 1)..-6].sub(/\.css$/,'')
else
raise Compass::Error, "You must compile individual stylesheets from the project directory."
end
end
def css_files
@css_files ||= sass_files.map{|sass_file| corresponding_css_file(sass_file)}
end
def sourcemap_files
@sourcemap_files ||= sass_files.map{|sass_file| corresponding_sourcemap_file(sass_file)}
end
def corresponding_css_file(sass_file)
"#{to}/#{stylesheet_name(sass_file)}.css"
end
def corresponding_sourcemap_file(sass_file)
"#{to}/#{stylesheet_name(sass_file)}.css.map"
end
def target_directories
css_files.map{|css_file| File.dirname(css_file)}.uniq.sort.sort_by{|d| d.length }
end
# Returns the sass file that needs to be compiled, if any.
def out_of_date?
sass_files.zip(css_files).each do |sass_filename, css_filename|
return sass_filename if needs_update?(css_filename, sass_filename)
end
false
end
def needs_update?(css_filename, sass_filename)
staleness_checker.stylesheet_needs_update?(css_filename, File.expand_path(sass_filename), importer)
end
# Determines if the configuration file is newer than any css file
def new_config?
config_file = Compass.detect_configuration_file
return false unless config_file
config_mtime = File.mtime(config_file)
css_files.each do |css_filename|
return config_file if File.exists?(css_filename) && config_mtime > File.mtime(css_filename)
end
nil
end
def reset!
reset_staleness_checker!
@sass_files = nil
@css_files = nil
@sourcemap_files = nil
end
def clean!
remove options[:cache_location]
css_files.zip(sourcemap_files).each do |css_file, sourcemap_file|
remove css_file
remove sourcemap_file
end
end
def run
failure_count = 0
if new_config?
# Wipe out the cache and force compilation if the configuration has changed.
remove options[:cache_location] if options[:cache_location]
options[:force] = true
end
# Make sure the target directories exist
target_directories.each {|dir| directory dir}
# Compile each sass file.
result = timed do
sass_files.zip(css_files, sourcemap_files).each do |sass_filename, css_filename, sourcemap_filename|
begin
compile_if_required sass_filename, css_filename, sourcemap_filename
rescue Sass::SyntaxError => e
failure_count += 1
handle_exception(sass_filename, css_filename, e)
end
end
end
if options[:time]
puts "Compilation took #{(result.__duration * 1000).round / 1000.0}s"
end
return failure_count
end
def compile_if_required(sass_filename, css_filename, sourcemap_filename = nil)
if should_compile?(sass_filename, css_filename, sourcemap_filename)
compile sass_filename, css_filename, sourcemap_filename
else
logger.record :unchanged, basename(sass_filename) unless options[:quiet]
remove(sourcemap_filename) if sourcemap_filename && !options[:sourcemap]
end
end
def timed(timed_thing = lambda {|res| res})
start_time = Time.now
res = yield
end_time = Time.now
has_duration = timed_thing.call(res)
has_duration.instance_variable_set("@__duration", end_time - start_time)
def has_duration.__duration
@__duration
end
res
end
# Compile one Sass file
def compile(sass_filename, css_filename, sourcemap_filename = nil)
css_content, sourcemap = logger.red do
timed(lambda {|r| r[0]}) do
engine = engine(sass_filename, css_filename, sourcemap_filename)
if sourcemap_filename && options[:sourcemap]
engine.render_with_sourcemap(relative_path(css_filename, sourcemap_filename))
else
[engine.render, nil]
end
end
end
duration = options[:time] ? "(#{(css_content.__duration * 1000).round / 1000.0}s)" : ""
write_file(css_filename, css_content, options.merge(:force => true, :extra => duration), sass_options[:unix_newlines])
Compass.configuration.run_stylesheet_saved(css_filename)
if sourcemap && sourcemap_filename
sourcemap_content = sourcemap.to_json(:css_path => css_filename,
:sourcemap_path => sourcemap_filename)
write_file(sourcemap_filename, sourcemap_content, options.merge(:force => true), sass_options[:unix_newlines])
Compass.configuration.run_sourcemap_saved(sourcemap_filename)
elsif sourcemap_filename && File.exist?(sourcemap_filename)
remove sourcemap_filename
Compass.configuration.run_sourcemap_removed(sourcemap_filename)
end
end
def relative_path(from_path, to_path)
Pathname.new(to_path).relative_path_from(Pathname.new(from_path).dirname).to_s
end
def should_compile?(sass_filename, css_filename, sourcemap_filename = nil)
return true if css_filename && !File.exist?(css_filename)
return true if sourcemap_filename && options[:sourcemap] && !File.exist?(sourcemap_filename)
options[:force] ||
needs_update?(css_filename, sass_filename) ||
(options[:sourcemap] && needs_update?(sourcemap_filename, sass_filename))
end
# A sass engine for compiling a single file.
def engine(sass_filename, css_filename, sourcemap_filename = nil)
syntax = (sass_filename =~ /\.(s[ac]ss)$/) && $1.to_sym || :sass
opts = sass_options.merge(:filename => sass_filename,
:css_filename => css_filename,
:syntax => syntax,
:sourcemap_filename => sourcemap_filename)
Sass::Engine.new(open(sass_filename).read, opts)
end
# Place the syntax error into the target css file,
# formatted to display in the browser (in development mode)
# if there's an error.
def handle_exception(sass_filename, css_filename, e)
exception_file = basename(e.sass_filename || sass_filename)
file = basename(sass_filename)
exception_file = nil if exception_file == file
formatted_error = "(Line #{e.sass_line}#{ " of #{exception_file}" if exception_file}: #{e.message})"
logger.record :error, file, formatted_error
Compass.configuration.run_stylesheet_error(sass_filename, formatted_error)
write_file css_filename, error_contents(e, sass_filename), options.merge(:force => true), sass_options[:unix_newlines]
end
# Haml refactored this logic in 2.3, this is backwards compatibility for either one
def error_contents(e, sass_filename)
if show_full_exception?
e.sass_template = sass_filename
Sass::SyntaxError.exception_to_css(e)
else
header = Sass::SyntaxError.send(:header_string, e, 1)
<