Парсер BBCode на PHP

tashkentchi

Новичок
Смайлик в вашем предыдущем сообщении ввел меня в заблуждение.

это не шутка. всё вполне реализуемо. просто нужно желание и время.
Я совершенно не сомневаюсь, что это возможно. Но это все равно будет похоже на шутку, пока вы не осветите два вопроса:

1. Насколько целесообразен конвертер XHTML -> BBCode, отрабатывающий на клиенте?

2. Есть ли у вас желание и время, чтобы его реализовать?
 

dark-demon

d(^-^)b
1. одному клиенту нужен бб-код, другом - маркдаун, третьему - вики-разметка. поэтому в базе проще хранить xml и при необходимости конвертить его в то, что надо. когда возникает такая необходимость? когда пользователь прочитал сообщение и хочет на него ответить. тут есть три варианта:
а) запрашиваем у сервера данные в нужно виде. на всех форумах так реализовано. но пользователю приходится ждать пока придут данные.
б) сразу высылать альтернативное представление для постов - много трафика
в) конвертить на клиенте. посты обычно сравнительно небольшие (особенно комментируемая часть), поэтому конвертация на среднестатистическом компе будет происходить гораздо быстрее, чем в случае (а)

2. конкретно в бб-код - скорее нет, чем да. мне больше импонирует висивиг как в гмыле.
 

BRat

o_0
dark-demon
ты бы сначала попробовал сам реализовать свою идею, прежде чем кому-то это предлагать. Возможно сам был понял, что глупость написал
 

кекс

Новичок
пытался достучаться до новой версии не вышло. в общем font face не обрабатывался, думал может там поправили.. ненашел. поправил
строки
PHP:
1143         $face = $elem['attrib']['font'];
1144        $attr = ' face="'.htmlspecialchars($face).'"';
меняем на
PHP:
        $face = isset($elem['attrib']['face']) ? $elem['attrib']['face'] : '';
        if ($face) { $attr .= ' face="'.htmlspecialchars($face).'"'; }
работает. http://www.racheev.ru/forum/view/101#877
 

tashkentchi

Новичок
Атрибут face не предусматривался. Тег font предполагает такое использование:

[ font=имя_шрифта]текст[/font ]

То есть указывается "атрибут" font. Так короче. Если же вам нужен еще и атрибут face, дублирующий font, то можно заюзать такой код:

PHP:
$face = $elem['attrib']['font'];
if (! $face) {
    $face = isset($elem['attrib']['face']) ? $elem['attrib']['face'] : '';
}
Праздник у нас сегодня. Сайт лежит, и до техподдержки не достучишься. Могу выслать последнюю версию на мыло, при условии, что выложите ее для скачивания. Мало ли чего с pc.uz-ом случится.

-~{}~ 21.03.07 16:56:

Или вот так:

PHP:
if (isset($elem['attrib']['face'])) {
    $face = $elem['attrib']['face'];
} else {
    $face = $elem['attrib']['font'];
}
А в текущей версии так:

PHP:
if (isset($this -> attrib['face'])) {
    $face = $this -> attrib['face'];
} else {
    $face = $this -> attrib['font'];
}
В этом виде вставлю его в очередную версию.

-~{}~ 22.03.07 17:30:

На http://prolib.ru/prog/web/bbcode/ вывешена демоверсия для моей либы. Кроме того, zip-архив с либой доступен для скачивания по адресу http://prolib.ru/prog/web/bbcode/xbb025.zip

Большое спасибо Whirlwind
 

Найч

Алгоритмик :-)
неплохой пример, однако

Fatal error: Maximum execution time of 30 seconds exceeded in /home/vhosts/prolib.ru/htdocs/prog/web/bbcode/bbcode.lib.php on line 271
 

tashkentchi

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

1. Заюзать "Подсветить BBCode". В этом случае вызывается всего 1-а функция. Работает быстро.

2. Урезать тестовый пример. Тогда можно будет выяснить, какой объем ббкода может быть зараз конвертирован на данной машине с данным "Maximum execution time".

Если есть идеи, как ускорить генерацию хтмл-а, буду очень признателен.
 

hermit_refined

Отшельник
кардинально поможет реализация на C.
но это, конечно, сократит кол-во потенциальных пользователей.
 

tashkentchi

Новичок
Порылся в коде, смог сократить время генерации хтмл-а на 10-15%. Кроме того, прикрутил к классу подсчет статистики по обрабатываемому ббкоду. Вот чего он мне выдает:

Страница формировалась 14.229476928711 секунд.

Время парсинга кода: 2.6878590583801 секунд.

Время генерации HTML-а: 11.494961977005 секунд.

Число тегов BBCode: 2424

Число уровней вложенности тегов BBCode: 8
Это на машине следующей конфигурации:

Pentium(R) 4, CPU 1.80GHz, 512 МБ ОЗУ
Windows XP Service Pack 2
Apache 2.2.3
PHP Version 5.2.0

to hermit_refined, C - это здорово. Займусь как нибудь. Пусть одна реализация будет для тех, кто имеет возможность хостом рулить, и одна реализация - для тех кто не может. Но все равно ее придется совершенствовать.

-~{}~ 23.03.07 01:44:

Немного пополню доку и выложу версию xBB 0.26
 

boombick

boombick.org
tashkentchi
Респект тебе огромнейший! Жду реализации на С с нетерпением
 

tashkentchi

Новичок
Спасибо.
C - это не скоро. Не могу ничего обещать.

-~{}~ 23.03.07 15:37:

Любопытное кино. Запустил щас тест под линухом и получилась такая картина:

Страница формировалась 4.5315351486206 секунд.

Время парсинга кода: 1.6640210151672 секунд.

Время генерации HTML-а: 0.51626777648926 секунд.

Число тегов BBCode: 2424

Число уровней вложенности тегов BBCode: 8
Конфигурация машины:

Intel(R) Pentium(R) 4 CPU 3.00GHz, 1024 МБ ОЗУ
Linux version 2.6.15-1.2054_FC5
Apache 2.0 Handler
PHP Version 5.1.2

То, что быстрее работает, - неудивительно. Но удивительно, что html здесь генерится в 3 раза быстрей, чем осуществлялся парсинг. А под виндой - в 4 раза медленей. Может кто прокомментировать?
 

hermit_refined

Отшельник
странно. для статистики - у меня под win XP, AMD 64 2.21GHz, 1Гб, php-cli 5.2.1 - распарсивается за 0.8, html генерируется за 0.4.
вообще, имеет смысл заняться профилированием с xdebug.
 

tashkentchi

Новичок
Есть гипотеза.
Поскольку парсинг реализован с помощью конечного автомата, - простого линейного алгоритма, то и мощность машины не очень сильно сказывается на скорости обработки: 2.7 сек против 1.7 сек.

А генерация html-a влечет за собой инициализацию десятков объектов, тысячи вызовов десятков функций. И здесь мощность машины уже сильно сказывается: 11.5 сек против 0.5 сек.

-~{}~ 23.03.07 20:45:

On Fri, 23 Mar 2007 14:55:55 +0300
Александр Глущенко <...> wrote:

> Приветствую вас дима, использую ваш класс xBB v. 0.24 и заметил очень
> нехорошую манеру неправильно обрабатывать линки..
>
> Например если скормить класу линк такого вида http://xzxzxzxzx.xz/ddd а
> дальше текст, то обработает он его так - <a
> href="http://xzxzxzxzx.xz/ddd&amp;nbsp;&amp;nbsp;fffff"
> target="_blank">http://xzxzxzxzx.xz/ddd&amp;nbsp;&amp;nbsp;а дальше текст</a>
> Т.е захватывает и следущий текст в линк. Очень хотелось бы узнать как
> поправить сие, т.к класс действительно хороший..
> --
> Александр Глущенко.
>

Дело в том, что скрипт сперва заменяет двойной пробел ' ' на '&amp;nbsp;&amp;nbsp;' а уже потом ищет и обрабатывает линки. Причем линком считает любую строку, которая начинается с 'http://' или 'https://' или 'ftp://' или 'www.' и заканчивается пробельным символом, запятой, кавычкой и т.п. Знак & может быть частью ссылки, поэтому тоже захватывается. Исправить можно так:

1. Найдите строки
PHP:
        $text = str_replace('  ', '&nbsp;&nbsp;', $text);
        if ($this -> autolinks) {
            $uri = "[\w\d-]+\.[\w\d-]+[^\s<\"\']*[^.,;\s<\"\'\)]+";
            $search = array(
                "'(.)((http|https|ftp)://".$uri.")'si",
                "'([^/])(www\.".$uri.")'si",
                "'([^\w\d-\.])([\w\d-\.]+@[\w\d-\.]+\.[\w]+[^.,;\s<\"\'\)]+)'si"
            );
            $replace = array(
                '$1<a href="$2" target="_blank">$2</a>',
                '$1<a href="http://$2" target="_blank">$2</a>',
                '$1<a href="mailto:$2">$2</a>'
            );
            $text = preg_replace($search, $replace, $text);
        }
2. Замените их на
PHP:
        if ($this -> autolinks) {
            $uri = "[\w\d-]+\.[\w\d-]+[^\s<\"\']*[^.,;\s<\"\'\)]+";
            $search = array(
                "'(.)((http|https|ftp)://".$uri.")'si",
                "'([^/])(www\.".$uri.")'si",
                "'([^\w\d-\.])([\w\d-\.]+@[\w\d-\.]+\.[\w]+[^.,;\s<\"\'\)]+)'si"
            );
            $replace = array(
                '$1<a href="$2" target="_blank">$2</a>',
                '$1<a href="http://$2" target="_blank">$2</a>',
                '$1<a href="mailto:$2">$2</a>'
            );
            $text = preg_replace($search, $replace, $text);
        }
        $text = str_replace('  ', '&nbsp;&nbsp;', $text);
Счастливо, Д.

-~{}~ 24.03.07 20:49:

У проекта xBB теперь собственный репозиторий, расположенный по адресу svn://svn.prolib.ru:3692

-~{}~ 24.03.07 20:51:

Это - усилиями Whirlwind

-~{}~ 25.03.07 14:50:

xBB версии 0.26

Отличается от 0.25 следующим:

1. Несколько оптимизирован код.

2. Добавлено свойство stat со статистикой по обрабатываемому BBCode (время парсинга, время генерации HTML-а, число тегов BBCode, максимальное число уровней вложенности).

3. Исправлено несколько багов.

4. Добавлено еще несколько мелких фичек (дополнительные атрибуты для anchor и font, добавление протокола svn:// в автоматические ссылки и т.п.).

5. Исправлена документация.

6. Переделан тестовый скрипт.

Скачать zip-архив со скриптом, тестами и набором смайликов можно здесь: http://www.pc.uz/files/illustrations/bbcode/xbb026-light.zip
 

dark-demon

d(^-^)b
Автор оригинала: BRat
dark-demon
ты бы сначала попробовал сам реализовать свою идею, прежде чем кому-то это предлагать. Возможно сам был понял, что глупость написал
буду безмерно благодарен, если укажешь, где в моих словах находятся глупости - постараюсь скорейшим образом исправить :D
 

SiMM

Новичок
> добавление протокола svn:// в автоматические ссылки
ИМХО, протоколы пора вынести в отдельную настройку - поскольку кроме всего прочего есть ещё irc://, dchub://, e2k://, nntp://, да и мало ли чего.
 

dark-demon

d(^-^)b
а можно просто все разрешить, кроме тех, которые выполняют скрипты...
 

tashkentchi

Новичок
В автоматических ссылках невозможно все разрешить. Иначе весь текст будет сплошной неправильной гиперссылкой.

А вот в теге url это имеет смысл. Но одна проблема. Там где юзер должен указать адрес ссылки, иногда пишут pc.uz вместо http://pc.uz и т.д. Сейчас такие пользовательские ошибки автоматом разруливаются. А если разрешить все, то как опознать ошибку?

-~{}~ 26.03.07 18:46:

dark-demon, последний пост я неподумав бросил. А если бы подумал, то догадался бы что "протокол" - это регулярка [\w\+]+:// (\+ - чтобы обрабатывались и такие протоколы, как svn+ssh). Так что твоя правда. Действительно так сделаю
 

ZigFreeD

Новичок
Тестил твой скрипт последний (0.26) и обнаружил что он выдает ошибку если в вызывающем скрипте нету функции getmicrotime() и далее функция прерывается :(
Хотя статистика нигде не запрашивается!!!
 
Сверху