weby 0.0.1

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: bad3a8a500f51db0006a12a6cecaa559b4e2e61e
4
+ data.tar.gz: a15dfd9e9d8423f143c1b85fe593b27daf0e9566
5
+ SHA512:
6
+ metadata.gz: '0584d1392b70e7585fc3e60ae51291431bef8fdcc2a3cddb19ac337711e4518e325e6d7a7ed25bcb6906eabc7e67b3e0d1a05e8c8a38ed76ae277f046a3a94ff'
7
+ data.tar.gz: f98cdd4c56d9b3aee976e9362a87dacaba387dfde6dd986a995cf0afc8e3a5ab28de1052c0e3a28808bb356e2086ca3237e0d2ba81285d675f29344828e2dadc
data/.gitignore ADDED
@@ -0,0 +1,15 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
15
+ *.gem
data/GEMDESC ADDED
@@ -0,0 +1 @@
1
+ Weby has been designed to easily write web interfaces. It can be used to generate HTML code in a template based fashion or you're free to create HTML in a programmatic way, or even a mix of them.
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in weby.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,23 @@
1
+ Copyright (c) 2016-2017 Fabio Nicotra.
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are met:
6
+ * Redistributions of source code must retain the above copyright
7
+ notice, this list of conditions and the following disclaimer.
8
+ * Redistributions in binary form must reproduce the above copyright
9
+ notice, this list of conditions and the following disclaimer in the
10
+ documentation and/or other materials provided with the distribution.
11
+ * Neither the name of PsyC nor the
12
+ names of its contributors may be used to endorse or promote products
13
+ derived from this software without specific prior written permission.
14
+
15
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2016 artix
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,225 @@
1
+ # Weby
2
+
3
+ Weby lets you easily handle and generate HTML, XHTML or XML code in Ruby.
4
+ It can be used both as a templating system and as a programmatic HTML generator.
5
+ You can even mix templating and programmatic HTML, so you're free to use it as you like.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'weby'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install weby
22
+
23
+ ## Usage
24
+
25
+ Here's some example:
26
+
27
+
28
+ ```ruby
29
+ require 'rubygems'
30
+ require 'weby'
31
+
32
+ #Loading a template
33
+
34
+ html = <<EOS
35
+ <div id="main">
36
+ <h1>Hello</h1>
37
+ <ul>
38
+ <li></li>
39
+ </ul>
40
+ <select>
41
+ <option></option>
42
+ </select>
43
+ <table>
44
+ <tr>
45
+ <td></td>
46
+ </tr>
47
+ </table>
48
+ <span wby-if="num.even?">An even number</span>
49
+ <span wby-if="num.odd?">An odd number</span>
50
+ </div>
51
+ EOS
52
+
53
+ h = HTML.parse html
54
+
55
+ puts h
56
+
57
+ ```
58
+
59
+ Now let's see some evaluation feature:
60
+
61
+ ```ruby
62
+
63
+ num = 2
64
+ h.evaluate binding: binding
65
+ puts h.to_html
66
+
67
+ ```
68
+ This will output:
69
+
70
+ ```html
71
+ <div id="main">
72
+ <h1>Hello</h1>
73
+ <ul>
74
+ <li>
75
+ </ul>
76
+ <select>
77
+ <option></option>
78
+ </select>
79
+ <table>
80
+ <tr>
81
+ <td></td>
82
+ </tr>
83
+ </table>
84
+ <span>An even number</span>
85
+
86
+ </div>
87
+ ```
88
+
89
+ Now let's manipulate HTML elements:
90
+
91
+ ```ruby
92
+
93
+ h.find('#main').append {
94
+ h2{'Title'}
95
+ }
96
+ h.append {
97
+ div(id: 'body'){'World'}
98
+ }
99
+ h.find('h1').add_class 'header'
100
+ h.find('h1,h2').add_class 'title'
101
+ puts h.to_html
102
+
103
+ ```
104
+
105
+ Output:
106
+
107
+ ```html
108
+ <div id="main">
109
+ <h1 class="header title">Hello</h1>
110
+ <ul>
111
+ <li>
112
+ </ul>
113
+ <select>
114
+ <option></option>
115
+ </select>
116
+ <table>
117
+ <tr>
118
+ <td></td>
119
+ </tr>
120
+ </table>
121
+ <span>An even number</span>
122
+
123
+ <h2 class="title">Title</h2>
124
+ </div>
125
+ <div id="body">World</div>
126
+ ```
127
+
128
+ We can also use some element as a template for given data:
129
+
130
+ ```ruby
131
+ li = h.find 'ul li'
132
+ li.as_template %w(Apple Banana)
133
+ puts h
134
+ ```
135
+
136
+ Output:
137
+
138
+ ```html
139
+
140
+ ...
141
+
142
+ <ul>
143
+ <li>Apple</li>
144
+ <li>Banana</li>
145
+ </ul>
146
+
147
+ ...
148
+
149
+ ```
150
+
151
+ More complex templating:
152
+
153
+ ```ruby
154
+ o = h.find 'option'
155
+ o.as_template [
156
+ {value: '#fff', content: :white},
157
+ {value: '#000', content: :black}
158
+ ]
159
+ ```
160
+
161
+ Will produce:
162
+
163
+ ```html
164
+
165
+ ...
166
+
167
+ <select>
168
+ <option value="#fff">white</option>
169
+ <option value="#000">black</option>
170
+ </select>
171
+
172
+ ...
173
+
174
+ ```
175
+
176
+ ```ruby
177
+ tr = h.find 'tr'
178
+ tr.as_template [
179
+ {
180
+ id: 'user-1',
181
+ select: {td: {content: 'User 1'}}
182
+ },
183
+ {
184
+ id: 'user-2',
185
+ select: {td: {content: 'User 2'}}
186
+ },
187
+ ]
188
+ ```
189
+
190
+ ```html
191
+ <table>
192
+ <tr id="user-1">
193
+ <td>User 1</td>
194
+ </tr>
195
+ <tr id="user-2">
196
+ <td>User 2</td>
197
+ </tr>
198
+ </table>
199
+ ```
200
+
201
+ We can also easily manipulate style and data:
202
+
203
+ ```ruby
204
+ main = h.find '#main'
205
+ main.style :width, '800px'
206
+ main.style height: '100%', border: '1px solid'
207
+ main.data 'pageid', '1'
208
+ main.data userid: 1, username: 'admin'
209
+ ```
210
+
211
+ ```html
212
+ <div id="main" style="width: 800px; height: 100%; border: 1px solid" data-pageid="1" data-userid="10" data-username="artix">
213
+
214
+ ...
215
+
216
+ </div>
217
+ ```
218
+
219
+ ## Contributing
220
+
221
+ 1. Fork it ( https://github.com/artix75/weby/fork )
222
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
223
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
224
+ 4. Push to the branch (`git push origin my-new-feature`)
225
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
data/lib/weby/html.rb ADDED
@@ -0,0 +1,491 @@
1
+ module Weby
2
+
3
+ class HTMLException < Exception
4
+ end
5
+
6
+ class HTML
7
+
8
+ attr_accessor :node, :nodeset, :document
9
+
10
+ @@prefix = 'wby'
11
+ @@evaluation_instance = nil
12
+ @@evaluation_binding = TOPLEVEL_BINDING
13
+ @@use_cache = true
14
+ @@cache = {}
15
+ @@include_path = nil
16
+
17
+ def initialize(obj, opts = {}, &block)
18
+ @source = opts[:source]
19
+ if obj.is_a? Nokogiri::XML::Node
20
+ @node = obj
21
+ @is_doc = obj.is_a? Nokogiri::XML::Document
22
+ @is_fragm = obj.is_a? Nokogiri::XML::DocumentFragment
23
+ @document = @node if @is_doc || @is_fragm
24
+ @document ||= @node.document
25
+ elsif obj.is_a? Nokogiri::XML::NodeSet
26
+ @nodeset = obj
27
+ @node = obj[0]
28
+ elsif obj.is_a? Symbol
29
+ @document = opts[:_doc]
30
+ raise_err ':_doc option is missing' if !@document
31
+ @document = @document.document if @document.is_a?(HTML)
32
+ if !@document.is_a?(Nokogiri::XML::DocumentFragment) &&
33
+ !@document.is_a?(Nokogiri::XML::Document)
34
+ raise_err ':_doc must be Nokogiri::XML::Document[Fragment]'
35
+ end
36
+ @node = Nokogiri::XML::Element.new obj.to_s, @document
37
+ opts.delete :_doc
38
+ opts.each{|attr, val|
39
+ next if val.nil?
40
+ @node[attr] = val
41
+ }
42
+ self.exec(&block) if block_given?
43
+ elsif obj.is_a? String
44
+ if @source && @source[/\.rb$/]
45
+ @node = Nokogiri::HTML::DocumentFragment.parse ''
46
+ self.exec :append, obj
47
+ else
48
+ @node = Nokogiri::HTML::DocumentFragment.parse obj
49
+ end
50
+ @document = @node
51
+ @is_fragm = true
52
+ end
53
+ @document ||= (@nodeset || @node).document
54
+ if @@use_cache && @source
55
+ @@cache[@source] = self if !@@cache.key?(@source)
56
+ end
57
+ end
58
+
59
+ def builder
60
+ @builder ||= HTMLBuilder.new(self)
61
+ end
62
+
63
+ def exec(mode = :append, src = nil, &block)
64
+ if src
65
+ text = builder.mode(mode).instance_eval(src)
66
+ else
67
+ text = builder.mode(mode).instance_eval(&block)
68
+ end
69
+ @node.add_child text if text.is_a? String
70
+ text
71
+ end
72
+
73
+ def evaluate(opts = {})
74
+ return if !@node
75
+ _self = opts[:self] || @@evaluation_instance
76
+ _binding = opts[:binding] || @@evaluation_binding
77
+ conditional_attr = "#{@@prefix}-if"
78
+ conditionals = @node.css "*[#{conditional_attr}]"
79
+ conditionals.each{|n|
80
+ condition = n[conditional_attr]
81
+ args = [condition]
82
+ args += [@source, n.line] if @source
83
+ if _self
84
+ ok = _self.instance_eval *args
85
+ else
86
+ ok = _binding.eval *args
87
+ end
88
+ if !ok
89
+ n.remove
90
+ else
91
+ n.remove_attribute conditional_attr
92
+ end
93
+ }
94
+ imports = @node.css "#{@@prefix}-include"
95
+ imports.each{|n|
96
+ path = n['path']
97
+ if path
98
+ path = resolvepath path
99
+ if !File.exists? path
100
+ line = (@source ? n.line : nil)
101
+ raise_err "File not found: #{path}", line
102
+ end
103
+ fragm = HTML::load path
104
+ next if !fragm.node
105
+ fragm.evaluate self: _self, binding: _binding
106
+ n.after fragm.node
107
+ n.remove
108
+ end
109
+ }
110
+ end
111
+
112
+ def append(_node = nil, &block)
113
+ _node = _node.node if _node.is_a? HTML
114
+ @node.add_child _node if _node
115
+ self.exec(&block) if block_given?
116
+ self
117
+ end
118
+
119
+ def append_to(_node)
120
+ if @node
121
+ _node = _node.node if _node.is_a? HTML
122
+ _node.add_child(@node)
123
+ end
124
+ self
125
+ end
126
+
127
+ def prepend(_node = nil, &block)
128
+ _node = _node.node if _node.is_a? HTML
129
+ @node.prepend_child _node if _node
130
+ self.exec(:prepend, &block) if block_given?
131
+ self
132
+ end
133
+
134
+ def prepend_to(_node)
135
+ if @node
136
+ _node = _node.node if _node.is_a? HTML
137
+ _node.prepend_child(@node)
138
+ end
139
+ self
140
+ end
141
+
142
+ def find(selector)
143
+ self.class.new((@nodeset || @node).css(selector))
144
+ end
145
+
146
+ def children
147
+ return [] if !@node
148
+ HTML.new(@node.children)
149
+ end
150
+
151
+ def each(&block)
152
+ (@nodeset || [@node]).each &block
153
+ end
154
+
155
+ def parent
156
+ self.class.new(@node.parent) if @node
157
+ end
158
+
159
+ def next
160
+ if @node && (nxt = @node.next)
161
+ self.class.new(nxt)
162
+ end
163
+ end
164
+
165
+ def [](attr)
166
+ (@node || {})[attr]
167
+ end
168
+
169
+ def []=(attr, val)
170
+ if @node
171
+ @node[attr] = val
172
+ end
173
+ end
174
+
175
+ def inner_html
176
+ return '' if !@node
177
+ @node.inner_html
178
+ end
179
+
180
+ def inner_html=(html)
181
+ @node.inner_html = html if @node
182
+ end
183
+
184
+ def remove
185
+ (@nodeset || @node).remove
186
+ self
187
+ end
188
+
189
+ def add_class(classname)
190
+ (@nodeset || [@node]).each{|n| add_class_to(n, classname)}
191
+ self
192
+ end
193
+
194
+ def remove_class(classname)
195
+ (@nodeset || [@node]).each{|n| remove_class_from(n, classname)}
196
+ self
197
+ end
198
+
199
+ def style(*args)
200
+ argl = args.length
201
+ _node = @node || {}
202
+ css = (_node['style']) || ''
203
+ hash = parse_css css
204
+ return hash if argl.zero?
205
+ if argl == 1
206
+ arg = args[0]
207
+ if hashlike? arg
208
+ return if !@node
209
+ arg.each{|prop, val|
210
+ hash[prop] = val
211
+ }
212
+ @node['style'] = hash_to_css(hash)
213
+ return self
214
+ else
215
+ return hash[arg.to_s]
216
+ end
217
+ else
218
+ prop, val = args
219
+ hash[prop] = val
220
+ @node['style'] = hash_to_css(hash)
221
+ return self
222
+ end
223
+ end
224
+
225
+ def hide
226
+ (@nodeset || [@node]).each{|n|
227
+ css = n['style'] || ''
228
+ hash = parse_css css
229
+ hash['display'] = 'none'
230
+ n['style'] = hash_to_css(hash)
231
+ }
232
+ self
233
+ end
234
+
235
+ def data(*args)
236
+ argl = args.length
237
+ if argl.zero?
238
+ return {} if !@node
239
+ attrs = @node.attributes
240
+ res = {}
241
+ attrs.each{|a,v|
242
+ res[a] = v if a[/^data-/]
243
+ }
244
+ res
245
+ elsif argl == 1
246
+ arg = args[0]
247
+ if hashlike?(arg)
248
+ arg.each{|name, val|
249
+ @node["data-#{name}"] = val
250
+ } if @node
251
+ self
252
+ else
253
+ return nil if !@node
254
+ @node["data-#{arg}"]
255
+ end
256
+ else
257
+ name, val = args
258
+ if @node
259
+ @node["data-#{name}"] = val
260
+ end
261
+ self
262
+ end
263
+ end
264
+
265
+ def as_template(obj, opts = nil)
266
+ opts ||= {}
267
+ nl = opts[:new_line]
268
+ res = self
269
+ if @node
270
+ if obj.is_a? String
271
+ @node.content = obj
272
+ elsif hashlike?(obj)
273
+ obj.each{|attr, v|
274
+ attr_s = attr.to_s
275
+ if v.nil? && !@node[attr_s].nil?
276
+ @node.remove_attribute attr_s
277
+ elsif attr == :content
278
+ v = '' if v.nil?
279
+ @node.content = v.to_s
280
+ elsif attr == :data && hashlike?(v)
281
+ v.each{|data_name, data_val|
282
+ @node["data-#{data_name}"] = data_val
283
+ }
284
+ elsif attr == :select && hashlike?(v)
285
+ v.each{|sel, o|
286
+ e = self.find sel.to_s
287
+ e.as_template(o)
288
+ }
289
+ else
290
+ @node[attr_s] = v
291
+ end
292
+ }
293
+ elsif obj.is_a? Array
294
+ last = @node
295
+ obj.each{|o|
296
+ _node = @node.clone
297
+ e = HTML.new(_node)
298
+ if block_given?
299
+ yield e, o
300
+ else
301
+ e.as_template(o)
302
+ end
303
+ last.after("\n") if nl
304
+ last.after(e.node)
305
+ last = e.node
306
+ }
307
+ @node.remove
308
+ end
309
+ end
310
+ res
311
+ end
312
+
313
+ def to_html
314
+ @node.to_html
315
+ end
316
+
317
+ def to_xhtml
318
+ @node.to_xhtml
319
+ end
320
+
321
+ def to_xml
322
+ @node.to_xml
323
+ end
324
+
325
+ def to_s
326
+ super if !@node
327
+ if @node.xml?
328
+ to_xml
329
+ else
330
+ to_html
331
+ end
332
+ end
333
+
334
+ def clone
335
+ _clone = super
336
+ _clone.instance_eval{
337
+ @node = @node.clone if @node
338
+ @nodeset = @nodeset.clone if @nodeset
339
+ @document = @document.clone if @document
340
+ }
341
+ _clone
342
+ end
343
+
344
+ def HTML::parse(text, opts = nil)
345
+ text ||= ''
346
+ opts ||= {}
347
+ opts = {auto: true}.merge(opts)
348
+ if opts[:auto]
349
+ opts[:is_document] = !text.strip[/^<!doctype /i].nil?
350
+ end
351
+ if opts[:is_document]
352
+ HTML.new(Nokogiri::HTML::Document.parse(text))
353
+ else
354
+ HTML.new(text)
355
+ end
356
+ end
357
+
358
+ def HTML::parse_doc(text, opts = {})
359
+ opts[:is_document] = true
360
+ HTML::parse text, opts
361
+ end
362
+
363
+ def HTML::load(path, opts = {})
364
+ if @@use_cache
365
+ cached = @@cache[path]
366
+ return cached.clone if cached
367
+ end
368
+ opts[:source] = path
369
+ text = File.read path
370
+ HTML::parse text, opts
371
+ end
372
+
373
+ def HTML::load_doc(path)
374
+ HTML::load path, is_document: true, source: path
375
+ end
376
+
377
+ def HTML::prefix
378
+ @@prefix
379
+ end
380
+
381
+ def HTML::prefix=(prfx)
382
+ @@prefix = prfx
383
+ end
384
+
385
+ def HTML::evaluation_instance
386
+ @@evaluation_instance
387
+ end
388
+
389
+ def HTML::evaluation_instance=(obj)
390
+ @@evaluation_instance = obj
391
+ end
392
+
393
+ def HTML::evaluation_binding
394
+ @@evaluation_binding
395
+ end
396
+
397
+ def HTML::evaluation_binding=(b)
398
+ @@evaluation_binding = b
399
+ end
400
+
401
+ def HTML::include_path
402
+ @@include_path
403
+ end
404
+
405
+ def HTML::include_path=(path)
406
+ @@include_path = path
407
+ end
408
+
409
+ private
410
+
411
+ def raise_err(msg, line = nil)
412
+ args = [HTMLException, msg]
413
+ args << "#{@source}:#{line}" if @source && line
414
+ raise *args
415
+ end
416
+
417
+ def add_class_to(_node, classname)
418
+ cls = _node['class'] || ''
419
+ classes = cls.split(/\s+/)
420
+ return if classes.include? classname
421
+ cls = (classes << classname).join(' ')
422
+ _node['class'] = cls
423
+ end
424
+
425
+ def remove_class_from(_node, classname)
426
+ cls = _node['class'] || ''
427
+ cls = cls.split(/\s+/).select{|c| c != classname}.join(' ')
428
+ _node['class'] = cls
429
+ end
430
+
431
+ def hashlike?(obj)
432
+ obj.is_a?(Hash) || (!obj.is_a?(Array) &&
433
+ obj.respond_to?(:[]) &&
434
+ obj.respond_to?(:each))
435
+ end
436
+
437
+ def resolvepath(path)
438
+ return path if path[/^\//]
439
+ if (include_path = @@include_path)
440
+ script_path = File.dirname(File.expand_path($0))
441
+ include_path = File.join(script_path, include_path, path)
442
+ path = include_path if File.exists? path
443
+ end
444
+ path
445
+ end
446
+
447
+ def parse_css(css)
448
+ o = {}
449
+ css = css.strip.gsub(/^\{/, '').gsub(/\}$/, '')
450
+ decls = css.split(';')
451
+ decls.each{|d|
452
+ prop, val = d.strip.split(':')
453
+ o[prop.strip] = val.strip
454
+ }
455
+ o
456
+ end
457
+
458
+ def hash_to_css(hash)
459
+ hash.to_a.map{|d|
460
+ prop, val = d
461
+ "#{prop}: #{val}"
462
+ }.join('; ')
463
+ end
464
+
465
+ end
466
+
467
+ class HTMLBuilder
468
+
469
+ def initialize(parent)
470
+ @parent = parent
471
+ end
472
+
473
+ def mode(mode)
474
+ @mode = mode
475
+ self
476
+ end
477
+
478
+ def method_missing(m, attrs = {}, &block)
479
+ attrs[:_doc] = @parent
480
+ element = HTML.new m, attrs, &block
481
+ if @mode == :prepend
482
+ @parent.prepend element
483
+ else
484
+ @parent.append element
485
+ end
486
+ element
487
+ end
488
+
489
+ end
490
+
491
+ end
@@ -0,0 +1,3 @@
1
+ module Weby
2
+ VERSION = "0.0.1"
3
+ end
data/lib/weby.rb ADDED
@@ -0,0 +1,6 @@
1
+ require 'nokogiri'
2
+ require "weby/version"
3
+ require "weby/html"
4
+
5
+ module Weby
6
+ end
data/weby.gemspec ADDED
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'weby/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ lpath = File.dirname(lib)
8
+ spec.name = "weby"
9
+ spec.version = Weby::VERSION
10
+ spec.authors = ["artix"]
11
+ spec.email = ["artix2@gmail.com"]
12
+ spec.summary = %q{Web programming for Ruby made easy.}
13
+ spec.description = File.read(File.join(lpath, 'GEMDESC'))
14
+ spec.homepage = "https://github.com/artix75/weby"
15
+ spec.license = "BSD-3-Clause"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0")
18
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_development_dependency "bundler", "~> 1.7"
23
+ spec.add_development_dependency "rake", "~> 10.0"
24
+
25
+ spec.add_runtime_dependency "nokogiri", "~> 1.8"
26
+
27
+ end
metadata ADDED
@@ -0,0 +1,101 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: weby
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - artix
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-07-12 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: nokogiri
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.8'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.8'
55
+ description: 'Weby has been designed to easily write web interfaces. It can be used
56
+ to generate HTML code in a template based fashion or you''re free to create HTML
57
+ in a programmatic way, or even a mix of them.
58
+
59
+ '
60
+ email:
61
+ - artix2@gmail.com
62
+ executables: []
63
+ extensions: []
64
+ extra_rdoc_files: []
65
+ files:
66
+ - ".gitignore"
67
+ - GEMDESC
68
+ - Gemfile
69
+ - LICENSE
70
+ - LICENSE.txt
71
+ - README.md
72
+ - Rakefile
73
+ - lib/weby.rb
74
+ - lib/weby/html.rb
75
+ - lib/weby/version.rb
76
+ - weby.gemspec
77
+ homepage: https://github.com/artix75/weby
78
+ licenses:
79
+ - BSD-3-Clause
80
+ metadata: {}
81
+ post_install_message:
82
+ rdoc_options: []
83
+ require_paths:
84
+ - lib
85
+ required_ruby_version: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ required_rubygems_version: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ requirements: []
96
+ rubyforge_project:
97
+ rubygems_version: 2.6.9
98
+ signing_key:
99
+ specification_version: 4
100
+ summary: Web programming for Ruby made easy.
101
+ test_files: []