cloudhead-less 1.0.3 → 1.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +2 -3
- data/VERSION +1 -1
- data/less.gemspec +2 -2
- data/lib/less.rb +8 -9
- data/lib/less/engine.rb +8 -14
- data/lib/less/engine/builder.rb +0 -5
- data/lib/less/engine/less.tt +1 -10
- data/lib/less/engine/nodes/element.rb +4 -9
- data/lib/less/engine/nodes/property.rb +3 -11
- data/lib/less/engine/parser.rb +42 -63
- data/lib/vendor/treetop/lib/treetop.rb +0 -3
- data/lib/vendor/treetop/lib/treetop/runtime/syntax_node.rb +5 -1
- data/lib/vendor/treetop/spec/compiler/character_class_spec.rb +8 -0
- data/lib/vendor/treetop/treetop.gemspec +0 -1
- metadata +2 -2
data/Rakefile
CHANGED
@@ -17,7 +17,6 @@ end
|
|
17
17
|
begin
|
18
18
|
require 'rake/contrib/sshpublisher'
|
19
19
|
namespace :rubyforge do
|
20
|
-
|
21
20
|
desc "Release gem and RDoc documentation to RubyForge"
|
22
21
|
task :release => ["rubyforge:release:gem", "rubyforge:release:docs"]
|
23
22
|
|
@@ -64,8 +63,8 @@ begin
|
|
64
63
|
require 'lib/less'
|
65
64
|
|
66
65
|
task :compile do
|
67
|
-
puts "compiling #{
|
68
|
-
File.open(
|
66
|
+
puts "compiling #{LESS_GRAMMAR.split('/').last}..."
|
67
|
+
File.open(LESS_PARSER, 'w') {|f| f.write Treetop::Compiler::GrammarCompiler.new.ruby_source(LESS_GRAMMAR) }
|
69
68
|
end
|
70
69
|
|
71
70
|
task :benchmark do
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.0.
|
1
|
+
1.0.4
|
data/less.gemspec
CHANGED
@@ -2,11 +2,11 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{less}
|
5
|
-
s.version = "1.0.
|
5
|
+
s.version = "1.0.4"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["cloudhead"]
|
9
|
-
s.date = %q{2009-07-
|
9
|
+
s.date = %q{2009-07-13}
|
10
10
|
s.default_executable = %q{lessc}
|
11
11
|
s.description = %q{LESS is leaner CSS}
|
12
12
|
s.email = %q{self@cloudhead.net}
|
data/lib/less.rb
CHANGED
@@ -1,19 +1,18 @@
|
|
1
|
-
$:.unshift File.dirname(__FILE__),
|
2
|
-
|
1
|
+
$:.unshift File.join(File.dirname(__FILE__), 'vendor', 'treetop', 'lib'),
|
2
|
+
File.dirname(__FILE__)
|
3
3
|
|
4
|
-
require 'rubygems'
|
5
4
|
require 'cgi'
|
6
|
-
require 'delegate'
|
7
5
|
require 'treetop'
|
6
|
+
require 'delegate'
|
7
|
+
|
8
|
+
LESS_ROOT = File.expand_path(File.dirname(__FILE__))
|
9
|
+
LESS_PARSER = File.join(LESS_ROOT, 'less', 'engine', 'parser.rb')
|
10
|
+
LESS_GRAMMAR = File.join(LESS_ROOT, 'less', 'engine', 'less.tt')
|
8
11
|
|
9
12
|
require 'less/command'
|
10
13
|
require 'less/engine'
|
11
14
|
|
12
|
-
module Less
|
13
|
-
ROOT = File.expand_path(File.dirname(__FILE__))
|
14
|
-
PARSER = File.join(ROOT, 'less', 'engine', 'parser.rb')
|
15
|
-
GRAMMAR = File.join(ROOT, 'less', 'engine', 'less.tt')
|
16
|
-
|
15
|
+
module Less
|
17
16
|
MixedUnitsError = Class.new(Exception)
|
18
17
|
PathError = Class.new(Exception)
|
19
18
|
VariableNameError = Class.new(NameError)
|
data/lib/less/engine.rb
CHANGED
@@ -3,6 +3,12 @@ $:.unshift File.dirname(__FILE__)
|
|
3
3
|
require 'engine/builder'
|
4
4
|
require 'engine/nodes'
|
5
5
|
|
6
|
+
begin
|
7
|
+
require 'engine/parser'
|
8
|
+
rescue LoadError
|
9
|
+
Treetop.load LESS_GRAMMAR
|
10
|
+
end
|
11
|
+
|
6
12
|
module Less
|
7
13
|
class Engine
|
8
14
|
attr_reader :css, :less
|
@@ -17,12 +23,6 @@ module Less
|
|
17
23
|
raise ArgumentError, "argument must be an instance of File or String!"
|
18
24
|
end
|
19
25
|
|
20
|
-
begin
|
21
|
-
require 'engine/parser'
|
22
|
-
rescue LoadError
|
23
|
-
Treetop.load Less::GRAMMAR
|
24
|
-
end
|
25
|
-
|
26
26
|
@parser = LessParser.new
|
27
27
|
end
|
28
28
|
|
@@ -34,9 +34,7 @@ module Less
|
|
34
34
|
else
|
35
35
|
raise SyntaxError, @parser.failure_message
|
36
36
|
end
|
37
|
-
|
38
|
-
log @tree.inspect
|
39
|
-
|
37
|
+
|
40
38
|
@tree
|
41
39
|
end
|
42
40
|
alias :to_tree :parse
|
@@ -46,11 +44,7 @@ module Less
|
|
46
44
|
end
|
47
45
|
|
48
46
|
def prepare
|
49
|
-
@less.gsub(/\r\n/, "\n").
|
50
|
-
gsub(/\t/, ' ') # Tabs to spaces
|
51
|
-
#gsub(/('|")(.*?)(\1)/) { $1 + CGI.escape( $2 ) + $1 } # Escape string values
|
52
|
-
# gsub(/\/\/.*\n/, ''). # Comments //
|
53
|
-
# gsub(/\/\*.*?\*\//m, '') # Comments /*
|
47
|
+
@less.gsub(/\r\n/, "\n").gsub(/\t/, ' ')
|
54
48
|
end
|
55
49
|
end
|
56
50
|
end
|
data/lib/less/engine/builder.rb
CHANGED
data/lib/less/engine/less.tt
CHANGED
@@ -20,13 +20,10 @@ grammar Less
|
|
20
20
|
end
|
21
21
|
} / ws selectors ';' ws {
|
22
22
|
def build env
|
23
|
-
log "[mixin]: #{selectors.text_value}"
|
24
23
|
selectors.build(env, :path).each do |path|
|
25
|
-
|
26
24
|
rules = path.inject(env.root) do |current, node|
|
27
25
|
current.descend(node.selector, node) or raise MixinNameError, path.join
|
28
26
|
end.rules
|
29
|
-
|
30
27
|
env.rules += rules
|
31
28
|
end
|
32
29
|
end
|
@@ -39,7 +36,6 @@ grammar Less
|
|
39
36
|
path = File.join(env.root.file, url.value)
|
40
37
|
path += '.less' unless path =~ /\.less$/
|
41
38
|
if File.exist? path
|
42
|
-
log "\nimporting #{path}"
|
43
39
|
imported = Less::Engine.new(File.new path).to_tree
|
44
40
|
env.rules += imported.rules
|
45
41
|
else
|
@@ -85,7 +81,6 @@ grammar Less
|
|
85
81
|
rule selector
|
86
82
|
(s select element s)+ {
|
87
83
|
def tree env
|
88
|
-
log "\n% element: #{text_value}\n"
|
89
84
|
elements.inject(env) do |node, e|
|
90
85
|
node << Node::Element.new(e.element.text_value, e.select.text_value)
|
91
86
|
node.last
|
@@ -170,7 +165,7 @@ grammar Less
|
|
170
165
|
# div / .class / #id / input[type="text"] / lang(fr)
|
171
166
|
#
|
172
167
|
rule element
|
173
|
-
(class_id / tag) attribute* ('(' ident ')')? / '@media' / '@font-face'
|
168
|
+
(class_id / tag / ident) attribute* ('(' ident ')')? / '@media' / '@font-face'
|
174
169
|
end
|
175
170
|
|
176
171
|
rule class_id
|
@@ -249,10 +244,6 @@ grammar Less
|
|
249
244
|
}
|
250
245
|
end
|
251
246
|
|
252
|
-
rule empty
|
253
|
-
"" <Empty>
|
254
|
-
end
|
255
|
-
|
256
247
|
#
|
257
248
|
# `blue`, `small`, `normal` etc.
|
258
249
|
#
|
@@ -52,7 +52,7 @@ module Less
|
|
52
52
|
def elements; @rules.select {|r| r.instance_of? Element } end
|
53
53
|
|
54
54
|
# Select a child element
|
55
|
-
# TODO: Implement full selector syntax
|
55
|
+
# TODO: Implement full selector syntax & merge with descend()
|
56
56
|
def [] key
|
57
57
|
@rules.find {|i| i.to_s == key }
|
58
58
|
end
|
@@ -119,16 +119,11 @@ module Less
|
|
119
119
|
raise VariableNameError, ident unless result
|
120
120
|
end
|
121
121
|
end
|
122
|
-
|
123
|
-
def each path = [], &blk
|
122
|
+
|
124
123
|
#
|
125
|
-
# Traverse the whole tree, returning each leaf
|
124
|
+
# Traverse the whole tree, returning each leaf (recursive)
|
126
125
|
#
|
127
|
-
|
128
|
-
# Aside from the key & value, we yield the full path of the leaf,
|
129
|
-
# aswell as the branch which contains it (self).
|
130
|
-
# Note that in :branch mode, we only return 'twigs', branches which contain leaves.
|
131
|
-
#
|
126
|
+
def each path = [], &blk
|
132
127
|
elements.each do |element|
|
133
128
|
path << element
|
134
129
|
yield element, path if element.leaf?
|
@@ -7,13 +7,11 @@ module Less
|
|
7
7
|
|
8
8
|
def initialize key, value = nil
|
9
9
|
super key
|
10
|
-
log "\n[new] #{self.class} `#{key}`\n"
|
11
10
|
@value = Expression.new(value ? [value] : [])
|
12
11
|
@eval = false # Store the first evaluation in here
|
13
12
|
end
|
14
13
|
|
15
14
|
def << token
|
16
|
-
log "[adding] to #{self.to_s}: '#{token.to_s}' <#{token.class}>\n"
|
17
15
|
token = Node::Anonymous.new(*token) unless token.is_a? Entity or token.is_a? Operator
|
18
16
|
@value << token
|
19
17
|
end
|
@@ -77,11 +75,11 @@ module Less
|
|
77
75
|
#
|
78
76
|
# Evaluates the expression and instantiates a new Literal with the result
|
79
77
|
# ex: [#111, +, #111] will evaluate to a Color node, with value #222
|
80
|
-
#
|
78
|
+
#
|
79
|
+
# TODO: refactor the conditionals
|
81
80
|
def evaluate
|
82
|
-
log "evaluating #{self}"
|
83
|
-
log "#{self.select{|i| i.is_a? Entity }}"
|
84
81
|
if size > 2 && (entities.size == operators.size + 1)
|
82
|
+
|
85
83
|
# Create a sub-expression with all the variables/properties evaluated
|
86
84
|
evaluated = Expression.new map {|e| e.respond_to?(:evaluate) ? e.evaluate : e }
|
87
85
|
|
@@ -95,21 +93,15 @@ module Less
|
|
95
93
|
ruby = map {|e| e.to_ruby if e.respond_to? :to_ruby }
|
96
94
|
|
97
95
|
unless ruby.include? nil
|
98
|
-
log "ruby(#{unit}): " + ruby.join(' ') + "\n"
|
99
|
-
|
100
96
|
if entity
|
101
|
-
log "\n# => #{eval(ruby.join)} <#{entity.class}>\n"
|
102
97
|
entity.class.new(eval(ruby.join), *(unit if entity.class == Node::Number))
|
103
98
|
else
|
104
|
-
log "\n# => not evaluated"
|
105
99
|
first
|
106
100
|
end
|
107
101
|
else
|
108
|
-
log "some elements dont respond to to_ruby: #{ruby}"
|
109
102
|
self
|
110
103
|
end
|
111
104
|
elsif size == 1
|
112
|
-
log "not evaluating, size == 1"
|
113
105
|
first
|
114
106
|
else
|
115
107
|
self
|
data/lib/less/engine/parser.rb
CHANGED
@@ -361,13 +361,10 @@ module Less
|
|
361
361
|
|
362
362
|
module Ruleset3
|
363
363
|
def build env
|
364
|
-
log "[mixin]: #{selectors.text_value}"
|
365
364
|
selectors.build(env, :path).each do |path|
|
366
|
-
|
367
365
|
rules = path.inject(env.root) do |current, node|
|
368
366
|
current.descend(node.selector, node) or raise MixinNameError, path.join
|
369
367
|
end.rules
|
370
|
-
|
371
368
|
env.rules += rules
|
372
369
|
end
|
373
370
|
end
|
@@ -497,7 +494,6 @@ module Less
|
|
497
494
|
path = File.join(env.root.file, url.value)
|
498
495
|
path += '.less' unless path =~ /\.less$/
|
499
496
|
if File.exist? path
|
500
|
-
log "\nimporting #{path}"
|
501
497
|
imported = Less::Engine.new(File.new path).to_tree
|
502
498
|
env.rules += imported.rules
|
503
499
|
else
|
@@ -930,7 +926,6 @@ module Less
|
|
930
926
|
|
931
927
|
module Selector1
|
932
928
|
def tree env
|
933
|
-
log "\n% element: #{text_value}\n"
|
934
929
|
elements.inject(env) do |node, e|
|
935
930
|
node << Node::Element.new(e.element.text_value, e.select.text_value)
|
936
931
|
node.last
|
@@ -1688,60 +1683,65 @@ module Less
|
|
1688
1683
|
if r4
|
1689
1684
|
r2 = r4
|
1690
1685
|
else
|
1691
|
-
|
1692
|
-
|
1686
|
+
r5 = _nt_ident
|
1687
|
+
if r5
|
1688
|
+
r2 = r5
|
1689
|
+
else
|
1690
|
+
@index = i2
|
1691
|
+
r2 = nil
|
1692
|
+
end
|
1693
1693
|
end
|
1694
1694
|
end
|
1695
1695
|
s1 << r2
|
1696
1696
|
if r2
|
1697
|
-
|
1697
|
+
s6, i6 = [], index
|
1698
1698
|
loop do
|
1699
|
-
|
1700
|
-
if
|
1701
|
-
|
1699
|
+
r7 = _nt_attribute
|
1700
|
+
if r7
|
1701
|
+
s6 << r7
|
1702
1702
|
else
|
1703
1703
|
break
|
1704
1704
|
end
|
1705
1705
|
end
|
1706
|
-
|
1707
|
-
s1 <<
|
1708
|
-
if
|
1709
|
-
|
1706
|
+
r6 = instantiate_node(SyntaxNode,input, i6...index, s6)
|
1707
|
+
s1 << r6
|
1708
|
+
if r6
|
1709
|
+
i9, s9 = index, []
|
1710
1710
|
if has_terminal?('(', false, index)
|
1711
|
-
|
1711
|
+
r10 = instantiate_node(SyntaxNode,input, index...(index + 1))
|
1712
1712
|
@index += 1
|
1713
1713
|
else
|
1714
1714
|
terminal_parse_failure('(')
|
1715
|
-
|
1715
|
+
r10 = nil
|
1716
1716
|
end
|
1717
|
-
|
1718
|
-
if
|
1719
|
-
|
1720
|
-
|
1721
|
-
if
|
1717
|
+
s9 << r10
|
1718
|
+
if r10
|
1719
|
+
r11 = _nt_ident
|
1720
|
+
s9 << r11
|
1721
|
+
if r11
|
1722
1722
|
if has_terminal?(')', false, index)
|
1723
|
-
|
1723
|
+
r12 = instantiate_node(SyntaxNode,input, index...(index + 1))
|
1724
1724
|
@index += 1
|
1725
1725
|
else
|
1726
1726
|
terminal_parse_failure(')')
|
1727
|
-
|
1727
|
+
r12 = nil
|
1728
1728
|
end
|
1729
|
-
|
1729
|
+
s9 << r12
|
1730
1730
|
end
|
1731
1731
|
end
|
1732
|
-
if
|
1733
|
-
|
1734
|
-
|
1732
|
+
if s9.last
|
1733
|
+
r9 = instantiate_node(SyntaxNode,input, i9...index, s9)
|
1734
|
+
r9.extend(Element0)
|
1735
1735
|
else
|
1736
|
-
@index =
|
1737
|
-
|
1736
|
+
@index = i9
|
1737
|
+
r9 = nil
|
1738
1738
|
end
|
1739
|
-
if
|
1740
|
-
|
1739
|
+
if r9
|
1740
|
+
r8 = r9
|
1741
1741
|
else
|
1742
|
-
|
1742
|
+
r8 = instantiate_node(SyntaxNode,input, index...index)
|
1743
1743
|
end
|
1744
|
-
s1 <<
|
1744
|
+
s1 << r8
|
1745
1745
|
end
|
1746
1746
|
end
|
1747
1747
|
if s1.last
|
@@ -1755,24 +1755,24 @@ module Less
|
|
1755
1755
|
r0 = r1
|
1756
1756
|
else
|
1757
1757
|
if has_terminal?('@media', false, index)
|
1758
|
-
|
1758
|
+
r13 = instantiate_node(SyntaxNode,input, index...(index + 6))
|
1759
1759
|
@index += 6
|
1760
1760
|
else
|
1761
1761
|
terminal_parse_failure('@media')
|
1762
|
-
|
1762
|
+
r13 = nil
|
1763
1763
|
end
|
1764
|
-
if
|
1765
|
-
r0 =
|
1764
|
+
if r13
|
1765
|
+
r0 = r13
|
1766
1766
|
else
|
1767
1767
|
if has_terminal?('@font-face', false, index)
|
1768
|
-
|
1768
|
+
r14 = instantiate_node(SyntaxNode,input, index...(index + 10))
|
1769
1769
|
@index += 10
|
1770
1770
|
else
|
1771
1771
|
terminal_parse_failure('@font-face')
|
1772
|
-
|
1772
|
+
r14 = nil
|
1773
1773
|
end
|
1774
|
-
if
|
1775
|
-
r0 =
|
1774
|
+
if r14
|
1775
|
+
r0 = r14
|
1776
1776
|
else
|
1777
1777
|
@index = i0
|
1778
1778
|
r0 = nil
|
@@ -2597,27 +2597,6 @@ module Less
|
|
2597
2597
|
r0
|
2598
2598
|
end
|
2599
2599
|
|
2600
|
-
def _nt_empty
|
2601
|
-
start_index = index
|
2602
|
-
if node_cache[:empty].has_key?(index)
|
2603
|
-
cached = node_cache[:empty][index]
|
2604
|
-
@index = cached.interval.end if cached
|
2605
|
-
return cached
|
2606
|
-
end
|
2607
|
-
|
2608
|
-
if has_terminal?("", false, index)
|
2609
|
-
r0 = instantiate_node(Empty,input, index...(index + 0))
|
2610
|
-
@index += 0
|
2611
|
-
else
|
2612
|
-
terminal_parse_failure("")
|
2613
|
-
r0 = nil
|
2614
|
-
end
|
2615
|
-
|
2616
|
-
node_cache[:empty][start_index] = r0
|
2617
|
-
|
2618
|
-
r0
|
2619
|
-
end
|
2620
|
-
|
2621
2600
|
module Keyword0
|
2622
2601
|
end
|
2623
2602
|
|
@@ -25,7 +25,7 @@ module Treetop
|
|
25
25
|
elements << node
|
26
26
|
end
|
27
27
|
elements
|
28
|
-
end
|
28
|
+
end.sort
|
29
29
|
end
|
30
30
|
|
31
31
|
def terminal?
|
@@ -43,6 +43,10 @@ module Treetop
|
|
43
43
|
def empty?
|
44
44
|
interval.first == interval.last && interval.exclude_end?
|
45
45
|
end
|
46
|
+
|
47
|
+
def <=>(other)
|
48
|
+
self.interval.first <=> other.interval.first
|
49
|
+
end
|
46
50
|
|
47
51
|
def extension_modules
|
48
52
|
local_extensions =
|
@@ -235,5 +235,13 @@ module CharacterClassSpec
|
|
235
235
|
result.elements.size.should == 2
|
236
236
|
end
|
237
237
|
end
|
238
|
+
|
239
|
+
describe "a character class with a label mixed with other expressions" do
|
240
|
+
testing_expression 'upper:([A-Z]) "b"'
|
241
|
+
it "returns the correct element for the labeled expression" do
|
242
|
+
result = parse('Ab')
|
243
|
+
result.upper.text_value.should == "A"
|
244
|
+
end
|
245
|
+
end
|
238
246
|
|
239
247
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cloudhead-less
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- cloudhead
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-07-
|
12
|
+
date: 2009-07-13 00:00:00 -07:00
|
13
13
|
default_executable: lessc
|
14
14
|
dependencies: []
|
15
15
|
|