rml 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (6) hide show
  1. data/bin/rml +17 -0
  2. data/lib/rml.rb +290 -0
  3. data/lib/rml/sinatra.rb +25 -0
  4. data/lib/rsm.rb +185 -0
  5. data/lib/tags.rb +418 -0
  6. metadata +57 -0
data/bin/rml ADDED
@@ -0,0 +1,17 @@
1
+ require 'rubygems'
2
+ require 'rml'
3
+
4
+ if ARGV[0].nil?
5
+ puts "/*********************************\\"
6
+ puts "* *"
7
+ puts "* RML: Ruby Markup Language *"
8
+ puts "* *"
9
+ puts "* Usage: *"
10
+ puts "* rml my_template.rml *"
11
+ puts "* *"
12
+ puts "* Output: Valid XHTML 1.0 *"
13
+ puts "* *"
14
+ puts "\\*********************************/"
15
+ else
16
+ puts RML.new.markup_file(ARGV[0])
17
+ end
data/lib/rml.rb ADDED
@@ -0,0 +1,290 @@
1
+ # ==RML: Ruby template engine
2
+ #
3
+ # Pure ruby xhtml markup language. Similar to Markaby, but with one big difference.
4
+ # RML is aimed to provide valid and only valid xhtml 1.0.
5
+ # It's mean, you got exception in runtime, if try to write not valid xhtml.
6
+ #
7
+ # ====Example:
8
+ # doctype!
9
+ # html do
10
+ # head { title 'RML Test' }
11
+ # body do
12
+ # div_main do
13
+ # div_menu do
14
+ # {"ruby!" => "ruby-lang.org", "gems!" => "rubyforge.org", "doc!" => "ruby-doc.org"}.each_pair do |t, s|
15
+ # a t, :href => s
16
+ # end
17
+ # end
18
+ # div_content do
19
+ # h1 "Try RML"
20
+ # end
21
+ # div_footer do
22
+ # p "Generated by RML", :style => "text-align: center"
23
+ # end
24
+ # end
25
+ # end
26
+ # end
27
+ #
28
+ #
29
+ # to insert DOCTYPE definition use doctype!
30
+ #
31
+ # to specify element id use '_'
32
+ # p_test "test" #=> <p id="test">test</p>
33
+ #
34
+ # to specify element class use '.'
35
+ # p.test "test" #=> <p class="test">test</p>
36
+ #
37
+ # you can use multiple classes for element
38
+ # p.test.test1 "test" #=> <p class="test test1">test</p>
39
+ #
40
+ # if you want to mix tags and text in parent tag, use method text:
41
+ # div.text do
42
+ # text "this is"
43
+ # br
44
+ # text "div with text"
45
+ # end
46
+ # also, you can use data method, to insert unescaped text,
47
+ # for example, result of the method, providing html:
48
+ # div.text do
49
+ # data "<p>some html</p>"
50
+ # data gen_html
51
+ # end
52
+ # use data method carefully! there's no validation for it
53
+ #
54
+ # you can use templatesin separate files, for example:
55
+ # div.external do
56
+ # rml :external #load 'external.rml' here
57
+ # end
58
+ #
59
+ # all code validating according to XHTML 1.0 DTD(not fully implemented yet) i.e.:
60
+ # td :width => "20%" #=> Attribute 'width' not allowed for tag <td> (AttrNotAllowedException)
61
+ # head { p "p in head"} #=> Tag <head> should't contain child tag <p> (TagNotAllowedException)
62
+ #
63
+ # mayby, for some reasons you want to disable xhtml validation,
64
+ # to do it use method dirty :
65
+ # dirty do
66
+ # td :width => "20%" # no exception here!
67
+ # end
68
+ #
69
+ # ====Limitations
70
+ # - to use attributes containing ':' or '-', instead standart syntax :attr use 'attr'.to_sym
71
+ # - you can't use css classes and ids containing '-' with '_' and '.',
72
+ # instead of div_id-with-dash or div.class-with-dash use div :class => "class_with_dash" and div :id => "id_with_dash"
73
+ require 'cgi'
74
+ require File.dirname(__FILE__)+'/tags'
75
+ require File.dirname(__FILE__)+'/rsm'
76
+
77
+
78
+ class AttrNotAllowedException < Exception
79
+ end
80
+
81
+ class AttrRequiredException < Exception
82
+ end
83
+
84
+ class TagNotAllowedException < Exception
85
+ end
86
+
87
+ class TextNotAllowedException < Exception
88
+ end
89
+
90
+ class AttributeException < Exception
91
+ end
92
+
93
+ class String
94
+ def tab n=1
95
+ if self.count("\n") > 1
96
+ self.split("\r\n").collect { |s| "\t"*n + s }.join("\r\n")
97
+ else
98
+ "\t"*n + self
99
+ end
100
+ end
101
+ end
102
+
103
+ class RML
104
+
105
+ def initialize
106
+ @dirty = false
107
+ reinit
108
+ end
109
+
110
+ def reinit
111
+ @tag_stack = []
112
+ @html = ''
113
+ @tag_css = nil
114
+ @css_classes = []
115
+ end
116
+
117
+ def allow_dirty_code d
118
+ @dirty = d
119
+ end
120
+
121
+ def use_bound b
122
+ @bound = b
123
+ end
124
+
125
+ def method_missing sym, *args, &block
126
+ args.flatten!
127
+ if @tag_css
128
+ @css_classes << sym
129
+ if not args.empty? or not block.nil?
130
+ tag = @tag_css
131
+ @tag_css = nil
132
+ classes = @css_classes.join(' ')
133
+ @css_classes = []
134
+ method_missing tag, add_attr(args, :class => classes), &block
135
+ end
136
+ elsif Tags.keys.include? sym
137
+ if args.empty? and block.nil? and not Tags[sym][:tags].empty?
138
+ @tag_css = sym
139
+ else
140
+ process_tag sym, args, &block
141
+ end
142
+ elsif Tags.keys.include? sym.to_s.split('_')[0].to_sym
143
+ if args.empty? and block.nil? and not Tags[sym.to_s.split('_')[0].to_sym][:tags].empty?
144
+ @tag_css = sym
145
+ else
146
+ process_tag sym.to_s.split('_')[0].to_sym, add_attr(args, :id => sym.to_s.split('_')[1]), &block
147
+ end
148
+ else
149
+ raise NoMethodError, "Undefined method '#{sym}'"
150
+ end
151
+ self
152
+ end
153
+
154
+ def process_tag name, attrs, &block
155
+ raise TagNotAllowedException, "Tag <#{@tag_stack.last}> should't contain child tag <#{name}>" unless @tag_stack.empty? or Tags[@tag_stack.last][:tags].include? name or @dirty
156
+ css = ''
157
+ content = ''
158
+ attr_str = ''
159
+
160
+ attributes = get_attrs(attrs)
161
+ content = get_content(attrs)
162
+
163
+ if not attributes.nil?
164
+ attributes.keys.each do |a|
165
+ raise AttrNotAllowedException, "Attribute '#{a}' not allowed for tag <#{name}>" unless Tags[name][:attrs].include? a or @dirty
166
+ end
167
+ Tags[name][:required_attrs].each do |a|
168
+ raise AttrRequiredException, "Attribute '#{a}' required for tag <#{name}>" unless attributes.include? a or @dirty
169
+ end
170
+ attributes.each_pair do |k,v|
171
+ attr_str += " #{k}=\"#{CGI.escapeHTML(v.to_s)}\""
172
+ end
173
+ else
174
+ raise AttrRequiredException, "Attributes '#{Tags[name][:required_attrs].join(', ')}' required for tag <#{name}>" unless Tags[name][:required_attrs].empty? or @dirty
175
+ end
176
+
177
+ if block
178
+ @html += "<#{name.to_s+attr_str}>#{content}\r\n".tab(@tag_stack.length)
179
+ @tag_stack << name
180
+ instance_eval &block
181
+ @html += "</#{@tag_stack.pop}>\r\n".tab(@tag_stack.length)
182
+ else
183
+ if Tags[name][:tags].empty? or content.empty?
184
+ @html += "<#{name.to_s+attr_str} />\r\n".tab(@tag_stack.length)
185
+ else
186
+ @html += "<#{name.to_s+attr_str}>#{content}</#{name}>\r\n".tab(@tag_stack.length)
187
+ end
188
+ end
189
+ self
190
+ end
191
+
192
+ # args -
193
+ # [0] args
194
+ # [0] Hash or String
195
+ # [1] Hash or String
196
+ # [1] hash => params
197
+
198
+ def add_attr *args
199
+ i = 0
200
+ i = 1 if args[0][0].class == String
201
+ args[0][i] = {} if args[0][i].nil? or args[0][i].class != Hash
202
+ args[1].each_pair do |k,v|
203
+ args[0][i][k] = v
204
+ end
205
+ args[0]
206
+ end
207
+
208
+ def get_content args
209
+ i = -1
210
+ i = 0 if args[0].class == String
211
+ i = 1 if args[1].class == String
212
+ return CGI.escapeHTML(args[i]) if i >= 0
213
+ ''
214
+ end
215
+
216
+ def get_attrs args
217
+ i = -1
218
+ i = 0 if args[0].class == Hash
219
+ i = 1 if args[1].class == Hash
220
+ return args[i] if i >= 0
221
+ nil
222
+ end
223
+
224
+ def dirty &block
225
+ @dirty = true
226
+ instance_eval &block
227
+ @dirty = false
228
+ self
229
+ end
230
+
231
+ def html *attrs, &block
232
+ method_missing :html, add_attr(attrs, :xmlns => "http://www.w3.org/1999/xhtml"), &block
233
+ end
234
+
235
+ def p *attrs, &block
236
+ method_missing :p, attrs, &block
237
+ end
238
+
239
+ def headfix *attrs, &block
240
+ method_missing :head, attrs, &block
241
+ end
242
+
243
+ def text t
244
+ raise TextNotAllowedException, "Tag <#{@tag_stack.last}> should't contain text" unless Tags[@tag_stack.last][:tags].include?(:pcdata) or @dirty
245
+ @html += CGI.escapeHTML(t).tab(@tag_stack.length)+"\r\n"
246
+ end
247
+
248
+ def data t
249
+ @html += t
250
+ end
251
+
252
+ def doctype!
253
+ @html += '<?xml version="1.0" encoding="utf-8" ?>'+"\r\n"
254
+ @html += '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">' + "\r\n"
255
+
256
+ end
257
+
258
+ def markup_file file
259
+ tmpl = ''
260
+ begin
261
+ tmpl = File.open(file).read
262
+ rescue
263
+ raise "Can't open file: #{file}"
264
+ end
265
+ instance_eval tmpl
266
+ end
267
+
268
+ def markup &proc
269
+ instance_eval &proc
270
+ self
271
+ end
272
+
273
+ def to_s
274
+ @html
275
+ end
276
+
277
+ def rml file
278
+ markup_file file.to_s + ".rml"
279
+ end
280
+ #todo add cdata to script and style
281
+ def rsm file, &block
282
+ s = RSM.new
283
+ if not file.nil?
284
+ s.markup File.open(file.to_s + ".rsm").read
285
+ else
286
+ s.markup &block
287
+ end
288
+ process_tag :style, [s.to_s, {:type => 'text/html'}]
289
+ end
290
+ end
@@ -0,0 +1,25 @@
1
+ require File.dirname(__FILE__) + '/../rml'
2
+
3
+ module Sinatra
4
+ module RML
5
+
6
+ def rml(content, options={})
7
+ require 'rml'
8
+ render(:rml, content, options)
9
+ end
10
+
11
+ private
12
+
13
+ def render_rml(content, options = {}, &b)
14
+ rml_options = (options[:options] || {})
15
+ r = ::RML.new
16
+ r.allow_dirty_code true if rml_options[:dirty]
17
+ r.instance_eval content
18
+ r.to_s
19
+ end
20
+
21
+ end
22
+ class EventContext
23
+ include RML
24
+ end
25
+ end
data/lib/rsm.rb ADDED
@@ -0,0 +1,185 @@
1
+ # Syntax:
2
+ # _main {
3
+ # padding.left '0px'
4
+ # }
5
+ # provide:
6
+ # #main {
7
+ # padding-left: 0px
8
+ # }
9
+ #
10
+ #
11
+ # main {
12
+ # padding.left '0px'
13
+ # }
14
+ # provide:
15
+ # .main {
16
+ # padding-left: 0px
17
+ # }
18
+ #
19
+ #
20
+ # tr {
21
+ # padding.left '0px'
22
+ # }
23
+ # provide:
24
+ # tr {
25
+ # padding-left: 0px
26
+ # }
27
+ #
28
+ #
29
+ # div.main {
30
+ # padding.left '0px'
31
+ # }
32
+ # provide:
33
+ # div.main {
34
+ # padding-left: 0px
35
+ # }
36
+ #
37
+ #
38
+ #
39
+ # body_div_p {
40
+ # padding '0px'
41
+ # }
42
+ # provide:
43
+ # body, div, p {
44
+ # padding: 0px
45
+ # }
46
+ #
47
+ #
48
+ # ugly, but no idea how to do better
49
+ # body{div{
50
+ # padding '0px'
51
+ # }}
52
+ # provide:
53
+ # body div {
54
+ # padding: 0px
55
+ # }
56
+ #
57
+ #
58
+ # includes for reusable styles
59
+ # inc! {
60
+ # color 'white'
61
+ # }
62
+ # _main {
63
+ # inc!
64
+ # text.align 'center'
65
+ # }
66
+ # provide:
67
+ # #main {
68
+ # color: white
69
+ # text-align: center
70
+ # }
71
+ require File.dirname(__FILE__)+'/tags'
72
+
73
+ class RSM
74
+ def initialize
75
+ @block = false
76
+ @prev_block = false
77
+ @styles = ''
78
+ @css = ''
79
+ @attr = false #for attrs with dash
80
+ @tag_class = false #for div.class
81
+ @includes = {}
82
+ end
83
+
84
+ def block= val
85
+ @block = val
86
+ end
87
+
88
+ def method_missing sym, *args, &block
89
+ if @block
90
+ if not block.nil? and @prev_block
91
+ #body{div{p{
92
+ process_style sym, *args, &block
93
+ end
94
+ @css += " {\r\n" if @prev_block
95
+ if block.nil?
96
+ if args.empty?
97
+ if @includes.include? sym
98
+ @css += @includes[sym]
99
+ else
100
+ @css+="\t#{sym}-"
101
+ @attr = true
102
+ end
103
+ else
104
+ @css += "\t" unless @attr
105
+ @css+="#{sym}: #{args.join(" ")}\r\n"
106
+ @attr = false
107
+ end
108
+ end
109
+ @prev_block = false
110
+ else
111
+ if block.nil? and args.empty?
112
+ @css += sym.to_s
113
+ elsif sym.to_s[-1] == ?!
114
+ r = RSM.new
115
+ r.block = true
116
+ r.markup &block
117
+ @includes[sym] = r.to_s
118
+ else
119
+ @block = true
120
+ @prev_block = true
121
+ process_style sym, args, &block
122
+ @block = false
123
+ @css += "}\r\n\r\n"
124
+ @tag_class = false
125
+ end
126
+ end
127
+ self
128
+ end
129
+
130
+ def process_style name, *args, &block
131
+ if name.to_s[0] == ?_
132
+ @css += "##{name.to_s[1..-1]}"
133
+ elsif Tags.include? name.to_s.split('_')[0].to_sym
134
+ @css += "." if @tag_class
135
+ @css += "#{name.to_s.split('_').join(', ')} "
136
+ @prev_class = true if block.nil?
137
+ @tag_class = true if block.nil?
138
+ else
139
+ @css += ".#{name} "
140
+ end
141
+ instance_eval &block unless block.nil?
142
+ end
143
+
144
+ def markup str=nil, &block
145
+ if str.nil?
146
+ instance_eval &block
147
+ else
148
+ instance_eval str
149
+ end
150
+ end
151
+
152
+ def to_s
153
+ @css
154
+ end
155
+ end
156
+ #r = RSM.new
157
+ #r.markup do
158
+ # _main {
159
+ # padding.left '0px'
160
+ # }
161
+ # main {
162
+ # padding.left '0px'
163
+ # }
164
+ # tr {
165
+ # padding.left '0px'
166
+ # }
167
+ # div.main {
168
+ # padding.left '0px'
169
+ # }
170
+ # body_div_p {
171
+ # padding '0px'
172
+ # }
173
+ # body{div{
174
+ # padding '0px'
175
+ # }}
176
+ # inc! {
177
+ # color 'white'
178
+ # }
179
+ # _main {
180
+ # inc!
181
+ # text.align 'center'
182
+ # }
183
+
184
+ #end
185
+ #puts r.to_s
data/lib/tags.rb ADDED
@@ -0,0 +1,418 @@
1
+ AttrI18n = [:lang, 'xml:lang'.to_sym, :dir]
2
+ AttrCore = [:id, :class, :style, :title]
3
+ AttrEvents = [:onclick, :ondblclick, :onmousedown, :onmouseup, :onmouseover, :onmousemove, :onmouseout, :onkeypress, :onkeydown, :onkeyup]
4
+ AttrFocus = [:accesskey, :tabindex, :onfocus, :onblur]
5
+ AttrCellAlign = [:align, :char, :charoff, :valign]
6
+
7
+ Attrs = AttrI18n + AttrCore + AttrEvents
8
+ AttrAll = [:xmlns, :profile, 'http-equip'.to_sym, :content, :scheme, :charset, :hreflang, :type, :rel, :rev, :media, 'xml:space'.to_sym, :src, :defer, :onload, :onuload, :cite, :datetime, :shape, :coords, :declare, :classid, :codebase, :data, :codetype, :archive, :standby, :height, :width, :usemap, :name, :value, :valuetype, :alt, :longdesc, :ismap, :nohref, :action, :method, :enctype, :onsubmit, :onreset, :accept, 'accept-charset'.to_sym, :for, :checked, :disabled, :readonly, :size, :maxlength, :onselect, :onchange, :multiple, :label, :selected, :summary, :border, :frame, :rules, :cellpadding, :cellspacing, :span, :abbr, :axis, :headers, :scope, :rowspan, :ccolspan] + Attrs + AttrFocus + AttrCellAlign
9
+
10
+ TagsSpecialPre = [:br, :span, :bdo, :map]
11
+ TagsSpecial = [:object, :img] + TagsSpecialPre
12
+ TagsFontStyle = [:tt, :i, :b, :big, :small]
13
+ TagsPhrase = [:em, :strong, :dfn, :code, :q, :samp, :kbd, :var, :cite, :abbr, :acronym, :sub, :sup]
14
+ TagsInlineForms = [:input, :select, :textarea, :label, :button]
15
+ TagsMiscInline = [:ins, :del, :script]
16
+ TagsMisc = [:noscript] + TagsMiscInline
17
+ TagsInline = [:a] + TagsSpecial + TagsFontStyle + TagsPhrase + TagsInlineForms
18
+ TagsInlineAll = [:pcdata] + TagsInline + TagsMiscInline
19
+ TagsHeading = [:h1, :h2, :h3, :h4, :h5, :h6]
20
+ TagsLists = [:ul, :ol, :dl]
21
+ TagsBlockText = [:pre, :hr, :blockquote, :address]
22
+ TagsBlock = [:p, :div, :table, :fieldset] + TagsHeading + TagsLists + TagsBlockText
23
+ TagsBlockAll = [:form] + TagsBlock + TagsMisc
24
+ TagsFlow = [:pcdata, :form] + TagsBlock + TagsInline + TagsMisc
25
+ TagsAContent = [:pcdata] + TagsSpecial + TagsFontStyle + TagsPhrase + TagsInlineForms + TagsMiscInline
26
+ TagsPreContent = [:pcdata, :a] + TagsFontStyle + TagsPhrase + TagsSpecialPre + TagsInlineForms + TagsMiscInline
27
+ TagsFormContent = TagsBlock + TagsMisc
28
+ TagsButtonContent = [:pcdata, :div, :table] + TagsHeading + TagsLists + TagsBlockText + TagsSpecial + TagsFontStyle + TagsPhrase + TagsMisc
29
+ TagsHeadMisc = [:script, :style, :meta, :link, :object]
30
+ #todo add tags
31
+ Tags = {
32
+ :html => {
33
+ :attrs => [:id, :xmlns] + AttrI18n,
34
+ :tags => [:head, :body],
35
+ :required_attrs => [],
36
+ },
37
+ :head => {
38
+ :attrs => [:id, :profile] + AttrI18n,
39
+ :tags => [:title, :base] + TagsHeadMisc,
40
+ :required_attrs => [],
41
+ },
42
+ :title => {
43
+ :attrs => [:id] + AttrI18n,
44
+ :tags => [:pcdata],
45
+ :required_attrs => [],
46
+ },
47
+ :base => {
48
+ :attrs => [:id, :href],
49
+ :tags => [],
50
+ :required_attrs => [:href],
51
+ },
52
+ :meta => {
53
+ :attrs => [:id, 'http-equip'.to_sym, :name, :content, :scheme] + AttrI18n,
54
+ :tags => [],
55
+ :required_attrs => [:content],
56
+ },
57
+ :link => {
58
+ :attrs => [:charset, :href, :hreflang, :type, :rel, :rev, :media] + Attrs,
59
+ :tags => [],
60
+ :required_attrs => [],
61
+ },
62
+ :style => {
63
+ :attrs => [:id, :type, :media, :title, 'xml:space'.to_sym] + AttrI18n,
64
+ :tags => [:pcdata],
65
+ :required_attrs => [:type],
66
+ },
67
+ :script => {
68
+ :attrs => [:id, :charset, :type, :src, :defer, 'xml:space'.to_sym],
69
+ :tags => [:pcdata],
70
+ :required_attrs => [:type],
71
+ },
72
+ :noscript => {
73
+ :attrs => Attrs,
74
+ :tags => TagsBlockAll,
75
+ :required_attrs => [],
76
+ },
77
+ :body => {
78
+ :attrs => [:onload, :onuload] + Attrs,
79
+ :tags => TagsBlockAll,
80
+ :required_attrs => [],
81
+ },
82
+ :div => {
83
+ :attrs => Attrs,
84
+ :tags => TagsFlow,
85
+ :required_attrs => [],
86
+ },
87
+ :p => {
88
+ :attrs => Attrs,
89
+ :tags => TagsInlineAll,
90
+ :required_attrs => [],
91
+ },
92
+ :h1 => {
93
+ :attrs => Attrs,
94
+ :tags => TagsInlineAll,
95
+ :required_attrs => [],
96
+ },
97
+ :h2 => {
98
+ :attrs => Attrs,
99
+ :tags => TagsInlineAll,
100
+ :required_attrs => [],
101
+ },
102
+ :h3 => {
103
+ :attrs => Attrs,
104
+ :tags => TagsInlineAll,
105
+ :required_attrs => [],
106
+ },
107
+ :h4 => {
108
+ :attrs => Attrs,
109
+ :tags => TagsInlineAll,
110
+ :required_attrs => [],
111
+ },
112
+ :h5 => {
113
+ :attrs => Attrs,
114
+ :tags => TagsInlineAll,
115
+ :required_attrs => [],
116
+ },
117
+ :h6 => {
118
+ :attrs => Attrs,
119
+ :tags => TagsInlineAll,
120
+ :required_attrs => [],
121
+ },
122
+ :ul => {
123
+ :attrs => Attrs,
124
+ :tags => [:li],
125
+ :required_attrs => [],
126
+ },
127
+ :ol => {
128
+ :attrs => Attrs,
129
+ :tags => [:li],
130
+ :required_attrs => [],
131
+ },
132
+ :li => {
133
+ :attrs => Attrs,
134
+ :tags => TagsFlow,
135
+ :required_attrs => [],
136
+ },
137
+ :dl => {
138
+ :attrs => Attrs,
139
+ :tags => [:dt, :dd],
140
+ :required_attrs => [],
141
+ },
142
+ :dt => {
143
+ :attrs => Attrs,
144
+ :tags => TagsInlineAll,
145
+ :required_attrs => [],
146
+ },
147
+ :dd => {
148
+ :attrs => Attrs,
149
+ :tags => TagsFlow,
150
+ :required_attrs => [],
151
+ },
152
+ :address => {
153
+ :attrs => Attrs,
154
+ :tags => TagsInlineAll,
155
+ :required_attrs => [],
156
+ },
157
+ :hr => {
158
+ :attrs => Attrs,
159
+ :tags => [],
160
+ :required_attrs => [],
161
+ },
162
+ :pre => {
163
+ :attrs => ['xml:space'.to_sym] + Attrs,
164
+ :tags => TagsPreContent,
165
+ :required_attrs => [],
166
+ },
167
+ :blockquote => {
168
+ :attrs => [:cite] + Attrs,
169
+ :tags => TagsBlockAll,
170
+ :required_attrs => [],
171
+ },
172
+ :ins => {
173
+ :attrs => [:cite, :datetime] + Attrs,
174
+ :tags => TagsFlow,
175
+ :required_attrs => [],
176
+ },
177
+ :del => {
178
+ :attrs => [:cite, :datetime] + Attrs,
179
+ :tags => TagsFlow,
180
+ :required_attrs => [],
181
+ },
182
+ :a => {
183
+ :attrs => [:charset, :type, :name, :href, :hreflang, :rel, :rev, :shape, :coords] + Attrs + AttrFocus,
184
+ :tags => TagsAContent,
185
+ :required_attrs => [],
186
+ },
187
+ :span => {
188
+ :attrs => Attrs,
189
+ :tags => TagsInlineAll,
190
+ :required_attrs => [],
191
+ },
192
+ :bdo => {
193
+ :attrs => [:lang, 'xml:lang'.to_sym, :dir] + AttrCore + AttrEvents,
194
+ :tags => TagsInlineAll,
195
+ :required_attrs => [:dir],
196
+ },
197
+ :br => {
198
+ :attrs => AttrCore,
199
+ :tags => [],
200
+ :required_attrs => [],
201
+ },
202
+ :strong => {
203
+ :attrs => Attrs,
204
+ :tags => TagsInlineAll,
205
+ :required_attrs => [],
206
+ },
207
+ :dfn => {
208
+ :attrs => Attrs,
209
+ :tags => TagsInlineAll,
210
+ :required_attrs => [],
211
+ },
212
+ :em => {
213
+ :attrs => Attrs,
214
+ :tags => TagsInlineAll,
215
+ :required_attrs => [],
216
+ },
217
+ :code => {
218
+ :attrs => Attrs,
219
+ :tags => TagsInlineAll,
220
+ :required_attrs => [],
221
+ },
222
+ :samp => {
223
+ :attrs => Attrs,
224
+ :tags => TagsInlineAll,
225
+ :required_attrs => [],
226
+ },
227
+ :kbd => {
228
+ :attrs => Attrs,
229
+ :tags => TagsInlineAll,
230
+ :required_attrs => [],
231
+ },
232
+ :var => {
233
+ :attrs => Attrs,
234
+ :tags => TagsInlineAll,
235
+ :required_attrs => [],
236
+ },
237
+ :cite => {
238
+ :attrs => Attrs,
239
+ :tags => TagsInlineAll,
240
+ :required_attrs => [],
241
+ },
242
+ :abbr => {
243
+ :attrs => Attrs,
244
+ :tags => TagsInlineAll,
245
+ :required_attrs => [],
246
+ },
247
+ :acronym => {
248
+ :attrs => Attrs,
249
+ :tags => TagsInlineAll,
250
+ :required_attrs => [],
251
+ },
252
+ :q => {
253
+ :attrs => [:cite] + Attrs,
254
+ :tags => TagsInlineAll,
255
+ :required_attrs => [],
256
+ },
257
+ :sub => {
258
+ :attrs => Attrs,
259
+ :tags => TagsInlineAll,
260
+ :required_attrs => [],
261
+ },
262
+ :sup => {
263
+ :attrs => Attrs,
264
+ :tags => TagsInlineAll,
265
+ :required_attrs => [],
266
+ },
267
+ :tt => {
268
+ :attrs => Attrs,
269
+ :tags => TagsInlineAll,
270
+ :required_attrs => [],
271
+ },
272
+ :i => {
273
+ :attrs => Attrs,
274
+ :tags => TagsInlineAll,
275
+ :required_attrs => [],
276
+ },
277
+ :b => {
278
+ :attrs => Attrs,
279
+ :tags => TagsInlineAll,
280
+ :required_attrs => [],
281
+ },
282
+ :big => {
283
+ :attrs => Attrs,
284
+ :tags => TagsInlineAll,
285
+ :required_attrs => [],
286
+ },
287
+ :small => {
288
+ :attrs => Attrs,
289
+ :tags => TagsInlineAll,
290
+ :required_attrs => [],
291
+ },
292
+ :object => {
293
+ :attrs => [:pcdata, :declare, :classid, :codebase, :data, :type, :codetype, :archive, :standby, :height, :width, :usemap, :name, :tabindex] + Attrs,
294
+ :tags => [:pcdata, :param, :form] + TagsBlock + TagsInline + TagsMisc,
295
+ :required_attrs => [],
296
+ },
297
+ :param => {
298
+ :attrs => [:id, :name, :value, :valuetype, :type],
299
+ :tags => [],
300
+ :required_attrs => [],
301
+ },
302
+ :img => {
303
+ :attrs => [:src, :alt, :longdesc, :height, :width, :usemap, :ismap] + Attrs,
304
+ :tags => [],
305
+ :required_attrs => [:src, :alt],
306
+ },
307
+ :map => {
308
+ :attrs => [:id, :class, :style, :title, :name] + AttrI18n + AttrEvents,
309
+ :tags => [:form, :area] + TagsBlock + TagsMisc,
310
+ :required_attrs => [:id],
311
+ },
312
+ :area => {
313
+ :attrs => [:shape, :coords, :href, :nohref, :alt] + Attrs + AttrFocus,
314
+ :tags => [],
315
+ :required_attrs => [:alt],
316
+ },
317
+ :map => {
318
+ :attrs => [:action, :method, :enctype, :onsubmit, :onreset, :accept, 'accept-charset'.to_sym] + Attrs,
319
+ :tags => TagsFormContent,
320
+ :required_attrs => [:action],
321
+ },
322
+ :label => {
323
+ :attrs => [:for, :accesskey, :onfocus, :onblur] + Attrs,
324
+ :tags => TagsInlineAll,
325
+ :required_attrs => [],
326
+ },
327
+ :input => {
328
+ :attrs => [:type, :name, :value, :checked, :disabled, :readonly, :size, :maxlength, :src, :alt, :usemap, :onselect, :onchange, :accept] + Attrs + AttrFocus,
329
+ :tags => [],
330
+ :required_attrs => [],
331
+ },
332
+ :select => {
333
+ :attrs => [:name, :size, :multiple, :disabled, :tabindex, :onfocus, :onblur, :onchange] + Attrs,
334
+ :tags => [:optgroup, :option],
335
+ :required_attrs => [],
336
+ },
337
+ :optgroup => {
338
+ :attrs => [:disable, :label] + Attrs,
339
+ :tags => [:option],
340
+ :required_attrs => [],
341
+ },
342
+ :option => {
343
+ :attrs => [:selected, :disabled, :label, :value] + Attrs,
344
+ :tags => [:pcdata],
345
+ :required_attrs => [],
346
+ },
347
+ :textarea => {
348
+ :attrs => [:name, :rows, :cols, :disabled, :readonly, :onselect, :onchange] + Attrs + AttrFocus,
349
+ :tags => [:pcdata],
350
+ :required_attrs => [:rows, :cols],
351
+ },
352
+ :fieldset => {
353
+ :attrs => Attrs,
354
+ :tags => [:pcdata, :legend, :form] + TagsBlock + TagsInline + TagsMisc,
355
+ :required_attrs => [],
356
+ },
357
+ :legend => {
358
+ :attrs => [:acceskey] + Attrs,
359
+ :tags => TagsInlineAll,
360
+ :required_attrs => [],
361
+ },
362
+ :button => {
363
+ :attrs => [:name, :value, :type, :disabled] + Attrs + AttrFocus,
364
+ :tags => TagsButtonContent,
365
+ :required_attrs => [],
366
+ },
367
+ :table => {
368
+ :attrs => [:summary, :width, :border, :frame, :rules, :cellpadding, :cellspacing] + Attrs,
369
+ :tags => [:caption, :col, :colgroup, :thead, :tfoot, :tbody, :tr],
370
+ :required_attrs => [],
371
+ },
372
+ :caption => {
373
+ :attrs => Attrs,
374
+ :tags => TagsInlineAll,
375
+ :required_attrs => [],
376
+ },
377
+ :thead => {
378
+ :attrs => AttrCellAlign + Attrs,
379
+ :tags => [:tr],
380
+ :required_attrs => [],
381
+ },
382
+ :tbody => {
383
+ :attrs => AttrCellAlign + Attrs,
384
+ :tags => [:tr],
385
+ :required_attrs => [],
386
+ },
387
+ :tfoot => {
388
+ :attrs => AttrCellAlign + Attrs,
389
+ :tags => [:tr],
390
+ :required_attrs => [],
391
+ },
392
+ :tr => {
393
+ :attrs => AttrCellAlign + Attrs,
394
+ :tags => [:td,:th],
395
+ :required_attrs => [],
396
+ },
397
+ :colgroup => {
398
+ :attrs => [:span, :width] + AttrCellAlign + Attrs,
399
+ :tags => [:col],
400
+ :required_attrs => [],
401
+ },
402
+ :col => {
403
+ :attrs => [:span, :width] + AttrCellAlign + Attrs,
404
+ :tags => [],
405
+ :required_attrs => [],
406
+ },
407
+ :th => {
408
+ :attrs => [:abbr, :axis, :headers, :scope, :rowspan, :ccolspan] + AttrCellAlign + Attrs,
409
+ :tags => TagsFlow,
410
+ :required_attrs => [],
411
+ },
412
+ :td => {
413
+ :attrs => [:abbr, :axis, :headers, :scope, :rowspan, :ccolspan] + AttrCellAlign + Attrs,
414
+ :tags => TagsFlow,
415
+ :required_attrs => [],
416
+ }
417
+ }
418
+
metadata ADDED
@@ -0,0 +1,57 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rml
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Ivan Sidorov
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-01-10 00:00:00 +08:00
13
+ default_executable: rml
14
+ dependencies: []
15
+
16
+ description: "RML: Ruby Markup Language. Pure ruby xhtml markup, but with one big difference. RML is aimed to provide valid and only valid xhtml 1.0 markup."
17
+ email: ivansid@gmail.com
18
+ executables:
19
+ - rml
20
+ extensions: []
21
+
22
+ extra_rdoc_files: []
23
+
24
+ files:
25
+ - lib/rml.rb
26
+ - lib/rsm.rb
27
+ - lib/tags.rb
28
+ - bin/rml
29
+ - lib/rml/sinatra.rb
30
+ has_rdoc: true
31
+ homepage: http://rml.rubyforge.org/
32
+ post_install_message:
33
+ rdoc_options: []
34
+
35
+ require_paths:
36
+ - lib
37
+ required_ruby_version: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: "0"
42
+ version:
43
+ required_rubygems_version: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: "0"
48
+ version:
49
+ requirements: []
50
+
51
+ rubyforge_project: rml
52
+ rubygems_version: 1.2.0
53
+ signing_key:
54
+ specification_version: 2
55
+ summary: "RML: Ruby Markup Language"
56
+ test_files: []
57
+