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