Add @for.

This commit is contained in:
Nathan Weizenbaum 2008-08-10 14:10:01 -04:00
parent f93f3fdca3
commit 473fd84d3b
4 changed files with 78 additions and 0 deletions

View File

@ -85,6 +85,10 @@ class Sass::Constant::Literal # :nodoc:
true
end
def to_i
raise SyntaxError.new("#{value.dump} is not an integer.")
end
attr_reader :value
protected

View File

@ -69,6 +69,11 @@ module Sass::Constant
"#{value}#{@unit}"
end
def to_i
super unless value % 1 == 0.0
return value
end
protected
def self.from_value(value, unit=nil)

View File

@ -92,6 +92,7 @@ module Sass
begin
render_to_tree.to_s
rescue SyntaxError => err
err.sass_line = @line unless err.sass_line
unless err.sass_filename
err.add_backtrace_entry(@options[:filename])
end
@ -321,6 +322,8 @@ END
import(value)
elsif directive == "if"
parse_if(line, root, value)
elsif directive == "for"
parse_for(line, root, value)
else
Tree::DirectiveNode.new(line.text, @options)
end
@ -334,6 +337,35 @@ END
end
end
def parse_for(line, root, text)
var, from_expr, to_name, to_expr = text.scan(/^([^\s]+)\s+from\s+(.+)\s+(to|through)\s+(.+)$/).first
if var.nil? # scan failed, try to figure out why for error message
if text !~ /^[^\s]+/
expected = "constant name"
elsif text !~ /^[^\s]+\s+from\s+.+/
expected = "'from <expr>'"
else
expected = "'to <expr>' or 'through <expr>'"
end
raise SyntaxError.new("Invalid for directive '@for #{text}': expected #{expected}.", @line)
end
raise SyntaxError.new("Invalid constant \"#{var}\".", @line) unless var =~ Constant::VALIDATE
from = Sass::Constant.parse(from_expr, @constants, @line).to_i
to = Sass::Constant.parse(to_expr, @constants, @line).to_i
range = Range.new(from, to, to_name == 'to')
tree = []
old_constants = @constants.dup
for i in range
@constants[var[1..-1]] = i.to_s
append_children(tree, line.children, root)
end
@constants = old_constants
tree
end
def parse_mixin_definition(line)
name, args = line.text.scan(/^=\s*([^(]+)(\([^)]*\))?$/).first
raise SyntaxError.new("Invalid mixin \"#{line.text[1..-1]}\".", @line) if name.nil?

View File

@ -454,6 +454,43 @@ a
SASS
end
def test_for
assert_equal(<<CSS, render(<<SASS))
a-0 {
2i: 0; }
a-1 {
2i: 2; }
a-2 {
2i: 4; }
a-3 {
2i: 6; }
b-1 {
j-1: 0; }
b-2 {
j-1: 1; }
b-3 {
j-1: 2; }
b-4 {
j-1: 3; }
CSS
!a = 3
@for !i from 0 to !a + 1
a-\#{!i}
2i = 2 * !i
@for !j from 1 through 4
b-\#{!j}
j-1 = !j - 1
SASS
end
def test_argument_error
assert_raise(Sass::SyntaxError) { render("a\n b = hsl(1)") }
end