less_to_sass 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE.txt +21 -0
- data/README.md +70 -0
- data/bin/less2sass +12 -0
- data/bin/sass2less +12 -0
- data/lib/less2sass/constants.rb +5 -0
- data/lib/less2sass/error.rb +100 -0
- data/lib/less2sass/exec/base.rb +83 -0
- data/lib/less2sass/exec/conversion.rb +102 -0
- data/lib/less2sass/exec.rb +2 -0
- data/lib/less2sass/js/less_parser.js +48 -0
- data/lib/less2sass/less/ast_handler.rb +33 -0
- data/lib/less2sass/less/environment.rb +212 -0
- data/lib/less2sass/less/parser.rb +131 -0
- data/lib/less2sass/less/tree/alpha_node.rb +9 -0
- data/lib/less2sass/less/tree/anonymous_node.rb +43 -0
- data/lib/less2sass/less/tree/assignment_node.rb +10 -0
- data/lib/less2sass/less/tree/attribute_node.rb +11 -0
- data/lib/less2sass/less/tree/call_node.rb +65 -0
- data/lib/less2sass/less/tree/color_node.rb +27 -0
- data/lib/less2sass/less/tree/combinator_node.rb +18 -0
- data/lib/less2sass/less/tree/comment_node.rb +58 -0
- data/lib/less2sass/less/tree/condition_node.rb +13 -0
- data/lib/less2sass/less/tree/detached_ruleset_node.rb +10 -0
- data/lib/less2sass/less/tree/dimension_node.rb +26 -0
- data/lib/less2sass/less/tree/directive_node.rb +40 -0
- data/lib/less2sass/less/tree/element_node.rb +32 -0
- data/lib/less2sass/less/tree/expression_node.rb +73 -0
- data/lib/less2sass/less/tree/extend_node.rb +14 -0
- data/lib/less2sass/less/tree/import_node.rb +14 -0
- data/lib/less2sass/less/tree/keyword_node.rb +49 -0
- data/lib/less2sass/less/tree/media_node.rb +12 -0
- data/lib/less2sass/less/tree/mixin_call_node.rb +13 -0
- data/lib/less2sass/less/tree/mixin_definition_node.rb +24 -0
- data/lib/less2sass/less/tree/negative_node.rb +9 -0
- data/lib/less2sass/less/tree/node.rb +212 -0
- data/lib/less2sass/less/tree/operation_node.rb +63 -0
- data/lib/less2sass/less/tree/paren_node.rb +9 -0
- data/lib/less2sass/less/tree/quoted_node.rb +64 -0
- data/lib/less2sass/less/tree/rule_node.rb +119 -0
- data/lib/less2sass/less/tree/ruleset_call_node.rb +9 -0
- data/lib/less2sass/less/tree/ruleset_node.rb +82 -0
- data/lib/less2sass/less/tree/selector_node.rb +27 -0
- data/lib/less2sass/less/tree/unicode_descriptor_node.rb +9 -0
- data/lib/less2sass/less/tree/unit_node.rb +17 -0
- data/lib/less2sass/less/tree/url_node.rb +22 -0
- data/lib/less2sass/less/tree/value_node.rb +53 -0
- data/lib/less2sass/less/tree/variable_node.rb +43 -0
- data/lib/less2sass/less/tree.rb +34 -0
- data/lib/less2sass/less.rb +2 -0
- data/lib/less2sass/sass/ast_handler.rb +57 -0
- data/lib/less2sass/sass/parser.rb +20 -0
- data/lib/less2sass/sass.rb +2 -0
- data/lib/less2sass/util.rb +36 -0
- data/lib/less2sass.rb +9 -0
- metadata +163 -0
@@ -0,0 +1,32 @@
|
|
1
|
+
module Less2Sass
|
2
|
+
module Less
|
3
|
+
module Tree
|
4
|
+
# Represents the elements of a {SelectorNode}.
|
5
|
+
# These elements are usually separated by a
|
6
|
+
# {CombinatorNode}.
|
7
|
+
#
|
8
|
+
# No equivalent in Sass.
|
9
|
+
class ElementNode < Node
|
10
|
+
# @return [Tree::CombinatorNode]
|
11
|
+
attr_accessor :combinator
|
12
|
+
# @return [String]
|
13
|
+
attr_accessor :value
|
14
|
+
# @return [Integer]
|
15
|
+
attr_accessor :index
|
16
|
+
# @return [Hash]
|
17
|
+
attr_accessor :currentFileInfo
|
18
|
+
|
19
|
+
# @see Node#to_sass
|
20
|
+
def to_sass
|
21
|
+
if @value.is_a?(VariableNode)
|
22
|
+
@value.to_sass
|
23
|
+
elsif @value.is_a?(String)
|
24
|
+
@combinator.to_s + @value
|
25
|
+
else
|
26
|
+
raise FeatureConversionError, self
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module Less2Sass
|
2
|
+
module Less
|
3
|
+
module Tree
|
4
|
+
# Represents the expression in the Less AST.
|
5
|
+
#
|
6
|
+
# Sass does not have an Expression node. It is usually
|
7
|
+
# represented as the `expr` member of the {::Sass::Tree::VariableNode},
|
8
|
+
# that represents a variable definition.
|
9
|
+
#
|
10
|
+
# The Sass equivalent is either {::Sass::Script::Value::Base}
|
11
|
+
# wrapped in {::Sass::Script::Tree::Literal} or {::Sass::Tree::Node}.
|
12
|
+
class ExpressionNode < Node
|
13
|
+
attr_accessor :value
|
14
|
+
|
15
|
+
# @return [::Sass::Script::Tree::Literal, ::Sass::Script::Tree::ListLiteral, ::Sass::Tree::Node]
|
16
|
+
# @see Node#to_sass
|
17
|
+
def to_sass
|
18
|
+
if @value.is_a?(Array)
|
19
|
+
# TODO: document solution of: method to_sass is invoked on "to right":String, deal with it
|
20
|
+
if is_multiword_keyword?
|
21
|
+
multiword_keyword_argument
|
22
|
+
elsif should_be_literal?
|
23
|
+
@value.inject([]) { |value, elem| value << elem.to_s }.join(' ')
|
24
|
+
else
|
25
|
+
elements = @value.inject([]) do |value, elem|
|
26
|
+
node = elem.to_sass
|
27
|
+
node = node(::Sass::Script::Tree::Literal.new(node), line) if node.is_a?(::Sass::Script::Value::Base)
|
28
|
+
value << node
|
29
|
+
end
|
30
|
+
node(::Sass::Script::Tree::ListLiteral.new(elements, :space), line)
|
31
|
+
end
|
32
|
+
else
|
33
|
+
value = @value.to_sass
|
34
|
+
return value unless value.is_a?(::Sass::Script::Value::Base)
|
35
|
+
node(::Sass::Script::Tree::Literal.new(value), line)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
LITERAL_PROPERTIES = %w(font transition).freeze
|
42
|
+
|
43
|
+
# @todo: should be checked once more
|
44
|
+
def is_multiword_keyword?
|
45
|
+
@value.select { |elem| !elem.is_a?(KeywordNode) }.empty?
|
46
|
+
end
|
47
|
+
|
48
|
+
# Checks, whether the expression contains a {VariableNode}.
|
49
|
+
# Some properties in Less store their values as string literals
|
50
|
+
# instead of list literals.
|
51
|
+
#
|
52
|
+
# @return [Boolean] true if the expression should be converted
|
53
|
+
# to {::Sass::Script::Tree::Literal}
|
54
|
+
def should_be_literal?
|
55
|
+
grandparent = @parent.parent
|
56
|
+
return false unless grandparent.is_a?(RuleNode)
|
57
|
+
LITERAL_PROPERTIES.include?(grandparent.name.value) && !contains_variables?
|
58
|
+
end
|
59
|
+
|
60
|
+
# Creates a {::Sass::Script::Tree::ListLiteral} out of
|
61
|
+
# multiple keywords - usually referencing a complex CSS keyword.
|
62
|
+
#
|
63
|
+
# Example (`to right` is an example of multiword keyword):
|
64
|
+
# `list-style-image: linear-gradient(to right, rgba(255,0,0,0), rgba(255,0,0,1));`
|
65
|
+
#
|
66
|
+
def multiword_keyword_argument
|
67
|
+
keywords = @value.inject([]) { |value, elem| value << elem.to_sass }
|
68
|
+
node(::Sass::Script::Tree::ListLiteral.new(keywords, :space), line)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Less2Sass
|
2
|
+
module Less
|
3
|
+
module Tree
|
4
|
+
class ExtendNode < Node
|
5
|
+
attr_accessor :selector
|
6
|
+
attr_accessor :option
|
7
|
+
attr_accessor :index
|
8
|
+
attr_accessor :object_id
|
9
|
+
attr_accessor :parent_ids
|
10
|
+
attr_accessor :currentFileInfo
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Less2Sass
|
2
|
+
module Less
|
3
|
+
module Tree
|
4
|
+
# Represents the CSS property names and
|
5
|
+
# a little bit more.
|
6
|
+
#
|
7
|
+
# It can represent the name of a CSS rule,
|
8
|
+
# or it can be a part of a variable definition's
|
9
|
+
# value.
|
10
|
+
#
|
11
|
+
# In the latter case its Sass equivalents are:
|
12
|
+
# - {::Sass::Script::Value::Bool}
|
13
|
+
# - {::Sass::Script::Value::Null}
|
14
|
+
class KeywordNode < Node
|
15
|
+
attr_accessor :value
|
16
|
+
|
17
|
+
def to_s
|
18
|
+
@value.to_s
|
19
|
+
end
|
20
|
+
|
21
|
+
def empty?
|
22
|
+
@value.empty?
|
23
|
+
end
|
24
|
+
|
25
|
+
# Returns a SassScript Value node.
|
26
|
+
#
|
27
|
+
# Usually will be called in case of a variable
|
28
|
+
# definition and its parent node would be a
|
29
|
+
# {ExpressionNode}, which would wrap it up into a
|
30
|
+
# {::Sass::Script::Tree::Literal}.
|
31
|
+
#
|
32
|
+
# @raise FeatureConversionError if this node's value is not expected.
|
33
|
+
# @return [::Sass::Script::Value::Base]
|
34
|
+
# @see Node#to_sass
|
35
|
+
def to_sass
|
36
|
+
case @value
|
37
|
+
when 'true' then ::Sass::Script::Value::Bool.new(true)
|
38
|
+
when 'false' then ::Sass::Script::Value::Bool.new(false)
|
39
|
+
when 'null' then ::Sass::Script::Value::Null.new
|
40
|
+
else
|
41
|
+
raise FeatureConversionError, self unless @value.respond_to?(:to_s)
|
42
|
+
string = ::Sass::Script::Value::String.new(@value.to_s)
|
43
|
+
node(::Sass::Script::Tree::Literal.new(string), line)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Less2Sass
|
2
|
+
module Less
|
3
|
+
module Tree
|
4
|
+
class MixinDefinitionNode < Node
|
5
|
+
attr_accessor :name
|
6
|
+
attr_accessor :selectors
|
7
|
+
attr_accessor :params
|
8
|
+
attr_accessor :condition
|
9
|
+
attr_accessor :variadic
|
10
|
+
attr_accessor :arity
|
11
|
+
attr_accessor :rules
|
12
|
+
attr_accessor :_lookups
|
13
|
+
attr_accessor :required
|
14
|
+
attr_accessor :optionalParameters
|
15
|
+
attr_accessor :frames
|
16
|
+
|
17
|
+
# @see Node#creates_environment?
|
18
|
+
def creates_environment?
|
19
|
+
true
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,212 @@
|
|
1
|
+
require 'less2sass/less/environment'
|
2
|
+
|
3
|
+
module Less2Sass
|
4
|
+
module Less
|
5
|
+
module Tree
|
6
|
+
# The base node class of the Less AST.
|
7
|
+
class Node
|
8
|
+
include Enumerable
|
9
|
+
|
10
|
+
# The parent node of this node.
|
11
|
+
#
|
12
|
+
# @return [Less2Sass::Less::Tree::Node]
|
13
|
+
attr_accessor :parent
|
14
|
+
|
15
|
+
# Whether or not this node has parent node.
|
16
|
+
#
|
17
|
+
# @return [Boolean]
|
18
|
+
attr_reader :has_parent
|
19
|
+
|
20
|
+
# The child nodes of this node.
|
21
|
+
#
|
22
|
+
# @return [Array<Less2Sass::Less::Tree::Node>]
|
23
|
+
attr_accessor :children
|
24
|
+
|
25
|
+
# Whether or not this node has child nodes.
|
26
|
+
#
|
27
|
+
# @return [Boolean]
|
28
|
+
attr_reader :has_children
|
29
|
+
|
30
|
+
# Sets the line number of the node
|
31
|
+
#
|
32
|
+
# @return [Void]
|
33
|
+
attr_writer :line
|
34
|
+
|
35
|
+
# This member gets set if the node's children contain
|
36
|
+
# referenced {VariableNode}s.
|
37
|
+
#
|
38
|
+
# @return [Array<String>] referenced variable names
|
39
|
+
attr_accessor :ref_vars
|
40
|
+
|
41
|
+
# The environment, where the nodes sits lexically.
|
42
|
+
# TODO: Consider to set a reference to the lexical scope (the environment) of the node.
|
43
|
+
# @return [Less2Sass::Less::Environment]
|
44
|
+
# attr_reader :env
|
45
|
+
|
46
|
+
# The current line number the conversion process is at
|
47
|
+
@@lines = 0
|
48
|
+
|
49
|
+
def initialize(parent)
|
50
|
+
@children = []
|
51
|
+
@parent = parent
|
52
|
+
@creates_new_line = false
|
53
|
+
end
|
54
|
+
|
55
|
+
# @private
|
56
|
+
def parent=(parent)
|
57
|
+
@has_parent ||= !parent.nil?
|
58
|
+
@parent = parent
|
59
|
+
end
|
60
|
+
|
61
|
+
# @private
|
62
|
+
def children=(children)
|
63
|
+
@has_children ||= !children.empty?
|
64
|
+
@children = children
|
65
|
+
end
|
66
|
+
|
67
|
+
# @private
|
68
|
+
def ref_vars
|
69
|
+
@ref_vars || get_referenced_variable_names
|
70
|
+
end
|
71
|
+
|
72
|
+
# Tells, whether the node creates a new context
|
73
|
+
# or variable environment.
|
74
|
+
#
|
75
|
+
# @return [Boolean]
|
76
|
+
def creates_context?
|
77
|
+
false
|
78
|
+
end
|
79
|
+
|
80
|
+
# Appends a child to the node.
|
81
|
+
#
|
82
|
+
# @param [Less2Sass::Less::Tree::Node, Array<Less2Sass::Less::Tree::Node>] child
|
83
|
+
# The child node or nodes
|
84
|
+
def <<(child)
|
85
|
+
return if child.nil?
|
86
|
+
if child.is_a?(Array)
|
87
|
+
child.each { |c| self << c }
|
88
|
+
else
|
89
|
+
@has_children = true
|
90
|
+
child.parent = self
|
91
|
+
@children << child
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
# Compares this node and another object (only other {Less2Sass::Less::Tree::Node}s will be equal).
|
96
|
+
#
|
97
|
+
# @param [Object] other The object to compare with
|
98
|
+
# @return [Boolean] Whether or not this node and the other object
|
99
|
+
# are the same
|
100
|
+
def ==(other)
|
101
|
+
self.class == other.class && other.children == children
|
102
|
+
end
|
103
|
+
|
104
|
+
# Iterates through each node in the tree rooted at this node
|
105
|
+
# in a pre-order walk.
|
106
|
+
#
|
107
|
+
# @yield node
|
108
|
+
# @yieldparam node [Less2Sass::Less::Tree::Node] a node in the tree
|
109
|
+
def each
|
110
|
+
yield self
|
111
|
+
children.each { |c| c.each { |n| yield n } }
|
112
|
+
end
|
113
|
+
|
114
|
+
# The base implementation of transform.
|
115
|
+
#
|
116
|
+
# Transforms the tree by its traversal. Each respective node type
|
117
|
+
# should implement the specific transformation and calling `#super`.
|
118
|
+
# The position, where `#super` is called determines the walking order.
|
119
|
+
# The standard should be post-order walk - transforming the child nodes
|
120
|
+
# first and self as last.
|
121
|
+
#
|
122
|
+
# Should be overridden by subclasses adding specific implementation.
|
123
|
+
#
|
124
|
+
# @param [Less2Sass::Less::Environment] env parent environment
|
125
|
+
# @return [Void]
|
126
|
+
def transform(env = nil)
|
127
|
+
# TODO: Consider to set a reference to the lexical scope (the environment) of the node.
|
128
|
+
# @env = env
|
129
|
+
@children.each { |c| c.transform(env) }
|
130
|
+
end
|
131
|
+
|
132
|
+
# Returns the line number and sets the class level
|
133
|
+
# current line number based on the passed option.
|
134
|
+
#
|
135
|
+
# @param [Symbol] opt the line number option
|
136
|
+
# @option opt [Symbol] :new tells the method to
|
137
|
+
# return the next line and increments @@lines
|
138
|
+
# @option opt [Symbol] :current tells the method to
|
139
|
+
# return the current line the converter is "processing"
|
140
|
+
#
|
141
|
+
# @return [Fixnum] the line number based on the given option
|
142
|
+
def line(opt = :current)
|
143
|
+
case opt
|
144
|
+
when :current
|
145
|
+
@@lines
|
146
|
+
when :new
|
147
|
+
@@lines = @@lines.next
|
148
|
+
else
|
149
|
+
raise StandardError, "Option can't be other than :current or :new"
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
# Converts this node to the equivalent Sass node
|
154
|
+
#
|
155
|
+
# Should be overwritten by subclasses.
|
156
|
+
# All subclasses should also set the line number
|
157
|
+
# of the resulting Sass node.
|
158
|
+
#
|
159
|
+
# @raise NotImplementedError if called on the base node object
|
160
|
+
# or subclass method not implemented, yet.
|
161
|
+
def to_sass
|
162
|
+
raise NotImplementedError
|
163
|
+
end
|
164
|
+
|
165
|
+
# Loops through the children nodes and
|
166
|
+
# searches for variable occurrences.
|
167
|
+
#
|
168
|
+
# @return [Array<String>] list of variable names
|
169
|
+
# contained in the value's expressions
|
170
|
+
# @note Use on {Less2Sass::Less::Tree::RuleNode}s. It's a good practice
|
171
|
+
# to check first if it's a variable definition.
|
172
|
+
# See (Less2Sass::Less::Tree::RuleNode#is_variable_definition?)
|
173
|
+
def get_referenced_variable_names
|
174
|
+
if is_a?(VariableNode)
|
175
|
+
[@name]
|
176
|
+
else
|
177
|
+
@children.inject([]) { |vars, c| vars + c.get_referenced_variable_names }
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
# Checks, whether a variable is referenced in the scope of the node.
|
182
|
+
#
|
183
|
+
# @return [Boolean]
|
184
|
+
def contains_variables?
|
185
|
+
variables = nil
|
186
|
+
each do |child|
|
187
|
+
if child.is_a?(VariableNode)
|
188
|
+
variables = true
|
189
|
+
break
|
190
|
+
end
|
191
|
+
end
|
192
|
+
variables
|
193
|
+
end
|
194
|
+
|
195
|
+
protected
|
196
|
+
|
197
|
+
# Sets up a node with the mandatory options (line, options).
|
198
|
+
#
|
199
|
+
# @param [::Sass::Tree::Node, ::Sass::Script::Tree::Node] node
|
200
|
+
# the node to be set up
|
201
|
+
# @param [Fixnum] line the line number, where the node sits lexically
|
202
|
+
# @param [Hash] options the options to pass to the node
|
203
|
+
# @return [::Sass::Tree::Node, ::Sass::Script::Tree::Node] the set up node
|
204
|
+
def node(node, line, options = { :style => :nested })
|
205
|
+
node.line = line if line
|
206
|
+
node.options = options if node.class.method_defined?(:options=)
|
207
|
+
node
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module Less2Sass
|
2
|
+
module Less
|
3
|
+
module Tree
|
4
|
+
# Node representing the operation with 2 operands.
|
5
|
+
#
|
6
|
+
# Converts to {::Sass::Script::Tree::Operation}.
|
7
|
+
class OperationNode < Node
|
8
|
+
attr_accessor :op
|
9
|
+
attr_accessor :operands
|
10
|
+
attr_accessor :isSpaced
|
11
|
+
|
12
|
+
def to_s
|
13
|
+
@operands[0].to_s + @op + @operands[1].to_s
|
14
|
+
end
|
15
|
+
|
16
|
+
# @see Node#to_sass
|
17
|
+
def to_sass
|
18
|
+
node(::Sass::Script::Tree::Operation.new(@operands[0].to_sass, @operands[1].to_sass, sass_operator), line)
|
19
|
+
end
|
20
|
+
|
21
|
+
# A hash from operator strings to the corresponding token types.
|
22
|
+
#
|
23
|
+
# Copied from Sass' lexer
|
24
|
+
# @see https://github.com/sass/sass/blob/stable/lib/sass/script/lexer.rb#L44-L69
|
25
|
+
OPERATORS = {
|
26
|
+
'+' => :plus,
|
27
|
+
'-' => :minus,
|
28
|
+
'*' => :times,
|
29
|
+
'/' => :div,
|
30
|
+
'%' => :mod,
|
31
|
+
'=' => :single_eq,
|
32
|
+
':' => :colon,
|
33
|
+
'(' => :lparen,
|
34
|
+
')' => :rparen,
|
35
|
+
',' => :comma,
|
36
|
+
'and' => :and,
|
37
|
+
'or' => :or,
|
38
|
+
'not' => :not,
|
39
|
+
'==' => :eq,
|
40
|
+
'!=' => :neq,
|
41
|
+
'>=' => :gte,
|
42
|
+
'<=' => :lte,
|
43
|
+
'>' => :gt,
|
44
|
+
'<' => :lt,
|
45
|
+
'#{' => :begin_interpolation,
|
46
|
+
'}' => :end_interpolation,
|
47
|
+
';' => :semicolon,
|
48
|
+
'{' => :lcurly,
|
49
|
+
'...' => :splat
|
50
|
+
}.freeze
|
51
|
+
|
52
|
+
# Returns the sass operator symbol, that is used internally.
|
53
|
+
#
|
54
|
+
# @param [String] op the operator to look for
|
55
|
+
# @return [Symbol] the operator symbol
|
56
|
+
def sass_operator(op = @op)
|
57
|
+
raise Less2Sass::OperatorConversionError, op unless OPERATORS[op]
|
58
|
+
OPERATORS[op]
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module Less2Sass
|
2
|
+
module Less
|
3
|
+
module Tree
|
4
|
+
# Represents a single or double-quoted string in Less.
|
5
|
+
#
|
6
|
+
# The Sass equivalent is a {::Sass::Script::Value::String}
|
7
|
+
# wrapped in {::Sass::Script::Tree::Literal}.
|
8
|
+
class QuotedNode < Node
|
9
|
+
attr_accessor :escaped
|
10
|
+
attr_accessor :value
|
11
|
+
attr_accessor :quote
|
12
|
+
attr_accessor :index
|
13
|
+
attr_accessor :currentFileInfo
|
14
|
+
|
15
|
+
# Returns the Sass equivalent for a quoted string.
|
16
|
+
#
|
17
|
+
# @return [::Sass::Script::Tree::Literal] simple string literal
|
18
|
+
# @return [::Sass::Script::Tree::StringInterpolation] interpolation node,
|
19
|
+
# if the string contains interpolations
|
20
|
+
# @see Node#to_sass
|
21
|
+
def to_sass
|
22
|
+
if string_interpolation?
|
23
|
+
interpolation_node(@value)
|
24
|
+
else
|
25
|
+
node(::Sass::Script::Tree::Literal.new(::Sass::Script::Value::String.new(@value, :string)), line)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# Returns the string's raw value without passing the type of quote.
|
30
|
+
#
|
31
|
+
# Sass has its own standards regarding the quotes, it should be in
|
32
|
+
# Sass' competences to choose what type of quote to use.
|
33
|
+
def to_s
|
34
|
+
@value
|
35
|
+
end
|
36
|
+
|
37
|
+
# Checks, whether the quoted string contains an interpolation.
|
38
|
+
#
|
39
|
+
# @return [Boolean]
|
40
|
+
def string_interpolation?(value = @value)
|
41
|
+
!value.index(INTERPOLATION).nil?
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
INTERPOLATION = /(@\{[\w_-]*\})/
|
47
|
+
VARIABLE_NAME = /@\{([\w_-]*)\}/
|
48
|
+
|
49
|
+
# Creates a {::Sass::Script::Tree::StringInterpolation} node.
|
50
|
+
#
|
51
|
+
# @param [String] value the string containing interpolation(s)
|
52
|
+
# @return [::Sass::Script::Tree::StringInterpolation] the interpolation node
|
53
|
+
def interpolation_node(value)
|
54
|
+
parts = value.split(INTERPOLATION, 2) # Must be split maximally into 3 parts
|
55
|
+
parts[2] = '' if parts.length == 2 # Always must have 3 parts
|
56
|
+
before = node(::Sass::Script::Tree::Literal.new(::Sass::Script::Value::String.new(parts[0], :string)), line)
|
57
|
+
mid = node(::Sass::Script::Tree::Variable.new(parts[1].match(VARIABLE_NAME)[1]), line)
|
58
|
+
after = string_interpolation?(parts[2]) ? interpolation_node(parts[2]) : node(::Sass::Script::Tree::Literal.new(::Sass::Script::Value::String.new(parts[2], :string)), line)
|
59
|
+
node(::Sass::Script::Tree::StringInterpolation.new(before, mid, after), line)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|