haml-edge 2.1.21 → 2.1.22

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.
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}\".")