Декабрь 19, 2019 Просмотры 252 просмотра

Парсер BBCode на PHP

Эта статья устарела. Предлагаемая в ней библиотека - тоже. Более совершенную версию библиотеки и документацию к ней найдете здесь

Реализовал класс на PHP для работы с BBCode. Предлагаю вашему вниманию. Он может быть использован в гостевых книгах, форумах, на досках объявлений и т.п. Данная статья целиком сверстана в BBCode и конвертирована в HTML с помощью описываемого класса.

Парсер реализован несколько отлично от аналогов. Обычно такие парсеры реализуются с помощью регулярных выражений. Этот же использует метод конечных автоматов. Имеет следующий плюс: как бы ни была богата и продвинута коллекция тегов, поддерживаемая в данной реализации, скорость обработки текстов будет постоянной, так как осуществляется за фиксированное число проходов. Коллекцию тегов можно увеличивать до бесконечности, а скрипт будет выполняться одинаково быстро. Скорость его работы зависит только от величины текста и от числа тегов, используемых в конкретном тексте, но не от числа всех возможных тегов и вариантов их написания. Скрипт не парсит текст многократно для каждого тега или варианта написания тега.

Использование в программах

Класс называется bbcode, поддерживает 30 тегов, "автоматические ссылки", смайлы. Коллекция тегов легко расширяема, смайлы - тем более. Well

Вот пример использования этого класса в PHP-коде:

$text
= '[b]Переменная с текстом BBCode: [i]Hello world![/i][/b]';
// Подключаем библиотеку с классом
include_once 'bbcode.lib.php';
// Создаем объект и распарсиваем $text
$bb = new bbcode($text);
// Конвертируем BBCode в HTML и выводим его
echo $bb -> get_html();
Все достаточно просто.
При инициализации объекта ему передается текст, содержащий BBCode. Метод get_html возвращает текст HTML, конвертированный из BBCode.

Стоит также обратить внимание на свойство syntax - массив, содержащий синтаксический разбор ББКода. Заполняется при инициализации объекта. Этот массив имеет следующую структуру:

Array
(
    ...
    [i] => Array  // [i] - целочисленный ключ начиная с 0
        (
            [type] => тип элемента: 'text', 'open', 'close' или 'open/close'
                      'text'  - элемент соответствует тексту между тегами
                      'open'  - элемент соответствует открывающему тегу
                      'close' - элемент соответствует закрывающему тегу
                      'open/close' - элемент соответствует закрытому тегу
                                     (например такому: [img="..." /])
            [str]  => строковое представление элемента: текст между тегами
                      или тег (например: '[FONT color=red size=+1]')
            [name] => имя тега. Всегда в нижнем регистре. Например: 'color'.
                      Значение [name] отсутствует для элементов типа 'text'
                      и может быть пустой строкой для элементов типа
                      'close'. В последнем случае элемент будет
                      соответствовать тегу '[/]', который будет считаться
                      закрывающим для последнего незакрытого перед ним.
            [attrib] => Array         // Это значение существует только для
                (                     // элементов типов 'open' и
                    ...               // 'open/close'
                    ...
                    [имя атрибута] => значение атрибута. Например:
                    ...               [color] => red
                                      Имя атрибута всегда в нижнем регистре.
                                      Значение атрибута может быть пустой
                                      строкой. Имя тега тоже присутствует в
                                      списке атрибутов. Это для того, чтобы
                                      можно было работать, например, с
                                      такими тегами - [color="#555555"]
                )
            [layout] => Array                 // Это значение несуществует
                (                             // для элементов типа 'text'.
                    [0] => Array              // Массив содержит пары
                        (                     // ( тип строки , строка )
                            [0] => 0          // Типы могут быть следующие:
                            [1] => [          // 0 - скобка ('[' или ']')
                        )                     // 1 - слэш '/'
                    ...                       // 2 - имя тега
                    [i] => Array              //     (например - 'FONT')
                        (                     // 3 - знак '='
                            [0] => тип строки // 4 - строка из пробельных
                            [1] => строка     //     символов
                        )                     // 5 - кавычка или апостроф,
                    ...                       //     ограничивающая значение
                                              //     атрибута
                )                             // 6 - имя атрибута
        )                                     // 7 - значение атрибута
    ...
)
Свойство syntax может помочь вам организовать подсветку ББКода или просто вырезать все теги из текста.

Подробно ознакомиться со свойствами и методами класса bbcode вы можете по его исходному коду Very we! Он хорошо прокомментирован.

Общие сведения о тегах

  1. Названия тегов и атрибутов не зависят от регистра. Например, [font=Arial size=+1], [FONT=Arial SIZE=+1] и [FoNt=Arial SiZe=+1] - равнозначны.

  2. Значения атрибутов могут быть закавычены "так" и 'так', либо никак не закавычены. Следующие конструкции равнозначны: [google="BBCode"], [google='BBCode'], [google=BBCode]. Следующие конструкции НЕ равнозначны: [google="Поддержка BBCode"], [google=Поддержка BBCode]. Последний вариант будет интерпретирован скриптом как [google="Поддержка" BBCode=""].

  3. Теги могут быть вложенными. Но те из них, которые создают элементы блочного типа (такие как [h1] или [table]), не могут быть вложены в строчные теги (такие как [i] или [color]). Строчные элементы закрываются, если начинается блочный.

  4. Теги должны быть правильно вложены. Неправильный код "[b][i]текст[/b][/i]" будет интерпретирован скриптом как "[b][i]текст[/i][/b][/i]"

  5. В данной реализации BBCode поддерживаются закрывающие теги вида [/]. Такой тег закрывает последний незакрытый тег. Например, [b]текст[/b] равнозначно [b]текст[/]. Тем не менее рекомендую пользоваться именно первой формой написания. Attention Тогда, в случае нагромождения вложенных тегов, вам будет легче ориентроваться в коде. Кроме того, первая форма написания позволяет скрипту более корректно обрабатывать пользовательские ошибки.

  6. Поддерживается закрытие тега способом [тег /]. Например, конструкции [url name=top][/url] и [url name=top /] равнозначны.

  7. В некоторых случаях можно не писать закрывающий тег. Например, тег [tr] (строка таблицы), будет автоматически закрыт, как только встретится очередной [tr] или закрывающий тег [/table]. Тег [hr] вообще не имеет закрывающего, интерпретируется скриптом как [hr/]. О поведении конкретных тегов смотрите их описания.

  8. При конвертации ББКода в HTML сохраняется форматирование пробелами. Т.е. все двойные пробелы переводятся в '&nbsp;&nbsp;', все переводы строк заменяются на '<br />'. Однако вокруг некоторых элементов (таких как [h1]) игнорируются 1-2 перевода строк, так как эти элементы сами по себе создают дополнительные отступы. Это сделано для того, чтобы по возможности приблизить визуальное представление HTML к исходному ББкоду.

Список тегов

  1. [*] - аналог HTML-ного <li>. Может содержаться только в теге [list]. Автоматически закрывается, если начинается очередной [*] или если закрывается [list]. При конвертации переводится в <li class="bb">. Смотрите примеры в описании [list].

  2. [align] - выравниване текста по левому ([align=left]) или правому ([align=right]) краю, по центру ([align=center]) или по ширине ([align=justify]). При конвертации переводится в <div align="...">. Пример: "[align=right]Текст, выровненный по правому краю.[/align]". Результат:
    Текст, выровненный по правому краю.
  3. [b] - аналог HTML-ного <b>. Пример: "[b]текст[/b]". Результат: "текст".

  4. [caption] - аналог HTML-ного <caption> (заголовок таблицы). Может содержаться только в теге [table]. При конвертации переводится в <caption class="bb">. Смотрите пример в описании [table].

  5. [code] - тег для программных кодов, кодов разметки и т.п. При конвертации переводится в <pre class="bb">. Внутри [code] игнорируются ББ-теги и смайлики, не работают "автоматические ссылки". Пример:
    [code]
    // Функция - обработчик тега "code"
    function code_2html($elem) {
        $str = '<pre class="bb">';
        foreach ($elem['val'] as $item) {
            if ('item'==$item['type']) { continue; }
            $str .= htmlspecialchars($item['str']);
        }
        $str .= '</pre>';
        return $str;
    }
    [/code]
    Результат:
    // Функция - обработчик тега "code"
    function code_2html($elem) {
        $str = '<pre class="bb">';
        foreach ($elem['val'] as $item) {
            if ('item'==$item['type']) { continue; }
            $str .= htmlspecialchars($item['str']);
        }
        $str .= '</pre>';
        return $str;
    }
    
  6. [color] - тег для цветового выделения текста. При конвертации переводится в <font color="...">. Пример: "[color=red]текст[/color]". Результат: "текст".

  7. [email] - тег для создания гиперссылки e-mail. При конвертации переводится в <a class="bb_email" href="mailto:...">...</a>. Поддерживает также атрибуты title, name и target, аналогичные соответствующим в HTML. Примеры:

    Код Результат
    [email]dima@pc.uz[/email] dima@pc.uz
    [email=dima@pc.uz title="Мой ящик"]Мой ящик[/email] Мой ящик
  8. [font] - аналог HTML-ного <font>. Используется для установки шрифта. Поддерживает также атрибуты color и size. Примеры:

    Код Результат
    [font=Arial]текст[/font] текст
    [font=Verdana color=red size=+2]текст[/font] текст
  9. [google] - тег для создания ссылки на Google. При конвертации переводится в <a class="bb_google" href="http://www.google.com/search?q=Запрос">. Поддерживает также атрибуты title, name и target. Пример: "[google=BBCode target=_blank]Спроси Гугл про ББКод[/google]". Результат: "Спроси Гугл про ББКод".

  10. [h1] - аналог HTML-ного <h1>. При конвертации переводится в <h1 class="bb">. Поддерживает атрибут align. Пример: "[h1 align=center]текст[/h1]". Результат:

    текст

  11. [h2] - аналог HTML-ного <h2>. При конвертации переводится в <h2 class="bb">. Поддерживает атрибут align. Пример: "[h2 align=center]текст[/h2]". Результат:

    текст

  12. [h3] - аналог HTML-ного <h3>. При конвертации переводится в <h3 class="bb">. Поддерживает атрибут align. Пример: "[h3 align=center]текст[/h3]". Результат:

    текст

  13. [hr] - аналог HTML-ного <hr>. При конвертации переводится в <hr class="bb" />. Пример: "[hr]". Результат:

  14. [i] - аналог HTML-ного <i>. Пример: "[i]текст[/i]". Результат: "текст".

  15. [img] - аналог HTML-ного <img>. Поддерживает атрибуты width, height и border. Примеры:

    Код Результат
    [img]http://www.pc.uz/files/images/pcuz_1.gif[/img]  
    [img width=116 height=22]http://www.pc.uz/files/images/pcuz_1.gif[/img]  
  16. [list] - тег для создания списка. Аналог HTML-ных <ul> и <ol>. При конвертации переводится в <ul class="bb"> или в <ol class="bb" type="...">. Единственный вложенный тег - [*], который в свою очередь может иметь вложенные теги. Примеры:

    Код Результат Код Результат Код Результат
    [list]
    [*]Раз
    [*]Два
    [*]Три
    [/list]
    • Раз
    • Два
    • Три
    [list=1]
    [*]Раз
    [*]Два
    [*]Три
    [/list]
    1. Раз
    2. Два
    3. Три
    [list=a]
    [*]Раз
    [*]Два
    [*]Три
    [/list]
    1. Раз
    2. Два
    3. Три
  17. [nobb] - тег, внутри которого не происходит конвертации ББКода в HTML, не работают "автоматические ссылки" и не вставляются смайлы. Пример: "[nobb][b]ББКод[/b] со смайлом :)[/nobb]". Результат: "[b]ББКод[/b] со смайлом :)".

    Должен предупредить, что неоднозначность во вложенности тегов может привести к неожидавшимся результатам. Например,
    код
    [nobb] текст1 [/nobb] текст2 [/nobb]
    будет интерпретирован скриптом так:
    [nobb] текст1 [/nobb] текст2 [/nobb]
    Код
    [b] текст1 [nobb] текст2 [/b] текст3 [/nobb] текст4 [/b]
    будет интерпретирован скриптом так:
    [b] текст1 [nobb] текст2 [/nobb][/b] текст3 [/nobb] текст4 [/b]
  18. [php] - тег, подсвечивающий код PHP. При конвертации посвеченный код вставляется в <div class="php">. Пример:
    [php]<?php
    // Функция - обработчик тега "php"
    function php_2html($elem) {
        $str = '';
        foreach ($elem['val'] as $item) {
            if ('text'==$item['type']) { $str .= $item['str']; }
        }
        if (false !== strpos($str,'<?')) {
            $str = highlight_string($str, true);
        } else {
            $str = '<?php '.$str.' ?>';
            $str = highlight_string($str, true);
            $str = str_replace('&lt;?php ', '', $str);
            $str = str_replace('&lt;?php&nbsp;', '', $str);
            $str = str_replace('<font color="#0000BB">?&gt;</font>', '', $str);
        }
        return '<div class="php">'.$str.'</div>';
    }
    ?>[/php]
    Результат:
    <?php
    // Функция - обработчик тега "php"
    function php_2html($elem) {
        
    $str = '';
        foreach (
    $elem['val'] as $item) {
            if (
    'text'==$item['type']) { $str .= $item['str']; }
        }
        if (
    false !== strpos($str,'<?')) {
            
    $str = highlight_string($str, true);
        } else {
            
    $str = '<?php '.$str.' ?>';
            
    $str = highlight_string($str, true);
            
    $str = str_replace('&lt;?php ', '', $str);
            
    $str = str_replace('&lt;?php&nbsp;', '', $str);
            
    $str = str_replace('<font color="#0000BB">?&gt;</font>', '', $str);
        }
        return
    '<div class="php">'.$str.'</div>';
    }
    ?>
  19. [quote] - Цитата. При конвертации конструкция [quote=Автор]текст[/quote] переводится в

    <table width="90%" border="0" align="center" class="bb_quote">
    <tr><td class="author"><b>Автор писал(а):</b></td></tr>
    <tr><td class="quote">текст</td></tr></table>


    Вот так это выглядит:

    Автор писал(а):
    текст

    Автора указывать необязательно. Вы можете оформить цитаты более изощрено средствами CSS.

  20. [s] - зачеркивание текста. Аналог HTML-ного <s>. Пример: "[s]текст[/s]". Результат: "текст".

  21. [size] - тег для изменения размера шрифта. При конвертации переводится в <font size="...">. Пример: "[size=6]текст[/size]". Результат: "текст".

  22. [sub] - нижний индекс. Аналог HTML-ного <sub>. Пример: "[sub]текст[/sub]". Результат: "текст".

  23. [sup] - верхний индекс. Аналог HTML-ного <sup>. Пример: "[sup]текст[/sup]". Результат: "текст".

  24. [table] - таблица. Аналог HTML-ного <table>. При конвертации переводится в <table class="bb">. Поддерживаются атрибуты border, width, cellspacing, cellpadding и align, аналогичные HTML-ным. В [table] могут быть вложены только теги [caption] (заголовок) и [tr] (строка). Пример:

    [table border=1 align=center cellspacing=0 cellpadding=5]
    [caption]
    Заголовок[/caption]
    [tr]
    [th]
    Столбец 1
    [th]Столбец 2
    [tr]
    [td align=center colspan=2]
    Строка
    [/table]


    Результат:
    Заголовок
    Столбец 1 Столбец 2
    Строка
  25. [td] - ячейка таблицы. Аналог HTML-ного <td>. Может быть вложен только в [tr]. При конвертации переводится в <td class="bb">. Поддерживаются атрибуты width, height, align, valign и colspan, аналогичные HTML-ным. Пример использования смотрите выше.

  26. [th] - заголовок столбца таблицы. Аналог HTML-ного <th>. Может быть вложен только в [tr]. При конвертации переводится в <th class="bb">. Поддерживаются атрибуты width, height, align, valign и colspan, аналогичные HTML-ным. Пример использования смотрите выше.

  27. [tr] - строка таблицы. Аналог HTML-ного <tr>. Может быть вложен только в [table]. Может содержать только [th] и [td]. При конвертации переводится в <tr class="bb">. Пример использования смотрите выше.

  28. [tt] - стиль печатной машинки. Аналог HTML-ного <tt>. Пример: "[tt]текст[/tt]". Результат: "текст".

  29. [u] - подчеркнутый текст. Аналог HTML-ного <u>. Пример: "[u]текст[/u]". Результат: "текст".

  30. [url] - ссылка. Аналог HTML-ного <a>. Поддерживаются атрибуты title, name (для создания якорей) и target, аналогичные HTML-ным. Может быть использован в двух вариантах: "[url]адрес_ссылки[/url]" и "[url=адрес_ссылки]текст ссылки[/url]". Если адрес ссылки не начинается с одной из следующих строк - "http://", "https://", "ftp://", "file://", "#", "/", "?", "./" или "../", то слева к нему автоматом допишется "http://". Примеры:

    Код Результат
    [url target=_blank]www.pc.uz[/url] www.pc.uz
    [url=forum.pc.uz title="Хороший форум"]Форум сайта PC.UZ[/url] Форум сайта PC.UZ

    Код [url name=this /] создаст якорь в документе.

"Автоматические ссылки" и смайлики

Поддержка "автоматических ссылок" означает, что строки вида "http://какойто_uri", "https://какойто_uri", "ftp://какойто_uri", "www.какойто_uri" и "ящик@домен" автоматически конвертируются в соответствующие гиперссылки. Этого не происходит только для содержимого тегов [code] и [nobb].

Для работы со смайликами в классе bbcode предусмотрено свойство mnemonics, которое является массивом и должно содержать пары

'мнемоника' => 'ее замена'

Например: ':)' => '<img src="ulibka.gif" alt="Улыбка" />'

Сформируйте массив замен и положите его в mnemonics. Тогда ваши смайлики будут обрабатываться. Смайлики не будут вставляться в содержимое тегов [code] и [nobb]

Пример PHP-кода, устанавливающего набор смайликов:

$text
= 'Переменная [b]BBCode[/b] со смайликами: :) :D';
// Формируем список смайликов:
$smiles = array(
        
':)' => '<img src="smilies/2.gif" alt="Well" />',
        
':D' => '<img src="smilies/1.gif" alt="Very we!" />'
    
)
// Подключаем библиотеку с классом
include_once 'bbcode.lib.php';
// Создаем объект и распарсиваем $text
$bb = new bbcode($text);
// Задаем набор смайликов
$bb -> mnemonics = $smiles;
// Конвертируем BBCode в HTML и выводим его
echo $bb -> get_html();

Условия использования и инсталляция

Скрипт распространяется бесплатно по лицензии GNU v 2. Согласно этой лицензии вы можете свободно использовать, распространять и менять этот скрипт при условии, что ваши собственные программы, использующие этот скрипт также будут распространяться по лицензии GNU.

Если вас не устраивает эта публичная лицензия, обращайтесь ко мне (dima@pc.uz).

Инсталляция проста:
  • Скачайте zip-архив с библиотекой.
  • Распакуйте его куда-либо на своем сайте, поддерживающим PHP.
  • Наберите в адресной строке броузера: http://ваш.сайт/ваш/путь/bbcode/test.html. Это - демонстрационная фича. - Убедитесь, что скрипт работает.
  • В ваш рабочий скрипт вставьте строчку
    include_once 'ваш/путь/bbcode/bbcode.lib.php';
    Готово. Можете пользоваться библиотекой.
Скачать zip-архив со скриптом, тестами и набором смайликов можно здесь.

Успешной работы!

 

Дмитрий Скоробогатов 27.07.2006

Обсудить на форуме


Просмотры 252 просмотра

Статистика просмотров страницы:

  • за текущий месяц (Март 2024) - 13;
  • за прошлый месяц (Февраль 2024) - 15;
  • за последние 3 месяца (Декабрь 2023 - Февраль 2024) - 21;
  • за последний год (Март 2023 - Февраль 2024) - 94;

Отзывы

Админ
Отлично!
Март 28 Админ

Статьи и обзоры Все статьи

GT & Industrial Systems, LP, действующая в Узбекистане через зарегистрированное ...
В начале 2000-х мир киберспорта переживал свою золотую эпоху, а ...
Бухгалтерская программа 1C способствует успешному развитию бизнеса в условиях современной ...
Автоматизация бизнес-процессов и повышение эффективности компании с помощью программы 1С.