diff -r c7c0fbc09788 -r 5e8dcbe22c24 web/wp-content/plugins/bbpress/includes/admin/parser.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/web/wp-content/plugins/bbpress/includes/admin/parser.php Tue Dec 04 18:43:10 2012 -0800 @@ -0,0 +1,2073 @@ + '\[', '<' => '<', '{' => '\{', '(' => '\(' ); +$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', +';D' => 'bigwink.gif', ';-D' => 'bigwink.gif', +':3' => 'smile3.gif', ':-3' => 'smile3.gif', +'=3' => 'smile3.gif', '=-3' => 'smile3.gif', +';3' => 'wink3.gif', ';-3' => 'wink3.gif', +'' => 'teeth.gif', '' => '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' => "", +'simple_end' => "", +'class' => 'inline', +'allow_in' => Array('listitem', 'block', 'columns', 'inline', 'link'), +'plain_start' => "", +'plain_end' => "", +), +'i' => Array( +'simple_start' => "", +'simple_end' => "", +'class' => 'inline', +'allow_in' => Array('listitem', 'block', 'columns', 'inline', 'link'), +'plain_start' => "", +'plain_end' => "", +), +'u' => Array( +'simple_start' => "", +'simple_end' => "", +'class' => 'inline', +'allow_in' => Array('listitem', 'block', 'columns', 'inline', 'link'), +'plain_start' => "", +'plain_end' => "", +), +'s' => Array( +'simple_start' => "", +'simple_end' => "", +'class' => 'inline', +'allow_in' => Array('listitem', 'block', 'columns', 'inline', 'link'), +'plain_start' => "", +'plain_end' => "", +), +'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' => '{$_content/v}', +'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' => "", +'simple_end' => "", +'class' => 'inline', +'allow_in' => Array('listitem', 'block', 'columns', 'inline', 'link'), +), +'sub' => Array( +'simple_start' => "", +'simple_end' => "", +'class' => 'inline', +'allow_in' => Array('listitem', 'block', 'columns', 'inline', 'link'), +), +'spoiler' => Array( +'simple_start' => "", +'simple_end' => "", +'class' => 'inline', +'allow_in' => Array('listitem', 'block', 'columns', 'inline', 'link'), +), +'acronym' => Array( +'mode' => BBCODE_MODE_ENHANCED, +'template' => '{$_content/v}', +'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' => "", +'plain_end' => "", +'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' => "", +'plain_end' => "", +'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' => "[", +'plain_end' => "]", +'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' => "
\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
\n", +'simple_end' => "\n
\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
\n", +'simple_end' => "\n
\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
\n", +'simple_end' => "\n
\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
\n", +'simple_end' => "\n
\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
\n", +'simple_end' => "\n
\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\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
\n
Code:
\n
{\$_content/v}
\n
\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' => "\nCode:\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' => "\nQuote:\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' => "
  • ", +'simple_end' => "
  • \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
    "; +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 '' . $content . ''; +} +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 '' . $content . ''; +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 "$content"; +} +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 "$content"; +} +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 "wiki_url}$name\" class=\"bbcode_wiki\">" +. htmlspecialchars($title) . ""; +} +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 "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 "\"""; +} +} +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 = "" . $title . ""; +} +} +else if (!is_string($default)) +$title = "Quote:"; +else $title = htmlspecialchars(trim($default)) . " wrote:"; +return "\n
    \n
    " +. $title . "
    \n
    " +. $content . "
    \n
    \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\n"; +else return "\n<$elem class=\"bbcode_list\">\n$content\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 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; + + +/* ADDED */ +// singleton instance +private static $instance; + +// private constructor function +// to prevent external instantiation +private 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 = '{$text/h}'; + $this->url_targetable = false; + $this->url_target = false; +} + +// getInstance method +public static function getInstance() +{ + if(!self::$instance) + { + self::$instance = new self(); + } + + return self::$instance; +} +/* ADDED */ + + +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
    \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/", "
    \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) { +if (!$this->detect_urls) { +$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 .= "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("/(?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); +if (!is_array($params)) $params = Array(); +$params['url'] = $url; +$params['link'] = $url; +$params['text'] = $token; +$output[$index] = $this->FillTemplate($this->url_pattern, $params); +} +$is_a_url = !$is_a_url; +} +} +return $output; +} +function FillTemplate($template, $insert_array, $default_array = Array()) { +$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 = ""; +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 .= ""; +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) { +if ($this->lexer->text == $end_tag) { +$end_tag_params = $this->lexer->tag; +break; +} +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; +} +$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; +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 { +} +} +} +$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" : "
    \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; +} +} +