sass 3.1.0.alpha.48 → 3.1.0.alpha.49

Sign up to get free protection for your applications and to get access to all the features.
@@ -25,21 +25,6 @@ module Sass
25
25
  @imported_file ||= import
26
26
  end
27
27
 
28
- # @see Node#to_sass
29
- def to_sass(tabs = 0, opts = {})
30
- "#{' ' * tabs}@import #{@imported_filename}\n"
31
- end
32
-
33
- # @see Node#to_scss
34
- def to_scss(tabs = 0, opts = {})
35
- "#{' ' * tabs}@import \"#{@imported_filename}\";\n"
36
- end
37
-
38
- # @see Node#cssize
39
- def cssize(*args)
40
- super.first
41
- end
42
-
43
28
  # Returns whether or not this import should emit a CSS @import declaration
44
29
  #
45
30
  # @return [Boolean] Whether or not this is a simple CSS @import declaration.
@@ -51,47 +36,6 @@ module Sass
51
36
  end
52
37
  end
53
38
 
54
- protected
55
-
56
- # @see Node#_cssize
57
- def _cssize(*args)
58
- super.children
59
- rescue Sass::SyntaxError => e
60
- e.modify_backtrace(:filename => children.first.filename)
61
- e.add_backtrace(:filename => @filename, :line => @line)
62
- raise e
63
- end
64
-
65
- # Returns a static DirectiveNode if this is importing a CSS file,
66
- # or parses and includes the imported Sass file.
67
- #
68
- # @param environment [Sass::Environment] The lexical environment containing
69
- # variable and mixin values
70
- def _perform(environment)
71
- if path = css_import?
72
- return DirectiveNode.new("@import url(#{path})")
73
- end
74
- super
75
- end
76
-
77
- # Parses the imported file and runs the dynamic Sass for it.
78
- #
79
- # @param environment [Sass::Environment] The lexical environment containing
80
- # variable and mixin values
81
- def perform!(environment)
82
- environment.push_frame(:filename => @filename, :line => @line)
83
- # TODO: re-enable caching
84
- root = imported_file.to_tree
85
- self.children = root.children
86
- self.children = perform_children(environment)
87
- rescue Sass::SyntaxError => e
88
- e.modify_backtrace(:filename => imported_file.options[:filename])
89
- e.add_backtrace(:filename => @filename, :line => @line)
90
- raise e
91
- ensure
92
- environment.pop_frame
93
- end
94
-
95
39
  private
96
40
 
97
41
  def import
@@ -28,48 +28,5 @@ module Sass::Tree
28
28
  def value
29
29
  "@media #{query}"
30
30
  end
31
-
32
- # Pass on the parent if it's a RuleNode.
33
- #
34
- # @see Node#cssize
35
- def cssize(extends, parent = nil)
36
- _cssize(extends, (parent if [MediaNode, RuleNode].include?(parent.class)))
37
- rescue Sass::SyntaxError => e
38
- e.modify_backtrace(:filename => filename, :line => line)
39
- raise e
40
- end
41
-
42
- protected
43
-
44
- # Merge nested media queries.
45
- #
46
- # @see Node#_cssize
47
- def _cssize(extends, parent)
48
- node = super
49
- media = node.children.select {|c| c.is_a?(MediaNode)}
50
- node.children.reject! {|c| c.is_a?(MediaNode)}
51
- media.each {|n| n.query = "#{query} and #{n.query}"}
52
- (node.children.empty? ? [] : [node]) + media
53
- end
54
-
55
- # If we're passed a parent, bubble it down.
56
- #
57
- # @see Node#cssize
58
- def cssize!(extends, parent)
59
- return super unless parent.is_a?(RuleNode)
60
- new_rule = parent.dup
61
- new_rule.children = self.children
62
- self.children = Array(new_rule.cssize(extends, self))
63
- # If the last child is actually the end of the group,
64
- # the parent's cssize will set it properly
65
- self.children.last.group_end = false unless self.children.empty?
66
- end
67
-
68
- # @see Node#to_s
69
- def _to_s(tabs)
70
- str = super(tabs + self.tabs)
71
- str.gsub!(/\n\Z/, '') unless style == :compressed || group_end
72
- str
73
- end
74
31
  end
75
32
  end
@@ -4,45 +4,24 @@ module Sass
4
4
  #
5
5
  # @see Sass::Tree
6
6
  class MixinDefNode < Node
7
+ # The mixin name.
8
+ # @return [String]
9
+ attr_reader :name
10
+
11
+ # The arguments for the mixin.
12
+ # Each element is a tuple containing the variable for argument
13
+ # and the parse tree for the default value of the argument.
14
+ #
15
+ # @return [Array<(Script::Node, Script::Node)>]
16
+ attr_reader :args
17
+
7
18
  # @param name [String] The mixin name
8
- # @param args [Array<(Script::Node, Script::Node)>] The arguments for the mixin.
9
- # Each element is a tuple containing the variable for argument
10
- # and the parse tree for the default value of the argument
19
+ # @param args [Array<(Script::Node, Script::Node)>] See \{#args}
11
20
  def initialize(name, args)
12
21
  @name = name
13
22
  @args = args
14
23
  super()
15
24
  end
16
-
17
- protected
18
-
19
- # @see Node#to_src
20
- def to_src(tabs, opts, fmt)
21
- args =
22
- if @args.empty?
23
- ""
24
- else
25
- '(' + @args.map do |v, d|
26
- if d
27
- "#{v.to_sass(opts)}: #{d.to_sass(opts)}"
28
- else
29
- v.to_sass(opts)
30
- end
31
- end.join(", ") + ')'
32
- end
33
-
34
- "#{' ' * tabs}#{fmt == :sass ? '=' : '@mixin '}#{dasherize(@name, opts)}#{args}" +
35
- children_to_src(tabs, opts, fmt)
36
- end
37
-
38
- # Loads the mixin into the environment.
39
- #
40
- # @param environment [Sass::Environment] The lexical environment containing
41
- # variable and mixin values
42
- def _perform(environment)
43
- environment.set_mixin(@name, Sass::Mixin.new(@name, @args, environment, children))
44
- []
45
- end
46
25
  end
47
26
  end
48
27
  end
@@ -7,6 +7,18 @@ module Sass::Tree
7
7
  #
8
8
  # @see Sass::Tree
9
9
  class MixinNode < Node
10
+ # The name of the mixin.
11
+ # @return [String]
12
+ attr_reader :name
13
+
14
+ # The arguments to the mixin.
15
+ # @return [Array<Script::Node>]
16
+ attr_reader :args
17
+
18
+ # A hash from keyword argument names to values.
19
+ # @return [{String => Script::Node}]
20
+ attr_reader :keywords
21
+
10
22
  # @see Node#options=
11
23
  def options=(opts)
12
24
  super
@@ -15,117 +27,13 @@ module Sass::Tree
15
27
  end
16
28
 
17
29
  # @param name [String] The name of the mixin
18
- # @param args [Array<Script::Node>] The arguments to the mixin
19
- # @param keywords [{String => Script::Node}] A hash from keyword argument names to values
30
+ # @param args [Array<Script::Node>] See \{#args}
31
+ # @param keywords [{String => Script::Node}] See \{#keywords}
20
32
  def initialize(name, args, keywords)
21
33
  @name = name
22
34
  @args = args
23
35
  @keywords = keywords
24
36
  super()
25
37
  end
26
-
27
- # @see Node#cssize
28
- def cssize(extends, parent = nil)
29
- _cssize(extends, parent) # Pass on the parent even if it's not a MixinNode
30
- end
31
-
32
- protected
33
-
34
- # @see Node#to_src
35
- def to_src(tabs, opts, fmt)
36
- unless @args.empty? && @keywords.empty?
37
- args = @args.map {|a| a.to_sass(opts)}.join(", ")
38
- keywords = @keywords.map {|k, v| "$#{dasherize(k, opts)}: #{v.to_sass(opts)}"}.join(', ')
39
- arglist = "(#{args}#{', ' unless args.empty? || keywords.empty?}#{keywords})"
40
- end
41
- "#{' ' * tabs}#{fmt == :sass ? '+' : '@include '}#{dasherize(@name, opts)}#{arglist}#{semi fmt}\n"
42
- end
43
-
44
- # @see Node#_cssize
45
- def _cssize(extends, parent)
46
- children.map do |c|
47
- parent.check_child! c
48
- c.cssize(extends, parent)
49
- end.flatten
50
- rescue Sass::SyntaxError => e
51
- e.modify_backtrace(:mixin => @name, :filename => filename, :line => line)
52
- e.add_backtrace(:filename => filename, :line => line)
53
- raise e
54
- end
55
-
56
- # Runs the mixin.
57
- #
58
- # @param environment [Sass::Environment] The lexical environment containing
59
- # variable and mixin values
60
- # @raise [Sass::SyntaxError] if there is no mixin with the given name
61
- # @raise [Sass::SyntaxError] if an incorrect number of arguments was passed
62
- # @see Sass::Tree
63
- def perform!(environment)
64
- handle_include_loop!(environment) if environment.mixins_in_use.include?(@name)
65
-
66
- original_env = environment
67
- original_env.push_frame(:filename => filename, :line => line)
68
- original_env.prepare_frame(:mixin => @name)
69
- raise Sass::SyntaxError.new("Undefined mixin '#{@name}'.") unless mixin = environment.mixin(@name)
70
-
71
- passed_args = @args.dup
72
- passed_keywords = @keywords.dup
73
-
74
- raise Sass::SyntaxError.new(<<END.gsub("\n", "")) if mixin.args.size < passed_args.size
75
- Mixin #{@name} takes #{mixin.args.size} argument#{'s' if mixin.args.size != 1}
76
- but #{@args.size} #{@args.size == 1 ? 'was' : 'were'} passed.
77
- END
78
-
79
- passed_keywords.each do |name, value|
80
- # TODO: Make this fast
81
- unless mixin.args.find {|(var, default)| var.underscored_name == name}
82
- raise Sass::SyntaxError.new("Mixin #{@name} doesn't have an argument named $#{name}")
83
- end
84
- end
85
-
86
- environment = mixin.args.zip(passed_args).
87
- inject(Sass::Environment.new(mixin.environment)) do |env, ((var, default), value)|
88
- env.set_local_var(var.name,
89
- if value
90
- value.perform(environment)
91
- elsif kv = passed_keywords[var.underscored_name]
92
- kv.perform(env)
93
- elsif default
94
- val = default.perform(env)
95
- if default.context == :equals && val.is_a?(Sass::Script::String)
96
- val = Sass::Script::String.new(val.value)
97
- end
98
- val
99
- end)
100
- raise Sass::SyntaxError.new("Mixin #{@name} is missing parameter #{var.inspect}.") unless env.var(var.name)
101
- env
102
- end
103
-
104
- self.children = mixin.tree.map {|c| c.perform(environment)}.flatten
105
- rescue Sass::SyntaxError => e
106
- if original_env # Don't add backtrace info if this is an @include loop
107
- e.modify_backtrace(:mixin => @name, :line => @line)
108
- e.add_backtrace(:line => @line)
109
- end
110
- raise e
111
- ensure
112
- original_env.pop_frame if original_env
113
- end
114
-
115
- private
116
-
117
- def handle_include_loop!(environment)
118
- msg = "An @include loop has been found:"
119
- mixins = environment.stack.map {|s| s[:mixin]}.compact
120
- if mixins.size == 2 && mixins[0] == mixins[1]
121
- raise Sass::SyntaxError.new("#{msg} #{@name} includes itself")
122
- end
123
-
124
- mixins << @name
125
- msg << "\n" << Sass::Util.enum_cons(mixins, 2).map do |m1, m2|
126
- " #{m1} includes #{m2}"
127
- end.join("\n")
128
- raise Sass::SyntaxError.new(msg)
129
- end
130
38
  end
131
39
  end
@@ -8,7 +8,7 @@ module Sass
8
8
  # in addition to nodes for CSS rules and properties.
9
9
  # Nodes that only appear in this state are called **dynamic nodes**.
10
10
  #
11
- # {Tree::Node#perform} returns a static Sass tree, which is different.
11
+ # {Tree::Visitors::Perform} creates a static Sass tree, which is different.
12
12
  # It still has nodes for CSS rules and properties
13
13
  # but it doesn't have any dynamic-generation-related nodes.
14
14
  # The nodes in this state are in the same structure as the Sass document:
@@ -16,12 +16,12 @@ module Sass
16
16
  # Nodes that can be in this state or in the dynamic state
17
17
  # are called **static nodes**.
18
18
  #
19
- # {Tree::Node#cssize} then returns a static CSS tree.
19
+ # {Tree::Visitors::Cssize} is then used to create a static CSS tree.
20
20
  # This is like a static Sass tree,
21
21
  # but the structure exactly mirrors that of the generated CSS.
22
22
  # Rules and properties can't be nested beneath one another in this state.
23
23
  #
24
- # Finally, {Tree::Node#to_s} can be called on a static CSS tree
24
+ # Finally, {Tree::Visitors::ToCss} can be called on a static CSS tree
25
25
  # to get the actual CSS code as a string.
26
26
  module Tree
27
27
  # The abstract superclass of all parse-tree nodes.
@@ -140,22 +140,13 @@ module Sass
140
140
 
141
141
  # Computes the CSS corresponding to this static CSS tree.
142
142
  #
143
- # \{#to_s} shouldn't be overridden directly; instead, override \{#\_to\_s}.
144
- # Only static-node subclasses need to implement \{#to\_s}.
145
- #
146
- # This may return `nil`, but it will only do so if \{#invisible?} is true.
147
- #
148
- # @param args [Array] Passed on to \{#\_to\_s}
149
143
  # @return [String, nil] The resulting CSS
150
144
  # @see Sass::Tree
151
- def to_s(opts = nil)
152
- _to_s(opts)
153
- rescue Sass::SyntaxError => e
154
- e.modify_backtrace(:filename => filename, :line => line)
155
- raise e
145
+ def to_s
146
+ Sass::Tree::Visitors::ToCss.visit(self)
156
147
  end
157
148
 
158
- # Converts a static CSS tree (e.g. the output of \{#cssize})
149
+ # Converts a static CSS tree (e.g. the output of \{Tree::Visitors::Cssize})
159
150
  # into another static CSS tree,
160
151
  # with the given extensions applied to all relevant {RuleNode}s.
161
152
  #
@@ -176,46 +167,6 @@ module Sass
176
167
  raise e
177
168
  end
178
169
 
179
- # Converts a static Sass tree (e.g. the output of \{#perform})
180
- # into a static CSS tree.
181
- #
182
- # \{#cssize} shouldn't be overridden directly;
183
- # instead, override \{#\_cssize} or \{#cssize!}.
184
- #
185
- # @param extends [Sass::Util::SubsetMap{Selector::Simple => Selector::Sequence}]
186
- # The extensions defined for this tree
187
- # @param parent [Node, nil] The parent node of this node.
188
- # This should only be non-nil if the parent is the same class as this node
189
- # @return [Tree::Node] The resulting tree of static nodes
190
- # @raise [Sass::SyntaxError] if some element of the tree is invalid
191
- # @see Sass::Tree
192
- def cssize(extends, parent = nil)
193
- _cssize(extends, (parent if parent.class == self.class))
194
- rescue Sass::SyntaxError => e
195
- e.modify_backtrace(:filename => filename, :line => line)
196
- raise e
197
- end
198
-
199
- # Converts a dynamic tree into a static Sass tree.
200
- # That is, runs the dynamic Sass code:
201
- # mixins, variables, control directives, and so forth.
202
- # This doesn't modify this node or any of its children.
203
- #
204
- # \{#perform} shouldn't be overridden directly;
205
- # instead, override \{#\_perform} or \{#perform!}.
206
- #
207
- # @param environment [Sass::Environment] The lexical environment containing
208
- # variable and mixin values
209
- # @return [Tree::Node] The resulting tree of static nodes
210
- # @raise [Sass::SyntaxError] if some element of the tree is invalid
211
- # @see Sass::Tree
212
- def perform(environment)
213
- _perform(environment)
214
- rescue Sass::SyntaxError => e
215
- e.modify_backtrace(:filename => filename, :line => line)
216
- raise e
217
- end
218
-
219
170
  # Iterates through each node in the tree rooted at this node
220
171
  # in a pre-order walk.
221
172
  #
@@ -228,20 +179,18 @@ module Sass
228
179
 
229
180
  # Converts a node to Sass code that will generate it.
230
181
  #
231
- # @param tabs [Fixnum] The amount of tabulation to use for the Sass code
232
- # @param opts [{Symbol => Object}] An options hash (see {Sass::CSS#initialize})
182
+ # @param options [{Symbol => Object}] An options hash (see {Sass::CSS#initialize})
233
183
  # @return [String] The Sass code corresponding to the node
234
- def to_sass(tabs = 0, opts = {})
235
- to_src(tabs, opts, :sass)
184
+ def to_sass(options = {})
185
+ Sass::Tree::Visitors::Convert.visit(self, options, :sass)
236
186
  end
237
187
 
238
188
  # Converts a node to SCSS code that will generate it.
239
189
  #
240
- # @param tabs [Fixnum] The amount of tabulation to use for the SCSS code
241
- # @param opts [{Symbol => Object}] An options hash (see {Sass::CSS#initialize})
190
+ # @param options [{Symbol => Object}] An options hash (see {Sass::CSS#initialize})
242
191
  # @return [String] The Sass code corresponding to the node
243
- def to_scss(tabs = 0, opts = {})
244
- to_src(tabs, opts, :scss)
192
+ def to_scss(options = {})
193
+ Sass::Tree::Visitors::Convert.visit(self, options, :scss)
245
194
  end
246
195
 
247
196
  # Names of options that are saved when the node is serialized and cached.
@@ -271,104 +220,6 @@ module Sass
271
220
 
272
221
  protected
273
222
 
274
- # Computes the CSS corresponding to this particular Sass node.
275
- #
276
- # This method should never raise {Sass::SyntaxError}s.
277
- # Such errors will not be properly annotated with Sass backtrace information.
278
- # All error conditions should be checked in earlier transformations,
279
- # such as \{#cssize} and \{#perform}.
280
- #
281
- # @param args [Array] ignored
282
- # @return [String, nil] The resulting CSS
283
- # @see #to_s
284
- # @see Sass::Tree
285
- def _to_s
286
- Sass::Util.abstract(self)
287
- end
288
-
289
- # Converts this static Sass node into a static CSS node,
290
- # returning the new node.
291
- # This doesn't modify this node or any of its children.
292
- #
293
- # @param extends [Sass::Util::SubsetMap{Selector::Simple => Selector::Sequence}]
294
- # The extensions defined for this tree
295
- # @param parent [Node, nil] The parent node of this node.
296
- # This should only be non-nil if the parent is the same class as this node
297
- # @return [Tree::Node, Array<Tree::Node>] The resulting static CSS nodes
298
- # @raise [Sass::SyntaxError] if some element of the tree is invalid
299
- # @see #cssize
300
- # @see Sass::Tree
301
- def _cssize(extends, parent)
302
- node = dup
303
- node.cssize!(extends, parent)
304
- node
305
- end
306
-
307
- # Destructively converts this static Sass node into a static CSS node.
308
- # This *does* modify this node,
309
- # but will be run non-destructively by \{#\_cssize\}.
310
- #
311
- # @param extends [Sass::Util::SubsetMap{Selector::Simple => Selector::Sequence}]
312
- # The extensions defined for this tree
313
- # @param parent [Node, nil] The parent node of this node.
314
- # This should only be non-nil if the parent is the same class as this node
315
- # @see #cssize
316
- def cssize!(extends, parent)
317
- self.children = children.map {|c| c.cssize(extends, self)}.flatten
318
- end
319
-
320
- # Runs any dynamic Sass code in this particular node.
321
- # This doesn't modify this node or any of its children.
322
- #
323
- # @param environment [Sass::Environment] The lexical environment containing
324
- # variable and mixin values
325
- # @return [Tree::Node, Array<Tree::Node>] The resulting static nodes
326
- # @see #perform
327
- # @see Sass::Tree
328
- def _perform(environment)
329
- node = dup
330
- node.perform!(environment)
331
- node
332
- end
333
-
334
- # Destructively runs dynamic Sass code in this particular node.
335
- # This *does* modify this node,
336
- # but will be run non-destructively by \{#\_perform\}.
337
- #
338
- # @param environment [Sass::Environment] The lexical environment containing
339
- # variable and mixin values
340
- # @see #perform
341
- def perform!(environment)
342
- self.children = perform_children(Environment.new(environment))
343
- self.children.each {|c| check_child! c}
344
- end
345
-
346
- # Non-destructively runs \{#perform} on all children of the current node.
347
- #
348
- # @param environment [Sass::Environment] The lexical environment containing
349
- # variable and mixin values
350
- # @return [Array<Tree::Node>] The resulting static nodes
351
- def perform_children(environment)
352
- children.map {|c| c.perform(environment)}.flatten
353
- end
354
-
355
- # Replaces SassScript in a chunk of text
356
- # with the resulting value.
357
- #
358
- # @param text [Array<String, Sass::Script::Node>] The text to interpolate
359
- # @param environment [Sass::Environment] The lexical environment containing
360
- # variable and mixin values
361
- # @return [String] The interpolated text
362
- def run_interp(text, environment)
363
- text.map do |r|
364
- next r if r.is_a?(String)
365
- val = r.perform(environment)
366
- # Interpolated strings should never render with quotes
367
- next val.value if val.is_a?(Sass::Script::String)
368
- val.to_s
369
- end.join.strip
370
- end
371
-
372
223
  # @see Sass::Shared.balance
373
224
  # @raise [Sass::SyntaxError] if the brackets aren't balanced
374
225
  def balance(*args)
@@ -396,94 +247,6 @@ module Sass
396
247
  "Import directives may only be used at the root of a document."
397
248
  end
398
249
  end
399
-
400
- # Converts a node to Sass or SCSS code that will generate it.
401
- #
402
- # This method is called by the default \{#to\_sass} and \{#to\_scss} methods,
403
- # so that the same code can be used for both with minor variations.
404
- #
405
- # @param tabs [Fixnum] The amount of tabulation to use for the SCSS code
406
- # @param opts [{Symbol => Object}] An options hash (see {Sass::CSS#initialize})
407
- # @param fmt [Symbol] `:sass` or `:scss`
408
- # @return [String] The Sass or SCSS code corresponding to the node
409
- def to_src(tabs, opts, fmt)
410
- Sass::Util.abstract(self)
411
- end
412
-
413
- # Converts the children of this node to a Sass or SCSS string.
414
- # This will return the trailing newline for the previous line,
415
- # including brackets if this is SCSS.
416
- #
417
- # @param tabs [Fixnum] The amount of tabulation to use for the Sass code
418
- # @param opts [{Symbol => Object}] An options hash (see {Sass::CSS#initialize})
419
- # @param fmt [Symbol] `:sass` or `:scss`
420
- # @return [String] The Sass or SCSS code corresponding to the children
421
- def children_to_src(tabs, opts, fmt)
422
- return fmt == :sass ? "\n" : " {}\n" if children.empty?
423
-
424
- (fmt == :sass ? "\n" : " {\n") +
425
- children.map {|c| c.send("to_#{fmt}", tabs + 1, opts)}.join.rstrip +
426
- (fmt == :sass ? "\n" : " }\n")
427
- end
428
-
429
- # Converts a selector to a Sass or SCSS string.
430
- #
431
- # @param sel [Array<String, Sass::Script::Node>] The selector to convert
432
- # @param tabs [Fixnum] The indentation of the selector
433
- # @param opts [{Symbol => Object}] An options hash (see {Sass::CSS#initialize})
434
- # @param fmt [Symbol] `:sass` or `:scss`
435
- # @return [String] The Sass or SCSS code corresponding to the selector
436
- def selector_to_src(sel, tabs, opts, fmt)
437
- fmt == :sass ? selector_to_sass(sel, opts) : selector_to_scss(sel, tabs, opts)
438
- end
439
-
440
- # Converts a selector to a Sass string.
441
- #
442
- # @param sel [Array<String, Sass::Script::Node>] The selector to convert
443
- # @param opts [{Symbol => Object}] An options hash (see {Sass::CSS#initialize})
444
- # @return [String] The Sass code corresponding to the selector
445
- def selector_to_sass(sel, opts)
446
- sel.map do |r|
447
- if r.is_a?(String)
448
- r.gsub(/(,[ \t]*)?\n\s*/) {$1 ? $1 + "\n" : " "}
449
- else
450
- "\#{#{r.to_sass(opts)}}"
451
- end
452
- end.join
453
- end
454
-
455
- # Converts a selector to a SCSS string.
456
- #
457
- # @param sel [Array<String, Sass::Script::Node>] The selector to convert
458
- # @param tabs [Fixnum] The indentation of the selector
459
- # @param opts [{Symbol => Object}] An options hash (see {Sass::CSS#initialize})
460
- # @return [String] The SCSS code corresponding to the selector
461
- def selector_to_scss(sel, tabs, opts)
462
- sel.map {|r| r.is_a?(String) ? r : "\#{#{r.to_sass(opts)}}"}.
463
- join.gsub(/^[ \t]*/, ' ' * tabs)
464
- end
465
-
466
- # Convert any underscores in a string into hyphens,
467
- # but only if the `:dasherize` option is set.
468
- #
469
- # @param s [String] The string to convert
470
- # @param opts [{Symbol => Object}] The options hash
471
- # @return [String] The converted string
472
- def dasherize(s, opts)
473
- if opts[:dasherize]
474
- s.gsub('_', '-')
475
- else
476
- s
477
- end
478
- end
479
-
480
- # Returns a semicolon if this is SCSS, or an empty string if this is Sass.
481
- #
482
- # @param fmt [Symbol] `:sass` or `:scss`
483
- # @return [String] A semicolon or the empty string
484
- def semi(fmt)
485
- fmt == :sass ? "" : ";"
486
- end
487
250
  end
488
251
  end
489
252
  end