Add a boolean datatype to SassScript.

This commit is contained in:
Nathan Weizenbaum 2008-08-09 00:17:58 -04:00
parent d394f8165f
commit 901e1f378d
6 changed files with 93 additions and 3 deletions

View File

@ -1,3 +1,4 @@
require 'strscan'
require 'sass/constant/operation' require 'sass/constant/operation'
require 'sass/constant/literal' require 'sass/constant/literal'
@ -29,16 +30,20 @@ module Sass
?* => :times, ?* => :times,
?/ => :div, ?/ => :div,
?% => :mod, ?% => :mod,
?& => :single_and,
?| => :single_or,
CONSTANT_CHAR => :const, CONSTANT_CHAR => :const,
STRING_CHAR => :str, STRING_CHAR => :str,
ESCAPE_CHAR => :esc ESCAPE_CHAR => :esc
} }
CONSTANT_CHARS = (SYMBOLS.keys + [ ?= ]).map {|c| Regexp.escape(c.chr) }.join
# The regular expression used to parse constants # The regular expression used to parse constants
MATCH = /^#{Regexp.escape(CONSTANT_CHAR.chr)}([^\s#{(SYMBOLS.keys + [ ?= ]).map {|c| Regexp.escape("#{c.chr}") }.join}]+)\s*((?:\|\|)?=)\s*(.+)/ MATCH = /^#{Regexp.escape(CONSTANT_CHAR.chr)}([^\s#{CONSTANT_CHARS}]+)\s*((?:\|\|)?=)\s*(.+)/
# The regular expression used to validate constants without matching # The regular expression used to validate constants without matching
VALIDATE = /^#{Regexp.escape(CONSTANT_CHAR.chr)}[^\s#{(SYMBOLS.keys + [ ?= ]).map {|c| Regexp.escape("#{c.chr}") }.join}]+$/ VALIDATE = /^#{Regexp.escape(CONSTANT_CHAR.chr)}[^\s#{CONSTANT_CHARS}]+$/
# Order of operations hash # Order of operations hash
ORDER = { ORDER = {
@ -129,12 +134,17 @@ module Sass
end end
# Time for a unary op! # Time for a unary op!
if ![nil, :open, :close, :const].include?(symbol) && beginning_of_token if ![nil, :open, :close, :const, :single_and, :single_or].include?(symbol) && beginning_of_token
beginning_of_token = true beginning_of_token = true
to_return << :unary << symbol to_return << :unary << symbol
next next
end end
if (symbol == :single_and || symbol == :single_or) && last == symbol
to_return[-1] = symbol.to_s.gsub(/^single_/, '').to_sym
next
end
# Are we looking at an operator? # Are we looking at an operator?
if symbol && (symbol != :mod || str.empty?) if symbol && (symbol != :mod || str.empty?)
str = reset_str.call str = reset_str.call

19
lib/sass/constant/bool.rb Normal file
View File

@ -0,0 +1,19 @@
require 'sass/constant/literal'
module Sass::Constant
class Bool < Literal # :nodoc:
def parse(value)
first, second, unit = value.scan(Literal::NUMBER)[0]
@value = value == 'true' ? true : false
end
def to_s
@value.to_s
end
def to_bool
@value
end
end
end

View File

@ -6,6 +6,7 @@ module Sass::Constant; class Literal; end; end;
require 'sass/constant/string' require 'sass/constant/string'
require 'sass/constant/number' require 'sass/constant/number'
require 'sass/constant/color' require 'sass/constant/color'
require 'sass/constant/bool'
require 'sass/constant/nil' require 'sass/constant/nil'
class Sass::Constant::Literal # :nodoc: class Sass::Constant::Literal # :nodoc:
@ -23,6 +24,8 @@ class Sass::Constant::Literal # :nodoc:
Sass::Constant::Number.new(value) Sass::Constant::Number.new(value)
when COLOR when COLOR
Sass::Constant::Color.new(value) Sass::Constant::Color.new(value)
when "true", "false"
Sass::Constant::Bool.new(value)
when ::Symbol when ::Symbol
value value
else else
@ -42,6 +45,14 @@ class Sass::Constant::Literal # :nodoc:
self self
end end
def and(other)
to_bool ? other : self
end
def or(other)
to_bool ? self : other
end
def concat(other) def concat(other)
Sass::Constant::String.from_value("#{self.to_s} #{other.to_s}") Sass::Constant::String.from_value("#{self.to_s} #{other.to_s}")
end end
@ -58,6 +69,10 @@ class Sass::Constant::Literal # :nodoc:
[self] [self]
end end
def to_bool
true
end
attr_reader :value attr_reader :value
protected protected

View File

@ -9,5 +9,9 @@ module Sass::Constant
def to_arglist def to_arglist
[] []
end end
def to_bool
false
end
end end
end end

View File

@ -7,6 +7,9 @@ require 'sass/constant/unary_operation'
module Sass::Constant module Sass::Constant
class Operation # :nodoc: class Operation # :nodoc:
def initialize(operand1, operand2, operator) def initialize(operand1, operand2, operator)
raise Sass::SyntaxError.new("SassScript doesn't support a single-& operator.") if operator == :single_and
raise Sass::SyntaxError.new("SassScript doesn't support a single-| operator.") if operator == :single_or
@operand1 = operand1 @operand1 = operand1
@operand2 = operand2 @operand2 = operand2
@operator = operator @operator = operator

View File

@ -67,6 +67,8 @@ class SassEngineTest < Test::Unit::TestCase
"=a(!foo bar)" => "Invalid constant \"!foo bar\".", "=a(!foo bar)" => "Invalid constant \"!foo bar\".",
"=foo\n bar: baz\n+foo" => ["Attributes aren't allowed at the root of a document.", 2], "=foo\n bar: baz\n+foo" => ["Attributes aren't allowed at the root of a document.", 2],
"a-\#{!b\n c: d" => ["Unbalanced brackets.", 1], "a-\#{!b\n c: d" => ["Unbalanced brackets.", 1],
"!a = 1 & 2" => "SassScript doesn't support a single-& operator.",
"!a = 1 | 2" => "SassScript doesn't support a single-| operator.",
# Regression tests # Regression tests
"a\n b:\n c\n d" => ["Illegal nesting: Only attributes may be nested beneath attributes.", 3], "a\n b:\n c\n d" => ["Illegal nesting: Only attributes may be nested beneath attributes.", 3],
@ -369,6 +371,43 @@ a-\#{!a}
SASS SASS
end end
def test_booleans
assert_equal(<<CSS, render(<<SASS))
a {
b: true;
c: false;
t1: true;
t2: true;
t3: true;
t4: true;
f1: false;
f2: false;
f3: false;
f4: false; }
CSS
a
b = true
c = false
t1 = true && true
t2 = false || true
t3 = true || false
t4 = true || true
f1 = false || false
f2 = false && true
f3 = true && false
f4 = false && false
SASS
end
def test_boolean_ops
assert_equal("a {\n b: 1;\n c: 2;\n d: 3; }\n", render(<<SASS))
a
b = false || 1
c = 2 || 3
d = 2 && 3
SASS
end
def test_functions def test_functions
assert_equal("a {\n b: #80ff80; }\n", render("a\n b = hsl(120, 100%, 75%)")) assert_equal("a {\n b: #80ff80; }\n", render("a\n b = hsl(120, 100%, 75%)"))
assert_equal("a {\n b: #81ff81; }\n", render("a\n b = hsl(120, 100%, 75%) + #010001")) assert_equal("a {\n b: #81ff81; }\n", render("a\n b = hsl(120, 100%, 75%) + #010001"))