ruby-bbcode 2.0.0 → 2.1.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 5a747eebc84dd7ba046dde015c5bcd30cc3301d610aa5ab10769f9428728e7bd
|
4
|
+
data.tar.gz: f02dd04c79a57b3f611b414804c5f62bc28c18ff6555c6d3ac3ca115560bdd4c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9d958f90dfb03450bca54fa5e2f41272a14fc11a5186911cf688c93d576582c6f0effd1b42e0d0a228e49a1b5cf4991fb3f39a7307296c1337afb2791688f82f
|
7
|
+
data.tar.gz: 26fd15dfccd85f1d1f74b8dd7d47eab7c0e12950d85863ea39f8cc430d51fb0e1617d0c5defcb7fab076f538db16a3efc5bb0fa98e7329374a540b2411ece93f
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,35 @@
|
|
1
1
|
Upcoming
|
2
2
|
--------
|
3
3
|
|
4
|
+
Version 2.1.1 - 27-May-2020
|
5
|
+
---------------------------
|
6
|
+
|
7
|
+
* Bump activesupport to version 5.2.4.3
|
8
|
+
|
9
|
+
Version 2.1.0 - 30-May-2019
|
10
|
+
---------------------------
|
11
|
+
|
12
|
+
* Use rubocup and sonargraph and fix minor issues
|
13
|
+
* Make behavior of unknown tags configurable ([#33](https://github.com/veger/ruby-bbcode/issues/36))
|
14
|
+
* Allow tags inside link tags ([#32](https://github.com/veger/ruby-bbcode/issues/32))
|
15
|
+
* Do not convert newlines to HTML br element for 'block tags' ([#31](https://github.com/veger/ruby-bbcode/issues/31))
|
16
|
+
|
17
|
+
Version 2.0.3 - 07-Feb-2019
|
18
|
+
---------------------------
|
19
|
+
|
20
|
+
* Require Ruby version 2.3.0 or higher
|
21
|
+
* Require activesupport version 4.2.2 or higher
|
22
|
+
|
23
|
+
Version 2.0.2 - 10-Apr-2017
|
24
|
+
---------------------------
|
25
|
+
|
26
|
+
* Fix error when tags are in self-closing tags ([#30](https://github.com/veger/ruby-bbcode/issues/30))
|
27
|
+
|
28
|
+
Version 2.0.1 - 15-Jan-2017
|
29
|
+
---------------------------
|
30
|
+
|
31
|
+
* Remove EOL newlines before/after self-closing tags ([#29](https://github.com/veger/ruby-bbcode/issues/29))
|
32
|
+
|
4
33
|
Version 2.0.0 - 09-Apr-2015
|
5
34
|
---------------------------
|
6
35
|
|
@@ -10,8 +39,8 @@ Version 2.0.0 - 09-Apr-2015
|
|
10
39
|
* Changed tag description symbols (to become descriptive), **breaks existing custom tag additions!**
|
11
40
|
* Add support to show the BBCode annotated with errors (when there are any)
|
12
41
|
* Add support to escape token value using :uri_escape.
|
13
|
-
* Recognize uppercase tags (
|
14
|
-
* Support [iframe-API](https://developers.google.com/youtube/iframe_api_reference) for YouTube videos (#18)
|
42
|
+
* Recognize uppercase tags ([#27](https://github.com/veger/ruby-bbcode/issues/27))
|
43
|
+
* Support [iframe-API](https://developers.google.com/youtube/iframe_api_reference) for YouTube videos ([#18](https://github.com/veger/ruby-bbcode/issues/18))
|
15
44
|
* Support difference between optional and required parameters
|
16
45
|
* Add optional parameters to youtube and vimeo tags to specify the dimensions of the video
|
17
46
|
|
data/README.md
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
# Ruby-BBCode
|
2
|
+
|
3
|
+
[![gem version](https://badge.fury.io/rb/ruby-bbcode.svg)](https://badge.fury.io/rb/ruby-bbcode) [![Build Status](https://travis-ci.org/veger/ruby-bbcode.svg?branch=master)](https://travis-ci.org/veger/ruby-bbcode) [![Code Coverage](https://coveralls.io/repos/github/veger/ruby-bbcode/badge.svg?branch=master)](https://coveralls.io/github/veger/ruby-bbcode?branch=master)
|
4
|
+
|
5
|
+
This gem adds support for [BBCode](http:/www.bbcode.org/) to Ruby. The BBCode is parsed by a parser before converted to HTML, allowing to convert nested BBCode tags in strings to their correct HTML equivalent. The parser also checks whether the BBCode is valid and gives errors for incorrect BBCode texts.
|
6
|
+
Additionally, annotations can be added to the BBCode string the showing errors that are present, assuming there are any errors.
|
7
|
+
|
8
|
+
The parser recognizes all [official tags](http://www.bbcode.org/reference.php) and allows to easily extend this set with custom tags.
|
9
|
+
|
10
|
+
## Examples
|
11
|
+
|
12
|
+
`bbcode_to_html` can be used to convert a BBCode string to HTML:
|
13
|
+
|
14
|
+
```ruby
|
15
|
+
'This is [b]bold[/b] and this is [i]italic[/i].'.bbcode_to_html
|
16
|
+
=> 'This is <strong>bold</strong> and this is <em>italic</em>.'
|
17
|
+
```
|
18
|
+
|
19
|
+
`bbcode_show_errors` can be used to convert a BBCode to BBCode annotated with errors (assuming the original BBCode did contain errors):
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
'[img=no_dimensions_here]image.png[/img]'.bbcode_show_errors
|
23
|
+
=> '<span class=\'bbcode_error\' data-bbcode-errors=\'["The image parameters \'no_dimensions_here\' are incorrect, \'<width>x<height>\' excepted"]\'>[img]</span>image.png[/img]'
|
24
|
+
```
|
25
|
+
|
26
|
+
These HTML attributes containing the JSON representation of the errors can be used to inform the user about the problems.
|
27
|
+
The following JavaScript/jQuery example makes use of the [Bootstrap tooltips plugin](http://getbootstrap.com/javascript/#tooltips) to show the errors in tooltip popups:
|
28
|
+
```javascript
|
29
|
+
$(".bbcode_error").tooltip({
|
30
|
+
title: function() {
|
31
|
+
var errors = JSON.parse($(this).attr('data-bbcode-errors'));
|
32
|
+
return errors.join("\n");
|
33
|
+
}
|
34
|
+
});
|
35
|
+
```
|
36
|
+
|
37
|
+
## Installing
|
38
|
+
|
39
|
+
Add the following line to the Gemfile of your application:
|
40
|
+
```ruby
|
41
|
+
gem 'ruby-bbcode'
|
42
|
+
```
|
43
|
+
|
44
|
+
Or to use the source code from the repository:
|
45
|
+
```ruby
|
46
|
+
gem 'ruby-bbcode', :git => 'git://github.com/veger/ruby-bbcode.git'
|
47
|
+
```
|
48
|
+
|
49
|
+
Run
|
50
|
+
```shell
|
51
|
+
bundle install
|
52
|
+
```
|
53
|
+
|
54
|
+
And Ruby-BBCode is available in your application.
|
55
|
+
|
56
|
+
_Note_: Do not forget to restart your server!
|
57
|
+
|
58
|
+
## Acknowledgements
|
59
|
+
|
60
|
+
A big thanks to [@TheNotary](https://github.com/TheNotary) for all contributions he made to this project!
|
61
|
+
|
62
|
+
Some of the ideas and the tests came from [bb-ruby](https://github.com/cpjolicoeur/bb-ruby) of Craig P Jolicoeur.
|
63
|
+
|
64
|
+
## License
|
65
|
+
|
66
|
+
MIT License. See the included [MIT-LICENCE](MIT-LICENSE) file.
|
data/Rakefile
CHANGED
@@ -9,7 +9,7 @@ begin
|
|
9
9
|
rescue LoadError
|
10
10
|
require 'rdoc/rdoc'
|
11
11
|
require 'rake/rdoctask'
|
12
|
-
|
12
|
+
require 'rdoc/task'
|
13
13
|
RDoc::Task = Rake::RDocTask
|
14
14
|
end
|
15
15
|
|
@@ -22,8 +22,6 @@ RDoc::Task.new(:rdoc) do |rdoc|
|
|
22
22
|
rdoc.rdoc_files.include('lib/**/*.rb')
|
23
23
|
end
|
24
24
|
|
25
|
-
|
26
|
-
|
27
25
|
Bundler::GemHelper.install_tasks
|
28
26
|
|
29
27
|
require 'rake/testtask'
|
@@ -42,4 +40,4 @@ Rake::TestTask.new(:current) do |t|
|
|
42
40
|
t.verbose = true
|
43
41
|
end
|
44
42
|
|
45
|
-
task :
|
43
|
+
task default: :test
|
data/lib/ruby-bbcode.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'tags/tags'
|
2
|
+
require 'ruby-bbcode/configuration'
|
2
3
|
require 'ruby-bbcode/tag_info'
|
3
4
|
require 'ruby-bbcode/tag_sifter'
|
4
5
|
require 'ruby-bbcode/tag_node'
|
@@ -11,6 +12,22 @@ require 'ruby-bbcode/bbtree'
|
|
11
12
|
module RubyBBCode
|
12
13
|
include ::RubyBBCode::Tags
|
13
14
|
|
15
|
+
class << self
|
16
|
+
attr_writer :configuration
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.configuration
|
20
|
+
@configuration ||= Configuration.new
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.reset
|
24
|
+
@configuration = Configuration.new
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.configure
|
28
|
+
yield(configuration)
|
29
|
+
end
|
30
|
+
|
14
31
|
# This method converts the given text (with BBCode tags) into a HTML representation
|
15
32
|
# The escape_html parameter (default: true) escapes HTML tags that were present in the given text and therefore blocking (mallicious) HTML in the original text
|
16
33
|
# The additional_tags parameter is used to add additional BBCode tags that should be accepted
|
@@ -43,38 +60,41 @@ module RubyBBCode
|
|
43
60
|
|
44
61
|
@tag_sifter.process_text
|
45
62
|
return @tag_sifter.errors unless @tag_sifter.valid?
|
63
|
+
|
46
64
|
true
|
47
65
|
end
|
48
66
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
67
|
+
class << self
|
68
|
+
protected
|
69
|
+
|
70
|
+
# This method provides the final set of bbcode tags, it merges the default tags with the given additional_tags
|
71
|
+
# and blacklists(method = :disable) or whitelists the list of tags with the given tags parameter.
|
72
|
+
def determine_applicable_tags(additional_tags, method, *tags)
|
73
|
+
use_tags = @@tags.merge(additional_tags)
|
74
|
+
if method == :disable
|
75
|
+
# if method is set to :disable blacklist (remove) the supplied tags
|
76
|
+
tags.each { |t| use_tags.delete(t) }
|
77
|
+
else
|
78
|
+
# only use the supplied tags (whitelist) if method is not :disable
|
79
|
+
new_use_tags = {}
|
80
|
+
tags.each { |t| new_use_tags[t] = use_tags[t] if use_tags.key?(t) }
|
81
|
+
use_tags = new_use_tags
|
82
|
+
end
|
83
|
+
use_tags
|
63
84
|
end
|
64
|
-
use_tags
|
65
|
-
end
|
66
|
-
|
67
|
-
# This method parses the given text (with BBCode tags) into a BBTree representation
|
68
|
-
# The escape_html parameter (default: true) escapes HTML tags that were present in the given text and therefore blocking (mallicious) HTML in the original text
|
69
|
-
# The additional_tags parameter is used to add additional BBCode tags that should be accepted
|
70
|
-
# The method parameter determines whether the tags parameter needs to be used to blacklist (when set to :disable) or whitelist (when not set to :disable) the list of BBCode tags
|
71
|
-
# The method raises an exception when the text could not be parsed due to errors
|
72
|
-
def self.parse(text, escape_html = true, additional_tags = {}, method = :disable, *tags)
|
73
|
-
text = text.clone
|
74
|
-
use_tags = determine_applicable_tags(additional_tags, method, *tags)
|
75
85
|
|
76
|
-
|
77
|
-
|
86
|
+
# This method parses the given text (with BBCode tags) into a BBTree representation
|
87
|
+
# The escape_html parameter (default: true) escapes HTML tags that were present in the given text and therefore blocking (mallicious) HTML in the original text
|
88
|
+
# The additional_tags parameter is used to add additional BBCode tags that should be accepted
|
89
|
+
# The method parameter determines whether the tags parameter needs to be used to blacklist (when set to :disable) or whitelist (when not set to :disable) the list of BBCode tags
|
90
|
+
# The method raises an exception when the text could not be parsed due to errors
|
91
|
+
def parse(text, escape_html = true, additional_tags = {}, method = :disable, *tags)
|
92
|
+
text = text.clone
|
93
|
+
use_tags = determine_applicable_tags(additional_tags, method, *tags)
|
94
|
+
|
95
|
+
@tag_sifter = TagSifter.new(text, use_tags, escape_html)
|
96
|
+
@tag_sifter.process_text
|
97
|
+
end
|
78
98
|
end
|
79
99
|
end
|
80
100
|
|
@@ -94,7 +114,7 @@ String.class_eval do
|
|
94
114
|
# The method parameter determines whether the tags parameter needs to be used to blacklist (when set to :disable) or whitelist (when not set to :disable) the list of BBCode tags
|
95
115
|
# The method raises an exception when the text could not be parsed due to errors
|
96
116
|
def bbcode_to_html!(escape_html = true, additional_tags = {}, method = :disable, *tags)
|
97
|
-
|
117
|
+
replace(RubyBBCode.to_html(self, escape_html, additional_tags, method, *tags))
|
98
118
|
end
|
99
119
|
|
100
120
|
# Convert a string with BBCode markup into its corresponding HTML markup
|
data/lib/ruby-bbcode/bbtree.rb
CHANGED
@@ -12,7 +12,7 @@ module RubyBBCode
|
|
12
12
|
class BBTree
|
13
13
|
attr_accessor :current_node, :tags_list
|
14
14
|
|
15
|
-
def initialize(hash = { :
|
15
|
+
def initialize(hash = { nodes: TagCollection.new })
|
16
16
|
@bbtree = hash
|
17
17
|
@current_node = TagNode.new(@bbtree)
|
18
18
|
@tags_list = []
|
@@ -23,13 +23,14 @@ module RubyBBCode
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def within_open_tag?
|
26
|
-
|
26
|
+
!@tags_list.empty?
|
27
27
|
end
|
28
|
-
alias
|
28
|
+
alias expecting_a_closing_tag? within_open_tag? # just giving this method multiple names for semantical purposes
|
29
29
|
|
30
30
|
# Returns the parent tag, if suitable/available
|
31
31
|
def parent_tag
|
32
32
|
return nil unless within_open_tag?
|
33
|
+
|
33
34
|
@tags_list.last
|
34
35
|
end
|
35
36
|
|
@@ -46,15 +47,22 @@ module RubyBBCode
|
|
46
47
|
|
47
48
|
# Step down the bbtree a notch because we've reached a closing tag
|
48
49
|
def retrogress_bbtree
|
49
|
-
@tags_list.
|
50
|
+
if @tags_list[-1].definition[:self_closable]
|
51
|
+
# It is possible that the next (self_closable) tag is on the next line
|
52
|
+
# Remove newline of current tag and parent tag as they are (probably) not intented as an actual newline here but as tag separator
|
53
|
+
@tags_list[-1][:nodes][0][:text]&.chomp!
|
54
|
+
@tags_list[-2][:nodes][0][:text].chomp! unless (@tags_list.length < 2) || @tags_list[-2][:nodes][0][:text].nil?
|
55
|
+
end
|
56
|
+
|
57
|
+
@tags_list.pop # remove latest tag in tags_list since it's closed now...
|
50
58
|
# The parsed data manifests in @bbtree.current_node.children << TagNode.new(element) which I think is more confusing than needed
|
51
59
|
|
52
|
-
if within_open_tag?
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
60
|
+
@current_node = if within_open_tag?
|
61
|
+
@tags_list[-1]
|
62
|
+
else
|
63
|
+
# we're still at the root of the BBTree or have returned back to the root via encountering closing tags...
|
64
|
+
TagNode.new(nodes: nodes)
|
65
|
+
end
|
58
66
|
end
|
59
67
|
|
60
68
|
# Create a new node and adds it to the current node as a child node
|
@@ -63,11 +71,11 @@ module RubyBBCode
|
|
63
71
|
end
|
64
72
|
|
65
73
|
def to_html(tags = {})
|
66
|
-
|
74
|
+
nodes.to_html(tags)
|
67
75
|
end
|
68
76
|
|
69
77
|
def to_bbcode(tags = {})
|
70
|
-
|
78
|
+
nodes.to_bbcode(tags)
|
71
79
|
end
|
72
80
|
end
|
73
81
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# Configuration holds RubyBBCode configuration
|
2
|
+
class Configuration
|
3
|
+
# Defines how to treat unknown tags
|
4
|
+
# * :exception throws and exception
|
5
|
+
# * :text converts it into a text
|
6
|
+
# * :ignore removes it from the output
|
7
|
+
attr_reader :ignore_unknown_tags
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@ignore_unknown_tags = :text
|
11
|
+
end
|
12
|
+
|
13
|
+
def ignore_unknown_tags=(value)
|
14
|
+
raise 'ignore_unknown_tags must be either :exception, :text or :ignore' unless %i[exception text ignore].include? value
|
15
|
+
|
16
|
+
@ignore_unknown_tags = value
|
17
|
+
end
|
18
|
+
end
|
@@ -17,9 +17,9 @@ module RubyBBCode
|
|
17
17
|
# This method is vulnerable to stack-level-too-deep scenarios where >=1,200 tags are being parsed.
|
18
18
|
# But that scenario can be mitigated by splitting up the tags. bbtree = { :nodes => [900tags, 1000tags] }, the work
|
19
19
|
# for that bbtree can be split up into two passes, do the each node one at a time. I'm not coding that though, it's pointless, just a thought though
|
20
|
-
def to_code(tags, template)
|
21
|
-
|
22
|
-
|
20
|
+
def to_code(tags, template, parent_node = nil)
|
21
|
+
output_string = ''
|
22
|
+
each do |node|
|
23
23
|
if node.type == :tag
|
24
24
|
t = template.new node
|
25
25
|
|
@@ -30,20 +30,20 @@ module RubyBBCode
|
|
30
30
|
t.remove_unused_tokens!
|
31
31
|
end
|
32
32
|
|
33
|
-
|
33
|
+
output_string << t.opening_part
|
34
34
|
|
35
35
|
# invoke "recursive" call if this node contains child nodes
|
36
|
-
|
36
|
+
output_string << node.children.to_code(tags, template, node) if node.has_children? # FIXME: Don't use recursion, it can lead to stack-level-too-deep errors for large volumes?
|
37
37
|
|
38
38
|
t.inlay_closing_part!
|
39
39
|
|
40
|
-
|
40
|
+
output_string << t.closing_part
|
41
41
|
elsif node.type == :text
|
42
|
-
|
42
|
+
output_string << template.convert_text(node, parent_node)
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
46
|
-
|
46
|
+
output_string
|
47
47
|
end
|
48
48
|
end
|
49
|
-
end
|
49
|
+
end
|
data/lib/ruby-bbcode/tag_info.rb
CHANGED
@@ -3,6 +3,16 @@ module RubyBBCode
|
|
3
3
|
# This class was made mostly just to keep track of all of the confusing the logic conditions that are checked.
|
4
4
|
#
|
5
5
|
class TagInfo
|
6
|
+
REGEX_STRING = '(?:(\[ (\/)? (\* | (?:\w+)) ((?:=[^\[\]]+) | (?:\s\w+=\w+)* | (?:[^\]]*))? \] (\s*)) | ([^\[]+))'.gsub(' ', '').freeze
|
7
|
+
REGEX = /#{REGEX_STRING}/i.freeze
|
8
|
+
|
9
|
+
COMPLETE_MATCH = 0
|
10
|
+
CLOSING_MATCH = 1
|
11
|
+
TAG_MATCH = 2
|
12
|
+
TAG_PARAM_MATCH = 3
|
13
|
+
WHITESPACE_AFTER_TAG = 4
|
14
|
+
TEXT = 5
|
15
|
+
|
6
16
|
def initialize(tag_info, dictionary)
|
7
17
|
@tag_data = find_tag_info(tag_info, dictionary)
|
8
18
|
end
|
@@ -15,16 +25,19 @@ module RubyBBCode
|
|
15
25
|
@tag_data[key] = value
|
16
26
|
end
|
17
27
|
|
18
|
-
#
|
19
|
-
|
20
|
-
@definition
|
21
|
-
end
|
28
|
+
# Definition of this instance (when it represents a tag element)
|
29
|
+
attr_reader :definition
|
22
30
|
|
23
31
|
# Returns the text (when this instance represents a text element)
|
24
32
|
def text
|
25
33
|
@tag_data[:text]
|
26
34
|
end
|
27
35
|
|
36
|
+
# Returns the whitespace that was available directly after the tag definition
|
37
|
+
def whitespace
|
38
|
+
@tag_data[:whitespace]
|
39
|
+
end
|
40
|
+
|
28
41
|
# Returns the type of the cuvvrent tag/node, which is either :opening_tag, :closing_tag, or :text
|
29
42
|
def type
|
30
43
|
return :opening_tag if element_is_opening_tag?
|
@@ -51,12 +64,12 @@ module RubyBBCode
|
|
51
64
|
|
52
65
|
# Returns true if this instance represents an opening tag element
|
53
66
|
def element_is_opening_tag?
|
54
|
-
self[:is_tag]
|
67
|
+
self[:is_tag] && !self[:closing_tag]
|
55
68
|
end
|
56
69
|
|
57
70
|
# Returns true if this instance represents a closing tag element
|
58
71
|
def element_is_closing_tag?
|
59
|
-
self[:is_tag]
|
72
|
+
self[:is_tag] && self[:closing_tag]
|
60
73
|
end
|
61
74
|
|
62
75
|
# Returns true if this tag element is included in the set of available tags
|
@@ -71,7 +84,7 @@ module RubyBBCode
|
|
71
84
|
|
72
85
|
# Returns true if the tag element is allowed in the provided parent_tag
|
73
86
|
def allowed_in?(parent_tag)
|
74
|
-
!only_allowed_in_parent_tags?
|
87
|
+
!only_allowed_in_parent_tags? || @definition[:only_in].include?(parent_tag)
|
75
88
|
end
|
76
89
|
|
77
90
|
# Returns true if this tag has quick parameter support
|
@@ -86,21 +99,39 @@ module RubyBBCode
|
|
86
99
|
|
87
100
|
protected
|
88
101
|
|
102
|
+
# Returns a default info structure used by all tags
|
103
|
+
def default_tag_info(tag_info)
|
104
|
+
{
|
105
|
+
errors: [],
|
106
|
+
complete_match: tag_info[COMPLETE_MATCH],
|
107
|
+
whitespace: tag_info[WHITESPACE_AFTER_TAG]
|
108
|
+
}
|
109
|
+
end
|
110
|
+
|
89
111
|
# Convert the result of the TagSifter#process_text regex into a more usable hash, that is used by the rest of the parser.
|
90
112
|
# tag_info should a result of the regex of TagSifter#process_text
|
91
113
|
# Returns the tag hash
|
92
114
|
def find_tag_info(tag_info, dictionary)
|
93
|
-
ti =
|
94
|
-
ti[:
|
95
|
-
ti[:complete_match] = tag_info[0]
|
96
|
-
ti[:is_tag] = (tag_info[0].start_with? '[')
|
115
|
+
ti = default_tag_info(tag_info)
|
116
|
+
ti[:is_tag] = (tag_info[COMPLETE_MATCH]&.start_with? '[')
|
97
117
|
if ti[:is_tag]
|
98
|
-
ti[:closing_tag] = (tag_info[
|
99
|
-
ti[:tag] = tag_info[
|
118
|
+
ti[:closing_tag] = (tag_info[CLOSING_MATCH] == '/')
|
119
|
+
ti[:tag] = tag_info[TAG_MATCH].to_sym.downcase
|
100
120
|
ti[:params] = {}
|
101
121
|
@definition = dictionary[ti[:tag]]
|
102
|
-
if
|
103
|
-
|
122
|
+
if !tag_in_dictionary?
|
123
|
+
# Tag is not defined in dictionary, so treat as text
|
124
|
+
raise "unknown tag #{ti[:tag]}" if RubyBBCode.configuration.ignore_unknown_tags == :exception
|
125
|
+
|
126
|
+
ti = default_tag_info(tag_info)
|
127
|
+
ti[:is_tag] = false
|
128
|
+
ti[:text] = if RubyBBCode.configuration.ignore_unknown_tags == :text
|
129
|
+
tag_info[COMPLETE_MATCH]
|
130
|
+
else
|
131
|
+
''
|
132
|
+
end
|
133
|
+
elsif (tag_info[TAG_PARAM_MATCH][0] == '=') && can_have_quick_param?
|
134
|
+
quick_param = tag_info[TAG_PARAM_MATCH][1..-1]
|
104
135
|
# Get list of parameter values and add them as (regular) parameters
|
105
136
|
value_array = quick_param.scan(@definition[:quick_param_format])[0]
|
106
137
|
if value_array.nil?
|
@@ -111,9 +142,9 @@ module RubyBBCode
|
|
111
142
|
ti[:params][param_tokens[i][:token]] = value
|
112
143
|
end
|
113
144
|
end
|
114
|
-
elsif tag_info[
|
145
|
+
elsif tag_info[TAG_PARAM_MATCH][0] == "\s"
|
115
146
|
regex_string = '((\w+)=([\w#]+)) | ((\w+)="([^"]+)") | ((\w+)=\'([^\']+)\')'
|
116
|
-
tag_info[
|
147
|
+
tag_info[TAG_PARAM_MATCH].scan(/#{regex_string}/ix) do |param_info|
|
117
148
|
param = param_info[1] || param_info[4] || param_info[7]
|
118
149
|
value = param_info[2] || param_info[5] || param_info[8]
|
119
150
|
ti[:params][param.to_sym] = value
|
@@ -121,7 +152,7 @@ module RubyBBCode
|
|
121
152
|
end
|
122
153
|
else
|
123
154
|
# Plain text
|
124
|
-
ti[:text] = tag_info[
|
155
|
+
ti[:text] = tag_info[TEXT]
|
125
156
|
end
|
126
157
|
ti
|
127
158
|
end
|