1
1
// -----------------------------------------------------------------------
2
- // Copyright (c) 2008, Stone Steps Inc.
2
+ // Copyright (c) 2008, Stone Steps Inc.
3
3
// All rights reserved
4
4
// http://www.stonesteps.ca/legal/bsd-license/
5
5
//
6
6
// This is a BBCode parser written in JavaScript. The parser is intended
7
- // to demonstrate how to parse text containing BBCode tags in one pass
7
+ // to demonstrate how to parse text containing BBCode tags in one pass
8
8
// using regular expressions.
9
9
//
10
- // The parser may be used as a backend component in ASP or in the browser,
11
- // after the text containing BBCode tags has been served to the client.
10
+ // The parser may be used as a backend component in ASP or in the browser,
11
+ // after the text containing BBCode tags has been served to the client.
12
12
//
13
13
// Following BBCode expressions are recognized:
14
14
//
31
31
// [blockquote=http://blogs.stonesteps.ca/showpost.asp?pid=33]block quote[/blockquote]
32
32
// [blockquote]block quote[/blockquote]
33
33
//
34
- // [pre]formatted
34
+ // [pre]formatted
35
35
// text[/pre]
36
- // [code]if(a == b)
36
+ // [code]if(a == b)
37
37
// print("done");[/code]
38
38
//
39
39
// text containing [noparse] [brackets][/noparse]
@@ -51,7 +51,7 @@ exports.parse = function(post, cb) {
51
51
var urlstart = - 1 ; // beginning of the URL if zero or greater (ignored if -1)
52
52
53
53
// aceptable BBcode tags, optionally prefixed with a slash
54
- var tagname_re = / ^ \/ ? (?: b | i | u | p r e | s a m p | c o d e | c o l o u ? r | s i z e | n o p a r s e | u r l | l i n k | s | q | b l o c k q u o t e | i m g | u ? l i s t | l i ) $ / ;
54
+ var tagname_re = / ^ \/ ? (?: b | i | u | p r e | s a m p | c o d e | c o l o u ? r | s i z e | n o p a r s e | u r l | l i n k | s | q | b l o c k q u o t e | i m g | u ? l i s t | l i ) $ / i ;
55
55
56
56
// color names or hex color
57
57
var color_re = / ^ ( : ? b l a c k | s i l v e r | g r a y | w h i t e | m a r o o n | r e d | p u r p l e | f u c h s i a | g r e e n | l i m e | o l i v e | y e l l o w | n a v y | b l u e | t e a l | a q u a | # (?: [ 0 - 9 a - f ] { 3 } ) ? [ 0 - 9 a - f ] { 3 } ) $ / i;
@@ -110,6 +110,8 @@ exports.parse = function(post, cb) {
110
110
// handle start tags
111
111
//
112
112
if ( isValidTag ( m2 ) ) {
113
+ var m2l = m2 . toLowerCase ( ) ;
114
+
113
115
// if in the noparse state, just echo the tag
114
116
if ( noparse )
115
117
return "[" + m2 + "]" ;
@@ -118,32 +120,32 @@ exports.parse = function(post, cb) {
118
120
if ( opentags . length && ( opentags [ opentags . length - 1 ] . bbtag == "url" || opentags [ opentags . length - 1 ] . bbtag == "link" ) && urlstart >= 0 )
119
121
return "[" + m2 + "]" ;
120
122
121
- switch ( m2 ) {
123
+ switch ( m2l ) {
122
124
case "code" :
123
- opentags . push ( new taginfo_t ( m2 , "</code></pre>" ) ) ;
125
+ opentags . push ( new taginfo_t ( m2l , "</code></pre>" ) ) ;
124
126
crlf2br = false ;
125
127
return "<pre><code>" ;
126
128
127
129
case "pre" :
128
- opentags . push ( new taginfo_t ( m2 , "</pre>" ) ) ;
130
+ opentags . push ( new taginfo_t ( m2l , "</pre>" ) ) ;
129
131
crlf2br = false ;
130
132
return "<pre>" ;
131
133
132
134
case "color" :
133
135
case "colour" :
134
136
if ( ! m3 || ! color_re . test ( m3 ) )
135
137
m3 = "inherit" ;
136
- opentags . push ( new taginfo_t ( m2 , "</span>" ) ) ;
138
+ opentags . push ( new taginfo_t ( m2l , "</span>" ) ) ;
137
139
return "<span style=\"color: " + m3 + "\">" ;
138
140
139
141
case "size" :
140
142
if ( ! m3 || ! number_re . test ( m3 ) )
141
143
m3 = "1" ;
142
- opentags . push ( new taginfo_t ( m2 , "</span>" ) ) ;
144
+ opentags . push ( new taginfo_t ( m2l , "</span>" ) ) ;
143
145
return "<span style=\"font-size: " + Math . min ( Math . max ( m3 , 0.7 ) , 3 ) + "em\">" ;
144
146
145
147
case "s" :
146
- opentags . push ( new taginfo_t ( m2 , "</span>" ) ) ;
148
+ opentags . push ( new taginfo_t ( m2l , "</span>" ) ) ;
147
149
return "<span style=\"text-decoration: line-through\">" ;
148
150
149
151
case "noparse" :
@@ -152,7 +154,7 @@ exports.parse = function(post, cb) {
152
154
153
155
case "link" :
154
156
case "url" :
155
- opentags . push ( new taginfo_t ( m2 , "</a>" ) ) ;
157
+ opentags . push ( new taginfo_t ( m2l , "</a>" ) ) ;
156
158
157
159
// check if there's a valid option
158
160
if ( m3 && uri_re . test ( m3 ) ) {
@@ -161,25 +163,25 @@ exports.parse = function(post, cb) {
161
163
return "<a target=\"_blank\" href=\"" + m3 + "\">" ;
162
164
}
163
165
164
- // otherwise, remember the URL offset
166
+ // otherwise, remember the URL offset
165
167
urlstart = mstr . length + offset ;
166
168
167
169
// and treat the text following [url] as a URL
168
170
return "<a target=\"_blank\" href=\"" ;
169
171
case "img" :
170
- opentags . push ( new taginfo_t ( m2 , "\" />" ) ) ;
172
+ opentags . push ( new taginfo_t ( m2l , "\" />" ) ) ;
171
173
172
174
if ( m3 && uri_re . test ( m3 ) ) {
173
175
urlstart = - 1 ;
174
- return "<" + m2 + " src=\"" + m3 + "" ;
176
+ return "<" + m2l + " src=\"" + m3 + "" ;
175
177
}
176
178
177
- return "<" + m2 + " src=\"" ;
179
+ return "<" + m2l + " src=\"" ;
178
180
179
181
case "q" :
180
182
case "blockquote" :
181
- opentags . push ( new taginfo_t ( m2 , "</" + m2 + ">" ) ) ;
182
- return m3 && m3 . length && uri_re . test ( m3 ) ? "<" + m2 + " cite=\"" + m3 + "\">" : "<" + m2 + ">" ;
183
+ opentags . push ( new taginfo_t ( m2l , "</" + m2l + ">" ) ) ;
184
+ return m3 && m3 . length && uri_re . test ( m3 ) ? "<" + m2l + " cite=\"" + m3 + "\">" : "<" + m2l + ">" ;
183
185
184
186
case "list" :
185
187
opentags . push ( new taginfo_t ( 'list' , '</ol>' ) ) ;
@@ -188,19 +190,19 @@ exports.parse = function(post, cb) {
188
190
case "ulist" :
189
191
opentags . push ( new taginfo_t ( 'ulist' , '</ul>' ) ) ;
190
192
return '<ul>' ;
191
-
193
+
192
194
case "b" :
193
195
opentags . push ( new taginfo_t ( 'b' , '</strong>' ) ) ;
194
196
return '<strong>' ;
195
-
197
+
196
198
case "i" :
197
199
opentags . push ( new taginfo_t ( 'i' , '</em>' ) ) ;
198
200
return '<em>' ;
199
201
200
202
default :
201
203
// [samp] and [u] don't need special processing
202
- opentags . push ( new taginfo_t ( m2 , "</" + m2 + ">" ) ) ;
203
- return "<" + m2 + ">" ;
204
+ opentags . push ( new taginfo_t ( m2l , "</" + m2l + ">" ) ) ;
205
+ return "<" + m2l + ">" ;
204
206
205
207
}
206
208
}
@@ -209,6 +211,8 @@ exports.parse = function(post, cb) {
209
211
// process end tags
210
212
//
211
213
if ( isValidTag ( m4 ) ) {
214
+ var m4l = m4 . toLowerCase ( ) ;
215
+
212
216
if ( noparse ) {
213
217
// if it's the closing noparse tag, flip the noparse state
214
218
if ( m4 == "noparse" ) {
@@ -221,18 +225,18 @@ exports.parse = function(post, cb) {
221
225
}
222
226
223
227
// highlight mismatched end tags
224
- if ( ! opentags . length || opentags [ opentags . length - 1 ] . bbtag != m4 )
228
+ if ( ! opentags . length || opentags [ opentags . length - 1 ] . bbtag != m4l )
225
229
return "<span style=\"color: red\">[/" + m4 + "]</span>" ;
226
230
227
- if ( m4 == "url" || m4 == "link" ) {
231
+ if ( m4l == "url" || m4l == "link" ) {
228
232
// if there was no option, use the content of the [url] tag
229
233
if ( urlstart > 0 )
230
234
return "\">" + string . substr ( urlstart , offset - urlstart ) + opentags . pop ( ) . etag ;
231
235
232
236
// otherwise just close the tag
233
237
return opentags . pop ( ) . etag ;
234
238
}
235
- else if ( m4 == "code" || m4 == "pre" )
239
+ else if ( m4l == "code" || m4l == "pre" )
236
240
crlf2br = true ;
237
241
238
242
// other tags require no special processing, just output the end tag
0 commit comments