Simple BBTag Parser

Small, short code snippets that other people may find useful. Do you have a good regex that you would like to share? Share it! Even better, the code can be commented on, and improved.

Moderator: General Moderators

User avatar
s.dot
Tranquility In Moderation
Posts: 5001
Joined: Sun Feb 06, 2005 7:18 pm
Location: Indiana

Simple BBTag Parser

Post by s.dot »

I was just bored and wrote something that might be useful to some people. It's a simple bb tag parser to convert common bb tags to html, and vice versa.

Currently replaces..

B,I,U,QUOTE,IMG, & URL

and.. converts them back to normal text.

bbtags.class.php

Code: Select all

 
<?php
 
/*
* This class will parse the common bbtags B U I URL IMG & QUOTE
* into suitable HTML equivalents and can also reverse them.
*
* Works with PHP >= 4.05
*
* author: scottayy@gmail.com
* date: June 4th, 2006
* update: June 5th, 2006
*   - converting and reversing called in one function (convertBB)
*   - replacing all bb tags combined into one function (replaceTags)
*   - reversing all html tags back to bb combined into one function (reverseTags)
*   - defining our tags called in one function (defineTags)
*/
 
class parseBB {
 
 
    var $basictags;
    var $basicreplacements;
 
    
    
    
 
    /*
    *   function called to turn bb tags into html tags
    *   and called with a FALSE boolean to do the opposite
    *
    *   @param str $text
    *   @param boolean
    */
    
    function convertBB($text,$normal=TRUE){
 
        //define our tags
        $this->defineTags();
 
        //normal or reverse conversion?
        if($normal === TRUE) 
            return $this->replaceTags($text);
        else 
            return $this->reverseTags($text);
    
    }
 
 
    
    
 
 
    //used internally, does the actual conversion from bb to html
    function replaceTags($text){
 
        //replace basic bbcode bold, underline, italics and quote
        $text = str_replace($this->basictags,$this->basicreplacements,$text);
        
        //replace [url=...]...[/url] bbcode
        if(preg_match("^\[url=(.+?)\](.+?)\[/url\]^im",$text,$urls)){
            
            $text = preg_replace_callback('^\[url=(.+?)\](.+?)\[/url\]^im',
                create_function('$urls',
                    'return \'<a href="\'.trim($urls[1]).\'" target="_blank">\'.trim($urls[2]).\'</a>\';'
                ),
            $text);
            
        }
 
        //replace url bbcode
        if(preg_match("^\[url\](.+?)\[/url\]^im",$text,$urls2)){
            
            $text = preg_replace_callback('^\[url\](.+?)\[/url\]^im',
                create_function('$urls2',
                    'return \'<a href="\'.trim($urls2[1]).\'" target="_blank">\'.trim($urls2[1]).\'</a>\';'
                ),
            $text);
        
        }
 
        //replace img tags
        $text = preg_replace_callback('^\[img\](.+?)\[/img\]^im',
            create_function('$matches',
                'return \'<img src="\'.trim(htmlentities($matches[1],ENT_QUOTES)).\'" alt="Image">\';'
            ),
        $text);
 
        return $text;
 
    }
 
 
    
    
    
    
    //used internally, reverses html back to bbcode
    function reverseTags($text){
        
        //reverse basic html to bold, underline, italics & quote bbcode tags
        $text = str_replace($this->basicreplacements,$this->basictags,$text);
        
        //reverse url tags
        if(preg_match_all("#<a href=\"(.+?)\" target=\"_blank\">(.+?)</a>#im",$text,$rurls)){
        $i=0;
            foreach($rurls[0] AS $url){
                $text = str_replace($url,"[url={$rurls[1][$i]}]{$rurls[2][$i]}[/url]",$text);
                $i++;
            }
        }
 
        //reverse img tags
        if(preg_match_all("#<img src=\"(.+?)\" alt=\"Image\">#im",$text,$imgs)){
            $i=0;
            foreach($imgs[0] AS $imglink){
                $text = str_replace($imglink,"[img"."]{$imgs[1][$i]}[/img]",$text);
                $i++;
            }
        }
        
        return $text;
    
    }
        
    
    
    
    
    
    function defineTags(){
            
        //define $basictags
        $this->basictags = array(
            '[b]',
            '[B]',
            '[i]',
            '[I]',
            '[u]',
            '[U]',
            '[/b]',
            '[/B]',
            '[/i]',
            '[/I]',
            '[/u]',
            '[/U]',
            '[quote'.']',
            '[quote'.']',
            '[/quote]',
            '[/quote]'
        );
            
        //define $basicreplacements
        $this->basicreplacements = array(
            '<b>',
            '<b>',
            '<i>',
            '<i>',
            '<u>',
            '<u>',
            '</b>',
            '</b>',
            '</i>',
            '</i>',
            '</u>',
            '</u>',
            '<blockquote>',
            '<blockquote>',
            '</blockquote>',
            '</blockquote>'
        );
    }
 
 
}
 
?>
 


Sample Usage:

Code: Select all

 
<?php
 
require 'bbtags.class.php';
$bb = new parseBB();
 
$raw = "[b"."]text[/b] [i"."]test[/i] [u"."]test[/u] [b"."][u"."][i"."]test[/i][/u][/b] 
[img"."]http://forums.devnetwork.net/templates/subSilver/images/logo_phpBB.gif[/img]
[quote"."]yo, i'm a quote![/quote][/quote] [url"."]http://www.showmypro.com[/url] [url"."=http://www.yahoo.com]Yahoo[/url]";
 
$bbalized   = $bb->convertBB($raw);
$regular    = $bb->convertBB($bbalized,FALSE);
 
echo $bbalized.'<br /><br />'.$regular;
 
?>
 
Edit: Those links in the sample are url bb tags.
Last edited by feyd on Fri Aug 01, 2008 10:18 am, edited 7 times in total.
Reason: fix php tags.
Set Search Time - A google chrome extension. When you search only results from the past year (or set time period) are displayed. Helps tremendously when using new technologies to avoid outdated results.
User avatar
ok
Forum Contributor
Posts: 393
Joined: Wed May 31, 2006 9:20 am
Location: The Holy Land

Post by ok »

Great code!!!

P.S
You can put "& # 9 1 ;" (without the spaces) instead of [ in the sample usage part, i.e:
http://www.google.com => http://www.google.com
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Re: Simple BBTag Parser

Post by Christopher »

One quick improvement would be to get rid of the function call to get the tags and replacements is creating the arrays in the constructor. It also might be better to use an associative array to keep the pairs together -- and make it less error prone when adding more.

It also seems like you could have a single tag replacement method and have the specific replacement ones call it will just the appropriate values.

Code: Select all

 
<?php
 
class parseBB {
    var $basictags;
    var $basicreplacements;
 
    function parseBB(){
        $this->basictags = array(
            '[b'.']','[B'.']','[i'.']','[I'.']','[u'.']','[U'.']','[/b]','[/B]',
            '[/i]','[/I]','[/u]','[/U]','[quote'.']','[quote'.']','[/quote]','[/quote]');
             $this->basicreplacements = array('<b>','<b>','<i>','<i>','<u>','<u>','</b>','</b>',
        '</i>','</i>','</u>','</u>','<blockquote>','<blockquote>','</blockquote>','</blockquote>');
       }
    
    //function called to turn bb tags into html tags
    function text2BB($text){
    
        //replace them
        $ret = str_replace($this->basictags, $this->basicreplacements, $text);
        
...
 
// get rid of getBasicTags() and getBasicReplacements()
}
?>
 
Last edited by feyd on Fri Aug 01, 2008 10:19 am, edited 1 time in total.
Reason: fix php tags.
(#10850)
User avatar
s.dot
Tranquility In Moderation
Posts: 5001
Joined: Sun Feb 06, 2005 7:18 pm
Location: Indiana

Post by s.dot »

Thanks.

I took up your suggestion aborint. And the entity for a bracket didn't work inside the PHP code. I don't think the bbtags should be parsed inside there. Perhaps its an error with the PHP mod.
Set Search Time - A google chrome extension. When you search only results from the past year (or set time period) are displayed. Helps tremendously when using new technologies to avoid outdated results.
User avatar
s.dot
Tranquility In Moderation
Posts: 5001
Joined: Sun Feb 06, 2005 7:18 pm
Location: Indiana

Post by s.dot »

A quick thought. If you're running php >= 5, this could easily be made a bit more effective by using str_ireplace() in place of the str_replace calls
Set Search Time - A google chrome extension. When you search only results from the past year (or set time period) are displayed. Helps tremendously when using new technologies to avoid outdated results.
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Post by Christopher »

In looking at the code it looks like you could reduce things down by reusing functions and passing some parameters. The methods reverseURLTags() and reverseURLTags() are identical except for two strings which could be parameters. Likewise replaceURLTags() appears to call twice the same code that is in replaceIMGTags() with only a few strings different. You could probably get it down to just replaceTags() and reverseTags() and pull the misc code back in to the main functions.

Also maybe calling the main functions bb2html() and html2bb() might be clearer.
(#10850)
User avatar
s.dot
Tranquility In Moderation
Posts: 5001
Joined: Sun Feb 06, 2005 7:18 pm
Location: Indiana

Post by s.dot »

I took up your suggestions again aborint... if the changes are indeed what you meant. I'm kind of proud of this one. Feel like I did something useful for someone. ;)

The main function is now called like convertBB($text); to convert bb to html... and is called with a false parameter to do the opposite. convertBB($text,FALSE);
Set Search Time - A google chrome extension. When you search only results from the past year (or set time period) are displayed. Helps tremendously when using new technologies to avoid outdated results.
User avatar
Verminox
Forum Contributor
Posts: 101
Joined: Sun May 07, 2006 5:19 am

CODE parsing

Post by Verminox »

Well this does not appear to NOT parse the [ CODE ] BBTag or a BBTag for direct HTML, etc.. But for simple use, its fine....

I suggest you make lists as well now, as they are very simple.

I made a BBCode2HTML Converter using Javascript in an hour that parses most bbcode so PHP should be much easier.

Nice work upto now though.
User avatar
TheMoose
Forum Contributor
Posts: 351
Joined: Tue May 23, 2006 10:42 am

Post by TheMoose »

Just a friendly suggestion, but instead (or alongside) of explicitly defining which tags to replace, maybe add a member function that you can completely customize what tags are replaced. Not only can you add custom tags this way, but you can customize their display style within the tag replacement itself (instead of the CSS flat file).

Code: Select all

 
function addTag($tag, $replace) {
    $this->basictags[] = $tag;
    $this->basicreplacements[] = $replace;
}
 
Just a thought!

- Moose
Last edited by feyd on Fri Aug 01, 2008 10:19 am, edited 1 time in total.
Reason: fix php tags.
User avatar
twigletmac
Her Royal Site Adminness
Posts: 5371
Joined: Tue Apr 23, 2002 2:21 am
Location: Essex, UK

Post by twigletmac »

Do be careful with using str_replace() to convert bbcode - if closing tags are missing it can cause all sorts of formatting weirdness...

Mac
Roja
Tutorials Group
Posts: 2692
Joined: Sun Jan 04, 2004 10:30 pm

Post by Roja »

twigletmac wrote:Do be careful with using str_replace() to convert bbcode - if closing tags are missing it can cause all sorts of formatting weirdness...
Can you help him by suggesting a solution? :)
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Post by Chris Corbyn »

Roja wrote:
twigletmac wrote:Do be careful with using str_replace() to convert bbcode - if closing tags are missing it can cause all sorts of formatting weirdness...
Can you help him by suggesting a solution? :)
Tokenize the string :)

Sorry to post this here - it was the quickest example. I wrote this BBCode parser in January.

Code: Select all

<?php
 
/*
 A custom BBCode handler.
 Chris Corbyn (Jan 2006)
 */
 
class BBCode
{
    protected
        $source,
        $output,
        $tokens = array(),
        $tags = array(
            'b' => '\[b\]',
            'u' => '\[u\]',
            'i' => '\[i\]',
            'size' => '\[size=([^\]]+)\]',
            'color' => '\[color=([^\]]+)\]',
            'img' => '\[img\]',
            'url' => '\[url=([^\]]+)\]',
            'quote' => '\[quote(?:="([^"]+)")?\]',
            'code' => '\[code(?:=([^\]]+))?\]',
            'list' => '\[list(?:=([^\]]+))?\]',
            'smilies' => ':dense:|:drunk:|:\)|:-\)|:smile:|;\)|;-\)|:wink:|:p|:P|:-p|:-P|:\(|:-\(|:sad:|:razz:|:\?|:confused:|:\||:-\||:blank:|:nod:|:shake:|:reading:|:cool:|:D|:-D|:grin:|:hit:|:smart:|:laugh:|:lol:|:thumbsup:|:thumbsdown:|:cry:|:wavecry:|:arrow:|:angry:|:woot:|:love:|:rolleyes:|:unsure:|:angel:|:clap:|:buzz:|:shocked:|:food:|:sleep:|:smirk:|:wiz:|:wizard:'
        );
        private $smiliePath = 'sys/img/smilies';
    
    function __construct($input)
    {
        $this->setSource($input);
    }
 
    //Tag name => RegExp
    public function setBBTag($tag, $eval)
    {
        $this->tags[$tag] = $eval;
    }
    
    protected function setSource($source)
    {
        $this->source = $source;
    }
    
    //Recursive
    protected function tokenize($tag, $text=false, $ignore=array(), $stack=array(), $recursing=false)
    {
        if (!$text && !$recursing) $text = $this->source;
        elseif (!$text && $recursing) return $stack; //Nothing left to do
        
        $block = '';
        foreach ($ignore as $t) $block .= $this->tags[$t].'.*?\[/'.$t.'\]|';
        
        $re = '@'.$block.$this->tags[$tag].'|\[/'.$tag.'\]@is'; //Opening tag or closing tag
        
        if (preg_match($re, $text, $matches, PREG_OFFSET_CAPTURE))
        {
            $chunks = $matches[0];
            $offset = 0;
            if ($chunks[1] > 0)
            {
                $offset = $chunks[1]; //Preg offset (substr)
                $plain_text = substr($text, 0, $offset);
                $stack[] = $plain_text; //Text before the tag
            }
            $stack[] = $chunks[0]; //The actual tag
            $text = substr($text, (strlen($chunks[0])+$offset)); //Drop chunk off the string since already processed
            return $this->tokenize($tag, $text, $ignore, $stack, 1); //Recurse
        }
        else
        {
            $stack[] = $text; //No match, nothing left to do
            return $stack;
        }
    }
 
    //Nothing more than a cascade through all the handlers
    public function parseComplete($source='')
    {
        if (empty($source)) $source = $this->source;
        $source = $this->parseSmilies($source);
        $source = $this->parseBold($source);
        $source = $this->parseItalic($source);
        $source = $this->parseUnderline($source);
        $source = $this->parseQuotes($source);
        $source = $this->parseUrl($source);
        $source = $this->parseCode($source);
        $this->output = $source;
        return $this->output;
    }
 
    public function parseSmilies($source='')
    {
        if (empty($source)) $source = $this->source;
        $this->tokens = $this->tokenize('smilies', $source); //Fetch tokens
        $ret = '';
        foreach ($this->tokens as $tok)
        {
            switch ($tok)
            {
                case ':)':
                case ':-)':
                case ':smile:':
                $ret .= '<img src="'.$this->smiliePath.'/smile1.gif" alt="smile" />';
                break;
                case ';)':
                case ';-)':
                case ':wink:':
                $ret .= '<img src="'.$this->smiliePath.'/wink.gif" alt="wink" />';
                break;
                case ':p':
                case ':P':
                case ':-p':
                case ':-P':
                case ':razz:':
                $ret .= '<img src="'.$this->smiliePath.'/tongue.gif" alt="razz" />';
                break;
                case ':(':
                case ':-(':
                case ':sad:':
                $ret .= '<img src="'.$this->smiliePath.'/sad.gif" alt="sad" />';
                break;
                case ':nod:':
                $ret .= '<img src="'.$this->smiliePath.'/yes.gif" alt="yes" />';
                break;
                case ':shake:':
                $ret .= '<img src="'.$this->smiliePath.'/no.gif" alt="no" />';
                break;
                case ':reading:':
                $ret .= '<img src="'.$this->smiliePath.'/coffee.gif" alt="coffee" />';
                break;
                case ':cool:':
                $ret .= '<img src="'.$this->smiliePath.'/cool2.gif" alt="cool" />';
                break;
                case ':D':
                case ':-D':
                case ':grin:':
                $ret .= '<img src="'.$this->smiliePath.'/grin.gif" alt="grin" />';
                break;
                case ':laugh:':
                case ':lol:':
                $ret .= '<img src="'.$this->smiliePath.'/laugh.gif" alt="laugh" />';
                break;
                case ':hit:':
                $ret .= '<img src="'.$this->smiliePath.'/hit.gif" alt="wollop" />';
                break;
                case ':thumbsup:':
                $ret .= '<img src="'.$this->smiliePath.'/thumbsup.gif" alt="thumbs up" />';
                break;
                case ':thumbsdown:':
                $ret .= '<img src="'.$this->smiliePath.'/thumbsdown.gif" alt="thumbs down" />';
                break;
                case ':dense:':
                $ret .= '<img src="'.$this->smiliePath.'/dense.gif" alt="dense" />';
                break;
                case ':smart:':
                $ret .= '<img src="'.$this->smiliePath.'/smartass.gif" alt="smart" />';
                break;
                case ':?':
                case ':confused:':
                $ret .= '<img src="'.$this->smiliePath.'/huh.gif" alt="confused" />';
                break;
                case ':arrow:':
                $ret .= '<img src="'.$this->smiliePath.'/arrow.gif" alt="arrow" />';
                break;
                case ':cry:':
                $ret .= '<img src="'.$this->smiliePath.'/cry.gif" alt="cry" />';
                break;
                case ':wavecry:':
                $ret .= '<img src="'.$this->smiliePath.'/wavecry.gif" alt="waving crying" />';
                break;
                case ':angry:':
                $ret .= '<img src="'.$this->smiliePath.'/wag.gif" alt="angry" />';
                break;
                case ':love:':
                $ret .= '<img src="'.$this->smiliePath.'/wub.gif" alt="lovey dovey" />';
                break;
                case ':woot:':
                $ret .= '<img src="'.$this->smiliePath.'/w00t.gif" alt="woot!" />';
                break;
                case ':rolleyes:':
                $ret .= '<img src="'.$this->smiliePath.'/rolleyes.gif" alt="rolling eyes" />';
                break;
                case ':unsure:':
                $ret .= '<img src="'.$this->smiliePath.'/hmmm.gif" alt="hmmm" />';
                break;
                case ':angel:':
                $ret .= '<img src="'.$this->smiliePath.'/angel.gif" alt="angel" />';
                break;
                case ':clap:':
                $ret .= '<img src="'.$this->smiliePath.'/clap2.gif" alt="clapping" />';
                break;
                case ':drunk:':
                $ret .= '<img src="'.$this->smiliePath.'/drunk.gif" alt="drunk" />';
                break;
                case ':buzz:':
                $ret .= '<img src="'.$this->smiliePath.'/mml.gif" alt="buzzing" />';
                break;
                case ':|':
                case ':-|':
                case ':blank:':
                $ret .= '<img src="'.$this->smiliePath.'/noexpression.gif" alt="blank" />';
                break;
                case ':shocked:':
                $ret .= '<img src="'.$this->smiliePath.'/ohmy.gif" alt="shocked" />';
                break;
                case ':food:':
                $ret .= '<img src="'.$this->smiliePath.'/pizza.gif" alt="pizza" />';
                break;
                case ':sleep:':
                $ret .= '<img src="'.$this->smiliePath.'/sleeping.gif" alt="sleeping" />';
                break;
                case ':smirk:':
                $ret .= '<img src="'.$this->smiliePath.'/smirk.gif" alt="smirk" />';
                break;
                case ':wiz:':
                case ':wizard:':
                $ret .= '<img src="'.$this->smiliePath.'/wizard.gif" alt="wizard" />';
                break;
                default: $ret .= $tok;
            }
        }
        return $ret;
    }
 
    public function parseUrl($source='')
    {
        if (empty($source)) $source = $this->source;
        $this->tokens = $this->tokenize('url', $source); //Fetch tokens
        if (!$this->checkClosure('url'))
        {
            $this->output = $source;
            return $this->output;
        }
        $ret = '';
        foreach ($this->tokens as $tok)
        {
            if (preg_match('@'.$this->tags['url'].'@is', $tok, $matches))
            { //Opening quote
                $href = $this->makeAbsoluteUrl($matches[1]);
                $ret .= '<a href="'.$href.'" target="_blank">';
            }
            elseif (preg_match('@\[/url\]@is', $tok, $matches))
            {
                $ret .= '</a>'; //Close the quote box
            }
            else
            {
                $ret .= $tok; //Insert the text
            }
        }
        $this->output = $ret;
        return $this->output;
    }
 
    private function checkClosure($tag)
    {
        $opened = 0;
        $closed = 0;
        foreach ($this->tokens as $tok)
        {
            if (preg_match('@'.$this->tags[$tag].'@is', $tok, $matches))
                $opened++;
            elseif (preg_match('@\[/'.$tag.'\]@is', $tok, $matches))
                $closed++;
        }
        if ($opened === $closed) return true;
    }
 
    private function makeAbsoluteUrl($url)
    {
        if (!preg_match('@^[a-z]+://@i', $url)) $url = 'http://'.$url;
        return $url;
    }
    
    public function parseQuotes($source='')
    {
        if (empty($source)) $source = $this->source;
        $this->tokens = $this->tokenize('quote', $source, array('code')); //Fetch tokens
        if (!$this->checkClosure('quote'))
        {
            $this->output = $source;
            return $this->output;
        }
        $ret = '';
        foreach ($this->tokens as $tok)
        {
            if (preg_match('@'.$this->tags['quote'].'@is', $tok, $matches))
            { //Opening quote
                $info = 'Quote';
                if (!empty($matches[1])) $info = $matches[1].' wrote'; //Name parameter given
                $ret .= '<div style="font-style: italic; border: 1px dotted #777777; background: #FFFFF8; padding: 4px; margin: 4px;">
                <div style="font-weight: bold; font-style: normal;">'.$info.':</div>';
            }
            elseif (preg_match('@\[/quote\]@is', $tok, $matches))
            {
                $ret .= '</div>'; //Close the quote box
            }
            else
            {
                $ret .= $tok; //Insert the text
            }
        }
        $this->output = $ret;
        return $this->output;
    }
 
    public function parseBold($source='')
    {
        if (empty($source)) $source = $this->source;
        $this->tokens = $this->tokenize('b', $source, array('code')); //Fetch tokens
        $ret = '';
        if (!$this->checkClosure('b'))
        {
            $this->output = $source;
            return $this->output;
        }
        foreach ($this->tokens as $tok)
        {
            if (preg_match('@'.$this->tags['b'].'@is', $tok, $matches))
            { //Opening tag
                $ret .= '<strong>';
            }
            elseif (preg_match('@\[/b\]@is', $tok, $matches))
            {
                $ret .= '</strong>'; //Close the tag
            }
            else
            {
                $ret .= $tok; //Insert the text
            }
        }
        $this->output = $ret;
        return $this->output;
    }
 
    public function parseItalic($source='')
    {
        if (empty($source)) $source = $this->source;
        $this->tokens = $this->tokenize('i', $source, array('code')); //Fetch tokens
        $ret = '';
        if (!$this->checkClosure('i'))
        {
            $this->output = $source;
            return $this->output;
        }
        foreach ($this->tokens as $tok)
        {
            if (preg_match('@'.$this->tags['i'].'@is', $tok, $matches))
            { //Opening tag
                $ret .= '<em>';
            }
            elseif (preg_match('@\[/i\]@is', $tok, $matches))
            {
                $ret .= '</em>'; //Close the tag
            }
            else
            {
                $ret .= $tok; //Insert the text
            }
        }
        $this->output = $ret;
        return $this->output;
    }
 
    public function parseUnderline($source='')
    {
        if (empty($source)) $source = $this->source;
        $this->tokens = $this->tokenize('u', $source, array('code')); //Fetch tokens
        $ret = '';
        if (!$this->checkClosure('u'))
        {
            $this->output = $source;
            return $this->output;
        }
        foreach ($this->tokens as $tok)
        {
            if (preg_match('@'.$this->tags['u'].'@is', $tok, $matches))
            { //Opening tag
                $ret .= '<u>';
            }
            elseif (preg_match('@\[/u\]@is', $tok, $matches))
            {
                $ret .= '</u>'; //Close the tag
            }
            else
            {
                $ret .= $tok; //Insert the text
            }
        }
        $this->output = $ret;
        return $this->output;
    }
 
    public function parseCode($source='')
    {
        if (empty($source)) $source = $this->source;
        $this->tokens = $this->tokenize('code', $source); //Fetch tokens
        $ret = '';
        if (!$this->checkClosure('code'))
        {
            $this->output = $source;
            return $this->output;
        }
        $type = false;
        $last = 0;
        $i = 0;
        foreach ($this->tokens as $tok)
        {
            $i++;
            if (preg_match('@'.$this->tags['code'].'@is', $tok, $matches))
            { //Opening code block
                if (!empty($matches[1]))
                {
                    switch (strtolower($matches[1]))
                    {
                        case 'javascript':
                        case 'js':
                        $type = 'js';
                        break;
                        default: $type = false;
                    }
                    $last = $i;
                }
                else $type = false;
                $ret .= '<div style=" border: 1px solid #AAAAAA; padding: 4px; margin: 4px; background: #FFFFFF;">
                <code style="white-space: pre; font-family: courier,monospace; color: #007700;">';
            }
            elseif (preg_match('@\[/code\]@is', $tok, $matches))
            {
                $ret .= '</code></div>'; //Close the code box
            }
            else
            {
                switch ($type)
                {
                    case 'js':
                    $js = new JSHighlight(str_replace('<br />', '', $tok));
                    if ($last == $i-1) $tok = $js->Generate(1);
                    break;
                }
                $ret .= $tok; //Insert the text
            }
        }
        $this->output = $ret;
        return $this->output;
    }
    
    //Just for debugging
    public function dumpTokens()
    {
        echo '<pre>'.print_r($this->tokens, 1).'</pre>';
    }
    
    //Internal
    protected function getOutput()
    {
        return $this->output;
    }
    
    public function fetchResult()
    {
        return $this->getOutput();
    }
}
 
?>
Last edited by Weirdan on Sun Feb 22, 2009 9:45 am, edited 3 times in total.
Reason: removed syntax highlighting so parser won't eat entire code block
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Post by Chris Corbyn »

Heh... well our Geshi MOD made a good job of that one :?
ziggy3000
Forum Contributor
Posts: 205
Joined: Fri Mar 23, 2007 3:04 pm

Post by ziggy3000 »

How do you use this code? it's pretty good. i copied the smilies. but after that what should i do to use your bbcode parser
LBmtb
Forum Newbie
Posts: 23
Joined: Wed May 14, 2008 11:14 am

Re: Simple BBTag Parser

Post by LBmtb »

Never used it but I know Pear has something that does something similar: http://pear.php.net/package/HTML_BBCodeParser
Post Reply