Парсер BBCode на PHP

nerezus

Вселенский отказник
> а зачем?

Чтобы использовать в своем проекте. Мой проект не на пхп. А по xmlrpc и т.д. не хочется =\

Перерыл десяток парсеров - все ппц убогие. Сплошные XSS.
 

ZigFreeD

Новичок
Сомневаюсь что будет на си :(

-~{}~ 12.05.07 23:32:

tashkentchi, не подскажешь... в новой версии xBBEditor-а можно будет указать в настройках какие смайлы указывать в нем?
Просто я хочу потом свой пакет смайлов прикрутить к нему...
 

tashkentchi

Новичок
ZigFreeD, спасибо за смайлы. Щас залью на xbb.uz для скачивания. Настройки организую.

Только со временем у меня проблема. Работы привалило, - не продыхнуть. Если не пашешь, - значит спишь :) Не то чтоб чего-то серьезное делать, но даже элементарно доки дописать времени нет.

Потому и реализацию на си незнаю, когда писать буду. Разве что найдется другой активист, который напишет ее для всех.

nerezus, видел простой пример, как заюзать GeSHi из под ASP. Аналогично можно сделать для чего угодно, в т.ч. и для xBB под ASP, C и чего угодно. Если интересно, можешь посмотреть пример здесь: http://forum.pc.uz/viewtopic.php?f=15&t=6
Не сказать, что красивое решение, но элементарное и рабочее. + К нему можно посоветовать кэширование сгенерированного хтмла.
 

ZigFreeD

Новичок
Привет!
Не знаю исправил ли ты это в новой версии...
Можешь исправить чтобы в xBBEditor картинки кнопок грузились с preload? а то наводя на важдую кнопку ждешь пока она загрузится.. а если бы она сразу прогружалась было бы приятнее...
 

DeadLy

Новичок
Решил отказатся от этого парсера!
Вроде он и хороший, но когда он начинает парсить текст в цикле - получается время очень большое на выполнение всех операци, у меня на локалке это около 3-4 секунд, а при помощи preg_replace() около 0,20-0,35 сек.

Я понял что мне такой бешеной функциональности не надо поэтому будет правильно выбрать обычные регулярные выражения
 

Bakti9rov

!*|=?
У меня есть решение ВВ-коды в несколько сотен строчек, на скорость вроде не жалуюсь. Кому скинуть? :)
 

tashkentchi

Новичок
DeadLy, не буду спорить. Одним нужна скорость на простых задачах, другим - на сложных. Следует соответственно выбирать инструментарий.
 

nem0x

Новичок
Уф, зарегился наконец.
Ребята, кто знает как установить xBB v.0.28 на e107 ?
 

tashkentchi

Новичок
Так же как 0.27, 0.26 и т.п. :) Различий в установке нет.
Установка во всех версиях такова:
1. Распаковать архив куда-нибудь в публик-хтмл
2. В рабочий скрипт вставить
PHP:
require_once 'ваш/путь/bbcode/bbcode.lib.php';
После этого можно юзать API.

Пожалуй единственное препятствие для успешной инсталляции, - недоступность смайлов и едитора по хттп, например, в случае мод-рерайта.

Что касается e107, то я с ним не работал и его специфику не знаю. Если опишите подробности проблемы, попробуем что-нибудь сообразить.
 

nem0x

Новичок
Автор оригинала: tashkentchi
Так же как 0.27, 0.26 и т.п. :) Различий в установке нет.
Установка во всех версиях такова:
1. Распаковать архив куда-нибудь в публик-хтмл
2. В рабочий скрипт вставить
PHP:
require_once 'ваш/путь/bbcode/bbcode.lib.php';
После этого можно юзать API.

Пожалуй единственное препятствие для успешной инсталляции, - недоступность смайлов и едитора по хттп, например, в случае мод-рерайта.

Что касается e107, то я с ним не работал и его специфику не знаю. Если опишите подробности проблемы, попробуем что-нибудь сообразить.
http://e107.org.ru/
http://e107.org/

Некоторые вопросы:
Что такое parsing?
  • Что такое parsing?
  • Юзать API - какое и что под этим подразумевается
В e107 я нашёл скрипт bbcode_handler.php, а в нём функцию parseBBcodes(), которая находится в классе e_bbcode
PHP:
  function parseBBCodes($value, $p_ID, $force_lower = 'default')
  {
	global $postID;
	$postID = $p_ID;

  if (strlen($value) <= 6) return $value;     // Don't waste time on trivia!
  if ($force_lower == 'default') $force_lower = TRUE;	// Set the default behaviour if not overridden
  $code_stack = array();				// Stack for unprocessed bbcodes and text
  $unmatch_stack = array();				// Stack for unmatched bbcodes
  $result = '';							// Accumulates fully processed text
  $stacktext = '';						// Accumulates text which might be subject to one or more bbcodes

  $content = preg_split('#(\[(?:\w|/\w).*?\])#mis', $value, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE );
  
  foreach ($content as $cont)
  {  // Each chunk is either a bbcode or a piece of text
    $is_proc = FALSE;
    while (!$is_proc)
	{
	  $oddtext = '';
      if ($cont[0] == '[')
	  {  // We've got a bbcode - split it up and process it
		$pattern = '#^\[(/?)([A-Za-z]+)(\d*)([=:]?)(.*?)]$#i';
		// $matches[0] - same as the input text
		// $matches[1] - '/' for a closing tag. Otherwise empty string
		// $matches[2] - the bbcode word
		// $matches[3] - any digits immediately following the bbcode word
		// $matches[4] - '=' or ':' according to the separator used
		// $matches[5] - any parameter
		$match_count = preg_match($pattern,$cont,$matches);
	    $bbparam = $matches[5];
        $bbword = $matches[2];
	    if (($bbword) && ($bbword == trim($bbword)))
	    {  // Got a code to process here
		  if ($force_lower) $bbword = strtolower($bbword);
		  if ($matches[1] == '/')
		  {  // Closing code to process
		    $found = FALSE;
		    $i = 0;
		    while ($i < count($code_stack))
		    {     // See if code is anywhere on the stack. 
		      if (($code_stack[$i]['type'] == 'bbcode') && ($code_stack[$i]['code'] == $bbword) && ($code_stack[0]['numbers'] == $matches[3]))
		      {
		        $found = TRUE;
			    break;
		      }
		      $i++;
		    }
		
		    if ($found)
		    {
		      $found = FALSE;   // Use as 'done' variable now
			  // Code is on stack - $i has index number. Process text, discard unmatched open codes, process 'our' code
			  while ($i > 0) { $unmatch_stack[] = array_shift($code_stack); $i--; }    // Get required code to top of stack
			  
			  // Pull it off using array_shift - this keeps it as a zero-based array, newest first.
			  while (!$found && (count($code_stack) != 0))
			  {
		        switch ($code_stack[0]['type'])
			    {
			      case 'text' :
			        $stacktext = $code_stack[0]['code'].$stacktext;   // Need to insert text at front
				    array_shift($code_stack);
			        break;
			      case 'bbcode' :
			        if (($code_stack[0]['code'] == $bbword) && ($code_stack[0]['numbers'] == $matches[3]))
				    {
				      $stacktext = $this->proc_bbcode($bbword,$code_stack[0]['param'],$stacktext,$bbparam);
				      array_shift($code_stack);
				      // Intentionally don't terminate here - may be some text we can clean up
				      $bbword='';    // Necessary to make sure we don't double process if several instances on stack
					  while (count($unmatch_stack) != 0) { array_unshift($code_stack,array_pop($unmatch_stack));  }
				    }
				    else
				    {
					  {
				        $found = TRUE;  // Terminate on unmatched bbcode
					  }
				    }
			        break;
			    }
			    if (count($code_stack) == 0)
			    {
			      $result .= $stacktext;
			      $stacktext = '';
			      $found = TRUE;
			    }
		      }
	          $is_proc = TRUE;
	        }
		  }
		  else
		  {  // Opening code to process
		     // If its a single code, we can process it now. Otherwise just stack the value
		    if (array_key_exists('_'.$bbword,$this->bbLocation))
		    {  // Single code to process
	          $stacktext .= $this->proc_bbcode('_'.$bbword);
			  $is_proc = TRUE;
		    }
		    elseif (array_key_exists($bbword,$this->bbLocation))
		    {
		      if ($stacktext != '')
			  { // Stack the text we've accumulated so far
			    array_unshift($code_stack,array('type' => 'text','code' => $stacktext));
			    $stacktext = '';
			  }
	          array_unshift($code_stack,array('type' => 'bbcode','code' => $bbword, 'numbers'=> $matches[3], 'param'=>$bbparam));
	          $is_proc = TRUE;
		    }
	      }
	    }
		// Next lines could be deleted - but gives better rejection of 'stray' opening brackets
		if ((!$is_proc) && (($temp = strrpos($cont,"[")) !== 0)) 
		{
		  $oddtext = substr($cont,0,$temp);
		  $cont = substr($cont,$temp);
		}
	  }
	
	  if (!$is_proc)
	  {  // We've got some text between bbcodes (or possibly text in front of a bbcode)
	    if ($oddtext == '') { $oddtext = $cont; $is_proc = TRUE; }
	    if (count($code_stack) == 0)
	    {  // Can just add text to answer
	      $result .= $oddtext;
	    }
	    else
	    {  // Add to accumulator at this level
	      $stacktext .= $oddtext;
	    }
      }
	}
  }

// Basically done - just tidy up now  
  // If there's still anything on the stack, we need to process it
  while (count($code_stack) != 0)
  {
	switch ($code_stack[0]['type'])
	{
	  case 'text' :
	    $stacktext = $code_stack[0]['code'].$stacktext;   // Need to insert text at front
		array_shift($code_stack);
	    break;
	  case 'bbcode' :
	    $stacktext = '['.$code_stack[0]['code'].']'.$stacktext;   // To discard unmatched codes, delete this line
		array_shift($code_stack);  		// Just discard any unmatched bbcodes
		break;
	}
  }
  $result .= $stacktext; 
  return $result;
  }
Как я понял, мне надо подредактить эту функцию. Пробовал вставлять код xbb в некоторые места = вообще ничо не пахало.
 

tashkentchi

Новичок
Что такое parsing?
http://www.google.com/search?q=parsing
Юзать API - какое и что под этим подразумевается
http://xbb.uz/?part=api
Как я понял, мне надо подредактить эту функцию. Пробовал вставлять код xbb в некоторые места = вообще ничо не пахало.
Попробуй так:
PHP:
require_once 'ваш/путь/bbcode/bbcode.lib.php';

...

function parseBBCodes($value, $p_ID, $force_lower = 'default') {
    global $postID;
    $postID = $p_ID;

    $bb = new bbcode($value);
    return $bb->get_html();
}
 

ZigFreeD

Новичок
tashkentchi
Привет! Как работа продвигается над следующей версией? ;)
 

tashkentchi

Новичок
Привет, ZigFreeD. Никак не продвигается. Работа все время отнимает. Но щас я ее скокато продвину :)
 

SukhovPro

Новичок
Привет, решил попробывать фмшку возникло пару вопросав:

1. Какаято некоректная замена символов напримр "!" (знак воскл) на &amp;#33;
2. Когда векс подгружаеться страницка прыгает в место фейса, например в форума в низ
3. Есть пожелание по фейсу, это два типа 1. краткий 2. полный, думаю многим пригодиться.
3. Есть пожелание при генерации ссылок добавит флаг - просто ссылки или ссылки обрамлять noindex noflo
 

tashkentchi

Новичок
1. Какаято некоректная замена символов напримр "!" (знак воскл) на &#33;
Не воспроизводится.
2. Когда векс подгружаеться страницка прыгает в место фейса, например в форума в низ
Воспроизводится только в опере. Лечится жаваскриптом:
Код:
if (document.body.scrollTop) {
    var x = document.body.scrollLeft;
    var y = document.body.scrollTop;
} else {
    var y = 0;
}
...
if (y && window.scrollTo) { // для Opera
    window.scrollTo(x, y);
}
Вместо троеточия должен стоять код, который приводит к прыганью. В очередной версии внесу эту поправку в код.
3. Есть пожелание по фейсу, это два типа 1. краткий 2. полный, думаю многим пригодиться.
Принимаю.
3. Есть пожелание при генерации ссылок добавит флаг - просто ссылки или ссылки обрамлять noindex noflo
Чтобы поменять формат вывода автоматических ссылок, обратите внимание на свойство bbcode::preg_autolinks, описание которого можно найти здесь: http://xbb.uz/?part=properties
Чтобы поменять формат вывода ссылок, заданных тегом [ url], исправьте файл bbcode/Xbb/Tags/A.php. Вместо
PHP:
return '<a '.$attr.'>'.parent::get_html($this -> tree).'</a>';
Вставьте
PHP:
return '<a '.$attr.' rel=”nofollow”>'.parent::get_html($this -> tree).'</a>';
Также добавлю этот код в очередную версию.
 

SukhovPro

Новичок
Не воспроизводится.
Да мой косяк, нашел, в системе cms сначала & преобрадовывался к 'amp'.

Воспроизводится только в опере. Лечится жаваскриптом:
Код:
if (document.body.scrollTop) {
    var x = document.body.scrollLeft;
    var y = document.body.scrollTop;
} else {
    var y = 0;
}
...
if (y && window.scrollTo) { // для Opera
    window.scrollTo(x, y);
}
Вместо троеточия должен стоять код, который приводит к прыганью. В очередной версии внесу эту поправку в код.
Попробую.

Чтобы поменять формат вывода автоматических ссылок, обратите внимание на свойство bbcode::preg_autolinks, описание которого можно найти здесь: http://xbb.uz/?part=properties
Чтобы поменять формат вывода ссылок, заданных тегом [ url], исправьте файл bbcode/Xbb/Tags/A.php. Вместо
PHP:
return '<a '.$attr.'>'.parent::get_html($this -> tree).'</a>';
Вставьте
PHP:
return '<a '.$attr.' rel=”nofollow”>'.parent::get_html($this -> tree).'</a>';
Также добавлю этот код в очередную версию.
Ну эт. понятно, уже поменял это было просто предложение внести в код.

Родился новый вопрос
Я аперегружаю обрасть редактора аяксом, как прравильно его снова переинициализировать, просто заново выполнить init не прокатыват, можно в коде поковыряться, но может уже извесно решение? Т.е. получаеться я удаляю textarea и создаю заново и надо натравить на него редактор.

-~{}~ 03.07.07 21:45:

Прикрутил к проекту team-info.net , пока местами кривовато, но насколько времени хватило.
 

tashkentchi

Новичок
:) Вот только разберусь с очередным авралом на работе, помогу кривизну исправить.
 

rkit

Новичок
tashkentchi
Очень хороший и полезный скрипт. Хорошая
работа!

У меня один вопрос.
Мне нужно все разрешить пару тэгов.
Вот.
У тебя вроде как разрешать нельзя (написать список
разрешенных тэгов)
а только исключать функцией
unset($bb->tags['tag']);
Я решил написать список тэгов, которые должны быть
исключены:
unset($bb->tags['table','tr','td']);
И это результатов не дало, может что не так делаю?
Была бы функция как типа strip_tags перечислить разрешенные
тэги...
 
Сверху