haml-edge 2.1.21 → 2.1.22
Sign up to get free protection for your applications and to get access to all the features.
- 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?
|