nirvdrum-less 1.1.4
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/.gitignore +4 -0
- data/LICENSE +179 -0
- data/README.md +39 -0
- data/Rakefile +90 -0
- data/VERSION +1 -0
- data/bin/lessc +86 -0
- data/less.gemspec +205 -0
- data/lib/ext.rb +62 -0
- data/lib/less.rb +33 -0
- data/lib/less/command.rb +106 -0
- data/lib/less/engine.rb +54 -0
- data/lib/less/engine/builder.rb +8 -0
- data/lib/less/engine/grammar/common.tt +29 -0
- data/lib/less/engine/grammar/entity.tt +139 -0
- data/lib/less/engine/grammar/less.tt +271 -0
- data/lib/less/engine/nodes.rb +9 -0
- data/lib/less/engine/nodes/element.rb +186 -0
- data/lib/less/engine/nodes/entity.rb +79 -0
- data/lib/less/engine/nodes/function.rb +79 -0
- data/lib/less/engine/nodes/literal.rb +167 -0
- data/lib/less/engine/nodes/property.rb +156 -0
- data/lib/less/engine/nodes/ruleset.rb +12 -0
- data/lib/less/engine/nodes/selector.rb +39 -0
- data/lib/vendor/treetop/.gitignore +7 -0
- data/lib/vendor/treetop/LICENSE +19 -0
- data/lib/vendor/treetop/README +164 -0
- data/lib/vendor/treetop/Rakefile +19 -0
- data/lib/vendor/treetop/benchmark/seqpar.gnuplot +15 -0
- data/lib/vendor/treetop/benchmark/seqpar.treetop +16 -0
- data/lib/vendor/treetop/benchmark/seqpar_benchmark.rb +107 -0
- data/lib/vendor/treetop/bin/tt +28 -0
- data/lib/vendor/treetop/lib/treetop.rb +8 -0
- data/lib/vendor/treetop/lib/treetop/bootstrap_gen_1_metagrammar.rb +45 -0
- data/lib/vendor/treetop/lib/treetop/compiler.rb +6 -0
- data/lib/vendor/treetop/lib/treetop/compiler/grammar_compiler.rb +42 -0
- data/lib/vendor/treetop/lib/treetop/compiler/lexical_address_space.rb +17 -0
- data/lib/vendor/treetop/lib/treetop/compiler/metagrammar.rb +3097 -0
- data/lib/vendor/treetop/lib/treetop/compiler/metagrammar.treetop +408 -0
- data/lib/vendor/treetop/lib/treetop/compiler/node_classes.rb +19 -0
- data/lib/vendor/treetop/lib/treetop/compiler/node_classes/anything_symbol.rb +18 -0
- data/lib/vendor/treetop/lib/treetop/compiler/node_classes/atomic_expression.rb +14 -0
- data/lib/vendor/treetop/lib/treetop/compiler/node_classes/character_class.rb +24 -0
- data/lib/vendor/treetop/lib/treetop/compiler/node_classes/choice.rb +31 -0
- data/lib/vendor/treetop/lib/treetop/compiler/node_classes/declaration_sequence.rb +24 -0
- data/lib/vendor/treetop/lib/treetop/compiler/node_classes/grammar.rb +28 -0
- data/lib/vendor/treetop/lib/treetop/compiler/node_classes/inline_module.rb +27 -0
- data/lib/vendor/treetop/lib/treetop/compiler/node_classes/nonterminal.rb +13 -0
- data/lib/vendor/treetop/lib/treetop/compiler/node_classes/optional.rb +19 -0
- data/lib/vendor/treetop/lib/treetop/compiler/node_classes/parenthesized_expression.rb +9 -0
- data/lib/vendor/treetop/lib/treetop/compiler/node_classes/parsing_expression.rb +138 -0
- data/lib/vendor/treetop/lib/treetop/compiler/node_classes/parsing_rule.rb +55 -0
- data/lib/vendor/treetop/lib/treetop/compiler/node_classes/predicate.rb +45 -0
- data/lib/vendor/treetop/lib/treetop/compiler/node_classes/repetition.rb +55 -0
- data/lib/vendor/treetop/lib/treetop/compiler/node_classes/sequence.rb +68 -0
- data/lib/vendor/treetop/lib/treetop/compiler/node_classes/terminal.rb +20 -0
- data/lib/vendor/treetop/lib/treetop/compiler/node_classes/transient_prefix.rb +9 -0
- data/lib/vendor/treetop/lib/treetop/compiler/node_classes/treetop_file.rb +9 -0
- data/lib/vendor/treetop/lib/treetop/compiler/ruby_builder.rb +113 -0
- data/lib/vendor/treetop/lib/treetop/ruby_extensions.rb +2 -0
- data/lib/vendor/treetop/lib/treetop/ruby_extensions/string.rb +42 -0
- data/lib/vendor/treetop/lib/treetop/runtime.rb +5 -0
- data/lib/vendor/treetop/lib/treetop/runtime/compiled_parser.rb +105 -0
- data/lib/vendor/treetop/lib/treetop/runtime/interval_skip_list.rb +4 -0
- data/lib/vendor/treetop/lib/treetop/runtime/interval_skip_list/head_node.rb +15 -0
- data/lib/vendor/treetop/lib/treetop/runtime/interval_skip_list/interval_skip_list.rb +200 -0
- data/lib/vendor/treetop/lib/treetop/runtime/interval_skip_list/node.rb +164 -0
- data/lib/vendor/treetop/lib/treetop/runtime/syntax_node.rb +72 -0
- data/lib/vendor/treetop/lib/treetop/runtime/terminal_parse_failure.rb +16 -0
- data/lib/vendor/treetop/lib/treetop/runtime/terminal_syntax_node.rb +17 -0
- data/lib/vendor/treetop/lib/treetop/version.rb +9 -0
- data/lib/vendor/treetop/spec/compiler/and_predicate_spec.rb +36 -0
- data/lib/vendor/treetop/spec/compiler/anything_symbol_spec.rb +44 -0
- data/lib/vendor/treetop/spec/compiler/character_class_spec.rb +182 -0
- data/lib/vendor/treetop/spec/compiler/choice_spec.rb +80 -0
- data/lib/vendor/treetop/spec/compiler/circular_compilation_spec.rb +28 -0
- data/lib/vendor/treetop/spec/compiler/failure_propagation_functional_spec.rb +21 -0
- data/lib/vendor/treetop/spec/compiler/grammar_compiler_spec.rb +84 -0
- data/lib/vendor/treetop/spec/compiler/grammar_spec.rb +41 -0
- data/lib/vendor/treetop/spec/compiler/nonterminal_symbol_spec.rb +40 -0
- data/lib/vendor/treetop/spec/compiler/not_predicate_spec.rb +38 -0
- data/lib/vendor/treetop/spec/compiler/one_or_more_spec.rb +35 -0
- data/lib/vendor/treetop/spec/compiler/optional_spec.rb +37 -0
- data/lib/vendor/treetop/spec/compiler/parenthesized_expression_spec.rb +19 -0
- data/lib/vendor/treetop/spec/compiler/parsing_rule_spec.rb +32 -0
- data/lib/vendor/treetop/spec/compiler/sequence_spec.rb +115 -0
- data/lib/vendor/treetop/spec/compiler/terminal_spec.rb +81 -0
- data/lib/vendor/treetop/spec/compiler/terminal_symbol_spec.rb +37 -0
- data/lib/vendor/treetop/spec/compiler/test_grammar.treetop +7 -0
- data/lib/vendor/treetop/spec/compiler/test_grammar.tt +7 -0
- data/lib/vendor/treetop/spec/compiler/test_grammar_do.treetop +7 -0
- data/lib/vendor/treetop/spec/compiler/zero_or_more_spec.rb +56 -0
- data/lib/vendor/treetop/spec/composition/a.treetop +11 -0
- data/lib/vendor/treetop/spec/composition/b.treetop +11 -0
- data/lib/vendor/treetop/spec/composition/c.treetop +10 -0
- data/lib/vendor/treetop/spec/composition/d.treetop +10 -0
- data/lib/vendor/treetop/spec/composition/f.treetop +17 -0
- data/lib/vendor/treetop/spec/composition/grammar_composition_spec.rb +40 -0
- data/lib/vendor/treetop/spec/composition/subfolder/e_includes_c.treetop +15 -0
- data/lib/vendor/treetop/spec/ruby_extensions/string_spec.rb +32 -0
- data/lib/vendor/treetop/spec/runtime/compiled_parser_spec.rb +101 -0
- data/lib/vendor/treetop/spec/runtime/interval_skip_list/delete_spec.rb +147 -0
- data/lib/vendor/treetop/spec/runtime/interval_skip_list/expire_range_spec.rb +349 -0
- data/lib/vendor/treetop/spec/runtime/interval_skip_list/insert_and_delete_node.rb +385 -0
- data/lib/vendor/treetop/spec/runtime/interval_skip_list/insert_spec.rb +660 -0
- data/lib/vendor/treetop/spec/runtime/interval_skip_list/interval_skip_list_spec.graffle +6175 -0
- data/lib/vendor/treetop/spec/runtime/interval_skip_list/interval_skip_list_spec.rb +58 -0
- data/lib/vendor/treetop/spec/runtime/interval_skip_list/palindromic_fixture.rb +23 -0
- data/lib/vendor/treetop/spec/runtime/interval_skip_list/palindromic_fixture_spec.rb +164 -0
- data/lib/vendor/treetop/spec/runtime/interval_skip_list/spec_helper.rb +84 -0
- data/lib/vendor/treetop/spec/runtime/syntax_node_spec.rb +53 -0
- data/lib/vendor/treetop/spec/spec_helper.rb +106 -0
- data/lib/vendor/treetop/spec/spec_suite.rb +4 -0
- data/lib/vendor/treetop/treetop.gemspec +17 -0
- data/spec/command_spec.rb +102 -0
- data/spec/css/accessors.css +18 -0
- data/spec/css/big.css +3768 -0
- data/spec/css/colors.css +11 -0
- data/spec/css/comments.css +9 -0
- data/spec/css/css-3.css +2 -0
- data/spec/css/css.css +45 -0
- data/spec/css/functions.css +6 -0
- data/spec/css/import.css +12 -0
- data/spec/css/lazy-eval.css +1 -0
- data/spec/css/mixins-args.css +0 -0
- data/spec/css/mixins.css +28 -0
- data/spec/css/operations.css +28 -0
- data/spec/css/parens.css +16 -0
- data/spec/css/rulesets.css +17 -0
- data/spec/css/scope.css +11 -0
- data/spec/css/selectors.css +8 -0
- data/spec/css/strings.css +12 -0
- data/spec/css/variables.css +6 -0
- data/spec/css/whitespace.css +11 -0
- data/spec/engine_spec.rb +111 -0
- data/spec/less/accessors.less +20 -0
- data/spec/less/big.less +4810 -0
- data/spec/less/colors.less +34 -0
- data/spec/less/comments.less +46 -0
- data/spec/less/css-3.less +11 -0
- data/spec/less/css.less +98 -0
- data/spec/less/exceptions/mixed-units-error.less +3 -0
- data/spec/less/exceptions/name-error-1.0.less +3 -0
- data/spec/less/exceptions/syntax-error-1.0.less +3 -0
- data/spec/less/functions.less +6 -0
- data/spec/less/import.less +7 -0
- data/spec/less/import/import-test-a.less +2 -0
- data/spec/less/import/import-test-b.less +8 -0
- data/spec/less/import/import-test-c.less +6 -0
- data/spec/less/import/import-test-d.css +1 -0
- data/spec/less/lazy-eval.less +6 -0
- data/spec/less/mixins-args.less +0 -0
- data/spec/less/mixins.less +43 -0
- data/spec/less/operations.less +39 -0
- data/spec/less/parens.less +21 -0
- data/spec/less/rulesets.less +30 -0
- data/spec/less/scope.less +32 -0
- data/spec/less/selectors.less +15 -0
- data/spec/less/strings.less +14 -0
- data/spec/less/variables.less +18 -0
- data/spec/less/whitespace.less +30 -0
- data/spec/spec.css +82 -0
- data/spec/spec.less +148 -0
- data/spec/spec_helper.rb +8 -0
- metadata +219 -0
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
$:.unshift File.dirname(__FILE__)
|
|
2
|
+
|
|
3
|
+
require 'engine/nodes/entity'
|
|
4
|
+
require 'engine/nodes/function'
|
|
5
|
+
require 'engine/nodes/ruleset'
|
|
6
|
+
require 'engine/nodes/element'
|
|
7
|
+
require 'engine/nodes/property'
|
|
8
|
+
require 'engine/nodes/literal'
|
|
9
|
+
require 'engine/nodes/selector'
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
module Less
|
|
2
|
+
module Node
|
|
3
|
+
#
|
|
4
|
+
# Element
|
|
5
|
+
#
|
|
6
|
+
# div {...}
|
|
7
|
+
#
|
|
8
|
+
# TODO: Look into making @rules its own hash-like class
|
|
9
|
+
# TODO: Look into whether selector should be child by default
|
|
10
|
+
#
|
|
11
|
+
class Element < ::String
|
|
12
|
+
include Enumerable
|
|
13
|
+
include Entity
|
|
14
|
+
|
|
15
|
+
attr_accessor :rules, :selector, :partial, :file, :set
|
|
16
|
+
|
|
17
|
+
def initialize name = "", selector = ''
|
|
18
|
+
super name
|
|
19
|
+
|
|
20
|
+
@set = []
|
|
21
|
+
@rules = [] # Holds all the nodes under this element's hierarchy
|
|
22
|
+
@selector = Selector[selector.strip].new # descendant | child | adjacent
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def class?; self =~ /^\./ end
|
|
26
|
+
def id?; self =~ /^#/ end
|
|
27
|
+
def universal?; self == '*' end
|
|
28
|
+
|
|
29
|
+
def tag?
|
|
30
|
+
not id? || class? || universal?
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Top-most node?
|
|
34
|
+
def root?
|
|
35
|
+
parent.nil?
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def empty?
|
|
39
|
+
@rules.empty?
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def leaf?
|
|
43
|
+
elements.empty?
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Group similar rulesets together
|
|
47
|
+
# This is horrible, horrible code,
|
|
48
|
+
# but it'll have to do until I find
|
|
49
|
+
# a proper way to do it.
|
|
50
|
+
def group
|
|
51
|
+
matched = false
|
|
52
|
+
stack, result = elements.dup, []
|
|
53
|
+
return self unless elements.size > 1
|
|
54
|
+
|
|
55
|
+
elements.each do
|
|
56
|
+
e = stack.first
|
|
57
|
+
result << e unless matched
|
|
58
|
+
|
|
59
|
+
matched = stack[1..-1].each do |ee|
|
|
60
|
+
if e.rules.size == ee.rules.size and
|
|
61
|
+
e.elements.size == 0 and
|
|
62
|
+
!e.rules.zip(ee.rules).map {|a, b|
|
|
63
|
+
a.to_css == b.to_css
|
|
64
|
+
}.include?(false)
|
|
65
|
+
|
|
66
|
+
# Add to set unless it's a duplicate
|
|
67
|
+
if e == ee
|
|
68
|
+
# Do something with dups
|
|
69
|
+
else
|
|
70
|
+
self[e].set << ee
|
|
71
|
+
end
|
|
72
|
+
stack.shift
|
|
73
|
+
else
|
|
74
|
+
stack.shift
|
|
75
|
+
break false
|
|
76
|
+
end
|
|
77
|
+
end if stack.size > 1
|
|
78
|
+
end
|
|
79
|
+
@rules -= (elements - result)
|
|
80
|
+
self
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
#
|
|
84
|
+
# Accessors for the different nodes in @rules
|
|
85
|
+
#
|
|
86
|
+
def identifiers; @rules.select {|r| r.kind_of? Property } end
|
|
87
|
+
def properties; @rules.select {|r| r.instance_of? Property } end
|
|
88
|
+
def variables; @rules.select {|r| r.instance_of? Variable } end
|
|
89
|
+
def elements; @rules.select {|r| r.instance_of? Element } end
|
|
90
|
+
|
|
91
|
+
# Select a child element
|
|
92
|
+
# TODO: Implement full selector syntax & merge with descend()
|
|
93
|
+
def [] key
|
|
94
|
+
@rules.find {|i| i.to_s == key }
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# Same as above, except with a specific selector
|
|
98
|
+
# TODO: clean this up or implement it differently
|
|
99
|
+
def descend selector, element
|
|
100
|
+
if selector.is_a? Child
|
|
101
|
+
s = self[element].selector
|
|
102
|
+
self[element] if s.is_a? Child or s.is_a? Descendant
|
|
103
|
+
elsif selector.is_a? Descendant
|
|
104
|
+
self[element]
|
|
105
|
+
else
|
|
106
|
+
self[element] if self[element].selector.class == selector.class
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
#
|
|
111
|
+
# Add an arbitrary node to this element
|
|
112
|
+
#
|
|
113
|
+
def << obj
|
|
114
|
+
if obj.kind_of? Node::Entity
|
|
115
|
+
obj.parent = self
|
|
116
|
+
@rules << obj
|
|
117
|
+
else
|
|
118
|
+
raise ArgumentError, "argument can't be a #{obj.class}"
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def last; elements.last end
|
|
123
|
+
def first; elements.first end
|
|
124
|
+
def to_s; root?? '*' : super end
|
|
125
|
+
|
|
126
|
+
#
|
|
127
|
+
# Entry point for the css conversion
|
|
128
|
+
#
|
|
129
|
+
def to_css path = []
|
|
130
|
+
path << @selector.to_css << self unless root?
|
|
131
|
+
|
|
132
|
+
content = properties.map do |i|
|
|
133
|
+
' ' * 2 + i.to_css
|
|
134
|
+
end.compact.reject(&:empty?) * "\n"
|
|
135
|
+
|
|
136
|
+
content = content.include?("\n") ?
|
|
137
|
+
"\n#{content}\n" : " #{content.strip} "
|
|
138
|
+
ruleset = !content.strip.empty??
|
|
139
|
+
"#{[path.reject(&:empty?).join.strip, *@set] * ', '} {#{content}}\n" : ""
|
|
140
|
+
|
|
141
|
+
css = ruleset + elements.map do |i|
|
|
142
|
+
i.to_css(path)
|
|
143
|
+
end.reject(&:empty?).join
|
|
144
|
+
path.pop; path.pop
|
|
145
|
+
css
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
#
|
|
149
|
+
# Find the nearest variable in the hierarchy or raise a NameError
|
|
150
|
+
#
|
|
151
|
+
def nearest ident
|
|
152
|
+
ary = ident =~ /^[.#]/ ? :elements : :variables
|
|
153
|
+
path.map do |node|
|
|
154
|
+
node.send(ary).find {|i| i.to_s == ident }
|
|
155
|
+
end.compact.first.tap do |result|
|
|
156
|
+
raise VariableNameError, ident unless result
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
#
|
|
161
|
+
# Traverse the whole tree, returning each leaf (recursive)
|
|
162
|
+
#
|
|
163
|
+
def each path = [], &blk
|
|
164
|
+
elements.each do |element|
|
|
165
|
+
path << element
|
|
166
|
+
yield element, path if element.leaf?
|
|
167
|
+
element.each path, &blk
|
|
168
|
+
path.pop
|
|
169
|
+
end
|
|
170
|
+
self
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
def inspect depth = 0
|
|
174
|
+
indent = lambda {|i| '. ' * i }
|
|
175
|
+
put = lambda {|ary| ary.map {|i| indent[ depth + 1 ] + i.inspect } * "\n"}
|
|
176
|
+
|
|
177
|
+
(root?? "\n" : "") + [
|
|
178
|
+
indent[ depth ] + (self == '' ? '*' : self.to_s),
|
|
179
|
+
put[ properties ],
|
|
180
|
+
put[ variables ],
|
|
181
|
+
elements.map {|i| i.inspect( depth + 1 ) } * "\n"
|
|
182
|
+
].reject(&:empty?).join("\n") + "\n" + indent[ depth ]
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
end
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
module Less
|
|
2
|
+
#
|
|
3
|
+
# Node::Entity
|
|
4
|
+
#
|
|
5
|
+
# Everything in the tree is an Entity
|
|
6
|
+
#
|
|
7
|
+
# Mixin/Class hierarchy
|
|
8
|
+
#
|
|
9
|
+
# - Entity
|
|
10
|
+
# - Element
|
|
11
|
+
# - Entity
|
|
12
|
+
# - Function
|
|
13
|
+
# - Keyword
|
|
14
|
+
# - Literal
|
|
15
|
+
# - Color
|
|
16
|
+
# - Number
|
|
17
|
+
# - String
|
|
18
|
+
# - FontFamily
|
|
19
|
+
# - Property
|
|
20
|
+
# - Variable
|
|
21
|
+
#
|
|
22
|
+
# TODO: Use delegate class -> @rules
|
|
23
|
+
#
|
|
24
|
+
module Node
|
|
25
|
+
module Entity
|
|
26
|
+
attr_accessor :parent
|
|
27
|
+
|
|
28
|
+
def initialize value, parent = nil
|
|
29
|
+
super value
|
|
30
|
+
@parent = parent
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
#
|
|
34
|
+
# Returns the path from any given node, to the root
|
|
35
|
+
#
|
|
36
|
+
# ex: ['color', 'p', '#header', 'body', '*']
|
|
37
|
+
#
|
|
38
|
+
def path node = self
|
|
39
|
+
path = []
|
|
40
|
+
while node do
|
|
41
|
+
path << node
|
|
42
|
+
node = node.parent
|
|
43
|
+
end
|
|
44
|
+
path
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def root
|
|
48
|
+
path.last
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def inspect; to_s end
|
|
52
|
+
def to_css; to_s end
|
|
53
|
+
def to_s; super end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
#
|
|
57
|
+
# An anonymous node, for all the 'other' stuff
|
|
58
|
+
# which doesn't need any specific functionality.
|
|
59
|
+
#
|
|
60
|
+
class Anonymous < ::String
|
|
61
|
+
include Entity
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
#
|
|
65
|
+
# + * - /
|
|
66
|
+
#
|
|
67
|
+
class Operator < ::String
|
|
68
|
+
def to_ruby
|
|
69
|
+
self
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
class Paren < ::String
|
|
74
|
+
def to_ruby
|
|
75
|
+
self
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
module Less
|
|
2
|
+
#
|
|
3
|
+
# Functions useable from within the style-sheet go here
|
|
4
|
+
#
|
|
5
|
+
module Functions
|
|
6
|
+
def rgb *rgb
|
|
7
|
+
rgba rgb, 1.0
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def hsl *args
|
|
11
|
+
hsla args, 1.0
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
#
|
|
15
|
+
# RGBA to Node::Color
|
|
16
|
+
#
|
|
17
|
+
def rgba *rgba
|
|
18
|
+
Node::Color.new *rgba.flatten
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
#
|
|
22
|
+
# HSLA to RGBA
|
|
23
|
+
#
|
|
24
|
+
def hsla h, s, l, a = 1.0
|
|
25
|
+
m2 = ( l <= 0.5 ) ? l * ( s + 1 ) : l + s - l * s
|
|
26
|
+
m1 = l * 2 - m2;
|
|
27
|
+
|
|
28
|
+
hue = lambda do |h|
|
|
29
|
+
h = h < 0 ? h + 1 : (h > 1 ? h - 1 : h)
|
|
30
|
+
if h * 6 < 1 then m1 + (m2 - m1) * h * 6
|
|
31
|
+
elsif h * 2 < 1 then m2
|
|
32
|
+
elsif h * 3 < 2 then m1 + (m2 - m1) * (2/3 - h) * 6
|
|
33
|
+
else m1
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
rgba hue[ h + 1/3 ], hue[ h ], hue[ h - 1/3 ], a
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def self.available
|
|
41
|
+
self.instance_methods.map(&:to_sym)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
module Node
|
|
46
|
+
#
|
|
47
|
+
# A CSS function, like rgb() or url()
|
|
48
|
+
#
|
|
49
|
+
# it calls functions from the Functions module
|
|
50
|
+
#
|
|
51
|
+
class Function < ::String
|
|
52
|
+
include Entity
|
|
53
|
+
include Functions
|
|
54
|
+
|
|
55
|
+
def initialize name, *args
|
|
56
|
+
@args = args.flatten
|
|
57
|
+
super name
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def to_css
|
|
61
|
+
self.evaluate.to_css
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
#
|
|
65
|
+
# Call the function
|
|
66
|
+
#
|
|
67
|
+
# If the function isn't found, we just print it out,
|
|
68
|
+
# this is the case for url(), for example,
|
|
69
|
+
#
|
|
70
|
+
def evaluate
|
|
71
|
+
if Functions.available.include? self.to_sym
|
|
72
|
+
send to_sym, *@args
|
|
73
|
+
else
|
|
74
|
+
Node::Anonymous.new("#{to_sym}(#{@args.map(&:to_css) * ', '})")
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
module Less
|
|
2
|
+
module Node
|
|
3
|
+
module Literal
|
|
4
|
+
include Entity
|
|
5
|
+
|
|
6
|
+
def unit
|
|
7
|
+
nil
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
#
|
|
12
|
+
# rgb(255, 0, 0) #f0f0f0
|
|
13
|
+
#
|
|
14
|
+
class Color
|
|
15
|
+
include Literal
|
|
16
|
+
attr_reader :r, :g, :b, :a
|
|
17
|
+
|
|
18
|
+
def initialize r, g, b, a = 1.0
|
|
19
|
+
@r, @g, @b = [r, g, b].map do |c|
|
|
20
|
+
normalize(c.is_a?(::String) ? c.to_i(16) : c)
|
|
21
|
+
end
|
|
22
|
+
@a = normalize(a, 1.0)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def alpha v
|
|
26
|
+
self.class.new r, g, b, v
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def rgb
|
|
30
|
+
[r, g, b]
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def operate op, other
|
|
34
|
+
color = if other.is_a? Numeric
|
|
35
|
+
rgb.map {|c| c.send(op, other) }
|
|
36
|
+
else
|
|
37
|
+
rgb.zip(other.rgb).map {|a, b| a.send(op, b) }
|
|
38
|
+
end
|
|
39
|
+
self.class.new *[color, @a].flatten # Ruby 1.8 hack
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def + other; operate :+, other end
|
|
43
|
+
def - other; operate :-, other end
|
|
44
|
+
def * other; operate :*, other end
|
|
45
|
+
def / other; operate :/, other end
|
|
46
|
+
|
|
47
|
+
def coerce other
|
|
48
|
+
return self, other
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def to_s
|
|
52
|
+
if a < 1.0
|
|
53
|
+
"rgba(#{r.to_i}, #{g.to_i}, #{b.to_i}, #{a})"
|
|
54
|
+
else
|
|
55
|
+
"#%02x%02x%02x" % [r, g, b]
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def inspect
|
|
60
|
+
if a < 1.0
|
|
61
|
+
"rgba(#{r}, #{g}, #{b}, #{a})"
|
|
62
|
+
else
|
|
63
|
+
"rgb(#{r}, #{g}, #{b})"
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def to_css
|
|
68
|
+
to_s
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def to_ruby
|
|
72
|
+
"#{self.class}.new(#{r},#{g},#{b},#{a})"
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
protected
|
|
76
|
+
def normalize(v, max = 255, min = 0)
|
|
77
|
+
[[min, v].max, max].min
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
#
|
|
82
|
+
# 6 10px 125%
|
|
83
|
+
#
|
|
84
|
+
class Number < DelegateClass(Float)
|
|
85
|
+
include Literal
|
|
86
|
+
|
|
87
|
+
attr_accessor :unit
|
|
88
|
+
|
|
89
|
+
def initialize value, unit = nil
|
|
90
|
+
super value.to_f
|
|
91
|
+
@unit = (unit.nil? || unit.empty?) ? nil : unit
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def to_s
|
|
95
|
+
"#{super}#@unit"
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def to_ruby
|
|
99
|
+
self.to_f
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def inspect
|
|
103
|
+
to_s
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def to_css
|
|
107
|
+
"#{(self % 1).zero?? "#{self.to_i}#@unit" : self}"
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
#
|
|
112
|
+
# "hello world"
|
|
113
|
+
#
|
|
114
|
+
class String < ::String
|
|
115
|
+
include Literal
|
|
116
|
+
|
|
117
|
+
attr_reader :quotes, :content
|
|
118
|
+
|
|
119
|
+
# Strip quotes if necessary, and save them in @quotes
|
|
120
|
+
def initialize str
|
|
121
|
+
@quotes, @content = unless str.nil? or str.empty?
|
|
122
|
+
str.match(/('|")(.*?)(\1)/).captures rescue [nil, str]
|
|
123
|
+
else
|
|
124
|
+
[nil, ""]
|
|
125
|
+
end
|
|
126
|
+
super @content
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def to_css
|
|
130
|
+
"#@quotes#{@content}#@quotes"
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
class Font
|
|
135
|
+
include Literal
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
class FontFamily
|
|
139
|
+
include Literal
|
|
140
|
+
|
|
141
|
+
def initialize family = []
|
|
142
|
+
@family = family
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def to_css
|
|
146
|
+
@family.map(&:to_css) * ', '
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
#
|
|
151
|
+
# Any un-quoted word
|
|
152
|
+
#
|
|
153
|
+
# ex: red, small, border-collapse
|
|
154
|
+
#
|
|
155
|
+
class Keyword < ::String
|
|
156
|
+
include Entity
|
|
157
|
+
|
|
158
|
+
def to_css
|
|
159
|
+
self
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def inspect
|
|
163
|
+
"#{self}"
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
end
|