style_train 0.1.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.
@@ -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