ubbparser 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (2) hide show
  1. data/lib/ubbparser.rb +447 -0
  2. metadata +45 -0
data/lib/ubbparser.rb ADDED
@@ -0,0 +1,447 @@
1
+ require "strscan"
2
+ require "securerandom"
3
+
4
+ # The UBBParser module converts UBB code into HTML. The parser is flexibel
5
+ # and adding new ubb codes is as easy as writing methods.
6
+ # Author:: Taco Jan Osinga, Osinga Software
7
+ #
8
+ # You can create your own ubbcodes by opening the module UBBParser and adding a method called render_xxx,
9
+ # where xxx is your ubb code of choice. The method should have the following arguments:
10
+ # (inner_text, attributes = {}, parse_options = {})
11
+ # inner_text:: Contains the text that's found between the opening and the closing tag.
12
+ # attributes:: A hash containing all the key-value attributes that are given.
13
+ # parse_options:: A hash containing the same parse_options that are used when UBBParser.parse() is called.
14
+ #
15
+ # *Example*
16
+ # The following example adds the ubb code \[sup\]...\[/sup], which wraps the inner_text with <sup> tags
17
+ #
18
+ # module UBBParser
19
+ # def render_sup(inner_text, attributes = {}, parse_options = {})
20
+ # "<sup>{inner_text}</sup>"
21
+ # end
22
+ # end
23
+ #
24
+ # When defining new ubb codes with a method and the name contains a dash, replace the dash by an underscore.
25
+ # I.e. the ubb code for img-left uses the method render_img_left
26
+
27
+ module UBBParser
28
+
29
+ # Converts a strings containing key-value-list into a hash. This function is mostly used by the parser itself.
30
+ # Attributes are given to the render methods as a hash.
31
+ def self.attrib_str_to_hash(attrib_str)
32
+ result = {:original_attrib_str => attrib_str.gsub(/^=/, "")}
33
+
34
+ attrib_str.insert(0, "default") if (attrib_str[0] == "=")
35
+ attrib_str.scan(/((\S*)=(\"[^\"]*\"|\'[^\']*\'|\S*))/) { | all, key, val |
36
+ result[(key.gsub(/-/, "_").to_sym rescue key)] = val.gsub(/^[\"\']/, "").gsub(/[\"\']$/, "")
37
+ }
38
+ return result
39
+ end
40
+
41
+ # Converts a hash into a string with key-values. You can use one of the following options:
42
+ # options[:allowed_keys]:: An array of keys that are only allowed
43
+ # options[:denied_keys]:: An array of keys that are denied
44
+ def self.hash_to_attrib_str(hash, options = {})
45
+ hash.delete_if { | k, v | !options[:allowed_keys].include?(k) } if options[:allowed_keys].is_a?(Array)
46
+ hash.delete_if { | k, v | options[:denied_keys].include?(k) } if options[:denied_keys].is_a?(Array)
47
+ return hash.map { | k, v | v = v.to_s.gsub(/\\|'/) { |c| "\\#{c}" }; "#{k}='#{v}'" }.join(" ");
48
+ end
49
+
50
+ # Parses the given text with ubb code into html. Use parse_options to specify a hash of options:
51
+ # parse_options\[:convert_newlines\]:: A boolean whether newlines should be convert into <br /> tags (default: true).
52
+ # parse_options\[:protect_email\]:: A boolean whether email addresses should be protected from spoofing using embedded JavaScript.
53
+ # parse_options\[:class_xxx\]:: A string with css class(es) that is embedded in the html for the tag xxx. Not all tags supports this.
54
+ # Replaces a dash in a tag with underscore (i.e. the class for img-left is defined in :class_img_left).
55
+ # {:class_code: "prettify linenums"} => <pre class='prettify linenums'>...</pre>
56
+ #
57
+ # When developing your own tags, you can also define your own parse_options.
58
+ def self.parse(text, parse_options = {})
59
+ result = ""
60
+ scnr = StringScanner.new(text)
61
+ parse_options.each { | k, v | v.to_s.gsub(/-/, "_").gsub(/[^\w]+/, "") if (k.to_s.start_with?("class_")); v }
62
+ while (!scnr.eos?)
63
+ untagged_text = scnr.scan(/[^\[]*/)
64
+
65
+ # convert newlines to breaks
66
+ untagged_text.gsub!(/\n/, "<br />") if (!parse_options.include?(:convert_newlines) || parse_options[:convert_newlines])
67
+
68
+ # check for untagged url's
69
+ uri_pattern = /(((http|https|ftp)\:\/\/)|(www))[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,4}(:[a-zA-Z0-9]*)?\/?([a-zA-Z0-9\-\._\?\,\'\/\\\+&amp;%\$#\=~])*[^\.\,\)\(\s]*/
70
+ untagged_text.gsub!(uri_pattern) { | url, | render_url(url, {}, parse_options) }
71
+
72
+ # check for untagged emails
73
+ email_pattern = /(([a-zA-Z0-9_\-\.\+]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?))/
74
+ untagged_text.gsub!(email_pattern) { | email, | render_email(email, {}, parse_options) }
75
+
76
+ result << untagged_text
77
+
78
+ # check for the upcoming ubb tag and process it (if valid tag)
79
+ if (scnr.match?(/\[/))
80
+ scnr.skip(/\[/)
81
+ code = scnr.scan(/[\w-]*/)
82
+ method_name = ("render_" + code.to_s.gsub(/-/, "_")).to_sym
83
+ if ((scnr.eos?) || (code == "") || (!self.respond_to?(method_name)))
84
+ result << "[" + code
85
+ else
86
+ attributes = self.attrib_str_to_hash(scnr.scan(/[^\]]*/))
87
+ scnr.skip(/\]/)
88
+ inner_text = scnr.scan_until(/\[\/#{code}\]/)
89
+ if inner_text.nil? #no closing tag found
90
+ inner_text = scnr.rest
91
+ scnr.terminate
92
+ else
93
+ inner_text.chomp!("[/#{code}]")
94
+ end
95
+ method_result = self.send(method_name, inner_text, attributes, parse_options).to_s
96
+ result << method_result
97
+ end
98
+ end
99
+ end
100
+ return result
101
+ end
102
+
103
+ # Returns true if the given value matches the given regular expression.
104
+ # :category: Validation methods
105
+ def self.matches_regexp?(value, regexp)
106
+ return !value.to_s.match(regexp).nil?
107
+ end
108
+
109
+ # Returns true if the given value is a valid email address
110
+ # :category: Validation methods
111
+ def self.is_email?(value)
112
+ return false if !value.is_a?(String)
113
+ return self.matches_regexp?(value, /^[-a-z0-9~!$%^&*_=+}{\'?]+(\.[-a-z0-9~!$%^&*_=+}{\'?]+)*@([a-z0-9_][-a-z0-9_]*(\.[-a-z0-9_]+)*\.(aero|arpa|biz|com|coop|edu|gov|info|int|mil|museum|name|net|org|pro|travel|mobi|[a-z][a-z])|([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}))(:[0-9]{1,5})?$/i)
114
+ end
115
+
116
+ # Returns true if the given value is a valid url
117
+ # :category: Validation methods
118
+ def self.is_url?(value)
119
+ return self.matches_regexp?(value, /^(http|https)\:\/\/([a-zA-Z0-9\.\-]+(\:[a-zA-Z0-9\.&amp;%\$\-]+)*@)*((25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])|localhost|([a-zA-Z0-9\-]+\.)*[a-zA-Z0-9\-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(\:[0-9]+)*(\/($|[a-zA-Z0-9\.\,\?\'\\\+&amp;%\$#\=~_\-]+))*$/)
120
+ end
121
+
122
+
123
+
124
+ # Converts the [anchor=myname]...[/anchor] tag into <a name='myname'>...</a>. Use the :class_anchor parse option to define html classes.
125
+ # :category: Render methods
126
+ def self.render_anchor(inner_text, attributes = {}, parse_options = {})
127
+ name = attributes[:default] || ""
128
+ name.inner_text.gsub!(/\\|'/) { |c| "\\#{c}" }
129
+ "<a name='#{name}' class='#{parse_options[:class_anchor].to_s.strip}'>#{self.parse(inner_text, parse_options)}</a>"
130
+ end
131
+
132
+ # Converts the url in the inner_text into a webplayer, playing the audio file.
133
+ # :category: Render methods
134
+ def self.render_audio(inner_text, attributes = {}, parse_options = {})
135
+ # Not yet implemented
136
+ end
137
+
138
+ # Renders the inner_text bold (using <strong>).
139
+ # :category: Render methods
140
+ def self.render_b(inner_text, attributes = {}, parse_options = {})
141
+ "<strong>#{self.parse(inner_text, parse_options)}</strong>"
142
+ end
143
+
144
+ # Converts [br] into a <br />.
145
+ # :category: Render methods
146
+ def self.render_br(inner_text, attributes = {}, parse_options = {})
147
+ "<br />#{self.parse(inner_text, parse_options)}"
148
+ end
149
+
150
+ # Converts all lines in the inner_text as a bullet list. Each line represents one list item. Empty lines are ignored. Use the :class_bullet parse option to define html classes.
151
+ # :category: Render methods
152
+ def self.render_bullets(inner_text, attributes = {}, parse_options = {})
153
+ items = inner_text.split(/\n/)
154
+ items.delete_if { | item | item.strip == "" }
155
+ items.map! { | item | "<li>" + self.parse(item, parse_options) + "</li>" }
156
+ return (items.empty?) ? "" : "<ul class='#{parse_options[:class_bullets].to_s.strip}'>" + items.join("") + "</ul>"
157
+ end
158
+
159
+ # Centers the inner_text.
160
+ # :category: Render methods
161
+ def self.render_center(inner_text, attributes = {}, parse_options = {})
162
+ "<div style='text-align: center'>#{self.parse(inner_text, parse_options)}</div>"
163
+ end
164
+
165
+ # Assures the inner_text is rendered below floating elements.
166
+ # :category: Render methods
167
+ def self.render_clear(inner_text, attributes = {}, parse_options = {})
168
+ "<div style='clear: both'></div>"
169
+ end
170
+
171
+ # Changes the font color of the inner_text
172
+ # :category: Render methods
173
+ def self.render_color(inner_text, attributes = {}, parse_options = {})
174
+ "<div style='color:#{attributes[:default]}'>#{self.parse(inner_text, parse_options)}</div>"
175
+ end
176
+
177
+ # Ignores all the inner_text
178
+ # :category: Render methods
179
+ def self.render_comment(inner_text, attributes = {}, parse_options = {})
180
+ ""
181
+ end
182
+
183
+ # Places the inner_text in a fixed font type. Also adds the classes prettify and linenums for styling purposes. Use the :class_code parse option to define html classes.
184
+ # :category: Render methods
185
+ def self.render_code(inner_text, attributes = {}, parse_options = {})
186
+ "<pre class='#{parse_options[:class_code].to_s.strip}'>#{inner_text}</pre>"
187
+ end
188
+
189
+ # Renders csv-data into a html table. You can use the following attributes:
190
+ # has_header: The first row should be rendered as header cells (using th).
191
+ # :category: Render methods
192
+ def self.render_csv(inner_text, attributes = {}, parse_options = {})
193
+ head_cells = body_cells = ""
194
+ cell_tag = (attributes[:has_header] || true) ? "th" : "td"
195
+ lines = inner_text.split(/\n/)
196
+ csv_pattern = /(\"[^\"]*\"|\'[^\']*\'|[^\n\r,]+)[,\n]?/
197
+ lines.each { | line |
198
+ cells = attrib_str.scan(csv_pattern) { | item | "<#{cell_tag}>#{item}</#{cell_tag}>" }
199
+ cells = "<tr>#{cells}</tr>"
200
+ if (cell_tag == "th")
201
+ head_cells += cells
202
+ else
203
+ body_cells += cells
204
+ end
205
+ cell_tag = "td"
206
+ }
207
+ result = ""
208
+ if (!head_cells.empty? || !body_cells.empty?)
209
+ result = "<table class='#{parse_options[:class_csv].to_s.strip}'>"
210
+ result += "<thead>#{head_cells}</thead>" if (!head_cells.empty?)
211
+ result += "<tbody>#{body_cells}</tbody>"
212
+ result = "</table>"
213
+ end
214
+ return result
215
+ end
216
+
217
+ # Renders an email address. There are two options to define:
218
+ # [email]info@osingasoftware.nl[/email]
219
+ # [email=info@osingasoftware.nl]Osinga Software[/email]
220
+ # By default the email address is protected against spoofing, using JavaScript. Use the :class_email parse option to define html classes.
221
+ # :category: Render methods
222
+ def self.render_email(inner_text, attributes = {}, parse_options = {})
223
+ email = (attributes[:default] || inner_text)
224
+ if (!self.is_email?(email))
225
+ parse_options[:class_email] = parse_options[:class_email].to_s + " ubbparser-error"
226
+ result = "<span class='#{parse_options[:class_email].to_s.strip}'>UBB error: invalid email address #{email}</span>"
227
+ elsif ((parse_options.has_key?(:protect_email) && !parse_options[:protect_email]) || (attributes[:protected] == "false"))
228
+ result = "<a href='mailto:#{email}' class='#{parse_options[:class_email].to_s.strip}'>#{inner_text}</a>"
229
+ else
230
+ username, domain = email.split("@", 2)
231
+ id = "ubb-email-" + SecureRandom.hex(16)
232
+
233
+ # Some generic javascript so every browser can parse this (instantly), regardless of used framework
234
+ title = (inner_text == email) ? "protected email address" : inner_text
235
+ script = "<script type='text/javascript'>obj=document.getElementById(\"#{id}\");email=obj.getAttribute(\"data-username\")+\"@\"+obj.getAttribute(\"data-domain\");obj.href=\"mailto:\"+email;obj.innerHTML=\"#{title}\"</script>";
236
+ result = "<a id='#{id}' class='#{parse_options[:class_email].to_s.strip}' href='#' data-username='#{username}' data-domain='#{domain}'>#{title}</a>#{script}"
237
+ end
238
+ return result
239
+ end
240
+
241
+ # Renders the inner_text in the specified list. The list should contain CSS style font-families, i.e.:
242
+ # [font=Arial, Helvetica, Sans]...[/font]
243
+ # :category: Render methods
244
+ def self.render_font(inner_text, attributes = {}, parse_options = {})
245
+ font = attributes[:original_attrib_str].gsub!(/\\|'/) { |c| "\\#{c}" }
246
+ "<span style='font-family: #{font}'>#{self.parse(inner_text, parse_options)}</span>"
247
+ end
248
+
249
+ # Renders the inner_text in a H1 heading.
250
+ # :category: Render methods
251
+ def self.render_h1(inner_text, attributes = {}, parse_options = {})
252
+ "<h1>#{self.parse(inner_text, parse_options)}</h1>"
253
+ end
254
+
255
+ # Renders the inner_text in a H2 heading.
256
+ # :category: Render methods
257
+ def self.render_h2(inner_text, attributes = {}, parse_options = {})
258
+ "<h2>#{self.parse(inner_text, parse_options)}</h2>"
259
+ end
260
+
261
+ # Renders the inner_text in a H3 heading.
262
+ # :category: Render methods
263
+ def self.render_h3(inner_text, attributes = {}, parse_options = {})
264
+ "<h3>#{self.parse(inner_text, parse_options)}</h3>"
265
+ end
266
+
267
+ # Renders a horizontal ruler.
268
+ # :category: Render methods
269
+ def self.render_hr(inner_text, attributes = {}, parse_options = {})
270
+ "<hr />#{self.parse(inner_text, parse_options)}"
271
+ end
272
+
273
+ # Renders the inner_text in italic.
274
+ # :category: Render methods
275
+ def self.render_i(inner_text, attributes = {}, parse_options = {})
276
+ "<em>#{self.parse(inner_text, parse_options)}</em>"
277
+ end
278
+
279
+ # Renders an iframe. Use the inner_text as source. Use the :class_iframe parse option to define html classes.
280
+ # :category: Render methods
281
+ def self.render_iframe(inner_text, attributes = {}, parse_options = {})
282
+ src = inner_text
283
+ src = "http://" + src if (src.match(/^www\./))
284
+ src.gsub!(/\\|'/) { |c| "\\#{c}" }
285
+ attributes[:src] = inner_text
286
+ attributes[:class] = (attributes[:class].to_s + " " + parse_options[:class_iframe].to_s).strip if ((!attributes.has_key?(:skip_class)) || !attributes[:skip_class])
287
+ attrib_str = self.hash_to_attrib_str(attributes, :allowed_keys => [:src, :class, :frameborder, :marginwidth, :marginheight, :width, :height])
288
+ return "<iframe #{attrib_str}></iframe>"
289
+ end
290
+
291
+ # Doesn't render the ubb code in the inner_text. It does strip all html-tags from the inner_text
292
+ # :category: Render methods
293
+ def self.render_ignore(inner_text, attributes = {}, parse_options = {})
294
+ inner_text
295
+ end
296
+
297
+ # Renders an image. Use the :class_img parse option to define html classes.
298
+ # :category: Render methods
299
+ def self.render_img(inner_text, attributes = {}, parse_options = {})
300
+ url = inner_text
301
+ url = "" if (!self.is_url?(inner_text))
302
+ attributes[:src] = inner_text.gsub(/\\|'/) { |c| "\\#{c}" }
303
+ attributes[:alt] ||= ""
304
+ attributes[:class] = parse_options[:class_img] if ((!attributes.has_key?(:skip_class)) || !attributes[:skip_class])
305
+ attrib_str = self.hash_to_attrib_str(attributes, :allowed_keys => [:src, :alt, :styles, :class])
306
+ return "<img #{attrib_str} />"
307
+ end
308
+
309
+ # Renders an image, floated on the left side of the text frame. Use the :class_img_left parse option to define html classes.
310
+ # :category: Render methods
311
+ def self.render_img_left(inner_text, attributes = {}, parse_options = {})
312
+ attributes[:styles] = "float: left; margin: 0px 10px 10px 0px"
313
+ attributes[:class] += " " + parse_options[:class_img_left]
314
+ attributes[:skip_class] = true
315
+ render_img(inner_text, attributes, parse_options)
316
+ end
317
+
318
+ # Renders an image, floated on the right side of the text frame. Use the :class_img_right parse option to define html classes.
319
+ # :category: Render methods
320
+ def self.render_img_right(inner_text, attributes = {}, parse_options = {})
321
+ attributes[:styles] = "float: left; margin: 0px 0px 10px 10px"
322
+ attributes[:class] += " " + parse_options[:class_img_right]
323
+ attributes[:skip_class] = true
324
+ render_img(inner_text, attributes, parse_options)
325
+ end
326
+
327
+ # Renders the inner_text with a justified text alignment.
328
+ # :category: Render methods
329
+ def self.render_justify(inner_text, attributes = {}, parse_options = {})
330
+ "<div style='text-align: justify'>#{self.parse(inner_text, parse_options)}</div>"
331
+ end
332
+
333
+ # Renders the inner_text with a left text alignment.
334
+ # :category: Render methods
335
+ def self.render_left(inner_text, attributes = {}, parse_options = {})
336
+ "<div style='text-align: left'>#{self.parse(inner_text, parse_options)}</div>"
337
+ end
338
+
339
+ # Renders the inner_text as an ordered list. Each line represents a list item. Use the :class_list parse option to define html classes.
340
+ # :category: Render methods
341
+ def self.render_list(inner_text, attributes = {}, parse_options = {})
342
+ items = inner_text.split(/\n/)
343
+ items.delete_if { | item | item.strip == "" }
344
+ items.map! { | item | "<li>" + self.parse(item, parse_options) + "</li>" }
345
+ return (items.empty?) ? "" : "<ul class='#{parse_options[:class_list].to_s.strip}'>" + items.join("") + "</ol>"
346
+ end
347
+
348
+ # Renders the inner_text as a paragraph. Use the :class_p parse option to define html classes.
349
+ # :category: Render methods
350
+ def self.render_p(inner_text, attributes = {}, parse_options = {})
351
+ "<p class='#{parse_options[:class_p].to_s.strip}'>#{self.parse(inner_text, parse_options)}</p>"
352
+ end
353
+
354
+ # Renders the inner_text with a right text alignment.
355
+ # :category: Render methods
356
+ def self.render_right(inner_text, attributes = {}, parse_options = {})
357
+ "<div style='text-align: right'>#{self.parse(inner_text, parse_options)}</div>"
358
+ end
359
+
360
+ # Renders the inner_text in a <div> block with inline CSS styles, i.e.:
361
+ # [style color: red; border: 1px solid green]...[/style]
362
+ # :category: Render methods
363
+ def self.render_style(inner_text, attributes = {}, parse_options = {})
364
+ styles = attributes[:original_attrib_str].gsub(/'/, "\'")
365
+ "<div style='#{styles}'>#{self.parse(inner_text, parse_options)}</div>"
366
+ end
367
+
368
+ # Converts the [table] to a <table>. Always use this in combination with [tr] and [td] or [th]. Use the :class_table parse option to define html classes.
369
+ # [style color: red; border: 1px solid green]...[/style]
370
+ # :category: Render methods
371
+ def self.render_table(inner_text, attributes = {}, parse_options = {})
372
+ styles = attributes[:default].gsub(/'/, "\'")
373
+ "<div style='#{styles}' class='#{parse_options[:class_table].to_s.strip}'>#{self.parse(inner_text, parse_options)}</div>"
374
+ end
375
+
376
+ # Renders the inner_text underline. Use this with caution, since underline text is associated with hyperlinks.
377
+ # :category: Render methods
378
+ def self.render_u(inner_text, attributes = {}, parse_options = {})
379
+ "<u>#{self.parse(inner_text, parse_options)}</u>"
380
+ end
381
+
382
+ # Renders a web addres. There are two options to define:
383
+ # [url]www.osingasoftware.nl[/ur]
384
+ # [url=www.osingasoftware.nl]Osinga Software[/url]
385
+ # Use the :class_url parse option to define html classes.
386
+ # :category: Render methods
387
+ def self.render_url(inner_text, attributes = {}, parse_options = {})
388
+ url = (attributes[:default] || inner_text)
389
+ url = "http://" + url if (url.match(/^www\./))
390
+ url.gsub!(/\\|'/) { |c| "\\#{c}" }
391
+ return "<a href='#{url}' class='#{parse_options[:class_url].to_s.strip}'>#{inner_text}</a>"
392
+ end
393
+
394
+ # Renders a YouTube video using the video id or url in the inner_text.
395
+ # :category: Render methods
396
+ def self.render_vimeo(inner_text, attributes = {}, parse_options = {})
397
+ attributes[:width] ||= 500
398
+ attributes[:height] ||= 281
399
+ attributes[:class] = parse_options[:class_vimeo]
400
+ attributes[:skip_class] = true
401
+ videoid = (inner_text.scan(/[0-9]{5,}/).to_a)[0].to_s
402
+ src = "http://player.vimeo.com/video/#{videoid}"
403
+ return render_iframe(src, attributes, parse_options)
404
+ end
405
+
406
+ # Renders a YouTube video using the video id or url in the inner_text.
407
+ # :category: Render methods
408
+ def self.render_youtube(inner_text, attributes = {}, parse_options = {})
409
+ attributes[:width] ||= 560
410
+ attributes[:height] ||= 315
411
+ attributes[:class] = parse_options[:class_youtube]
412
+ attributes[:skip_class] = true
413
+ videoid = !inner_text.match(/^[^\?\&]$/).nil? ? inner_text : inner_text.scan(/(\?|&)v=([^\&]*)/)[0][1]
414
+ src = "http://www.youtube.com/embed/#{videoid}"
415
+ return render_iframe(src, attributes, parse_options)
416
+ end
417
+
418
+ # Renders a Youtube, Vimeo or Zideo video using the video id or url in the inner_text.
419
+ # It automatically determines which video renderer should be used based on the given url.
420
+ # :category: Render methods
421
+ def self.render_video(inner_text, attributes = {}, parse_options = {})
422
+ attributes[:class] += " " + parse_options[:class_zideo]
423
+ url = inner_text
424
+ if (!url.match(/zideo\.nl/).nil?)
425
+ return self.render_zideo(inner_text, attributes, parse_options)
426
+ elsif (!url.match(/[0-9]{5,}/).nil?) || (!url.match(/vimeo/).nil?)
427
+ return self.render_vimeo(inner_text, attributes, parse_options)
428
+ elsif (!url.match(/youtu/).nil?) || (!url.match(/^[^\?\&]+{11}$/).nil?)
429
+ return self.render_youtube(inner_text, attributes, parse_options)
430
+ else
431
+ return "Unknown video"
432
+ end
433
+ end
434
+
435
+ # Renders a zideo.nl video using the video id or url in the inner_text.
436
+ # :category: Render methods
437
+ def self.render_zideo(inner_text, attributes = {}, parse_options = {})
438
+ attributes[:width] ||= 480
439
+ attributes[:height] ||= 360
440
+ attributes[:class] += " " + parse_options[:class_zideo]
441
+ attributes[:skip_class] = true
442
+ videoid = !inner_text.match(/^\w+$/).nil? ? inner_text : (inner_text.scan(/playzideo\/(\w+)/).to_a)[1].to_s
443
+ src = "http://www.zideo.nl/zideomediaplayer.php?" + inner_text
444
+ return render_iframe(src, attributes, parse_options)
445
+ end
446
+
447
+ end
metadata ADDED
@@ -0,0 +1,45 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ubbparser
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.5
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Taco Jan Osinga
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-01-16 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: A simple and flexibel ubb parser.
15
+ email: info@osingasoftware.nl
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - lib/ubbparser.rb
21
+ homepage: http://ubbparser.mojura.nl
22
+ licenses: []
23
+ post_install_message:
24
+ rdoc_options: []
25
+ require_paths:
26
+ - lib
27
+ required_ruby_version: !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ required_rubygems_version: !ruby/object:Gem::Requirement
34
+ none: false
35
+ requirements:
36
+ - - ! '>='
37
+ - !ruby/object:Gem::Version
38
+ version: '0'
39
+ requirements: []
40
+ rubyforge_project:
41
+ rubygems_version: 1.8.11
42
+ signing_key:
43
+ specification_version: 3
44
+ summary: UBB Parser
45
+ test_files: []