Module: Sass::Script::Functions
- Defined in:
- lib/sass/script/functions.rb
Overview
Methods in this module are accessible from the SassScript context. For example, you can write
$color = hsl(120deg, 100%, 50%)
and it will call #hsl.
The following functions are provided:
RGB Functions
#rgb
: Converts an rgb(red, green, blue) triplet into a color.
#rgba
: Converts an rgba(red, green, blue, alpha) quadruplet into a color.
#red : Gets the red component of a color.
#green : Gets the green component of a color.
#blue : Gets the blue component of a color.
#mix : Mixes two colors together.
HSL Functions
#hsl
: Converts an hsl(hue, saturation, lightness) triplet into a color.
#hsla
: Converts an hsla(hue, saturation, lightness, alpha) quadruplet into a color.
#hue : Gets the hue component of a color.
#saturation : Gets the saturation component of a color.
#lightness : Gets the lightness component of a color.
#adjust-hue : Changes the hue of a color.
#lighten : Makes a color lighter.
#darken : Makes a color darker.
#saturate : Makes a color more saturated.
#desaturate : Makes a color less saturated.
#grayscale : Converts a color to grayscale.
#complement : Returns the complement of a color.
Opacity Functions
#alpha / #opacity : Gets the alpha component (opacity) of a color.
#rgba : Sets the alpha component of a color.
#opacify / #fade-in : Makes a color more opaque.
#transparentize / #fade-out : Makes a color more transparent.
String Functions
#unquote : Removes the quotes from a string.
#quote : Adds quotes to a string.
Number Functions
#percentage : Converts a unitless number to a percentage.
#round : Rounds a number to the nearest whole number.
#ceil : Rounds a number up to the nearest whole number.
#floor : Rounds a number down to the nearest whole number.
#abs : Returns the absolute value of a number.
Introspection Functions
#type_of : Returns the type of a value.
#unit : Returns the units associated with a number.
#unitless : Returns whether a number has units or not.
#comparable : Returns whether two numbers can be added or compared.
These functions are described in more detail below.
Adding Custom Functions
New Sass functions can be added by adding Ruby methods to this module. For example:
module Sass::Script::Functions
  def reverse(string)
    assert_type string, :String
    Sass::Script::String.new(string.value.reverse)
  end
end
There are a few things to keep in mind when modifying this module. First of all, the arguments passed are Literal objects. Literal objects are also expected to be returned. This means that Ruby values must be unwrapped and wrapped.
Most Literal objects support the value accessor for getting their Ruby values. Color objects, though, must be accessed using rgb, red, green, or blue.
Second, making Ruby functions accessible from Sass introduces the temptation to do things like database access within stylesheets. This is generally a bad idea; since Sass files are by default only compiled once, dynamic code is not a great fit.
If you really, really need to compile Sass on each request,
first make sure you have adequate caching set up.
Then you can use Engine to render the code,
using the options parameter
to pass in data that can be accessed
from your Sass functions.
Within one of the functions in this module, methods of EvaluationContext can be used.
Caveats
When creating new Literal objects within functions, be aware that it's not safe to call #to_s (or other methods that use the string representation) on those objects without first setting the #options attribute.
Defined Under Namespace
Classes: EvaluationContext
Instance Method Summary collapse
- 
  
    
      #abs(value)  ⇒ Number 
    
    
  
  
  
  
  
  
  
  
  
    Finds the absolute value of a number. 
- 
  
    
      #adjust_hue(color, degrees)  ⇒ Color 
    
    
  
  
  
  
  
  
  
  
  
    Changes the hue of a color while retaining the lightness and saturation. 
- 
  
    
      #alpha(color)  ⇒ Number 
    
    
  
  
  
  
  
  
  
  
  
    Returns the alpha component (opacity) of a color. 
- 
  
    
      #blue(color)  ⇒ Number 
    
    
  
  
  
  
  
  
  
  
  
    Returns the blue component of a color. 
- 
  
    
      #ceil(value)  ⇒ Number 
    
    
  
  
  
  
  
  
  
  
  
    Rounds a number up to the nearest whole number. 
- 
  
    
      #comparable(number1, number2)  ⇒ Bool 
    
    
  
  
  
  
  
  
  
  
  
    Returns true if two numbers are similar enough to be added, subtracted, or compared. 
- 
  
    
      #complement(color)  ⇒ Color 
    
    
  
  
  
  
  
  
  
  
  
    Returns the complement of a color. 
- 
  
    
      #darken(color, amount)  ⇒ Color 
    
    
  
  
  
  
  
  
  
  
  
    Makes a color darker. 
- 
  
    
      #desaturate(color, amount)  ⇒ Color 
    
    
  
  
  
  
  
  
  
  
  
    Makes a color less saturated. 
- 
  
    
      #floor(value)  ⇒ Number 
    
    
  
  
  
  
  
  
  
  
  
    Rounds down to the nearest whole number. 
- 
  
    
      #grayscale(color)  ⇒ Color 
    
    
  
  
  
  
  
  
  
  
  
    Converts a color to grayscale. 
- 
  
    
      #green(color)  ⇒ Number 
    
    
  
  
  
  
  
  
  
  
  
    Returns the green component of a color. 
- 
  
    
      #hsl(hue, saturation, lightness)  ⇒ Color 
    
    
  
  
  
  
  
  
  
  
  
    Creates a Color object from hue, saturation, and lightness. 
- 
  
    
      #hsla(hue, saturation, lightness, alpha)  ⇒ Color 
    
    
  
  
  
  
  
  
  
  
  
    Creates a Color object from hue, saturation, and lightness, as well as an alpha channel indicating opacity. 
- 
  
    
      #hue(color)  ⇒ Number 
    
    
  
  
  
  
  
  
  
  
  
    Returns the hue component of a color. 
- 
  
    
      #lighten(color, amount)  ⇒ Color 
    
    
  
  
  
  
  
  
  
  
  
    Makes a color lighter. 
- 
  
    
      #lightness(color)  ⇒ Number 
    
    
  
  
  
  
  
  
  
  
  
    Returns the hue component of a color. 
- 
  
    
      #mix(color1, color2, weight = 50%)  ⇒ Color 
    
    
  
  
  
  
  
  
  
  
  
    Mixes together two colors. 
- 
  
    
      #opacify(color, amount)  ⇒ Color 
    
    
      (also: #fade_in)
    
  
  
  
  
  
  
  
  
  
    Makes a color more opaque. 
- 
  
    
      #opacity(color)  ⇒ Number 
    
    
  
  
  
  
  
  
  
  
  
    Returns the alpha component (opacity) of a color. 
- 
  
    
      #percentage(value)  ⇒ Number 
    
    
  
  
  
  
  
  
  
  
  
    Converts a decimal number to a percentage. 
- 
  
    
      #quote(str)  ⇒ String 
    
    
  
  
  
  
  
  
  
  
  
    Add quotes to a string if the string isn't quoted, or returns the same string if it is. 
- 
  
    
      #red(color)  ⇒ Number 
    
    
  
  
  
  
  
  
  
  
  
    Returns the red component of a color. 
- 
  
    
      #rgb(red, green, blue)  ⇒ Color 
    
    
  
  
  
  
  
  
  
  
  
    Creates a Color object from red, green, and blue values. 
- #rgba(*args)
- 
  
    
      #round(value)  ⇒ Number 
    
    
  
  
  
  
  
  
  
  
  
    Rounds a number to the nearest whole number. 
- 
  
    
      #saturate(color, amount)  ⇒ Color 
    
    
  
  
  
  
  
  
  
  
  
    Makes a color more saturated. 
- 
  
    
      #saturation(color)  ⇒ Number 
    
    
  
  
  
  
  
  
  
  
  
    Returns the saturation component of a color. 
- 
  
    
      #transparentize(color, amount)  ⇒ Color 
    
    
      (also: #fade_out)
    
  
  
  
  
  
  
  
  
  
    Makes a color more transparent. 
- 
  
    
      #type_of(obj)  ⇒ String 
    
    
  
  
  
  
  
  
  
  
  
    Inspects the type of the argument, returning it as an unquoted string. 
- 
  
    
      #unit(number)  ⇒ String 
    
    
  
  
  
  
  
  
  
  
  
    Inspects the unit of the number, returning it as a quoted string. 
- 
  
    
      #unitless(number)  ⇒ Bool 
    
    
  
  
  
  
  
  
  
  
  
    Inspects the unit of the number, returning a boolean indicating if it is unitless. 
- 
  
    
      #unquote(str)  ⇒ String 
    
    
  
  
  
  
  
  
  
  
  
    Removes quotes from a string if the string is quoted, or returns the same string if it's not. 
Instance Method Details
#abs(value) ⇒ Number
Finds the absolute value of a number.
| 807 808 809 | # File 'lib/sass/script/functions.rb', line 807
def abs(value)
  numeric_transformation(value) {|n| n.abs}
end | 
#adjust_hue(color, degrees) ⇒ Color
Changes the hue of a color while retaining the lightness and saturation. Takes a color and a number of degrees (usually between -360deg and 360deg), and returns a color with the hue rotated by that value.
| 566 567 568 569 570 | # File 'lib/sass/script/functions.rb', line 566
def adjust_hue(color, degrees)
  assert_type color, :Color
  assert_type degrees, :Number
  color.with(:hue => color.hue + degrees.value)
end | 
#alpha(color) ⇒ Number
Returns the alpha component (opacity) of a color. This is 1 unless otherwise specified.
This function also supports the proprietary Microsoft
alpha(opacity=20) syntax.
| 425 426 427 428 429 430 431 432 433 434 435 | # File 'lib/sass/script/functions.rb', line 425
def alpha(*args)
  if args.all? do |a|
      a.is_a?(Sass::Script::String) && a.type == :identifier &&
        a.value =~ /^[a-zA-Z]+\s*=/
    end
    # Support the proprietary MS alpha() function
    return Sass::Script::String.new("alpha(#{args.map {|a| a.to_s}.join(", ")})")
  end
  opacity(*args)
end | 
#blue(color) ⇒ Number
Returns the blue component of a color.
| 361 362 363 364 | # File 'lib/sass/script/functions.rb', line 361
def blue(color)
  assert_type color, :Color
  Sass::Script::Number.new(color.blue)
end | 
#ceil(value) ⇒ Number
Rounds a number up to the nearest whole number.
| 783 784 785 | # File 'lib/sass/script/functions.rb', line 783
def ceil(value)
  numeric_transformation(value) {|n| n.ceil}
end | 
#comparable(number1, number2) ⇒ Bool
Returns true if two numbers are similar enough to be added, subtracted, or compared.
| 743 744 745 746 747 | # File 'lib/sass/script/functions.rb', line 743
def comparable(number1, number2)
  assert_type number1, :Number
  assert_type number2, :Number
  Sass::Script::Bool.new(number1.comparable_to?(number2))
end | 
#complement(color) ⇒ Color
Returns the complement of a color.
This is identical to adjust-hue(color, 180deg).
| 654 655 656 | # File 'lib/sass/script/functions.rb', line 654
def complement(color)
  adjust_hue color, Number.new(180)
end | 
#darken(color, amount) ⇒ Color
Makes a color darker. Takes a color and an amount between 0% and 100%, and returns a color with the lightness decreased by that value.
| 516 517 518 | # File 'lib/sass/script/functions.rb', line 516
def darken(color, amount)
  adjust(color, amount, :lightness, 0..100, :-, "%")
end | 
#desaturate(color, amount) ⇒ Color
Makes a color less saturated. Takes a color and an amount between 0% and 100%, and returns a color with the saturation decreased by that value.
| 550 551 552 | # File 'lib/sass/script/functions.rb', line 550
def desaturate(color, amount)
  adjust(color, amount, :saturation, 0..100, :-, "%")
end | 
#floor(value) ⇒ Number
Rounds down to the nearest whole number.
| 795 796 797 | # File 'lib/sass/script/functions.rb', line 795
def floor(value)
  numeric_transformation(value) {|n| n.floor}
end | 
#grayscale(color) ⇒ Color
Converts a color to grayscale.
This is identical to desaturate(color, 100%).
| 643 644 645 | # File 'lib/sass/script/functions.rb', line 643
def grayscale(color)
  desaturate color, Number.new(100)
end | 
#green(color) ⇒ Number
Returns the green component of a color.
| 351 352 353 354 | # File 'lib/sass/script/functions.rb', line 351
def green(color)
  assert_type color, :Color
  Sass::Script::Number.new(color.green)
end | 
#hsl(hue, saturation, lightness) ⇒ Color
| 297 298 299 | # File 'lib/sass/script/functions.rb', line 297
def hsl(hue, saturation, lightness)
  hsla(hue, saturation, lightness, Number.new(1))
end | 
#hsla(hue, saturation, lightness, alpha) ⇒ Color
| 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 | # File 'lib/sass/script/functions.rb', line 316
def hsla(hue, saturation, lightness, alpha)
  assert_type hue, :Number
  assert_type saturation, :Number
  assert_type lightness, :Number
  assert_type alpha, :Number
  unless (0..1).include?(alpha.value)
    raise ArgumentError.new("Alpha channel #{alpha.value} must be between 0 and 1")
  end
  original_s = saturation
  original_l = lightness
  # This algorithm is from http://www.w3.org/TR/css3-color#hsl-color
  h, s, l = [hue, saturation, lightness].map { |a| a.value }
  raise ArgumentError.new("Saturation #{s} must be between 0% and 100%") unless (0..100).include?(s)
  raise ArgumentError.new("Lightness #{l} must be between 0% and 100%") unless (0..100).include?(l)
  Color.new(:hue => h, :saturation => s, :lightness => l, :alpha => alpha.value)
end | 
#hue(color) ⇒ Number
Returns the hue component of a color.
See the CSS3 HSL specification.
Calculated from RGB where necessary via this algorithm.
| 376 377 378 379 | # File 'lib/sass/script/functions.rb', line 376
def hue(color)
  assert_type color, :Color
  Sass::Script::Number.new(color.hue, ["deg"])
end | 
#lighten(color, amount) ⇒ Color
Makes a color lighter. Takes a color and an amount between 0% and 100%, and returns a color with the lightness increased by that value.
| 499 500 501 | # File 'lib/sass/script/functions.rb', line 499
def lighten(color, amount)
  adjust(color, amount, :lightness, 0..100, :+, "%")
end | 
#lightness(color) ⇒ Number
Returns the hue component of a color.
See the CSS3 HSL specification.
Calculated from RGB where necessary via this algorithm.
| 408 409 410 411 | # File 'lib/sass/script/functions.rb', line 408
def lightness(color)
  assert_type color, :Color
  Sass::Script::Number.new(color.lightness, ["%"])
end | 
#mix(color1, color2, weight = 50%) ⇒ Color
Mixes together two colors. Specifically, takes the average of each of the RGB components, optionally weighted by the given percentage. The opacity of the colors is also considered when weighting the components.
The weight specifies the amount of the first color that should be included in the returned color. The default, 50%, means that half the first color and half the second color should be used. 25% means that a quarter of the first color and three quarters of the second color should be used.
| 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 | # File 'lib/sass/script/functions.rb', line 595
def mix(color1, color2, weight = Number.new(50))
  assert_type color1, :Color
  assert_type color2, :Color
  assert_type weight, :Number
  unless (0..100).include?(weight.value)
    raise ArgumentError.new("Weight #{weight} must be between 0% and 100%")
  end
  # This algorithm factors in both the user-provided weight
  # and the difference between the alpha values of the two colors
  # to decide how to perform the weighted average of the two RGB values.
  #
  # It works by first normalizing both parameters to be within [-1, 1],
  # where 1 indicates "only use color1", -1 indicates "only use color 0",
  # and all values in between indicated a proportionately weighted average.
  #
  # Once we have the normalized variables w and a,
  # we apply the formula (w + a)/(1 + w*a)
  # to get the combined weight (in [-1, 1]) of color1.
  # This formula has two especially nice properties:
  #
  #   * When either w or a are -1 or 1, the combined weight is also that number
  #     (cases where w * a == -1 are undefined, and handled as a special case).
  #
  #   * When a is 0, the combined weight is w, and vice versa
  #
  # Finally, the weight of color1 is renormalized to be within [0, 1]
  # and the weight of color2 is given by 1 minus the weight of color1.
  p = weight.value/100.0
  w = p*2 - 1
  a = color1.alpha - color2.alpha
  w1 = (((w * a == -1) ? w : (w + a)/(1 + w*a)) + 1)/2.0
  w2 = 1 - w1
  rgb = color1.rgb.zip(color2.rgb).map {|v1, v2| v1*w1 + v2*w2}
  alpha = color1.alpha*p + color2.alpha*(1-p)
  Color.new(rgb + [alpha])
end | 
#opacify(color, amount) ⇒ Color Also known as: fade_in
Makes a color more opaque. Takes a color and an amount between 0 and 1, and returns a color with the opacity increased by that value.
| 463 464 465 | # File 'lib/sass/script/functions.rb', line 463
def opacify(color, amount)
  adjust(color, amount, :alpha, 0..1, :+)
end | 
#opacity(color) ⇒ Number
Returns the alpha component (opacity) of a color. This is 1 unless otherwise specified.
| 445 446 447 448 | # File 'lib/sass/script/functions.rb', line 445
def opacity(color)
  assert_type color, :Color
  Sass::Script::Number.new(color.alpha)
end | 
#percentage(value) ⇒ Number
Converts a decimal number to a percentage.
| 756 757 758 759 760 761 | # File 'lib/sass/script/functions.rb', line 756
def percentage(value)
  unless value.is_a?(Sass::Script::Number) && value.unitless?
    raise ArgumentError.new("#{value.inspect} is not a unitless number")
  end
  Sass::Script::Number.new(value.value * 100, ['%'])
end | 
#quote(str) ⇒ String
Add quotes to a string if the string isn't quoted, or returns the same string if it is.
| 683 684 685 686 | # File 'lib/sass/script/functions.rb', line 683
def quote(str)
  assert_type str, :String
  Sass::Script::String.new(str.value, :string)
end | 
#red(color) ⇒ Number
Returns the red component of a color.
| 341 342 343 344 | # File 'lib/sass/script/functions.rb', line 341
def red(color)
  assert_type color, :Color
  Sass::Script::Number.new(color.red)
end | 
#rgb(red, green, blue) ⇒ Color
Creates a Color object from red, green, and blue values.
| 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 | # File 'lib/sass/script/functions.rb', line 221
def rgb(red, green, blue)
  assert_type red, :Number
  assert_type green, :Number
  assert_type blue, :Number
  Color.new([red, green, blue].map do |c|
      v = c.value
      if c.numerator_units == ["%"] && c.denominator_units.empty?
        next v * 255 / 100.0 if (0..100).include?(v)
        raise ArgumentError.new("Color value #{c} must be between 0% and 100% inclusive")
      else
        next v if (0..255).include?(v)
        raise ArgumentError.new("Color value #{v} must be between 0 and 255 inclusive")
      end
    end)
end | 
#rgba(red, green, blue, alpha) ⇒ Color #rgba(color, alpha) ⇒ Color
| 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 | # File 'lib/sass/script/functions.rb', line 264
def rgba(*args)
  case args.size
  when 2
    color, alpha = args
    assert_type color, :Color
    assert_type alpha, :Number
    unless (0..1).include?(alpha.value)
      raise ArgumentError.new("Alpha channel #{alpha.value} must be between 0 and 1 inclusive")
    end
    color.with(:alpha => alpha.value)
  when 4
    red, green, blue, alpha = args
    rgba(rgb(red, green, blue), alpha)
  else
    raise ArgumentError.new("wrong number of arguments (#{args.size} for 4)")
  end
end | 
#round(value) ⇒ Number
Rounds a number to the nearest whole number.
| 771 772 773 | # File 'lib/sass/script/functions.rb', line 771
def round(value)
  numeric_transformation(value) {|n| n.round}
end | 
#saturate(color, amount) ⇒ Color
Makes a color more saturated. Takes a color and an amount between 0% and 100%, and returns a color with the saturation increased by that value.
| 533 534 535 | # File 'lib/sass/script/functions.rb', line 533
def saturate(color, amount)
  adjust(color, amount, :saturation, 0..100, :+, "%")
end | 
#saturation(color) ⇒ Number
Returns the saturation component of a color.
See the CSS3 HSL specification.
Calculated from RGB where necessary via this algorithm.
| 392 393 394 395 | # File 'lib/sass/script/functions.rb', line 392
def saturation(color)
  assert_type color, :Color
  Sass::Script::Number.new(color.saturation, ["%"])
end | 
#transparentize(color, amount) ⇒ Color Also known as: fade_out
Makes a color more transparent. Takes a color and an amount between 0 and 1, and returns a color with the opacity decreased by that value.
| 481 482 483 | # File 'lib/sass/script/functions.rb', line 481
def transparentize(color, amount)
  adjust(color, amount, :alpha, 0..1, :-)
end | 
#type_of(obj) ⇒ String
Inspects the type of the argument, returning it as an unquoted string.
| 699 700 701 | # File 'lib/sass/script/functions.rb', line 699
def type_of(obj)
  Sass::Script::String.new(obj.class.name.gsub(/Sass::Script::/,'').downcase)
end | 
#unit(number) ⇒ String
Inspects the unit of the number, returning it as a quoted string. Complex units are sorted in alphabetical order by numerator and denominator.
| 715 716 717 718 | # File 'lib/sass/script/functions.rb', line 715
def unit(number)
  assert_type number, :Number
  Sass::Script::String.new(number.unit_str, :string)
end | 
#unitless(number) ⇒ Bool
Inspects the unit of the number, returning a boolean indicating if it is unitless.
| 728 729 730 731 | # File 'lib/sass/script/functions.rb', line 728
def unitless(number)
  assert_type number, :Number
  Sass::Script::Bool.new(number.unitless?)
end | 
#unquote(str) ⇒ String
Removes quotes from a string if the string is quoted, or returns the same string if it's not.
| 668 669 670 671 | # File 'lib/sass/script/functions.rb', line 668
def unquote(str)
  assert_type str, :String
  Sass::Script::String.new(str.value, :identifier)
end |