haml-edge 2.1.21 → 2.1.22

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. data/EDGE_GEM_VERSION +1 -1
  2. data/FAQ.md +142 -0
  3. data/{README.rdoc → README.md} +141 -141
  4. data/Rakefile +29 -17
  5. data/VERSION +1 -1
  6. data/lib/haml/buffer.rb +63 -27
  7. data/lib/haml/engine.rb +103 -80
  8. data/lib/haml/error.rb +7 -7
  9. data/lib/haml/exec.rb +80 -26
  10. data/lib/haml/filters.rb +106 -40
  11. data/lib/haml/helpers/action_view_extensions.rb +34 -39
  12. data/lib/haml/helpers/action_view_mods.rb +132 -139
  13. data/lib/haml/helpers.rb +207 -153
  14. data/lib/haml/html.rb +40 -21
  15. data/lib/haml/precompiler.rb +2 -0
  16. data/lib/haml/shared.rb +34 -3
  17. data/lib/haml/template/patch.rb +1 -1
  18. data/lib/haml/template/plugin.rb +0 -2
  19. data/lib/haml/template.rb +5 -0
  20. data/lib/haml/util.rb +136 -1
  21. data/lib/haml/version.rb +16 -4
  22. data/lib/haml.rb +502 -481
  23. data/lib/sass/css.rb +106 -68
  24. data/lib/sass/engine.rb +55 -22
  25. data/lib/sass/environment.rb +52 -21
  26. data/lib/sass/error.rb +23 -12
  27. data/lib/sass/files.rb +27 -0
  28. data/lib/sass/plugin/merb.rb +2 -2
  29. data/lib/sass/plugin/rails.rb +0 -2
  30. data/lib/sass/plugin.rb +32 -23
  31. data/lib/sass/repl.rb +7 -0
  32. data/lib/sass/script/bool.rb +9 -5
  33. data/lib/sass/script/color.rb +87 -1
  34. data/lib/sass/script/funcall.rb +23 -2
  35. data/lib/sass/script/functions.rb +93 -44
  36. data/lib/sass/script/lexer.rb +33 -3
  37. data/lib/sass/script/literal.rb +93 -1
  38. data/lib/sass/script/node.rb +14 -0
  39. data/lib/sass/script/number.rb +128 -4
  40. data/lib/sass/script/operation.rb +16 -1
  41. data/lib/sass/script/parser.rb +51 -21
  42. data/lib/sass/script/string.rb +7 -4
  43. data/lib/sass/script/unary_operation.rb +14 -1
  44. data/lib/sass/script/variable.rb +12 -1
  45. data/lib/sass/script.rb +26 -5
  46. data/lib/sass/tree/attr_node.rb +46 -9
  47. data/lib/sass/tree/comment_node.rb +41 -1
  48. data/lib/sass/tree/debug_node.rb +8 -0
  49. data/lib/sass/tree/directive_node.rb +20 -0
  50. data/lib/sass/tree/file_node.rb +12 -0
  51. data/lib/sass/tree/for_node.rb +15 -0
  52. data/lib/sass/tree/if_node.rb +22 -0
  53. data/lib/sass/tree/mixin_def_node.rb +12 -1
  54. data/lib/sass/tree/mixin_node.rb +13 -0
  55. data/lib/sass/tree/node.rb +136 -6
  56. data/lib/sass/tree/rule_node.rb +66 -7
  57. data/lib/sass/tree/variable_node.rb +10 -0
  58. data/lib/sass/tree/while_node.rb +11 -1
  59. data/lib/sass.rb +544 -534
  60. metadata +7 -6
  61. data/FAQ +0 -138
@@ -1,80 +1,172 @@
1
1
  module Sass::Script
2
- class Literal # :nodoc:
2
+ # The abstract superclass for SassScript objects.
3
+ #
4
+ # Many of these methods, especially the ones that correspond to SassScript operations,
5
+ # are designed to be overridden by subclasses which may change the semantics somewhat.
6
+ # The operations listed here are just the defaults.
7
+ class Literal < Node
3
8
  require 'sass/script/string'
4
9
  require 'sass/script/number'
5
10
  require 'sass/script/color'
6
11
  require 'sass/script/bool'
7
12
 
13
+ # Returns the Ruby value of the literal.
14
+ # The type of this value varies based on the subclass.
15
+ #
16
+ # @return [Object]
8
17
  attr_reader :value
9
18
 
19
+ # Creates a new literal.
20
+ #
21
+ # @param value [Object] The object for \{#value}
10
22
  def initialize(value = nil)
11
23
  @value = value
12
24
  end
13
25
 
26
+ # Evaluates the literal.
27
+ #
28
+ # @param environment [Sass::Environment] The environment in which to evaluate the SassScript
29
+ # @return [Literal] This literal
14
30
  def perform(environment)
15
31
  self
16
32
  end
17
33
 
34
+ # The SassScript `and` operation.
35
+ #
36
+ # @param other [Literal] The right-hand side of the operator
37
+ # @return [Literal] The result of a logical and:
38
+ # `other` if this literal isn't a false {Bool},
39
+ # and this literal otherwise
18
40
  def and(other)
19
41
  to_bool ? other : self
20
42
  end
21
43
 
44
+ # The SassScript `or` operation.
45
+ #
46
+ # @param other [Literal] The right-hand side of the operator
47
+ # @return [Literal] The result of the logical or:
48
+ # this literal if it isn't a false {Bool},
49
+ # and `other` otherwise
22
50
  def or(other)
23
51
  to_bool ? self : other
24
52
  end
25
53
 
54
+ # The SassScript `==` operation.
55
+ # **Note that this returns a {Sass::Script::Bool} object,
56
+ # not a Ruby boolean**.
57
+ #
58
+ # @param other [Literal] The right-hand side of the operator
59
+ # @return [Bool] True if this literal is the same as the other,
60
+ # false otherwise
26
61
  def eq(other)
27
62
  Sass::Script::Bool.new(self.class == other.class && self.value == other.value)
28
63
  end
29
64
 
65
+ # The SassScript `!=` operation.
66
+ # **Note that this returns a {Sass::Script::Bool} object,
67
+ # not a Ruby boolean**.
68
+ #
69
+ # @param other [Literal] The right-hand side of the operator
70
+ # @return [Bool] False if this literal is the same as the other,
71
+ # true otherwise
30
72
  def neq(other)
31
73
  Sass::Script::Bool.new(!eq(other).to_bool)
32
74
  end
33
75
 
76
+ # The SassScript `==` operation.
77
+ # **Note that this returns a {Sass::Script::Bool} object,
78
+ # not a Ruby boolean**.
79
+ #
80
+ # @param other [Literal] The right-hand side of the operator
81
+ # @return [Bool] True if this literal is the same as the other,
82
+ # false otherwise
34
83
  def unary_not
35
84
  Sass::Script::Bool.new(!to_bool)
36
85
  end
37
86
 
87
+ # The SassScript default operation (e.g. `!a !b`, `"foo" "bar"`).
88
+ #
89
+ # @param other [Literal] The right-hand side of the operator
90
+ # @return [Script::String] A string containing both literals
91
+ # separated by a space
38
92
  def concat(other)
39
93
  Sass::Script::String.new("#{self.to_s} #{other.to_s}")
40
94
  end
41
95
 
96
+ # The SassScript `,` operation (e.g. `!a, !b`, `"foo", "bar"`).
97
+ #
98
+ # @param other [Literal] The right-hand side of the operator
99
+ # @return [Script::String] A string containing both literals
100
+ # separated by `", "`
42
101
  def comma(other)
43
102
  Sass::Script::String.new("#{self.to_s}, #{other.to_s}")
44
103
  end
45
104
 
105
+ # The SassScript `+` operation.
106
+ #
107
+ # @param other [Literal] The right-hand side of the operator
108
+ # @return [Script::String] A string containing both literals
109
+ # without any separation
46
110
  def plus(other)
47
111
  Sass::Script::String.new(self.to_s + other.to_s)
48
112
  end
49
113
 
114
+ # The SassScript `-` operation.
115
+ #
116
+ # @param other [Literal] The right-hand side of the operator
117
+ # @return [Script::String] A string containing both literals
118
+ # separated by `"-"`
50
119
  def minus(other)
51
120
  Sass::Script::String.new("#{self.to_s}-#{other.to_s}")
52
121
  end
53
122
 
123
+ # The SassScript `/` operation.
124
+ #
125
+ # @param other [Literal] The right-hand side of the operator
126
+ # @return [Script::String] A string containing both literals
127
+ # separated by `"/"`
54
128
  def div(other)
55
129
  Sass::Script::String.new("#{self.to_s}/#{other.to_s}")
56
130
  end
57
131
 
132
+ # The SassScript unary `-` operation (e.g. `-!a`).
133
+ #
134
+ # @param other [Literal] The right-hand side of the operator
135
+ # @return [Script::String] A string containing the literal
136
+ # preceded by `"-"`
58
137
  def unary_minus
59
138
  Sass::Script::String.new("-#{self.to_s}")
60
139
  end
61
140
 
141
+ # The SassScript unary `/` operation (e.g. `/!a`).
142
+ #
143
+ # @param other [Literal] The right-hand side of the operator
144
+ # @return [Script::String] A string containing the literal
145
+ # preceded by `"/"`
62
146
  def unary_div
63
147
  Sass::Script::String.new("/#{self.to_s}")
64
148
  end
65
149
 
150
+ # @return [String] A readable representation of the literal
66
151
  def inspect
67
152
  value.inspect
68
153
  end
69
154
 
155
+ # @return [Boolean] `true` (the Ruby boolean value)
70
156
  def to_bool
71
157
  true
72
158
  end
73
159
 
160
+ # Compares this object with another.
161
+ #
162
+ # @param other [Object] The object to compare with
163
+ # @return [Boolean] Whether or not this literal is equivalent to `other`
74
164
  def ==(other)
75
165
  eq(other).to_bool
76
166
  end
77
167
 
168
+ # @return [Fixnum] The integer value of this literal
169
+ # @raise [Sass::SyntaxError] if this literal isn't an integer
78
170
  def to_i
79
171
  raise Sass::SyntaxError.new("#{self.inspect} is not an integer.")
80
172
  end
@@ -0,0 +1,14 @@
1
+ module Sass::Script
2
+ # The abstract superclass for SassScript parse tree nodes.
3
+ #
4
+ # Use \{#perform} to evaluate a parse tree.
5
+ class Node
6
+ # Evaluates the node.
7
+ #
8
+ # @param environment [Sass::Environment] The environment in which to evaluate the SassScript
9
+ # @return [Literal] The SassScript object that is the value of the SassScript
10
+ def perform(environment)
11
+ raise NotImplementedError.new("All subclasses of Sass::Script::Node must override #perform.")
12
+ end
13
+ end
14
+ end
@@ -1,12 +1,38 @@
1
1
  require 'sass/script/literal'
2
2
 
3
3
  module Sass::Script
4
- class Number < Literal # :nodoc:
5
-
6
- attr_reader :numerator_units, :denominator_units
7
-
4
+ # A SassScript object representing a number.
5
+ # SassScript numbers can have decimal values,
6
+ # and can also have units.
7
+ # For example, `12`, `1px`, and `10.45em`
8
+ # are all valid values.
9
+ #
10
+ # Numbers can also have more complex units, such as `1px*em/in`.
11
+ # These cannot be inputted directly in Sass code at the moment.
12
+ class Number < Literal
13
+ # The Ruby value of the number.
14
+ #
15
+ # @return [Numeric]
16
+ attr_reader :value
17
+
18
+ # A list of units in the numerator of the number.
19
+ # For example, `1px*em/in*cm` would return `["px", "em"]`
20
+ # @return [Array<String>]
21
+ attr_reader :numerator_units
22
+
23
+ # A list of units in the denominator of the number.
24
+ # For example, `1px*em/in*cm` would return `["in", "cm"]`
25
+ # @return [Array<String>]
26
+ attr_reader :denominator_units
27
+
28
+ # The precision with which numbers will be printed to CSS files.
29
+ # For example, if this is `1000.0`,
30
+ # `3.1415926` will be printed as `3.142`.
8
31
  PRECISION = 1000.0
9
32
 
33
+ # @param value [Numeric] The value of the number
34
+ # @param numerator_units [Array<String>] See \{#numerator\_units}
35
+ # @param denominator_units [Array<String>] See \{#denominator\_units}
10
36
  def initialize(value, numerator_units = [], denominator_units = [])
11
37
  super(value)
12
38
  @numerator_units = numerator_units
@@ -14,6 +40,21 @@ module Sass::Script
14
40
  normalize!
15
41
  end
16
42
 
43
+ # The SassScript `+` operation.
44
+ # Its functionality depends on the type of its argument:
45
+ #
46
+ # {Number}
47
+ # : Adds the two numbers together, converting units if possible.
48
+ #
49
+ # {Color}
50
+ # : Adds this number to each of the RGB color channels.
51
+ #
52
+ # {Literal}
53
+ # : See {Literal#plus}.
54
+ #
55
+ # @param other [Literal] The right-hand side of the operator
56
+ # @return [Literal] The result of the operation
57
+ # @raise [Sass::SyntaxError] if `other` is a number with incompatible units
17
58
  def plus(other)
18
59
  if other.is_a? Number
19
60
  operate(other, :+)
@@ -24,6 +65,18 @@ module Sass::Script
24
65
  end
25
66
  end
26
67
 
68
+ # The SassScript binary `-` operation (e.g. `!a - !b`).
69
+ # Its functionality depends on the type of its argument:
70
+ #
71
+ # {Number}
72
+ # : Subtracts this number from the other, converting units if possible.
73
+ #
74
+ # {Literal}
75
+ # : See {Literal#minus}.
76
+ #
77
+ # @param other [Literal] The right-hand side of the operator
78
+ # @return [Literal] The result of the operation
79
+ # @raise [Sass::SyntaxError] if `other` is a number with incompatible units
27
80
  def minus(other)
28
81
  if other.is_a? Number
29
82
  operate(other, :-)
@@ -32,10 +85,25 @@ module Sass::Script
32
85
  end
33
86
  end
34
87
 
88
+ # The SassScript unary `-` operation (e.g. `-!a`).
89
+ #
90
+ # @return [Number] The negative value of this number
35
91
  def unary_minus
36
92
  Number.new(-value, numerator_units, denominator_units)
37
93
  end
38
94
 
95
+ # The SassScript `*` operation.
96
+ # Its functionality depends on the type of its argument:
97
+ #
98
+ # {Number}
99
+ # : Multiplies the two numbers together, converting units appropriately.
100
+ #
101
+ # {Color}
102
+ # : Multiplies each of the RGB color channels by this number.
103
+ #
104
+ # @param other [Number, Color] The right-hand side of the operator
105
+ # @return [Number, Color] The result of the operation
106
+ # @raise [NoMethodError] if `other` is an invalid type
39
107
  def times(other)
40
108
  if other.is_a? Number
41
109
  self.operate(other, :*)
@@ -46,6 +114,17 @@ module Sass::Script
46
114
  end
47
115
  end
48
116
 
117
+ # The SassScript `/` operation.
118
+ # Its functionality depends on the type of its argument:
119
+ #
120
+ # {Number}
121
+ # : Divides this number by the other, converting units appropriately.
122
+ #
123
+ # {Literal}
124
+ # : See {Literal#div}.
125
+ #
126
+ # @param other [Literal] The right-hand side of the operator
127
+ # @return [Literal] The result of the operation
49
128
  def div(other)
50
129
  if other.is_a? Number
51
130
  operate(other, :/)
@@ -54,6 +133,12 @@ module Sass::Script
54
133
  end
55
134
  end
56
135
 
136
+ # The SassScript `%` operation.
137
+ #
138
+ # @param other [Number] The right-hand side of the operator
139
+ # @return [Number] This number modulo the other
140
+ # @raise [NoMethodError] if `other` is an invalid type
141
+ # @raise [Sass::SyntaxError] if `other` has any units
57
142
  def mod(other)
58
143
  if other.is_a?(Number)
59
144
  unless other.unitless?
@@ -65,37 +150,70 @@ module Sass::Script
65
150
  end
66
151
  end
67
152
 
153
+ # The SassScript `==` operation.
154
+ #
155
+ # @param other [Literal] The right-hand side of the operator
156
+ # @return [Boolean] Whether this number is equal to the other object
68
157
  def eq(other)
69
158
  Sass::Script::Bool.new(super.to_bool &&
70
159
  self.numerator_units.sort == other.numerator_units.sort &&
71
160
  self.denominator_units.sort == other.denominator_units.sort)
72
161
  end
73
162
 
163
+ # The SassScript `>` operation.
164
+ #
165
+ # @param other [Number] The right-hand side of the operator
166
+ # @return [Boolean] Whether this number is greater than the other
167
+ # @raise [NoMethodError] if `other` is an invalid type
74
168
  def gt(other)
75
169
  raise NoMethodError.new(nil, :gt) unless other.is_a?(Number)
76
170
  operate(other, :>)
77
171
  end
78
172
 
173
+ # The SassScript `>=` operation.
174
+ #
175
+ # @param other [Number] The right-hand side of the operator
176
+ # @return [Boolean] Whether this number is greater than or equal to the other
177
+ # @raise [NoMethodError] if `other` is an invalid type
79
178
  def gte(other)
80
179
  raise NoMethodError.new(nil, :gte) unless other.is_a?(Number)
81
180
  operate(other, :>=)
82
181
  end
83
182
 
183
+ # The SassScript `<` operation.
184
+ #
185
+ # @param other [Number] The right-hand side of the operator
186
+ # @return [Boolean] Whether this number is less than the other
187
+ # @raise [NoMethodError] if `other` is an invalid type
84
188
  def lt(other)
85
189
  raise NoMethodError.new(nil, :lt) unless other.is_a?(Number)
86
190
  operate(other, :<)
87
191
  end
88
192
 
193
+ # The SassScript `<=` operation.
194
+ #
195
+ # @param other [Number] The right-hand side of the operator
196
+ # @return [Boolean] Whether this number is less than or equal to the other
197
+ # @raise [NoMethodError] if `other` is an invalid type
89
198
  def lte(other)
90
199
  raise NoMethodError.new(nil, :lte) unless other.is_a?(Number)
91
200
  operate(other, :<=)
92
201
  end
93
202
 
203
+ # @return [String] The CSS representation of this number
204
+ # @raise [Sass::SyntaxError] if this number has units that can't be used in CSS
205
+ # (e.g. `px*in`)
94
206
  def to_s
95
207
  raise Sass::SyntaxError.new("#{inspect} isn't a valid CSS value.") unless legal_units?
96
208
  inspect
97
209
  end
98
210
 
211
+ # Returns a readable representation of this number.
212
+ #
213
+ # This representation is valid CSS (and valid SassScript)
214
+ # as long as there is only one unit.
215
+ #
216
+ # @return [String] The representation
99
217
  def inspect
100
218
  value =
101
219
  if self.value.is_a?(Float) && (self.value.infinite? || self.value.nan?)
@@ -108,19 +226,25 @@ module Sass::Script
108
226
  "#{value}#{unit_str}"
109
227
  end
110
228
 
229
+ # @return [Fixnum] The integer value of the number
230
+ # @raise [Sass::SyntaxError] if the number isn't an integer
111
231
  def to_i
112
232
  super unless int?
113
233
  return value
114
234
  end
115
235
 
236
+ # @return [Boolean] Whether or not this number is an integer.
116
237
  def int?
117
238
  value % 1 == 0.0
118
239
  end
119
240
 
241
+ # @return [Boolean] Whether or not this number has no units.
120
242
  def unitless?
121
243
  numerator_units.empty? && denominator_units.empty?
122
244
  end
123
245
 
246
+ # @return [Boolean] Whether or not this number has units that can be represented in CSS
247
+ # (that is, zero or one \{#numerator\_units}).
124
248
  def legal_units?
125
249
  (numerator_units.empty? || numerator_units.size == 1) && denominator_units.empty?
126
250
  end
@@ -1,3 +1,4 @@
1
+ require 'set'
1
2
  require 'sass/script/string'
2
3
  require 'sass/script/number'
3
4
  require 'sass/script/color'
@@ -5,17 +6,31 @@ require 'sass/script/functions'
5
6
  require 'sass/script/unary_operation'
6
7
 
7
8
  module Sass::Script
8
- class Operation # :nodoc:
9
+ # A SassScript parse node representing a binary operation,
10
+ # such as `!a + !b` or `"foo" + 1`.
11
+ class Operation < Node
12
+ # @param operand1 [Script::Node] The parse-tree node
13
+ # for the right-hand side of the operator
14
+ # @param operand2 [Script::Node] The parse-tree node
15
+ # for the left-hand side of the operator
16
+ # @param operator [Symbol] The operator to perform.
17
+ # This should be one of the binary operator names in {Lexer::OPERATORS}
9
18
  def initialize(operand1, operand2, operator)
10
19
  @operand1 = operand1
11
20
  @operand2 = operand2
12
21
  @operator = operator
13
22
  end
14
23
 
24
+ # @return [String] A human-readable s-expression representation of the operation
15
25
  def inspect
16
26
  "(#{@operator.inspect} #{@operand1.inspect} #{@operand2.inspect})"
17
27
  end
18
28
 
29
+ # Evaluates the operation.
30
+ #
31
+ # @param environment [Sass::Environment] The environment in which to evaluate the SassScript
32
+ # @return [Literal] The SassScript object that is the value of the operation
33
+ # @raise [Sass::SyntaxError] if the operation is undefined for the operands
19
34
  def perform(environment)
20
35
  literal1 = @operand1.perform(environment)
21
36
  literal2 = @operand2.perform(environment)
@@ -2,55 +2,85 @@ require 'sass/script/lexer'
2
2
 
3
3
  module Sass
4
4
  module Script
5
+ # The parser for SassScript.
6
+ # It parses a string of code into a tree of {Script::Node}s.
5
7
  class Parser
8
+ # @param str [String, StringScanner] The source text to parse
9
+ # @param line [Fixnum] The line on which the SassScript appears.
10
+ # Used for error reporting
11
+ # @param offset [Fixnum] The number of characters in on which the SassScript appears.
12
+ # Used for error reporting
13
+ # @param filename [String] The name of the file in which the SassScript appears.
14
+ # Used for error reporting
6
15
  def initialize(str, line, offset, filename = nil)
7
16
  @filename = filename
8
17
  @lexer = Lexer.new(str, line, offset)
9
18
  end
10
19
 
20
+ # Parses a SassScript expression within an interpolated segment (`#{}`).
21
+ # This means that it stops when it comes across an unmatched `}`,
22
+ # which signals the end of an interpolated segment,
23
+ # it returns rather than throwing an error.
24
+ #
25
+ # @return [Script::Node] The root node of the parse tree
26
+ # @raise [Sass::SyntaxError] if the expression isn't valid SassScript
11
27
  def parse_interpolated
12
28
  expr = assert_expr :expr
13
29
  assert_tok :end_interpolation
14
30
  expr
15
31
  end
16
32
 
33
+ # Parses a SassScript expression.
34
+ #
35
+ # @return [Script::Node] The root node of the parse tree
36
+ # @raise [Sass::SyntaxError] if the expression isn't valid SassScript
17
37
  def parse
18
38
  expr = assert_expr :expr
19
39
  raise Sass::SyntaxError.new("Unexpected #{@lexer.peek.type} token.") unless @lexer.done?
20
40
  expr
21
41
  end
22
42
 
43
+ # Parses a SassScript expression.
44
+ #
45
+ # @overload parse(str, line, offset, filename = nil)
46
+ # @return [Script::Node] The root node of the parse tree
47
+ # @see Parser#initialize
48
+ # @see Parser#parse
23
49
  def self.parse(*args)
24
50
  new(*args).parse
25
51
  end
26
52
 
27
- private
28
-
29
- # Defines a simple left-associative production.
30
- # name is the name of the production,
31
- # sub is the name of the production beneath it,
32
- # and ops is a list of operators for this precedence level
33
- def self.production(name, sub, *ops)
34
- class_eval <<RUBY
35
- def #{name}
36
- return unless e = #{sub}
37
- while tok = try_tok(#{ops.map {|o| o.inspect}.join(', ')})
38
- e = Operation.new(e, assert_expr(#{sub.inspect}), tok.type)
53
+ class << self
54
+ private
55
+
56
+ # Defines a simple left-associative production.
57
+ # name is the name of the production,
58
+ # sub is the name of the production beneath it,
59
+ # and ops is a list of operators for this precedence level
60
+ def production(name, sub, *ops)
61
+ class_eval <<RUBY
62
+ def #{name}
63
+ return unless e = #{sub}
64
+ while tok = try_tok(#{ops.map {|o| o.inspect}.join(', ')})
65
+ e = Operation.new(e, assert_expr(#{sub.inspect}), tok.type)
66
+ end
67
+ e
39
68
  end
40
- e
41
- end
42
69
  RUBY
43
- end
70
+ end
44
71
 
45
- def self.unary(op, sub)
46
- class_eval <<RUBY
47
- def unary_#{op}
48
- return #{sub} unless try_tok(:#{op})
49
- UnaryOperation.new(assert_expr(:unary_#{op}), :#{op})
50
- end
72
+ def unary(op, sub)
73
+ class_eval <<RUBY
74
+ def unary_#{op}
75
+ return #{sub} unless try_tok(:#{op})
76
+ UnaryOperation.new(assert_expr(:unary_#{op}), :#{op})
77
+ end
51
78
  RUBY
79
+ end
52
80
  end
53
81
 
82
+ private
83
+
54
84
  production :expr, :concat, :comma
55
85
 
56
86
  def concat
@@ -1,9 +1,12 @@
1
1
  require 'sass/script/literal'
2
2
 
3
3
  module Sass::Script
4
- class String < Literal # :nodoc:
5
- def to_s
6
- @value
7
- end
4
+ # A SassScript object representing a string of text.
5
+ class String < Literal
6
+ # The Ruby value of the string.
7
+ #
8
+ # @return [String]
9
+ attr_reader :value
10
+ alias_method :to_s, :value
8
11
  end
9
12
  end
@@ -1,14 +1,27 @@
1
1
  module Sass::Script
2
- class UnaryOperation # :nodoc:
2
+ # A SassScript parse node representing a unary operation,
3
+ # such as `-!b` or `not true`.
4
+ #
5
+ # Currently only `-`, `/`, and `not` are unary operators.
6
+ class UnaryOperation < Node
7
+ # @param operand [Script::Node] The parse-tree node
8
+ # for the object of the operator
9
+ # @param operator [Symbol] The operator to perform
3
10
  def initialize(operand, operator)
4
11
  @operand = operand
5
12
  @operator = operator
6
13
  end
7
14
 
15
+ # @return [String] A human-readable s-expression representation of the operation
8
16
  def inspect
9
17
  "(#{@operator.inspect} #{@operand.inspect})"
10
18
  end
11
19
 
20
+ # Evaluates the operation.
21
+ #
22
+ # @param environment [Sass::Environment] The environment in which to evaluate the SassScript
23
+ # @return [Literal] The SassScript object that is the value of the operation
24
+ # @raise [Sass::SyntaxError] if the operation is undefined for the operand
12
25
  def perform(environment)
13
26
  operator = "unary_#{@operator}"
14
27
  literal = @operand.perform(environment)
@@ -1,16 +1,27 @@
1
1
  module Sass
2
2
  module Script
3
- class Variable # :nodoc:
3
+ # A SassScript parse node representing a variable.
4
+ class Variable < Node
5
+ # The name of the variable.
6
+ #
7
+ # @return [String]
4
8
  attr_reader :name
5
9
 
10
+ # @param name [String] See \{#name}
6
11
  def initialize(name)
7
12
  @name = name
8
13
  end
9
14
 
15
+ # @return [String] A string representation of the variable
10
16
  def inspect
11
17
  "!#{name}"
12
18
  end
13
19
 
20
+ # Evaluates the variable.
21
+ #
22
+ # @param environment [Sass::Environment] The environment in which to evaluate the SassScript
23
+ # @return [Literal] The SassScript object that is the value of the variable
24
+ # @raise [Sass::SyntaxError] if the variable is undefined
14
25
  def perform(environment)
15
26
  (val = environment.var(name)) && (return val)
16
27
  raise SyntaxError.new("Undefined variable: \"!#{name}\".")