automatthew-casuistry 0.1.1 → 0.2.0

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/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