haml-edge 2.3.100 → 2.3.148

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 (54) hide show
  1. data/.yardopts +3 -0
  2. data/EDGE_GEM_VERSION +1 -1
  3. data/Rakefile +14 -2
  4. data/VERSION +1 -1
  5. data/extra/haml-mode.el +97 -11
  6. data/extra/sass-mode.el +2 -2
  7. data/lib/haml/engine.rb +2 -2
  8. data/lib/haml/exec.rb +121 -25
  9. data/lib/haml/filters.rb +1 -1
  10. data/lib/haml/helpers/action_view_mods.rb +2 -1
  11. data/lib/haml/helpers/xss_mods.rb +43 -13
  12. data/lib/haml/helpers.rb +38 -17
  13. data/lib/haml/html.rb +13 -4
  14. data/lib/haml/precompiler.rb +24 -3
  15. data/lib/haml/template/plugin.rb +7 -3
  16. data/lib/haml/template.rb +3 -3
  17. data/lib/haml/util.rb +40 -0
  18. data/lib/sass/callbacks.rb +50 -0
  19. data/lib/sass/css.rb +1 -1
  20. data/lib/sass/engine.rb +45 -5
  21. data/lib/sass/error.rb +6 -3
  22. data/lib/sass/files.rb +8 -1
  23. data/lib/sass/plugin/rails.rb +2 -2
  24. data/lib/sass/plugin.rb +260 -28
  25. data/lib/sass/script/color.rb +216 -30
  26. data/lib/sass/script/functions.rb +356 -74
  27. data/lib/sass/script/lexer.rb +7 -4
  28. data/lib/sass/script/number.rb +2 -0
  29. data/lib/sass/script/parser.rb +1 -1
  30. data/lib/sass/script.rb +3 -0
  31. data/lib/sass/tree/node.rb +1 -1
  32. data/lib/sass/tree/root_node.rb +6 -0
  33. data/lib/sass/tree/rule_node.rb +1 -0
  34. data/lib/sass.rb +4 -0
  35. data/test/haml/engine_test.rb +25 -0
  36. data/test/haml/helper_test.rb +81 -1
  37. data/test/haml/html2haml_test.rb +13 -0
  38. data/test/haml/spec/README.md +97 -0
  39. data/test/haml/spec/lua_haml_spec.lua +30 -0
  40. data/test/haml/spec/ruby_haml_test.rb +19 -0
  41. data/test/haml/spec/tests.json +534 -0
  42. data/test/haml/spec_test.rb +0 -0
  43. data/test/haml/template_test.rb +18 -4
  44. data/test/haml/util_test.rb +0 -0
  45. data/test/sass/callbacks_test.rb +61 -0
  46. data/test/sass/css2sass_test.rb +1 -0
  47. data/test/sass/engine_test.rb +70 -14
  48. data/test/sass/functions_test.rb +223 -3
  49. data/test/sass/plugin_test.rb +193 -25
  50. data/test/sass/results/options.css +1 -0
  51. data/test/sass/script_test.rb +5 -5
  52. data/test/sass/templates/options.sass +2 -0
  53. data/test/test_helper.rb +12 -5
  54. metadata +19 -9
@@ -2,23 +2,19 @@ module Sass::Script
2
2
  # Methods in this module are accessible from the SassScript context.
3
3
  # For example, you can write
4
4
  #
5
- # !color = hsl(120, 100%, 50%)
5
+ # !color = hsl(120deg, 100%, 50%)
6
6
  #
7
7
  # and it will call {Sass::Script::Functions#hsl}.
8
8
  #
9
9
  # The following functions are provided:
10
10
  #
11
- # \{#hsl}
12
- # : Converts an `hsl(hue, saturation, lightness)` triplet into a color.
13
- #
14
- # \{#hsla}
15
- # : Converts an `hsla(hue, saturation, lightness, alpha)` quadruplet into a color.
11
+ # ## RGB Functions
16
12
  #
17
13
  # \{#rgb}
18
14
  # : Converts an `rgb(red, green, blue)` triplet into a color.
19
15
  #
20
16
  # \{#rgba}
21
- # : Converts an `rgb(red, green, blue, alpha)` triplet into a color.
17
+ # : Converts an `rgba(red, green, blue, alpha)` quadruplet into a color.
22
18
  #
23
19
  # \{#red}
24
20
  # : Gets the red component of a color.
@@ -29,15 +25,63 @@ module Sass::Script
29
25
  # \{#blue}
30
26
  # : Gets the blue component of a color.
31
27
  #
28
+ # \{#mix}
29
+ # : Mixes two colors together.
30
+ #
31
+ # ## HSL Functions
32
+ #
33
+ # \{#hsl}
34
+ # : Converts an `hsl(hue, saturation, lightness)` triplet into a color.
35
+ #
36
+ # \{#hsla}
37
+ # : Converts an `hsla(hue, saturation, lightness, alpha)` quadruplet into a color.
38
+ #
39
+ # \{#hue}
40
+ # : Gets the hue component of a color.
41
+ #
42
+ # \{#saturation}
43
+ # : Gets the saturation component of a color.
44
+ #
45
+ # \{#lightness}
46
+ # : Gets the lightness component of a color.
47
+ #
48
+ # \{#adjust_hue #adjust-hue}
49
+ # : Changes the hue of a color.
50
+ #
51
+ # \{#lighten}
52
+ # : Makes a color lighter.
53
+ #
54
+ # \{#darken}
55
+ # : Makes a color darker.
56
+ #
57
+ # \{#saturate}
58
+ # : Makes a color more saturated.
59
+ #
60
+ # \{#desaturate}
61
+ # : Makes a color less saturated.
62
+ #
63
+ # \{#grayscale}
64
+ # : Converts a color to grayscale.
65
+ #
66
+ # \{#complement}
67
+ # : Returns the complement of a color.
68
+ #
69
+ # ## Opacity Functions
70
+ #
32
71
  # \{#alpha} / \{#opacity}
33
72
  # : Gets the alpha component (opacity) of a color.
34
73
  #
74
+ # \{#rgba}
75
+ # : Sets the alpha component of a color.
76
+ #
35
77
  # \{#opacify} / \{#fade_in #fade-in}
36
78
  # : Makes a color more opaque.
37
79
  #
38
80
  # \{#transparentize} / \{#fade_out #fade-out}
39
81
  # : Makes a color more transparent.
40
82
  #
83
+ # ## Number Functions
84
+ #
41
85
  # \{#percentage}
42
86
  # : Converts a unitless number to a percentage.
43
87
  #
@@ -79,11 +123,16 @@ module Sass::Script
79
123
  #
80
124
  # Second, making Ruby functions accessible from Sass introduces the temptation
81
125
  # to do things like database access within stylesheets.
82
- # This temptation must be resisted.
83
- # Keep in mind that Sass stylesheets are only compiled once
84
- # at a somewhat indeterminate time
85
- # and then left as static CSS files.
86
- # Any dynamic CSS should be left in `<style>` tags in the HTML.
126
+ # This is generally a bad idea;
127
+ # since Sass files are by default only compiled once,
128
+ # dynamic code is not a great fit.
129
+ #
130
+ # If you really, really need to compile Sass on each request,
131
+ # first make sure you have adequate caching set up.
132
+ # Then you can use {Sass::Engine} to render the code,
133
+ # using the {file:SASS_REFERENCE.md#custom-option `options` parameter}
134
+ # to pass in data that {EvaluationContext#options can be accessed}
135
+ # from your Sass functions.
87
136
  #
88
137
  # Within one of the functions in this module,
89
138
  # methods of {EvaluationContext} can be used.
@@ -134,52 +183,78 @@ module Sass::Script
134
183
 
135
184
 
136
185
  # Creates a {Color} object from red, green, and blue values.
137
- # @param red
186
+ #
187
+ # @param red [Number]
138
188
  # A number between 0 and 255 inclusive,
139
189
  # or between 0% and 100% inclusive
140
- # @param green
190
+ # @param green [Number]
141
191
  # A number between 0 and 255 inclusive,
142
192
  # or between 0% and 100% inclusive
143
- # @param blue
193
+ # @param blue [Number]
144
194
  # A number between 0 and 255 inclusive,
145
195
  # or between 0% and 100% inclusive
196
+ # @return [Color]
146
197
  def rgb(red, green, blue)
147
- rgba(red, green, blue, Number.new(1))
148
- end
149
-
150
- # Creates a {Color} object from red, green, and blue values,
151
- # as well as an alpha channel indicating opacity.
152
- #
153
- # @param red
154
- # A number between 0 and 255 inclusive
155
- # @param green
156
- # A number between 0 and 255 inclusive
157
- # @param blue
158
- # A number between 0 and 255 inclusive
159
- # @param alpha
160
- # A number between 0 and 1
161
- def rgba(red, green, blue, alpha)
162
198
  assert_type red, :Number
163
199
  assert_type green, :Number
164
200
  assert_type blue, :Number
165
- assert_type alpha, :Number
166
201
 
167
- rgb = [red, green, blue].map do |c|
168
- v = c.value
169
- if c.numerator_units == ["%"] && c.denominator_units.empty?
170
- next v * 255 / 100.0 if (0..100).include?(v)
171
- raise ArgumentError.new("Color value #{c} must be between 0% and 100% inclusive")
172
- else
173
- next v if (0..255).include?(v)
174
- raise ArgumentError.new("Color value #{v} must be between 0 and 255 inclusive")
202
+ Color.new([red, green, blue].map do |c|
203
+ v = c.value
204
+ if c.numerator_units == ["%"] && c.denominator_units.empty?
205
+ next v * 255 / 100.0 if (0..100).include?(v)
206
+ raise ArgumentError.new("Color value #{c} must be between 0% and 100% inclusive")
207
+ else
208
+ next v if (0..255).include?(v)
209
+ raise ArgumentError.new("Color value #{v} must be between 0 and 255 inclusive")
210
+ end
211
+ end)
212
+ end
213
+
214
+ # @overload rgba(red, green, blue, alpha)
215
+ # Creates a {Color} object from red, green, and blue values,
216
+ # as well as an alpha channel indicating opacity.
217
+ #
218
+ # @param red [Number]
219
+ # A number between 0 and 255 inclusive
220
+ # @param green [Number]
221
+ # A number between 0 and 255 inclusive
222
+ # @param blue [Number]
223
+ # A number between 0 and 255 inclusive
224
+ # @param alpha [Number]
225
+ # A number between 0 and 1
226
+ # @return [Color]
227
+ #
228
+ # @overload rgba(color, alpha)
229
+ # Sets the opacity of a color.
230
+ #
231
+ # @example
232
+ # rgba(#102030, 0.5) => rgba(16, 32, 48, 0.5)
233
+ # rgba(blue, 0.2) => rgba(0, 0, 255, 0.2)
234
+ #
235
+ # @param color [Color]
236
+ # @param alpha [Number]
237
+ # A number between 0 and 1
238
+ # @return [Color]
239
+ def rgba(*args)
240
+ case args.size
241
+ when 2
242
+ color, alpha = args
243
+
244
+ assert_type color, :Color
245
+ assert_type alpha, :Number
246
+
247
+ unless (0..1).include?(alpha.value)
248
+ raise ArgumentError.new("Alpha channel #{alpha.value} must be between 0 and 1 inclusive")
175
249
  end
176
- end
177
250
 
178
- unless (0..1).include?(alpha.value)
179
- raise ArgumentError.new("Alpha channel #{alpha.value} must be between 0 and 1 inclusive")
251
+ color.with(:alpha => alpha.value)
252
+ when 4
253
+ red, green, blue, alpha = args
254
+ rgba(rgb(red, green, blue), alpha)
255
+ else
256
+ raise ArgumentError.new("wrong number of arguments (#{args.size} for 4)")
180
257
  end
181
-
182
- Color.new(rgb + [alpha.value])
183
258
  end
184
259
 
185
260
  # Creates a {Color} object from hue, saturation, and lightness.
@@ -228,17 +303,7 @@ module Sass::Script
228
303
  raise ArgumentError.new("Saturation #{s} must be between 0% and 100%") unless (0..100).include?(s)
229
304
  raise ArgumentError.new("Lightness #{l} must be between 0% and 100%") unless (0..100).include?(l)
230
305
 
231
- h = (h % 360) / 360.0
232
- s /= 100.0
233
- l /= 100.0
234
-
235
- m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s
236
- m1 = l * 2 - m2
237
- Color.new(
238
- [hue_to_rgb(m1, m2, h + 1.0/3),
239
- hue_to_rgb(m1, m2, h),
240
- hue_to_rgb(m1, m2, h - 1.0/3)].map { |c| (c * 0xff).round } +
241
- [alpha.value])
306
+ Color.new(:hue => h, :saturation => s, :lightness => l, :alpha => alpha.value)
242
307
  end
243
308
 
244
309
  # Returns the red component of a color.
@@ -271,6 +336,48 @@ module Sass::Script
271
336
  Sass::Script::Number.new(color.blue)
272
337
  end
273
338
 
339
+ # Returns the hue component of a color.
340
+ #
341
+ # See [the CSS3 HSL specification](http://en.wikipedia.org/wiki/HSL_and_HSV#Conversion_from_RGB_to_HSL_or_HSV).
342
+ #
343
+ # Calculated from RGB where necessary via [this algorithm](http://en.wikipedia.org/wiki/HSL_and_HSV#Conversion_from_RGB_to_HSL_or_HSV).
344
+ #
345
+ # @param color [Color]
346
+ # @return [Number] between 0deg and 360deg
347
+ # @raise [ArgumentError] if `color` isn't a color
348
+ def hue(color)
349
+ assert_type color, :Color
350
+ Sass::Script::Number.new(color.hue, ["deg"])
351
+ end
352
+
353
+ # Returns the saturation component of a color.
354
+ #
355
+ # See [the CSS3 HSL specification](http://en.wikipedia.org/wiki/HSL_and_HSV#Conversion_from_RGB_to_HSL_or_HSV).
356
+ #
357
+ # Calculated from RGB where necessary via [this algorithm](http://en.wikipedia.org/wiki/HSL_and_HSV#Conversion_from_RGB_to_HSL_or_HSV).
358
+ #
359
+ # @param color [Color]
360
+ # @return [Number] between 0% and 100%
361
+ # @raise [ArgumentError] if `color` isn't a color
362
+ def saturation(color)
363
+ assert_type color, :Color
364
+ Sass::Script::Number.new(color.saturation, ["%"])
365
+ end
366
+
367
+ # Returns the hue component of a color.
368
+ #
369
+ # See [the CSS3 HSL specification](http://en.wikipedia.org/wiki/HSL_and_HSV#Conversion_from_RGB_to_HSL_or_HSV).
370
+ #
371
+ # Calculated from RGB where necessary via [this algorithm](http://en.wikipedia.org/wiki/HSL_and_HSV#Conversion_from_RGB_to_HSL_or_HSV).
372
+ #
373
+ # @param color [Color]
374
+ # @return [Number] between 0% and 100%
375
+ # @raise [ArgumentError] if `color` isn't a color
376
+ def lightness(color)
377
+ assert_type color, :Color
378
+ Sass::Script::Number.new(color.lightness, ["%"])
379
+ end
380
+
274
381
  # Returns the alpha component (opacity) of a color.
275
382
  # This is 1 unless otherwise specified.
276
383
  #
@@ -294,16 +401,11 @@ module Sass::Script
294
401
  #
295
402
  # @param color [Color]
296
403
  # @param amount [Number]
404
+ # @return [Color]
297
405
  # @raise [ArgumentError] If `color` isn't a color,
298
406
  # or `number` isn't a number between 0 and 1
299
407
  def opacify(color, amount)
300
- assert_type color, :Color
301
- assert_type amount, :Number
302
- unless (0..1).include?(amount.value)
303
- raise ArgumentError.new("Amount #{amount} must be between 0 and 1")
304
- end
305
-
306
- color.with(:alpha => Haml::Util.restrict(color.alpha + amount.value, 0..1))
408
+ adjust(color, amount, :alpha, 0..1, :+)
307
409
  end
308
410
  alias_method :fade_in, :opacify
309
411
 
@@ -318,18 +420,193 @@ module Sass::Script
318
420
  #
319
421
  # @param color [Color]
320
422
  # @param amount [Number]
423
+ # @return [Color]
321
424
  # @raise [ArgumentError] If `color` isn't a color,
322
425
  # or `number` isn't a number between 0 and 1
323
426
  def transparentize(color, amount)
427
+ adjust(color, amount, :alpha, 0..1, :-)
428
+ end
429
+ alias_method :fade_out, :transparentize
430
+
431
+ # Makes a color lighter.
432
+ # Takes a color and an amount between 0% and 100%,
433
+ # and returns a color with the lightness increased by that value.
434
+ #
435
+ # For example:
436
+ #
437
+ # lighten(hsl(0, 0%, 0%), 30%) => hsl(0, 0, 30)
438
+ # lighten(#800, 20%) => #e00
439
+ #
440
+ # @param color [Color]
441
+ # @param amount [Number]
442
+ # @return [Color]
443
+ # @raise [ArgumentError] If `color` isn't a color,
444
+ # or `number` isn't a number between 0% and 100%
445
+ def lighten(color, amount)
446
+ adjust(color, amount, :lightness, 0..100, :+, "%")
447
+ end
448
+
449
+ # Makes a color darker.
450
+ # Takes a color and an amount between 0% and 100%,
451
+ # and returns a color with the lightness decreased by that value.
452
+ #
453
+ # For example:
454
+ #
455
+ # darken(hsl(25, 100%, 80%), 30%) => hsl(25, 100%, 50%)
456
+ # darken(#800, 20%) => #200
457
+ #
458
+ # @param color [Color]
459
+ # @param amount [Number]
460
+ # @return [Color]
461
+ # @raise [ArgumentError] If `color` isn't a color,
462
+ # or `number` isn't a number between 0% and 100%
463
+ def darken(color, amount)
464
+ adjust(color, amount, :lightness, 0..100, :-, "%")
465
+ end
466
+
467
+ # Makes a color more saturated.
468
+ # Takes a color and an amount between 0% and 100%,
469
+ # and returns a color with the saturation increased by that value.
470
+ #
471
+ # For example:
472
+ #
473
+ # saturate(hsl(120, 30%, 90%), 20%) => hsl(120, 50%, 90%)
474
+ # saturate(#855, 20%) => #9e3f3f
475
+ #
476
+ # @param color [Color]
477
+ # @param amount [Number]
478
+ # @return [Color]
479
+ # @raise [ArgumentError] If `color` isn't a color,
480
+ # or `number` isn't a number between 0% and 100%
481
+ def saturate(color, amount)
482
+ adjust(color, amount, :saturation, 0..100, :+, "%")
483
+ end
484
+
485
+ # Makes a color less saturated.
486
+ # Takes a color and an amount between 0% and 100%,
487
+ # and returns a color with the saturation decreased by that value.
488
+ #
489
+ # For example:
490
+ #
491
+ # desaturate(hsl(120, 30%, 90%), 20%) => hsl(120, 10%, 90%)
492
+ # desaturate(#855, 20%) => #726b6b
493
+ #
494
+ # @param color [Color]
495
+ # @param amount [Number]
496
+ # @return [Color]
497
+ # @raise [ArgumentError] If `color` isn't a color,
498
+ # or `number` isn't a number between 0% and 100%
499
+ def desaturate(color, amount)
500
+ adjust(color, amount, :saturation, 0..100, :-, "%")
501
+ end
502
+
503
+ # Changes the hue of a color while retaining the lightness and saturation.
504
+ # Takes a color and a number of degrees (usually between -360deg and 360deg),
505
+ # and returns a color with the hue rotated by that value.
506
+ #
507
+ # For example:
508
+ #
509
+ # adjust-hue(hsl(120, 30%, 90%), 60deg) => hsl(180, 30%, 90%)
510
+ # adjust-hue(hsl(120, 30%, 90%), 060deg) => hsl(60, 30%, 90%)
511
+ # adjust-hue(#811, 45deg) => #886a11
512
+ #
513
+ # @param color [Color]
514
+ # @param amount [Number]
515
+ # @return [Color]
516
+ # @raise [ArgumentError] If `color` isn't a color, or `number` isn't a number
517
+ def adjust_hue(color, degrees)
324
518
  assert_type color, :Color
325
- assert_type amount, :Number
326
- unless (0..1).include?(amount.value)
327
- raise ArgumentError.new("Amount #{amount} must be between 0 and 1")
519
+ assert_type degrees, :Number
520
+ color.with(:hue => color.hue + degrees.value)
521
+ end
522
+
523
+ # Mixes together two colors.
524
+ # Specifically, takes the average of each of the RGB components,
525
+ # optionally weighted by the given percentage.
526
+ # The opacity of the colors is also considered when weighting the components.
527
+ #
528
+ # The weight specifies the amount of the first color that should be included
529
+ # in the returned color.
530
+ # The default, 50%, means that half the first color
531
+ # and half the second color should be used.
532
+ # 25% means that a quarter of the first color
533
+ # and three quarters of the second color should be used.
534
+ #
535
+ # For example:
536
+ #
537
+ # mix(#f00, #00f) => #7f007f
538
+ # mix(#f00, #00f, 25%) => #3f00bf
539
+ # mix(rgba(255, 0, 0, 0.5), #00f) => rgba(63, 0, 191, 0.75)
540
+ #
541
+ # @overload mix(color1, color2, weight = 50%)
542
+ # @param color1 [Color]
543
+ # @param color2 [Color]
544
+ # @param weight [Number] between 0% and 100%
545
+ # @return [Color]
546
+ # @raise [ArgumentError] if `color1` or `color2` aren't colors,
547
+ # or `weight` isn't a number between 0% and 100%
548
+ def mix(color1, color2, weight = Number.new(50))
549
+ assert_type color1, :Color
550
+ assert_type color2, :Color
551
+ assert_type weight, :Number
552
+
553
+ unless (0..100).include?(weight.value)
554
+ raise ArgumentError.new("Weight #{weight} must be between 0% and 100%")
328
555
  end
329
556
 
330
- color.with(:alpha => Haml::Util.restrict(color.alpha - amount.value, 0..1))
557
+ # This algorithm factors in both the user-provided weight
558
+ # and the difference between the alpha values of the two colors
559
+ # to decide how to perform the weighted average of the two RGB values.
560
+ #
561
+ # It works by first normalizing both parameters to be within [-1, 1],
562
+ # where 1 indicates "only use color1", -1 indicates "only use color 0",
563
+ # and all values in between indicated a proportionately weighted average.
564
+ #
565
+ # Once we have the normalized variables w and a,
566
+ # we apply the formula (w + a)/(1 + w*a)
567
+ # to get the combined weight (in [-1, 1]) of color1.
568
+ # This formula has two especially nice properties:
569
+ #
570
+ # * When either w or a are -1 or 1, the combined weight is also that number
571
+ # (cases where w * a == -1 are undefined, and handled as a special case).
572
+ #
573
+ # * When a is 0, the combined weight is w, and vice versa
574
+ #
575
+ # Finally, the weight of color1 is renormalized to be within [0, 1]
576
+ # and the weight of color2 is given by 1 minus the weight of color1.
577
+ p = weight.value/100.0
578
+ w = p*2 - 1
579
+ a = color1.alpha - color2.alpha
580
+
581
+ w1 = (((w * a == -1) ? w : (w + a)/(1 + w*a)) + 1)/2.0
582
+ w2 = 1 - w1
583
+
584
+ rgb = color1.rgb.zip(color2.rgb).map {|v1, v2| v1*w1 + v2*w2}
585
+ alpha = color1.alpha*p + color2.alpha*(1-p)
586
+ Color.new(rgb + [alpha])
587
+ end
588
+
589
+ # Converts a color to grayscale.
590
+ # This is identical to `desaturate(color, 100%)`.
591
+ #
592
+ # @param color [Color]
593
+ # @return [Color]
594
+ # @raise [ArgumentError] if `color` isn't a color
595
+ # @see #desaturate
596
+ def grayscale(color)
597
+ desaturate color, Number.new(100)
598
+ end
599
+
600
+ # Returns the complement of a color.
601
+ # This is identical to `adjust-hue(color, 180deg)`.
602
+ #
603
+ # @param color [Color]
604
+ # @return [Color]
605
+ # @raise [ArgumentError] if `color` isn't a color
606
+ # @see #adjust_hue #adjust-hue
607
+ def complement(color)
608
+ adjust_hue color, Number.new(180)
331
609
  end
332
- alias_method :fade_out, :transparentize
333
610
 
334
611
  # Converts a decimal number to a percentage.
335
612
  # For example:
@@ -408,13 +685,18 @@ module Sass::Script
408
685
  Sass::Script::Number.new(yield(value.value), value.numerator_units, value.denominator_units)
409
686
  end
410
687
 
411
- def hue_to_rgb(m1, m2, h)
412
- h += 1 if h < 0
413
- h -= 1 if h > 1
414
- return m1 + (m2 - m1) * h * 6 if h * 6 < 1
415
- return m2 if h * 2 < 1
416
- return m1 + (m2 - m1) * (2.0/3 - h) * 6 if h * 3 < 2
417
- return m1
688
+ def adjust(color, amount, attr, range, op, units = "")
689
+ assert_type color, :Color
690
+ assert_type amount, :Number
691
+ unless range.include?(amount.value)
692
+ raise ArgumentError.new("Amount #{amount} must be between #{range.first}#{units} and #{range.last}#{units}")
693
+ end
694
+
695
+ # TODO: is it worth restricting here,
696
+ # or should we do so in the Color constructor itself,
697
+ # and allow clipping in rgb() et al?
698
+ color.with(attr => Haml::Util.restrict(
699
+ color.send(attr).send(op, amount.value), range))
418
700
  end
419
701
  end
420
702
  end
@@ -8,20 +8,21 @@ module Sass
8
8
  class Lexer
9
9
  # A struct containing information about an individual token.
10
10
  #
11
- # `type`: \[{Symbol}\]
11
+ # `type`: \[`Symbol`\]
12
12
  # : The type of token.
13
13
  #
14
- # `value`: \[{Object}\]
14
+ # `value`: \[`Object`\]
15
15
  # : The Ruby object corresponding to the value of the token.
16
16
  #
17
- # `line`: \[{Fixnum}\]
17
+ # `line`: \[`Fixnum`\]
18
18
  # : The line of the source file on which the token appears.
19
19
  #
20
- # `offset`: \[{Fixnum}\]
20
+ # `offset`: \[`Fixnum`\]
21
21
  # : The number of bytes into the line the SassScript token appeared.
22
22
  Token = Struct.new(:type, :value, :line, :offset)
23
23
 
24
24
  # A hash from operator strings to the corresponding token types.
25
+ # @private
25
26
  OPERATORS = {
26
27
  '+' => :plus,
27
28
  '-' => :minus,
@@ -47,9 +48,11 @@ module Sass
47
48
 
48
49
  # A list of operator strings ordered with longer names first
49
50
  # so that `>` and `<` don't clobber `>=` and `<=`.
51
+ # @private
50
52
  OP_NAMES = OPERATORS.keys.sort_by {|o| -o.size}
51
53
 
52
54
  # A hash of regular expressions that are used for tokenizing.
55
+ # @private
53
56
  REGULAR_EXPRESSIONS = {
54
57
  :whitespace => /\s*/,
55
58
  :variable => /!([\w-]+)/,
@@ -351,7 +351,9 @@ module Sass::Script
351
351
  end
352
352
 
353
353
  # A hash of unit names to their index in the conversion table
354
+ # @private
354
355
  CONVERTABLE_UNITS = {"in" => 0, "cm" => 1, "pc" => 2, "mm" => 3, "pt" => 4}
356
+ # @private
355
357
  CONVERSION_TABLE = [[ 1, 2.54, 6, 25.4, 72 ], # in
356
358
  [ nil, 1, 2.36220473, 10, 28.3464567], # cm
357
359
  [ nil, nil, 1, 4.23333333, 12 ], # pc
@@ -149,7 +149,7 @@ RUBY
149
149
  warn(<<END)
150
150
  DEPRECATION WARNING:
151
151
  On line #{name.line}, character #{name.offset}#{" of '#{filename}'" if filename}
152
- Implicit strings have been deprecated and will be removed in version 2.4.
152
+ Implicit strings have been deprecated and will be removed in version 3.0.
153
153
  '#{name.value}' was not quoted. Please add double quotes (e.g. "#{name.value}").
154
154
  END
155
155
  Script::String.new(name.value)
data/lib/sass/script.rb CHANGED
@@ -13,12 +13,15 @@ module Sass
13
13
  # This module contains code that handles the parsing and evaluation of SassScript.
14
14
  module Script
15
15
  # The character that begins a variable.
16
+ # @private
16
17
  VARIABLE_CHAR = ?!
17
18
 
18
19
  # The regular expression used to parse variables.
20
+ # @private
19
21
  MATCH = /^!([a-zA-Z_]\w*)\s*((?:\|\|)?=)\s*(.+)/
20
22
 
21
23
  # The regular expression used to validate variables without matching.
24
+ # @private
22
25
  VALIDATE = /^![a-zA-Z_]\w*$/
23
26
 
24
27
  # Parses a string of SassScript
@@ -64,7 +64,7 @@ module Sass
64
64
  #
65
65
  # @return [String]
66
66
  def filename
67
- @filename || @options[:filename]
67
+ @filename || (@options && @options[:filename])
68
68
  end
69
69
 
70
70
  # Appends a child to the node.
@@ -38,6 +38,12 @@ module Sass
38
38
  raise e
39
39
  end
40
40
 
41
+ # @see \{Node#perform!}
42
+ def perform!(environment)
43
+ environment.options = @options if environment.options.nil? || environment.options.empty?
44
+ super
45
+ end
46
+
41
47
  protected
42
48
 
43
49
  # Destructively converts this static Sass node into a static CSS node,
@@ -6,6 +6,7 @@ module Sass::Tree
6
6
  # @see Sass::Tree
7
7
  class RuleNode < Node
8
8
  # The character used to include the parent selector
9
+ # @private
9
10
  PARENT = '&'
10
11
 
11
12
  # The CSS selectors for this rule.
data/lib/sass.rb CHANGED
@@ -20,5 +20,9 @@ module Sass
20
20
  end
21
21
 
22
22
  require 'haml/util'
23
+
24
+ dir = Haml::Util.scope("vendor/fssm/lib")
25
+ $LOAD_PATH.unshift dir unless $LOAD_PATH.include?(dir)
26
+
23
27
  require 'sass/engine'
24
28
  require 'sass/plugin' if defined?(Merb::Plugins)