cloudhead-less 1.0.3 → 1.0.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/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
|
|