2006-12-03 23:56:47 +00:00
|
|
|
require File.dirname(__FILE__) + '/../sass'
|
2006-12-04 08:40:23 +00:00
|
|
|
require 'sass/tree/node'
|
|
|
|
require 'sass/tree/value_node'
|
|
|
|
require 'sass/tree/rule_node'
|
2006-11-28 19:43:58 +00:00
|
|
|
|
|
|
|
module Sass
|
|
|
|
class Engine
|
2006-12-04 08:40:23 +00:00
|
|
|
# The character that begins a CSS attribute.
|
|
|
|
ATTRIBUTE_CHAR = ':'[0]
|
|
|
|
|
|
|
|
# The string that begins one-line comments.
|
|
|
|
COMMENT_STRING = '//'
|
|
|
|
|
2006-12-04 02:47:37 +00:00
|
|
|
def initialize(template, options={})
|
2006-12-04 08:40:23 +00:00
|
|
|
@template = template.split("\n")
|
2006-12-04 02:47:37 +00:00
|
|
|
@options = options
|
2006-12-04 08:40:23 +00:00
|
|
|
@index = 0
|
2006-11-28 20:33:22 +00:00
|
|
|
end
|
2006-12-04 02:47:37 +00:00
|
|
|
|
|
|
|
def render
|
2006-12-04 16:49:23 +00:00
|
|
|
root = Tree::Node.new
|
2006-12-04 08:40:23 +00:00
|
|
|
first_line, first_tabs = next_line
|
2006-12-04 16:49:23 +00:00
|
|
|
build_plain_tree(first_line, root, first_tabs)
|
|
|
|
root.to_s
|
2006-12-04 08:40:23 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
|
|
|
|
def build_plain_tree(line, node, tabs)
|
|
|
|
current_tabs = tabs
|
|
|
|
tabs ||= 0
|
|
|
|
|
|
|
|
while line && (current_tabs.nil? || current_tabs >= tabs)
|
|
|
|
if current_tabs.nil?
|
|
|
|
line, current_tabs = next_line
|
|
|
|
elsif current_tabs == tabs
|
2006-12-04 16:49:23 +00:00
|
|
|
node << parse_line(line)
|
2006-11-28 19:43:58 +00:00
|
|
|
|
2006-12-04 08:40:23 +00:00
|
|
|
line, current_tabs = next_line
|
|
|
|
else # current_tabs > tabs
|
|
|
|
line, current_tabs = build_plain_tree(line, node.children[-1], current_tabs)
|
2006-11-28 19:43:58 +00:00
|
|
|
end
|
|
|
|
end
|
2006-12-04 08:40:23 +00:00
|
|
|
|
|
|
|
[line, current_tabs]
|
|
|
|
end
|
|
|
|
|
|
|
|
def next_line
|
|
|
|
line = @template[@index]
|
|
|
|
return if line.nil?
|
|
|
|
|
|
|
|
# TODO: Allow comments appended to the end of lines, find some way to make url(http://www.google.com/) work
|
|
|
|
line = '' if line[0..1] == COMMENT_STRING
|
|
|
|
current_tabs = count_soft_tabs(line)
|
|
|
|
line.strip!
|
|
|
|
@index += 1
|
|
|
|
[line, current_tabs]
|
|
|
|
end
|
|
|
|
|
|
|
|
def parse_line(line)
|
|
|
|
if line[0] == ATTRIBUTE_CHAR
|
|
|
|
name, *value = line.split(' ')
|
|
|
|
name = name[1..-1]
|
|
|
|
Tree::AttrNode.new(name, value)
|
|
|
|
else
|
|
|
|
Tree::RuleNode.new(line)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
# Counts the tabulation of a line.
|
|
|
|
def count_soft_tabs(line)
|
|
|
|
spaces = line.index(/[^ ]/)
|
|
|
|
spaces ? spaces/2 : nil
|
2006-11-28 19:43:58 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|