getSmiliesEmos();
$self = dirname($_SERVER['PHP_SELF']);
$this->_root_url = $self == '/' ? '' : $self;
$this->_smilies = array(
':D' => '
',
';)' => '
',
':p' => '
',
':P' => '
',
':)' => '
',
':(' => '
',
':o' => '
',
':O' => '
',
'^^' => '
',
'>:(' => '
',
'8)' => '
',
);
$this->_emos = array(
':lol:' => '
',
':huh:' => '
',
':angry:' => '
',
':cool:' => '
',
':moon:' => '
',
);
}
function &getInstance() {
static $instance = NULL;
if ($instance === NULL)
$instance = array(new BBEmoticons);
return $instance[0];
}
function parse($text) {
foreach($this->_smilies as $smily => $image) { // => $img
$regex = '~('.preg_quote($smily).')(\W|$)~e';
$text = preg_replace($regex, '$this->_smilies["$1"]."$2"', $text);
}
$text = str_replace(array_keys($this->_emos), array_values($this->_emos), $text);
return $text;
}
function revert($text) {
$text = strtr($text, array_flip($this->_smilies));
$text = strtr($text, array_flip($this->_emos));
return $text;
}
}
// includes carriage returns
function nltobr($str) {
return preg_replace("~(\r\n|\n\r|\r|\n)+~", '
', $str);
}
class BBCodeStack {
var $_items = array();
var $_size = 0;
function _update() {
$this->_size = sizeof($this->_items);
}
function getSize() {
return $this->_size;
}
function pop() {
$ret = FALSE;
if ($this->_size > 0)
$ret = TRUE;
array_pop($this->_items);
$this->_update();
return $ret;
}
function push(&$value) {
$this->_items[] = &$value;
$this->_update();
}
function &top() {
$ret = NULL;
if ($this->_size > 0)
$ret = &$this->_items[$this->_size - 1];
return $ret;
}
}
class BBNode {
var $_children = array();
function addChild(&$child) {
$this->_children[] = &$child;
}
function getChildren() {
return $this->_children;
}
function getTagNames() {
return array();
}
function getRevertPatterns() {
return array();
}
function flatten($noparse = FALSE) {
$buffer = '';
for ($i = 0; $i < sizeof($this->_children); $i++) {
$buffer .= $this->_children[$i]->flatten($noparse);
}
return $buffer;
}
function revert() {
$buffer = '';
for ($i = 0; $i < sizeof($this->_children); $i++) {
$buffer .= $this->_children[$i]->revert();
}
return $buffer;
}
}
class BBRootNode extends BBNode {
function getTag() {
return 'ROOT_TAG';
}
}
class BBTextNode extends BBNode {
var $_text;
function BBTextNode($text) {
$this->_text = $text;
}
function handleUrl($matches) {
$url = ($matches[2]) ? $matches[0] : 'http://' . $matches[0];
return "". $matches[0] ."";
}
function flatten($noparse = FALSE) {
if ($noparse) return $this->_text;
$buffer = preg_replace_callback(K4_REGEX_URL, array(&$this, 'handleUrl'), $this->_text);
$paras = preg_split('~(?:(\r\n|\n\r|\r|\n)){2}~', $buffer);
if (count($paras) > 1) {
$buffer = '';
foreach ($paras as $para)
if ($para = trim($para))
$buffer .= "\n\n
". nltobr($para) ."
";
$buffer .= "\n\n";
}
$emos = &BBEmoticons::getInstance();
$buffer = $emos->parse($buffer);
return $buffer;
}
function revert() {
return $this->_text;
}
}
class BBTagNode extends BBNode {
var $_tag;
var $_attrib;
function BBTagNode($tag, $attrib) {
$this->_tag = $tag;
$this->_attrib = $attrib;
}
function getClass() {
return 'class="bb_'.$this->getTag().'"';
}
function getTag() {
return $this->_tag;
}
function getUnparsed($noparse = FALSE) {
$attrib = ($this->_attrib) ? '=' . $this->_attrib : '';
return "[{$this->_tag}$attrib]" . parent::flatten($noparse) . "[/{$this->_tag}]";
}
}
class BBDefaultNode extends BBTagNode {
function flatten($noparse = FALSE) {
return $this->getUnparsed($noparse);
}
}
class BBTagRegistry {
var $_parse = array();
var $_revert = array();
var $_default;
function BBTagRegistry($default) {
$this->_default = $default;
}
function getParserClass($tag) {
$class = $this->_default;
$tag = strtolower($tag);
if (isset($this->_parse[$tag]))
$class = $this->_parse[$tag];
return $class;
}
function getReverterClass($tag) {
$ret = $this->_default;
foreach ($this->_revert as $class => $pattern) {
if (preg_match($pattern, $tag)) {
$ret = $class;
}
}
return $ret;
}
function register($class) {
if (class_exists($class)) {
$tags = call_user_func(array($class, 'getTagNames'));
foreach ($tags as $tag)
$this->_parse[$tag] = $class;
$patterns = call_user_func(array($class, 'getRevertPatterns'));
foreach ($patterns as $pattern)
$this->_revert[$pattern] = $class;
}
}
}
class BBParser {
var $_reg;
function BBParser() {
$this->_reg = &new BBTagRegistry('BBDefaultNode');
}
function register($class) {
$this->_reg->register($class);
return TRUE;
}
function &createRegistry() {
$this->register('BBFormatNode');
$this->register('BBCenterNode');
$this->register('BBLeftNode');
$this->register('BBRightNode');
$this->register('BBJustifyNode');
$this->register('BBCodeNode');
$this->register('BBLinkNode');
$this->register('BBListNode');
$this->register('BBListItemNode');
$this->register('BBPhpNode');
$this->register('BBQuoteNode');
$this->register('BBImgNode');
$this->register('BBLinkNode');
return $this->_reg;
}
function revert($buffer) {
$stack = &new BBCodeStack;
$root = &new BBRootNode;
$registry = &$this->createRegistry();
$emos = &BBEmoticons::getInstance();
$buffer = preg_replace('~
\n?~', "\n", $buffer);
$buffer = $emos->revert($buffer);
$buffer = str_replace("©", "(c)", $buffer);
$buffer = str_replace("", "(tm)", $buffer);
$buffer = str_replace("®", "(r)", $buffer);
$buffer = str_replace("—", "--", $buffer);
$buffer = str_replace("–", " - ", $buffer);
$buffer = str_replace("…", "...", $buffer);
$buffer = preg_replace("~([0-9]+)×([0-9]+)~i", "$1x$2", $buffer);
$stack->push($root);
$matches = preg_split('~< ( (?>[^<>]+) | (?R) )* >~x', $buffer, -1, PREG_SPLIT_DELIM_CAPTURE);
foreach ($matches as $i => $match) {
$parent = &$stack->top();
if ((int)$i & 1) {
if (preg_match('~^(/?)([a-z]+)(?: class="bb_([a-z]+)"(.*?)(/?))?$~i', $match, $tag)) {
if ($tag[5] == '/') {
$class = $registry->getParserClass($tag[3]);
$node = &new $class($tag[3], $tag[4]);
$parent->addChild($node);
} elseif ($tag[1] == '/') {
if ($stack->getSize() > 1)
$stack->pop();
} else {
$class = $registry->getParserClass($tag[3]);
$node = &new $class($tag[3], $tag[4]);
$stack->push($node);
$parent->addChild($node);
}
} else {
$class = $registry->getParserClass('');
$node = &new $class('', '');
$stack->push($node);
$parent->addChild($node);
}
} else {
$node = &new BBTextNode($match);
$parent->addChild($node);
}
}
return $root->revert();
}
function parse($buffer) {
$stack = &new BBCodeStack;
$root = &new BBRootNode;
$registry = &$this->createRegistry();
$stack->push($root);
// htmlspecialchars ?
$buffer = htmlentities($buffer, ENT_QUOTES, K4_CHARSET);
$buffer = preg_replace("~\(c\)~i", "©", $buffer);
$buffer = preg_replace("~\(tm\)~i", "", $buffer);
$buffer = preg_replace("~\(r\)~i", "®", $buffer);
$buffer = preg_replace("~--([a-zA-Z\s])?~", "—", $buffer);
$buffer = preg_replace("~\s-\s~", "–", $buffer);
$buffer = preg_replace("~\.\.\.~", "…", $buffer);
$buffer = preg_replace("~([0-9]+)x([0-9]+)~i", "$1×$2", $buffer);
$matches = preg_split('~\[ ( (?>[^\[\]]+) | (?R) )* \]~x', $buffer, -1, PREG_SPLIT_DELIM_CAPTURE);
foreach ($matches as $i => $match) {
$parent = &$stack->top();
if ((int)$i & 1) {
if (preg_match('~^(/?)([a-z]+)(?:=([^\]]*))?$~i', $match, $tag)) {
$class = $registry->getParserClass($tag[2]);
if ($tag[1] == '/') {
if ($tag[2] == $parent->getTag()) {
$stack->pop();
} else {
$node = &new BBTextNode("[$match]");
$parent->addChild($node);
}
} else {
$node = &new $class($tag[2], $tag[3]);
$stack->push($node);
$parent->addChild($node);
}
} else {
$node = &new BBTextNode("[$match]");
$parent->addChild($node);
}
} else {
$node = &new BBTextNode($match);
$parent->addChild($node);
}
}
return $root->flatten();
}
}
/**
*
* TAG COMPILERS
*
*/
class BBCenterNode extends BBTagNode {
function flatten($noparse = FALSE) {
if ($noparse) return $this->getUnparsed($noparse);
$body = parent::flatten($noparse);
$class = $this->getClass();
return "$body
";
}
function getTagNames() {
return array('center');
}
function revert() {
$body = parent::revert();
return "[center]{$body}[/center]";
}
}
class BBLeftNode extends BBTagNode {
function flatten($noparse = FALSE) {
if ($noparse) return $this->getUnparsed($noparse);
$body = parent::flatten($noparse);
$class = $this->getClass();
return "$body
";
}
function getTagNames() {
return array('left');
}
function revert() {
$body = parent::revert();
return "[left]{$body}[/left]";
}
}
class BBRightNode extends BBTagNode {
function flatten($noparse = FALSE) {
if ($noparse) return $this->getUnparsed($noparse);
$body = parent::flatten($noparse);
$class = $this->getClass();
return "$body
";
}
function getTagNames() {
return array('right');
}
function revert() {
$body = parent::revert();
return "[right]{$body}[/right]";
}
}
class BBJustifyNode extends BBTagNode {
function flatten($noparse = FALSE) {
if ($noparse) return $this->getUnparsed($noparse);
$body = parent::flatten($noparse);
$class = $this->getClass();
return "$body
";
}
function getTagNames() {
return array('justify');
}
function revert() {
$body = parent::revert();
return "[justify]{$body}[/justify]";
}
}
class BBCodeNode extends BBTagNode {
function flatten($noparse = FALSE) {
if ($noparse) return $this->getUnparsed($noparse);
return "". parent::flatten(TRUE) ."
";
}
function getTagNames() {
return array('code');
}
function revert() {
$body = parent::revert();
return "[code]{$body}[/code]";
}
}
class BBFormatNode extends BBTagNode {
function getSize() {
$size = $this->_attrib;
if (intval($size) == $size)
return $size;
if (in_array($size, array(1,2,3,4,5))) {
$sizes = array(1=>'12px',2=>'16px',3=>'20px',4=>'24px',5=>'28px',6=>'32px');
return $sizes[$size];
}
}
function getColor() {
$color = $this->_attrib;
if (ctype_alpha($color))
return $color;
if (preg_match('~^#[0-9a-f]{3,6}$~i', $color))
return $color;
}
function getFont() {
$font = $this->_attrib;
if (ctype_alpha($font)) {
$fonts = array('comic'=>'\'Comic Sans MS\'','arial'=>'Arial, Helvetica, sans-serif','times'=>'\'Times New Roman\', Times, serif','verdana'=>'Verdana, Arial, Helvetica, sans-serif');
if(isset($fonts[$font])) {
$font = $fonts[$font];
}
return $font;
}
}
function flatten($noparse = FALSE) {
if ($noparse) return $this->getUnparsed($noparse);
$body = parent::flatten($noparse);
$styles = array(
'b' => 'font-weight: bold;',
'i' => 'font-style: italic;',
'u' => 'text-decoration: underline;',
'color' => 'color: '.$this->getColor().';',
'size' => 'font-size: '.$this->getSize().';',
'font' => 'font-family: '.$this->getFont().';',
'indent' => 'margin-left: 40px;',
'outdent' => 'margin-left: 0px;',
);
$tag = $this->getTag();
$style = $styles[$tag];
$class = $this->getClass();
return "$body";
}
function getTagNames() {
return array('b', 'color', 'i', 'size', 'u', 'font', 'indent', 'outdent');
}
function revert() {
switch ($this->getTag()) {
case 'b': {
return "[b]".parent::revert()."[/b]";
}
case 'i': {
return "[i]".parent::revert()."[/i]";
}
case 'u': {
return "[u]".parent::revert()."[/u]";
}
case 'size': {
$size = preg_replace('~^.*font-size: (\S+);.*$~', '$1', $this->_attrib);
return "[size=$size]".parent::revert()."[/size]";
}
case 'color': {
$color = preg_replace('~^.*color: (\S+);.*$~', '$1', $this->_attrib);
return "[color=$color]".parent::revert()."[/color]";
}
case 'font': {
$font = preg_replace('~^.*font-family: (\S+);.*$~', '$1', $this->_attrib);
return "[font=$font]".parent::revert()."[/font]";
}
case 'indent': {
return "[indent]".parent::revert()."[/indent]";
}
case 'outdent': {
return "[outdent]".parent::revert()."[/outdent]";
}
}
}
}
class BBLinkNode extends BBTagNode {
function flatten($noparse = FALSE) {
if ($noparse) return $this->getUnparsed($noparse);
$body = parent::flatten(TRUE);
$url = ($this->_attrib) ? $this->_attrib : $this->_body;
return "$body";
}
function getTagNames() {
return array('link', 'url');
}
function revert() {
$body = parent::revert();
$tag = $this->getTag();
$url = preg_replace('~^.*href="([^"]*)".*$~', '$1', $this->_attrib);
return "[$tag=$url]{$body}[/$tag]";
}
}
class BBImgNode extends BBTagNode {
function flatten($noparse = FALSE) {
if ($noparse) return $this->getUnparsed($noparse);
$url = parent::flatten(TRUE);
//$url = ($this->_attrib) ? $this->_attrib : $this->_body;
$class = $this->getClass();
return "
";
}
function getTagNames() {
return array('img');
}
function revert() {
$body = parent::revert();
$src = preg_replace('~^.*src="([^"]*)".*$~', '$1', $this->_attrib);
return "[img]".$src."[/img]";
}
}
class BBListNode extends BBTagNode {
function flatten($noparse = FALSE) {
if ($noparse) return $this->getUnparsed($noparse);
$body = parent::flatten($noparse);
$class = $this->getClass();
$items = explode('[*]', $body);
$param = $this->_attrib;
if (ctype_digit($param)) {
$list = 'ol';
$attribs = " type=\"1\" start=\"$param\"";
} elseif ($param == 'a' || $param == 'A' || $param == 'i' || $param == 'I') {
$list = 'ol';
$attribs = " type=\"$param\"";
} else {
$list = 'ul';
$attribs = '';
}
$buffer = '';
foreach ($items as $item) {
if (trim($item))
$buffer .= "$item";
}
return "<$list class=\"bbcode_list\" $attribs>\n$buffer$list>";
}
function getTagNames() {
return array('list');
}
function revert() {
$body = parent::revert();
$type = preg_replace('~^.*type(=)"([^"]*)".*$~', '$1$2', $this->_attrib);
return "[list$type]{$body}[/list]";
}
}
class BBListItemNode extends BBTagNode {
function getTagNames() {
return array('li');
}
function revert() {
$body = parent::revert();
return "[*]{$body}";
}
}
class BBPhpNode extends BBTagNode {
function flatten($noparse = FALSE) {
if ($noparse) return $this->getUnparsed($noparse);
$body = parent::flatten(TRUE);
$geshi = &new GeSHi($body, 'PHP');
return "". $geshi->parse_code() ."
";
}
function getTagNames() {
return array('php');
}
function revert() {
$body = parent::revert();
return "[php]{$body}[/php]";
}
}
class BBQuoteNode extends BBTagNode {
function flatten($noparse = FALSE) {
if ($noparse) return $this->getUnparsed($noparse);
return "". parent::flatten() ."
";
}
function getTagNames() {
return array('quote');
}
}
?>