haml-edge 2.3.179 → 2.3.180
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/README.md +88 -149
- data/VERSION +1 -1
- data/bin/css2sass +7 -1
- data/bin/sass-convert +7 -0
- data/lib/haml/exec.rb +95 -22
- data/lib/haml/template.rb +1 -1
- data/lib/haml/util.rb +50 -0
- data/lib/sass.rb +1 -1
- data/lib/sass/css.rb +38 -210
- data/lib/sass/engine.rb +121 -47
- data/lib/sass/files.rb +28 -19
- data/lib/sass/plugin.rb +32 -43
- data/lib/sass/repl.rb +1 -1
- data/lib/sass/script.rb +25 -6
- data/lib/sass/script/bool.rb +1 -0
- data/lib/sass/script/color.rb +2 -2
- data/lib/sass/script/css_lexer.rb +22 -0
- data/lib/sass/script/css_parser.rb +28 -0
- data/lib/sass/script/funcall.rb +17 -9
- data/lib/sass/script/functions.rb +46 -1
- data/lib/sass/script/interpolation.rb +42 -0
- data/lib/sass/script/lexer.rb +142 -34
- data/lib/sass/script/literal.rb +28 -12
- data/lib/sass/script/node.rb +57 -1
- data/lib/sass/script/number.rb +18 -3
- data/lib/sass/script/operation.rb +44 -8
- data/lib/sass/script/parser.rb +149 -24
- data/lib/sass/script/string.rb +50 -2
- data/lib/sass/script/unary_operation.rb +25 -10
- data/lib/sass/script/variable.rb +20 -11
- data/lib/sass/scss.rb +14 -0
- data/lib/sass/scss/css_parser.rb +39 -0
- data/lib/sass/scss/parser.rb +683 -0
- data/lib/sass/scss/rx.rb +112 -0
- data/lib/sass/scss/script_lexer.rb +13 -0
- data/lib/sass/scss/script_parser.rb +25 -0
- data/lib/sass/tree/comment_node.rb +58 -16
- data/lib/sass/tree/debug_node.rb +7 -2
- data/lib/sass/tree/directive_node.rb +38 -34
- data/lib/sass/tree/for_node.rb +6 -0
- data/lib/sass/tree/if_node.rb +13 -0
- data/lib/sass/tree/import_node.rb +26 -7
- data/lib/sass/tree/mixin_def_node.rb +18 -0
- data/lib/sass/tree/mixin_node.rb +16 -1
- data/lib/sass/tree/node.rb +98 -27
- data/lib/sass/tree/prop_node.rb +97 -20
- data/lib/sass/tree/root_node.rb +37 -0
- data/lib/sass/tree/rule_node.rb +88 -60
- data/lib/sass/tree/variable_node.rb +9 -5
- data/lib/sass/tree/while_node.rb +4 -0
- data/test/haml/results/filters.xhtml +1 -1
- data/test/haml/util_test.rb +28 -0
- data/test/sass/conversion_test.rb +884 -0
- data/test/sass/css2sass_test.rb +46 -21
- data/test/sass/engine_test.rb +680 -160
- data/test/sass/functions_test.rb +27 -0
- data/test/sass/more_results/more_import.css +1 -1
- data/test/sass/more_templates/more_import.sass +3 -3
- data/test/sass/plugin_test.rb +28 -8
- data/test/sass/results/compact.css +1 -1
- data/test/sass/results/complex.css +5 -5
- data/test/sass/results/compressed.css +1 -1
- data/test/sass/results/expanded.css +1 -1
- data/test/sass/results/import.css +3 -1
- data/test/sass/results/mixins.css +12 -12
- data/test/sass/results/nested.css +1 -1
- data/test/sass/results/parent_ref.css +4 -4
- data/test/sass/results/script.css +3 -3
- data/test/sass/results/scss_import.css +15 -0
- data/test/sass/results/scss_importee.css +2 -0
- data/test/sass/script_conversion_test.rb +153 -0
- data/test/sass/script_test.rb +44 -54
- data/test/sass/scss/css_test.rb +811 -0
- data/test/sass/scss/rx_test.rb +156 -0
- data/test/sass/scss/scss_test.rb +871 -0
- data/test/sass/scss/test_helper.rb +37 -0
- data/test/sass/templates/alt.sass +2 -2
- data/test/sass/templates/bork1.sass +1 -1
- data/test/sass/templates/import.sass +4 -4
- data/test/sass/templates/importee.sass +3 -3
- data/test/sass/templates/line_numbers.sass +1 -1
- data/test/sass/templates/mixins.sass +2 -2
- data/test/sass/templates/nested_mixin_bork.sass +1 -1
- data/test/sass/templates/options.sass +1 -1
- data/test/sass/templates/parent_ref.sass +2 -2
- data/test/sass/templates/script.sass +69 -69
- data/test/sass/templates/scss_import.scss +10 -0
- data/test/sass/templates/scss_importee.scss +1 -0
- data/test/sass/templates/units.sass +10 -10
- data/test/test_helper.rb +4 -4
- metadata +27 -2
@@ -2,7 +2,7 @@ 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
|
-
#
|
5
|
+
# $color = hsl(120deg, 100%, 50%)
|
6
6
|
#
|
7
7
|
# and it will call {Sass::Script::Functions#hsl}.
|
8
8
|
#
|
@@ -80,6 +80,14 @@ module Sass::Script
|
|
80
80
|
# \{#transparentize} / \{#fade_out #fade-out}
|
81
81
|
# : Makes a color more transparent.
|
82
82
|
#
|
83
|
+
# ## String Functions
|
84
|
+
#
|
85
|
+
# \{#unquote}
|
86
|
+
# : Removes the quotes from a string.
|
87
|
+
#
|
88
|
+
# \{#quote}
|
89
|
+
# : Adds quotes to a string.
|
90
|
+
#
|
83
91
|
# ## Number Functions
|
84
92
|
#
|
85
93
|
# \{#percentage}
|
@@ -170,6 +178,8 @@ module Sass::Script
|
|
170
178
|
# assert_type value, :Number
|
171
179
|
#
|
172
180
|
# Valid types are `:Bool`, `:Color`, `:Number`, and `:String`.
|
181
|
+
# Note that `:String` will match both double-quoted strings
|
182
|
+
# and unquoted identifiers.
|
173
183
|
#
|
174
184
|
# @param value [Sass::Script::Literal] A SassScript value
|
175
185
|
# @param type [Symbol] The name of the type the value is expected to be
|
@@ -608,6 +618,36 @@ module Sass::Script
|
|
608
618
|
adjust_hue color, Number.new(180)
|
609
619
|
end
|
610
620
|
|
621
|
+
# Removes quotes from a string if the string is quoted,
|
622
|
+
# or returns the same string if it's not.
|
623
|
+
#
|
624
|
+
# @param str [String]
|
625
|
+
# @return [String]
|
626
|
+
# @raise [ArgumentError] if `str` isn't a string
|
627
|
+
# @see #quote
|
628
|
+
# @example
|
629
|
+
# unquote("foo") => foo
|
630
|
+
# unquote(foo) => foo
|
631
|
+
def unquote(str)
|
632
|
+
assert_type str, :String
|
633
|
+
Sass::Script::String.new(str.value, :identifier)
|
634
|
+
end
|
635
|
+
|
636
|
+
# Add quotes to a string if the string isn't quoted,
|
637
|
+
# or returns the same string if it is.
|
638
|
+
#
|
639
|
+
# @param str [String]
|
640
|
+
# @return [String]
|
641
|
+
# @raise [ArgumentError] if `str` isn't a string
|
642
|
+
# @see #unquote
|
643
|
+
# @example
|
644
|
+
# quote("foo") => "foo"
|
645
|
+
# quote(foo) => "foo"
|
646
|
+
def quote(str)
|
647
|
+
assert_type str, :String
|
648
|
+
Sass::Script::String.new(str.value, :string)
|
649
|
+
end
|
650
|
+
|
611
651
|
# Converts a decimal number to a percentage.
|
612
652
|
# For example:
|
613
653
|
#
|
@@ -675,6 +715,11 @@ module Sass::Script
|
|
675
715
|
numeric_transformation(value) {|n| n.abs}
|
676
716
|
end
|
677
717
|
|
718
|
+
def unquote(value)
|
719
|
+
assert_type value, :String
|
720
|
+
Sass::Script::String.new(value.value)
|
721
|
+
end
|
722
|
+
|
678
723
|
private
|
679
724
|
|
680
725
|
# This method implements the pattern of transforming a numeric value into
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Sass::Script
|
2
|
+
class Interpolation < Node
|
3
|
+
def initialize(before, mid, after, wb, wa)
|
4
|
+
@before = before
|
5
|
+
@mid = mid
|
6
|
+
@after = after
|
7
|
+
@whitespace_before = wb
|
8
|
+
@whitespace_after = wa
|
9
|
+
end
|
10
|
+
|
11
|
+
def inspect
|
12
|
+
"(interpolation #{@before.inspect} #{@mid.inspect} #{after.inspect})"
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_sass
|
16
|
+
res = ""
|
17
|
+
res << @before.to_sass if @before
|
18
|
+
res << ' ' if @before && @whitespace_before
|
19
|
+
res << '#{' << @mid.to_sass << '}'
|
20
|
+
res << ' ' if @after && @whitespace_after
|
21
|
+
res << @after.to_sass if @after
|
22
|
+
res
|
23
|
+
end
|
24
|
+
|
25
|
+
def children
|
26
|
+
[@before, @mid, @after].compact
|
27
|
+
end
|
28
|
+
|
29
|
+
protected
|
30
|
+
|
31
|
+
def _perform(environment)
|
32
|
+
res = ""
|
33
|
+
res << @before.perform(environment).to_s if @before
|
34
|
+
res << " " if @before && @whitespace_before
|
35
|
+
val = @mid.perform(environment)
|
36
|
+
res << (val.is_a?(Sass::Script::String) ? val.value : val.to_s)
|
37
|
+
res << " " if @after && @whitespace_after
|
38
|
+
res << @after.perform(environment).to_s if @after
|
39
|
+
Sass::Script::String.new(res)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/lib/sass/script/lexer.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'sass/scss/rx'
|
2
|
+
|
1
3
|
require 'strscan'
|
2
4
|
|
3
5
|
module Sass
|
@@ -6,6 +8,8 @@ module Sass
|
|
6
8
|
# It takes a raw string and converts it to individual tokens
|
7
9
|
# that are easier to parse.
|
8
10
|
class Lexer
|
11
|
+
include Sass::SCSS::RX
|
12
|
+
|
9
13
|
# A struct containing information about an individual token.
|
10
14
|
#
|
11
15
|
# `type`: \[`Symbol`\]
|
@@ -19,7 +23,21 @@ module Sass
|
|
19
23
|
#
|
20
24
|
# `offset`: \[`Fixnum`\]
|
21
25
|
# : The number of bytes into the line the SassScript token appeared.
|
22
|
-
|
26
|
+
#
|
27
|
+
# `pos`: \[`Fixnum`\]
|
28
|
+
# : The scanner position at which the SassScript token appeared.
|
29
|
+
Token = Struct.new(:type, :value, :line, :offset, :pos)
|
30
|
+
|
31
|
+
# The line number of the lexer's current position.
|
32
|
+
#
|
33
|
+
# @return [Fixnum]
|
34
|
+
attr_reader :line
|
35
|
+
|
36
|
+
# The number of bytes into the current line
|
37
|
+
# of the lexer's current position.
|
38
|
+
#
|
39
|
+
# @return [Fixnum]
|
40
|
+
attr_reader :offset
|
23
41
|
|
24
42
|
# A hash from operator strings to the corresponding token types.
|
25
43
|
# @private
|
@@ -30,6 +48,7 @@ module Sass
|
|
30
48
|
'/' => :div,
|
31
49
|
'%' => :mod,
|
32
50
|
'=' => :single_eq,
|
51
|
+
':' => :colon,
|
33
52
|
'(' => :lparen,
|
34
53
|
')' => :rparen,
|
35
54
|
',' => :comma,
|
@@ -44,23 +63,43 @@ module Sass
|
|
44
63
|
'<' => :lt,
|
45
64
|
'#{' => :begin_interpolation,
|
46
65
|
'}' => :end_interpolation,
|
66
|
+
';' => :semicolon,
|
67
|
+
'{' => :lcurly,
|
47
68
|
}
|
48
69
|
|
70
|
+
# @private
|
71
|
+
OPERATORS_REVERSE = Haml::Util.map_hash(OPERATORS) {|k, v| [v, k]}
|
72
|
+
|
73
|
+
# @private
|
74
|
+
TOKEN_NAMES = Haml::Util.map_hash(OPERATORS_REVERSE) {|k, v| [k, v.inspect]}.merge({
|
75
|
+
:const => "variable (e.g. $foo)",
|
76
|
+
:ident => "identifier (e.g. middle)",
|
77
|
+
:bool => "boolean (e.g. true, false)",
|
78
|
+
})
|
79
|
+
|
49
80
|
# A list of operator strings ordered with longer names first
|
50
81
|
# so that `>` and `<` don't clobber `>=` and `<=`.
|
51
82
|
# @private
|
52
83
|
OP_NAMES = OPERATORS.keys.sort_by {|o| -o.size}
|
53
84
|
|
85
|
+
# A sub-list of {OP_NAMES} that only includes operators
|
86
|
+
# with identifier names.
|
87
|
+
# @private
|
88
|
+
IDENT_OP_NAMES = OP_NAMES.select {|k, v| k =~ /^\w+/}
|
89
|
+
|
54
90
|
# A hash of regular expressions that are used for tokenizing.
|
55
91
|
# @private
|
56
92
|
REGULAR_EXPRESSIONS = {
|
57
|
-
:whitespace => /\s
|
58
|
-
:
|
59
|
-
:
|
93
|
+
:whitespace => /\s+/,
|
94
|
+
:comment => COMMENT,
|
95
|
+
:single_line_comment => SINGLE_LINE_COMMENT,
|
96
|
+
:variable => /([!\$])(#{IDENT})/,
|
97
|
+
:ident => IDENT,
|
60
98
|
:number => /(-)?(?:(\d*\.\d+)|(\d+))([a-zA-Z%]+)?/,
|
61
|
-
:color =>
|
99
|
+
:color => HEXCOLOR,
|
62
100
|
:bool => /(true|false)\b/,
|
63
|
-
:
|
101
|
+
:ident_op => %r{(#{Regexp.union(*IDENT_OP_NAMES.map{|s| Regexp.new(Regexp.escape(s) + '(?:\b|$)')})})},
|
102
|
+
:op => %r{(#{Regexp.union(*OP_NAMES)})},
|
64
103
|
}
|
65
104
|
|
66
105
|
class << self
|
@@ -109,6 +148,18 @@ module Sass
|
|
109
148
|
return tok
|
110
149
|
end
|
111
150
|
|
151
|
+
# Returns whether or not there's whitespace before the next token.
|
152
|
+
#
|
153
|
+
# @return [Boolean]
|
154
|
+
def whitespace?(tok = @tok)
|
155
|
+
if tok
|
156
|
+
@scanner.string[0...tok.pos] =~ /\s$/
|
157
|
+
else
|
158
|
+
@scanner.string[@scanner.pos, 1] =~ /^\s/ ||
|
159
|
+
@scanner.string[@scanner.pos - 1, 1] =~ /\s$/
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
112
163
|
# Returns the next token without moving the lexer forward.
|
113
164
|
#
|
114
165
|
# @return [Token] The next token
|
@@ -116,83 +167,140 @@ module Sass
|
|
116
167
|
@tok ||= read_token
|
117
168
|
end
|
118
169
|
|
170
|
+
# Rewinds the underlying StringScanner
|
171
|
+
# to before the token returned by \{#peek}.
|
172
|
+
def unpeek!
|
173
|
+
@scanner.pos = @tok.pos if @tok
|
174
|
+
end
|
175
|
+
|
119
176
|
# @return [Boolean] Whether or not there's more source text to lex.
|
120
177
|
def done?
|
121
|
-
whitespace unless after_interpolation?
|
178
|
+
whitespace unless after_interpolation? && @interpolation_stack.last
|
122
179
|
@scanner.eos? && @tok.nil?
|
123
180
|
end
|
124
181
|
|
182
|
+
def expected!(name)
|
183
|
+
unpeek!
|
184
|
+
Sass::SCSS::Parser.expected(@scanner, name, @line)
|
185
|
+
end
|
186
|
+
|
187
|
+
def str
|
188
|
+
old_pos = @tok ? @tok.pos : @scanner.pos
|
189
|
+
yield
|
190
|
+
new_pos = @tok ? @tok.pos : @scanner.pos
|
191
|
+
@scanner.string[old_pos...new_pos]
|
192
|
+
end
|
193
|
+
|
125
194
|
private
|
126
195
|
|
127
196
|
def read_token
|
128
197
|
return if done?
|
198
|
+
return unless value = token
|
129
199
|
|
130
|
-
value =
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
Token.new(value.first, value.last, @line, last_match_position)
|
200
|
+
value.last.line = @line if value.last.is_a?(Script::Node)
|
201
|
+
Token.new(value.first, value.last, @line,
|
202
|
+
current_position - @scanner.matched_size,
|
203
|
+
@scanner.pos - @scanner.matched_size)
|
135
204
|
end
|
136
205
|
|
137
206
|
def whitespace
|
138
|
-
|
207
|
+
nil while scan(REGULAR_EXPRESSIONS[:whitespace]) ||
|
208
|
+
scan(REGULAR_EXPRESSIONS[:comment]) ||
|
209
|
+
scan(REGULAR_EXPRESSIONS[:single_line_comment])
|
139
210
|
end
|
140
211
|
|
141
212
|
def token
|
142
|
-
|
143
|
-
|
213
|
+
if after_interpolation? && (interp_type = @interpolation_stack.pop)
|
214
|
+
return string(interp_type, true)
|
215
|
+
end
|
216
|
+
|
217
|
+
variable || string(:double, false) || string(:single, false) || number ||
|
218
|
+
color || bool || raw(URI) || raw(UNICODERANGE) || special_fun ||
|
219
|
+
ident_op || ident || op
|
144
220
|
end
|
145
221
|
|
146
222
|
def variable
|
147
|
-
|
148
|
-
|
223
|
+
_variable(REGULAR_EXPRESSIONS[:variable])
|
224
|
+
end
|
225
|
+
|
226
|
+
def _variable(rx)
|
227
|
+
line = @line
|
228
|
+
offset = @offset
|
229
|
+
return unless scan(rx)
|
230
|
+
if @scanner[1] == '!' && @scanner[2] != 'important'
|
231
|
+
Script.var_warning(@scanner[2], line, offset + 1, @options[:filename])
|
232
|
+
end
|
233
|
+
|
234
|
+
[:const, @scanner[2]]
|
149
235
|
end
|
150
236
|
|
151
237
|
def ident
|
152
|
-
return unless s =
|
238
|
+
return unless s = scan(REGULAR_EXPRESSIONS[:ident])
|
153
239
|
[:ident, s.gsub(/\\(.)/, '\1')]
|
154
240
|
end
|
155
241
|
|
156
242
|
def string(re, open)
|
157
|
-
return unless
|
243
|
+
return unless scan(STRING_REGULAR_EXPRESSIONS[[re, open]])
|
158
244
|
@interpolation_stack << re if @scanner[2].empty? # Started an interpolated section
|
159
|
-
[:string, Script::String.new(@scanner[1].gsub(/\\([^0-9a-f])/, '\1').gsub(/\\([0-9a-f]{1,4})/, "\\\\\\1"))]
|
245
|
+
[:string, Script::String.new(@scanner[1].gsub(/\\([^0-9a-f])/, '\1').gsub(/\\([0-9a-f]{1,4})/, "\\\\\\1"), :string)]
|
160
246
|
end
|
161
247
|
|
162
248
|
def number
|
163
|
-
return unless
|
249
|
+
return unless scan(REGULAR_EXPRESSIONS[:number])
|
164
250
|
value = @scanner[2] ? @scanner[2].to_f : @scanner[3].to_i
|
165
251
|
value = -value if @scanner[1]
|
166
252
|
[:number, Script::Number.new(value, Array(@scanner[4]))]
|
167
253
|
end
|
168
254
|
|
169
255
|
def color
|
170
|
-
return unless
|
171
|
-
value =
|
172
|
-
|
173
|
-
else
|
174
|
-
(1..3).map {|i| @scanner[i]}.map {|num| num.ljust(2, num).to_i(16)}
|
175
|
-
end
|
256
|
+
return unless s = scan(REGULAR_EXPRESSIONS[:color])
|
257
|
+
value = s.scan(/^#(..?)(..?)(..?)$/).first.
|
258
|
+
map {|num| num.ljust(2, num).to_i(16)}
|
176
259
|
[:color, Script::Color.new(value)]
|
177
260
|
end
|
178
261
|
|
179
262
|
def bool
|
180
|
-
return unless s =
|
263
|
+
return unless s = scan(REGULAR_EXPRESSIONS[:bool])
|
181
264
|
[:bool, Script::Bool.new(s == 'true')]
|
182
265
|
end
|
183
266
|
|
267
|
+
def special_fun
|
268
|
+
return unless str1 = scan(/(calc|expression|progid:[a-z\.]*)\(/i)
|
269
|
+
str2, _ = Haml::Shared.balance(@scanner, ?(, ?), 1)
|
270
|
+
c = str2.count("\n")
|
271
|
+
@line += c
|
272
|
+
@offset = (c == 0 ? @offset + str2.size : str2[/\n(.*)/, 1].size)
|
273
|
+
[:special_fun,
|
274
|
+
Haml::Util.merge_adjacent_strings(
|
275
|
+
[str1] + Sass::Engine.parse_interp(str2, @line, @options))]
|
276
|
+
end
|
277
|
+
|
278
|
+
def ident_op
|
279
|
+
return unless op = scan(REGULAR_EXPRESSIONS[:ident_op])
|
280
|
+
[OPERATORS[op]]
|
281
|
+
end
|
282
|
+
|
184
283
|
def op
|
185
|
-
|
186
|
-
|
284
|
+
return unless op = scan(REGULAR_EXPRESSIONS[:op])
|
285
|
+
@interpolation_stack << nil if op == :begin_interpolation
|
187
286
|
[OPERATORS[op]]
|
188
287
|
end
|
189
288
|
|
190
|
-
def
|
191
|
-
|
289
|
+
def raw(rx)
|
290
|
+
return unless val = scan(rx)
|
291
|
+
[:raw, val]
|
292
|
+
end
|
293
|
+
|
294
|
+
def scan(re)
|
295
|
+
return unless str = @scanner.scan(re)
|
296
|
+
c = str.count("\n")
|
297
|
+
@line += c
|
298
|
+
@offset = (c == 0 ? @offset + str.size : str[/\n(.*)/, 1].size)
|
299
|
+
str
|
192
300
|
end
|
193
301
|
|
194
|
-
def
|
195
|
-
|
302
|
+
def current_position
|
303
|
+
@offset + 1
|
196
304
|
end
|
197
305
|
|
198
306
|
def after_interpolation?
|
data/lib/sass/script/literal.rb
CHANGED
@@ -21,14 +21,7 @@ module Sass::Script
|
|
21
21
|
# @param value [Object] The object for \{#value}
|
22
22
|
def initialize(value = nil)
|
23
23
|
@value = value
|
24
|
-
|
25
|
-
|
26
|
-
# Evaluates the literal.
|
27
|
-
#
|
28
|
-
# @param environment [Sass::Environment] The environment in which to evaluate the SassScript
|
29
|
-
# @return [Literal] This literal
|
30
|
-
def perform(environment)
|
31
|
-
self
|
24
|
+
super()
|
32
25
|
end
|
33
26
|
|
34
27
|
# Returns an empty array.
|
@@ -109,7 +102,7 @@ MSG
|
|
109
102
|
Sass::Script::Bool.new(!to_bool)
|
110
103
|
end
|
111
104
|
|
112
|
-
# The SassScript default operation (e.g.
|
105
|
+
# The SassScript default operation (e.g. `$a $b`, `"foo" "bar"`).
|
113
106
|
#
|
114
107
|
# @param other [Literal] The right-hand side of the operator
|
115
108
|
# @return [Script::String] A string containing both literals
|
@@ -118,7 +111,7 @@ MSG
|
|
118
111
|
Sass::Script::String.new("#{self.to_s} #{other.to_s}")
|
119
112
|
end
|
120
113
|
|
121
|
-
# The SassScript `,` operation (e.g.
|
114
|
+
# The SassScript `,` operation (e.g. `$a, $b`, `"foo", "bar"`).
|
122
115
|
#
|
123
116
|
# @param other [Literal] The right-hand side of the operator
|
124
117
|
# @return [Script::String] A string containing both literals
|
@@ -133,6 +126,9 @@ MSG
|
|
133
126
|
# @return [Script::String] A string containing both literals
|
134
127
|
# without any separation
|
135
128
|
def plus(other)
|
129
|
+
if other.is_a?(Sass::Script::String)
|
130
|
+
return Sass::Script::String.new(self.to_s + other.value, other.type)
|
131
|
+
end
|
136
132
|
Sass::Script::String.new(self.to_s + other.to_s)
|
137
133
|
end
|
138
134
|
|
@@ -154,7 +150,16 @@ MSG
|
|
154
150
|
Sass::Script::String.new("#{self.to_s}/#{other.to_s}")
|
155
151
|
end
|
156
152
|
|
157
|
-
# The SassScript unary
|
153
|
+
# The SassScript unary `+` operation (e.g. `+$a`).
|
154
|
+
#
|
155
|
+
# @param other [Literal] The right-hand side of the operator
|
156
|
+
# @return [Script::String] A string containing the literal
|
157
|
+
# preceded by `"+"`
|
158
|
+
def unary_plus
|
159
|
+
Sass::Script::String.new("+#{self.to_s}")
|
160
|
+
end
|
161
|
+
|
162
|
+
# The SassScript unary `-` operation (e.g. `-$a`).
|
158
163
|
#
|
159
164
|
# @param other [Literal] The right-hand side of the operator
|
160
165
|
# @return [Script::String] A string containing the literal
|
@@ -163,7 +168,7 @@ MSG
|
|
163
168
|
Sass::Script::String.new("-#{self.to_s}")
|
164
169
|
end
|
165
170
|
|
166
|
-
# The SassScript unary `/` operation (e.g.
|
171
|
+
# The SassScript unary `/` operation (e.g. `/$a`).
|
167
172
|
#
|
168
173
|
# @param other [Literal] The right-hand side of the operator
|
169
174
|
# @return [Script::String] A string containing the literal
|
@@ -206,5 +211,16 @@ MSG
|
|
206
211
|
def to_s
|
207
212
|
raise Sass::SyntaxError.new("[BUG] All subclasses of Sass::Literal must implement #to_s.")
|
208
213
|
end
|
214
|
+
alias_method :to_sass, :to_s
|
215
|
+
|
216
|
+
protected
|
217
|
+
|
218
|
+
# Evaluates the literal.
|
219
|
+
#
|
220
|
+
# @param environment [Sass::Environment] The environment in which to evaluate the SassScript
|
221
|
+
# @return [Literal] This literal
|
222
|
+
def _perform(environment)
|
223
|
+
self
|
224
|
+
end
|
209
225
|
end
|
210
226
|
end
|