style_train 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,192 @@
1
+ module StyleTrain
2
+ class KeywordColor < ColorType
3
+ class KeywordError < ArgumentError
4
+ def message
5
+ @message ||= 'Keyword not found'
6
+ end
7
+ end
8
+
9
+ KEYWORD_MAP = {
10
+ :aliceblue => [240, 248, 255],
11
+ :antiquewhite => [250, 235, 215],
12
+ :aqua => [0, 255, 255],
13
+ :aquamarine => [127, 255, 212],
14
+ :azure => [240, 255, 255],
15
+ :beige => [245, 245, 220],
16
+ :bisque => [255, 228, 196],
17
+ :black => [0, 0, 0],
18
+ :blanchedalmond => [255, 235, 205],
19
+ :blue => [0, 0, 255],
20
+ :blueviolet => [138, 43, 226],
21
+ :brown => [165, 42, 42],
22
+ :burlywood => [222, 184, 135],
23
+ :cadetblue => [95, 158, 160],
24
+ :chartreuse => [127, 255, 0],
25
+ :chocolate => [210, 105, 30],
26
+ :coral => [255, 127, 80],
27
+ :cornflowerblue => [100, 149, 237],
28
+ :cornsilk => [255, 248, 220],
29
+ :crimson => [220, 20, 60],
30
+ :cyan => [0, 255, 255],
31
+ :darkblue => [0, 0, 139],
32
+ :darkcyan => [0, 139, 139],
33
+ :darkgoldenrod => [184, 134, 11],
34
+ :darkgray => [169, 169, 169],
35
+ :darkgreen => [0, 100, 0],
36
+ :darkgrey => [169, 169, 169],
37
+ :darkkhaki => [189, 183, 107],
38
+ :darkmagenta => [139, 0, 139],
39
+ :darkolivegreen => [85, 107, 47],
40
+ :darkorange => [255, 140, 0],
41
+ :darkorchid => [153, 50, 204],
42
+ :darkred => [139, 0, 0],
43
+ :darksalmon => [233, 150, 122],
44
+ :darkseagreen => [143, 188, 143],
45
+ :darkslateblue => [72, 61, 139],
46
+ :darkslategray => [47, 79, 79],
47
+ :darkslategrey => [47, 79, 79],
48
+ :darkturquoise => [0, 206, 209],
49
+ :darkviolet => [148, 0, 211],
50
+ :deeppink => [255, 20, 147],
51
+ :deepskyblue => [0, 191, 255],
52
+ :dimgray => [105, 105, 105],
53
+ :dimgrey => [105, 105, 105],
54
+ :dodgerblue => [30, 144, 255],
55
+ :firebrick => [178, 34, 34],
56
+ :floralwhite => [255, 250, 240],
57
+ :forestgreen => [34, 139, 34],
58
+ :fuchsia => [255, 0, 255],
59
+ :gainsboro => [220, 220, 220],
60
+ :ghostwhite => [248, 248, 255],
61
+ :gold => [255, 215, 0],
62
+ :goldenrod => [218, 165, 32],
63
+ :gray => [128, 128, 128],
64
+ :green => [0, 128, 0],
65
+ :greenyellow => [173, 255, 47],
66
+ :grey => [128, 128, 128],
67
+ :honeydew => [240, 255, 240],
68
+ :hotpink => [255, 105, 180],
69
+ :indianred => [205, 92, 92],
70
+ :indigo => [75, 0, 130],
71
+ :ivory => [255, 255, 240],
72
+ :khaki => [240, 230, 140],
73
+ :lavender => [230, 230, 250],
74
+ :lavenderblush => [255, 240, 245],
75
+ :lawngreen => [124, 252, 0],
76
+ :lemonchiffon => [255, 250, 205],
77
+ :lightblue => [173, 216, 230],
78
+ :lightcoral => [240, 128, 128],
79
+ :lightcyan => [224, 255, 255],
80
+ :lightgoldenrodyellow => [250, 250, 210],
81
+ :lightgray => [211, 211, 211],
82
+ :lightgreen => [144, 238, 144],
83
+ :lightgrey => [211, 211, 211],
84
+ :lightpink => [255, 182, 193],
85
+ :lightsalmon => [255, 160, 122],
86
+ :lightseagreen => [32, 178, 170],
87
+ :lightskyblue => [135, 206, 250],
88
+ :lightslategray => [119, 136, 153],
89
+ :lightslategrey => [119, 136, 153],
90
+ :lightsteelblue => [176, 196, 222],
91
+ :lightyellow => [255, 255, 224],
92
+ :lime => [0, 255, 0],
93
+ :limegreen => [50, 205, 50],
94
+ :linen => [250, 240, 230],
95
+ :magenta => [255, 0, 255],
96
+ :maroon => [128, 0, 0],
97
+ :mediumaquamarine => [102, 205, 170],
98
+ :mediumblue => [0, 0, 205],
99
+ :mediumorchid => [186, 85, 211],
100
+ :mediumpurple => [147, 112, 219],
101
+ :mediumseagreen => [60, 179, 113],
102
+ :mediumslateblue => [123, 104, 238],
103
+ :mediumspringgreen => [0, 250, 154],
104
+ :mediumturquoise => [72, 209, 204],
105
+ :mediumvioletred => [199, 21, 133],
106
+ :midnightblue => [25, 25, 112],
107
+ :mintcream => [245, 255, 250],
108
+ :mistyrose => [255, 228, 225],
109
+ :moccasin => [255, 228, 181],
110
+ :navajowhite => [255, 222, 173],
111
+ :navy => [0, 0, 128],
112
+ :oldlace => [253, 245, 230],
113
+ :olive => [128, 128, 0],
114
+ :olivedrab => [107, 142, 35],
115
+ :orange => [255, 165, 0],
116
+ :orangered => [255, 69, 0],
117
+ :orchid => [218, 112, 214],
118
+ :palegoldenrod => [238, 232, 170],
119
+ :palegreen => [152, 251, 152],
120
+ :paleturquoise => [175, 238, 238],
121
+ :palevioletred => [219, 112, 147],
122
+ :papayawhip => [255, 239, 213],
123
+ :peachpuff => [255, 218, 185],
124
+ :peru => [205, 133, 63],
125
+ :pink => [255, 192, 203],
126
+ :plum => [221, 160, 221],
127
+ :powderblue => [176, 224, 230],
128
+ :purple => [128, 0, 128],
129
+ :red => [255, 0, 0],
130
+ :rosybrown => [188, 143, 143],
131
+ :royalblue => [65, 105, 225],
132
+ :saddlebrown => [139, 69, 19],
133
+ :salmon => [250, 128, 114],
134
+ :sandybrown => [244, 164, 96],
135
+ :seagreen => [46, 139, 87],
136
+ :seashell => [255, 245, 238],
137
+ :sienna => [160, 82, 45],
138
+ :silver => [192, 192, 192],
139
+ :skyblue => [135, 206, 235],
140
+ :slateblue => [106, 90, 205],
141
+ :slategray => [112, 128, 144],
142
+ :slategrey => [112, 128, 144],
143
+ :snow => [255, 250, 250],
144
+ :springgreen => [0, 255, 127],
145
+ :steelblue => [70, 130, 180],
146
+ :tan => [210, 180, 140],
147
+ :teal => [0, 128, 128],
148
+ :thistle => [216, 191, 216],
149
+ :tomato => [255, 99, 71],
150
+ :turquoise => [64, 224, 208],
151
+ :violet => [238, 130, 238],
152
+ :wheat => [245, 222, 179],
153
+ :white => [255, 255, 255],
154
+ :whitesmoke => [245, 245, 245],
155
+ :yellow => [255, 255, 0],
156
+ :yellowgreen => [154, 205, 50],
157
+
158
+ }
159
+
160
+ attr_reader :keyword
161
+
162
+ def keyword=( color )
163
+ color = color.to_sym
164
+ raise KeywordError, "'#{color}' not found" unless KEYWORD_MAP.keys.include?( color )
165
+ @keyword = color.to_sym
166
+ mapped = KEYWORD_MAP[color]
167
+ self.r = mapped[0]
168
+ self.g = mapped[1]
169
+ self.b = mapped[2]
170
+ end
171
+
172
+ def type_initialize( color, opts )
173
+ self.keyword = color
174
+ end
175
+
176
+ def build
177
+ # TODO: map to closest color instead of throwing an error
178
+ found = false
179
+ KEYWORD_MAP.each do |keyword, rgb|
180
+ if self.r == rgb[0] && self.g == rgb[1] && self.b == rgb[2]
181
+ found = true
182
+ self.keyword = keyword
183
+ end
184
+ end
185
+ raise KeywordError, "Keyword match not found for color matching rgb( #{self.r}, #{self.g}, #{self.b} )" unless found
186
+ end
187
+
188
+ def render_as_given
189
+ self.keyword.to_s
190
+ end
191
+ end
192
+ end
@@ -0,0 +1,57 @@
1
+ module StyleTrain
2
+ class RGBcolor < ColorType
3
+ attr_reader :red, :green, :blue # these are the entered values, not the calculated values
4
+
5
+ METHOD_MAP ={
6
+ 'r' => 'red',
7
+ 'g' => 'green',
8
+ 'b' => 'blue'
9
+ }
10
+
11
+ ['red', 'green', 'blue'].each do |clr|
12
+ class_eval "
13
+ def #{clr}=( value )
14
+ @#{clr} = value
15
+ self.#{clr[0..0]} = value
16
+ end
17
+ "
18
+ end
19
+
20
+ ['r', 'g', 'b'].each do |clr|
21
+ class_eval "
22
+ def #{clr}=( value )
23
+ @#{clr} = normalize_internal_rgb( value )
24
+ end
25
+ "
26
+ end
27
+
28
+ def type_initialize( color, opts )
29
+ if color.is_a? Array
30
+ self.red = color[0]
31
+ self.green = color[1]
32
+ self.blue = color[2]
33
+ else
34
+ raise ArgumentError, 'RGB color must be initialized with a :color opts argument that is an array' unless color && color.class == Array
35
+ end
36
+ end
37
+
38
+ def build
39
+ self.red = self.r
40
+ self.green = self.g
41
+ self.blue = self.b
42
+ end
43
+
44
+ def normalize_internal_rgb( value )
45
+ if percentage = self.class.percentage( value )
46
+ percentage = value.to_i
47
+ self.class.percent_to_byte( percentage )
48
+ else
49
+ value.to_i if self.class.valid_byte?( value, true )
50
+ end
51
+ end
52
+
53
+ def render_as_given
54
+ "rgb( #{self.red}, #{self.green}, #{self.blue} )"
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,234 @@
1
+ module StyleTrain
2
+ class Sheet
3
+ attr_accessor :output, :indent_level
4
+
5
+ def initialize(opts={})
6
+ self.output = ''
7
+ self.indent_level = 0
8
+ end
9
+
10
+ def render render_method = :content
11
+ self.output = ''
12
+ if render_method == :content
13
+ content
14
+ else
15
+ send render_method
16
+ end
17
+ output
18
+ end
19
+
20
+ def style(selector)
21
+ self.output << "\n"
22
+ if selector.is_a?(String) || TAGS.include?(selector)
23
+ self.output << "#{selector}"
24
+ else
25
+ self.output << ".#{selector}"
26
+ end
27
+ self.output << " {"
28
+ if block_given?
29
+ self.indent_level += 2
30
+ yield
31
+ self.indent_level -= 2
32
+ end
33
+ self.output << "\n}\n"
34
+ end
35
+
36
+ TAGS = [
37
+ :a, :abbr, :acronym, :address, :area, :b, :base, :bdo,
38
+ :big, :blockquote, :body, :br, :button, :caption, :center,
39
+ :cite, :code, :col, :colgroup, :dd, :del, :dfn, :div,
40
+ :dl, :dt, :em, :embed, :fieldset, :form, :frame, :frameset,
41
+ :h1, :h2, :h3, :h4, :h5, :h6, :head, :hr, :html, :i, :iframe,
42
+ :img, :input, :ins, :kbd, :label, :legend, :li, :link,
43
+ :map, :meta, :noframes, :noscript, :object, :ol, :optgroup,
44
+ :option, :p, :param, :pre, :q, :s, :samp, :script, :select,
45
+ :small, :span, :strike, :strong, :sub, :sup, :table,
46
+ :tbody, :td, :textarea, :tfoot, :th, :thead, :title,
47
+ :tr, :tt, :u, :ul, :var
48
+ ]
49
+
50
+ TAGS.each do |tag|
51
+ class_eval <<-RUBY
52
+ def #{tag} &block
53
+ style( '#{tag}', &block )
54
+ end
55
+ RUBY
56
+ end
57
+
58
+ def indent
59
+ " " * indent_level
60
+ end
61
+
62
+ def property( label, value )
63
+ value = value.join(' ') if value.is_a?(Array)
64
+ self.output << "\n#{indent}#{label}: #{value};"
65
+ end
66
+
67
+ def background( opts )
68
+ str = ""
69
+ str << property('background-color', Color.new(opts[:color])) if opts[:color]
70
+ str << property('background-image', opts[:image]) if opts[:image]
71
+ str << property('background-position', opts[:position]) if opts[:position]
72
+ str << property('background-attachment', opts[:attachment]) if opts[:attachment]
73
+ str << property('background-repeat', background_repeat_value(opts[:repeat])) if opts[:repeat]
74
+ str
75
+ end
76
+
77
+ def background_repeat_value(value)
78
+ value = value.to_sym
79
+ if value == :x || value == :y
80
+ "repeat-#{value}"
81
+ else
82
+ value
83
+ end
84
+ end
85
+
86
+ def border(opts={})
87
+ value = border_value(opts)
88
+ if only = opts[:only]
89
+ if only.is_a?(Array)
90
+ str = ""
91
+ only.each do |type|
92
+ str << property( "border-#{type}", value )
93
+ end
94
+ str
95
+ else
96
+ property "border-#{only}", value
97
+ end
98
+ else
99
+ property "border", value
100
+ end
101
+ end
102
+
103
+ def border_value(opts)
104
+ color = opts[:color] || 'black'
105
+ style = opts[:style] || 'solid'
106
+ width = opts[:width] || '1px'
107
+ "#{width} #{style} #{color}"
108
+ end
109
+
110
+ def outline(opts={})
111
+ value = border_value(opts)
112
+ property "outline", value
113
+ end
114
+
115
+ def text(opts)
116
+ str = ""
117
+ str << property('font-family', opts[:font]) if opts[:font]
118
+ str << property('font-weight', opts[:weight]) if opts[:weight]
119
+ str << property('font-variant', opts[:variant]) if opts[:variant]
120
+ str << property('font-style', opts[:style]) if opts[:style]
121
+ str << property('font-size', opts[:size]) if opts[:size]
122
+ str << property('color', opts[:color]) if opts[:color]
123
+ str << property('text-direction', opts[:direction]) if opts[:direction]
124
+ str << property('letter-spacing', opts[:spacing]) if opts[:spacing]
125
+ str << property('line-height', opts[:line_height]) if opts[:line_height]
126
+ str << property('text-align', opts[:align]) if opts[:align]
127
+ str << property('text-decoration', opts[:decoration]) if opts[:decoration]
128
+ str << property('text-indent', opts[:indent]) if opts[:indent]
129
+ str << property('text-transform', opts[:transform]) if opts[:transform]
130
+ str << property('vertical-align', opts[:vertical_align]) if opts[:vertical_align]
131
+ str << property('white-space', opts[:white_space]) if opts[:white_space]
132
+ str << property('word-spacing', opts[:word_spacing]) if opts[:word_spacing]
133
+ str
134
+ end
135
+
136
+ def list(opts)
137
+ str = ""
138
+ str << property('list-style-image', opts[:image]) if opts[:image]
139
+ str << property('list-style-type', opts[:type]) if opts[:type]
140
+ str << property('list-style-position', opts[:position]) if opts[:position]
141
+ str
142
+ end
143
+
144
+ def margin(opts)
145
+ if opts.is_a?(Array)
146
+ property('margin', opts)
147
+ else
148
+ str = ""
149
+ str << property('margin-left', opts[:left]) if opts[:left]
150
+ str << property('margin-top', opts[:top]) if opts[:top]
151
+ str << property('margin-bottom', opts[:bottom]) if opts[:bottom]
152
+ str << property('margin-right', opts[:right]) if opts[:right]
153
+ str
154
+ end
155
+ end
156
+
157
+ def padding(opts)
158
+ if opts.is_a?(Array)
159
+ property('padding', opts)
160
+ else
161
+ str = ""
162
+ str << property('padding-left', opts[:left]) if opts[:left]
163
+ str << property('padding-top', opts[:top]) if opts[:top]
164
+ str << property('padding-bottom', opts[:bottom]) if opts[:bottom]
165
+ str << property('padding-right', opts[:right]) if opts[:right]
166
+ str
167
+ end
168
+ end
169
+
170
+ def position(opts)
171
+ if opts.is_a?(Hash)
172
+ str = ""
173
+ str << property('position', opts[:type]) if opts[:type]
174
+ str << property('bottom', opts[:bottom]) if opts[:bottom]
175
+ str << property('top', opts[:top]) if opts[:top]
176
+ str << property('left', opts[:left]) if opts[:left]
177
+ str << property('right', opts[:right]) if opts[:right]
178
+ str << property('float', opts[:float]) if opts[:float]
179
+ str << property('clear', opts[:clear]) if opts[:clear]
180
+ str << property('display', opts[:display]) if opts[:display]
181
+ str << property('visibility', opts[:visibility]) if opts[:visibility]
182
+ str << property('z-index', opts[:z_index]) if opts[:z_index]
183
+ str << property('overflow', opts[:overflow]) if opts[:overflow]
184
+ str << property('overflow-x', opts[:overflow_x]) if opts[:overflow_x]
185
+ str << property('overflow-y', opts[:overflow_y]) if opts[:overflow_y]
186
+ str << property('clip', "rect(#{opts[:clip].join(' ')})") if opts[:clip]
187
+ str
188
+ else
189
+ property('position', opts)
190
+ end
191
+ end
192
+
193
+ def table_options(opts)
194
+ str = ""
195
+ str << property('border-collapse', opts[:border]) if opts[:border]
196
+ str << property('border-spacing', opts[:border_spacing]) if opts[:border_spacing]
197
+ str << property('caption-side', opts[:caption]) if opts[:caption]
198
+ str << property('empty-cells', opts[:empty]) if opts[:empty]
199
+ str << property('table-layout', opts[:layout]) if opts[:layout]
200
+ str
201
+ end
202
+
203
+ def overflow(opts)
204
+ if opts.is_a?(Hash)
205
+ str = ""
206
+ str << property( 'overflow-x', opts[:x]) if opts[:x]
207
+ str << property( 'overflow-y', opts[:y]) if opts[:y]
208
+ str
209
+ else
210
+ property 'overflow', opts
211
+ end
212
+ end
213
+
214
+ [
215
+ 'color', 'display', 'float', 'clear', 'visibility', 'cursor',
216
+ 'height', 'width', 'max_height', 'max_width', 'min_height', 'min_width'
217
+ ].each do |meth|
218
+ class_eval <<-RUBY
219
+ def #{meth}(value)
220
+ property('#{meth.dasherize}', value)
221
+ end
222
+ RUBY
223
+ end
224
+
225
+
226
+ def content
227
+ # override me in subclasses
228
+ end
229
+
230
+ def self.render(render_method=:content)
231
+ new.render(render_method)
232
+ end
233
+ end
234
+ end