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.
- data/EDGE_GEM_VERSION +1 -1
- data/FAQ.md +142 -0
- data/{README.rdoc → README.md} +141 -141
- data/Rakefile +29 -17
- data/VERSION +1 -1
- data/lib/haml/buffer.rb +63 -27
- data/lib/haml/engine.rb +103 -80
- data/lib/haml/error.rb +7 -7
- data/lib/haml/exec.rb +80 -26
- data/lib/haml/filters.rb +106 -40
- data/lib/haml/helpers/action_view_extensions.rb +34 -39
- data/lib/haml/helpers/action_view_mods.rb +132 -139
- data/lib/haml/helpers.rb +207 -153
- data/lib/haml/html.rb +40 -21
- data/lib/haml/precompiler.rb +2 -0
- data/lib/haml/shared.rb +34 -3
- data/lib/haml/template/patch.rb +1 -1
- data/lib/haml/template/plugin.rb +0 -2
- data/lib/haml/template.rb +5 -0
- data/lib/haml/util.rb +136 -1
- data/lib/haml/version.rb +16 -4
- data/lib/haml.rb +502 -481
- data/lib/sass/css.rb +106 -68
- data/lib/sass/engine.rb +55 -22
- data/lib/sass/environment.rb +52 -21
- data/lib/sass/error.rb +23 -12
- data/lib/sass/files.rb +27 -0
- data/lib/sass/plugin/merb.rb +2 -2
- data/lib/sass/plugin/rails.rb +0 -2
- data/lib/sass/plugin.rb +32 -23
- data/lib/sass/repl.rb +7 -0
- data/lib/sass/script/bool.rb +9 -5
- data/lib/sass/script/color.rb +87 -1
- data/lib/sass/script/funcall.rb +23 -2
- data/lib/sass/script/functions.rb +93 -44
- data/lib/sass/script/lexer.rb +33 -3
- data/lib/sass/script/literal.rb +93 -1
- data/lib/sass/script/node.rb +14 -0
- data/lib/sass/script/number.rb +128 -4
- data/lib/sass/script/operation.rb +16 -1
- data/lib/sass/script/parser.rb +51 -21
- data/lib/sass/script/string.rb +7 -4
- data/lib/sass/script/unary_operation.rb +14 -1
- data/lib/sass/script/variable.rb +12 -1
- data/lib/sass/script.rb +26 -5
- data/lib/sass/tree/attr_node.rb +46 -9
- data/lib/sass/tree/comment_node.rb +41 -1
- data/lib/sass/tree/debug_node.rb +8 -0
- data/lib/sass/tree/directive_node.rb +20 -0
- data/lib/sass/tree/file_node.rb +12 -0
- data/lib/sass/tree/for_node.rb +15 -0
- data/lib/sass/tree/if_node.rb +22 -0
- data/lib/sass/tree/mixin_def_node.rb +12 -1
- data/lib/sass/tree/mixin_node.rb +13 -0
- data/lib/sass/tree/node.rb +136 -6
- data/lib/sass/tree/rule_node.rb +66 -7
- data/lib/sass/tree/variable_node.rb +10 -0
- data/lib/sass/tree/while_node.rb +11 -1
- data/lib/sass.rb +544 -534
- metadata +7 -6
- data/FAQ +0 -138
data/lib/sass/plugin.rb
CHANGED
@@ -1,9 +1,13 @@
|
|
1
1
|
require 'sass/engine'
|
2
2
|
|
3
3
|
module Sass
|
4
|
-
# This module
|
5
|
-
#
|
6
|
-
#
|
4
|
+
# This module handles the compilation of Sass files.
|
5
|
+
# It provides global options and checks whether CSS files
|
6
|
+
# need to be updated.
|
7
|
+
#
|
8
|
+
# This module is used as the primary interface with Sass
|
9
|
+
# when it's used as a plugin for various frameworks.
|
10
|
+
# Currently Rails and Merb are supported out of the box.
|
7
11
|
module Plugin
|
8
12
|
extend self
|
9
13
|
|
@@ -15,37 +19,42 @@ module Sass
|
|
15
19
|
}
|
16
20
|
@checked_for_updates = false
|
17
21
|
|
18
|
-
# Whether or not Sass has
|
22
|
+
# Whether or not Sass has **ever** checked if the stylesheets need to be updated
|
19
23
|
# (in this Ruby instance).
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
#
|
25
|
-
|
26
|
-
#
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
#
|
24
|
+
#
|
25
|
+
# @return [Boolean]
|
26
|
+
attr_reader :checked_for_updates
|
27
|
+
|
28
|
+
# An options hash.
|
29
|
+
# See [the Sass options documentation](../Sass.html#sass_options).
|
30
|
+
#
|
31
|
+
# @return [Hash<Symbol, Object>]
|
32
|
+
attr_reader :options
|
33
|
+
|
34
|
+
# Sets the options hash.
|
35
|
+
# See [the Sass options documentation](../Sass.html#sass_options).
|
36
|
+
#
|
37
|
+
# @param value [Hash<Symbol, Object>] The options hash
|
33
38
|
def options=(value)
|
34
39
|
@options.merge!(value)
|
35
40
|
end
|
36
41
|
|
37
|
-
#
|
42
|
+
# Non-destructively modifies \{#options} so that default values are properly set.
|
43
|
+
#
|
44
|
+
# @param additional_options [Hash<Symbol, Object>] An options hash with which to merge \{#options}
|
45
|
+
# @return [Hash<Symbol, Object>] The modified options hash
|
38
46
|
def engine_options(additional_options = {})
|
39
47
|
opts = options.dup.merge(additional_options)
|
40
48
|
opts[:load_paths] = load_paths(opts)
|
41
49
|
opts
|
42
50
|
end
|
43
51
|
|
44
|
-
#
|
45
|
-
#
|
46
|
-
#
|
47
|
-
#
|
48
|
-
#
|
52
|
+
# Updates out-of-date stylesheets.
|
53
|
+
#
|
54
|
+
# Checks each Sass file in [`:template_location`](../Sass.html#template_location-option)
|
55
|
+
# to see if it's been modified more recently than the corresponding CSS file
|
56
|
+
# in [`:css_location`](../Sass.html#css_location-option).
|
57
|
+
# If it has, it updates the CSS file.
|
49
58
|
def update_stylesheets
|
50
59
|
return if options[:never_update]
|
51
60
|
|
data/lib/sass/repl.rb
CHANGED
@@ -1,11 +1,18 @@
|
|
1
1
|
require 'readline'
|
2
2
|
|
3
3
|
module Sass
|
4
|
+
# Runs a SassScript read-eval-print loop.
|
5
|
+
# It presents a prompt on the terminal,
|
6
|
+
# reads in SassScript expressions,
|
7
|
+
# evaluates them,
|
8
|
+
# and prints the result.
|
4
9
|
class Repl
|
10
|
+
# @param options [Hash<Symbol, Object>] An options hash.
|
5
11
|
def initialize(options = {})
|
6
12
|
@options = options
|
7
13
|
end
|
8
14
|
|
15
|
+
# Starts the read-eval-print loop.
|
9
16
|
def run
|
10
17
|
environment = Environment.new
|
11
18
|
environment.set_var('important', Script::String.new('!important'))
|
data/lib/sass/script/bool.rb
CHANGED
@@ -1,13 +1,17 @@
|
|
1
1
|
require 'sass/script/literal'
|
2
2
|
|
3
3
|
module Sass::Script
|
4
|
-
|
4
|
+
# A SassScript object representing a boolean (true or false) value.
|
5
|
+
class Bool < Literal
|
6
|
+
# The Ruby value of the boolean.
|
7
|
+
#
|
8
|
+
# @return [Boolean]
|
9
|
+
attr_reader :value
|
10
|
+
alias_method :to_bool, :value
|
11
|
+
|
12
|
+
# @return [String] "true" or "false"
|
5
13
|
def to_s
|
6
14
|
@value.to_s
|
7
15
|
end
|
8
|
-
|
9
|
-
def to_bool
|
10
|
-
@value
|
11
|
-
end
|
12
16
|
end
|
13
17
|
end
|
data/lib/sass/script/color.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
require 'sass/script/literal'
|
2
2
|
|
3
3
|
module Sass::Script
|
4
|
-
|
4
|
+
# A SassScript object representing a CSS color.
|
5
|
+
class Color < Literal
|
5
6
|
class << self; include Haml::Util; end
|
6
7
|
|
8
|
+
# A hash from color names to [red, green, blue] value arrays.
|
7
9
|
HTML4_COLORS = map_vals({
|
8
10
|
'black' => 0x000000,
|
9
11
|
'silver' => 0xc0c0c0,
|
@@ -22,14 +24,33 @@ module Sass::Script
|
|
22
24
|
'teal' => 0x008080,
|
23
25
|
'aqua' => 0x00ffff
|
24
26
|
}) {|color| (0..2).map {|n| color >> (n << 3) & 0xff}.reverse}
|
27
|
+
# A hash from [red, green, blue] value arrays to color names.
|
25
28
|
HTML4_COLORS_REVERSE = map_hash(HTML4_COLORS) {|k, v| [v, k]}
|
26
29
|
|
30
|
+
# @param rgb [Array<Fixnum>] A three-element array of the red, green, and blue values (respectively)
|
31
|
+
# of the color
|
32
|
+
# @raise [Sass::SyntaxError] if any color value isn't between 0 and 255
|
27
33
|
def initialize(rgb)
|
28
34
|
rgb = rgb.map {|c| c.to_i}
|
29
35
|
raise Sass::SyntaxError.new("Color values must be between 0 and 255") if rgb.any? {|c| c < 0 || c > 255}
|
30
36
|
super(rgb)
|
31
37
|
end
|
32
38
|
|
39
|
+
# The SassScript `+` operation.
|
40
|
+
# Its functionality depends on the type of its argument:
|
41
|
+
#
|
42
|
+
# {Number}
|
43
|
+
# : Adds the number to each of the RGB color channels.
|
44
|
+
#
|
45
|
+
# {Color}
|
46
|
+
# : Adds each of the RGB color channels together.
|
47
|
+
#
|
48
|
+
# {Literal}
|
49
|
+
# : See {Literal#plus}.
|
50
|
+
#
|
51
|
+
# @param other [Literal] The right-hand side of the operator
|
52
|
+
# @return [Color] The resulting color
|
53
|
+
# @raise [Sass::SyntaxError] if `other` is a number with units
|
33
54
|
def plus(other)
|
34
55
|
if other.is_a?(Sass::Script::Number) || other.is_a?(Sass::Script::Color)
|
35
56
|
piecewise(other, :+)
|
@@ -38,6 +59,21 @@ module Sass::Script
|
|
38
59
|
end
|
39
60
|
end
|
40
61
|
|
62
|
+
# The SassScript `-` operation.
|
63
|
+
# Its functionality depends on the type of its argument:
|
64
|
+
#
|
65
|
+
# {Number}
|
66
|
+
# : Subtracts the number from each of the RGB color channels.
|
67
|
+
#
|
68
|
+
# {Color}
|
69
|
+
# : Subtracts each of the other color's RGB color channels from this color's.
|
70
|
+
#
|
71
|
+
# {Literal}
|
72
|
+
# : See {Literal#minus}.
|
73
|
+
#
|
74
|
+
# @param other [Literal] The right-hand side of the operator
|
75
|
+
# @return [Color] The resulting color
|
76
|
+
# @raise [Sass::SyntaxError] if `other` is a number with units
|
41
77
|
def minus(other)
|
42
78
|
if other.is_a?(Sass::Script::Number) || other.is_a?(Sass::Script::Color)
|
43
79
|
piecewise(other, :-)
|
@@ -46,6 +82,21 @@ module Sass::Script
|
|
46
82
|
end
|
47
83
|
end
|
48
84
|
|
85
|
+
# The SassScript `*` operation.
|
86
|
+
# Its functionality depends on the type of its argument:
|
87
|
+
#
|
88
|
+
# {Number}
|
89
|
+
# : Multiplies the number by each of the RGB color channels.
|
90
|
+
#
|
91
|
+
# {Color}
|
92
|
+
# : Multiplies each of the RGB color channels together.
|
93
|
+
#
|
94
|
+
# {Literal}
|
95
|
+
# : See {Literal#times}.
|
96
|
+
#
|
97
|
+
# @param other [Literal] The right-hand side of the operator
|
98
|
+
# @return [Color] The resulting color
|
99
|
+
# @raise [Sass::SyntaxError] if `other` is a number with units
|
49
100
|
def times(other)
|
50
101
|
if other.is_a?(Sass::Script::Number) || other.is_a?(Sass::Script::Color)
|
51
102
|
piecewise(other, :*)
|
@@ -54,6 +105,21 @@ module Sass::Script
|
|
54
105
|
end
|
55
106
|
end
|
56
107
|
|
108
|
+
# The SassScript `/` operation.
|
109
|
+
# Its functionality depends on the type of its argument:
|
110
|
+
#
|
111
|
+
# {Number}
|
112
|
+
# : Divides each of the RGB color channels by the number.
|
113
|
+
#
|
114
|
+
# {Color}
|
115
|
+
# : Divides each of this color's RGB color channels by the other color's.
|
116
|
+
#
|
117
|
+
# {Literal}
|
118
|
+
# : See {Literal#div}.
|
119
|
+
#
|
120
|
+
# @param other [Literal] The right-hand side of the operator
|
121
|
+
# @return [Color] The resulting color
|
122
|
+
# @raise [Sass::SyntaxError] if `other` is a number with units
|
57
123
|
def div(other)
|
58
124
|
if other.is_a?(Sass::Script::Number) || other.is_a?(Sass::Script::Color)
|
59
125
|
piecewise(other, :/)
|
@@ -62,6 +128,21 @@ module Sass::Script
|
|
62
128
|
end
|
63
129
|
end
|
64
130
|
|
131
|
+
# The SassScript `%` operation.
|
132
|
+
# Its functionality depends on the type of its argument:
|
133
|
+
#
|
134
|
+
# {Number}
|
135
|
+
# : Takes each of the RGB color channels module the number.
|
136
|
+
#
|
137
|
+
# {Color}
|
138
|
+
# : Takes each of this color's RGB color channels modulo the other color's.
|
139
|
+
#
|
140
|
+
# {Literal}
|
141
|
+
# : See {Literal#mod}.
|
142
|
+
#
|
143
|
+
# @param other [Literal] The right-hand side of the operator
|
144
|
+
# @return [Color] The resulting color
|
145
|
+
# @raise [Sass::SyntaxError] if `other` is a number with units
|
65
146
|
def mod(other)
|
66
147
|
if other.is_a?(Sass::Script::Number) || other.is_a?(Sass::Script::Color)
|
67
148
|
piecewise(other, :%)
|
@@ -70,6 +151,11 @@ module Sass::Script
|
|
70
151
|
end
|
71
152
|
end
|
72
153
|
|
154
|
+
# Returns a string representation of the color.
|
155
|
+
# This is usually the color's hex value,
|
156
|
+
# but if the color has a name that's used instead.
|
157
|
+
#
|
158
|
+
# @return [String] The string representation
|
73
159
|
def to_s
|
74
160
|
return HTML4_COLORS_REVERSE[@value] if HTML4_COLORS_REVERSE[@value]
|
75
161
|
red, green, blue = @value.map { |num| num.to_s(16).rjust(2, '0') }
|
data/lib/sass/script/funcall.rb
CHANGED
@@ -1,18 +1,39 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), 'functions')
|
2
2
|
module Sass
|
3
3
|
module Script
|
4
|
-
|
5
|
-
|
4
|
+
# A SassScript parse node representing a function call.
|
5
|
+
#
|
6
|
+
# A function call either calls one of the functions in {Script::Functions},
|
7
|
+
# or if no function with the given name exists
|
8
|
+
# it returns a string representation of the function call.
|
9
|
+
class Funcall < Node
|
10
|
+
# The name of the function.
|
11
|
+
#
|
12
|
+
# @return [String]
|
13
|
+
attr_reader :name
|
6
14
|
|
15
|
+
# The arguments to the function.
|
16
|
+
#
|
17
|
+
# @return [Array<Script::Node>]
|
18
|
+
attr_reader :args
|
19
|
+
|
20
|
+
# @param name [String] See \{#name}
|
21
|
+
# @param name [Array<Script::Node>] See \{#args}
|
7
22
|
def initialize(name, args)
|
8
23
|
@name = name
|
9
24
|
@args = args
|
10
25
|
end
|
11
26
|
|
27
|
+
# @return [String] A string representation of the function call
|
12
28
|
def inspect
|
13
29
|
"#{name}(#{args.map {|a| a.inspect}.join(', ')})"
|
14
30
|
end
|
15
31
|
|
32
|
+
# Evaluates the function call.
|
33
|
+
#
|
34
|
+
# @param environment [Sass::Environment] The environment in which to evaluate the SassScript
|
35
|
+
# @return [Literal] The SassScript object that is the value of the function call
|
36
|
+
# @raise [Sass::SyntaxError] if the function call raises an ArgumentError
|
16
37
|
def perform(environment)
|
17
38
|
args = self.args.map {|a| a.perform(environment)}
|
18
39
|
unless Haml::Util.has?(:public_instance_method, Functions, name) && name !~ /^__/
|
@@ -1,15 +1,35 @@
|
|
1
1
|
module Sass::Script
|
2
|
-
# Methods in this module are accessible from the
|
2
|
+
# Methods in this module are accessible from the SassScript context.
|
3
3
|
# For example, you can write
|
4
4
|
#
|
5
|
-
#
|
5
|
+
# !color = hsl(120, 100%, 50%)
|
6
6
|
#
|
7
|
-
# and it will call Sass::Script::Functions#hsl.
|
7
|
+
# and it will call {Sass::Script::Functions#hsl}.
|
8
|
+
#
|
9
|
+
# The following functions are provided:
|
10
|
+
#
|
11
|
+
# \{#hsl}
|
12
|
+
# : Converts an `hsl(hue, saturation, lightness)` triplet into a color.
|
13
|
+
#
|
14
|
+
# \{#percentage}
|
15
|
+
# : Converts a unitless number to a percentage.
|
16
|
+
#
|
17
|
+
# \{#round}
|
18
|
+
# : Rounds a number to the nearest whole number.
|
19
|
+
#
|
20
|
+
# \{#ceil}
|
21
|
+
# : Rounds a number up to the nearest whole number.
|
22
|
+
#
|
23
|
+
# \{#floor}
|
24
|
+
# : Rounds a number down to the nearest whole number.
|
25
|
+
#
|
26
|
+
# \{#abs}
|
27
|
+
# : Returns the absolute value of a number.
|
8
28
|
#
|
9
29
|
# You can add your own functions to this module,
|
10
30
|
# but there are a few things to keep in mind.
|
11
|
-
# First of all, the arguments passed are
|
12
|
-
# Literal objects are also
|
31
|
+
# First of all, the arguments passed are {Sass::Script::Literal} objects.
|
32
|
+
# Literal objects are also expected to be returned.
|
13
33
|
#
|
14
34
|
# Second, making Ruby functions accessible from Sass introduces the temptation
|
15
35
|
# to do things like database access within stylesheets.
|
@@ -17,38 +37,23 @@ module Sass::Script
|
|
17
37
|
# Keep in mind that Sass stylesheets are only compiled once
|
18
38
|
# at a somewhat indeterminate time
|
19
39
|
# and then left as static CSS files.
|
20
|
-
# Any dynamic CSS should be left in
|
21
|
-
#
|
22
|
-
# Within a sass function you can call the options method to gain access to the
|
23
|
-
# options hash that was used to create the Sass::Engine that is processing the function call.
|
24
|
-
#
|
25
|
-
# The following functions are provided:
|
26
|
-
# * +hsl+ - converts an <tt>hsl(hue, saturation, lightness)</tt> triplet into a color.
|
27
|
-
#
|
28
|
-
# The +hue+ value should be between 0 and 360 inclusive,
|
29
|
-
# saturation and lightness must be between <tt>0%</tt> to <tt>100%</tt> inclusive.
|
30
|
-
# The percent sign is optional.
|
31
|
-
# * +percentage+ - converts a unitless number to a css percentage.
|
32
|
-
#
|
33
|
-
# Example: <tt>percentage(14px / 7px) => 200%</tt>
|
34
|
-
# * +round+ - Rounds a number to the nearest whole number.
|
35
|
-
#
|
36
|
-
# Example: <tt>round(10.4px) => 10px</tt>
|
37
|
-
# * +ceil+ - Rounds a number up to the nearest whole number.
|
38
|
-
#
|
39
|
-
# Example: <tt>ceil(10.4px) => 11px</tt>
|
40
|
-
# * +floor+ - Rounds a number down to the nearest whole number.
|
41
|
-
#
|
42
|
-
# Example: <tt>floor(10.6px) => 10px</tt>
|
43
|
-
# * +abs+ - Returns the absolute value of a number.
|
40
|
+
# Any dynamic CSS should be left in `<style>` tags in the HTML.
|
44
41
|
#
|
45
|
-
#
|
42
|
+
# Within one of the functions in this module,
|
43
|
+
# methods of {EvaluationContext} can be used.
|
46
44
|
module Functions
|
47
|
-
|
45
|
+
# The context in which methods in {Script::Functions} are evaluated.
|
46
|
+
# That means that all instance methods of {EvaluationContext}
|
47
|
+
# are available to use in functions.
|
48
|
+
class EvaluationContext
|
48
49
|
include Sass::Script::Functions
|
49
50
|
|
51
|
+
# The options hash for the {Sass::Engine} that is processing the function call
|
52
|
+
#
|
53
|
+
# @return [Hash<Symbol, Object>]
|
50
54
|
attr_reader :options
|
51
55
|
|
56
|
+
# @param options [Hash<Symbol, Object>] See \{#options}
|
52
57
|
def initialize(options)
|
53
58
|
@options = options
|
54
59
|
end
|
@@ -56,15 +61,22 @@ module Sass::Script
|
|
56
61
|
|
57
62
|
instance_methods.each { |m| undef_method m unless m.to_s =~ /^__/ }
|
58
63
|
|
59
|
-
# Creates a
|
60
|
-
#
|
61
|
-
#
|
62
|
-
#
|
63
|
-
|
64
|
-
|
65
|
-
|
64
|
+
# Creates a {Color} object from hue, saturation, and lightness
|
65
|
+
# as per the CSS3 spec (http://www.w3.org/TR/css3-color/#hsl-color).
|
66
|
+
#
|
67
|
+
# @param hue [Number] The hue of the color.
|
68
|
+
# Should be between 0 and 360 degrees, inclusive
|
69
|
+
# @param saturation [Number] The saturation of the color.
|
70
|
+
# Must be between `0%` and `100%`, inclusive
|
71
|
+
# @param lightness [Number] The lightness of the color.
|
72
|
+
# Must be between `0%` and `100%`, inclusive
|
73
|
+
# @return [Color] The resulting color
|
74
|
+
# @raise [ArgumentError] if `saturation` or `lightness` are out of bounds
|
75
|
+
def hsl(hue, saturation, lightness)
|
76
|
+
original_s = saturation
|
77
|
+
original_l = lightness
|
66
78
|
# This algorithm is from http://www.w3.org/TR/css3-color#hsl-color
|
67
|
-
h, s, l = [
|
79
|
+
h, s, l = [hue, saturation, lightness].map { |a| a.value }
|
68
80
|
raise ArgumentError.new("Saturation #{s} must be between 0% and 100%") if s < 0 || s > 100
|
69
81
|
raise ArgumentError.new("Lightness #{l} must be between 0% and 100%") if l < 0 || l > 100
|
70
82
|
|
@@ -79,9 +91,14 @@ module Sass::Script
|
|
79
91
|
hue_to_rgb(m1, m2, h - 1.0/3)].map { |c| (c * 0xff).round })
|
80
92
|
end
|
81
93
|
|
82
|
-
# Converts a
|
83
|
-
#
|
84
|
-
#
|
94
|
+
# Converts a decimal number to a percentage.
|
95
|
+
# For example:
|
96
|
+
#
|
97
|
+
# percentage(100px / 50px) => 200%
|
98
|
+
#
|
99
|
+
# @param value [Number] The decimal number to convert to a percentage
|
100
|
+
# @return [Number] The percentage
|
101
|
+
# @raise [ArgumentError] If `value` isn't a unitless number
|
85
102
|
def percentage(value)
|
86
103
|
unless value.is_a?(Sass::Script::Number) && value.unitless?
|
87
104
|
raise ArgumentError.new("#{value} is not a unitless number")
|
@@ -90,21 +107,53 @@ module Sass::Script
|
|
90
107
|
end
|
91
108
|
|
92
109
|
# Rounds a number to the nearest whole number.
|
110
|
+
# For example:
|
111
|
+
#
|
112
|
+
# round(10.4px) => 10px
|
113
|
+
# round(10.6px) => 11px
|
114
|
+
#
|
115
|
+
# @param value [Number] The number
|
116
|
+
# @return [Number] The rounded number
|
117
|
+
# @raise [Sass::SyntaxError] if `value` isn't a number
|
93
118
|
def round(value)
|
94
119
|
numeric_transformation(value) {|n| n.round}
|
95
120
|
end
|
96
121
|
|
97
|
-
# Rounds up to the nearest whole number.
|
122
|
+
# Rounds a number up to the nearest whole number.
|
123
|
+
# For example:
|
124
|
+
#
|
125
|
+
# ciel(10.4px) => 11px
|
126
|
+
# ciel(10.6px) => 11px
|
127
|
+
#
|
128
|
+
# @param value [Number] The number
|
129
|
+
# @return [Number] The rounded number
|
130
|
+
# @raise [Sass::SyntaxError] if `value` isn't a number
|
98
131
|
def ceil(value)
|
99
132
|
numeric_transformation(value) {|n| n.ceil}
|
100
133
|
end
|
101
134
|
|
102
135
|
# Rounds down to the nearest whole number.
|
136
|
+
# For example:
|
137
|
+
#
|
138
|
+
# floor(10.4px) => 10px
|
139
|
+
# floor(10.6px) => 10px
|
140
|
+
#
|
141
|
+
# @param value [Number] The number
|
142
|
+
# @return [Number] The rounded number
|
143
|
+
# @raise [Sass::SyntaxError] if `value` isn't a number
|
103
144
|
def floor(value)
|
104
145
|
numeric_transformation(value) {|n| n.floor}
|
105
146
|
end
|
106
147
|
|
107
|
-
#
|
148
|
+
# Finds the absolute value of a number.
|
149
|
+
# For example:
|
150
|
+
#
|
151
|
+
# abs(10px) => 10px
|
152
|
+
# abs(-10px) => 10px
|
153
|
+
#
|
154
|
+
# @param value [Number] The number
|
155
|
+
# @return [Number] The absolute value
|
156
|
+
# @raise [Sass::SyntaxError] if `value` isn't a number
|
108
157
|
def abs(value)
|
109
158
|
numeric_transformation(value) {|n| n.abs}
|
110
159
|
end
|
data/lib/sass/script/lexer.rb
CHANGED
@@ -2,9 +2,26 @@ require 'strscan'
|
|
2
2
|
|
3
3
|
module Sass
|
4
4
|
module Script
|
5
|
-
|
5
|
+
# The lexical analyzer for SassScript.
|
6
|
+
# It takes a raw string and converts it to individual tokens
|
7
|
+
# that are easier to parse.
|
8
|
+
class Lexer
|
9
|
+
# A struct containing information about an individual token.
|
10
|
+
#
|
11
|
+
# `type`: [{Symbol}]
|
12
|
+
# : The type of token.
|
13
|
+
#
|
14
|
+
# `value`: [{Object}]
|
15
|
+
# : The Ruby object corresponding to the value of the token.
|
16
|
+
#
|
17
|
+
# `line`: [{Fixnum}]
|
18
|
+
# : The line of the source file on which the token appears.
|
19
|
+
#
|
20
|
+
# `offset`: [{Fixnum}]
|
21
|
+
# : The number of bytes into the line the SassScript token appeared.
|
6
22
|
Token = Struct.new(:type, :value, :line, :offset)
|
7
23
|
|
24
|
+
# A hash from operator strings to the corresponding token types.
|
8
25
|
OPERATORS = {
|
9
26
|
'+' => :plus,
|
10
27
|
'-' => :minus,
|
@@ -27,10 +44,11 @@ module Sass
|
|
27
44
|
'}' => :end_interpolation,
|
28
45
|
}
|
29
46
|
|
30
|
-
#
|
31
|
-
# so that
|
47
|
+
# A list of operator strings ordered with longer names first
|
48
|
+
# so that `>` and `<` don't clobber `>=` and `<=`.
|
32
49
|
OP_NAMES = OPERATORS.keys.sort_by {|o| -o.size}
|
33
50
|
|
51
|
+
# A hash of regular expressions that are used for tokenizing.
|
34
52
|
REGULAR_EXPRESSIONS = {
|
35
53
|
:whitespace => /\s*/,
|
36
54
|
:variable => /!(\w+)/,
|
@@ -42,6 +60,11 @@ module Sass
|
|
42
60
|
:op => %r{(#{Regexp.union(*OP_NAMES.map{|s| Regexp.new(Regexp.escape(s) + (s =~ /\w$/ ? '(?:\b|$)' : ''))})})}
|
43
61
|
}
|
44
62
|
|
63
|
+
# @param str [String, StringScanner] The source text to lex
|
64
|
+
# @param line [Fixnum] The line on which the SassScript appears.
|
65
|
+
# Used for error reporting
|
66
|
+
# @param offset [Fixnum] The number of characters in on which the SassScript appears.
|
67
|
+
# Used for error reporting
|
45
68
|
def initialize(str, line, offset)
|
46
69
|
@scanner = str.is_a?(StringScanner) ? str : StringScanner.new(str)
|
47
70
|
@line = line
|
@@ -49,6 +72,9 @@ module Sass
|
|
49
72
|
@prev = nil
|
50
73
|
end
|
51
74
|
|
75
|
+
# Moves the lexer forward one token.
|
76
|
+
#
|
77
|
+
# @return [Token] The token that was moved past
|
52
78
|
def next
|
53
79
|
@tok ||= read_token
|
54
80
|
@tok, tok = nil, @tok
|
@@ -56,10 +82,14 @@ module Sass
|
|
56
82
|
return tok
|
57
83
|
end
|
58
84
|
|
85
|
+
# Returns the next token without moving the lexer forward.
|
86
|
+
#
|
87
|
+
# @return [Token] The next token
|
59
88
|
def peek
|
60
89
|
@tok ||= read_token
|
61
90
|
end
|
62
91
|
|
92
|
+
# @return [Boolean] Whether or not there's more source text to lex.
|
63
93
|
def done?
|
64
94
|
whitespace unless after_interpolation?
|
65
95
|
@scanner.eos? && @tok.nil?
|