hacsoft
Junior Member | Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору Функция обработки BB-кодов однопроходная: Код: function protection ($text) // Замена опасных символов: { return str_replace (array("&", "'", "\"", "<", ">"), array("&", "'", """, "<", ">"), $text); } function check_url ($url) // Корректироваа URL-адреса: { return preg_match ("#^(http://|https://|ftp://|mailto #", $url) ? $url : $url = "http://" . str_replace (":", "%3A", $url); } $colors = array( "darkred" => 1, "red" => 1, "orange" => 1, "brown" => 1, "yellow" => 1, "green" => 1, "olive" => 1, "cyan" => 1, "cyan" => 1, "blue" => 1, "darkblue" => 1, "indigo" => 1, "violet" => 1, "white" => 1, "silver" => 1, "gray" => 1, "black" => 1); function bb_codes ($text, $smiles) // Обработка BB-кодов: { global $colors; $text = str_replace ("`", "'", $text); $codes = array(); $cnum = 0; $res = ""; $p = 0; while ( true ) { if ( ($l = strpos ($text, "[", $p)) === false ) { $res .= substr ($text, $p); break; } if ( ($r = strpos ($text, "]", $l)) === false ) { $res .= substr ($text, $p); break; } $res .= substr ($text, $p, $l - $p); $tag = substr ($text, $l + 1, $r - $l - 1); if ( ($e = strpos ($tag, "=")) !== false ) { $val = substr ($tag, $e + 1); $tag = substr ($tag, 0, $e); } else $val = ""; $c = $p = $r; while ( ($c = strpos ($text, "[/$tag]", $c + 1)) !== false && ($p = strpos ($text, "[$tag]", $p + 1)) !== false && $p < $c ); if ( $c === false ) { $res .= "["; $p = $l + 1; continue; } $con = substr ($text, $r + 1, $c - $r - 1); $err = true; if ( $tag === "b" ) { // Жирный: $con = "<b class=\"bb\">" . bb_codes ($con, $smiles) . "</b>"; $err = false; } elseif ( $tag === "i" ) { // Курсив: $con = "<i class=\"bb\">" . bb_codes ($con, $smiles) . "</i>"; $err = false; } elseif ( $tag === "u" ) { // Подчеркнутый: $con = "<u class=\"bb\">" . bb_codes ($con, $smiles) . "</u>"; $err = false; } elseif ( $tag === "center" ) { // По центру: $con = "<div align=\"center\" class=\"bb\">" . bb_codes ($con, $smiles) . "</div>"; $err = false; } elseif ( $tag === "right" ) { // По правому краю: $con = "<div align=\"right\" class=\"bb\">" . bb_codes ($con, $smiles) . "</div>"; $err = false; } elseif ( $tag === "color" ) { // Цвет шрифта: $val = strtolower ($val); if ( isset ($colors[$val]) || preg_match ("/^#[0-9a-f]{6}$/", $val) ) { $con = "<font color=\"$val\" class=\"bb\">" . bb_codes ($con, $smiles) . "</font>"; $err = false; } } elseif ( $tag === "size" ) { // Размер шрифта: if ( preg_match ("#^[1-7]$#", $val) ) { $con = "<font size=\"$val\" class=\"bb\">" . bb_codes ($con, $smiles) . "</font>"; $err = false; } } elseif ( $tag === "no" ) { // Не обрабатывать BB-коды: $con = nl2br (protection ($con)); $err = false; } elseif ( $tag === "code" ) { // Исходный код: if ( ! empty ($con) ) { $comment = protection (( empty ($val) ) ? "Code:" : "Code ($val):"); $con = protection ($con); $con = "<table width=\"90%\" class=\"code\"><tr><th>$comment</th></tr><tr><td><pre class=\"bb\">$con</pre></td></tr></table>"; } $err = false; } elseif ( $tag === "quote" ) { // Цитата: if (! empty ($con) ) { $comment = protection (( empty ($val) ) ? "Quote:" : "$val wrote:"); $con = "<table width=\"90%\" class=\"quote\"><tr><th>$comment</th></tr><tr><td>" . bb_codes ($con, $smiles) . "</td></tr></table>"; } $err = false; } elseif ( $tag === "img" ) { // Вставка картинки: if ( strpos ("?", $con) === false && preg_match ("#.(gif|png|jpg|jpeg|tiff)$#", $con) ) { $title = empty ($val) ? "" : " title=\"" . protection ($val) . "\""; $con = protection (check_url ($con)); $con = "<img src=\"$con\" alt=\"$con\"$title class=\"bb\" />"; $err = false; } } elseif ( $tag === "url" ) { // Вставка гиперссылки: $href = protection (check_url (empty ($val) ? $con : $val)); if ( ! empty ($val) ) $con = bb_codes ($con, $smiles); $con = "<a href=\"$href\" target=\"_blank\" class=\"bb\">$con</a>"; $err = false; } if ( $err === true ) { $res .= "["; $p = $l + 1; continue; } $cd = "`" . (++$cnum) . "`"; $codes[$cd] = $con; $res .= $cd; $p = $c + strlen ($tag) + 3; } // Подсветка ссылок: $prot = array ("http://", "https://", "ftp://", "www."); $ahref = array(); for ($i = 0; $i < count ($prot); $i++) { $p = 0; while ( true ) { $p = strpos ($res, $prot[$i], $p); if ( $p === false ) break; $url = $prot[$i]; $p += strlen ($url); while ( $p < strlen ($res) && preg_match ("([0-9a-zA-Z_\\-+%&?:@.\\=/#])", $res[$p]) ) $url .= $res[$p++]; $cd = "`" . (++$cnum) . "`"; $ahref[$url] = $cd; $url = protection ($url); $href = ( $prot[$i] === "www." ) ? "http://$url" : $url; $codes[$cd] = "<a href=\"$href\" target=\"_blank\" class=\"bb\">$url</a>"; } } $res = str_replace (array_keys ($ahref), array_values ($ahref), $res); // Замена смайликов: foreach ($smiles as $smile => $img) { $cd = "`" . (++$cnum) . "`"; $sm = protection ($smile); $codes[$cd] = "<img src=\"$img\" alt=\"$sm\" title=\"$sm\" class=\"smile\" />"; $smiles[$smile] = $cd; } $res = str_replace (array_keys ($smiles), array_values ($smiles), $res); return str_replace (array_keys ($codes), array_values ($codes), nl2br (protection ($res))); } | Доступны следующие псевдотеги: [b]text[/b] - жирный [i]text[/i] - курсив [u]text[/u] - подчеркнутый [center]text[/center] - по центру [right]text[/right] - справа [color=#ffffff]text[/color], [color=red]text[/color] - цвет текста [size=5]text[/size] - размер шрифта [code]text[/code], [code=Pascal]text[/code] - исходный код (нуждается в корректировки, определяется стилями) [quote]text[/quote], [quote=username]text[/quote] - цитата (определяется стилями) [img]src[/img], [img=title]src[/img] - картинка [url]href[/url], [url=href]text[/url] - ссылка [nо]text[/nо] - отмена действия BB-кодов. Автоматически подсвечиваются ссылки, начинающиеся с http://, https://, ftp://, www. Смайлики передавать в виде хэш-массива: ключи - мнемоника смайла, значение - путь к картинки. Работает не очень быстро, но корректно. Если ее модифицировать в двупроходную, то скорость будет хорошей. И вот функция, вырезающая все BB-коды из сообщения, оставляющая только текст: Код: function no_bb ($text, $smiles) // Удаление bb-кодов: { // Вырезаем блоки qoute и code: $remove = array ("quote", "code"); for ($i = 0; $i < count ($remove); $i++) { $l = 0; do { $l = $r = $p = strpos ($text, "[{$remove[$i]}", $l); if ( $l !== false ) { while ( ($r = strpos ($text, "[/{$remove[$i]}]", $r + 1)) !== false && ($p = strpos ($text, "[{$remove[$i]}", $p + 1)) !== false && $p < $r ); if ( $r !== false ) $text = substr ($text, 0, $l) . substr ($text, $r + strlen ($remove[$i]) + 3); } } while ( $l !== false ); } // Вырезаем смайлики: $text = str_replace (array_keys ($smiles), "", $text); // Вырезаем все псевдотеги: $l = 0; do { $l = strpos ($text, "[", $l); if ( $l !== false ) { $r = strpos ($text, "]", $l); if ( $r !== false ) $text = substr ($text, 0, $l) . substr ($text, $r + 1); } } while ( $l !== false && $r !== false ); return nl2br (protection ($text)); } |
|