diff --git a/lib/sass/css/attribute.rb b/lib/sass/css/attribute.rb new file mode 100644 index 0000000000..7f583f3d44 --- /dev/null +++ b/lib/sass/css/attribute.rb @@ -0,0 +1,6 @@ +module Sass + module Css + class Attribute + end + end +end diff --git a/lib/sass/css/node.rb b/lib/sass/css/node.rb new file mode 100644 index 0000000000..de069670ad --- /dev/null +++ b/lib/sass/css/node.rb @@ -0,0 +1,25 @@ +require File.dirname(__FILE__) + '/attribute' + +module Sass + module Css + class Node + attr_reader :children, :attributes, :parent, :name + attr_writer :children, :attributes, :parent, :name + + def initialize(name) + @name = name + @children, @attributes = [], [] + end + + def <<(child) + @children << child + child.parent = self + true + end + + def to_s + name + "\n" + (self.children.collect { |c| c.to_s }).join("\n>>") + end + end + end +end diff --git a/lib/sass/css/parser.rb b/lib/sass/css/parser.rb new file mode 100644 index 0000000000..24ad662566 --- /dev/null +++ b/lib/sass/css/parser.rb @@ -0,0 +1,43 @@ + + +require File.dirname(__FILE__) + '/node' + +module Sass + module Css + def self.parse(sass_file) + build_tree(sass_file) + end + + def self.build_tree(sass_tree) + last_level, last_node = 0, nil + base_container = [] + sass_tree.each do |line| + line, level = whitespace_strip_and_count(line) + #puts "#{level}:#{last_level} #{line}" + if level == 0 + base_container << (last_node = Node.new(line)) + else + if line[0] == ':'[0] + if last_level == level + (1 + last_level - level).times { last_node = last_node.parent } + last_level = level + end + last_node.attributes << line + else + node = Node.new(line) + if last_level <= level + (1 + last_level - level).times { last_node = last_node.parent } + end + last_node << node + last_level, last_node = level, node + end + end + end + return base_container + end + + def self.whitespace_strip_and_count(line) + [line.strip, line.scan(/[ ]*/)[0].length / 2] + end + end +end diff --git a/lib/sass/engine.rb b/lib/sass/engine.rb new file mode 100644 index 0000000000..26518115a1 --- /dev/null +++ b/lib/sass/engine.rb @@ -0,0 +1,40 @@ + +require File.dirname(__FILE__) + '/css/parser' + +module Sass + class Engine + def render(input) + buffer, stack, last_level, first = "", [], 0, true + input.each do |line| + line, level = [line.strip, line.scan(/[ ]*/)[0].length / 2] + unless line.empty? + if '%.#'.index line[0..0] + if !first + buffer << "}\n" + end + if level <= last_level + stack.delete_at(stack.size - 1) + if stack.empty? + buffer << "\n" + end + end + stack << line + buffer << stack.join(" ") + " { " + last_level, first = level, false + elsif ':' == line[0..0] + attribute, *value = line.scan(/[^ ]*/) + value = value.join(" ") if value.is_a? Array + buffer << "#{attribute[1..-1]}: #{value.strip}; " + end + + end + end + + unless stack.empty? + buffer << "}" + end + + buffer + end + end +end diff --git a/lib/sass/plugin.rb b/lib/sass/plugin.rb new file mode 100644 index 0000000000..961df54115 --- /dev/null +++ b/lib/sass/plugin.rb @@ -0,0 +1,27 @@ + +#Rails plugin stuff. For use with action_view + +module Sass + module Plugin + + def options + @@options + end + + def stylesheet_location + @@options[:stylesheet_location] || (RAILS_ROOT + "/public/stylesheets/") + end + + def sass_template(name) + file_location = stylesheet_location + name + if stylesheet_needs_update?(file_location) + file = File.open(file_location + ".css") + Sass::Engine.new.render(file_location + ".sass") + end + end + + def stylesheet_needs_update?(file_location) + !File.exists?(file_location + ".css") || (File.mtime("#{file_location}.sass") - 60) > File.mtime("#{file_location}.css") + end + end +end