BBCode to HTML conversion is usually done on server side thus at least one server request is required to display the result. BBCode2HTML is a JavaScript function implemented to do the conversion on client side so the result can be previewed without hitting the server. Supported BBCode tags and a live preview example can be found at BBCode Editor page.
function BBC2HTML(S) {
if (S.indexOf('[') < 0) return S;
function X(p, f) {return new RegExp(p, f)}
function D(s) {return rD.exec(s)}
function R(s) {return s.replace(rB, P)}
function A(s, p) {for (var i in p) s = s.replace(X(i, 'g'), p[i]); return s;}
function P($0, $1, $2, $3) {
if ($3 && $3.indexOf('[') > -1) $3 = R($3);
switch ($1) {
case 'url':case 'anchor':case 'email': return '<a '+ L[$1] + ($2||$3) +'">'+ $3 +'</a>';
case 'img': var d = D($2); return '<img src="'+ $3 +'"'+ (d ? ' width="'+ d[1] +'" height="'+ d[2] +'"' : '') +' alt="'+ (d ? '' : $2) +'" />';
case 'flash':case 'youtube': var d = D($2)||[0, 425, 366]; return '<object type="application/x-shockwave-flash" data="'+ Y[$1] + $3 +'" width="'+ d[1] +'" height="'+ d[2] +'"><param name="movie" value="'+ Y[$1] + $3 +'" /></object>';
case 'float': return '<span style="float: '+ $2 +'">'+ $3 +'</span>';
case 'left':case 'right':case 'center':case 'justify': return '<div style="text-align: '+ $1 +'">'+ $3 +'</div>';
case 'google':case 'wikipedia': return '<a href="'+ G[$1] + $3 +'">'+ $3 +'</a>';
case 'b':case 'i':case 'u':case 's':case 'sup':case 'sub':case 'h1':case 'h2':case 'h3':case 'h4':case 'h5':case 'h6':case 'table':case 'tr':case 'th':case 'td': return '<'+ $1 +'>'+ $3 +'</'+ $1 +'>';
case 'row': case 'r':case 'header':case 'head':case 'h':case 'col':case 'c': return '<'+ T[$1] +'>'+ $3 +'</'+ T[$1] +'>';
case 'acronym':case 'abbr': return '<'+ $1 +' title="'+ $2 +'">'+ $3 +'</'+ $1 +'>';
}
return '['+ $1 + ($2 ? '='+ $2 : '') +']'+ $3 +'[/'+ $1 +']';
}
var rB = X('\\[([a-z][a-z0-9]*)(?:=([^\\]]+))?]((?:.|[\r\n])*?)\\[/\\1]', 'g'), rD = X('^(\\d+)x(\\d+)$');
var L = {url: 'href="', 'anchor': 'name="', email: 'href="mailto: '};
var G = {google: 'http://www.google.com/search?q=', wikipedia: 'http://www.wikipedia.org/wiki/'};
var Y = {youtube: 'http://www.youtube.com/v/', flash: ''};
var T = {row: 'tr', r: 'tr', header: 'th', head: 'th', h: 'th', col: 'td', c: 'td'};
var C = {notag: [{'\\[': '[', ']': ']'}, '', ''], code: [{'<': '<'}, '<code><pre>', '</pre></code>']};
C.php = [C.code[0], C.code[1]+ '<?php ', '?>'+ C.code[2]];
var F = {font: 'font-family:$1', size: 'font-size:$1px', color: 'color:$1'};
var U = {c: 'circle', d: 'disc', s: 'square', '1': 'decimal', a: 'lower-alpha', A: 'upper-alpha', i: 'lower-roman', I: 'upper-roman'};
var I = {}, B = {};
for (var i in C) I['\\[('+ i +')]((?:.|[\r\n])*?)\\[/\\1]'] = function($0, $1, $2) {return C[$1][1] + A($2, C[$1][0]) + C[$1][2]};
for (var i in F) {B['\\['+ i +'=([^\\]]+)]'] = '<span style="'+ F[i] +'">'; B['\\[/'+ i +']'] = '</span>';}
B['\\[list]'] = '<ul>'; B['\\[list=(\\w)]'] = function($0, $1) {return '<ul style="list-style-type: '+ (U[$1]||'disc') +'">'}; B['\\[/list]'] = '</ul>'; B['\\[\\*]'] = '<li>';
B['\\[quote(?:=([^\\]]+))?]'] = function($0, $1) {return '<div class="bb-quote">'+ ($1 ? $1 +' wrote' : 'Quote') +':<blockquote>'}; B['\\[/quote]'] = '</blockquote></div>';
B['\\[(hr|br)]'] = '<$1 />'; B['\\[sp]'] = ' ';
return R(A(A(S, I), B));
}
Very nice converter What
Very nice converter
What happens if users don't close the tags though?
By the way: what's the copyright status of this code?
Sorry, I see now that the bb
Sorry, I see now that the bb tags aren't converted if they're not closed!
I would like to use this on my site: am I okey to do this or is this copyrighted?
It's GPL. I'll be more than
It's GPL. I'll be more than happy if you make any improvements on the code and let me know.
Thanks :) Unfortunately I
Thanks :)
Unfortunately I don't know a lot about regular expressions so making improvements on the code is kind of beyond me!
My only concern is with XSS attacks - as it is, the script doesn't stop them!
Fortunately most only work on legacy browsers that people shouldn't be using:
http://ha.ckers.org/xss.html
Adding some measures to stop XSS is all I'm going to do. Not sure you'll be interested in my improvements though as they're just going to be crude string replaces!
alert("XSS")
The aim of BBCode2HTML is to
The aim of BBCode2HTML is to preview BBCode on client side without posting the content to the server for processing. If the user is previewing his/her own content then there is nothing to worry about XSS on the client side.
OTH, you will always need a general XSS filter to run on the server side. And it should be run after BBCode is converted to HTML
What I've been working on is
What I've been working on is a comment interface that requires no server processing at all.
I've created a comment system that doesn't require the user to have any server-side processing abilities (hence why I've found this code really helpful!) All they need is a Google Docs account.
I've combined this code with a script I've written to filter tags (as I'm allowing the input of BB and basic HTML) and to protect against XSS - I hope it's good enough...
Testing the BB/HTML Filter
Comments Interface
I know I haven't used this script in the way intended but I've found it great. I only wish I knew how to write such efficient code...
I love it :) I was trying to
I love it :) I was trying to make a preview mode for the form I was working on, but couldn't get the JS variables to pass into PHP so my BBcode parser could parse them but now I don't need to for the preview mode!
Only thing that bothers me is that it doesn't seem to recognise when a new line is started? it just carries on from where the last bit of text was for me :(
How can I install this on my
How can I install this on my server?
best regards,Marco.
Very nice! Thanks. Here is a
Very nice! Thanks.
Here is a simple implementation that also shows blank lines:
<textarea name="BBCODE" cols="60" rows="20"></textarea><input type="submit" value="Preview" onClick="document.all.output.innerHTML=BBC2HTML(BBCODE.value.replace(/\n/g,'<br />'));" /><br />
<div id="output" style="border:1px solid;padding:1px;"></div>
Anybody knows how to make it
Anybody knows how to make it case insensitive? currently, this doesn't works if the quote bbcode is "QUOTE" instead of "quote"