BBcode parser help

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
User avatar
spamyboy
Forum Contributor
Posts: 266
Joined: Sun Nov 06, 2005 11:29 am
Location: Lithuania, vilnius

BBcode parser help

Post by spamyboy »

Here is parser class:

Code: Select all

<?php
class HTML_BBCodeParser
{
    //An array of tags parsed by the engine

    var $_definedTags = array('b' => array( 'htmlopen'  => 'strong',
                                            'htmlclose' => 'strong',
                                            'allowed'   => 'all',
                                            'attributes'=> array()),
                              'i' => array( 'htmlopen'  => 'em',
                                            'htmlclose' => 'em',
                                            'allowed'   => 'all',
                                            'attributes'=> array()),
                              'u' => array( 'htmlopen'  => 'u',
                                            'htmlclose' => 'u',
                                            'allowed'   => 'all',
                                            'attributes'=> array()),
                              's' => array( 'htmlopen'  => 'del',
                                            'htmlclose' => 'del',
                                            'allowed'   => 'all',
                                            'attributes'=> array()),
                            'sub' => array( 'htmlopen'  => 'sub',
                                            'htmlclose' => 'sub',
                                            'allowed'   => 'all',
                                            'attributes'=> array()),
                            'sup' => array( 'htmlopen'  => 'sup',
                                            'htmlclose' => 'sup',
                                            'allowed'   => 'all',
                                            'attributes'=> array()),
                           'list' => array( 'htmlopen'  => 'ol',
                                            'htmlclose' => 'ol',
                                            'allowed'   => 'none^li',
                                            'attributes'=> array('list' => 'type=%2$s%1$s%2$s', 's' => 'start=%2$s%1$d%2$s')),
                          'ulist' => array( 'htmlopen'  => 'ul',
                                            'htmlclose' => 'ul',
                                            'allowed'   => 'none^li',
                                            'attributes'=> array()),
                             'li' => array( 'htmlopen'  => 'li',
                                            'htmlclose' => 'li',
                                            'allowed'   => 'all',
                                            'attributes'=> array('li' => 'value=%2$s%1$d%2$s')),
                          'color' => array( 'htmlopen'  => 'span',
                                            'htmlclose' => 'span',
                                            'allowed'   => 'all',
                                            'attributes'=> array('color' =>'style=%2$scolor: %1$s%2$s')),
                           'size' => array( 'htmlopen'  => 'span',
                                            'htmlclose' => 'span',
                                            'allowed'   => 'all',
                                            'attributes'=> array('size' =>'style=%2$sfont-size: %1$spt%2$s')),
                           'font' => array( 'htmlopen'  => 'span',
                                            'htmlclose' => 'span',
                                            'allowed'   => 'all',
                                            'attributes'=> array('font' =>'style=%2$sfont-family: %1$s%2$s')),
                          'align' => array( 'htmlopen'  => 'div',
                                            'htmlclose' => 'div',
                                            'allowed'   => 'all',
                                            'attributes'=> array('align' =>'style=%2$stext-align: %1$s%2$s')),
                          'quote' => array( 'htmlopen'  => 'blockquote',
                                            'htmlclose' => 'blockquote',
                                            'allowed'   => 'all',
                                            'attributes'=> array()),
                           'cite' => array( 'htmlopen'  => 'cite',
                                            'htmlclose' => 'cite',
                                            'allowed'   => 'all',
                                            'attributes'=> array()),
                           'code' => array( 'htmlopen'  => 'code',
                                            'htmlclose' => 'code',
                                            'allowed'   => 'all',
                                            'attributes'=> array()),
                            'img' => array( 'htmlopen'  => 'img',
                                            'htmlclose' => '',
                                            'allowed'   => 'none',
                                            'attributes'=> array('img' => 'src=%2$s%1$s%2$s', 'w' => 'width=%2$s%1$d%2$s', 'h' => 'height=%2$s%1$d%2$s')),
                            'url' => array( 'htmlopen'  => 'a',
                                            'htmlclose' => 'a',
                                            'allowed'   => 'none^img',
                                            'attributes'=> array('url' => 'href=%2$s%1$s%2$s', 't' => 'target=%2$s%1$s%2$s')));


    //A string containing the input

    var $_text          = '';


    //A string containing the preparsed input

    var $_preparsed     = '';


    //An array tags and texts build from the input text

    var $_tagArray      = array();


    //A string containing the parsed version of the text

    var $_parsed        = '';


    //An array of options, filled by an ini file or through the contructor

    var $_options = array('quotestyle' => 'single',
                          'quotewhat'  => 'all',
                          'open'       => '[',
                          'close'      => ']',
                          'xmlclose'   => true );



    // Constructor, initialises the options and filters

    function HTML_BBCodeParser($options = array())
    {
        //Set the options passed as an argument

        foreach ($options as $k => $v )  {
           $this->_options[$k] = $v;
        }


        //Add escape open and close chars to the options for preg escaping

        $preg_escape = '\^$.[]|()?*+{}';
        if (strstr($preg_escape, $this->_options['open'])) {
            $this->_options['open_esc'] = "\\".$this->_options['open'];
        } else {
            $this->_options['open_esc'] = $this->_options['open'];
        }
        if (strstr($preg_escape, $this->_options['close'])) {
            $this->_options['close_esc'] = "\\".$this->_options['close'];
        } else {
            $this->_options['close_esc'] = $this->_options['close'];
        }

    }




    //Executes statements before the actual array building starts

    function _preparse()
    {
		
        $o  = $this->_options['open'];
        $c  = $this->_options['close'];
        $oe = $this->_options['open_esc'];
        $ce = $this->_options['close_esc'];

        $this->_preparsed = $this->_text;

        //Links
        $pattern = array(   "!(^|\s|\()((((http(s?)|ftp)://)|www)[-a-z0-9.]+\.[a-z]{2,4}[^\s()]*)!i",
                            "!".$oe."url(".$ce."|\s.*".$ce.")(.*)".$oe."/url".$ce."!iU");
        $replace = array(   "\\1".$o."url".$c."\\2".$o."/url".$c,
                            $o."url=\\2\\1\\2".$o."/url".$c);

        $this->_preparsed = preg_replace($pattern, $replace, $this->_preparsed);


        //Image
        $this->_preparsed = preg_replace("!".$oe."img(".$ce."|\s.*".$ce.")(.*)".$oe."/img".$ce."!Ui", $o."img=\\2\\1".$o."/img".$c, $this->_preparsed);

        //List Items
        $this->_preparsed = preg_replace("!".$oe."\*".$ce."(.*)!i", $o."li".$c."\\1".$o."/li".$c, $this->_preparsed);
    }




    /**
    * Builds the tag array from the input string $_text
    *
    * An array consisting of tag and text elements is contructed from the
    * $_preparsed variable. The method uses _buildTag() to check if a tag is
    * valid and to build the actual tag to be added to the tag array.
    *
    * TODO: - rewrite whole method, as this one is old and probably slow
    *       - see if a recursive method would be better than an iterative one
    *
    * @return   none
    * @access   private
    * @see      _buildTag()
    * @see      $_text
    * @see      $_tagArray
    * @author   Stijn de Reede  <sjr@gmx.co.uk>
    */
    function _buildTagArray()
    {
        $this->_tagArray = array();
        $str = $this->_preparsed;
        $strPos = 0;
        $strLength = strlen($str);

        while ( ($strPos < $strLength) ) {
            $tag = array();
            $openPos = strpos($str, $this->_options['open'], $strPos);
            if ($openPos === false) {
                $openPos = $strLength;
                $nextOpenPos = $strLength;
            }
            if ($openPos + 1 > $strLength) {
                $nextOpenPos = $strLength;
            } else {
                $nextOpenPos = strpos($str, $this->_options['open'], $openPos + 1);
                if ($nextOpenPos === false) {
                    $nextOpenPos = $strLength;
                }
            }
            $closePos = strpos($str, $this->_options['close'], $strPos);
            if ($closePos === false) {
                $closePos = $strLength + 1;
            }

            if ( $openPos == $strPos ) {
                if ( ($nextOpenPos < $closePos) ) {
                    /* new open tag before closing tag: treat as text */
                    $newPos = $nextOpenPos;
                    $tag['text'] = substr($str, $strPos, $nextOpenPos - $strPos);
                    $tag['type'] = 0;
                } else {
                    /* possible valid tag */
                    $newPos = $closePos + 1;
                    $newTag = $this->_buildTag(substr($str, $strPos, $closePos - $strPos + 1));
                    if ( ($newTag !== false) ) {
                        $tag = $newTag;
                    } else {
                    /* no valid tag after all */
                        $tag['text'] = substr($str, $strPos, $closePos - $strPos + 1);
                        $tag['type'] = 0;
                    }
                }
            } else {
                /* just text */
                $newPos = $openPos;
                $tag['text'] = substr($str, $strPos, $openPos - $strPos);
                $tag['type'] = 0;
            }

            /* join 2 following text elements */
            if ($tag['type'] === 0 && isset($prev) && $prev['type'] === 0) {
                $tag['text'] = $prev['text'].$tag['text'];
                array_pop($this->_tagArray);
            }

            $this->_tagArray[] = $tag;
            $prev = $tag;
            $strPos = $newPos;
        }
    }




    /**
    * Builds a tag from the input string
    *
    * This method builds a tag array based on the string it got as an
    * argument. If the tag is invalid, <false> is returned. The tag
    * attributes are extracted from the string and stored in the tag
    * array as an associative array.
    *
    * @param    string          string to build tag from
    * @return   array           tag in array format
    * @access   private
    * @see      _buildTagArray()
    * @author   Stijn de Reede  <sjr@gmx.co.uk>
    */
    function _buildTag($str)
    {
        $tag = array('text' => $str, 'attributes' => array());

        if (substr($str, 1, 1) == '/') {        /* closing tag */

            $tag['tag'] = substr($str, 2, strlen($str) - 3);
            if ( (in_array($tag['tag'], array_keys($this->_definedTags)) == false) ) {
                return false;                   /* nope, it's not valid */
            } else {
                $tag['type'] = 2;
                return $tag;
            }
        } else {                                /* opening tag */

            $tag['type'] = 1;
            if ( (strpos($str, ' ') == true) && (strpos($str, '=') == false) ) {
                return false;                   /* nope, it's not valid */
            }

            /* tnx to Onno for the regex
               split the tag with arguments and all */
            $oe = $this->_options['open_esc'];
            $ce = $this->_options['close_esc'];
            if (preg_match("!$oe([a-z]+)[^$ce]*$ce!i", $str, $tagArray) == 0) {
                return false;
            }
            $tag['tag'] = $tagArray[1];
            if ( (in_array($tag['tag'], array_keys($this->_definedTags)) == false) ) {
                return false;                   /* nope, it's not valid */
            }

            /* tnx to Onno for the regex
               validate the arguments */
            preg_match_all("![\s$oe]([a-z]+)=([^\s$ce]+)(?=[\s$ce])!i", $str, $attributeArray, PREG_SET_ORDER);
            foreach ($attributeArray as $attribute) {
                if ( (in_array($attribute[1], array_keys($this->_definedTags[$tag['tag']]['attributes'])) == true) ) {
                    $tag['attributes'][$attribute[1]] = $attribute[2];
                }
            }
            return $tag;
        }
    }




    /**
    * Validates the tag array, regarding the allowed tags
    *
    * While looping through the tag array, two following text tags are
    * joined, and it is checked that the tag is allowed inside the
    * last opened tag.
    * By remembering what tags have been opened it is checked that
    * there is correct (xml compliant) nesting.
    * In the end all still opened tags are closed.
    *
    * @return   none
    * @access   private
    * @see      _isAllowed()
    * @see      $_tagArray
    * @author   Stijn de Reede  <sjr@gmx.co.uk>
    */
    function _validateTagArray()
    {
        $newTagArray = array();
        $openTags = array();
        foreach ($this->_tagArray as $tag) {
            $prevTag = end($newTagArray);
            switch ($tag['type']) {
            case 0:
                if ($prevTag['type'] === 0) {
                    $tag['text'] = $prevTag['text'].$tag['text'];
                    array_pop($newTagArray);
                }
                $newTagArray[] = $tag;
                break;

            case 1:
                if ($this->_isAllowed(end($openTags), $tag['tag']) == false) {
                    $tag['type'] = 0;
                    if ($prevTag['type'] === 0) {
                        $tag['text'] = $prevTag['text'].$tag['text'];
                        array_pop($newTagArray);
                    }
                } else {
                    $openTags[] = $tag['tag'];
                }
                $newTagArray[] = $tag;
                break;

            case 2:
                if ( ($this->_isAllowed(end($openTags), $tag['tag']) == true) || ($tag['tag'] == end($openTags)) ) {
                    if (in_array($tag['tag'], $openTags)) {
                        $tmpOpenTags = array();
                        while (end($openTags) != $tag['tag']) {
                            $newTagArray[] = $this->_buildTag('[/'.end($openTags).']');
                            $tmpOpenTags[] = end($openTags);
                            array_pop($openTags);
                        }
                        $newTagArray[] = $tag;
                        array_pop($openTags);
                        while (end($tmpOpenTags)) {
                            $tmpTag = $this->_buildTag('['.end($tmpOpenTags).']');
                            $newTagArray[] = $tmpTag;
                            $openTags[] = $tmpTag['tag'];
                            array_pop($tmpOpenTags);
                        }
                    }
                } else {
                    $tag['type'] = 0;
                    if ($prevTag['type'] === 0) {
                        $tag['text'] = $prevTag['text'].$tag['text'];
                        array_pop($newTagArray);
                    }
                    $newTagArray[] = $tag;
                }
                break;
            }
        }
        while (end($openTags)) {
            $newTagArray[] = $this->_buildTag('[/'.end($openTags).']');
            array_pop($openTags);
        }
        $this->_tagArray = $newTagArray;
    }




    /**
    * Checks to see if a tag is allowed inside another tag
    *
    * The allowed tags are extracted from the private _definedTags array.
    *
    * @param    array           tag that is on the outside
    * @param    array           tag that is on the inside
    * @return   boolean         return true if the tag is allowed, false
    *                           otherwise
    * @access   private
    * @see      _validateTagArray()
    * @author   Stijn de Reede  <sjr@gmx.co.uk>
    */
    function _isAllowed($out, $in)
    {
        if (!$out)                                          return true;
        if ($this->_definedTags[$out]['allowed'] == 'all')  return true;
        if ($this->_definedTags[$out]['allowed'] == 'none') return false;

        $ar = explode('^', $this->_definedTags[$out]['allowed']);
        $tags = explode(',', $ar[1]);
        if ($ar[0] == 'none' && in_array($in, $tags))       return true;
        if ($ar[0] == 'all'  && in_array($in, $tags))       return false;
        return false;
    }




    /**
    * Builds a parsed string based on the tag array
    *
    * The correct html and atribute values are extracted from the private
    * _definedTags array.
    *
    * @return   none
    * @access   private
    * @see      $_tagArray
    * @see      $_parsed
    * @author   Stijn de Reede  <sjr@gmx.co.uk>
    */
    function _buildParsedString()
    {
        $this->_parsed = '';
        foreach ($this->_tagArray as $tag) {
            switch ($tag['type']) {

            /* just text */
            case 0:
                $this->_parsed .= $tag['text'];
                break;

            /* opening tag */
            case 1:
                $this->_parsed .= '<'.$this->_definedTags[$tag['tag']]['htmlopen'];
                if ($this->_options['quotestyle'] == 'single') $q = "'";
                if ($this->_options['quotestyle'] == 'double') $q = '"';
                foreach ($tag['attributes'] as $a => $v) {
                    if (    ($this->_options['quotewhat'] == 'nothing') ||
                            ($this->_options['quotewhat'] == 'strings') && (is_numeric($v)) ) {
                        $this->_parsed .= ' '.sprintf($this->_definedTags[$tag['tag']]['attributes'][$a], $v, '');
                    } else {
                        $this->_parsed .= ' '.sprintf($this->_definedTags[$tag['tag']]['attributes'][$a], $v, $q);
                    }
                }
                if ($this->_definedTags[$tag['tag']]['htmlclose'] == '' && $this->_options['xmlclose']) {
                    $this->_parsed .= ' /';
                }
                $this->_parsed .= '>';
                break;

            /* closing tag */
            case 2:
                if ($this->_definedTags[$tag['tag']]['htmlclose'] != '') {
                    $this->_parsed .= '</'.$this->_definedTags[$tag['tag']]['htmlclose'].'>';
                }
                break;
            }
        }

    }




    /**
    * Sets text in the object to be parsed
    *
    * @param    string          the text to set in the object
    * @return   none
    * @access   public
    * @see      getText()
    * @see      $_text
    * @author   Stijn de Reede  <sjr@gmx.co.uk>
    */
    function setText($str)
    {
        $this->_text = $str;
    }




    /**
    * Gets the unparsed text from the object
    *
    * @return   string          the text set in the object
    * @access   public
    * @see      setText()
    * @see      $_text
    * @author   Stijn de Reede  <sjr@gmx.co.uk>
    */
    function getText()
    {
        return $this->_text;
    }




    /**
    * Gets the preparsed text from the object
    *
    * @return   string          the text set in the object
    * @access   public
    * @see      _preparse()
    * @see      $_preparsed
    * @author   Stijn de Reede  <sjr@gmx.co.uk>
    */
    function getPreparsed()
    {
        return $this->_preparsed;
    }




    /**
    * Gets the parsed text from the object
    *
    * @return   string          the parsed text set in the object
    * @access   public
    * @see      parse()
    * @see      $_parsed
    * @author   Stijn de Reede  <sjr@gmx.co.uk>
    */
    function getParsed()
    {
        return $this->_parsed;
    }




    /**
    * Parses the text set in the object
    *
    * @return   none
    * @access   public
    * @see      _preparse()
    * @see      _buildTagArray()
    * @see      _validateTagArray()
    * @see      _buildParsedString()
    * @author   Stijn de Reede  <sjr@gmx.co.uk>
    */
    function parse()
    {
        $this->_preparse();
        $this->_buildTagArray();
        $this->_validateTagArray();
        $this->_buildParsedString();
    }




    /**
    * Quick method to do setText(), parse() and getParsed at once
    *
    * @return   none
    * @access   public
    * @see      parse()
    * @see      $_text
    * @author   Stijn de Reede  <sjr@gmx.co.uk>
    */
    function qparse($str)
    {
        $this->_text = $str;
        $this->parse();
        return $this->_parsed;
    }




    /**
    * Quick static method to do setText(), parse() and getParsed at once
    *
    * @return   none
    * @access   public
    * @see      parse()
    * @see      $_text
    * @author   Stijn de Reede  <sjr@gmx.co.uk>
    */
    function staticQparse($str)
    {
        $p = new HTML_BBCodeParser();
        $str = $p->qparse($str);
        unset($p);
        return $str;
    }


}


?>
Here is example, where I get error:

Code: Select all

[code]<?php
    function createHeader(){
        $from   = "From: $this->fromName <$this->fromEmail>\r\n";

        $replay = "Reply-To: $this->replyEmail\r\n";    
        $params = "MIME-Version: 1.0\r\n";
        $params .= "Content-type: $this->type; charset=$this->characterSet\r\n";
        $this->header = $from.$replay.$params;
        return $this->header;
    }
?>[/code]
parser closes code allready in:

Code: Select all

[code]<?php
    function createHeader(){
        $from   = "From: $this->fromName <$this->fromEmail>\r\n";
<<-- HERE
        $replay = "Reply-To: $this->replyEmail\r\n";    
        $params = "MIME-Version: 1.0\r\n";
        $params .= "Content-type: $this->type; charset=$this->characterSet\r\n";
        $this->header = $from.$replay.$params;
        return $this->header;
    }
?>[/code]
It couses of whitespaces (probaly), I think so, becoause it works when I write it like:

Code: Select all

[code]<?php
    function createHeader(){
        $from   = "From: $this->fromName <$this->fromEmail>\r\n";
        $replay = "Reply-To: $this->replyEmail\r\n";    
        $params = "MIME-Version: 1.0\r\n";
        $params .= "Content-type: $this->type; charset=$this->characterSet\r\n";
        $this->header = $from.$replay.$params;
        return $this->header;
    }
?>[/code]
Pleas help to fix it.
User avatar
spamyboy
Forum Contributor
Posts: 266
Joined: Sun Nov 06, 2005 11:29 am
Location: Lithuania, vilnius

Post by spamyboy »

Here is another file that might couse it:

Code: Select all

<?php
// some definitions
$Context->Dictionary['bbbold'] = 'Bold';
$Context->Dictionary['bbitalic'] = 'Italic';
$Context->Dictionary['bbunderline'] = 'Underline';
$Context->Dictionary['bbstrikethrough'] = 'Strikethrough';
$Context->Dictionary['bbalignleft'] = 'Align Left';
$Context->Dictionary['bbaligncenter'] = 'Align Center';
$Context->Dictionary['bbalignright'] = 'Align Right';
$Context->Dictionary['bbcode'] = 'Code';
$Context->Dictionary['bbcolor'] = 'Font Color';
$Context->Dictionary['bbfont'] = 'Font Face';
$Context->Dictionary['bbimage'] = 'Insert Image';
$Context->Dictionary['bblist'] = 'List';
$Context->Dictionary['bbolist'] = 'Ordered List';
$Context->Dictionary['bbquote'] = 'Blockquote';
$Context->Dictionary['bbsub'] = 'Sub';
$Context->Dictionary['bbsup'] = 'Sup';
$Context->Dictionary['bburl'] = 'Insert Link';
$Context->Dictionary['bbmail'] = 'Insert Mail Link';

// set the default formatter to BBCode
$Context->Configuration['DEFAULT_FORMAT_TYPE'] = 'BBCode';

// by only having the BBCode option, you force all other formats to be parsed as BBCode
$Context->Configuration['FORMAT_TYPES'] = array('BBCode'); 

// overwrite a user preference for showing/hiding the format selector radio buttons
$Context->Session->User->Preferences['ShowFormatSelector'] = 0;

if (in_array($Context->SelfUrl, array("post.php", "comments.php"))) {

	class ForcedBBBar {
		var $Name;
		var $Context;
		
		function ForcedBBBar(&$Context) {
			$this->Name = "ForcedBBBar";
			$this->Context = &$Context;
		}
		function ForcedBBBar_Create() {
		
			$path = $this->Context->Configuration["BASE_URL"].'extensions/ForcedBBCode/';
			
			// get us a spot in the list
			echo '<li><div id="ForcedBBBar">';
			
			// base controls
			?>
			
			<a onclick="insert('b','/b')"><img src="<?php echo $path ?>buttons/text_bold.gif" alt="<?php echo $this->Context->GetDefinition('bbbold') ?>" title="<?php echo $this->Context->GetDefinition('bbbold') ?>" /></a>
			<a onclick="insert('i','/i')"><img src="<?php echo $path ?>buttons/text_italic.gif" alt="<?php echo $this->Context->GetDefinition('bbitalic') ?>" title="<?php echo $this->Context->GetDefinition('bbitalic') ?>" /></a>
			<a onclick="insert('u','/u')"><img src="<?php echo $path ?>buttons/text_underline.gif" alt="<?php echo $this->Context->GetDefinition('bbunderline') ?>" title="<?php echo $this->Context->GetDefinition('bbunderline') ?>" /></a>
			<a onclick="insert('s','/s')"><img src="<?php echo $path ?>buttons/text_strikethrough.gif" alt="<?php echo $this->Context->GetDefinition('bbstrikethrough') ?>" title="<?php echo $this->Context->GetDefinition('bbstrikethrough') ?>" /></a>
			<a onclick="insert('align=left','/align')"><img src="<?php echo $path ?>buttons/text_align_left.gif" alt="<?php echo $this->Context->GetDefinition('bbalignleft') ?>" title="<?php echo $this->Context->GetDefinition('bbalignleft') ?>" /></a>
			<a onclick="insert('align=center','/align')"><img src="<?php echo $path ?>buttons/text_align_center.gif" alt="<?php echo $this->Context->GetDefinition('bbaligncenter') ?>" title="<?php echo $this->Context->GetDefinition('bbaligncenter') ?>" /></a>
			<a onclick="insert('align=right','/align')"><img src="<?php echo $path ?>buttons/text_align_right.gif" alt="<?php echo $this->Context->GetDefinition('bbalignright') ?>" title="<?php echo $this->Context->GetDefinition('bbalignright') ?>" /></a>
			<a onclick="insert('code','/code')"><img src="<?php echo $path ?>buttons/text_code.gif" alt="<?php echo $this->Context->GetDefinition('bbcode') ?>" title="<?php echo $this->Context->GetDefinition('bbcode') ?>" /></a>
			<a onclick="showColor()"><img src="<?php echo $path ?>buttons/text_color.gif" alt="<?php echo $this->Context->GetDefinition('bbcolor') ?>" title="<?php echo $this->Context->GetDefinition('bbcolor') ?>" /></a>
			<a onclick="showFont()"><img src="<?php echo $path ?>buttons/text_font.gif" alt="<?php echo $this->Context->GetDefinition('font') ?>" title="<?php echo $this->Context->GetDefinition('bbfont') ?>" /></a>
			<a onclick="insertImage()"><img src="<?php echo $path ?>buttons/text_image.gif" alt="<?php echo $this->Context->GetDefinition('bbimage') ?>" title="<?php echo $this->Context->GetDefinition('bbimage') ?>" /></a>
			<a onclick="list('u')"><img src="<?php echo $path ?>buttons/text_list_bullets.gif" alt="<?php echo $this->Context->GetDefinition('bblist') ?>" title="<?php echo $this->Context->GetDefinition('bblist') ?>" /></a>
			<a onclick="list('o')"><img src="<?php echo $path ?>buttons/text_list_numbers.gif" alt="<?php echo $this->Context->GetDefinition('bbolist') ?>" title="<?php echo $this->Context->GetDefinition('bbolist') ?>" /></a>
			<a onclick="insert('quote','/quote')"><img src="<?php echo $path ?>buttons/text_quote.gif" alt="<?php echo $this->Context->GetDefinition('bbquote') ?>" title="<?php echo $this->Context->GetDefinition('bbquote') ?>" /></a>
			<a onclick="insert('sub','/sub')"><img src="<?php echo $path ?>buttons/text_subscript.gif" alt="<?php echo $this->Context->GetDefinition('bbsub') ?>" title="<?php echo $this->Context->GetDefinition('bbsub') ?>" /></a>
			<a onclick="insert('sup','/sup')"><img src="<?php echo $path ?>buttons/text_superscript.gif" alt="<?php echo $this->Context->GetDefinition('bbsup') ?>" title="<?php echo $this->Context->GetDefinition('bbsup') ?>" /></a>
			<a onclick="insertURL()"><img src="<?php echo $path ?>buttons/text_url.gif" alt="<?php echo $this->Context->GetDefinition('bburl') ?>" title="<?php echo $this->Context->GetDefinition('bburl') ?>" /></a>
			<a onclick="insertMail()"><img src="<?php echo $path ?>buttons/text_mail.gif" alt="<?php echo $this->Context->GetDefinition('bbmail') ?>" title="<?php echo $this->Context->GetDefinition('bbmail') ?>" /></a>
			
			<?php
			
			// color picker
			echo '<div id="ForcedBBBarColorPicker" style="display:none;">';
			$array = array('CCFF','CCCC','CC99','CC66','CC33','CC00','6600','6633','6666','6699','66CC','66FF','00FF','00CC','0099','0066','0033','0000');
			$array2 = array('FF','CC','99','66','33','00');
			$zeile = 1;
			while ($zeile <= 6) {
				$spalte = 1;
				while ($spalte <= 18) {
					$i = $spalte -1;
					$j = $zeile - 1;
					$col = substr($array[$i],0,2).$array2[$j].substr($array[$i],2,2);
					echo '<div onclick="writeColor(\''.$col.'\'); " title="#'.$col.'" style="cursor:pointer; position:absolute; left:'.(10+($spalte-1)*10).'px; top:'.(($zeile-1)*10).'px; width:9px; height:9px; border:1px solid #000; background-color:#'.$col.'">&nbsp;</div>';
					$spalte++;	
				}
				$zeile++;
			}
			$array = array('FFFF','FFCC','FF99','FF66','FF33','FF00','9900','9933','9966','9999','99CC','99FF','33FF','33CC','3399','3366','3333','3300');
			$array2 = array('FF','CC','99','66','33','00');
			$zeile = 7;
			while ($zeile <= 12) {
				$spalte = 1;
				while ($spalte <= 18) {
					$i = $spalte -1;
					$j = 12 - $zeile;
					$col = substr($array[$i],0,2).$array2[$j].substr($array[$i],2,2);
					echo '<div onclick="writeColor(\''.$col.'\');" title="#'.$col.'" style="cursor:pointer; position:absolute; left:'.(10+($spalte-1)*10).'px; top:'.(($zeile-1)*10).'px; width:9px; height:9px; border:1px solid #000; background-color:#'.$col.';">&nbsp;</div>';
					$spalte++;	
				}
				$zeile++;
			}
			$array = array('000000','333333','666666','999999','CCCCCC','FFFFFF','FF0000','00FF00','0000FF','FFFF00','00FFFF','FF00FF');
			$zeile = 1;
			while ($zeile <= 12) {
				$i = $zeile -1;
				$col = $array[$i];
				echo '<div onclick="writeColor(\''.$col.'\');" title="#'.$col.'" style="cursor:pointer; position:absolute; left:0px; top:'.(($zeile-1)*10).'px; width:9px; height:9px; border:1px solid #000; background-color:#'.$col.';">&nbsp;</div>';
				$zeile++;
			}		
			echo '</div>';
			
			// font picker
			echo '<div id="ForcedBBBarFontPicker" style="display:none;">';	
			$array = array('Arial','Helvetica','Times New Roman','Times','Courier New','Courier','Georgia','Geneva');
			foreach ($array AS $value) {
				echo '<a class="ForcedBBBarFontList" onclick="writeFont(\''.$value.'\');" title="'.$value.'">&nbsp;&bull;&nbsp;<span style="font-family: '.$value.'">'.$value.'</span></a>';
			}
			echo'</div>';
			
			// close it up
			echo '</div></li>';
		}

	}
	
	$Head->AddStyleSheet('extensions/ForcedBBCode/style.css');
	$Head->AddScript('extensions/ForcedBBCode/functions.js');

	function AddForcedBBCodetoCommentForm(&$DiscussionForm) {
		$ForcedBBBar = new ForcedBBBar($DiscussionForm->Context);
		$ForcedBBBar->ForcedBBBar_Create();
	}
	
	if( $Context->Session->UserID > 0 ) {
		$Context->AddToDelegate('DiscussionForm', 'CommentForm_PreCommentsInputRender', 'AddForcedBBCodetoCommentForm');
		$Context->AddToDelegate('DiscussionForm', 'DiscussionForm_PreCommentRender',    'AddForcedBBCodetoCommentForm');
	}
	
}

// remove the preference for showing/hiding the "Show Format Selector"
if( $Context->SelfUrl == 'account.php' ) {
	function PreferencesForm_RemoveSFS(&$PreferencesForm) {
		unset($PreferencesForm->Preferences['CommentsForm']);
	}
	$Context->AddToDelegate('PreferencesForm', 'PreRender', 'PreferencesForm_RemoveSFS');
}

require_once('BBCodeParser.php');

class ForcedBetterBBCodeFormatter extends StringFormatter {

	function Parse($String, $Object, $FormatPurpose) {
		$parser = new HTML_BBCodeParser();
		
		if ($FormatPurpose == FORMAT_STRING_FOR_DISPLAY) {
			$String = $this->ProtectString($String);
			$String = $parser->qparse($String);
			$String = $this->wpautop($String);
		}
		
		return $String;
	}
		
	function ProtectString ($String) {
		$String = str_replace(array('<','>'), array('<','>'), $String);
		return $String;
	}
	
	// graciously borrowed from wordpress 
	function wpautop($pee, $br = 1) {
		$pee = $pee . "\n"; // just to make things a little easier, pad the end
		$pee = preg_replace('|<br />\s*<br />|', "\n\n", $pee); // Space things out a little
		$allblocks = '(?:table|thead|tfoot|caption|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|select|form|blockquote|address|math|style|script|object|input|param|p|h[1-6])';
		$pee = preg_replace('!(<' . $allblocks . '[^>]*>)!', "\n$1", $pee);
		$pee = preg_replace('!(</' . $allblocks . '>)!', "$1\n\n", $pee);
		$pee = str_replace(array("\r\n", "\r"), "\n", $pee); // cross-platform newlines
		$pee = preg_replace("/\n\n+/", "\n\n", $pee); // take care of duplicates
		$pee = preg_replace('/\n?(.+?)(?:\n\s*\n|\z)/s', "<p>$1</p>\n", $pee); // make paragraphs, including one at the end
		$pee = preg_replace('|<p>\s*?</p>|', '', $pee); // under certain strange conditions it could create a P of entirely whitespace
		$pee = preg_replace('!<p>\s*(</?' . $allblocks . '[^>]*>)\s*</p>!', "$1", $pee); // don't pee all over a tag
		$pee = preg_replace("|<p>(<li.+?)</p>|", "$1", $pee); // problem with nested lists
		$pee = preg_replace('|<p><blockquote([^>]*)>|i', "<blockquote$1><p>", $pee);
		$pee = str_replace('</blockquote></p>', '</p></blockquote>', $pee);
		$pee = preg_replace('!<p>\s*(</?' . $allblocks . '[^>]*>)!', "$1", $pee);
		$pee = preg_replace('!(</?' . $allblocks . '[^>]*>)\s*</p>!', "$1", $pee);
		if ($br) {
			$pee = preg_replace('/<(script|style).*?<\/\\1>/se', 'str_replace("\n", "<WPPreserveNewline />", "\\0")', $pee);
			$pee = preg_replace('|(?<!<br />)\s*\n|', "<br />\n", $pee); // optionally make line breaks
			$pee = str_replace('<WPPreserveNewline />', "\n", $pee);
		}
		$pee = preg_replace('!(</?' . $allblocks . '[^>]*>)\s*<br />!', "$1", $pee);
		$pee = preg_replace('!<br />(\s*</?(?:p|li|div|dl|dd|dt|th|pre|td|ul|ol)[^>]*>)!', '$1', $pee);
		if ( strstr( $pee, '<pre' ) )
			$pee = preg_replace('!(<pre.*?>)(.*?)</pre>!ise', " stripslashes('$1') .  stripslashes(clean_pre('$2'))  . '</pre>' ", $pee);
		$pee = preg_replace( "|\n</p>$|", '</p>', $pee );
		return $pee;
	}
	
}

// Instantiate the bbcode object and add it to the string manipulation methods
$ForcedBetterBBCodeFormatter = $Context->ObjectFactory->NewObject($Context, "ForcedBetterBBCodeFormatter");
$Context->StringManipulator->AddManipulator("BBCode", $ForcedBetterBBCodeFormatter);

?>
User avatar
spamyboy
Forum Contributor
Posts: 266
Joined: Sun Nov 06, 2005 11:29 am
Location: Lithuania, vilnius

Post by spamyboy »

Bump
Post Reply