less_to_sass 0.1.0
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.
- 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,119 @@
|
|
1
|
+
module Less2Sass
|
2
|
+
module Less
|
3
|
+
module Tree
|
4
|
+
# A RuleNode in Less can be a CSS rule, or a
|
5
|
+
# variable definition.
|
6
|
+
#
|
7
|
+
# Examples:
|
8
|
+
# - color: @var;
|
9
|
+
# - @var: 50px;
|
10
|
+
#
|
11
|
+
# The Sass equivalent is {::Sass::Tree::VariableNode}
|
12
|
+
# or {::Sass::Tree::RuleNode}.
|
13
|
+
class RuleNode < Node
|
14
|
+
attr_accessor :name
|
15
|
+
attr_accessor :value
|
16
|
+
attr_accessor :important
|
17
|
+
attr_accessor :merge
|
18
|
+
attr_accessor :index
|
19
|
+
attr_accessor :currentFileInfo
|
20
|
+
attr_accessor :inline
|
21
|
+
attr_accessor :variable
|
22
|
+
|
23
|
+
attr_accessor :guarded
|
24
|
+
attr_accessor :global
|
25
|
+
|
26
|
+
# @see VariableNode#sass_name
|
27
|
+
def sass_name
|
28
|
+
@name[1..-1] if @name
|
29
|
+
end
|
30
|
+
|
31
|
+
# Returns whether the node is a variable definition.
|
32
|
+
#
|
33
|
+
# @return [Boolean]
|
34
|
+
def is_variable_definition?
|
35
|
+
@variable
|
36
|
+
end
|
37
|
+
|
38
|
+
# Checks, if the given variable is referenced by the variable's definition
|
39
|
+
#
|
40
|
+
# @param [Less2Sass::Less::Tree:RuleNode] variable the variable
|
41
|
+
# @param [String] variable the variable's name
|
42
|
+
# @return [Boolean]
|
43
|
+
def references?(variable)
|
44
|
+
if variable.is_a?(String)
|
45
|
+
@ref_vars.include?(variable)
|
46
|
+
else
|
47
|
+
@ref_vars.include?(variable.name)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Converts this node to {::Sass::Tree::VariableNode}, if
|
52
|
+
# it's a variable definition. Otherwise it must be a CSS
|
53
|
+
# property declaration and gets converted to {::Sass::Tree::PropNode}.
|
54
|
+
#
|
55
|
+
# The 3rd param of `::Sass::Tree::PropNode` refers to the CSS
|
56
|
+
# syntax to be outputted. Its value can be:
|
57
|
+
# - `:new` using `a: b`-style syntax
|
58
|
+
# - `:old` using `:a b`-style syntax
|
59
|
+
#
|
60
|
+
# For the sake of simplicity, we'll use the new syntax only.
|
61
|
+
# Later could be set in cli arguments as option.
|
62
|
+
#
|
63
|
+
# @note Always put on a new line.
|
64
|
+
# @return [::Sass::Tree::VariableNode, ::Sass::Tree::PropNode]
|
65
|
+
# @see Node#to_sass
|
66
|
+
def to_sass
|
67
|
+
node ||=
|
68
|
+
begin
|
69
|
+
if is_variable_definition?
|
70
|
+
::Sass::Tree::VariableNode.new(
|
71
|
+
sass_name, @value.to_sass, @guarded, @global
|
72
|
+
)
|
73
|
+
else
|
74
|
+
# TODO: Don't forget about the `#{}`
|
75
|
+
::Sass::Tree::PropNode.new(
|
76
|
+
process_property_name, @value.to_sass, :new
|
77
|
+
)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
node(node, line(:new))
|
81
|
+
end
|
82
|
+
|
83
|
+
private
|
84
|
+
|
85
|
+
# Creates the Sass representation of the property name.
|
86
|
+
#
|
87
|
+
# @return [Array<String, ::Sass::Script::Tree::Node>]
|
88
|
+
def process_property_name
|
89
|
+
return [create_name] unless @name.is_a?(Array)
|
90
|
+
@name.inject([]) do |name, part|
|
91
|
+
name << create_name(part)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
# Returns a part of the property name.
|
96
|
+
#
|
97
|
+
# @param [VariableNode, #to_s] name part of the property name
|
98
|
+
# @return [String, ::Sass::Script::Tree::Node] converted
|
99
|
+
# part of property name
|
100
|
+
def create_name(name = @name)
|
101
|
+
if name.is_a?(VariableNode)
|
102
|
+
create_interpolation(name)
|
103
|
+
else
|
104
|
+
name.to_s
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
# Creates a Sass interpolation node
|
109
|
+
#
|
110
|
+
# @param [VariableNode] variable_node the variable node to convert
|
111
|
+
# @return [::Sass::Script::Tree::Interpolation] a Sass Interpolation node
|
112
|
+
def create_interpolation(variable_node)
|
113
|
+
var = ::Sass::Script::Tree::Variable.new(variable_node.name[1..-1])
|
114
|
+
node(::Sass::Script::Tree::Interpolation.new(nil, var, nil, false, false), line)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
module Less2Sass
|
2
|
+
module Less
|
3
|
+
module Tree
|
4
|
+
# The Ruleset node is the root node of every Less AST.
|
5
|
+
# It also means a block of selector and its inner rules.
|
6
|
+
#
|
7
|
+
# Its Sass equivalent is a {::Sass::Tree::RootNode}, or
|
8
|
+
# {::Sass::Tree::RuleNode}.
|
9
|
+
class RulesetNode < Node
|
10
|
+
attr_accessor :selectors, :rules, :_lookups,
|
11
|
+
:root, :firstRoot, :strictImports
|
12
|
+
|
13
|
+
def initialize(options = nil)
|
14
|
+
super
|
15
|
+
@options = options unless options.nil?
|
16
|
+
end
|
17
|
+
|
18
|
+
# @see Node#creates_context?
|
19
|
+
def creates_context?
|
20
|
+
true
|
21
|
+
end
|
22
|
+
|
23
|
+
# Transforms the ruleset node by reordering the child nodes.
|
24
|
+
#
|
25
|
+
# 1. Creates a new environment and puts the child
|
26
|
+
# nodes into it.
|
27
|
+
#
|
28
|
+
# 2. Further traverses the tree of nodes and transforms them, as well.
|
29
|
+
#
|
30
|
+
# 3. Saves the re-ordered rules and child nodes.
|
31
|
+
#
|
32
|
+
# @param (see Node#transform)
|
33
|
+
# @return [Void]
|
34
|
+
def transform(env = nil)
|
35
|
+
env = Less2Sass::Less::Environment.new(env)
|
36
|
+
env.set_environment(@children)
|
37
|
+
env.build
|
38
|
+
super(env)
|
39
|
+
@rules = env.get_ordered_child_nodes
|
40
|
+
@children = @rules
|
41
|
+
end
|
42
|
+
|
43
|
+
# Converts node to {::Sass::Tree::RootNode} if it's root.
|
44
|
+
# Otherwise it converts to {::Sass::Tree::RuleNode}.
|
45
|
+
#
|
46
|
+
# In case of root node, all the children nodes have to be
|
47
|
+
# converted. Otherwise rule nodes only.
|
48
|
+
#
|
49
|
+
# @note I both cases the node is placed on a new line.
|
50
|
+
# @return [::Sass::Tree::RootNode, ::Sass::Tree::RuleNode]
|
51
|
+
# @see Node#to_sass
|
52
|
+
def to_sass(options = nil)
|
53
|
+
if @root
|
54
|
+
node = node(::Sass::Engine.new('', options).to_tree, line(:new))
|
55
|
+
children = @children
|
56
|
+
else
|
57
|
+
node = node(::Sass::Tree::RuleNode.new(get_full_selector), line(:new))
|
58
|
+
children = @rules.is_a?(Array) ? @rules : [@rules]
|
59
|
+
end
|
60
|
+
children.each { |c| node << c.to_sass }
|
61
|
+
node
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
# Creates a list of selectors.
|
67
|
+
#
|
68
|
+
# @return [Array<String, Sass::Script::Tree::Node>] the list of selectors
|
69
|
+
def get_full_selector
|
70
|
+
raise UnknownError if @selectors.nil?
|
71
|
+
if @selectors.is_a?(Array)
|
72
|
+
# Creates a list of selectors {Array<String, Sass::Script::Tree::node>} separated by a comma
|
73
|
+
# and returns the list without the last, trailing comma
|
74
|
+
@selectors.inject([]) { |rule, selector| rule << [selector.to_sass, ','] }.flatten[0..-2]
|
75
|
+
else
|
76
|
+
[@selectors.to_sass].flatten
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Less2Sass
|
2
|
+
module Less
|
3
|
+
module Tree
|
4
|
+
# Represents the full selector of a given {RulesetNode}.
|
5
|
+
#
|
6
|
+
# No equivalent node is present in Sass, it's the `rule`
|
7
|
+
# member of {::Sass::Tree::PropNode}, instead.
|
8
|
+
class SelectorNode < Node
|
9
|
+
# @return [Array<Tree::ElementNode>]
|
10
|
+
attr_accessor :elements
|
11
|
+
attr_accessor :extendList
|
12
|
+
attr_accessor :condition
|
13
|
+
# @return [Hash]
|
14
|
+
attr_accessor :currentFileInfo
|
15
|
+
# @return [Boolean]
|
16
|
+
attr_accessor :evaldCondition
|
17
|
+
|
18
|
+
# see Node#to_sass
|
19
|
+
def to_sass
|
20
|
+
raise UnknownError if @elements.nil?
|
21
|
+
return @elements.to_sass unless @elements.is_a?(Array)
|
22
|
+
@elements.inject([]) { |selector, element| selector << element.to_sass }
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Less2Sass
|
2
|
+
module Less
|
3
|
+
module Tree
|
4
|
+
class UnitNode < Node
|
5
|
+
attr_accessor :numerator
|
6
|
+
attr_accessor :denominator
|
7
|
+
attr_accessor :backupUnit
|
8
|
+
|
9
|
+
def to_s
|
10
|
+
val = @numerator[0].to_s
|
11
|
+
val += @denominator[0] unless @denominator.nil? || @denominator.empty?
|
12
|
+
val
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Less2Sass
|
2
|
+
module Less
|
3
|
+
module Tree
|
4
|
+
# Represents the CSS `url` function call.
|
5
|
+
#
|
6
|
+
# The Sass equivalent is {::Sass::Script::Tree::Funcall}.
|
7
|
+
class UrlNode < Node
|
8
|
+
attr_accessor :value
|
9
|
+
attr_accessor :currentFileInfo
|
10
|
+
attr_accessor :index
|
11
|
+
attr_accessor :isEvald
|
12
|
+
|
13
|
+
# @return [::Sass::Script::Tree::Funcall]
|
14
|
+
# @see https://github.com/sass/sass/blob/stable/lib/sass/script/tree/funcall.rb#L42-46
|
15
|
+
# @see Node#to_sass
|
16
|
+
def to_sass
|
17
|
+
node(::Sass::Script::Tree::Funcall.new('url', [@value.to_sass], ::Sass::Util::NormalizedMap.new, nil, nil), line)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Less2Sass
|
2
|
+
module Less
|
3
|
+
module Tree
|
4
|
+
# Represents the value of any Less AST node.
|
5
|
+
#
|
6
|
+
# It has no individual representation in Sass,
|
7
|
+
# so it returns its value node's Sass representation,
|
8
|
+
# when {#to_sass} gets called.
|
9
|
+
#
|
10
|
+
# Sass equivalents:
|
11
|
+
# - {::Sass::Script::Tree::Literal} if part of property declaration
|
12
|
+
# - {::Sass::Script::Tree::ListLiteral} if part of variable definition
|
13
|
+
#
|
14
|
+
# @see Node
|
15
|
+
class ValueNode < Node
|
16
|
+
# @todo update Sass and check out a lately commit regarding the deprecated SassScript usage in CSS rules
|
17
|
+
# @see https://github.com/sass/sass/commit/b671122234d2d4df088a6c6d4c54b64d6997d255
|
18
|
+
|
19
|
+
# The ValueNode is not the final value of a variable
|
20
|
+
# or a property.
|
21
|
+
#
|
22
|
+
# @return [Node, Array<Node>]
|
23
|
+
attr_accessor :value
|
24
|
+
|
25
|
+
# This node's value is either a single expression,
|
26
|
+
# or an array of those. The array needs to be further
|
27
|
+
# processed.
|
28
|
+
#
|
29
|
+
# @return [::Sass::Script::Tree::Literal, ::Sass::Script::Tree::ListLiteral]
|
30
|
+
# @see Node#to_sass
|
31
|
+
def to_sass
|
32
|
+
if @value.is_a?(Array)
|
33
|
+
# TODO: don't forget about interpolation. What if one of the expressions is a variable?
|
34
|
+
if @parent.is_variable_definition? || contains_variables?
|
35
|
+
elements = @value.inject([]) { |elements, elem| elements << elem.to_sass }
|
36
|
+
node(::Sass::Script::Tree::ListLiteral.new(elements, :comma), line)
|
37
|
+
else
|
38
|
+
value = @value.inject([]) do |value, elem|
|
39
|
+
substring = elem.to_sass
|
40
|
+
# TODO: describe solution for '"Source Code Pro", Monaco, monospace'
|
41
|
+
substring = substring.value.value if substring.is_a?(::Sass::Script::Tree::Literal)
|
42
|
+
value << substring
|
43
|
+
end.join(', ')
|
44
|
+
node(::Sass::Script::Tree::Literal.new(::Sass::Script::Value::String.new(value)), line)
|
45
|
+
end
|
46
|
+
else
|
47
|
+
@value.to_sass
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Less2Sass
|
2
|
+
module Less
|
3
|
+
module Tree
|
4
|
+
# A node representing a variable.
|
5
|
+
# The Sass representation of it is {::Sass::Script::Tree:Variable}
|
6
|
+
class VariableNode < Node
|
7
|
+
# @return [String]
|
8
|
+
attr_accessor :name
|
9
|
+
# @return [Integer]
|
10
|
+
attr_accessor :index
|
11
|
+
# @return [Hash]
|
12
|
+
attr_accessor :currentFileInfo
|
13
|
+
|
14
|
+
# Returns the sass specific name property by
|
15
|
+
# removing the starting @.
|
16
|
+
#
|
17
|
+
# Example:
|
18
|
+
# node.sass_name => "var1"
|
19
|
+
#
|
20
|
+
# @return [String]
|
21
|
+
def sass_name
|
22
|
+
@name[1..-1] if @name
|
23
|
+
end
|
24
|
+
|
25
|
+
# Checks, whether the variable node is an interpolation
|
26
|
+
#
|
27
|
+
# @return [Boolean]
|
28
|
+
def interpolation?
|
29
|
+
return false unless [ElementNode, RuleNode].include?(@parent.class)
|
30
|
+
return !@parent.is_variable_definition? if @parent.is_a?(RuleNode)
|
31
|
+
true
|
32
|
+
end
|
33
|
+
|
34
|
+
# @see Node#to_sass
|
35
|
+
def to_sass
|
36
|
+
variable = node(::Sass::Script::Tree::Variable.new(sass_name), line)
|
37
|
+
variable = node(::Sass::Script::Tree::Interpolation.new(nil, variable, nil, false, false), line) if interpolation?
|
38
|
+
variable
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'less2sass/less/tree/node'
|
2
|
+
require 'less2sass/less/tree/alpha_node'
|
3
|
+
require 'less2sass/less/tree/anonymous_node'
|
4
|
+
require 'less2sass/less/tree/assignment_node'
|
5
|
+
require 'less2sass/less/tree/attribute_node'
|
6
|
+
require 'less2sass/less/tree/call_node'
|
7
|
+
require 'less2sass/less/tree/color_node'
|
8
|
+
require 'less2sass/less/tree/combinator_node'
|
9
|
+
require 'less2sass/less/tree/comment_node'
|
10
|
+
require 'less2sass/less/tree/condition_node'
|
11
|
+
require 'less2sass/less/tree/detached_ruleset_node'
|
12
|
+
require 'less2sass/less/tree/dimension_node'
|
13
|
+
require 'less2sass/less/tree/directive_node'
|
14
|
+
require 'less2sass/less/tree/element_node'
|
15
|
+
require 'less2sass/less/tree/expression_node'
|
16
|
+
require 'less2sass/less/tree/extend_node'
|
17
|
+
require 'less2sass/less/tree/import_node'
|
18
|
+
require 'less2sass/less/tree/keyword_node'
|
19
|
+
require 'less2sass/less/tree/media_node'
|
20
|
+
require 'less2sass/less/tree/mixin_call_node'
|
21
|
+
require 'less2sass/less/tree/mixin_definition_node'
|
22
|
+
require 'less2sass/less/tree/negative_node'
|
23
|
+
require 'less2sass/less/tree/operation_node'
|
24
|
+
require 'less2sass/less/tree/paren_node'
|
25
|
+
require 'less2sass/less/tree/quoted_node'
|
26
|
+
require 'less2sass/less/tree/rule_node'
|
27
|
+
require 'less2sass/less/tree/ruleset_call_node'
|
28
|
+
require 'less2sass/less/tree/ruleset_node'
|
29
|
+
require 'less2sass/less/tree/selector_node'
|
30
|
+
require 'less2sass/less/tree/unicode_descriptor_node'
|
31
|
+
require 'less2sass/less/tree/unit_node'
|
32
|
+
require 'less2sass/less/tree/url_node'
|
33
|
+
require 'less2sass/less/tree/value_node'
|
34
|
+
require 'less2sass/less/tree/variable_node'
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Less2Sass
|
2
|
+
module Sass
|
3
|
+
# Wrapped Sass AST
|
4
|
+
class ASTHandler
|
5
|
+
# Creates an empty Sass AST.
|
6
|
+
#
|
7
|
+
# @param [::Sass::Tree::Node] tree the Sass AST
|
8
|
+
def initialize(tree)
|
9
|
+
@tree = tree
|
10
|
+
end
|
11
|
+
|
12
|
+
# Appends child notes to the empty Sass AST.
|
13
|
+
#
|
14
|
+
# Note, that this should be called only once.
|
15
|
+
#
|
16
|
+
# @param [::Sass::Tree::Node] child the rest
|
17
|
+
# of the converted Less AST
|
18
|
+
def <<(child)
|
19
|
+
# TODO: check if child.is_a?(::Sass::Tree::Node) and raise some error, if not
|
20
|
+
@tree << child
|
21
|
+
self
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_css
|
25
|
+
@tree.render
|
26
|
+
end
|
27
|
+
|
28
|
+
# Outputs the transformed and converted AST
|
29
|
+
# in the form of Sass code.
|
30
|
+
#
|
31
|
+
# @todo method cannot handle import nodes, yet - single files only
|
32
|
+
#
|
33
|
+
# @param [String, IO] destination the base directory
|
34
|
+
# or an IO Stream where the converted projects
|
35
|
+
# should be outputted.
|
36
|
+
def code_gen(destination = nil)
|
37
|
+
code = @tree.to_scss
|
38
|
+
return code unless destination
|
39
|
+
if destination.is_a?(String)
|
40
|
+
open_file(destination, 'w') { |file| file.write(code) }
|
41
|
+
else
|
42
|
+
destination.write(code)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def open_file(filename, flag = 'r')
|
47
|
+
return if filename.nil?
|
48
|
+
return File.open(filename, flag) unless block_given?
|
49
|
+
yield File.open(filename, flag)
|
50
|
+
end
|
51
|
+
|
52
|
+
def to_yaml
|
53
|
+
@tree.to_yaml
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Less2Sass
|
2
|
+
module Sass
|
3
|
+
class Parser
|
4
|
+
def initialize(input)
|
5
|
+
@input = input
|
6
|
+
end
|
7
|
+
|
8
|
+
def parse
|
9
|
+
sass_file_content = File.read(@input)
|
10
|
+
sass_file_path = File.expand_path(@input)
|
11
|
+
tree = ::Sass::Engine.new(
|
12
|
+
sass_file_content,
|
13
|
+
:syntax => :scss, :filename => sass_file_path
|
14
|
+
).to_tree
|
15
|
+
::Sass::Tree::Visitors::CheckNesting.visit(tree)
|
16
|
+
::Sass::Tree::Visitors::Perform.visit(tree)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Less2Sass
|
2
|
+
module Util
|
3
|
+
extend self
|
4
|
+
|
5
|
+
# Returns a file's path relative to the Less2Sass root directory.
|
6
|
+
#
|
7
|
+
# @param file [String] The filename relative to the Less2Sass root
|
8
|
+
# @return [String] The filename relative to the the working directory
|
9
|
+
def scope(file)
|
10
|
+
File.join(Less2Sass::ROOT_DIR, file)
|
11
|
+
end
|
12
|
+
|
13
|
+
# Formats a multiline console input, so it can be passed as an argument
|
14
|
+
# to a console application.
|
15
|
+
#
|
16
|
+
# @return [String] properly formatted multiline argument
|
17
|
+
def read_stdin_as_multiline_arg
|
18
|
+
str = ''
|
19
|
+
puts 'Write your code below, so it can be converted for you.'
|
20
|
+
while line = gets
|
21
|
+
line["\n"] = "\\\n"
|
22
|
+
str << line
|
23
|
+
end
|
24
|
+
str
|
25
|
+
end
|
26
|
+
|
27
|
+
# Formats class names properly.
|
28
|
+
#
|
29
|
+
# @return [String] formatted class name
|
30
|
+
# @example formats dashed class name
|
31
|
+
# "anonymous_node".classify #=> "AnonymousNode"
|
32
|
+
def classify(str)
|
33
|
+
str.split('_').collect!(&:capitalize).join
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/lib/less2sass.rb
ADDED