automatthew-casuistry 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/casuistry.gemspec CHANGED
@@ -1,14 +1,14 @@
1
1
 
2
- # Gem::Specification for Casuistry-0.1.1
2
+ # Gem::Specification for Casuistry-0.2.0
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.1.1"
7
+ s.version = "0.2.0"
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-07}
11
+ s.date = %q{2008-07-08}
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"]
@@ -40,7 +40,7 @@ end
40
40
  # require dep
41
41
  # end
42
42
  #
43
- # Version = '0.1.1'
43
+ # Version = '0.2.0'
44
44
  #
45
45
  # task :default => [:test]
46
46
  #
data/lib/casuistry.rb CHANGED
@@ -8,20 +8,23 @@ class Casuistry
8
8
 
9
9
  attr_reader :data, :assigns
10
10
 
11
- def self.process(file)
12
- cssy = File.read(file)
13
- c = self.new
14
- c.process(cssy)
15
- c
11
+ def self.process(*args,&block)
12
+ self.new.process(*args,&block)
16
13
  end
17
-
18
- def process(string)
19
- self.instance_eval(string)
20
- end
21
-
14
+
22
15
  def initialize(selector=nil)
23
16
  @selector = selector
24
17
  @data = []
18
+
19
+ end
20
+
21
+ def process(*args, &block)
22
+ if block
23
+ Selector.new(@selector, self).instance_eval(&block)
24
+ else
25
+ Selector.new(@selector, self).instance_eval(args.join("\n"))
26
+ end
27
+ @data
25
28
  end
26
29
 
27
30
  def output
@@ -34,46 +37,110 @@ class Casuistry
34
37
  output
35
38
  end
36
39
 
37
- def selector_eval(*args, &block)
38
- selector = args.compact.join(" ")
39
- Selector.new(selector, self).instance_eval(&block)
40
- end
40
+ end
41
41
 
42
+ class Selector
42
43
 
43
- def selectify(method_name)
44
- matches = method_name.to_s.match( /([\w_]+)!$/)
45
- matches ? "##{matches[1]}" : ".#{method_name}"
44
+ def initialize(base_selector, casuist)
45
+ @selectors = [ base_selector ]
46
+ @properties = []
47
+ @casuist = casuist
48
+ # possible states are :closed_block, :chaining, :open_block
49
+ @state = :closed_block
46
50
  end
47
51
 
48
- def method_missing(name, &block)
49
- selector = selectify(name)
50
- if block
51
- selector_eval(@selector, selector, &block)
52
+
53
+ # transitions
54
+ def open_block(new_selector)
55
+ case @state
56
+ when :closed_block, :open_block
57
+ combined_selector = [current_selector, new_selector].compact.join(" ")
58
+ @selectors.push combined_selector
59
+ open_properties
60
+ when :chaining
61
+ # puts current_selector, new_selector
62
+ @selectors[-1] = "#{current_selector}#{new_selector}"
63
+ open_properties
52
64
  else
53
- x = [@selector, selector].compact.join(' ')
54
- Selector.new(x, self)
65
+ raise "You can't get to :open_block from #{@state.inspect}"
55
66
  end
67
+ @state = :open_block
56
68
  end
57
69
 
58
- end
59
-
60
- class Selector
61
- include Tags
62
- def initialize(base_selector, casuist)
63
- @selector = base_selector
64
- @casuist = casuist
70
+ def chaining(new_selector)
71
+ case @state
72
+ when :closed_block, :open_block
73
+ combined_selector = [current_selector, new_selector].compact.join(" ")
74
+ @selectors.push( combined_selector)
75
+ when :chaining
76
+ @selectors[-1] = "#{current_selector}#{new_selector}"
77
+ else
78
+ raise "You can't get to :chaining from #{@state.inspect}"
79
+ end
80
+ @state = :chaining
65
81
  end
66
-
67
82
 
68
- def selector_eval(*args, &block)
69
- selector = args.compact.join(" ")
70
- if block
71
- Selector.new(selector, @casuist).instance_eval(&block)
83
+ def closed_block
84
+ case @state
85
+ when :open_block, :closed_block
86
+ @selectors.pop
87
+ @properties.pop
72
88
  else
73
- Selector.new(selector, @casuist)
89
+ raise "You can't get to :closed_block from #{@state.inspect}"
74
90
  end
91
+ @state = :closed_block
75
92
  end
76
93
 
94
+
95
+ # methods
96
+
97
+ def selector_eval(sel)
98
+ if block_given?
99
+ open_block(sel)
100
+ yield
101
+ closed_block
102
+ else
103
+ chaining(sel)
104
+ end
105
+ self
106
+ end
107
+
108
+ def method_missing(name, &block)
109
+ sel = selectify(name)
110
+ if block_given?
111
+ open_block(sel)
112
+ yield
113
+ closed_block
114
+ else
115
+ chaining(sel)
116
+ end
117
+ self
118
+ end
119
+
120
+ def current_selector
121
+ @selectors[-1]
122
+ end
123
+
124
+ def current_properties
125
+ @properties[-1]
126
+ end
127
+
128
+ def open_properties
129
+ @properties.push []
130
+ @casuist.data << [current_selector, current_properties ]
131
+ end
132
+
133
+ # define tag methods to delegate to selector_eval
134
+ methods = Tags::HTML_TAGS.map do |tag|
135
+ <<-METHOD
136
+ def #{tag}(&block)
137
+ selector_eval('#{tag}', &block)
138
+ end
139
+ METHOD
140
+ end.join
141
+
142
+ module_eval methods
143
+
77
144
  CSS_PROPERTIES.each do |method_name|
78
145
  define_method method_name do |*args|
79
146
  css_attr = method_name.gsub('_', '-')
@@ -81,34 +148,20 @@ class Selector
81
148
  end
82
149
  end
83
150
 
84
- def properties
85
- if @properties
86
- return @properties
87
- else
88
- @properties ||= []
89
- @casuist.data << [@selector, @properties]
90
- @properties
91
- end
92
- end
151
+
93
152
 
94
153
  def property(css_attr, *args)
95
- properties << "#{css_attr}: #{args.join(' ')};"
154
+ current_properties << "#{css_attr}: #{args.join(' ')};"
96
155
  end
97
156
 
157
+
158
+
159
+
98
160
  def selectify(method_name)
99
161
  matches = method_name.to_s.match( /([\w_]+)!$/)
100
162
  matches ? "##{matches[1]}" : ".#{method_name}"
101
163
  end
102
-
103
- def method_missing(name, &block)
104
- selector = selectify(name)
105
- if block
106
- selector_eval(@selector, selector, &block)
107
- else
108
- x = [@selector, selector].join(' ')
109
- Selector.new(x, @casuist)
110
- end
111
- end
164
+
112
165
 
113
166
  end
114
167
 
data/lib/properties.rb CHANGED
@@ -50,7 +50,10 @@ list_style_image
50
50
  list_style_position
51
51
  list_style_type
52
52
  margin
53
+ margin_left
53
54
  margin_top
55
+ margin_right
56
+ margin_bottom
54
57
  marker_offset
55
58
  marks
56
59
  max_height
@@ -64,7 +67,10 @@ outline_style
64
67
  outline_width
65
68
  overflow
66
69
  padding
70
+ padding_left
67
71
  padding_top
72
+ padding_right
73
+ padding_bottom
68
74
  page
69
75
  page_break_after
70
76
  page_break_before
data/lib/tags.rb CHANGED
@@ -81,7 +81,7 @@ module Tags
81
81
 
82
82
  # define tag methods to delegate to selector_eval
83
83
  methods = HTML_TAGS.map do |tag|
84
- "def #{tag}(&block); selector_eval(@selector, '#{tag}', &block);end\n"
84
+ "def #{tag}(&block); selector_eval(@selector.first, '#{tag}', &block);end\n"
85
85
  end.join
86
86
 
87
87
  module_eval methods
data/test/basics.rb CHANGED
@@ -3,73 +3,104 @@ require "#{here}/helper"
3
3
 
4
4
  describe "Casuistry" do
5
5
 
6
- before do
7
- @string = File.read("test.css")
8
- @data = [
9
- [ '.class_name1 .class_name2 .class_name3',
10
- [ 'font-size: 2em;', 'line-height: 3em;', 'border: 1px solid blue;']],
11
- [ '#milk',
12
- ['background-color: blue;', 'border: 1px solid red']]
6
+ it "can nest blocks" do
7
+ proc = lambda do
8
+ div do
9
+ form { width "35px" }
10
+ ul do
11
+ li { background :red }
12
+ end
13
+ end
14
+ end
15
+
16
+ data = [
17
+ ["div", []],
18
+ ["div form", ["width: 35px;"]],
19
+ ["div ul", []],
20
+ ["div ul li", ["background: red;"]]
13
21
  ]
14
- @data2 = [
15
- [ '#header', ['width: 500px;'] ],
16
- [ '#header #menu', ['background: gray;']]
22
+ Cssy.process(&proc).should == data
23
+ end
24
+
25
+ it "can chain blocks" do
26
+ proc = lambda do
27
+ p.smurf { color :blue }
28
+ p.gnome.hat { color :red }
29
+ end
30
+
31
+ data = [
32
+ ["p.smurf", [ "color: blue;"]],
33
+ ["p.gnome.hat", ["color: red;"]]
17
34
  ]
35
+ Cssy.process(&proc).should == data
36
+ end
37
+
38
+ it "can nest and chain" do
39
+ proc = lambda do
40
+ div do
41
+ span.ugly { font_family "Arial" }
42
+ end
43
+ end
18
44
 
19
- @data3 = [
20
- ["ul", ["background: red;", "width: 134px;"]],
21
- ["ul li .ugly", ["color: green;"]],
22
- ["ul .smurf .house", ["height: 256px;"]],
23
- ["ul #asrael", ["padding: 10px;"]],
24
- [".gargamel", ["margin: 0px;"]],
25
- [".outer .middle .inner", ["top: 34px;"]]
45
+ data = [
46
+ ["div", []],
47
+ ["div span.ugly", ["font-family: Arial;"]]
26
48
  ]
49
+ Cssy.process(&proc).should == data
50
+ end
51
+
52
+ it "can chain and nest" do
53
+ proc = lambda do
54
+ ul.monkey do
55
+ li { list_style :none }
56
+ end
57
+ end
27
58
 
28
- @css1 = <<-CSS
29
- ul
30
- {
31
- background: red;
32
- width: 134px;
33
- }
34
- ul li .ugly
35
- {
36
- color: green;
37
- }
38
- ul .smurf .house
39
- {
40
- height: 256px;
41
- }
42
- ul #asrael
43
- {
44
- padding: 10px;
45
- }
46
- .gargamel
47
- {
48
- margin: 0px;
49
- }
50
- .outer .middle .inner
51
- {
52
- top: 34px;
53
- }
54
- CSS
59
+ data = [
60
+ ["ul.monkey", []],
61
+ ["ul.monkey li", ["list-style: none;"]]
62
+ ]
63
+ Cssy.process(&proc).should == data
55
64
  end
56
-
57
-
58
- it "interprets unknown ! methods as ids and others as classes" do
59
- c = Casuistry.new
60
- c.selectify("smurf!").should == "#smurf"
61
- c.selectify("smurf").should == ".smurf"
65
+
66
+ it "can chain and nest and chain and ..." do
67
+ proc = lambda do
68
+ div do
69
+ div.milk!.toast do
70
+ p.jam { margin :auto }
71
+ hr { background :green }
72
+ end
73
+
74
+ p { border :none }
75
+ end
76
+ end
77
+
78
+ data = [
79
+ ["div", []],
80
+ ["div div#milk.toast", []],
81
+ ["div div#milk.toast p.jam", ["margin: auto;"]],
82
+ ["div div#milk.toast hr", ["background: green;"]],
83
+ ["div p", ["border: none;"]]
84
+ ]
85
+ Cssy.process(&proc).should == data
62
86
  end
63
87
 
64
- it "processes cssy code" do
65
- c = Casuistry.new
66
- c.instance_eval do
67
- @background = "red"
68
- end
69
- c.process(File.read( "#{here}/fiddle.cssy"))
70
- c.data.should == @data3
71
- c.output.should == @css1
88
+
89
+ it "processes strings" do
90
+ fiddle = [
91
+ ["ul", ["background: red;"]],
92
+ ["ul li", ["color: green;"]],
93
+ ["ul p.ugly", ["color: aqua;"]],
94
+ ["ul .smurf.house", ["height: 256px;"]],
95
+ ["ul #asrael", ["padding: 10px;"]],
96
+ [".gargamel", ["margin: 0px;"]],
97
+ [".outer.middle.inner", ["top: 34px;"]]
98
+ ]
99
+ c = Cssy.process(File.read( "#{here}/fiddle.cssy"))
100
+ c.should == fiddle
101
+ # c.output.should == File.read( "#{here}/fiddle.css")
72
102
  end
73
103
 
74
104
 
105
+
75
106
  end
data/test/dan.css CHANGED
@@ -1,58 +1,40 @@
1
- /* reset.css */
2
- @import url( /stylesheets/main.css );
3
- @import url( /stylesheets/products.css );
4
-
5
- #intro_text a.back {
6
- padding: 0 0 2px 25px;
7
- font-weight: bold;
8
- background: url("/images/icons-back.gif") 0 0 no-repeat;
9
- }
10
- div.wizard { margin-right: 8px; float: left; }
1
+ #content form ul.properties li.property hr { display: block; clear: left; float: none; height: 0; visibility: hidden; margin: -0.66em; padding: 0; }
2
+
3
+ #intro_text a.back{padding:0 0 2px 25px;font-weight:bold;background:url("/images/icons-back.gif") 0 0 no-repeat;}
4
+
5
+
6
+ div.ac_results { border: 1px solid silver; text-align: left; background-color: white; color: gray; padding: 5px; margin-top: -8px; }
7
+
8
+ div.preview { float: left ; height: 400px; }
9
+ div.preview iframe { border: none; display: block; position: relative; width: 490px; height: 340px; border: 1px solid silver; margin: 4px; padding: 30px 0; }
10
+
11
+ div.radio div.option, div.checkbox div.option { cursor: pointer; }
12
+
13
+ div.tab-selector span{color:gray;font-size:11px;text-align:center;display:block;float:left;height:26px;width:129px;padding:12px 8px 0px 8px;background:url( /images/tab/unselected.gif ) repeat-x;cursor:pointer;}
14
+ div.tab-selector span.selected{font-weight:bold;color:black;background:url( /images/tab/selected.gif ) repeat-x;}
15
+
16
+ div.text.value { margin-top: -4px; }
17
+ div.text.value input { height: 23px; width: 220px; border: none; background: url( /images/textfield_bg.gif) no-repeat;padding: 4px; font-size: 11px; font-weight: bold; color: gray; }
18
+ div.text.value textarea { width: 280px; height: 184px; font-size: 11px; color: gray; }
11
19
 
20
+ div.wizard { margin-right: 8px; float: left; }
21
+ form div.value { float: left; color: gray; }
22
+ form label { float: left; display: block; width: 80px; text-align: right; padding-right: 14px; color: gray; font-weight: bold; font-size: 13px; }
12
23
  form ul.properties { display: block; margin: 0; padding: 0; clear: both; }
24
+ img.title { padding-bottom: 8px; }
25
+
13
26
  li.property { display: block; list-style-type: none; clear: both; padding-bottom: 40px; }
14
- #content form ul.properties li.property hr { display: block; clear: left; float: none; height: 0; visibility: hidden; margin: -0.66em; padding: 0; }
15
- form label { float: left; display: block; width: 80px; text-align: right; padding-right: 14px; color: gray; font-weight: bold; font-size: 13px; }
16
- form div.value { float: left; color: gray; }
17
- div.radio div.option, div.checkbox div.option { cursor: pointer; }
27
+ li.code.property { display: none; }
28
+
18
29
  li.size div.option { background: url( /images/bt_radio_off.gif) no-repeat; padding-left: 17px; height: 21px; font-size: 13px; }
19
30
  li.size div.option.selected { background: url( /images/bt_radio_on.gif) no-repeat; padding-left: 17px; height: 21px; font-size: 13px; }
31
+
20
32
  li.style div.option { float: left; border: 1px solid silver; padding: 1px; margin-left: 4px; opacity: 0.5; }
21
33
  li.style div.option.hover, li.style div.option.selected { border: 1px solid gray; }
22
34
  li.style div.option.selected { opacity: 1.0; }
23
- li.tos div.option { background: url( /images/checkbox.gif ) no-repeat; padding-left: 17px; }
24
- li.code.property { display: none; }
25
- div.text.value { margin-top: -4px; }
26
- div.text.value input { height: 23px; width: 220px; border: none; background: url( /images/textfield_bg.gif) no-repeat;
27
- padding: 4px; font-size: 11px; font-weight: bold; color: gray; }
28
- div.text.value textarea { width: 280px; height: 184px; font-size: 11px; color: gray; }
29
- div.preview { float: left ; height: 400px; }
30
- div.preview iframe { border: none; display: block; position: relative; width: 490px; height: 340px; border: 1px solid silver; margin: 4px; padding: 30px 0; }
31
-
32
- div.ac_results { border: 1px solid silver; text-align: left; background-color: white; color: gray; padding: 5px; margin-top: -8px; }
33
35
 
34
- img.title { padding-bottom: 8px; }
36
+ li.tos div.option { background: url( /images/checkbox.gif ) no-repeat; padding-left: 17px; }
35
37
 
36
38
  ul.steps { display: block; margin: 0; padding: 0; clear: both; }
37
-
38
- ul.steps li.step {
39
- display: none; width: 403px; height: 335px;
40
- margin-left: 2px; padding: 16px;
41
- list-style-type: none;
42
- border: 1px solid silver;
43
- }
44
- u.steps li.step.selected { display: block; }
45
-
46
- div.tab-selector span {
47
- color: gray;
48
- font-size: 11px; text-align: center;
49
- display: block; float: left; height: 26px; width: 129px; padding: 12px 8px 0px 8px;
50
- background: url( /images/tab/unselected.gif ) repeat-x; cursor: pointer;
51
- }
52
-
53
- div.tab-selector span.selected {
54
- /* border-right: 1px solid gray; border-left: 1px solid gray; border-top: 1px solid silver; */
55
- font-weight: bold; color: black;
56
- background: url( /images/tab/selected.gif ) repeat-x;
57
- }
58
-
39
+ ul.steps li.step{display:none;width:403px;height:335px;margin-left:2px;padding:16px;list-style-type:none;border:1px solid silver;}
40
+ ul.steps li.step.selected { display: block; }
data/test/fiddle.cssy CHANGED
@@ -1,11 +1,15 @@
1
- favorite = 'green'
1
+ # favorite = 'green'
2
2
 
3
3
  ul do
4
4
 
5
5
  background('red')
6
6
 
7
- li.ugly do
8
- color(favorite)
7
+ li do
8
+ color('green')
9
+ end
10
+
11
+ p.ugly do
12
+ color('aqua')
9
13
  end
10
14
 
11
15
  smurf.house do
@@ -16,7 +20,7 @@ ul do
16
20
  padding("10px")
17
21
  end
18
22
 
19
- width('134px')
23
+ # width('9934px')
20
24
 
21
25
  end
22
26
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: automatthew-casuistry
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
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-07 00:00:00 -07:00
12
+ date: 2008-07-08 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies: []
15
15