...

View Full Version : BBCode Parser



MRushton
11-02-2010, 10:45 AM
/**
* A class to allow easy parsing of BBCode
*
* @author Michael Rushton <michael@squiloople.com>
* @version 1.0
* @copyright 2010 Michael Rushton - http://squiloople.com
*
* Feel free to use and redistribute this code
*/

namespace Parsers;

final class BBCodeParser
{

/**
* Array to contain regular expressions of BB tags
*
* @access private
* @var array
*/

private $_bbTags = array(

'/\([\x20-\x7E]+?)\[\/b\]/i',
'/\([\x20-\x7E]+?)\[\/i\]/i',
'/\[u\]([\x20-\x7E]+?)\[\/u\]/i',
'/\[s\]([\x20-\x7E]+?)\[\/s\]/i',
'/\[sub\]([\x20-\x7E]+?)\[\/sub\]/i',
'/\[sup\]([\x20-\x7E]+?)\[\/sup\]/i',
'/\[img\]([\x20-\x7E]+?)\[\/img\]/i',
'/\[url\]([\x20-\x7E]+?)\[\/url\]/i',
'/\[email\]([\x20-\x7E]+?)\[\/email\]/i',
'/\[quote\]([\x20-\x7E]+?)\[\/quote\]/i',
'/\[color=([0-9a-f]{6})\]([\x20-\x7E]+?)\[\/color\]/i',
'/\[size=([1-9]?[0-9])\]([\x20-\x7E]+?)\[\/size\]/i',
'/\[font=([a-z\x20]+)\]([\x20-\x7E]+?)\[\/font\]/i',
'/\[img=([\x20-\x7E]+?)\]([\x20-\x7E]+?)\[\/img\]/i',
'/\+)\]([\x20-\x7E]+?)\[\/url\]/i',
'/\[email=([\x20-\x5A\x5C\x5E-\x7E]+)\]([\x20-\x7E]+?)\[\/email\]/i',
'/\[quote=([\x20-\x5A\x5C\x5E-\x7E]+)\]([\x20-\x7E]+?)\[\/quote\]/i',

);

/**
* Array to contain HTML tag replacements
*
* @access private
* @var array
*/

private $_htmlTags = array(

'<strong>$1</strong>',
'<em>$1</em>',
'<span style="text-decoration:underline">$1</span>',
'<del>$1</del>',
'<sub>$1</sub>',
'<sup>$1</sup>',
'<img src="$1" alt="" />',
'<a href="$1">$1</a>',
'<a href="mailto:$1">$1</a>',
'<fieldset>$1</fieldset>',
'<span style="color:#$1;background-color:transparent">$2</span>',
'<span style="font-size:$1px">$2</span>',
'<span style="font-family:\'$1\', sans-serif">$2</span>',
'<img src="$2" alt="$1" />',
'<a href="$1">$2</a>',
'<a href="mailto:$1">$2</a>',
'<fieldset><legend>$1</legend>$2</fieldset>',

);

/**
* Create "Text => <tag>Text</tag>" style BB tags
*
* @access public
* @param string
* @param string
*/

public function createTag($bb, $html = false)
{

// If an HTML tag is not specified, emulate the BB tag

$html = $html ?: $bb;

// Create a new BB tag regular expression of the form: Text

$this->_bbTags[] = '/\[' . $bb . '\]([\x20-\x7E]+?)\[\/' . $bb . '\]/i';

// Create a new HTML tag replacement of the form <tag>Text</tag>

$this->_htmlTags[] = '<' . $html . '>$1</' . $html . '>';

}

/**
* Create "Text => <tag option="option">Text</tag>" style BB tags
*
* @access public
* @param string
* @param string
*/

public function createParameterTag($bb, $html)
{

// Create a new BB tag regular expression of the form

$this->_bbTags[] = '/\[' . $bb . '=([\x20-\x5A\x5C\x5E-\x7E]+)\]([\x20-\x7E]+?)\[\/' . $bb . '\]/i';

// Create a new HTML tag replacement of the form <tag option="option">Text</tag>

$this->_htmlTags[] = '<' . $html . '>$2</' . strtok($html, ' ') . '>';

}

/**
* Create "[smile] => :)" style BB tags
*
* @access public
* @param string
* @param string
*/

public function createSpecialTag($bb, $html)
{

// Create a new BB tag regular expression of the form [tag] (does not require usual brackets)

$this->_bbTags[] = '/' . preg_quote($bb) . '/i';

// Create a new replacement (does not need to be an HTML tag)

$this->_htmlTags[] = $html;

}

/**
* Return the parsed string
*
* @access public
* @param string
* @return string
*/

public function parseString($string)
{

// Ensure that the loop runs at least once

$count = 1;

// Only replace tags if the string has not been fully parsed

while ($count !== 0) {

// Replace BB tags with HTML tags; will repeat if successful

$string = preg_replace($this->_bbTags, $this->_htmlTags, $string, -1, $count);

}

// Return the parsed string

return $string;

}

}


Usage example:



$stringParser = new BBCodeParser;

echo $stringParser->parseString('[url=http://example.com][b]Bold Example (([\x20-\x5A\x5C\x5E-\x7E)');

// <a href="http://example.com"><strong>Bold</strong></a>

$stringParser->createTag('p');
$stringParser->createTag('d', 'div');

echo $stringParser->parseString('[d]Paragraph 1Paragraph 2[/div]');

// <div><p>Paragraph 1</p><p>Paragraph 2</p></div>

$stringParser->createParameterTag('span', 'span id="$1"');

echo $stringParser->parseString('This has a parameter');

// <span id="special">This is special</span>

$stringParser->createSpecialTag(':)', '<img src="smile.png" alt="smile" />');

echo $stringParser->parseString('Look at my smile: :)');

// Look at my smile: <img src="smile.png" alt="smile" />


The default tags are:



Bold
Italics
[u]Underline
Strikethrough
Subscript
Superscript
image.png
http://example.com
michael@example.com

Quote
Red
15px
Arial
smile.png
Example (http://example.com)
Michael (michael@example.com)

Quote

SmoothieVemund
11-02-2010, 04:32 PM
Real cool. I want to use this in a textarea with a form. How can I do that?

<form action="post_massage.php" method="post">
<textarea rows="5" cols="55" name="post" wrap="physical">Enter your favorite quote!</textarea><br />
<input type="submit" />
</form>

MRushton
11-02-2010, 07:16 PM
If you're looking to insert/update a row into the table on the form submission, try this. Note, however, that where I have "new Parsers/BBCodeParser", it should say "new Parsers\BBCodeParser". Unfortunately, this forum seems to strip backslashes.




if (isset($_POST['post'])) {

require_once 'BBCodeParser.php';

$stringParser = new Parsers/BBCodeParser;

$parsedString = $mysqli->real_escape_string($stringParser->parseString($_POST['post']));

try {

if (!$mysqli->query("INSERT INTO `table` (`post`) VALUES ('" . $parsedString . "')") {
throw new Exception('Unable to insert the post into the database.');
}

}

catch (Exception $e) {
echo $e->getMessage();
}

}

MRushton
11-02-2010, 07:23 PM
To do list:

1. Include
tags which do not parse contents within
2. Enforce XHTML conformity
3. Make createOptionTag() more flexible (at the moment, to emulate the replacement for &#91;quote=parameter]Text&#91;/quote] one would need to do createOptionTag('quote', 'fieldset><legend>$1</legend'), which isn't very nice).
4. createTag(), createParameterTag(), and createSpecialTag() should return an array containing the BBCode regular expression and its HTML replacement.



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum