ubbparser 0.0.5

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 (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: []