ruby-bbcode 2.0.0 → 2.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.
- checksums.yaml +5 -5
- data/CHANGELOG.md +31 -2
- data/README.md +66 -0
- data/Rakefile +2 -4
- data/lib/ruby-bbcode.rb +48 -28
- data/lib/ruby-bbcode/bbtree.rb +20 -12
- data/lib/ruby-bbcode/configuration.rb +18 -0
- data/lib/ruby-bbcode/tag_collection.rb +9 -9
- data/lib/ruby-bbcode/tag_info.rb +49 -18
- data/lib/ruby-bbcode/tag_node.rb +4 -4
- data/lib/ruby-bbcode/tag_sifter.rb +80 -57
- data/lib/ruby-bbcode/templates/bbcode_errors_template.rb +20 -17
- data/lib/ruby-bbcode/templates/html_template.rb +36 -10
- data/lib/ruby-bbcode/version.rb +1 -1
- data/lib/tags/tags.rb +126 -104
- data/test/ruby_bbcode_bbcode_test.rb +39 -16
- data/test/ruby_bbcode_html_test.rb +68 -40
- data/test/ruby_bbcode_validity_test.rb +22 -19
- data/test/test_helper.rb +4 -5
- data/test/unit/configuration_test.rb +37 -0
- data/test/unit/tag_sifter_test.rb +7 -9
- data/test/unit/tags_test.rb +2 -2
- metadata +76 -18
- data/README.textile +0 -56
data/lib/ruby-bbcode/tag_node.rb
CHANGED
@@ -15,7 +15,7 @@ module RubyBBCode
|
|
15
15
|
# and a tag element has the form of
|
16
16
|
# { :is_tag=>true, :tag=>:i, :nodes => [] }
|
17
17
|
# * +nodes+
|
18
|
-
def initialize(element
|
18
|
+
def initialize(element)
|
19
19
|
@element = element
|
20
20
|
end
|
21
21
|
|
@@ -39,12 +39,12 @@ module RubyBBCode
|
|
39
39
|
|
40
40
|
# Returns true if the tag does not have any parameters set.
|
41
41
|
def params_not_set?
|
42
|
-
@element[:params].
|
42
|
+
@element[:params].empty?
|
43
43
|
end
|
44
44
|
|
45
|
-
# Returns true
|
45
|
+
# Returns true if the node that child nodes
|
46
46
|
def has_children?
|
47
|
-
type == :tag
|
47
|
+
(type == :tag) && !children.empty?
|
48
48
|
end
|
49
49
|
|
50
50
|
# Returns true when the quick parameter was invalid (i.e. it did not match the required format)
|
@@ -8,10 +8,10 @@ module RubyBBCode
|
|
8
8
|
attr_reader :bbtree, :errors
|
9
9
|
|
10
10
|
def initialize(text_to_parse, dictionary, escape_html = true)
|
11
|
-
@text = escape_html ? text_to_parse.gsub('<', '<').gsub('>', '>').gsub('"',
|
11
|
+
@text = escape_html ? text_to_parse.gsub('<', '<').gsub('>', '>').gsub('"', '"') : text_to_parse
|
12
12
|
|
13
13
|
@dictionary = dictionary # dictionary containing all allowed/defined tags
|
14
|
-
@bbtree = BBTree.new(
|
14
|
+
@bbtree = BBTree.new(nodes: TagCollection.new)
|
15
15
|
@ti = nil
|
16
16
|
@errors = []
|
17
17
|
end
|
@@ -25,34 +25,33 @@ module RubyBBCode
|
|
25
25
|
# once this tree is built, the to_html method can be invoked where the tree is finally
|
26
26
|
# converted into HTML syntax.
|
27
27
|
def process_text
|
28
|
-
|
29
|
-
@text.scan(/#{regex_string}/ix) do |tag_info|
|
28
|
+
@text.scan(TagInfo::REGEX) do |tag_info|
|
30
29
|
@ti = TagInfo.new(tag_info, @dictionary)
|
31
30
|
|
32
|
-
# if the tag isn't in the @dictionary list, then treat it as text
|
33
|
-
@ti.handle_tag_as_text if @ti.element_is_tag? and !@ti.tag_in_dictionary?
|
34
|
-
|
35
31
|
validate_element
|
36
32
|
|
37
33
|
case @ti.type
|
38
34
|
when :opening_tag
|
39
|
-
element = {:
|
35
|
+
element = { is_tag: true, tag: @ti[:tag], definition: @ti.definition, opening_whitespace: @ti.whitespace, errors: @ti[:errors], nodes: TagCollection.new }
|
40
36
|
element[:invalid_quick_param] = true if @ti.invalid_quick_param?
|
41
37
|
element[:params] = get_formatted_element_params
|
42
38
|
|
43
|
-
|
39
|
+
if self_closing_tag_reached_a_closer?
|
40
|
+
transfer_whitespace_to_closing_tag
|
41
|
+
@bbtree.retrogress_bbtree
|
42
|
+
end
|
44
43
|
|
45
44
|
@bbtree.build_up_new_tag(element)
|
46
45
|
|
47
46
|
@bbtree.escalate_bbtree(element)
|
48
47
|
when :text
|
49
48
|
tag_def = @bbtree.current_node.definition
|
50
|
-
if tag_def
|
49
|
+
if tag_def && (tag_def[:multi_tag] == true)
|
51
50
|
set_multi_tag_to_actual_tag
|
52
51
|
tag_def = @bbtree.current_node.definition
|
53
52
|
end
|
54
53
|
|
55
|
-
if within_open_tag?
|
54
|
+
if within_open_tag? && tag_def[:require_between]
|
56
55
|
between = get_formatted_between
|
57
56
|
@bbtree.current_node[:between] = between
|
58
57
|
if use_text_as_parameter?
|
@@ -63,7 +62,7 @@ module RubyBBCode
|
|
63
62
|
add_element = true
|
64
63
|
|
65
64
|
# ...and clear between, as this would result in two 'between' texts
|
66
|
-
@bbtree.current_node[:between] =
|
65
|
+
@bbtree.current_node[:between] = ''
|
67
66
|
end
|
68
67
|
else
|
69
68
|
# Between text can be used as (first) parameter
|
@@ -76,16 +75,20 @@ module RubyBBCode
|
|
76
75
|
|
77
76
|
create_text_element
|
78
77
|
when :closing_tag
|
78
|
+
@bbtree.current_node[:closing_whitespace] = @ti.whitespace
|
79
79
|
if @ti[:wrong_closing]
|
80
80
|
# Convert into text, so it
|
81
81
|
@ti.handle_tag_as_text
|
82
82
|
create_text_element
|
83
83
|
else
|
84
|
-
|
84
|
+
if parent_of_self_closing_tag? && within_open_tag?
|
85
|
+
transfer_whitespace_to_closing_tag
|
86
|
+
@bbtree.retrogress_bbtree
|
87
|
+
end
|
85
88
|
@bbtree.retrogress_bbtree
|
86
89
|
end
|
87
90
|
end
|
88
|
-
end
|
91
|
+
end
|
89
92
|
|
90
93
|
validate_all_tags_closed_off
|
91
94
|
validate_stack_level_too_deep_potential
|
@@ -93,6 +96,25 @@ module RubyBBCode
|
|
93
96
|
|
94
97
|
private
|
95
98
|
|
99
|
+
def transfer_whitespace_to_closing_tag
|
100
|
+
last_text_node = node_last_text(parent_tag)
|
101
|
+
unless last_text_node.nil?
|
102
|
+
last_text_node[:text].scan(/(\s+)$/) do |result|
|
103
|
+
parent_tag[:closing_whitespace] = result[0]
|
104
|
+
last_text_node[:text] = last_text_node[:text][0..-result[0].length - 1]
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
# Return the node that holds the last piece of text for the given node (self or child)
|
110
|
+
def node_last_text(node)
|
111
|
+
return node if node.type == :text
|
112
|
+
return node_last_text(node.children[-1]) unless node.children.empty?
|
113
|
+
|
114
|
+
# node does not hold text
|
115
|
+
nil
|
116
|
+
end
|
117
|
+
|
96
118
|
def set_multi_tag_to_actual_tag
|
97
119
|
# Try to find the actual tag
|
98
120
|
tag = get_actual_tag
|
@@ -121,7 +143,7 @@ module RubyBBCode
|
|
121
143
|
end
|
122
144
|
|
123
145
|
def create_text_element
|
124
|
-
element = {:
|
146
|
+
element = { is_tag: false, text: @ti.text, errors: @ti[:errors] }
|
125
147
|
@bbtree.build_up_new_tag(element)
|
126
148
|
end
|
127
149
|
|
@@ -132,26 +154,26 @@ module RubyBBCode
|
|
132
154
|
# perform special formatting for certain tags
|
133
155
|
params[:url] = match_url_id(params[:url], @ti.definition[:url_matches])
|
134
156
|
end
|
135
|
-
|
157
|
+
params
|
136
158
|
end
|
137
159
|
|
138
160
|
# Get 'between tag' for tag
|
139
161
|
def get_formatted_between
|
140
162
|
between = @ti[:text]
|
141
|
-
# perform special formatting for
|
163
|
+
# perform special formatting for certain tags
|
142
164
|
between = match_url_id(between, @bbtree.current_node.definition[:url_matches]) if @bbtree.current_node.definition[:url_matches]
|
143
|
-
|
165
|
+
between
|
144
166
|
end
|
145
167
|
|
146
168
|
def match_url_id(url, regex_matches)
|
147
169
|
regex_matches.each do |regex|
|
148
170
|
if url =~ regex
|
149
|
-
id =
|
171
|
+
id = Regexp.last_match(1)
|
150
172
|
return id
|
151
173
|
end
|
152
174
|
end
|
153
175
|
|
154
|
-
|
176
|
+
url # if we couldn't find a match, then just return the url, hopefully it's a valid ID...
|
155
177
|
end
|
156
178
|
|
157
179
|
# Validates the element
|
@@ -162,7 +184,7 @@ module RubyBBCode
|
|
162
184
|
end
|
163
185
|
|
164
186
|
def valid_text_or_opening_element?
|
165
|
-
if @ti.element_is_text?
|
187
|
+
if @ti.element_is_text? || @ti.element_is_opening_tag?
|
166
188
|
return false unless valid_opening_tag?
|
167
189
|
return false unless valid_constraints_on_child?
|
168
190
|
end
|
@@ -171,7 +193,7 @@ module RubyBBCode
|
|
171
193
|
|
172
194
|
def valid_opening_tag?
|
173
195
|
if @ti.element_is_opening_tag?
|
174
|
-
if @ti.only_allowed_in_parent_tags?
|
196
|
+
if @ti.only_allowed_in_parent_tags? && (!within_open_tag? || !@ti.allowed_in?(parent_tag[:tag])) && !self_closing_tag_reached_a_closer?
|
175
197
|
# Tag doesn't belong in the last opened tag
|
176
198
|
throw_child_requires_specific_parent_error
|
177
199
|
return false
|
@@ -183,19 +205,15 @@ module RubyBBCode
|
|
183
205
|
end
|
184
206
|
|
185
207
|
# Note that if allow_between_as_param is true, other checks already test the (correctness of the) 'between parameter'
|
186
|
-
unless @ti.definition[:param_tokens].nil?
|
208
|
+
unless @ti.definition[:param_tokens].nil? || (@ti.definition[:allow_between_as_param] == true)
|
187
209
|
# Check if all required parameters are added
|
188
210
|
@ti.definition[:param_tokens].each do |token|
|
189
|
-
if @ti[:params][token[:token]].nil?
|
190
|
-
add_tag_error "Tag [#{@ti[:tag]}] must have '#{token[:token]}' parameter"
|
191
|
-
end
|
211
|
+
add_tag_error "Tag [#{@ti[:tag]}] must have '#{token[:token]}' parameter" if @ti[:params][token[:token]].nil? && token[:optional].nil?
|
192
212
|
end
|
193
213
|
|
194
214
|
# Check if no 'custom parameters' are added
|
195
215
|
@ti[:params].keys.each do |token|
|
196
|
-
if @ti.definition[:param_tokens].find {|param_token| param_token[:token]==token}.nil?
|
197
|
-
add_tag_error "Tag [#{@ti[:tag]}] doesn't have a '#{token}' parameter"
|
198
|
-
end
|
216
|
+
add_tag_error "Tag [#{@ti[:tag]}] doesn't have a '#{token}' parameter" if @ti.definition[:param_tokens].find { |param_token| param_token[:token] == token }.nil?
|
199
217
|
end
|
200
218
|
end
|
201
219
|
end
|
@@ -203,15 +221,15 @@ module RubyBBCode
|
|
203
221
|
end
|
204
222
|
|
205
223
|
def self_closing_tag_reached_a_closer?
|
206
|
-
@ti.definition[:self_closable]
|
224
|
+
@ti.definition[:self_closable] && (@bbtree.current_node[:tag] == @ti[:tag])
|
207
225
|
end
|
208
226
|
|
209
227
|
def valid_constraints_on_child?
|
210
|
-
if within_open_tag?
|
228
|
+
if within_open_tag? && parent_has_constraints_on_children?
|
211
229
|
# Check if the found tag is allowed
|
212
230
|
last_tag_def = parent_tag[:definition]
|
213
231
|
allowed_tags = last_tag_def[:only_allow]
|
214
|
-
if (!@ti
|
232
|
+
if (!@ti.element_is_tag? && (last_tag_def[:require_between] != true) && (@ti[:text].lstrip != '')) || (@ti.element_is_tag? && (allowed_tags.include?(@ti[:tag]) == false)) # TODO: refactor this, it's just too long
|
215
233
|
# Last opened tag does not allow tag
|
216
234
|
throw_parent_prohibits_this_child_error
|
217
235
|
return false
|
@@ -221,7 +239,6 @@ module RubyBBCode
|
|
221
239
|
end
|
222
240
|
|
223
241
|
def valid_closing_element?
|
224
|
-
|
225
242
|
if @ti.element_is_closing_tag?
|
226
243
|
|
227
244
|
if parent_tag.nil?
|
@@ -230,9 +247,9 @@ module RubyBBCode
|
|
230
247
|
return false
|
231
248
|
end
|
232
249
|
|
233
|
-
if parent_tag[:tag] != @ti[:tag]
|
250
|
+
if (parent_tag[:tag] != @ti[:tag]) && !parent_of_self_closing_tag?
|
234
251
|
# Make an exception for 'supported tags'
|
235
|
-
if @ti.definition[:supported_tags].nil?
|
252
|
+
if @ti.definition[:supported_tags].nil? || !@ti.definition[:supported_tags].include?(parent_tag[:tag])
|
236
253
|
add_tag_error "Closing tag [/#{@ti[:tag]}] doesn't match [#{parent_tag[:tag]}]"
|
237
254
|
@ti[:wrong_closing] = true
|
238
255
|
return false
|
@@ -240,7 +257,7 @@ module RubyBBCode
|
|
240
257
|
end
|
241
258
|
|
242
259
|
tag_def = @bbtree.current_node.definition
|
243
|
-
if tag_def[:require_between]
|
260
|
+
if tag_def[:require_between] && @bbtree.current_node[:between].nil? && @bbtree.current_node[:nodes].empty?
|
244
261
|
err = "No text between [#{@ti[:tag]}] and [/#{@ti[:tag]}] tags."
|
245
262
|
err = "Cannot determine multi-tag type: #{err}" if tag_def[:multi_tag]
|
246
263
|
add_tag_error err, @bbtree.current_node
|
@@ -251,17 +268,16 @@ module RubyBBCode
|
|
251
268
|
end
|
252
269
|
|
253
270
|
def parent_of_self_closing_tag?
|
254
|
-
tag_being_parsed = @ti.definition
|
255
271
|
was_last_tag_self_closable = @bbtree.current_node[:definition][:self_closable] unless @bbtree.current_node[:definition].nil?
|
256
272
|
|
257
|
-
was_last_tag_self_closable
|
273
|
+
was_last_tag_self_closable && last_tag_fit_in_this_tag?
|
258
274
|
end
|
259
275
|
|
260
276
|
def last_tag_fit_in_this_tag?
|
261
|
-
@ti.definition[:only_allow]
|
277
|
+
@ti.definition[:only_allow]&.each do |tag|
|
262
278
|
return true if tag == @bbtree.current_node[:tag]
|
263
|
-
end
|
264
|
-
|
279
|
+
end
|
280
|
+
false
|
265
281
|
end
|
266
282
|
|
267
283
|
# This validation is for text elements with between text
|
@@ -271,8 +287,13 @@ module RubyBBCode
|
|
271
287
|
def valid_param_supplied_as_text?
|
272
288
|
tag_def = @bbtree.current_node.definition
|
273
289
|
|
290
|
+
if within_open_tag? && use_text_as_parameter? && @ti.element_is_tag? && has_no_text_node?
|
291
|
+
add_tag_error 'between parameter must be plain text'
|
292
|
+
return false
|
293
|
+
end
|
294
|
+
|
274
295
|
# this conditional ensures whether the validation is apropriate to this tag type
|
275
|
-
if @ti.element_is_text?
|
296
|
+
if @ti.element_is_text? && within_open_tag? && tag_def[:require_between] && use_text_as_parameter? && !tag_def[:quick_param_format].nil?
|
276
297
|
|
277
298
|
# check if valid
|
278
299
|
if @ti[:text].match(tag_def[:quick_param_format]).nil?
|
@@ -284,19 +305,17 @@ module RubyBBCode
|
|
284
305
|
end
|
285
306
|
|
286
307
|
def validate_all_tags_closed_off
|
308
|
+
return unless expecting_a_closing_tag?
|
309
|
+
|
287
310
|
# if we're still expecting a closing tag and we've come to the end of the string... throw error(s)
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
tag[:closed] = false
|
292
|
-
end
|
311
|
+
@bbtree.tags_list.each do |tag|
|
312
|
+
add_tag_error "[#{tag[:tag]}] not closed", tag
|
313
|
+
tag[:closed] = false
|
293
314
|
end
|
294
315
|
end
|
295
316
|
|
296
317
|
def validate_stack_level_too_deep_potential
|
297
|
-
if @bbtree.nodes.count > 2200
|
298
|
-
throw_stack_level_will_be_too_deep_error
|
299
|
-
end
|
318
|
+
throw_stack_level_will_be_too_deep_error if @bbtree.nodes.count > 2200
|
300
319
|
end
|
301
320
|
|
302
321
|
def throw_child_requires_specific_parent_error
|
@@ -312,20 +331,24 @@ module RubyBBCode
|
|
312
331
|
def throw_parent_prohibits_this_child_error
|
313
332
|
allowed_tags = parent_tag[:definition][:only_allow]
|
314
333
|
err = "[#{parent_tag[:tag]}] can only contain [#{allowed_tags.to_sentence(to_sentence_bbcode_tags)}] tags, so "
|
315
|
-
err += "[#{@ti[:tag]}]" if @ti
|
316
|
-
err += "\"#{@ti[:text]}\"" unless @ti
|
334
|
+
err += "[#{@ti[:tag]}]" if @ti.element_is_tag?
|
335
|
+
err += "\"#{@ti[:text]}\"" unless @ti.element_is_tag?
|
317
336
|
err += ' is not allowed'
|
318
337
|
add_tag_error err
|
319
338
|
end
|
320
339
|
|
321
340
|
def throw_stack_level_will_be_too_deep_error
|
322
|
-
@errors <<
|
341
|
+
@errors << 'Stack level would go too deep. You must be trying to process a text containing thousands of BBTree nodes at once. (limit around 2300 tags containing 2,300 strings). Check RubyBBCode::TagCollection#to_html to see why this validation is needed.'
|
323
342
|
end
|
324
343
|
|
325
344
|
def to_sentence_bbcode_tags
|
326
|
-
{:
|
327
|
-
:
|
328
|
-
:
|
345
|
+
{ words_connector: '], [',
|
346
|
+
two_words_connector: '] and [',
|
347
|
+
last_word_connector: '] and [' }
|
348
|
+
end
|
349
|
+
|
350
|
+
def has_no_text_node?
|
351
|
+
@bbtree.current_node[:nodes].blank? || @bbtree.current_node[:nodes][0][:text].nil?
|
329
352
|
end
|
330
353
|
|
331
354
|
def expecting_a_closing_tag?
|
@@ -338,7 +361,7 @@ module RubyBBCode
|
|
338
361
|
|
339
362
|
def use_text_as_parameter?
|
340
363
|
tag = @bbtree.current_node
|
341
|
-
tag.definition[:allow_between_as_param]
|
364
|
+
tag.definition[:allow_between_as_param] && tag.params_not_set? && !tag.invalid_quick_param?
|
342
365
|
end
|
343
366
|
|
344
367
|
def parent_tag
|
@@ -14,16 +14,15 @@ module RubyBBCode::Templates
|
|
14
14
|
def initialize(node)
|
15
15
|
@node = node
|
16
16
|
@tag_definition = node.definition # tag_definition
|
17
|
-
@opening_part = "[#{node[:tag]}#{node.allow_params? ? '%param%' : ''}]"
|
18
|
-
unless @node[:errors].empty?
|
19
|
-
|
20
|
-
end
|
21
|
-
@closing_part = "[/#{node[:tag]}]"
|
17
|
+
@opening_part = "[#{node[:tag]}#{node.allow_params? ? '%param%' : ''}]" + add_whitespace(node[:opening_whitespace])
|
18
|
+
@opening_part = "<span class='bbcode_error' #{BBCodeErrorsTemplate.error_attribute(@node[:errors])}>#{@opening_part}</span>" unless @node[:errors].empty?
|
19
|
+
@closing_part = "[/#{node[:tag]}]" + add_whitespace(node[:closing_whitespace])
|
22
20
|
end
|
23
21
|
|
24
|
-
def self.convert_text(node)
|
22
|
+
def self.convert_text(node, _parent_node)
|
25
23
|
# Keep the text as it was
|
26
24
|
return "<span class='bbcode_error' #{error_attribute(node[:errors])}>#{node[:text]}</span>" unless node[:errors].empty?
|
25
|
+
|
27
26
|
node[:text]
|
28
27
|
end
|
29
28
|
|
@@ -41,8 +40,7 @@ module RubyBBCode::Templates
|
|
41
40
|
end
|
42
41
|
end
|
43
42
|
|
44
|
-
def inlay_closing_part
|
45
|
-
end
|
43
|
+
def inlay_closing_part!; end
|
46
44
|
|
47
45
|
def remove_unused_tokens!
|
48
46
|
@opening_part.gsub!('%param%', '')
|
@@ -54,15 +52,20 @@ module RubyBBCode::Templates
|
|
54
52
|
|
55
53
|
private
|
56
54
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
end
|
55
|
+
def add_whitespace(whitespace)
|
56
|
+
whitespace || ''
|
57
|
+
end
|
61
58
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
59
|
+
def get_between
|
60
|
+
return @node[:between] if @tag_definition[:require_between] && @node[:between]
|
61
|
+
|
62
|
+
''
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.error_attribute(errors)
|
66
|
+
# Escape (double) quotes so the JSON can be generated properly (and parsed properly by JavaScript)
|
67
|
+
escapedErrors = errors.map { |error| error.gsub('"', '"').gsub("'", ''') }
|
68
|
+
"data-bbcode-errors='#{JSON.fast_generate(escapedErrors)}'"
|
69
|
+
end
|
67
70
|
end
|
68
71
|
end
|
@@ -10,20 +10,30 @@ module RubyBBCode::Templates
|
|
10
10
|
|
11
11
|
def initialize(node)
|
12
12
|
@node = node
|
13
|
-
@tag_definition = node.definition
|
14
|
-
@opening_part = node.definition[:html_open]
|
15
|
-
@closing_part = node.definition[:html_close]
|
13
|
+
@tag_definition = node.definition
|
14
|
+
@opening_part = node.definition[:html_open] + add_whitespace(:opening_whitespace)
|
15
|
+
@closing_part = node.definition[:html_close] + add_whitespace(:closing_whitespace)
|
16
16
|
end
|
17
17
|
|
18
18
|
# Newlines are converted to html <br /> syntax before being returned.
|
19
|
-
def self.convert_text(node)
|
19
|
+
def self.convert_text(node, parent_node)
|
20
20
|
return '' if node[:text].nil?
|
21
|
-
|
22
|
-
node[:text]
|
21
|
+
|
22
|
+
text = node[:text]
|
23
|
+
whitespace = ''
|
24
|
+
|
25
|
+
if !parent_node.nil? && parent_node.definition[:block_tag]
|
26
|
+
# Strip EOL whitespace, so it does not get converted
|
27
|
+
text.scan(/(\s+)$/) do |result|
|
28
|
+
whitespace = result[0]
|
29
|
+
text = text[0..-result[0].length - 1]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
convert_newlines(text) + whitespace
|
23
33
|
end
|
24
34
|
|
25
35
|
def inlay_between_text!
|
26
|
-
@opening_part.gsub!('%between%',
|
36
|
+
@opening_part.gsub!('%between%', format_between) if between_text_as_param?
|
27
37
|
end
|
28
38
|
|
29
39
|
def inlay_params!
|
@@ -31,12 +41,12 @@ module RubyBBCode::Templates
|
|
31
41
|
@tag_definition[:param_tokens].each do |token|
|
32
42
|
param_value = @node[:params][token[:token]] || token[:default]
|
33
43
|
param_value = CGI.escape(param_value) if token[:uri_escape]
|
34
|
-
@opening_part.gsub!("%#{token[:token]
|
44
|
+
@opening_part.gsub!("%#{token[:token]}%", "#{token[:prefix]}#{param_value}#{token[:postfix]}") unless param_value.nil?
|
35
45
|
end
|
36
46
|
end
|
37
47
|
|
38
48
|
def inlay_closing_part!
|
39
|
-
@closing_part.gsub!('%between%',
|
49
|
+
@closing_part.gsub!('%between%', format_between) if between_text_as_param?
|
40
50
|
end
|
41
51
|
|
42
52
|
def remove_unused_tokens!
|
@@ -45,11 +55,27 @@ module RubyBBCode::Templates
|
|
45
55
|
end
|
46
56
|
end
|
47
57
|
|
58
|
+
def self.convert_newlines(text)
|
59
|
+
text.gsub("\r\n", "\n").gsub("\n", "<br />\n")
|
60
|
+
end
|
61
|
+
|
48
62
|
private
|
49
63
|
|
64
|
+
def add_whitespace(key)
|
65
|
+
whitespace = @node[key]
|
66
|
+
return '' if whitespace.nil?
|
67
|
+
|
68
|
+
whitespace = HtmlTemplate.convert_newlines(whitespace) unless @tag_definition[:block_tag]
|
69
|
+
whitespace
|
70
|
+
end
|
71
|
+
|
50
72
|
# Return true if the between text is needed as param
|
51
73
|
def between_text_as_param?
|
52
74
|
@tag_definition[:require_between]
|
53
75
|
end
|
76
|
+
|
77
|
+
def format_between
|
78
|
+
@node[:between] || ''
|
79
|
+
end
|
54
80
|
end
|
55
|
-
end
|
81
|
+
end
|