| Server IP : 213.186.33.4 / Your IP : 216.73.216.193 Web Server : Apache System : Linux webm006.cluster103.gra.hosting.ovh.net 5.15.206-ovh-vps-grsec-zfs-classid #1 SMP Fri May 15 02:41:25 UTC 2026 x86_64 User : awebpaca ( 35430) PHP Version : 8.5.0 Disable Function : _dyuweyrj4,_dyuweyrj4r,dl MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : OFF | Pkexec : OFF Directory : /home/awebpaca/blog/libraries/kunena/external/nbbc/ |
Upload File : |
<?php
/*
This is a compressed copy of NBBC. Do not edit!
Copyright (c) 2008-9, the Phantom Inker. All rights reserved.
Portions Copyright (c) 2004-2008 AddedBytes.com
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE PHANTOM INKER "AS IS" AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
define("BBCODE_VERSION", "1.4.5");
define("BBCODE_RELEASE", "2010-09-17");
define("BBCODE_VERBATIM", 2);
define("BBCODE_REQUIRED", 1);
define("BBCODE_OPTIONAL", 0);
define("BBCODE_PROHIBIT", -1);
define("BBCODE_CHECK", 1);
define("BBCODE_OUTPUT", 2);
define("BBCODE_ENDTAG", 5);
define("BBCODE_TAG", 4);
define("BBCODE_TEXT", 3);
define("BBCODE_NL", 2);
define("BBCODE_WS", 1);
define("BBCODE_EOI", 0);
define("BBCODE_LEXSTATE_TEXT", 0);
define("BBCODE_LEXSTATE_TAG", 1);
define("BBCODE_MODE_SIMPLE", 0);
define("BBCODE_MODE_CALLBACK", 1);
define("BBCODE_MODE_INTERNAL", 2);
define("BBCODE_MODE_LIBRARY", 3);
define("BBCODE_MODE_ENHANCED", 4);
define("BBCODE_STACK_TOKEN", 0);
define("BBCODE_STACK_TEXT", 1);
define("BBCODE_STACK_TAG", 2);
define("BBCODE_STACK_CLASS", 3);
if (!function_exists('str_split'))
{
function str_split($string, $split_length = 1)
{
$array = explode("\r\n", chunk_split($string, $split_length));
array_pop($array);
return $array;
}
}
$BBCode_SourceDir = dirname(__FILE__);
class BBCodeLexer
{
var $token;
var $text;
var $tag;
var $state;
var $input;
var $ptr;
var $unget;
var $verbatim;
var $debug;
var $tagmarker;
var $end_tagmarker;
var $pat_main;
var $pat_comment;
var $pat_comment2;
var $pat_wiki;
function __construct($string, $tagmarker = '[')
{
$regex_beginmarkers = Array('[' => '\[', '<' => '<', '{' => '\{', '(' => '\(');
$regex_endmarkers = Array('[' => '\]', '<' => '>', '{' => '\}', '(' => '\)');
$endmarkers = Array('[' => ']', '<' => '>', '{' => '}', '(' => ')');
if (!isset($regex_endmarkers[$tagmarker]))
{
$tagmarker = '[';
}
$e = $regex_endmarkers[$tagmarker];
$b = $regex_beginmarkers[$tagmarker];
$this->tagmarker = $tagmarker;
$this->end_tagmarker = $endmarkers[$tagmarker];
$this->pat_main = "/( "
. "{$b}"
. "(?! -- | ' | !-- | {$b}{$b} )"
. "(?: [^\\n\\r{$b}{$e}] | \\\" [^\\\"\\n\\r]* \\\" | \\' [^\\'\\n\\r]* \\' )*"
. "{$e}"
. "| {$b}{$b} (?: [^{$e}\\r\\n] | {$e}[^{$e}\\r\\n] )* {$e}{$e}"
. "| {$b} (?: -- | ' ) (?: [^{$e}\\n\\r]* ) {$e}"
. "| {$b}!-- (?: [^-] | -[^-] | --[^{$e}] )* --{$e}"
. "| -----+"
. "| \\x0D\\x0A | \\x0A\\x0D | \\x0D | \\x0A"
. "| [\\x00-\\x09\\x0B-\\x0C\\x0E-\\x20]+(?=[\\x0D\\x0A{$b}]|-----|$)"
. "| (?<=[\\x0D\\x0A{$e}]|-----|^)[\\x00-\\x09\\x0B-\\x0C\\x0E-\\x20]+"
. " )/Dx";
$this->input = preg_split($this->pat_main, $string, -1, PREG_SPLIT_DELIM_CAPTURE);
$this->pat_comment = "/^ {$b} (?: -- | ' ) /Dx";
$this->pat_comment2 = "/^ {$b}!-- (?: [^-] | -[^-] | --[^{$e}] )* --{$e} $/Dx";
$this->pat_wiki = "/^ {$b}{$b} ([^\\|]*) (?:\\|(.*))? {$e}{$e} $/Dx";
$this->ptr = 0;
$this->unget = false;
$this->state = BBCODE_LEXSTATE_TEXT;
$this->verbatim = false;
$this->token = BBCODE_EOI;
$this->tag = false;
$this->text = "";
}
function GuessTextLength()
{
$length = 0;
$ptr = 0;
$state = BBCODE_LEXSTATE_TEXT;
while ($ptr < count($this->input))
{
$text = $this->input[$ptr++];
if ($state == BBCODE_LEXSTATE_TEXT)
{
$state = BBCODE_LEXSTATE_TAG;
$length += strlen($text);
}
else
{
switch (ord(substr($this->text, 0, 1)))
{
case 10:
case 13:
$state = BBCODE_LEXSTATE_TEXT;
$length++;
break;
default:
$state = BBCODE_LEXSTATE_TEXT;
$length += strlen($text);
break;
case 40:
case 60:
case 91:
case 123:
$state = BBCODE_LEXSTATE_TEXT;
break;
}
}
}
return $length;
}
function NextToken()
{
if ($this->unget)
{
$this->unget = false;
return $this->token;
}
while (true)
{
if ($this->ptr >= count($this->input))
{
$this->text = "";
$this->tag = false;
return $this->token = BBCODE_EOI;
}
$this->text = preg_replace("/[\\x00-\\x08\\x0B-\\x0C\\x0E-\\x1F]/", "",
$this->input[$this->ptr++]);
if ($this->verbatim)
{
$this->tag = false;
if ($this->state == BBCODE_LEXSTATE_TEXT)
{
$this->state = BBCODE_LEXSTATE_TAG;
$token_type = BBCODE_TEXT;
}
else
{
$this->state = BBCODE_LEXSTATE_TEXT;
switch (ord(substr($this->text, 0, 1)))
{
case 10:
case 13:
$token_type = BBCODE_NL;
break;
default:
$token_type = BBCODE_WS;
break;
case 45:
case 40:
case 60:
case 91:
case 123:
$token_type = BBCODE_TEXT;
break;
}
}
if (strlen($this->text) > 0)
{
return $this->token = $token_type;
}
}
else
{
if ($this->state == BBCODE_LEXSTATE_TEXT)
{
$this->state = BBCODE_LEXSTATE_TAG;
$this->tag = false;
if (strlen($this->text) > 0)
{
return $this->token = BBCODE_TEXT;
}
}
else
{
switch (ord(substr($this->text, 0, 1)))
{
case 10:
case 13:
$this->tag = false;
$this->state = BBCODE_LEXSTATE_TEXT;
return $this->token = BBCODE_NL;
case 45:
if (preg_match("/^-----/", $this->text))
{
$this->tag = Array('_name' => 'rule', '_endtag' => false, '_default' => '');
$this->state = BBCODE_LEXSTATE_TEXT;
return $this->token = BBCODE_TAG;
}
else
{
$this->tag = false;
$this->state = BBCODE_LEXSTATE_TEXT;
if (strlen($this->text) > 0)
{
return $this->token = BBCODE_TEXT;
}
continue;
}
default:
$this->tag = false;
$this->state = BBCODE_LEXSTATE_TEXT;
return $this->token = BBCODE_WS;
case 40:
case 60:
case 91:
case 123:
if (preg_match($this->pat_comment, $this->text))
{
$this->state = BBCODE_LEXSTATE_TEXT;
continue;
}
if (preg_match($this->pat_comment2, $this->text))
{
$this->state = BBCODE_LEXSTATE_TEXT;
continue;
}
if (preg_match($this->pat_wiki, $this->text, $matches))
{
$this->tag = Array('_name' => 'wiki', '_endtag' => false,
'_default' => @$matches[1], 'title' => @$matches[2]);
$this->state = BBCODE_LEXSTATE_TEXT;
return $this->token = BBCODE_TAG;
}
$this->tag = $this->Internal_DecodeTag($this->text);
$this->state = BBCODE_LEXSTATE_TEXT;
return $this->token = ($this->tag['_end'] ? BBCODE_ENDTAG : BBCODE_TAG);
}
}
}
}
}
function UngetToken()
{
if ($this->token !== BBCODE_EOI)
{
$this->unget = true;
}
}
function PeekToken()
{
$result = $this->NextToken();
if ($this->token !== BBCODE_EOI)
{
$this->unget = true;
}
return $result;
}
function SaveState()
{
return Array(
'token' => $this->token,
'text' => $this->text,
'tag' => $this->tag,
'state' => $this->state,
'input' => $this->input,
'ptr' => $this->ptr,
'unget' => $this->unget,
'verbatim' => $this->verbatim
);
}
function RestoreState($state)
{
if (!is_array($state))
{
return;
}
$this->token = @$state['token'];
$this->text = @$state['text'];
$this->tag = @$state['tag'];
$this->state = @$state['state'];
$this->input = @$state['input'];
$this->ptr = @$state['ptr'];
$this->unget = @$state['unget'];
$this->verbatim = @$state['verbatim'];
}
function Internal_StripQuotes($string)
{
if (preg_match("/^\\\"(.*)\\\"$/", $string, $matches))
{
return $matches[1];
}
else
{
if (preg_match("/^\\'(.*)\\'$/", $string, $matches))
{
return $matches[1];
}
else
{
return $string;
}
}
}
function Internal_ClassifyPiece($ptr, $pieces)
{
if ($ptr >= count($pieces))
{
return -1;
}
$piece = $pieces[$ptr];
if ($piece == '=')
{
return '=';
}
else
{
if (preg_match("/^[\\'\\\"]/", $piece))
{
return '"';
}
else
{
if (preg_match("/^[\\x00-\\x20]+$/", $piece))
{
return ' ';
}
else
{
return 'A';
}
}
}
}
function Internal_DecodeTag($tag)
{
$result = Array('_tag' => $tag, '_endtag' => '', '_name' => '',
'_hasend' => false, '_end' => false, '_default' => false);
$tag = substr($tag, 1, strlen($tag) - 2);
$ch = ord(substr($tag, 0, 1));
if ($ch >= 0 && $ch <= 32)
{
return $result;
}
$pieces = preg_split("/(\\\"[^\\\"]+\\\"|\\'[^\\']+\\'|=|[\\x00-\\x20]+)/",
$tag, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
$ptr = 0;
if (count($pieces) < 1)
{
return $result;
}
if (@substr($pieces[$ptr], 0, 1) == '/')
{
$result['_name'] = strtolower(substr($pieces[$ptr++], 1));
$result['_end'] = true;
}
else
{
$result['_name'] = strtolower($pieces[$ptr++]);
$result['_end'] = false;
}
while (($type = $this->Internal_ClassifyPiece($ptr, $pieces)) == ' ')
$ptr++;
$params = Array();
if ($type != '=')
{
$result['_default'] = false;
$params[] = Array('key' => '', 'value' => '');
}
else
{
$ptr++;
while (($type = $this->Internal_ClassifyPiece($ptr, $pieces)) == ' ')
$ptr++;
if ($type == "\"")
{
$value = $this->Internal_StripQuotes($pieces[$ptr++]);
}
else
{
$after_space = false;
$start = $ptr;
while (($type = $this->Internal_ClassifyPiece($ptr, $pieces)) != -1)
{
if ($type == ' ')
{
$after_space = true;
}
if ($type == '=' && $after_space)
{
break;
}
$ptr++;
}
if ($type == -1)
{
$ptr--;
}
if ($type == '=')
{
$ptr--;
while ($ptr > $start && $this->Internal_ClassifyPiece($ptr, $pieces) == ' ')
$ptr--;
while ($ptr > $start && $this->Internal_ClassifyPiece($ptr, $pieces) != ' ')
$ptr--;
}
$value = "";
for (; $start <= $ptr; $start++)
{
if ($this->Internal_ClassifyPiece($start, $pieces) == ' ')
{
$value .= " ";
}
else
{
$value .= $this->Internal_StripQuotes($pieces[$start]);
}
}
$value = trim($value);
$ptr++;
}
$result['_default'] = $value;
$params[] = Array('key' => '', 'value' => $value);
}
while (($type = $this->Internal_ClassifyPiece($ptr, $pieces)) != -1)
{
while ($type == ' ')
{
$ptr++;
$type = $this->Internal_ClassifyPiece($ptr, $pieces);
}
if ($type == 'A' || $type == '"')
{
$key = strtolower($this->Internal_StripQuotes(@$pieces[$ptr++]));
}
else
{
if ($type == '=')
{
$ptr++;
continue;
}
else
{
if ($type == -1)
{
break;
}
}
}
while (($type = $this->Internal_ClassifyPiece($ptr, $pieces)) == ' ')
$ptr++;
if ($type != '=')
{
$value = $this->Internal_StripQuotes($key);
}
else
{
$ptr++;
while (($type = $this->Internal_ClassifyPiece($ptr, $pieces)) == ' ')
$ptr++;
if ($type == '"')
{
$value = $this->Internal_StripQuotes($pieces[$ptr++]);
}
else
{
if ($type != -1)
{
$value = $pieces[$ptr++];
while (($type = $this->Internal_ClassifyPiece($ptr, $pieces)) != -1
&& $type != ' ')
$value .= $pieces[$ptr++];
}
else
{
$value = "";
}
}
}
if (substr($key, 0, 1) != '_')
{
$result[$key] = $value;
}
$params[] = Array('key' => $key, 'value' => $value);
}
$result['_params'] = $params;
return $result;
}
}
class BBCodeLibrary
{
var $default_smileys = Array(
':)' => 'smile.gif', ':-)' => 'smile.gif',
'=)' => 'smile.gif', '=-)' => 'smile.gif',
':(' => 'frown.gif', ':-(' => 'frown.gif',
'=(' => 'frown.gif', '=-(' => 'frown.gif',
':D' => 'bigsmile.gif', ':-D' => 'bigsmile.gif',
'=D' => 'bigsmile.gif', '=-D' => 'bigsmile.gif',
'>:(' => 'angry.gif', '>:-(' => 'angry.gif',
'>=(' => 'angry.gif', '>=-(' => 'angry.gif',
'D:' => 'angry.gif', 'D-:' => 'angry.gif',
'D=' => 'angry.gif', 'D-=' => 'angry.gif',
'>:)' => 'evil.gif', '>:-)' => 'evil.gif',
'>=)' => 'evil.gif', '>=-)' => 'evil.gif',
'>:D' => 'evil.gif', '>:-D' => 'evil.gif',
'>=D' => 'evil.gif', '>=-D' => 'evil.gif',
'>;)' => 'sneaky.gif', '>;-)' => 'sneaky.gif',
'>;D' => 'sneaky.gif', '>;-D' => 'sneaky.gif',
'O:)' => 'saint.gif', 'O:-)' => 'saint.gif',
'O=)' => 'saint.gif', 'O=-)' => 'saint.gif',
':O' => 'surprise.gif', ':-O' => 'surprise.gif',
'=O' => 'surprise.gif', '=-O' => 'surprise.gif',
':?' => 'confuse.gif', ':-?' => 'confuse.gif',
'=?' => 'confuse.gif', '=-?' => 'confuse.gif',
':s' => 'worry.gif', ':-S' => 'worry.gif',
'=s' => 'worry.gif', '=-S' => 'worry.gif',
':|' => 'neutral.gif', ':-|' => 'neutral.gif',
'=|' => 'neutral.gif', '=-|' => 'neutral.gif',
':I' => 'neutral.gif', ':-I' => 'neutral.gif',
'=I' => 'neutral.gif', '=-I' => 'neutral.gif',
':/' => 'irritated.gif', ':-/' => 'irritated.gif',
'=/' => 'irritated.gif', '=-/' => 'irritated.gif',
':\\' => 'irritated.gif', ':-\\' => 'irritated.gif',
'=\\' => 'irritated.gif', '=-\\' => 'irritated.gif',
':P' => 'tongue.gif', ':-P' => 'tongue.gif',
'=P' => 'tongue.gif', '=-P' => 'tongue.gif',
'X-P' => 'tongue.gif',
'8)' => 'bigeyes.gif', '8-)' => 'bigeyes.gif',
'B)' => 'cool.gif', 'B-)' => 'cool.gif',
';)' => 'wink.gif', ';-)' => 'wink.gif',
';D' => 'bigwink.gif', ';-D' => 'bigwink.gif',
'^_^' => 'anime.gif', '^^;' => 'sweatdrop.gif',
'>_>' => 'lookright.gif', '>.>' => 'lookright.gif',
'<_<' => 'lookleft.gif', '<.<' => 'lookleft.gif',
'XD' => 'laugh.gif', 'X-D' => 'laugh.gif',
':3' => 'smile3.gif', ':-3' => 'smile3.gif',
'=3' => 'smile3.gif', '=-3' => 'smile3.gif',
';3' => 'wink3.gif', ';-3' => 'wink3.gif',
'<g>' => 'teeth.gif', '<G>' => 'teeth.gif',
'o.O' => 'boggle.gif', 'O.o' => 'boggle.gif',
':blue:' => 'blue.gif',
':zzz:' => 'sleepy.gif',
'<3' => 'heart.gif',
':star:' => 'star.gif',
);
var $default_tag_rules = Array(
'b' => Array(
'simple_start' => "<b>",
'simple_end' => "</b>",
'class' => 'inline',
'allow_in' => Array('listitem', 'block', 'columns', 'inline', 'link'),
'plain_start' => "<b>",
'plain_end' => "</b>",
),
'i' => Array(
'simple_start' => "<i>",
'simple_end' => "</i>",
'class' => 'inline',
'allow_in' => Array('listitem', 'block', 'columns', 'inline', 'link'),
'plain_start' => "<i>",
'plain_end' => "</i>",
),
'u' => Array(
'simple_start' => "<u>",
'simple_end' => "</u>",
'class' => 'inline',
'allow_in' => Array('listitem', 'block', 'columns', 'inline', 'link'),
'plain_start' => "<u>",
'plain_end' => "</u>",
),
's' => Array(
'simple_start' => "<strike>",
'simple_end' => "</strike>",
'class' => 'inline',
'allow_in' => Array('listitem', 'block', 'columns', 'inline', 'link'),
'plain_start' => "<i>",
'plain_end' => "</i>",
),
'font' => Array(
'mode' => BBCODE_MODE_LIBRARY,
'allow' => Array('_default' => '/^[a-zA-Z0-9._ -]+$/'),
'method' => 'DoFont',
'class' => 'inline',
'allow_in' => Array('listitem', 'block', 'columns', 'inline', 'link'),
),
'color' => Array(
'mode' => BBCODE_MODE_ENHANCED,
'allow' => Array('_default' => '/^#?[a-zA-Z0-9._ -]+$/'),
'template' => '<span style="color:{$_default/tw}">{$_content/v}</span>',
'class' => 'inline',
'allow_in' => Array('listitem', 'block', 'columns', 'inline', 'link'),
),
'size' => Array(
'mode' => BBCODE_MODE_LIBRARY,
'allow' => Array('_default' => '/^[0-9.]+$/D'),
'method' => 'DoSize',
'class' => 'inline',
'allow_in' => Array('listitem', 'block', 'columns', 'inline', 'link'),
),
'sup' => Array(
'simple_start' => "<sup>",
'simple_end' => "</sup>",
'class' => 'inline',
'allow_in' => Array('listitem', 'block', 'columns', 'inline', 'link'),
),
'sub' => Array(
'simple_start' => "<sub>",
'simple_end' => "</sub>",
'class' => 'inline',
'allow_in' => Array('listitem', 'block', 'columns', 'inline', 'link'),
),
'spoiler' => Array(
'simple_start' => "<span class=\"bbcode_spoiler\">",
'simple_end' => "</span>",
'class' => 'inline',
'allow_in' => Array('listitem', 'block', 'columns', 'inline', 'link'),
),
'acronym' => Array(
'mode' => BBCODE_MODE_ENHANCED,
'template' => '<span class="bbcode_acronym" title="{$_default/e}">{$_content/v}</span>',
'class' => 'inline',
'allow_in' => Array('listitem', 'block', 'columns', 'inline', 'link'),
),
'url' => Array(
'mode' => BBCODE_MODE_LIBRARY,
'method' => 'DoURL',
'class' => 'link',
'allow_in' => Array('listitem', 'block', 'columns', 'inline'),
'content' => BBCODE_REQUIRED,
'plain_start' => "<a href=\"{\$link}\">",
'plain_end' => "</a>",
'plain_content' => Array('_content', '_default'),
'plain_link' => Array('_default', '_content'),
),
'email' => Array(
'mode' => BBCODE_MODE_LIBRARY,
'method' => 'DoEmail',
'class' => 'link',
'allow_in' => Array('listitem', 'block', 'columns', 'inline'),
'content' => BBCODE_REQUIRED,
'plain_start' => "<a href=\"mailto:{\$link}\">",
'plain_end' => "</a>",
'plain_content' => Array('_content', '_default'),
'plain_link' => Array('_default', '_content'),
),
'wiki' => Array(
'mode' => BBCODE_MODE_LIBRARY,
'method' => "DoWiki",
'class' => 'link',
'allow_in' => Array('listitem', 'block', 'columns', 'inline'),
'end_tag' => BBCODE_PROHIBIT,
'content' => BBCODE_PROHIBIT,
'plain_start' => "<b>[",
'plain_end' => "]</b>",
'plain_content' => Array('title', '_default'),
'plain_link' => Array('_default', '_content'),
),
'img' => Array(
'mode' => BBCODE_MODE_LIBRARY,
'method' => "DoImage",
'class' => 'image',
'allow_in' => Array('listitem', 'block', 'columns', 'inline', 'link'),
'end_tag' => BBCODE_REQUIRED,
'content' => BBCODE_REQUIRED,
'plain_start' => "[image]",
'plain_content' => Array(),
),
'rule' => Array(
'mode' => BBCODE_MODE_LIBRARY,
'method' => "DoRule",
'class' => 'block',
'allow_in' => Array('listitem', 'block', 'columns'),
'end_tag' => BBCODE_PROHIBIT,
'content' => BBCODE_PROHIBIT,
'before_tag' => "sns",
'after_tag' => "sns",
'plain_start' => "\n-----\n",
'plain_end' => "",
'plain_content' => Array(),
),
'br' => Array(
'mode' => BBCODE_MODE_SIMPLE,
'simple_start' => "<br />\n",
'simple_end' => "",
'class' => 'inline',
'allow_in' => Array('listitem', 'block', 'columns', 'inline', 'link'),
'end_tag' => BBCODE_PROHIBIT,
'content' => BBCODE_PROHIBIT,
'before_tag' => "s",
'after_tag' => "s",
'plain_start' => "\n",
'plain_end' => "",
'plain_content' => Array(),
),
'left' => Array(
'simple_start' => "\n<div class=\"bbcode_left\" style=\"text-align:left\">\n",
'simple_end' => "\n</div>\n",
'allow_in' => Array('listitem', 'block', 'columns'),
'before_tag' => "sns",
'after_tag' => "sns",
'before_endtag' => "sns",
'after_endtag' => "sns",
'plain_start' => "\n",
'plain_end' => "\n",
),
'right' => Array(
'simple_start' => "\n<div class=\"bbcode_right\" style=\"text-align:right\">\n",
'simple_end' => "\n</div>\n",
'allow_in' => Array('listitem', 'block', 'columns'),
'before_tag' => "sns",
'after_tag' => "sns",
'before_endtag' => "sns",
'after_endtag' => "sns",
'plain_start' => "\n",
'plain_end' => "\n",
),
'center' => Array(
'simple_start' => "\n<div class=\"bbcode_center\" style=\"text-align:center\">\n",
'simple_end' => "\n</div>\n",
'allow_in' => Array('listitem', 'block', 'columns'),
'before_tag' => "sns",
'after_tag' => "sns",
'before_endtag' => "sns",
'after_endtag' => "sns",
'plain_start' => "\n",
'plain_end' => "\n",
),
'indent' => Array(
'simple_start' => "\n<div class=\"bbcode_indent\" style=\"margin-left:4em\">\n",
'simple_end' => "\n</div>\n",
'allow_in' => Array('listitem', 'block', 'columns'),
'before_tag' => "sns",
'after_tag' => "sns",
'before_endtag' => "sns",
'after_endtag' => "sns",
'plain_start' => "\n",
'plain_end' => "\n",
),
'columns' => Array(
'simple_start' => "\n<table class=\"bbcode_columns\"><tbody><tr><td class=\"bbcode_column bbcode_firstcolumn\">\n",
'simple_end' => "\n</td></tr></tbody></table>\n",
'class' => 'columns',
'allow_in' => Array('listitem', 'block', 'columns'),
'end_tag' => BBCODE_REQUIRED,
'content' => BBCODE_REQUIRED,
'before_tag' => "sns",
'after_tag' => "sns",
'before_endtag' => "sns",
'after_endtag' => "sns",
'plain_start' => "\n",
'plain_end' => "\n",
),
'nextcol' => Array(
'simple_start' => "\n</td><td class=\"bbcode_column\">\n",
'class' => 'nextcol',
'allow_in' => Array('columns'),
'end_tag' => BBCODE_PROHIBIT,
'content' => BBCODE_PROHIBIT,
'before_tag' => "sns",
'after_tag' => "sns",
'before_endtag' => "sns",
'after_endtag' => "sns",
'plain_start' => "\n",
'plain_end' => "",
),
'code' => Array(
'mode' => BBCODE_MODE_ENHANCED,
'template' => "\n<div class=\"bbcode_code\">\n<div class=\"bbcode_code_head\">Code:</div>\n<div class=\"bbcode_code_body\" style=\"white-space:pre\">{\$_content/v}</div>\n</div>\n",
'class' => 'code',
'allow_in' => Array('listitem', 'block', 'columns'),
'content' => BBCODE_VERBATIM,
'before_tag' => "sns",
'after_tag' => "sn",
'before_endtag' => "sn",
'after_endtag' => "sns",
'plain_start' => "\n<b>Code:</b>\n",
'plain_end' => "\n",
),
'quote' => Array(
'mode' => BBCODE_MODE_LIBRARY,
'method' => "DoQuote",
'allow_in' => Array('listitem', 'block', 'columns'),
'before_tag' => "sns",
'after_tag' => "sns",
'before_endtag' => "sns",
'after_endtag' => "sns",
'plain_start' => "\n<b>Quote:</b>\n",
'plain_end' => "\n",
),
'list' => Array(
'mode' => BBCODE_MODE_LIBRARY,
'method' => 'DoList',
'class' => 'list',
'allow_in' => Array('listitem', 'block', 'columns'),
'before_tag' => "sns",
'after_tag' => "sns",
'before_endtag' => "sns",
'after_endtag' => "sns",
'plain_start' => "\n",
'plain_end' => "\n",
),
'*' => Array(
'simple_start' => "<li>",
'simple_end' => "</li>\n",
'class' => 'listitem',
'allow_in' => Array('list'),
'end_tag' => BBCODE_OPTIONAL,
'before_tag' => "s",
'after_tag' => "s",
'before_endtag' => "sns",
'after_endtag' => "sns",
'plain_start' => "\n * ",
'plain_end' => "\n",
),
);
function DoURL($bbcode, $action, $name, $default, $params, $content)
{
if ($action == BBCODE_CHECK)
{
return true;
}
$url = is_string($default) ? $default : $bbcode->UnHTMLEncode(strip_tags($content));
if ($bbcode->IsValidURL($url))
{
if ($bbcode->debug)
{
print "ISVALIDURL<br />";
}
if ($bbcode->url_targetable !== false && isset($params['target']))
{
$target = " target=\"" . htmlspecialchars($params['target']) . "\"";
}
else
{
$target = "";
}
if ($bbcode->url_target !== false)
{
if (!($bbcode->url_targetable == 'override' && isset($params['target'])))
{
$target = " target=\"" . htmlspecialchars($bbcode->url_target) . "\"";
}
}
return '<a href="' . htmlspecialchars($url) . '" class="bbcode_url"' . $target . '>' . $content . '</a>';
}
else
{
return htmlspecialchars($params['_tag']) . $content . htmlspecialchars($params['_endtag']);
}
}
function DoEmail($bbcode, $action, $name, $default, $params, $content)
{
if ($action == BBCODE_CHECK)
{
return true;
}
$email = is_string($default) ? $default : $bbcode->UnHTMLEncode(strip_tags($content));
if ($bbcode->IsValidEmail($email))
{
return '<a href="mailto:' . htmlspecialchars($email) . '" class="bbcode_email">' . $content . '</a>';
}
else
{
return htmlspecialchars($params['_tag']) . $content . htmlspecialchars($params['_endtag']);
}
}
function DoSize($bbcode, $action, $name, $default, $params, $content)
{
switch ($default)
{
case '0':
$size = '.5em';
break;
case '1':
$size = '.67em';
break;
case '2':
$size = '.83em';
break;
default:
case '3':
$size = '1.0em';
break;
case '4':
$size = '1.17em';
break;
case '5':
$size = '1.5em';
break;
case '6':
$size = '2.0em';
break;
case '7':
$size = '2.5em';
break;
}
return "<span style=\"font-size:$size\">$content</span>";
}
function DoFont($bbcode, $action, $name, $default, $params, $content)
{
$fonts = explode(",", $default);
$result = "";
$special_fonts = Array(
'serif' => 'serif',
'sans-serif' => 'sans-serif',
'sans serif' => 'sans-serif',
'sansserif' => 'sans-serif',
'sans' => 'sans-serif',
'cursive' => 'cursive',
'fantasy' => 'fantasy',
'monospace' => 'monospace',
'mono' => 'monospace',
);
foreach ($fonts as $font)
{
$font = trim($font);
if (isset($special_fonts[$font]))
{
if (strlen($result) > 0)
{
$result .= ",";
}
$result .= $special_fonts[$font];
}
else
{
if (strlen($font) > 0)
{
if (strlen($result) > 0)
{
$result .= ",";
}
$result .= "'$font'";
}
}
}
return "<span style=\"font-family:$result\">$content</span>";
}
function DoWiki($bbcode, $action, $name, $default, $params, $content)
{
$name = $bbcode->Wikify($default);
if ($action == BBCODE_CHECK)
{
return strlen($name) > 0;
}
$title = trim(@$params['title']);
if (strlen($title) <= 0)
{
$title = trim($default);
}
return "<a href=\"{$bbcode->wiki_url}$name\" class=\"bbcode_wiki\">"
. htmlspecialchars($title) . "</a>";
}
function DoImage($bbcode, $action, $name, $default, $params, $content)
{
if ($action == BBCODE_CHECK)
{
return true;
}
$content = trim($bbcode->UnHTMLEncode(strip_tags($content)));
if (preg_match("/\\.(?:gif|jpeg|jpg|jpe|png)$/", $content))
{
if (preg_match("/^[a-zA-Z0-9_][^:]+$/", $content))
{
if (!preg_match("/(?:\\/\\.\\.\\/)|(?:^\\.\\.\\/)|(?:^\\/)/", $content))
{
$info = @getimagesize("{$bbcode->local_img_dir}/{$content}");
if ($info[2] == IMAGETYPE_GIF || $info[2] == IMAGETYPE_JPEG || $info[2] == IMAGETYPE_PNG)
{
return "<img src=\""
. htmlspecialchars("{$bbcode->local_img_url}/{$content}") . "\" alt=\""
. htmlspecialchars(basename($content)) . "\" width=\""
. htmlspecialchars($info[0]) . "\" height=\""
. htmlspecialchars($info[1]) . "\" class=\"bbcode_img\" />";
}
}
}
else
{
if ($bbcode->IsValidURL($content, false))
{
return "<img src=\"" . htmlspecialchars($content) . "\" alt=\""
. htmlspecialchars(basename($content)) . "\" class=\"bbcode_img\" />";
}
}
}
return htmlspecialchars($params['_tag']) . htmlspecialchars($content) . htmlspecialchars($params['_endtag']);
}
function DoRule($bbcode, $action, $name, $default, $params, $content)
{
if ($action == BBCODE_CHECK)
{
return true;
}
else
{
return $bbcode->rule_html;
}
}
function DoQuote($bbcode, $action, $name, $default, $params, $content)
{
if ($action == BBCODE_CHECK)
{
return true;
}
if (isset($params['name']))
{
$title = htmlspecialchars(trim($params['name'])) . " wrote";
if (isset($params['date']))
{
$title .= " on " . htmlspecialchars(trim($params['date']));
}
$title .= ":";
if (isset($params['url']))
{
$url = trim($params['url']);
if ($bbcode->IsValidURL($url))
{
$title = "<a href=\"" . htmlspecialchars($params['url']) . "\">" . $title . "</a>";
}
}
}
else
{
if (!is_string($default))
{
$title = "Quote:";
}
else
{
$title = htmlspecialchars(trim($default)) . " wrote:";
}
}
return "\n<div class=\"bbcode_quote\">\n<div class=\"bbcode_quote_head\">"
. $title . "</div>\n<div class=\"bbcode_quote_body\">"
. $content . "</div>\n</div>\n";
}
function DoList($bbcode, $action, $name, $default, $params, $content)
{
$list_styles = Array(
'1' => 'decimal',
'01' => 'decimal-leading-zero',
'i' => 'lower-roman',
'I' => 'upper-roman',
'a' => 'lower-alpha',
'A' => 'upper-alpha',
);
$ci_list_styles = Array(
'circle' => 'circle',
'disc' => 'disc',
'square' => 'square',
'greek' => 'lower-greek',
'armenian' => 'armenian',
'georgian' => 'georgian',
);
$ul_types = Array(
'circle' => 'circle',
'disc' => 'disc',
'square' => 'square',
);
$default = trim($default);
if ($action == BBCODE_CHECK)
{
if (!is_string($default) || strlen($default) == "")
{
return true;
}
else
{
if (isset($list_styles[$default]))
{
return true;
}
else
{
if (isset($ci_list_styles[strtolower($default)]))
{
return true;
}
else
{
return false;
}
}
}
}
if (!is_string($default) || strlen($default) == "")
{
$elem = 'ul';
$type = '';
}
else
{
if ($default == '1')
{
$elem = 'ol';
$type = '';
}
else
{
if (isset($list_styles[$default]))
{
$elem = 'ol';
$type = $list_styles[$default];
}
else
{
$default = strtolower($default);
if (isset($ul_types[$default]))
{
$elem = 'ul';
$type = $ul_types[$default];
}
else
{
if (isset($ci_list_styles[$default]))
{
$elem = 'ol';
$type = $ci_list_styles[$default];
}
}
}
}
}
if (strlen($type))
{
return "\n<$elem class=\"bbcode_list\" style=\"list-style-type:$type\">\n$content</$elem>\n";
}
else
{
return "\n<$elem class=\"bbcode_list\">\n$content</$elem>\n";
}
}
}
class BBCodeEmailAddressValidator
{
function check_email_address($strEmailAddress)
{
if (preg_match('/[\x00-\x1F\x7F-\xFF]/', $strEmailAddress))
{
return false;
}
$intAtSymbol = strrpos($strEmailAddress, '@');
if ($intAtSymbol === false)
{
return false;
}
$arrEmailAddress[0] = substr($strEmailAddress, 0, $intAtSymbol);
$arrEmailAddress[1] = substr($strEmailAddress, $intAtSymbol + 1);
$arrTempAddress[0] = preg_replace('/"[^"]+"/'
, ''
, $arrEmailAddress[0]);
$arrTempAddress[1] = $arrEmailAddress[1];
$strTempAddress = $arrTempAddress[0] . $arrTempAddress[1];
if (strrpos($strTempAddress, '@') !== false)
{
return false;
}
if (!$this->check_local_portion($arrEmailAddress[0]))
{
return false;
}
if (!$this->check_domain_portion($arrEmailAddress[1]))
{
return false;
}
return true;
}
function check_local_portion($strLocalPortion)
{
if (!$this->check_text_length($strLocalPortion, 1, 64))
{
return false;
}
$arrLocalPortion = explode('.', $strLocalPortion);
for ($i = 0, $max = sizeof($arrLocalPortion); $i < $max; $i++)
{
if (!preg_match('.^('
. '([A-Za-z0-9!#$%&\'*+/=?^_`{|}~-]'
. '[A-Za-z0-9!#$%&\'*+/=?^_`{|}~-]{0,63})'
. '|'
. '("[^\\\"]{0,62}")'
. ')$.'
, $arrLocalPortion[$i])
)
{
return false;
}
}
return true;
}
function check_domain_portion($strDomainPortion)
{
if (!$this->check_text_length($strDomainPortion, 1, 255))
{
return false;
}
if (preg_match('/^(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])'
. '(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}$/'
, $strDomainPortion) ||
preg_match('/^\[(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])'
. '(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}\]$/'
, $strDomainPortion)
)
{
return true;
}
else
{
$arrDomainPortion = explode('.', $strDomainPortion);
if (sizeof($arrDomainPortion) < 2)
{
return false;
}
for ($i = 0, $max = sizeof($arrDomainPortion); $i < $max; $i++)
{
if (!$this->check_text_length($arrDomainPortion[$i], 1, 63))
{
return false;
}
if (!preg_match('/^(([A-Za-z0-9][A-Za-z0-9-]{0,61}[A-Za-z0-9])|'
. '([A-Za-z0-9]+))$/', $arrDomainPortion[$i])
)
{
return false;
}
}
}
return true;
}
function check_text_length($strText, $intMinimum, $intMaximum)
{
$intTextLength = strlen($strText);
if (($intTextLength < $intMinimum) || ($intTextLength > $intMaximum))
{
return false;
}
else
{
return true;
}
}
}
class NBBC_BBCode
{
var $tag_rules;
var $defaults;
var $current_class;
var $root_class;
var $lost_start_tags;
var $start_tags;
var $allow_ampersand;
var $tag_marker;
var $ignore_newlines;
var $plain_mode;
var $detect_urls;
var $url_pattern;
var $output_limit;
var $text_length;
var $was_limited;
var $limit_tail;
var $limit_precision;
var $smiley_dir;
var $smiley_url;
var $smileys;
var $smiley_regex;
var $enable_smileys;
var $wiki_url;
var $local_img_dir;
var $local_img_url;
var $url_targetable;
var $url_target;
var $rule_html;
var $pre_trim;
var $post_trim;
var $debug;
function __construct()
{
$this->defaults = new BBCodeLibrary;
$this->tag_rules = $this->defaults->default_tag_rules;
$this->smileys = $this->defaults->default_smileys;
$this->enable_smileys = true;
$this->smiley_regex = false;
$this->smiley_dir = $this->GetDefaultSmileyDir();
$this->smiley_url = $this->GetDefaultSmileyURL();
$this->wiki_url = $this->GetDefaultWikiURL();
$this->local_img_dir = $this->GetDefaultLocalImgDir();
$this->local_img_url = $this->GetDefaultLocalImgURL();
$this->rule_html = $this->GetDefaultRuleHTML();
$this->pre_trim = "";
$this->post_trim = "";
$this->root_class = 'block';
$this->lost_start_tags = Array();
$this->start_tags = Array();
$this->tag_marker = '[';
$this->allow_ampsersand = false;
$this->current_class = $this->root_class;
$this->debug = false;
$this->ignore_newlines = false;
$this->output_limit = 0;
$this->plain_mode = false;
$this->was_limited = false;
$this->limit_tail = "...";
$this->limit_precision = 0.15;
$this->detect_urls = false;
$this->url_pattern = '<a href="{$url/h}">{$text/h}</a>';
$this->url_targetable = false;
$this->url_target = false;
}
function SetPreTrim($trim = "a")
{
$this->pre_trim = $trim;
}
function GetPreTrim()
{
return $this->pre_trim;
}
function SetPostTrim($trim = "a")
{
$this->post_trim = $trim;
}
function GetPostTrim()
{
return $this->post_trim;
}
function SetRoot($class = 'block')
{
$this->root_class = $class;
}
function SetRootInline()
{
$this->root_class = 'inline';
}
function SetRootBlock()
{
$this->root_class = 'block';
}
function GetRoot()
{
return $this->root_class;
}
function SetDebug($enable = true)
{
$this->debug = $enable;
}
function GetDebug()
{
return $this->debug;
}
function SetAllowAmpersand($enable = true)
{
$this->allow_ampersand = $enable;
}
function GetAllowAmpersand()
{
return $this->allow_ampersand;
}
function SetTagMarker($marker = '[')
{
$this->tag_marker = $marker;
}
function GetTagMarker()
{
return $this->tag_marker;
}
function SetIgnoreNewlines($ignore = true)
{
$this->ignore_newlines = $ignore;
}
function GetIgnoreNewlines()
{
return $this->ignore_newlines;
}
function SetLimit($limit = 0)
{
$this->output_limit = $limit;
}
function GetLimit()
{
return $this->output_limit;
}
function SetLimitTail($tail = "...")
{
$this->limit_tail = $tail;
}
function GetLimitTail()
{
return $this->limit_tail;
}
function SetLimitPrecision($prec = 0.15)
{
$this->limit_precision = $prec;
}
function GetLimitPrecision()
{
return $this->limit_precision;
}
function WasLimited()
{
return $this->was_limited;
}
function SetPlainMode($enable = true)
{
$this->plain_mode = $enable;
}
function GetPlainMode()
{
return $this->plain_mode;
}
function SetDetectURLs($enable = true)
{
$this->detect_urls = $enable;
}
function GetDetectURLs()
{
return $this->detect_urls;
}
function SetURLPattern($pattern)
{
$this->url_pattern = $pattern;
}
function GetURLPattern()
{
return $this->url_pattern;
}
function SetURLTargetable($enable)
{
$this->url_targetable = $enable;
}
function GetURLTargetable()
{
return $this->url_targetable;
}
function SetURLTarget($target)
{
$this->url_target = $target;
}
function GetURLTarget()
{
return $this->url_target;
}
function AddRule($name, $rule)
{
$this->tag_rules[$name] = $rule;
}
function RemoveRule($name)
{
unset($this->tag_rules[$name]);
}
function GetRule($name)
{
return isset($this->tag_rules[$name])
? $this->tag_rules[$name] : false;
}
function ClearRules()
{
$this->tag_rules = Array();
}
function GetDefaultRule($name)
{
return isset($this->defaults->default_tag_rules[$name])
? $this->defaults->default_tag_rules[$name] : false;
}
function SetDefaultRule($name)
{
if (isset($this->defaults->default_tag_rules[$name]))
{
$this->AddRule($name, $this->defaults->default_tag_rules[$name]);
}
else
{
$this->RemoveRule($name);
}
}
function GetDefaultRules()
{
return $this->defaults->default_tag_rules;
}
function SetDefaultRules()
{
$this->tag_rules = $this->defaults->default_tag_rules;
}
function SetWikiURL($url)
{
$this->wiki_url = $url;
}
function GetWikiURL($url)
{
return $this->wiki_url;
}
function GetDefaultWikiURL()
{
return '/?page=';
}
function SetLocalImgDir($path)
{
$this->local_img_dir = $path;
}
function GetLocalImgDir()
{
return $this->local_img_dir;
}
function GetDefaultLocalImgDir()
{
return "img";
}
function SetLocalImgURL($path)
{
$this->local_img_url = $path;
}
function GetLocalImgURL()
{
return $this->local_img_url;
}
function GetDefaultLocalImgURL()
{
return "img";
}
function SetRuleHTML($html)
{
$this->rule_html = $html;
}
function GetRuleHTML()
{
return $this->rule_html;
}
function GetDefaultRuleHTML()
{
return "\n<hr class=\"bbcode_rule\" />\n";
}
function AddSmiley($code, $image)
{
$this->smileys[$code] = $image;
$this->smiley_regex = false;
}
function RemoveSmiley($code)
{
unset($this->smileys[$code]);
$this->smiley_regex = false;
}
function GetSmiley($code)
{
return isset($this->smileys[$code])
? $this->smileys[$code] : false;
}
function ClearSmileys()
{
$this->smileys = Array();
$this->smiley_regex = false;
}
function GetDefaultSmiley($code)
{
return isset($this->defaults->default_smileys[$code])
? $this->defaults->default_smileys[$code] : false;
}
function SetDefaultSmiley($code)
{
$this->smileys[$code] = @$this->defaults->default_smileys[$code];
$this->smiley_regex = false;
}
function GetDefaultSmileys()
{
return $this->defaults->default_smileys;
}
function SetDefaultSmileys()
{
$this->smileys = $this->defaults->default_smileys;
$this->smiley_regex = false;
}
function SetSmileyDir($path)
{
$this->smiley_dir = $path;
}
function GetSmileyDir()
{
return $this->smiley_dir;
}
function GetDefaultSmileyDir()
{
return "smileys";
}
function SetSmileyURL($path)
{
$this->smiley_url = $path;
}
function GetSmileyURL()
{
return $this->smiley_url;
}
function GetDefaultSmileyURL()
{
return "smileys";
}
function SetEnableSmileys($enable = true)
{
$this->enable_smileys = $enable;
}
function GetEnableSmileys()
{
return $this->enable_smileys;
}
function nl2br($string)
{
return preg_replace("/\\x0A|\\x0D|\\x0A\\x0D|\\x0D\\x0A/", "<br />\n", $string);
}
function UnHTMLEncode($string)
{
if (function_exists("html_entity_decode"))
{
return html_entity_decode($string);
}
$string = preg_replace('~&#x([0-9a-f]+);~ei', 'chr(hexdec("\\1"))', $string);
$string = preg_replace('~&#([0-9]+);~e', 'chr("\\1")', $string);
$trans_tbl = get_html_translation_table(HTML_ENTITIES);
$trans_tbl = array_flip($trans_tbl);
return strtr($string, $trans_tbl);
}
function Wikify($string)
{
return rawurlencode(str_replace(" ", "_",
trim(preg_replace("/[!?;@#\$%\\^&*<>=+`~\\x00-\\x20_-]+/", " ", $string))));
}
function IsValidURL($string, $email_too = true)
{
if (preg_match("/^
(?:https?|ftp):\\/\\/
(?:
(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\\.)+
[a-zA-Z0-9]
(?:[a-zA-Z0-9-]*[a-zA-Z0-9])?
|
\\[
(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}
(?:
25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-zA-Z0-9-]*[a-zA-Z0-9]:
(?:[\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F\\x21-\\x5A\\x53-\\x7F]
|\\\\[\\x01-\\x09\\x0B\\x0C\\x0E-\\x7F])+
)
\\]
)
(?::[0-9]{1,5})?
(?:[\\/\\?\\#][^\\n\\r]*)?
$/Dx", $string))
{
return true;
}
if (preg_match("/^[^:]+([\\/\\\\?#][^\\r\\n]*)?$/D", $string))
{
return true;
}
if ($email_too)
{
if (substr($string, 0, 7) == "mailto:")
{
return $this->IsValidEmail(substr($string, 7));
}
}
return false;
}
function IsValidEmail($string)
{
$validator = new BBCodeEmailAddressValidator;
return $validator->check_email_address($string);
/*
return preg_match("/^
(?:
[a-z0-9\\!\\#\\\$\\%\\&\\'\\*\\+\\/=\\?\\^_`\\{\\|\\}~-]+
(?:\.[a-z0-9\\!\\#\\\$\\%\\&\\'\\*\\+\\/=\\?\\^_`\\{\\|\\}~-]+)*
|
\"(?:[\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F\\x21\\x23-\\x5B\\x5D-\\x7F]
|\\\\[\\x01-\\x09\\x0B\\x0C\\x0E-\\x7F])*\"
)
@
(?:
(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+
[a-z0-9]
(?:[a-z0-9-]*[a-z0-9])?
|
\\[
(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}
(?:
25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:
(?:[\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F\\x21-\\x5A\\x53-\\x7F]
|\\\\[\\x01-\\x09\\x0B\\x0C\\x0E-\\x7F])+
)
\\]
)
$/Dx", $string);
*/
}
function HTMLEncode($string)
{
if (!$this->allow_ampersand)
{
return htmlspecialchars($string);
}
else
{
return str_replace(Array('<', '>', '"'),
Array('<', '>', '"'), $string);
}
}
function FixupOutput($string)
{
/*HACK >*/
if (!$this->detect_urls || $this->autolink_disable)
{
/*< HACK*/
$output = $this->Internal_ProcessSmileys($string);
}
else
{
$chunks = $this->Internal_AutoDetectURLs($string);
$output = Array();
if (count($chunks))
{
$is_a_url = false;
foreach ($chunks as $index => $chunk)
{
if (!$is_a_url)
{
$chunk = $this->Internal_ProcessSmileys($chunk);
}
$output[] = $chunk;
$is_a_url = !$is_a_url;
}
}
$output = implode("", $output);
}
return $output;
}
function Internal_ProcessSmileys($string)
{
if (!$this->enable_smileys || $this->plain_mode)
{
$output = $this->HTMLEncode($string);
}
else
{
if ($this->smiley_regex === false)
{
$this->Internal_RebuildSmileys();
}
$tokens = preg_split($this->smiley_regex, $string, -1, PREG_SPLIT_DELIM_CAPTURE);
if (count($tokens) <= 1)
{
$output = $this->HTMLEncode($string);
}
else
{
$output = "";
$is_a_smiley = false;
foreach ($tokens as $token)
{
if (!$is_a_smiley)
{
$output .= $this->HTMLEncode($token);
}
else
{
if (isset($this->smiley_info[$token]))
{
$info = $this->smiley_info[$token];
}
else
{
$info = @getimagesize($this->smiley_dir . '/' . $this->smileys[$token]);
$this->smiley_info[$token] = $info;
}
$alt = htmlspecialchars($token);
$output .= "<img src=\"" . htmlspecialchars($this->smiley_url . '/' . $this->smileys[$token])
. "\" width=\"{$info[0]}\" height=\"{$info[1]}\""
. " alt=\"$alt\" title=\"$alt\" class=\"bbcode_smiley\" />";
}
$is_a_smiley = !$is_a_smiley;
}
}
}
return $output;
}
function Internal_RebuildSmileys()
{
$regex = Array("/(?<![\\w])(");
$first = true;
foreach ($this->smileys as $code => $filename)
{
if (!$first)
{
$regex[] = "|";
}
$regex[] = preg_quote("$code", '/');
$first = false;
}
$regex[] = ")(?![\\w])/";
$this->smiley_regex = implode("", $regex);
}
function Internal_AutoDetectURLs($string)
{
$output = preg_split("/( (?:
(?:https?|ftp) : \\/*
(?:
(?: (?: [a-zA-Z0-9-]{2,} \\. )+
(?: arpa | com | org | net | edu | gov | mil | int | [a-z]{2}
| aero | biz | coop | info | museum | name | pro
| example | invalid | localhost | test | local | onion | swift ) )
| (?: [0-9]{1,3} \\. [0-9]{1,3} \\. [0-9]{1,3} \\. [0-9]{1,3} )
| (?: [0-9A-Fa-f:]+ : [0-9A-Fa-f]{1,4} )
)
(?: : [0-9]+ )?
(?! [a-zA-Z0-9.:-] )
(?:
\\/
[^&?#\\(\\)\\[\\]\\{\\}<>\\'\\\"\\x00-\\x20\\x7F-\\xFF]*
)?
(?:
[?#]
[^\\(\\)\\[\\]\\{\\}<>\\'\\\"\\x00-\\x20\\x7F-\\xFF]+
)?
) | (?:
(?:
(?: (?: [a-zA-Z0-9-]{2,} \\. )+
(?: arpa | com | org | net | edu | gov | mil | int | [a-z]{2}
| aero | biz | coop | info | museum | name | pro
| example | invalid | localhost | test | local | onion | swift ) )
| (?: [0-9]{1,3} \\. [0-9]{1,3} \\. [0-9]{1,3} \\. [0-9]{1,3} )
)
(?: : [0-9]+ )?
(?! [a-zA-Z0-9.:-] )
(?:
\\/
[^&?#\\(\\)\\[\\]\\{\\}<>\\'\\\"\\x00-\\x20\\x7F-\\xFF]*
)?
(?:
[?#]
[^\\(\\)\\[\\]\\{\\}<>\\'\\\"\\x00-\\x20\\x7F-\\xFF]+
)?
) | (?:
[a-zA-Z0-9._-]{2,} @
(?:
(?: (?: [a-zA-Z0-9-]{2,} \\. )+
(?: arpa | com | org | net | edu | gov | mil | int | [a-z]{2}
| aero | biz | coop | info | museum | name | pro
| example | invalid | localhost | test | local | onion | swift ) )
| (?: [0-9]{1,3} \\. [0-9]{1,3} \\. [0-9]{1,3} \\. [0-9]{1,3} )
)
) )/Dx", $string, -1, PREG_SPLIT_DELIM_CAPTURE);
if (count($output) > 1)
{
$is_a_url = false;
foreach ($output as $index => $token)
{
if ($is_a_url)
{
if (preg_match("/^[a-zA-Z0-9._-]{2,}@/", $token))
{
$url = "mailto:" . $token;
}
else
{
if (preg_match("/^(https?:|ftp:)\\/*([^\\/&?#]+)\\/*(.*)\$/", $token, $matches))
{
$url = $matches[1] . '/' . '/' . $matches[2] . "/" . $matches[3];
}
else
{
preg_match("/^([^\\/&?#]+)\\/*(.*)\$/", $token, $matches);
$url = "http:/" . "/" . $matches[1] . "/" . $matches[2];
}
}
$params = @parse_url($url);
/*HACK >*/
if (!is_array($params))
{
$output[$index] = $token;
continue;
}
/*< HACK*/
$params['url'] = $url;
$params['isurl'] = $this->IsValidURL($url);
$params['link'] = $url;
$params['text'] = $token;
/*HACK >*/
$output[$index] = $this->FillTemplate($this->url_pattern, $params);
/*< HACK*/
}
$is_a_url = !$is_a_url;
}
}
return $output;
}
function FillTemplate($template, $insert_array, $default_array = Array())
{
/*HACK >*/
if (is_array($template))
{
return call_user_func($template, $insert_array);
}
/*< HACK*/
$pieces = preg_split('/(\{\$[a-zA-Z0-9_.:\/-]+\})/', $template,
-1, PREG_SPLIT_DELIM_CAPTURE);
if (count($pieces) <= 1)
{
return $template;
}
$result = Array();
$is_an_insert = false;
foreach ($pieces as $piece)
{
if (!$is_an_insert)
{
$result[] = $piece;
}
else
{
if (!preg_match('/\{\$([a-zA-Z0-9_:-]+)((?:\\.[a-zA-Z0-9_:-]+)*)(?:\/([a-zA-Z0-9_:-]+))?\}/', $piece, $matches))
{
$result[] = $piece;
}
else
{
if (isset($insert_array[$matches[1]]))
{
$value = @$insert_array[$matches[1]];
}
else
{
$value = @$default_array[$matches[1]];
}
if (strlen(@$matches[2]))
{
foreach (split(".", substr($matches[2], 1)) as $index)
{
if (is_array($value))
{
$value = @$value[$index];
}
else
{
if (is_object($value))
{
$value = (array) $value;
$value = @$value[$index];
}
else
{
$value = "";
}
}
}
}
switch (gettype($value))
{
case 'boolean':
$value = $value ? "true" : "false";
break;
case 'integer':
$value = (string) $value;
break;
case 'double':
$value = (string) $value;
break;
case 'string':
break;
default:
$value = "";
break;
}
if (strlen(@$matches[3]))
{
$flags = array_flip(str_split($matches[3]));
}
else
{
$flags = Array();
}
if (!isset($flags['v']))
{
if (isset($flags['w']))
{
$value = preg_replace("/[\\x00-\\x09\\x0B-\x0C\x0E-\\x20]+/", " ", $value);
}
if (isset($flags['t']))
{
$value = trim($value);
}
if (isset($flags['b']))
{
$value = basename($value);
}
if (isset($flags['e']))
{
$value = $this->HTMLEncode($value);
}
else
{
if (isset($flags['k']))
{
$value = $this->Wikify($value);
}
else
{
if (isset($flags['h']))
{
$value = htmlspecialchars($value);
}
else
{
if (isset($flags['u']))
{
$value = urlencode($value);
}
}
}
}
if (isset($flags['n']))
{
$value = $this->nl2br($value);
}
}
$result[] = $value;
}
}
$is_an_insert = !$is_an_insert;
}
return implode("", $result);
}
function Internal_CollectText($array, $start = 0)
{
ob_start();
for ($start = intval($start), $end = count($array); $start < $end; $start++)
print $array[$start][BBCODE_STACK_TEXT];
$output = ob_get_contents();
ob_end_clean();
return $output;
}
function Internal_CollectTextReverse($array, $start = 0, $end = 0)
{
ob_start();
for ($start = intval($start); $start >= $end; $start--)
print $array[$start][BBCODE_STACK_TEXT];
$output = ob_get_contents();
ob_end_clean();
return $output;
}
function Internal_GenerateOutput($pos)
{
$output = Array();
while (count($this->stack) > $pos)
{
$token = array_pop($this->stack);
if ($token[BBCODE_STACK_TOKEN] != BBCODE_TAG)
{
$output[] = $token;
}
else
{
$name = @$token[BBCODE_STACK_TAG]['_name'];
$rule = @$this->tag_rules[$name];
$end_tag = @$rule['end_tag'];
if (!isset($rule['end_tag']))
{
$end_tag = BBCODE_REQUIRED;
}
else
{
$end_tag = $rule['end_tag'];
}
array_pop($this->start_tags[$name]);
if ($end_tag == BBCODE_PROHIBIT)
{
$output[] = Array(
BBCODE_STACK_TOKEN => BBCODE_TEXT,
BBCODE_STACK_TAG => false,
BBCODE_STACK_TEXT => $token[BBCODE_STACK_TEXT],
BBCODE_STACK_CLASS => $this->current_class,
);
}
else
{
if ($end_tag == BBCODE_REQUIRED)
{
@$this->lost_start_tags[$name] + 1;
}
$end = $this->Internal_CleanupWSByIteratingPointer(@$rule['before_endtag'], 0, $output);
$this->Internal_CleanupWSByPoppingStack(@$rule['after_tag'], $output);
$tag_body = $this->Internal_CollectTextReverse($output, count($output) - 1, $end);
$this->Internal_CleanupWSByPoppingStack(@$rule['before_tag'], $this->stack);
$this->Internal_UpdateParamsForMissingEndTag(@$token[BBCODE_STACK_TAG]);
$tag_output = $this->DoTag(BBCODE_OUTPUT, $name,
@$token[BBCODE_STACK_TAG]['_default'], @$token[BBCODE_STACK_TAG], $tag_body);
$output = Array(Array(
BBCODE_STACK_TOKEN => BBCODE_TEXT,
BBCODE_STACK_TAG => false,
BBCODE_STACK_TEXT => $tag_output,
BBCODE_STACK_CLASS => $this->current_class
));
}
}
}
$this->Internal_ComputeCurrentClass();
return $output;
}
function Internal_RewindToClass($class_list)
{
$pos = count($this->stack) - 1;
while ($pos >= 0 && !in_array($this->stack[$pos][BBCODE_STACK_CLASS], $class_list))
$pos--;
if ($pos < 0)
{
if (!in_array($this->root_class, $class_list))
{
return false;
}
}
$output = $this->Internal_GenerateOutput($pos + 1);
while (count($output))
{
$token = array_pop($output);
$token[BBCODE_STACK_CLASS] = $this->current_class;
$this->stack[] = $token;
}
return true;
}
function Internal_FinishTag($tag_name)
{
if (strlen($tag_name) <= 0)
{
return false;
}
if (isset($this->start_tags[$tag_name])
&& count($this->start_tags[$tag_name])
)
{
$pos = array_pop($this->start_tags[$tag_name]);
}
else
{
$pos = -1;
}
if ($pos < 0)
{
return false;
}
$newpos = $this->Internal_CleanupWSByIteratingPointer(@$this->tag_rules[$tag_name]['after_tag'],
$pos + 1, $this->stack);
$delta = $newpos - ($pos + 1);
$output = $this->Internal_GenerateOutput($newpos);
$newend = $this->Internal_CleanupWSByIteratingPointer(@$this->tag_rules[$tag_name]['before_endtag'],
0, $output);
$output = $this->Internal_CollectTextReverse($output, count($output) - 1, $newend);
while ($delta-- > 0)
array_pop($this->stack);
$this->Internal_ComputeCurrentClass();
return $output;
}
function Internal_ComputeCurrentClass()
{
if (count($this->stack) > 0)
{
$this->current_class = $this->stack[count($this->stack) - 1][BBCODE_STACK_CLASS];
}
else
{
$this->current_class = $this->root_class;
}
}
function Internal_DumpStack($array = false, $raw = false)
{
if (!$raw)
{
$string = "<span style='color: #00C;'>";
}
else
{
$string = "";
}
if ($array === false)
{
$array = $this->stack;
}
foreach ($array as $item)
{
switch (@$item[BBCODE_STACK_TOKEN])
{
case BBCODE_TEXT:
$string .= "\"" . htmlspecialchars(@$item[BBCODE_STACK_TEXT]) . "\" ";
break;
case BBCODE_WS:
$string .= "WS ";
break;
case BBCODE_NL:
$string .= "NL ";
break;
case BBCODE_TAG:
$string .= "[" . htmlspecialchars(@$item[BBCODE_STACK_TAG]['_name']) . "] ";
break;
default:
$string .= "unknown ";
break;
}
}
if (!$raw)
{
$string .= "</span>";
}
return $string;
}
function Internal_CleanupWSByPoppingStack($pattern, &$array)
{
if (strlen($pattern) <= 0)
{
return;
}
$oldlen = count($array);
foreach (str_split($pattern) as $char)
{
switch ($char)
{
case 's':
while (count($array) > 0 && $array[count($array) - 1][BBCODE_STACK_TOKEN] == BBCODE_WS)
array_pop($array);
break;
case 'n':
if (count($array) > 0 && $array[count($array) - 1][BBCODE_STACK_TOKEN] == BBCODE_NL)
{
array_pop($array);
}
break;
case 'a':
while (count($array) > 0
&& (($token = $array[count($array) - 1][BBCODE_STACK_TOKEN]) == BBCODE_WS
|| $token == BBCODE_NL))
array_pop($array);
break;
}
}
if (count($array) != $oldlen)
{
$this->Internal_ComputeCurrentClass();
}
}
function Internal_CleanupWSByEatingInput($pattern)
{
if (strlen($pattern) <= 0)
{
return;
}
foreach (str_split($pattern) as $char)
{
switch ($char)
{
case 's':
$token_type = $this->lexer->NextToken();
while ($token_type == BBCODE_WS)
{
$token_type = $this->lexer->NextToken();
}
$this->lexer->UngetToken();
break;
case 'n':
$token_type = $this->lexer->NextToken();
if ($token_type != BBCODE_NL)
{
$this->lexer->UngetToken();
}
break;
case 'a':
$token_type = $this->lexer->NextToken();
while ($token_type == BBCODE_WS || $token_type == BBCODE_NL)
{
$token_type = $this->lexer->NextToken();
}
$this->lexer->UngetToken();
break;
}
}
}
function Internal_CleanupWSByIteratingPointer($pattern, $pos, $array)
{
if (strlen($pattern) <= 0)
{
return $pos;
}
foreach (str_split($pattern) as $char)
{
switch ($char)
{
case 's':
while ($pos < count($array) && $array[$pos][BBCODE_STACK_TOKEN] == BBCODE_WS)
$pos++;
break;
case 'n':
if ($pos < count($array) && $array[$pos][BBCODE_STACK_TOKEN] == BBCODE_NL)
{
$pos++;
}
break;
case 'a':
while ($pos < count($array)
&& (($token = $array[$pos][BBCODE_STACK_TOKEN]) == BBCODE_WS || $token == BBCODE_NL))
$pos++;
break;
}
}
return $pos;
}
function Internal_LimitText($string, $limit)
{
$chunks = preg_split("/([\\x00-\\x20]+)/", $string, -1, PREG_SPLIT_DELIM_CAPTURE);
$output = "";
foreach ($chunks as $chunk)
{
if (strlen($output) + strlen($chunk) > $limit)
{
break;
}
$output .= $chunk;
}
$output = rtrim($output);
return $output;
}
function Internal_DoLimit()
{
$this->Internal_CleanupWSByPoppingStack("a", $this->stack);
if (strlen($this->limit_tail) > 0)
{
$this->stack[] = Array(
BBCODE_STACK_TOKEN => BBCODE_TEXT,
BBCODE_STACK_TEXT => $this->limit_tail,
BBCODE_STACK_TAG => false,
BBCODE_STACK_CLASS => $this->current_class,
);
}
$this->was_limited = true;
}
function DoTag($action, $tag_name, $default_value, $params, $contents)
{
$tag_rule = @$this->tag_rules[$tag_name];
switch ($action)
{
case BBCODE_CHECK:
if (isset($tag_rule['allow']))
{
foreach ($tag_rule['allow'] as $param => $pattern)
{
if ($param == '_content')
{
$value = $contents;
}
else
{
if ($param == '_defaultcontent')
{
if (strlen($default_value))
{
$value = $default_value;
}
else
{
$value = $contents;
}
}
else
{
if (isset($params[$param]))
{
$value = $params[$param];
}
else
{
$value = @$tag_rule['default'][$param];
}
}
}
if (!preg_match($pattern, $value))
{
return false;
}
}
return true;
}
switch (@$tag_rule['mode'])
{
default:
case BBCODE_MODE_SIMPLE:
$result = true;
break;
case BBCODE_MODE_ENHANCED:
$result = true;
break;
case BBCODE_MODE_INTERNAL:
$result = @call_user_func(Array($this, @$tag_rule['method']), BBCODE_CHECK,
$tag_name, $default_value, $params, $contents);
break;
case BBCODE_MODE_LIBRARY:
$result = @call_user_func(Array($this->defaults, @$tag_rule['method']), $this, BBCODE_CHECK,
$tag_name, $default_value, $params, $contents);
break;
case BBCODE_MODE_CALLBACK:
$result = @call_user_func(@$tag_rule['method'], $this, BBCODE_CHECK,
$tag_name, $default_value, $params, $contents);
break;
}
return $result;
case BBCODE_OUTPUT:
if ($this->plain_mode)
{
if (!isset($tag_rule['plain_content']))
{
$plain_content = Array('_content');
}
else
{
$plain_content = $tag_rule['plain_content'];
}
$result = $possible_content = "";
foreach ($plain_content as $possible_content)
{
if ($possible_content == '_content'
&& strlen($contents) > 0
)
{
$result = $contents;
break;
}
if (isset($params[$possible_content])
&& strlen($params[$possible_content]) > 0
)
{
$result = htmlspecialchars($params[$possible_content]);
break;
}
}
$start = @$tag_rule['plain_start'];
$end = @$tag_rule['plain_end'];
if (isset($tag_rule['plain_link']))
{
$link = $possible_content = "";
foreach ($tag_rule['plain_link'] as $possible_content)
{
if ($possible_content == '_content'
&& strlen($contents) > 0
)
{
$link = $this->UnHTMLEncode(strip_tags($contents));
break;
}
if (isset($params[$possible_content])
&& strlen($params[$possible_content]) > 0
)
{
$link = $params[$possible_content];
break;
}
}
$params = @parse_url($link);
if (!is_array($params))
{
$params = Array();
}
$params['link'] = $link;
$params['url'] = $link;
$start = $this->FillTemplate($start, $params);
$end = $this->FillTemplate($end, $params);
}
return $start . $result . $end;
}
switch (@$tag_rule['mode'])
{
default:
case BBCODE_MODE_SIMPLE:
$result = @$tag_rule['simple_start'] . $contents . @$tag_rule['simple_end'];
break;
case BBCODE_MODE_ENHANCED:
$result = $this->Internal_DoEnhancedTag($tag_rule, $params, $contents);
break;
case BBCODE_MODE_INTERNAL:
$result = @call_user_func(Array($this, @$tag_rule['method']), BBCODE_OUTPUT,
$tag_name, $default_value, $params, $contents);
break;
case BBCODE_MODE_LIBRARY:
$result = @call_user_func(Array($this->defaults, @$tag_rule['method']), $this, BBCODE_OUTPUT,
$tag_name, $default_value, $params, $contents);
break;
case BBCODE_MODE_CALLBACK:
$result = @call_user_func(@$tag_rule['method'], $this, BBCODE_OUTPUT,
$tag_name, $default_value, $params, $contents);
break;
}
return $result;
default:
return false;
}
}
function Internal_DoEnhancedTag($tag_rule, $params, $contents)
{
$params['_content'] = $contents;
$params['_defaultcontent'] = strlen(@$params['_default']) ? $params['_default'] : $contents;
return $this->FillTemplate(@$tag_rule['template'], $params, @$tag_rule['default']);
}
function Internal_UpdateParamsForMissingEndTag($params)
{
switch ($this->tag_marker)
{
case '[':
$tail_marker = ']';
break;
case '<':
$tail_marker = '>';
break;
case '{':
$tail_marker = '}';
break;
case '(':
$tail_marker = ')';
break;
default:
$tail_marker = $this->tag_marker;
break;
}
$params['_endtag'] = $this->tag_marker . '/' . $params['_name'] . $tail_marker;
}
function Internal_ProcessIsolatedTag($tag_name, $tag_params, $tag_rule)
{
if (!$this->DoTag(BBCODE_CHECK, $tag_name, @$tag_params['_default'], $tag_params, ""))
{
$this->stack[] = Array(
BBCODE_STACK_TOKEN => BBCODE_TEXT,
BBCODE_STACK_TEXT => $this->FixupOutput($this->lexer->text),
BBCODE_STACK_TAG => false,
BBCODE_STACK_CLASS => $this->current_class,
);
return;
}
$this->Internal_CleanupWSByPoppingStack(@$tag_rule['before_tag'], $this->stack);
$output = $this->DoTag(BBCODE_OUTPUT, $tag_name, @$tag_params['_default'], $tag_params, "");
$this->Internal_CleanupWSByEatingInput(@$tag_rule['after_tag']);
$this->stack[] = Array(
BBCODE_STACK_TOKEN => BBCODE_TEXT,
BBCODE_STACK_TEXT => $output,
BBCODE_STACK_TAG => false,
BBCODE_STACK_CLASS => $this->current_class,
);
}
function Internal_ProcessVerbatimTag($tag_name, $tag_params, $tag_rule)
{
$state = $this->lexer->SaveState();
$end_tag = $this->lexer->tagmarker . "/" . $tag_name . $this->lexer->end_tagmarker;
$start = count($this->stack);
$this->lexer->verbatim = true;
while (($token_type = $this->lexer->NextToken()) != BBCODE_EOI)
{
// START FIX
if (strtolower($this->lexer->text) == $end_tag)
{
// END FIX
$end_tag_params = $this->lexer->tag;
break;
}
// START FIX
if ($this->was_limited)
{
continue;
}
// END FIX
if ($this->output_limit > 0
&& $this->text_length + strlen($this->lexer->text) >= $this->output_limit
)
{
$text = $this->Internal_LimitText($this->lexer->text,
$this->output_limit - $this->text_length);
if (strlen($text) > 0)
{
$this->text_length += strlen($text);
$this->stack[] = Array(
BBCODE_STACK_TOKEN => BBCODE_TEXT,
BBCODE_STACK_TEXT => $this->FixupOutput($text),
BBCODE_STACK_TAG => false,
BBCODE_STACK_CLASS => $this->current_class,
);
}
$this->Internal_DoLimit();
// START FIX
continue;
// END FIX
}
$this->text_length += strlen($this->lexer->text);
$this->stack[] = Array(
BBCODE_STACK_TOKEN => $token_type,
BBCODE_STACK_TEXT => htmlspecialchars($this->lexer->text),
BBCODE_STACK_TAG => $this->lexer->tag,
BBCODE_STACK_CLASS => $this->current_class,
);
}
$this->lexer->verbatim = false;
if ($token_type == BBCODE_EOI)
{
$this->lexer->RestoreState($state);
$this->stack[] = Array(
BBCODE_STACK_TOKEN => BBCODE_TEXT,
BBCODE_STACK_TEXT => $this->FixupOutput($this->lexer->text),
BBCODE_STACK_TAG => false,
BBCODE_STACK_CLASS => $this->current_class,
);
return;
}
$newstart = $this->Internal_CleanupWSByIteratingPointer(@$tag_rule['after_tag'], $start, $this->stack);
$this->Internal_CleanupWSByPoppingStack(@$tag_rule['before_endtag'], $this->stack);
$this->Internal_CleanupWSByEatingInput(@$tag_rule['after_endtag']);
$content = $this->Internal_CollectText($this->stack, $newstart);
array_splice($this->stack, $start);
$this->Internal_ComputeCurrentClass();
$this->Internal_CleanupWSByPoppingStack(@$tag_rule['before_tag'], $this->stack);
$tag_params['_endtag'] = $end_tag_params['_tag'];
$tag_params['_hasend'] = true;
$output = $this->DoTag(BBCODE_OUTPUT, $tag_name,
@$tag_params['_default'], $tag_params, $content);
$this->stack[] = Array(
BBCODE_STACK_TOKEN => BBCODE_TEXT,
BBCODE_STACK_TEXT => $output,
BBCODE_STACK_TAG => false,
BBCODE_STACK_CLASS => $this->current_class,
);
}
function Internal_ParseStartTagToken()
{
$tag_params = $this->lexer->tag;
$tag_name = @$tag_params['_name'];
if (!isset($this->tag_rules[$tag_name]))
{
$this->stack[] = Array(
BBCODE_STACK_TOKEN => BBCODE_TEXT,
BBCODE_STACK_TEXT => $this->FixupOutput($this->lexer->text),
BBCODE_STACK_TAG => false,
BBCODE_STACK_CLASS => $this->current_class,
);
return;
}
$tag_rule = $this->tag_rules[$tag_name];
$allow_in = is_array($tag_rule['allow_in'])
? $tag_rule['allow_in'] : Array($this->root_class);
if (!in_array($this->current_class, $allow_in))
{
if (!$this->Internal_RewindToClass($allow_in))
{
$this->stack[] = Array(
BBCODE_STACK_TOKEN => BBCODE_TEXT,
BBCODE_STACK_TEXT => $this->FixupOutput($this->lexer->text),
BBCODE_STACK_TAG => false,
BBCODE_STACK_CLASS => $this->current_class,
);
return;
}
}
$end_tag = isset($tag_rule['end_tag']) ? $tag_rule['end_tag'] : BBCODE_REQUIRED;
if ($end_tag == BBCODE_PROHIBIT)
{
$this->Internal_ProcessIsolatedTag($tag_name, $tag_params, $tag_rule);
return;
}
if (!$this->DoTag(BBCODE_CHECK, $tag_name, @$tag_params['_default'], $tag_params, ""))
{
$this->stack[] = Array(
BBCODE_STACK_TOKEN => BBCODE_TEXT,
BBCODE_STACK_TEXT => $this->FixupOutput($this->lexer->text),
BBCODE_STACK_TAG => false,
BBCODE_STACK_CLASS => $this->current_class,
);
return;
}
if (@$tag_rule['content'] == BBCODE_VERBATIM)
{
$this->Internal_ProcessVerbatimTag($tag_name, $tag_params, $tag_rule);
return;
}
if (isset($tag_rule['class']))
{
$newclass = $tag_rule['class'];
}
else
{
$newclass = $this->root_class;
}
$this->stack[] = Array(
BBCODE_STACK_TOKEN => $this->lexer->token,
BBCODE_STACK_TEXT => $this->FixupOutput($this->lexer->text),
BBCODE_STACK_TAG => $this->lexer->tag,
BBCODE_STACK_CLASS => ($this->current_class = $newclass),
);
if (!isset($this->start_tags[$tag_name]))
{
$this->start_tags[$tag_name] = Array(count($this->stack) - 1);
}
else
{
$this->start_tags[$tag_name][] = count($this->stack) - 1;
}
}
function Internal_ParseEndTagToken()
{
$tag_params = $this->lexer->tag;
$tag_name = @$tag_params['_name'];
$contents = $this->Internal_FinishTag($tag_name);
if ($contents === false)
{
if (@$this->lost_start_tags[$tag_name] > 0)
{
$this->lost_start_tags[$tag_name]--;
}
else
{
$this->stack[] = Array(
BBCODE_STACK_TOKEN => BBCODE_TEXT,
BBCODE_STACK_TEXT => $this->FixupOutput($this->lexer->text),
BBCODE_STACK_TAG => false,
BBCODE_STACK_CLASS => $this->current_class,
);
}
return;
}
$start_tag_node = array_pop($this->stack);
$start_tag_params = $start_tag_node[BBCODE_STACK_TAG];
$this->Internal_ComputeCurrentClass();
$this->Internal_CleanupWSByPoppingStack(@$this->tag_rules[$tag_name]['before_tag'], $this->stack);
$start_tag_params['_endtag'] = $tag_params['_tag'];
$start_tag_params['_hasend'] = true;
$output = $this->DoTag(BBCODE_OUTPUT, $tag_name, @$start_tag_params['_default'],
$start_tag_params, $contents);
$this->Internal_CleanupWSByEatingInput(@$this->tag_rules[$tag_name]['after_endtag']);
$this->stack[] = Array(
BBCODE_STACK_TOKEN => BBCODE_TEXT,
BBCODE_STACK_TEXT => $output,
BBCODE_STACK_TAG => false,
BBCODE_STACK_CLASS => $this->current_class,
);
}
function Parse($string)
{
$this->lexer = new BBCodeLexer($string, $this->tag_marker);
$this->lexer->debug = $this->debug;
$old_output_limit = $this->output_limit;
/** HACK >
* if ($this->output_limit > 0) {
* if (strlen($string) < $this->output_limit) {
* $this->output_limit = 0;
* }
* else if ($this->limit_precision > 0) {
* $guess_length = $this->lexer->GuessTextLength();
* if ($guess_length < $this->output_limit * ($this->limit_precision + 1.0)) {
* $this->output_limit = 0;
* }
* else {
* }
* }
* }
* < HACK */
$this->stack = Array();
$this->start_tags = Array();
$this->lost_start_tags = Array();
$this->text_length = 0;
$this->was_limited = false;
if (strlen($this->pre_trim) > 0)
{
$this->Internal_CleanupWSByEatingInput($this->pre_trim);
}
$newline = $this->plain_mode ? "\n" : "<br />\n";
while (true)
{
if (($token_type = $this->lexer->NextToken()) == BBCODE_EOI)
{
break;
}
switch ($token_type)
{
case BBCODE_TEXT:
if ($this->output_limit > 0
&& $this->text_length + strlen($this->lexer->text) >= $this->output_limit
)
{
$text = $this->Internal_LimitText($this->lexer->text,
$this->output_limit - $this->text_length);
if (strlen($text) > 0)
{
$this->text_length += strlen($text);
$this->stack[] = Array(
BBCODE_STACK_TOKEN => BBCODE_TEXT,
BBCODE_STACK_TEXT => $this->FixupOutput($text),
BBCODE_STACK_TAG => false,
BBCODE_STACK_CLASS => $this->current_class,
);
}
$this->Internal_DoLimit();
break 2;
}
$this->text_length += strlen($this->lexer->text);
$this->stack[] = Array(
BBCODE_STACK_TOKEN => BBCODE_TEXT,
BBCODE_STACK_TEXT => $this->FixupOutput($this->lexer->text),
BBCODE_STACK_TAG => false,
BBCODE_STACK_CLASS => $this->current_class,
);
break;
case BBCODE_WS:
if ($this->output_limit > 0
&& $this->text_length + strlen($this->lexer->text) >= $this->output_limit
)
{
$this->Internal_DoLimit();
break 2;
}
$this->text_length += strlen($this->lexer->text);
$this->stack[] = Array(
BBCODE_STACK_TOKEN => BBCODE_WS,
BBCODE_STACK_TEXT => $this->lexer->text,
BBCODE_STACK_TAG => false,
BBCODE_STACK_CLASS => $this->current_class,
);
break;
case BBCODE_NL:
if ($this->ignore_newlines)
{
if ($this->output_limit > 0
&& $this->text_length + 1 >= $this->output_limit
)
{
$this->Internal_DoLimit();
break 2;
}
$this->text_length += 1;
$this->stack[] = Array(
BBCODE_STACK_TOKEN => BBCODE_WS,
BBCODE_STACK_TEXT => "\n",
BBCODE_STACK_TAG => false,
BBCODE_STACK_CLASS => $this->current_class,
);
}
else
{
$this->Internal_CleanupWSByPoppingStack("s", $this->stack);
if ($this->output_limit > 0
&& $this->text_length + 1 >= $this->output_limit
)
{
$this->Internal_DoLimit();
break 2;
}
$this->text_length += 1;
$this->stack[] = Array(
BBCODE_STACK_TOKEN => BBCODE_NL,
BBCODE_STACK_TEXT => $newline,
BBCODE_STACK_TAG => false,
BBCODE_STACK_CLASS => $this->current_class,
);
$this->Internal_CleanupWSByEatingInput("s");
}
break;
case BBCODE_TAG:
$this->Internal_ParseStartTagToken();
break;
case BBCODE_ENDTAG:
$this->Internal_ParseEndTagToken();
break;
default:
break;
}
}
if (strlen($this->post_trim) > 0)
{
$this->Internal_CleanupWSByPoppingStack($this->post_trim, $this->stack);
}
$result = $this->Internal_GenerateOutput(0);
$result = $this->Internal_CollectTextReverse($result, count($result) - 1);
$this->output_limit = $old_output_limit;
if ($this->plain_mode)
{
$result = preg_replace("/[\\x00-\\x09\\x0B-\\x20]+/", " ", $result);
$result = preg_replace("/(?:[\\x20]*\\n){2,}[\\x20]*/", "\n\n", $result);
$result = trim($result);
}
return $result;
}
}