This repository has been archived by the owner on Jan 19, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 8
/
bbcodeParser.js
169 lines (140 loc) · 5.72 KB
/
bbcodeParser.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
var bbcodeParser = {};
(function() {
var token_match = /{[A-Z_]+[0-9]*}/g;
// regular expressions for the different bbcode tokens
bbcodeParser.tokens = {
'URL' : '((?:(?:[a-z][a-z\\d+\\-.]*:\\/{2}(?:(?:[a-z0-9\\-._~\\!$&\'*+,;=:@|]+|%[\\dA-F]{2})+|[0-9.]+|\\[[a-z0-9.]+:[a-z0-9.]+:[a-z0-9.:]+\\])(?::\\d*)?(?:\\/(?:[a-z0-9\\-._~\\!$&\'*+,;=:@|]+|%[\\dA-F]{2})*)*(?:\\?(?:[a-z0-9\\-._~\\!$&\'*+,;=:@\\/?|]+|%[\\dA-F]{2})*)?(?:#(?:[a-z0-9\\-._~\\!$&\'*+,;=:@\\/?|]+|%[\\dA-F]{2})*)?)|(?:www\\.(?:[a-z0-9\\-._~\\!$&\'*+,;=:@|]+|%[\\dA-F]{2})+(?::\\d*)?(?:\\/(?:[a-z0-9\\-._~\\!$&\'*+,;=:@|]+|%[\\dA-F]{2})*)*(?:\\?(?:[a-z0-9\\-._~\\!$&\'*+,;=:@\\/?|]+|%[\\dA-F]{2})*)?(?:#(?:[a-z0-9\\-._~\\!$&\'*+,;=:@\\/?|]+|%[\\dA-F]{2})*)?)))',
'LOCAL_URL' : '((?:[a-z0-9\-._~\!$&\'()*+,;=:@|]+|%[\dA-F]{2})*(?:\/(?:[a-z0-9\-._~\!$&\'()*+,;=:@|]+|%[\dA-F]{2})*)*(?:\?(?:[a-z0-9\-._~\!$&\'()*+,;=:@\/?|]+|%[\dA-F]{2})*)?(?:#(?:[a-z0-9\-._~\!$&\'()*+,;=:@\/?|]+|%[\dA-F]{2})*)?)',
'EMAIL' : '((?:[\\w\!\#$\%\&\'\*\+\-\/\=\?\^\`{\|\}\~]+\.)*(?:[\\w\!\#$\%\'\*\+\-\/\=\?\^\`{\|\}\~]|&)+@(?:(?:(?:(?:(?:[a-z0-9]{1}[a-z0-9\-]{0,62}[a-z0-9]{1})|[a-z])\.)+[a-z]{2,6})|(?:\\d{1,3}\.){3}\\d{1,3}(?:\:\\d{1,5})?))',
'TEXT' : '(.*?)',
'SIMPLETEXT' : '([a-zA-Z0-9-+.,_ ]+)',
'INTTEXT' : '([a-zA-Z0-9-+,_. ]+)',
'IDENTIFIER' : '([a-zA-Z0-9-_]+)',
'COLOR' : '([a-z]+|#[0-9abcdef]+)',
'NUMBER' : '([0-9]+)'
};
// matches for bbcode to html
bbcodeParser.bbcode_matches = [];
// html templates for bbcode to html
bbcodeParser.html_tpls = [];
// matches for html to bbcode
bbcodeParser.html_matches = [];
// bbcode templates for bbcode to html
bbcodeParser.bbcode_tpls = [];
/**
* Turns a bbcode into a regular rexpression by changing the tokens into
* their regex form
*/
bbcodeParser._getRegEx = function(str) {
var matches = str.match(token_match);
var i = 0;
var replacement = '';
if (matches.length <= 0) {
// no tokens so return the escaped string
return new RegExp(preg_quote(str), 'g');
}
for(; i < matches.length; i += 1) {
// Remove {, } and numbers from the token so it can match the
// keys in bbcodeParser.tokens
var token = matches[i].replace(/[{}0-9]/g, '');
if (bbcodeParser.tokens[token]) {
// Escape everything before the token
replacement += preg_quote(str.substr(0, str.indexOf(matches[i]))) + bbcodeParser.tokens[token];
// Remove everything before the end of the token so it can be used
// with the next token. Doing this so that parts can be escaped
str = str.substr(str.indexOf(matches[i]) + matches[i].length);
}
}
// add whatever is left to the string
replacement += preg_quote(str);
return new RegExp(replacement, 'gi');
};
/**
* Turns a bbcode template into the replacement form used in regular expressions
* by turning the tokens in $1, $2, etc.
*/
bbcodeParser._getTpls = function(str) {
var matches = str.match(token_match);
var i = 0;
var replacement = '';
var positions = {};
var next_position = 0;
if (matches.length <= 0) {
// no tokens so return the string
return str;
}
for(; i < matches.length; i += 1) {
// Remove {, } and numbers from the token so it can match the
// keys in bbcodeParser.tokens
var token = matches[i].replace(/[{}0-9]/g, '');
var position;
// figure out what $# to use ($1, $2)
if (positions[matches[i]]) {
// if the token already has a position then use that
position = positions[matches[i]];
} else {
// token doesn't have a position so increment the next position
// and record this token's position
next_position += 1;
position = next_position;
positions[matches[i]] = position;
}
if (bbcodeParser.tokens[token]) {
replacement += str.substr(0, str.indexOf(matches[i])) + '$' + position;
str = str.substr(str.indexOf(matches[i]) + matches[i].length);
}
}
replacement += str;
return replacement;
};
/**
* Adds a bbcode to the list
*/
bbcodeParser.addBBCode = function(bbcode_match, bbcode_tpl) {
// add the regular expressions and templates for bbcode to html
bbcodeParser.bbcode_matches.push(bbcodeParser._getRegEx(bbcode_match));
bbcodeParser.html_tpls.push(bbcodeParser._getTpls(bbcode_tpl));
// add the regular expressions and templates for html to bbcode
bbcodeParser.html_matches.push(bbcodeParser._getRegEx(bbcode_tpl));
bbcodeParser.bbcode_tpls.push(bbcodeParser._getTpls(bbcode_match));
};
/**
* Turns all of the added bbcodes into html
*/
bbcodeParser.bbcodeToHtml = function(str) {
var i = 0;
for(; i < bbcodeParser.bbcode_matches.length; i += 1) {
str = str.replace(bbcodeParser.bbcode_matches[i], bbcodeParser.html_tpls[i]);
}
return str;
};
/**
* Turns html into bbcode
*/
bbcodeParser.htmlToBBCode = function(str) {
var i = 0;
for(; i < bbcodeParser.html_matches.length; i += 1) {
str = str.replace(bbcodeParser.html_matches[i], bbcodeParser.bbcode_tpls[i]);
}
return str;
}
/**
* Quote regular expression characters plus an optional character
* taken from phpjs.org
*/
function preg_quote (str, delimiter) {
// http://kevin.vanzonneveld.net
// + original by: booeyOH
// + improved by: Ates Goral (http://magnetiq.com)
// + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// + bugfixed by: Onno Marsman
// + improved by: Brett Zamir (http://brett-zamir.me)
// * example 1: preg_quote("$40");
// * returns 1: '\$40'
// * example 2: preg_quote("*RRRING* Hello?");
// * returns 2: '\*RRRING\* Hello\?'
// * example 3: preg_quote("\\.+*?[^]$(){}=!<>|:");
// * returns 3: '\\\.\+\*\?\[\^\]\$\(\)\{\}\=\!\<\>\|\:'
return (str + '').replace(new RegExp('[.\\\\+*?\\[\\^\\]$(){}=!<>|:\\' + (delimiter || '') + '-]', 'g'), '\\$&');
}
})();