rml 0.1.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.
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
+