mab-cj 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/COPYING +19 -0
- data/Gemfile +14 -0
- data/README.md +224 -0
- data/Rakefile +16 -0
- data/lib/mab.rb +6 -0
- data/lib/mab/builder.rb +45 -0
- data/lib/mab/indentation.rb +33 -0
- data/lib/mab/kernel_method.rb +6 -0
- data/lib/mab/mixin.rb +262 -0
- data/lib/mab/rails.rb +20 -0
- data/lib/mab/tilt.rb +42 -0
- data/lib/mab/version.rb +4 -0
- data/mab.gemspec +20 -0
- data/test/helper.rb +4 -0
- data/test/rails/Rakefile +7 -0
- data/test/rails/app/assets/images/rails.png +0 -0
- data/test/rails/app/assets/javascripts/application.js +15 -0
- data/test/rails/app/assets/stylesheets/application.css +13 -0
- data/test/rails/app/controllers/application_controller.rb +17 -0
- data/test/rails/app/helpers/application_helper.rb +2 -0
- data/test/rails/app/views/application/content_for.html.mab +6 -0
- data/test/rails/app/views/application/normal.html.mab +2 -0
- data/test/rails/app/views/application/variables.html.mab +2 -0
- data/test/rails/app/views/layouts/application.html.mab +15 -0
- data/test/rails/config.ru +4 -0
- data/test/rails/config/application.rb +54 -0
- data/test/rails/config/boot.rb +6 -0
- data/test/rails/config/environment.rb +5 -0
- data/test/rails/config/environments/development.rb +27 -0
- data/test/rails/config/environments/production.rb +67 -0
- data/test/rails/config/environments/test.rb +29 -0
- data/test/rails/config/initializers/backtrace_silencers.rb +7 -0
- data/test/rails/config/initializers/inflections.rb +15 -0
- data/test/rails/config/initializers/mime_types.rb +5 -0
- data/test/rails/config/initializers/secret_token.rb +7 -0
- data/test/rails/config/initializers/session_store.rb +8 -0
- data/test/rails/config/initializers/wrap_parameters.rb +14 -0
- data/test/rails/config/locales/en.yml +5 -0
- data/test/rails/config/routes.rb +3 -0
- data/test/rails/script/rails +6 -0
- data/test/rails/test/helper.rb +7 -0
- data/test/rails/test/test_mab.rb +40 -0
- data/test/test_mab_builder.rb +56 -0
- data/test/test_mab_indentation.rb +66 -0
- data/test/test_mab_kernel_method.rb +10 -0
- data/test/test_mab_mixin.rb +250 -0
- metadata +118 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 6b56014736fcafd7c7f040d47c1b3d6ee14cfa27
|
4
|
+
data.tar.gz: 4d6e5b38d9532ef9dab04f6c2b945332ad345f6f
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 7b5a2d08f46788cdda2061f7201fea7f4aae7067143e9bc35d714339b431e3033580c97222245d1fc5f81e6eb8e61168e924d231eac4d243c1500293336016f6
|
7
|
+
data.tar.gz: 3350aa5ddb6ad086ef32b691c21741592e44f0a8a568de64d4ca1db2f45bf1e1f6457d5d8a2756c8b54f62734ff0949ac4c4c50644eaa24e7e2320f625a975e6
|
data/COPYING
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (c) 2012 Magnus Holm <judofyr@gmail.com>
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to
|
5
|
+
deal in the Software without restriction, including without limitation the
|
6
|
+
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
7
|
+
sell copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
11
|
+
all copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
16
|
+
THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
17
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
18
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
19
|
+
|
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,224 @@
|
|
1
|
+
Mab (Markup as Ruby)
|
2
|
+
====================
|
3
|
+
|
4
|
+
Mab let's you write HTML in plain Ruby:
|
5
|
+
|
6
|
+
```ruby
|
7
|
+
doctype!
|
8
|
+
html do
|
9
|
+
head do
|
10
|
+
link :rel => 'stylesheet', :href => 'style.css'
|
11
|
+
script :src => 'jquery.js'
|
12
|
+
end
|
13
|
+
body :id => :frontpage do
|
14
|
+
h1 'Hello World', :class => :main
|
15
|
+
end
|
16
|
+
end
|
17
|
+
```
|
18
|
+
|
19
|
+
|
20
|
+
Syntax
|
21
|
+
------
|
22
|
+
|
23
|
+
### 1. Tags and Attributes
|
24
|
+
|
25
|
+
There are four basic forms:
|
26
|
+
|
27
|
+
```ruby
|
28
|
+
tagname(content)
|
29
|
+
|
30
|
+
tagname(content, attributes)
|
31
|
+
|
32
|
+
tagname do
|
33
|
+
content
|
34
|
+
end
|
35
|
+
|
36
|
+
tagname(attributes) do
|
37
|
+
content
|
38
|
+
end
|
39
|
+
```
|
40
|
+
|
41
|
+
Example:
|
42
|
+
|
43
|
+
```ruby
|
44
|
+
doctype!
|
45
|
+
html do
|
46
|
+
head do
|
47
|
+
link :rel => 'stylesheet', :href => 'style.css'
|
48
|
+
script :src => 'jquery.js'
|
49
|
+
end
|
50
|
+
body :id => :frontpage do
|
51
|
+
h1 'Hello World', :class => :main
|
52
|
+
end
|
53
|
+
end
|
54
|
+
```
|
55
|
+
|
56
|
+
Which results in:
|
57
|
+
|
58
|
+
```html
|
59
|
+
<!DOCTYPE html>
|
60
|
+
<html>
|
61
|
+
<head>
|
62
|
+
<link rel="stylesheet" href="style.css">
|
63
|
+
<script src="jquery"></script>
|
64
|
+
</head>
|
65
|
+
<body id="frontpage">
|
66
|
+
<h1 class="main">Hello World</h1>
|
67
|
+
</body>
|
68
|
+
</html>
|
69
|
+
```
|
70
|
+
|
71
|
+
Notice how Mab knows that script tag must have content, so although you didn't
|
72
|
+
specify anything it closed the tag for you.
|
73
|
+
|
74
|
+
### 2. Element Classes and IDs
|
75
|
+
|
76
|
+
You can easily add classes and IDs by hooking methods onto the container:
|
77
|
+
|
78
|
+
```ruby
|
79
|
+
body.frontpage! do
|
80
|
+
h1.main 'Hello World'
|
81
|
+
end
|
82
|
+
```
|
83
|
+
|
84
|
+
Which results in:
|
85
|
+
|
86
|
+
```html
|
87
|
+
<body id="frontpage">
|
88
|
+
<h1 class="main">Hello World</h1>
|
89
|
+
</body>
|
90
|
+
```
|
91
|
+
|
92
|
+
You can mix and match as you'd like (`div.klass.klass1.id!`), but you can only
|
93
|
+
provide content and attributes on the *last* call:
|
94
|
+
|
95
|
+
```ruby
|
96
|
+
# This is not valid:
|
97
|
+
form(:action => :post).world do
|
98
|
+
input
|
99
|
+
end
|
100
|
+
|
101
|
+
# But this is:
|
102
|
+
form.world(:action => :post) do
|
103
|
+
input
|
104
|
+
end
|
105
|
+
```
|
106
|
+
|
107
|
+
### 3. Escape or Not Escape
|
108
|
+
|
109
|
+
Mab uses a very simple convention for escaping: Strings as *arguments* gets
|
110
|
+
escaped, strings in *blocks* don't:
|
111
|
+
|
112
|
+
```ruby
|
113
|
+
div.comment "<script>alert(1)</script>"
|
114
|
+
# <div class="comment"><script>alert(1)</script></div>
|
115
|
+
|
116
|
+
div.comment { "I <strong>love</strong> you" }
|
117
|
+
# <div class="comment">I <strong>love</strong> you</div>
|
118
|
+
```
|
119
|
+
|
120
|
+
Be aware that Mab ignores the string in a block if there's other tags there:
|
121
|
+
|
122
|
+
```ruby
|
123
|
+
div.comment do
|
124
|
+
div.author "BitPuffin"
|
125
|
+
"<p>Silence!</p>"
|
126
|
+
end
|
127
|
+
```
|
128
|
+
|
129
|
+
The p tag above won't appear in the output.
|
130
|
+
|
131
|
+
### 4. Text
|
132
|
+
|
133
|
+
Sometimes you need to insert plain text:
|
134
|
+
|
135
|
+
```ruby
|
136
|
+
p.author do
|
137
|
+
text 'Written by '
|
138
|
+
a 'Bluebie', :href => 'http://creativepony.com/'
|
139
|
+
end
|
140
|
+
```
|
141
|
+
|
142
|
+
Which results in:
|
143
|
+
|
144
|
+
```html
|
145
|
+
<p class="author">
|
146
|
+
Written by
|
147
|
+
<a href="http://creativepony.com/">Bluebie</a>
|
148
|
+
</p>
|
149
|
+
```
|
150
|
+
|
151
|
+
There's also `text!` which doesn't escape:
|
152
|
+
|
153
|
+
```ruby
|
154
|
+
p.author do
|
155
|
+
text! '<strong>Written</strong> by'
|
156
|
+
a 'Bluebie', :href => 'http://creativepony.com/'
|
157
|
+
```
|
158
|
+
|
159
|
+
|
160
|
+
Invoking Mab
|
161
|
+
------------
|
162
|
+
|
163
|
+
Using #mab:
|
164
|
+
|
165
|
+
```ruby
|
166
|
+
require 'mab/kernel_method'
|
167
|
+
|
168
|
+
str = mab do
|
169
|
+
doctype!
|
170
|
+
html do
|
171
|
+
# ...
|
172
|
+
end
|
173
|
+
end
|
174
|
+
```
|
175
|
+
|
176
|
+
Using Mab::Builder (or Mab::PrettyBuilder if you want indentation):
|
177
|
+
|
178
|
+
```ruby
|
179
|
+
class Person
|
180
|
+
attr_reader :name
|
181
|
+
|
182
|
+
def initialize(name)
|
183
|
+
@name = name
|
184
|
+
end
|
185
|
+
|
186
|
+
def awesome?; true end
|
187
|
+
end
|
188
|
+
|
189
|
+
# Assign instance variables:
|
190
|
+
Mab::Builder.new(:person => Person.new('BitBuffin')) do
|
191
|
+
if @person.awesome?
|
192
|
+
h1 @person.name
|
193
|
+
else
|
194
|
+
p @person.name
|
195
|
+
end
|
196
|
+
end.to_s
|
197
|
+
|
198
|
+
# Use helper (methods and instance variables will be available):
|
199
|
+
Mab::Builder.new({}, Person.new('BitPuffin')) do
|
200
|
+
if awesome?
|
201
|
+
h1 @name
|
202
|
+
else
|
203
|
+
p @name
|
204
|
+
end
|
205
|
+
end.to_s
|
206
|
+
```
|
207
|
+
|
208
|
+
Extending an object (*advanced usage*):
|
209
|
+
|
210
|
+
```ruby
|
211
|
+
r = Object.new
|
212
|
+
r.extend Mab::Mixin::HTML5
|
213
|
+
r.extend Mab::Indentation
|
214
|
+
|
215
|
+
r.mab do
|
216
|
+
doctype!
|
217
|
+
html do
|
218
|
+
# ...
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
```
|
223
|
+
|
224
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'rake/testtask'
|
2
|
+
|
3
|
+
task :default => :test
|
4
|
+
task :test => 'test:core'
|
5
|
+
|
6
|
+
namespace 'test' do
|
7
|
+
Rake::TestTask.new('core') do |t|
|
8
|
+
t.libs << 'lib' << 'test'
|
9
|
+
end
|
10
|
+
|
11
|
+
Rake::TestTask.new('rails') do |t|
|
12
|
+
t.libs << 'lib'
|
13
|
+
t.test_files = FileList['test/rails/test/test_*.rb']
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
data/lib/mab.rb
ADDED
data/lib/mab/builder.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
module Mab
|
2
|
+
class SimpleBuilder
|
3
|
+
include Mixin
|
4
|
+
|
5
|
+
def initialize(assigns = {}, helper = nil, &blk)
|
6
|
+
@_helper = helper
|
7
|
+
@_result = []
|
8
|
+
|
9
|
+
assigns.each do |key, value|
|
10
|
+
instance_variable_set(:"@#{key}", value)
|
11
|
+
end
|
12
|
+
|
13
|
+
if helper
|
14
|
+
helper.instance_variables.each do |var|
|
15
|
+
instance_variable_set(var, helper.instance_variable_get(var))
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
capture(&blk) if blk
|
20
|
+
end
|
21
|
+
|
22
|
+
def capture(&blk)
|
23
|
+
@_result << mab(&blk)
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_s; @_result.join end
|
27
|
+
|
28
|
+
def method_missing(name, *args, &blk)
|
29
|
+
if @_helper && @_helper.respond_to?(name, true)
|
30
|
+
@_helper.send(name, *args, &blk)
|
31
|
+
else
|
32
|
+
super
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
class Builder < SimpleBuilder
|
38
|
+
include HTML5
|
39
|
+
end
|
40
|
+
|
41
|
+
class PrettyBuilder < Builder
|
42
|
+
include Indentation
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Mab
|
2
|
+
module Indentation
|
3
|
+
def mab_insert(str)
|
4
|
+
if i = @mab_context.options[:indentation]
|
5
|
+
super([$/ + " " * i, str])
|
6
|
+
else
|
7
|
+
@mab_context.options[:indentation] = 0
|
8
|
+
super
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def mab_done(tag)
|
13
|
+
if blk = tag._block
|
14
|
+
tag._block = proc do
|
15
|
+
begin
|
16
|
+
@mab_context.options[:indentation] += 1
|
17
|
+
blk.call
|
18
|
+
ensure
|
19
|
+
@mab_context.options[:indentation] -= 1
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
super
|
24
|
+
end
|
25
|
+
|
26
|
+
def reindent!(str)
|
27
|
+
str.split(/\r?\n/).each do |s|
|
28
|
+
text! s
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
data/lib/mab/mixin.rb
ADDED
@@ -0,0 +1,262 @@
|
|
1
|
+
require 'cgi'
|
2
|
+
|
3
|
+
module Mab
|
4
|
+
module Mixin
|
5
|
+
class Error < StandardError; end
|
6
|
+
class Tag
|
7
|
+
attr_accessor :_name, :_content, :_attributes, :_block, :_has_content
|
8
|
+
attr_reader :_options, :_context, :_instance
|
9
|
+
|
10
|
+
def initialize(name, options, context, instance = nil)
|
11
|
+
@_name = name
|
12
|
+
@_options = options
|
13
|
+
@_context = context
|
14
|
+
@_instance = instance
|
15
|
+
@_done = false
|
16
|
+
|
17
|
+
@_content = nil
|
18
|
+
@_has_content = nil
|
19
|
+
|
20
|
+
@_attributes = {}
|
21
|
+
|
22
|
+
@_pos = @_context.size
|
23
|
+
end
|
24
|
+
|
25
|
+
def _block
|
26
|
+
return @_block unless block_given?
|
27
|
+
current = @_block
|
28
|
+
@_block = proc { yield current }
|
29
|
+
end
|
30
|
+
|
31
|
+
def _merge_attributes(*args)
|
32
|
+
args.each do |attrs|
|
33
|
+
@_attributes.merge!(attrs)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def method_missing(name, *args, &blk)
|
38
|
+
name = name.to_s
|
39
|
+
|
40
|
+
if name[-1] == ?!
|
41
|
+
@_attributes[:id] = name[0..-2]
|
42
|
+
else
|
43
|
+
if @_attributes.has_key?(:class)
|
44
|
+
@_attributes[:class] += " #{name}"
|
45
|
+
else
|
46
|
+
@_attributes[:class] = name
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
_insert(*args, &blk)
|
51
|
+
end
|
52
|
+
|
53
|
+
def _insert(*args, &blk)
|
54
|
+
raise Error, "This tag is already closed" if @_done
|
55
|
+
|
56
|
+
if !args.empty? && !args[0].is_a?(Hash)
|
57
|
+
content = args.shift
|
58
|
+
raise Error, "Tag doesn't allow content" if @_has_content == false
|
59
|
+
@_has_content = true
|
60
|
+
end
|
61
|
+
|
62
|
+
if content
|
63
|
+
@_content = CGI.escapeHTML(content.to_s)
|
64
|
+
@_done = true
|
65
|
+
end
|
66
|
+
|
67
|
+
if !args.empty?
|
68
|
+
_merge_attributes(*args)
|
69
|
+
@_done = true
|
70
|
+
end
|
71
|
+
|
72
|
+
if block_given?
|
73
|
+
raise Error, "Tag doesn't allow content" if @_has_content == false
|
74
|
+
@_has_content = true
|
75
|
+
@_block = blk
|
76
|
+
@_done = true
|
77
|
+
end
|
78
|
+
|
79
|
+
if @_content && @_block
|
80
|
+
raise Error, "Both content and _block is not allowed"
|
81
|
+
end
|
82
|
+
|
83
|
+
@_instance.mab_done(self) if @_done
|
84
|
+
|
85
|
+
if @_block
|
86
|
+
before = @_context.children
|
87
|
+
res = @_block.call
|
88
|
+
|
89
|
+
if before >= @_context.children
|
90
|
+
@_content = res.to_s
|
91
|
+
else
|
92
|
+
# Turn the node into just an opening tag.
|
93
|
+
@_has_content = false
|
94
|
+
@_instance.mab_insert("</#{@_name}>")
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
self
|
99
|
+
end
|
100
|
+
|
101
|
+
def to_ary() nil end
|
102
|
+
def to_str() to_s end
|
103
|
+
|
104
|
+
def _attrs_to_s
|
105
|
+
@_attributes.inject("") do |res, (name, value)|
|
106
|
+
if value
|
107
|
+
value = (value == true) ? name : CGI.escapeHTML(value.to_s)
|
108
|
+
res << " #{name}=\"#{value}\""
|
109
|
+
end
|
110
|
+
res
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def to_s
|
115
|
+
if !@_context.joining? && @_context[@_pos]
|
116
|
+
@_context[@_pos] = nil
|
117
|
+
@_context.children -= 1
|
118
|
+
end
|
119
|
+
|
120
|
+
res = "<#{@_name}#{_attrs_to_s}"
|
121
|
+
res << (@_options[:xml] && !@_block && !@_has_content ? ' />' : '>')
|
122
|
+
res << "#{@_content}</#{@_name}>" if @_has_content
|
123
|
+
res
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
class Context < Array
|
128
|
+
attr_accessor :children, :options
|
129
|
+
|
130
|
+
def initialize
|
131
|
+
@children = 0
|
132
|
+
@joining = false
|
133
|
+
@options = {}
|
134
|
+
end
|
135
|
+
|
136
|
+
def <<(str)
|
137
|
+
@children += 1
|
138
|
+
super(str)
|
139
|
+
end
|
140
|
+
|
141
|
+
def join(*)
|
142
|
+
@joining = true
|
143
|
+
super
|
144
|
+
end
|
145
|
+
|
146
|
+
def joining?
|
147
|
+
@joining
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
def mab_tag(name)
|
152
|
+
ctx = @mab_context || raise(Error, "Tags can only be written within a `mab { }`-block")
|
153
|
+
tag = Tag.new(name, mab_options, ctx, self)
|
154
|
+
mab_insert(tag)
|
155
|
+
tag
|
156
|
+
end
|
157
|
+
|
158
|
+
def tag!(name, *args, &blk)
|
159
|
+
mab_tag(name)._insert(*args, &blk)
|
160
|
+
end
|
161
|
+
|
162
|
+
def text!(str)
|
163
|
+
mab_insert(str)
|
164
|
+
end
|
165
|
+
|
166
|
+
def text(str)
|
167
|
+
text! CGI.escapeHTML(str.to_s)
|
168
|
+
end
|
169
|
+
|
170
|
+
def mab(&blk)
|
171
|
+
prev = defined?(@mab_context) && @mab_context
|
172
|
+
ctx = @mab_context = Context.new
|
173
|
+
res = instance_eval(&blk)
|
174
|
+
ctx.empty? ? res : ctx.join
|
175
|
+
ensure
|
176
|
+
@mab_context = prev
|
177
|
+
end
|
178
|
+
|
179
|
+
def mab_insert(tag)
|
180
|
+
ctx = @mab_context || raise(Error, 'mab { }-block required')
|
181
|
+
ctx << tag
|
182
|
+
end
|
183
|
+
|
184
|
+
def mab_done(tag)
|
185
|
+
end
|
186
|
+
|
187
|
+
def mab_options
|
188
|
+
@mab_options ||= {}
|
189
|
+
end
|
190
|
+
|
191
|
+
module XML
|
192
|
+
include Mixin
|
193
|
+
|
194
|
+
def mab_options
|
195
|
+
@mab_options ||= super.update(:xml => true)
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
module HTMLDefiners
|
200
|
+
def define_tag(meth, tag)
|
201
|
+
class_eval <<-EOF
|
202
|
+
def #{meth}(*args, &blk)
|
203
|
+
tag = mab_tag(:#{tag})
|
204
|
+
tag._has_content = true
|
205
|
+
tag._insert(*args, &blk)
|
206
|
+
end
|
207
|
+
EOF
|
208
|
+
end
|
209
|
+
|
210
|
+
def define_tags(*tags)
|
211
|
+
tags.flatten.each do |tag|
|
212
|
+
define_tag(tag, tag)
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
def define_empty_tag(meth, tag)
|
217
|
+
class_eval <<-EOF
|
218
|
+
def #{meth}(*args, &blk)
|
219
|
+
tag = mab_tag(:#{tag})
|
220
|
+
tag._has_content = false
|
221
|
+
tag._insert(*args, &blk)
|
222
|
+
end
|
223
|
+
EOF
|
224
|
+
end
|
225
|
+
|
226
|
+
def define_empty_tags(*tags)
|
227
|
+
tags.flatten.each do |tag|
|
228
|
+
define_empty_tag(tag, tag)
|
229
|
+
end
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
module HTML5
|
234
|
+
extend HTMLDefiners
|
235
|
+
include Mixin
|
236
|
+
|
237
|
+
define_tags %w[a abbr acronym address applet article aside audio b
|
238
|
+
basefont bdi bdo big blockquote body button canvas caption
|
239
|
+
center cite code colgroup datalist dd del details dfn dir div dl
|
240
|
+
dt em fieldset figcaption figure font footer form frame frameset
|
241
|
+
h1 h2 h3 h4 h5 h6 head header hgroup html i iframe ins kbd label
|
242
|
+
legend li link map mark math menu meter nav noframes noscript
|
243
|
+
object ol optgroup option output p pre progress q rp rt ruby s
|
244
|
+
samp script section select small span strike strong style sub
|
245
|
+
summary sup svg table tbody td textarea tfoot th thead time
|
246
|
+
title tr tt u ul var video xmp]
|
247
|
+
|
248
|
+
define_empty_tags %w[base link meta hr br wbr img embed param source
|
249
|
+
track area col input keygen command]
|
250
|
+
|
251
|
+
def doctype!
|
252
|
+
text! '<!DOCTYPE html>'
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
module XHTML5
|
257
|
+
include HTML5
|
258
|
+
include XML
|
259
|
+
end
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|