haml 1.8.0 → 2.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/FAQ +138 -0
- data/MIT-LICENSE +1 -1
- data/{README → README.rdoc} +66 -3
- data/REVISION +1 -0
- data/Rakefile +115 -147
- data/VERSION +1 -1
- data/bin/css2sass +0 -0
- data/bin/haml +2 -1
- data/bin/html2haml +0 -0
- data/bin/sass +0 -0
- data/init.rb +6 -1
- data/lib/haml/buffer.rb +122 -64
- data/lib/haml/engine.rb +77 -46
- data/lib/haml/error.rb +15 -6
- data/lib/haml/exec.rb +61 -10
- data/lib/haml/filters.rb +229 -74
- data/lib/haml/helpers/action_view_extensions.rb +1 -1
- data/lib/haml/helpers/action_view_mods.rb +109 -24
- data/lib/haml/helpers.rb +137 -76
- data/lib/haml/html.rb +8 -8
- data/lib/haml/precompiler.rb +280 -153
- data/lib/haml/template/patch.rb +10 -3
- data/lib/haml/template/plugin.rb +61 -10
- data/lib/haml/template.rb +14 -9
- data/lib/haml.rb +483 -214
- data/lib/sass/constant/color.rb +13 -13
- data/lib/sass/constant/literal.rb +8 -7
- data/lib/sass/constant/nil.rb +9 -0
- data/lib/sass/constant/number.rb +10 -10
- data/lib/sass/constant/operation.rb +4 -4
- data/lib/sass/constant/string.rb +3 -3
- data/lib/sass/constant.rb +46 -77
- data/lib/sass/css.rb +130 -56
- data/lib/sass/engine.rb +131 -43
- data/lib/sass/plugin/merb.rb +48 -12
- data/lib/sass/plugin/rails.rb +10 -4
- data/lib/sass/plugin.rb +33 -10
- data/lib/sass/tree/attr_node.rb +5 -5
- data/lib/sass/tree/directive_node.rb +2 -7
- data/lib/sass/tree/node.rb +1 -12
- data/lib/sass/tree/rule_node.rb +39 -31
- data/lib/sass/tree/value_node.rb +1 -1
- data/lib/sass.rb +194 -19
- data/rails/init.rb +1 -0
- data/test/benchmark.rb +67 -80
- data/test/haml/engine_test.rb +368 -152
- data/test/haml/helper_test.rb +68 -16
- data/test/haml/html2haml_test.rb +3 -4
- data/test/haml/results/content_for_layout.xhtml +1 -2
- data/test/haml/results/eval_suppressed.xhtml +2 -4
- data/test/haml/results/filters.xhtml +38 -30
- data/test/haml/results/helpers.xhtml +4 -8
- data/test/haml/results/just_stuff.xhtml +8 -7
- data/test/haml/results/nuke_inner_whitespace.xhtml +40 -0
- data/test/haml/results/nuke_outer_whitespace.xhtml +148 -0
- data/test/haml/results/original_engine.xhtml +3 -7
- data/test/haml/results/partials.xhtml +1 -0
- data/test/haml/results/tag_parsing.xhtml +1 -6
- data/test/haml/results/very_basic.xhtml +2 -4
- data/test/haml/results/whitespace_handling.xhtml +13 -21
- data/test/haml/template_test.rb +42 -57
- data/test/haml/templates/_partial.haml +1 -0
- data/test/haml/templates/filters.haml +39 -21
- data/test/haml/templates/helpers.haml +10 -10
- data/test/haml/templates/just_stuff.haml +8 -3
- data/test/haml/templates/nuke_inner_whitespace.haml +32 -0
- data/test/haml/templates/nuke_outer_whitespace.haml +144 -0
- data/test/haml/templates/partials.haml +1 -1
- data/test/haml/templates/tag_parsing.haml +0 -3
- data/test/haml/templates/whitespace_handling.haml +10 -10
- data/test/sass/engine_test.rb +97 -39
- data/test/sass/plugin_test.rb +4 -7
- data/test/sass/results/constants.css +2 -0
- data/test/sass/results/import.css +2 -2
- data/test/sass/results/mixins.css +95 -0
- data/test/sass/results/multiline.css +24 -0
- data/test/sass/templates/constants.sass +3 -0
- data/test/sass/templates/import.sass +4 -1
- data/test/sass/templates/importee.sass +4 -0
- data/test/sass/templates/mixins.sass +76 -0
- data/test/sass/templates/multiline.sass +20 -0
- data/test/test_helper.rb +18 -0
- metadata +70 -53
- data/lib/haml/helpers/action_view_mods.rb.rej +0 -30
- data/lib/haml/util.rb +0 -18
- data/lib/sass/constant.rb.rej +0 -42
- data/test/haml/runner.rb +0 -16
- data/test/profile.rb +0 -65
- data/test/sass/engine_test.rb.rej +0 -18
data/lib/sass/constant/color.rb
CHANGED
|
@@ -21,9 +21,9 @@ module Sass::Constant # :nodoc:
|
|
|
21
21
|
'teal' => 0x008080,
|
|
22
22
|
'aqua' => 0x00ffff
|
|
23
23
|
}
|
|
24
|
-
|
|
24
|
+
|
|
25
25
|
REGEXP = /\##{"([0-9a-fA-F]{1,2})" * 3}/
|
|
26
|
-
|
|
26
|
+
|
|
27
27
|
def parse(value)
|
|
28
28
|
if (value =~ REGEXP)
|
|
29
29
|
@value = value.scan(REGEXP)[0].map { |num| num.ljust(2, num).to_i(16) }
|
|
@@ -32,7 +32,7 @@ module Sass::Constant # :nodoc:
|
|
|
32
32
|
@value = (0..2).map{ |n| color >> (n << 3) & 0xff }.reverse
|
|
33
33
|
end
|
|
34
34
|
end
|
|
35
|
-
|
|
35
|
+
|
|
36
36
|
def plus(other)
|
|
37
37
|
if other.is_a? Sass::Constant::String
|
|
38
38
|
Sass::Constant::String.from_value(self.to_s + other.to_s)
|
|
@@ -40,7 +40,7 @@ module Sass::Constant # :nodoc:
|
|
|
40
40
|
piecewise(other, :+)
|
|
41
41
|
end
|
|
42
42
|
end
|
|
43
|
-
|
|
43
|
+
|
|
44
44
|
def minus(other)
|
|
45
45
|
if other.is_a? Sass::Constant::String
|
|
46
46
|
raise NoMethodError.new(nil, :minus)
|
|
@@ -48,7 +48,7 @@ module Sass::Constant # :nodoc:
|
|
|
48
48
|
piecewise(other, :-)
|
|
49
49
|
end
|
|
50
50
|
end
|
|
51
|
-
|
|
51
|
+
|
|
52
52
|
def times(other)
|
|
53
53
|
if other.is_a? Sass::Constant::String
|
|
54
54
|
raise NoMethodError.new(nil, :times)
|
|
@@ -56,7 +56,7 @@ module Sass::Constant # :nodoc:
|
|
|
56
56
|
piecewise(other, :*)
|
|
57
57
|
end
|
|
58
58
|
end
|
|
59
|
-
|
|
59
|
+
|
|
60
60
|
def div(other)
|
|
61
61
|
if other.is_a? Sass::Constant::String
|
|
62
62
|
raise NoMethodError.new(nil, :div)
|
|
@@ -64,7 +64,7 @@ module Sass::Constant # :nodoc:
|
|
|
64
64
|
piecewise(other, :/)
|
|
65
65
|
end
|
|
66
66
|
end
|
|
67
|
-
|
|
67
|
+
|
|
68
68
|
def mod(other)
|
|
69
69
|
if other.is_a? Sass::Constant::String
|
|
70
70
|
raise NoMethodError.new(nil, :mod)
|
|
@@ -72,24 +72,24 @@ module Sass::Constant # :nodoc:
|
|
|
72
72
|
piecewise(other, :%)
|
|
73
73
|
end
|
|
74
74
|
end
|
|
75
|
-
|
|
75
|
+
|
|
76
76
|
def to_s
|
|
77
77
|
red, green, blue = @value.map { |num| num.to_s(16).rjust(2, '0') }
|
|
78
78
|
"##{red}#{green}#{blue}"
|
|
79
79
|
end
|
|
80
|
-
|
|
80
|
+
|
|
81
81
|
protected
|
|
82
|
-
|
|
82
|
+
|
|
83
83
|
def self.filter_value(value)
|
|
84
84
|
value.map { |num| num.to_i }
|
|
85
85
|
end
|
|
86
|
-
|
|
86
|
+
|
|
87
87
|
private
|
|
88
|
-
|
|
88
|
+
|
|
89
89
|
def piecewise(other, operation)
|
|
90
90
|
other_num = other.is_a? Number
|
|
91
91
|
other_val = other.value
|
|
92
|
-
|
|
92
|
+
|
|
93
93
|
rgb = []
|
|
94
94
|
for i in (0...3)
|
|
95
95
|
res = @value[i].send(operation, other_num ? other_val : other_val[i])
|
|
@@ -4,6 +4,7 @@ module Sass::Constant; class Literal; end; end; # :nodoc:
|
|
|
4
4
|
require 'sass/constant/string'
|
|
5
5
|
require 'sass/constant/number'
|
|
6
6
|
require 'sass/constant/color'
|
|
7
|
+
require 'sass/constant/nil'
|
|
7
8
|
|
|
8
9
|
class Sass::Constant::Literal # :nodoc:
|
|
9
10
|
# The regular expression matching numbers.
|
|
@@ -13,7 +14,7 @@ class Sass::Constant::Literal # :nodoc:
|
|
|
13
14
|
|
|
14
15
|
# The regular expression matching colors.
|
|
15
16
|
COLOR = /^\# (?: [\da-f]{3} | [\da-f]{6} ) | #{html_color_matcher}/ix
|
|
16
|
-
|
|
17
|
+
|
|
17
18
|
def self.parse(value)
|
|
18
19
|
case value
|
|
19
20
|
when NUMBER
|
|
@@ -24,11 +25,11 @@ class Sass::Constant::Literal # :nodoc:
|
|
|
24
25
|
Sass::Constant::String.new(value)
|
|
25
26
|
end
|
|
26
27
|
end
|
|
27
|
-
|
|
28
|
+
|
|
28
29
|
def initialize(value = nil)
|
|
29
30
|
self.parse(value) if value
|
|
30
31
|
end
|
|
31
|
-
|
|
32
|
+
|
|
32
33
|
def perform
|
|
33
34
|
self
|
|
34
35
|
end
|
|
@@ -36,15 +37,15 @@ class Sass::Constant::Literal # :nodoc:
|
|
|
36
37
|
def concat(other)
|
|
37
38
|
Sass::Constant::String.from_value("#{self.to_s} #{other.to_s}")
|
|
38
39
|
end
|
|
39
|
-
|
|
40
|
+
|
|
40
41
|
attr_reader :value
|
|
41
|
-
|
|
42
|
+
|
|
42
43
|
protected
|
|
43
|
-
|
|
44
|
+
|
|
44
45
|
def self.filter_value(value)
|
|
45
46
|
value
|
|
46
47
|
end
|
|
47
|
-
|
|
48
|
+
|
|
48
49
|
def self.from_value(value)
|
|
49
50
|
instance = self.new
|
|
50
51
|
instance.instance_variable_set('@value', self.filter_value(value))
|
data/lib/sass/constant/number.rb
CHANGED
|
@@ -8,9 +8,9 @@ module Sass::Constant # :nodoc:
|
|
|
8
8
|
def parse(value)
|
|
9
9
|
first, second, unit = value.scan(Literal::NUMBER)[0]
|
|
10
10
|
@value = first.empty? ? second.to_i : "#{first}#{second}".to_f
|
|
11
|
-
@unit = unit
|
|
11
|
+
@unit = unit.empty? ? nil : unit
|
|
12
12
|
end
|
|
13
|
-
|
|
13
|
+
|
|
14
14
|
def plus(other)
|
|
15
15
|
if other.is_a? Number
|
|
16
16
|
operate(other, :+)
|
|
@@ -20,7 +20,7 @@ module Sass::Constant # :nodoc:
|
|
|
20
20
|
Sass::Constant::String.from_value(self.to_s + other.to_s)
|
|
21
21
|
end
|
|
22
22
|
end
|
|
23
|
-
|
|
23
|
+
|
|
24
24
|
def minus(other)
|
|
25
25
|
if other.is_a? Number
|
|
26
26
|
operate(other, :-)
|
|
@@ -28,7 +28,7 @@ module Sass::Constant # :nodoc:
|
|
|
28
28
|
raise NoMethodError.new(nil, :minus)
|
|
29
29
|
end
|
|
30
30
|
end
|
|
31
|
-
|
|
31
|
+
|
|
32
32
|
def times(other)
|
|
33
33
|
if other.is_a? Number
|
|
34
34
|
operate(other, :*)
|
|
@@ -38,7 +38,7 @@ module Sass::Constant # :nodoc:
|
|
|
38
38
|
raise NoMethodError.new(nil, :times)
|
|
39
39
|
end
|
|
40
40
|
end
|
|
41
|
-
|
|
41
|
+
|
|
42
42
|
def div(other)
|
|
43
43
|
if other.is_a? Number
|
|
44
44
|
operate(other, :/)
|
|
@@ -46,7 +46,7 @@ module Sass::Constant # :nodoc:
|
|
|
46
46
|
raise NoMethodError.new(nil, :div)
|
|
47
47
|
end
|
|
48
48
|
end
|
|
49
|
-
|
|
49
|
+
|
|
50
50
|
def mod(other)
|
|
51
51
|
if other.is_a? Number
|
|
52
52
|
operate(other, :%)
|
|
@@ -54,13 +54,13 @@ module Sass::Constant # :nodoc:
|
|
|
54
54
|
raise NoMethodError.new(nil, :mod)
|
|
55
55
|
end
|
|
56
56
|
end
|
|
57
|
-
|
|
57
|
+
|
|
58
58
|
def to_s
|
|
59
59
|
value = @value
|
|
60
60
|
value = value.to_i if value % 1 == 0.0
|
|
61
61
|
"#{value}#{@unit}"
|
|
62
62
|
end
|
|
63
|
-
|
|
63
|
+
|
|
64
64
|
protected
|
|
65
65
|
|
|
66
66
|
def self.from_value(value, unit=nil)
|
|
@@ -68,7 +68,7 @@ module Sass::Constant # :nodoc:
|
|
|
68
68
|
instance.instance_variable_set('@unit', unit)
|
|
69
69
|
instance
|
|
70
70
|
end
|
|
71
|
-
|
|
71
|
+
|
|
72
72
|
def operate(other, operation)
|
|
73
73
|
unit = nil
|
|
74
74
|
if other.unit.nil?
|
|
@@ -78,7 +78,7 @@ module Sass::Constant # :nodoc:
|
|
|
78
78
|
elsif other.unit == self.unit
|
|
79
79
|
unit = self.unit
|
|
80
80
|
else
|
|
81
|
-
raise Sass::SyntaxError.new("Incompatible units: #{self.unit} and #{other.unit}")
|
|
81
|
+
raise Sass::SyntaxError.new("Incompatible units: #{self.unit} and #{other.unit}.")
|
|
82
82
|
end
|
|
83
83
|
|
|
84
84
|
Number.from_value(self.value.send(operation, other.value), unit)
|
|
@@ -9,13 +9,13 @@ module Sass::Constant # :nodoc:
|
|
|
9
9
|
@operand2 = operand2
|
|
10
10
|
@operator = operator
|
|
11
11
|
end
|
|
12
|
-
|
|
12
|
+
|
|
13
13
|
def to_s
|
|
14
14
|
self.perform.to_s
|
|
15
15
|
end
|
|
16
|
-
|
|
16
|
+
|
|
17
17
|
protected
|
|
18
|
-
|
|
18
|
+
|
|
19
19
|
def perform
|
|
20
20
|
literal1 = @operand1.perform
|
|
21
21
|
literal2 = @operand2.perform
|
|
@@ -23,7 +23,7 @@ module Sass::Constant # :nodoc:
|
|
|
23
23
|
literal1.send(@operator, literal2)
|
|
24
24
|
rescue NoMethodError => e
|
|
25
25
|
raise e unless e.name.to_s == @operator.to_s
|
|
26
|
-
raise Sass::SyntaxError.new("Undefined operation: \"#{literal1} #{@operator} #{literal2}\"")
|
|
26
|
+
raise Sass::SyntaxError.new("Undefined operation: \"#{literal1} #{@operator} #{literal2}\".")
|
|
27
27
|
end
|
|
28
28
|
end
|
|
29
29
|
end
|
data/lib/sass/constant/string.rb
CHANGED
|
@@ -2,11 +2,11 @@ require 'sass/constant/literal'
|
|
|
2
2
|
|
|
3
3
|
module Sass::Constant # :nodoc:
|
|
4
4
|
class String < Literal # :nodoc:
|
|
5
|
-
|
|
5
|
+
|
|
6
6
|
def parse(value)
|
|
7
7
|
@value = value
|
|
8
8
|
end
|
|
9
|
-
|
|
9
|
+
|
|
10
10
|
def plus(other)
|
|
11
11
|
Sass::Constant::String.from_value(self.to_s + other.to_s)
|
|
12
12
|
end
|
|
@@ -14,7 +14,7 @@ module Sass::Constant # :nodoc:
|
|
|
14
14
|
def funcall(other)
|
|
15
15
|
Sass::Constant::String.from_value("#{self.to_s}(#{other.to_s})")
|
|
16
16
|
end
|
|
17
|
-
|
|
17
|
+
|
|
18
18
|
def to_s
|
|
19
19
|
@value
|
|
20
20
|
end
|
data/lib/sass/constant.rb
CHANGED
|
@@ -8,13 +8,13 @@ module Sass
|
|
|
8
8
|
|
|
9
9
|
# Whitespace characters
|
|
10
10
|
WHITESPACE = [?\ , ?\t, ?\n, ?\r]
|
|
11
|
-
|
|
11
|
+
|
|
12
12
|
# The character used to escape values
|
|
13
13
|
ESCAPE_CHAR = ?\\
|
|
14
14
|
|
|
15
15
|
# The character used to open and close strings
|
|
16
16
|
STRING_CHAR = ?"
|
|
17
|
-
|
|
17
|
+
|
|
18
18
|
# A mapping of syntactically-significant characters
|
|
19
19
|
# to parsed symbols
|
|
20
20
|
SYMBOLS = {
|
|
@@ -31,14 +31,14 @@ module Sass
|
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
# The regular expression used to parse constants
|
|
34
|
-
MATCH = /^#{Regexp.escape(CONSTANT_CHAR.chr)}([^\s#{(SYMBOLS.keys + [ ?= ]).map {|c| Regexp.escape("#{c.chr}") }.join}]+)\s
|
|
35
|
-
|
|
34
|
+
MATCH = /^#{Regexp.escape(CONSTANT_CHAR.chr)}([^\s#{(SYMBOLS.keys + [ ?= ]).map {|c| Regexp.escape("#{c.chr}") }.join}]+)\s*((?:\|\|)?=)\s*(.+)/
|
|
35
|
+
|
|
36
36
|
# First-order operations
|
|
37
37
|
FIRST_ORDER = [:times, :div, :mod]
|
|
38
|
-
|
|
38
|
+
|
|
39
39
|
# Second-order operations
|
|
40
40
|
SECOND_ORDER = [:plus, :minus]
|
|
41
|
-
|
|
41
|
+
|
|
42
42
|
class << self
|
|
43
43
|
def parse(value, constants, line)
|
|
44
44
|
begin
|
|
@@ -46,28 +46,28 @@ module Sass
|
|
|
46
46
|
rescue Sass::SyntaxError => e
|
|
47
47
|
if e.message == "Constant arithmetic error"
|
|
48
48
|
e.instance_eval do
|
|
49
|
-
@message += ": #{value.dump}"
|
|
49
|
+
@message += ": #{value.dump}."
|
|
50
50
|
end
|
|
51
51
|
end
|
|
52
52
|
e.sass_line = line
|
|
53
53
|
raise e
|
|
54
54
|
end
|
|
55
55
|
end
|
|
56
|
-
|
|
56
|
+
|
|
57
57
|
private
|
|
58
|
-
|
|
58
|
+
|
|
59
59
|
def tokenize(value)
|
|
60
60
|
escaped = false
|
|
61
61
|
is_string = false
|
|
62
62
|
beginning_of_token = true
|
|
63
63
|
str = ''
|
|
64
64
|
to_return = []
|
|
65
|
-
|
|
65
|
+
|
|
66
66
|
reset_str = Proc.new do
|
|
67
67
|
to_return << str unless str.empty?
|
|
68
68
|
''
|
|
69
69
|
end
|
|
70
|
-
|
|
70
|
+
|
|
71
71
|
value.each_byte do |byte|
|
|
72
72
|
unless escaped
|
|
73
73
|
if byte == ESCAPE_CHAR
|
|
@@ -97,7 +97,7 @@ module Sass
|
|
|
97
97
|
str = reset_str.call
|
|
98
98
|
next
|
|
99
99
|
end
|
|
100
|
-
|
|
100
|
+
|
|
101
101
|
symbol = SYMBOLS[byte]
|
|
102
102
|
|
|
103
103
|
# Adjacent values without an operator should be concatenated
|
|
@@ -119,95 +119,64 @@ module Sass
|
|
|
119
119
|
next
|
|
120
120
|
end
|
|
121
121
|
|
|
122
|
-
# Is this a constant?
|
|
123
|
-
if beginning_of_token && symbol == :const
|
|
124
|
-
beginning_of_token = true
|
|
125
|
-
to_return << :const
|
|
126
|
-
next
|
|
127
|
-
end
|
|
128
|
-
|
|
129
122
|
# Are we looking at an operator?
|
|
130
123
|
if symbol && (symbol != :mod || str.empty?)
|
|
131
124
|
str = reset_str.call
|
|
132
|
-
beginning_of_token =
|
|
125
|
+
beginning_of_token = symbol != :close
|
|
133
126
|
to_return << symbol
|
|
134
127
|
next
|
|
135
128
|
end
|
|
136
129
|
end
|
|
137
130
|
end
|
|
138
|
-
|
|
131
|
+
|
|
139
132
|
escaped = false
|
|
140
133
|
beginning_of_token = false
|
|
141
134
|
str << byte.chr
|
|
142
135
|
end
|
|
143
|
-
|
|
136
|
+
|
|
144
137
|
if is_string
|
|
145
|
-
raise Sass::SyntaxError.new("Unterminated string: #{value.dump}")
|
|
138
|
+
raise Sass::SyntaxError.new("Unterminated string: #{value.dump}.")
|
|
146
139
|
end
|
|
147
140
|
str = reset_str.call
|
|
148
141
|
to_return
|
|
149
142
|
end
|
|
150
|
-
|
|
151
|
-
def parenthesize(value)
|
|
152
|
-
parenthesize_helper(0, value, value.length)[0]
|
|
153
|
-
end
|
|
154
|
-
|
|
155
|
-
def parenthesize_helper(i, value, value_len, return_after_expr = false)
|
|
143
|
+
|
|
144
|
+
def parenthesize(value, return_after_expr = false)
|
|
156
145
|
to_return = []
|
|
157
|
-
|
|
158
|
-
token = value
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
to_return <<
|
|
166
|
-
|
|
167
|
-
if value
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
sub, i = parenthesize_helper(i + 2, value, value_len)
|
|
173
|
-
beginning = i
|
|
174
|
-
to_return << [:neg, sub]
|
|
175
|
-
elsif value[i + 1].is_a?(::Symbol)
|
|
176
|
-
to_return.push(*value[beginning...i])
|
|
177
|
-
sub, i = parenthesize_helper(i + 1, value, value_len, true)
|
|
178
|
-
beginning = i
|
|
179
|
-
to_return << [:neg, sub]
|
|
180
|
-
else
|
|
181
|
-
to_return.push(*value[beginning...i])
|
|
182
|
-
to_return << [:neg, value[i + 1]]
|
|
183
|
-
beginning = i = i + 2
|
|
184
|
-
end
|
|
185
|
-
return to_return[0], i if return_after_expr
|
|
186
|
-
elsif token == :const
|
|
187
|
-
raise Sass::SyntaxError.new("Unterminated constant.") if value[i + 1].nil?
|
|
188
|
-
raise Sass::SyntaxError.new("Invalid constant.") unless value[i + 1].is_a?(::String)
|
|
189
|
-
|
|
190
|
-
to_return.push(*value[beginning...i])
|
|
191
|
-
to_return << [:const, value[i + 1]]
|
|
192
|
-
beginning = i = i + 2
|
|
193
|
-
return to_return[0], i if return_after_expr
|
|
146
|
+
|
|
147
|
+
while (token = value.shift) && token != :close
|
|
148
|
+
case token
|
|
149
|
+
when :open
|
|
150
|
+
to_return << parenthesize(value)
|
|
151
|
+
when :neg
|
|
152
|
+
# This is never actually reached, but we'll leave it in just in case.
|
|
153
|
+
raise Sass::SyntaxError.new("Unterminated unary minus.") if value.first.nil?
|
|
154
|
+
to_return << [:neg, parenthesize(value, true)]
|
|
155
|
+
when :const
|
|
156
|
+
raise Sass::SyntaxError.new("Unterminated constant.") if value.first.nil?
|
|
157
|
+
raise Sass::SyntaxError.new("Invalid constant.") unless value.first.is_a?(::String)
|
|
158
|
+
|
|
159
|
+
to_return << [:const, value.first]
|
|
160
|
+
value.shift
|
|
194
161
|
else
|
|
195
|
-
|
|
162
|
+
to_return << token
|
|
196
163
|
end
|
|
197
|
-
|
|
198
|
-
|
|
164
|
+
|
|
165
|
+
return to_return.first if return_after_expr
|
|
199
166
|
end
|
|
200
|
-
to_return
|
|
201
|
-
return to_return, i + 1
|
|
167
|
+
return to_return
|
|
202
168
|
end
|
|
203
|
-
|
|
169
|
+
|
|
204
170
|
#--
|
|
205
171
|
# TODO: Don't pass around original value;
|
|
206
172
|
# have Constant.parse automatically add it to exception.
|
|
207
173
|
#++
|
|
208
174
|
def operationalize(value, constants)
|
|
209
175
|
value = [value] unless value.is_a?(Array)
|
|
210
|
-
|
|
176
|
+
case value.length
|
|
177
|
+
when 0
|
|
178
|
+
Sass::Constant::Nil.new
|
|
179
|
+
when 1
|
|
211
180
|
value = value[0]
|
|
212
181
|
if value.is_a? Array
|
|
213
182
|
operationalize(value, constants)
|
|
@@ -216,7 +185,7 @@ module Sass
|
|
|
216
185
|
else
|
|
217
186
|
Literal.parse(value)
|
|
218
187
|
end
|
|
219
|
-
|
|
188
|
+
when 2
|
|
220
189
|
if value[0] == :neg
|
|
221
190
|
Operation.new(Sass::Constant::Number.new('0'), operationalize(value[1], constants), :minus)
|
|
222
191
|
elsif value[0] == :const
|
|
@@ -224,7 +193,7 @@ module Sass
|
|
|
224
193
|
else
|
|
225
194
|
raise SyntaxError.new("Constant arithmetic error")
|
|
226
195
|
end
|
|
227
|
-
|
|
196
|
+
when 3
|
|
228
197
|
Operation.new(operationalize(value[0], constants), operationalize(value[2], constants), value[1])
|
|
229
198
|
else
|
|
230
199
|
if SECOND_ORDER.include?(value[1]) && FIRST_ORDER.include?(value[3])
|
|
@@ -234,10 +203,10 @@ module Sass
|
|
|
234
203
|
end
|
|
235
204
|
end
|
|
236
205
|
end
|
|
237
|
-
|
|
206
|
+
|
|
238
207
|
def get_constant(value, constants)
|
|
239
208
|
to_return = constants[value]
|
|
240
|
-
raise SyntaxError.new("Undefined constant: \"!#{value}\"") unless to_return
|
|
209
|
+
raise SyntaxError.new("Undefined constant: \"!#{value}\".") unless to_return
|
|
241
210
|
to_return
|
|
242
211
|
end
|
|
243
212
|
end
|