casuistry 0.2.1 → 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- data/casuistry.gemspec +6 -6
- data/lib/casuistry.rb +108 -108
- data/lib/properties.rb +4 -0
- data/test/basics.rb +1 -1
- data/test/benchmark_for_fun.rb +50 -0
- data/test/fiddle.css +10 -6
- metadata +3 -2
data/casuistry.gemspec
CHANGED
@@ -1,18 +1,18 @@
|
|
1
1
|
|
2
|
-
# Gem::Specification for Casuistry-0.2.
|
2
|
+
# Gem::Specification for Casuistry-0.2.2
|
3
3
|
# Originally generated by Echoe
|
4
4
|
|
5
5
|
Gem::Specification.new do |s|
|
6
6
|
s.name = %q{casuistry}
|
7
|
-
s.version = "0.2.
|
7
|
+
s.version = "0.2.2"
|
8
8
|
|
9
9
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
10
10
|
s.authors = ["Matthew King"]
|
11
|
-
s.date = %q{2008-07-
|
11
|
+
s.date = %q{2008-07-29}
|
12
12
|
s.description = %q{Generates CSS using Ruby, like Markaby}
|
13
13
|
s.email = %q{automatthew@gmail.com}
|
14
14
|
s.extra_rdoc_files = ["lib/casuistry.rb", "lib/properties.rb", "lib/tags.rb", "README.rdoc"]
|
15
|
-
s.files = ["casuistry.gemspec", "lib/casuistry.rb", "lib/properties.rb", "lib/tags.rb", "Manifest", "README.rdoc", "test/basics.rb", "test/dan.css", "test/dan.cssy", "test/fiddle.css", "test/fiddle.cssy", "test/helper.rb", "test/nesting.cssy", "test/test.css", "test/test.cssy"]
|
15
|
+
s.files = ["casuistry.gemspec", "lib/casuistry.rb", "lib/properties.rb", "lib/tags.rb", "Manifest", "README.rdoc", "test/basics.rb", "test/dan.css", "test/dan.cssy", "test/fiddle.css", "test/fiddle.cssy", "test/helper.rb", "test/nesting.cssy", "test/test.css", "test/test.cssy", "test/benchmark_for_fun.rb"]
|
16
16
|
s.has_rdoc = true
|
17
17
|
s.homepage = %q{}
|
18
18
|
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Casuistry", "--main", "README.rdoc"]
|
@@ -20,7 +20,7 @@ Gem::Specification.new do |s|
|
|
20
20
|
s.rubyforge_project = %q{casuistry}
|
21
21
|
s.rubygems_version = %q{1.2.0}
|
22
22
|
s.summary = %q{Generates CSS using Ruby, like Markaby}
|
23
|
-
s.test_files = ["test/basics.rb", "test/helper.rb"]
|
23
|
+
s.test_files = ["test/basics.rb", "test/benchmark_for_fun.rb", "test/helper.rb"]
|
24
24
|
|
25
25
|
if s.respond_to? :specification_version then
|
26
26
|
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
@@ -40,7 +40,7 @@ end
|
|
40
40
|
# require dep
|
41
41
|
# end
|
42
42
|
#
|
43
|
-
# Version = '0.2.
|
43
|
+
# Version = '0.2.2'
|
44
44
|
#
|
45
45
|
# task :default => [:test]
|
46
46
|
#
|
data/lib/casuistry.rb
CHANGED
@@ -6,19 +6,20 @@ class Casuistry
|
|
6
6
|
|
7
7
|
attr_reader :data
|
8
8
|
|
9
|
-
def self.process(*args,&block)
|
10
|
-
self.new.process(*args,&block)
|
11
|
-
end
|
12
|
-
|
13
9
|
def initialize(sel=nil)
|
14
10
|
@data = []
|
15
|
-
@selectors = [ sel]
|
11
|
+
@selectors = [ sel ]
|
16
12
|
@properties = []
|
17
13
|
|
14
|
+
# Primitive state machine
|
18
15
|
# possible states are :closed_block, :chain, :open_block
|
19
16
|
@state = :closed_block
|
20
17
|
end
|
21
18
|
|
19
|
+
def self.process(*args,&block)
|
20
|
+
self.new.process(*args,&block)
|
21
|
+
end
|
22
|
+
|
22
23
|
def process(*args, &block)
|
23
24
|
if block
|
24
25
|
instance_eval(&block)
|
@@ -29,128 +30,127 @@ class Casuistry
|
|
29
30
|
end
|
30
31
|
|
31
32
|
def output
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
output << "\n{\n#{properties}\n}\n"
|
37
|
-
end
|
38
|
-
output
|
33
|
+
@data.map do |sel|
|
34
|
+
properties = sel.last.join("\n ")
|
35
|
+
"#{sel.first}\n{\n #{properties}\n}\n"
|
36
|
+
end.join
|
39
37
|
end
|
40
|
-
|
41
|
-
# state transitions
|
42
|
-
def open_block(new_selector)
|
43
|
-
case @state
|
44
|
-
when :closed_block, :open_block
|
45
|
-
combined_selector = [current_selector, new_selector].compact.join(" ")
|
46
|
-
@selectors.push combined_selector
|
47
|
-
new_property_set
|
48
|
-
when :chain
|
49
|
-
@selectors[-1] = "#{current_selector}#{new_selector}"
|
50
|
-
new_property_set
|
51
|
-
else
|
52
|
-
raise "You can't get to :open_block from #{@state.inspect}"
|
53
|
-
end
|
54
|
-
|
55
|
-
@state = :open_block
|
56
|
-
end
|
57
38
|
|
58
|
-
def chain(new_selector)
|
59
|
-
case @state
|
60
|
-
when :closed_block, :open_block
|
61
|
-
combined_selector = [current_selector, new_selector].compact.join(" ")
|
62
|
-
@selectors.push( combined_selector)
|
63
|
-
when :chain
|
64
|
-
@selectors[-1] = "#{current_selector}#{new_selector}"
|
65
|
-
else
|
66
|
-
raise "You can't get to :chain from #{@state.inspect}"
|
67
|
-
end
|
68
|
-
|
69
|
-
@state = :chain
|
70
|
-
end
|
71
39
|
|
72
|
-
def closed_block
|
73
|
-
case @state
|
74
|
-
when :open_block, :closed_block
|
75
|
-
@selectors.pop
|
76
|
-
@properties.pop
|
77
|
-
else
|
78
|
-
raise "You can't get to :closed_block from #{@state.inspect}"
|
79
|
-
end
|
80
|
-
|
81
|
-
@state = :closed_block
|
82
|
-
end
|
83
40
|
|
41
|
+
# Pushes an empty array on the properties stack and registers
|
42
|
+
# that array (against the current selector) in @data
|
43
|
+
def new_property_set
|
44
|
+
@properties.push []
|
45
|
+
@data << [@selectors[-1], @properties[-1] ]
|
46
|
+
end
|
84
47
|
|
85
|
-
# normal methods
|
86
48
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
self
|
49
|
+
# Declare a CSS selector using a block. May be chained and nested.
|
50
|
+
def selector(sel)
|
51
|
+
if block_given?
|
52
|
+
open_block(sel)
|
53
|
+
yield
|
54
|
+
closed_block
|
55
|
+
else
|
56
|
+
chain(sel)
|
96
57
|
end
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
58
|
+
self
|
59
|
+
end
|
60
|
+
|
61
|
+
# Catch unknown methods and treat them as CSS class or id selectors.
|
62
|
+
def method_missing(name, &block)
|
63
|
+
sel = selectify(name)
|
64
|
+
if block_given?
|
65
|
+
open_block(sel)
|
66
|
+
yield
|
67
|
+
closed_block
|
68
|
+
else
|
69
|
+
chain(sel)
|
108
70
|
end
|
71
|
+
self
|
72
|
+
end
|
73
|
+
|
74
|
+
# bang methods represent CSS ids. Otherwise CSS classes.
|
75
|
+
def selectify(method_name)
|
76
|
+
matches = method_name.to_s.match( /([\w_]+)!$/)
|
77
|
+
matches ? "##{matches[1]}" : ".#{method_name}"
|
78
|
+
end
|
109
79
|
|
110
|
-
def current_selector
|
111
|
-
@selectors[-1]
|
112
|
-
end
|
113
80
|
|
114
|
-
|
115
|
-
|
81
|
+
# define tag methods that delegate to selector
|
82
|
+
methods = HTML_TAGS.map do |tag|
|
83
|
+
<<-METHOD
|
84
|
+
def #{tag}(&block)
|
85
|
+
selector('#{tag}', &block)
|
116
86
|
end
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
87
|
+
METHOD
|
88
|
+
end.join; module_eval(methods)
|
89
|
+
|
90
|
+
# define methods for CSS properties.
|
91
|
+
CSS_PROPERTIES.each do |method_name|
|
92
|
+
define_method method_name do |*args|
|
93
|
+
css_attr = method_name.gsub('_', '-')
|
94
|
+
property(css_attr, args)
|
121
95
|
end
|
96
|
+
end
|
122
97
|
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
98
|
+
# Add a property declaration string to the current selector's properties array.
|
99
|
+
def property(css_attr, *args)
|
100
|
+
@properties[-1] << "#{css_attr}: #{args.join(' ')};"
|
101
|
+
end
|
102
|
+
|
103
|
+
## State transitions
|
104
|
+
|
105
|
+
# Push the accumulated selector and a new property array onto the
|
106
|
+
# tops of their respected stacks
|
107
|
+
def open_block(new_selector)
|
108
|
+
case @state
|
109
|
+
when :closed_block, :open_block
|
110
|
+
combined_selector = [@selectors[-1], new_selector].compact.join(" ")
|
111
|
+
@selectors.push combined_selector
|
112
|
+
new_property_set
|
113
|
+
when :chain
|
114
|
+
@selectors[-1] = "#{@selectors[-1]}#{new_selector}"
|
115
|
+
new_property_set
|
116
|
+
else
|
117
|
+
raise "You can't get to :open_block from #{@state.inspect}"
|
139
118
|
end
|
119
|
+
|
120
|
+
@state = :open_block
|
121
|
+
end
|
140
122
|
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
123
|
+
# Pushes accumulated selector on the stack without generating a new properties array.
|
124
|
+
def chain(new_selector)
|
125
|
+
case @state
|
126
|
+
when :closed_block, :open_block
|
127
|
+
combined_selector = [@selectors[-1], new_selector].compact.join(" ")
|
128
|
+
@selectors.push( combined_selector)
|
129
|
+
when :chain
|
130
|
+
@selectors[-1] = "#{@selectors[-1]}#{new_selector}"
|
131
|
+
else
|
132
|
+
raise "You can't get to :chain from #{@state.inspect}"
|
145
133
|
end
|
134
|
+
|
135
|
+
@state = :chain
|
136
|
+
end
|
146
137
|
|
138
|
+
# Pop the selector string and property array for the closing block
|
139
|
+
# off of their respective stacks
|
140
|
+
def closed_block
|
141
|
+
case @state
|
142
|
+
when :open_block, :closed_block
|
143
|
+
@selectors.pop
|
144
|
+
@properties.pop
|
145
|
+
else
|
146
|
+
raise "You can't get to :closed_block from #{@state.inspect}"
|
147
|
+
end
|
148
|
+
|
149
|
+
@state = :closed_block
|
150
|
+
end
|
147
151
|
|
148
152
|
|
149
|
-
|
150
|
-
def selectify(method_name)
|
151
|
-
matches = method_name.to_s.match( /([\w_]+)!$/)
|
152
|
-
matches ? "##{matches[1]}" : ".#{method_name}"
|
153
|
-
end
|
153
|
+
|
154
154
|
|
155
155
|
end
|
156
156
|
|
data/lib/properties.rb
CHANGED
data/test/basics.rb
CHANGED
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'benchmark'
|
2
|
+
require 'rubygems'
|
3
|
+
require 'ruby-prof'
|
4
|
+
here = File.dirname(__FILE__)
|
5
|
+
require "#{here}/helper"
|
6
|
+
|
7
|
+
n = 1000
|
8
|
+
|
9
|
+
Benchmark.bm do |x|
|
10
|
+
x.report "fiddle.css " do
|
11
|
+
n.times do
|
12
|
+
css = File.read "#{here}/fiddle.css"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
x.report "fiddle.cssy " do
|
17
|
+
n.times do
|
18
|
+
c = Cssy.new
|
19
|
+
c.process(File.read("#{here}/fiddle.cssy"))
|
20
|
+
css = c.output
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
x.report "blog.css " do
|
25
|
+
n.times do
|
26
|
+
css = File.read "#{here}/blog.css"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
x.report "blog.cssy " do
|
31
|
+
n.times do
|
32
|
+
c = Cssy.new
|
33
|
+
c.process(File.read("#{here}/blog.cssy"))
|
34
|
+
css = c.output
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
result = RubyProf.profile do
|
41
|
+
c = Cssy.new
|
42
|
+
c.process(File.read("#{here}/blog.cssy"))
|
43
|
+
# css = c.output
|
44
|
+
end
|
45
|
+
|
46
|
+
printer = RubyProf::FlatPrinter.new(result)
|
47
|
+
printer.print(STDOUT, 0)
|
48
|
+
|
49
|
+
printer = RubyProf::GraphPrinter.new(result)
|
50
|
+
printer.print(STDOUT, 0)
|
data/test/fiddle.css
CHANGED
@@ -1,17 +1,21 @@
|
|
1
|
-
|
1
|
+
div
|
2
2
|
{
|
3
3
|
background: red;
|
4
|
-
width:
|
4
|
+
width: 9934px;
|
5
5
|
}
|
6
|
-
ul li
|
6
|
+
div ul li
|
7
7
|
{
|
8
8
|
color: green;
|
9
9
|
}
|
10
|
-
|
10
|
+
div p.ugly.truly
|
11
|
+
{
|
12
|
+
color: aqua;
|
13
|
+
}
|
14
|
+
div .smurf.house
|
11
15
|
{
|
12
16
|
height: 256px;
|
13
17
|
}
|
14
|
-
|
18
|
+
div #menu
|
15
19
|
{
|
16
20
|
padding: 10px;
|
17
21
|
}
|
@@ -19,7 +23,7 @@ ul #asrael
|
|
19
23
|
{
|
20
24
|
margin: 0px;
|
21
25
|
}
|
22
|
-
.outer
|
26
|
+
.outer.middle.inner
|
23
27
|
{
|
24
28
|
top: 34px;
|
25
29
|
}
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: casuistry
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matthew King
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-07-
|
12
|
+
date: 2008-07-29 00:00:00 -05:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -73,4 +73,5 @@ specification_version: 2
|
|
73
73
|
summary: Generates CSS using Ruby, like Markaby
|
74
74
|
test_files:
|
75
75
|
- test/basics.rb
|
76
|
+
- test/benchmark_for_fun.rb
|
76
77
|
- test/helper.rb
|