Интернет, компьютеры, софт и прочий Hi-Tech

Подписаться через RSS2Email.ru

xBB портирован на Ruby

Не могу не похвастаться. Well Вчера (15.04.2008) на PHPClub-е прочел сообщение от Bakti9rov:

Как я понял, существует порт парсера на язык JavaScript (в минимуме, необходимом для подсветки).

Так вот, кому интересно, сделан порт парсера на язык Руби (Ruby).

Ссылка: http://code.google.com/p/rbbparser/

Пошел по ссылке и нашел там "rbbparser":

rBB является портом библиотеки xBB (http://xbb.uz) на язык Ruby.

Как оказалось, Well очень приятно видеть перевод своего произведения кода на иностранный другой язык:

# BB Code
# Port this from xBB (http://xbb.uz)

module BB
  module Tags
    @@tags = nil
    def Tags.get_all
      return @@tags unless @@tags.nil?

      path = File.dirname(__FILE__) + '/tags'
      Dir.entries(path).each do |f|
        require path + "/#{f}" if f =~ /^Tags\.(.*)\.rb$/
      end

      @@tags = {
        '*' => BB::Tags::Li,
        'url' => BB::Tags::A,
        'b' => BB::Tags::Simple,
        'big' => BB::Tags::Simple,
        'blockquote' => BB::Tags::Quote,
        'center' => BB::Tags::Align,
        'code' => BB::Tags::Code,
        'color' => BB::Tags::Color,
        'email' => BB::Tags::Email,
        'font' => BB::Tags::Font,
        'h1' => BB::Tags::P,
        'h2' => BB::Tags::P,
        'h3' => BB::Tags::P,
        'h4' => BB::Tags::P,
        'h5' => BB::Tags::P,
        'h6' => BB::Tags::P,
        'hr' => BB::Tags::Hr,
        'i' => BB::Tags::Simple,
        'img' => BB::Tags::Img,
        'justify' => BB::Tags::Align,
        'left' => BB::Tags::Align,
        'nobb' => BB::Tags::Nobb,
        'ol' => BB::Tags::List,
        'quote' => BB::Tags::Quote,
        'right' => BB::Tags::Align,
        's' => BB::Tags::Simple,
        'size' => BB::Tags::Size,
        'small' => BB::Tags::Simple,
        'sub' => BB::Tags::Simple,
        'sup' => BB::Tags::Simple,
        'tt' => BB::Tags::Simple,
        'u' => BB::Tags::Simple,
        'ul' => BB::Tags::List,
        'url' => BB::Tags::A
      }
    end

    @@children = nil
    def Tags.children
      return @@children unless @@children.nil?
      @@children = {
        'a'       => ['code','img'],
        'code'    => [],
        'hr'      => [],
        'img'     => [],
        'li'      => ['a', 'code', 'hr', 'img', 'ul'],
        'ul'      => ['li'],
      }
    end

    @@ends = nil
    def Tags.ends
      return @@ends unless @@ends.nil?
      @@ends = {
        'a' => [
          'a', 'hr', 'li', 'ul'
        ],
        'code' => [],
        'hr' => [
          'a', 'code', 'hr', 'img', 'li', 'ul'
        ],
        'img' => [
          'a', 'code', 'hr', 'img', 'li', 'ul'
        ],
        'li' => ['li'],
        'ul' => [],
      }
    end

    def Tags.get(tag)
      tag_class = Tags.get_all[tag]
      tag_class.new
    end
  end

  CHAR_TABLE = {
    '[' => 0,
    ']' => 1,
    '"' => 2,
    "'" => 3,
    "=" => 4,
    '/' => 5,
    ' ' => 6, "\t" => 6, "\n" => 6, "\r" => 6, "\0" => 6, "\v" => 6
  }

  TOKEN_TABLE = [
    [1,  0,  0,  0,  0,  0,  0,  0,  0 ],
    [2,  3,  3,  3,  3,  4,  3,  3,  5 ],
    [2,  3,  3,  3,  3,  4,  3,  3,  5 ],
    [1,  0,  0,  0,  0,  0,  0,  0,  0 ],
    [2,  6,  3,  3,  3,  3,  3,  3,  7 ],
    [2,  6,  3,  3,  8,  9, 10,  3,  3 ],
    [1,  0,  0,  0,  0,  0,  0,  0,  0 ],
    [2,  6,  3,  3,  3,  3,  3,  3,  3 ],
    [13, 13, 11, 12, 13, 13, 14, 13, 13],
    [2,  6,  3,  3,  3,  3,  3,  3,  3 ],
    [2,  6,  3,  3,  8,  9,  3,  15, 15],
    [16, 16, 17, 16, 16, 16, 16, 16, 16],
    [18, 18, 18, 17, 18, 18, 18, 18, 18],
    [19, 6,  19, 19, 19, 19, 17, 19, 19],
    [2,  3,  11, 12, 13, 13, 3,  13, 13],
    [2,  6,  3,  3,  8,  9,  10, 3,  3 ],
    [16, 16, 17, 16, 16, 16, 16, 16, 16],
    [2,  6,  3,  3,  3,  9,  20, 15, 15],
    [18, 18, 18, 17, 18, 18, 18, 18, 18],
    [19, 6,  19, 19, 19, 19, 20, 19, 19],
    [2,  6,  3,  3,  3,  9,  3,  15, 15]
  ]

  class Code
    attr_accessor :tag
    attr_accessor :attrib
    attr_accessor :tree

    attr_accessor :tags
    attr_accessor :mnemonics
    attr_accessor :autolinks
    attr_accessor :preg_autolinks

    attr_accessor :behavior
    attr_accessor :close

    attr_accessor :children
    attr_accessor :ends
    ... ну и т.д.

Возникает ощущение, что я этот язык немножко знаю. Well

Биржа долевых инвестиций SIMEX.

Последнее редактирование: 2008-04-17 14:46:47

Метки материала: xBB, rBB, rbbparser, Руби, Ruby, BBCode, PHPClub, Bakti9rov, парсер


5 комментариев

18.04.2008 12:33:06 #
Mozilla Firefox dima
Создал страницу для обсуждения BBCode: http://xbb.uz/bbcode/
Рад буду вашему участию. Со своей стороны обещаю как можно более полно изложить там свой опыт Well
17.04.2008 16:26:42 #
Mozilla Firefox Гость Bakti9rov
Согласен, валидность имеет большое значение.
 
Насчет спецификаций - не против. Well От этого выиграют обе стороны) Тут больше подходит слово "совместимость". Я не против "унифицикации" для начала, например, модели поведения тегов. То есть, согласен, семантика ВВ-тегов должна быть одинаковой. А выдачу HTML кастомизировать не представляет никакой сложности (заменить "b" на "strong" или добавить class="bb").
 
Получается так: алгоритм и основные фичи xBB перенесены на другой язык с другим синтаксисом, а по сути никаких кардинальных изменений в портированной версии - по сравнению с оригинальной версией - не было (разве что имена некоторых методов и переменных переименованы - так сказать "в духе руби"). Если же будут серьезные изменения в оригинале - например, в алгоритме парсинга (например добавится новое состояние в конечном автомате), то понятное дело, что для совместимости придется менять код и в портированной версии.
 
У xBB хороший опыт - в каком плане? То, что есть пользователи софта, есть фидбек. Порт делается для частного проекта, так что опыт заимствуется пока без особых проблем. Well
17.04.2008 14:16:29 #
Mozilla Firefox dima
Кстати, есть предложение.
 
Если уж мы стали общаться на технические темы, то может быть приложим некоторые усилия к унификации BBCode, хотя бы в рамках наших двух проектов?
 
Имею в виду, что было бы здорово, если из одного и того же BBCode обе либы будут генерировать один и тот же HTML.
 
Конечно, по возможности и в рамках разумного.
 
Это облегчило бы переносимость исходных текстов BBCode и сгенерированных текстов HTML с одной платформу на другую. Облегчило бы жизнь пользователей BBCode (нет нужды переправлять тексты, нет нужды переучиваться с одной версии на другую).
 
Может быть имеет смысл обсудить этот вопрос и выработать нечто вроде рекомендации (или спецификации) BBCode? Если да, то как нам организовать эту работу?
17.04.2008 12:57:00 #
Mozilla Firefox dima
rBB, действительно, работает Well
Есть, конечно, куда совершенствовать. Вбил код:
 
текст [b]текст [quote=автор]текст[/quote] текст[/b] текст
 
Получил на выходе:
 
HTML
текст <b>текст <blockquote class="bb">текст</blockquote> текст</b> текст

То, что автора нет, - не важно, раз теги урезаны. Но обратите внимание на вложенность тегов, - она не валидна.
 
xBB в том же примере выдает такой код:
 
HTML
текст <strong class="bb">текст </strong><blockquote class="bb_quote"><div class="bb_quote_author">автор</div>текст</blockquote>текст[/b] текст

и этот код полность валиден с т.з. W3C. Даже и депрекатедов нет. Я достаточно намучился с нормализацией кода. Если валидность и для вас имеет значение, то обратите внимание на следующий код в xBB:
 
PHP
/*
Массив пар: 'модель_поведения_тегов' => массив_моделей_поведений_тегов.
Накладывает ограничения на вложенность тегов. Теги с моделями поведения, не
указанными в массиве справа, вложенные в тег с моделью поведения, указанной
слева, будут игнорироваться как неправильно вложенные.
*/

$children = array(
    'a'       => array('code','img','span'),
    'caption' => array('a','code','img','span'),
    'code'    => array(),
    'div'     => array('a','code','div','hr','img','p','pre','span','table','ul'),
    'hr'      => array(),
    'img'     => array(),
    'li'      => array('a','code','div','hr','img','p','pre','span','table','ul'),
    'p'       => array('a','code','img','span'),
    'pre'     => array(),
    'span'    => array('a','code','img','span'),
    'table'   => array('caption','tr'),
    'td'      => array('a','code','div','hr','img','p','pre','span','table','ul'),
    'tr'      => array('td'),
    'ul'      => array('li'),
);
 
/*
Массив пар: 'модель_поведения_тегов' => массив_моделей_поведений_тегов.
Накладывает ограничения на вложенность тегов.
Тег, принадлежещий указанной слева модели поведения тегов должен закрыться, как
только начинается тег, принадлежещий какой то из моделей поведения, указанных
справа.
*/

$ends = array(
    'a'       => array(
        'a','caption','div','hr','li','p','pre','table','td','tr', 'ul'
    ),
    'caption' => array('tr'),
    'code'    => array(),
    'div'     => array('li','tr','td'),
    'hr'      => array(
        'a','caption','code','div','hr','img','li','p','pre','span','table',
        'td','tr','ul'
    ),
    'img'     => array(
        'a','caption','code','div','hr','img','li','p','pre','span','table',
        'td','tr','ul'
    ),
    'li'      => array('li','tr','td'),
    'p'       => array('div','hr','li','p','pre','table','td','tr','ul'),
    'pre'     => array(),
    'span'    => array('div','hr','li','p','pre','table','td','tr','ul'),
    'table'   => array('table'),
    'td'      => array('td','tr'),
    'tr'      => array('tr'),
    'ul'      => array(),
);

и на методы must_close_tag($current, $next) и isPermissiblyChild($parent, $child).
 
Надеюсь, что ваш продукт найдет широкое применение у рубистов (есть ли какое нить устоявшееся сокращение для "программистов на Ruby"?)
17.04.2008 10:59:08 #
Opera Гость Bakti9rov
Работающий пример (некоторые теги урезаны) тут. Well

Оставьте, пожалуйста, свой комментарий к публикации

Представиться как     Антибот:
   

Просьба не постить мусор. Если вы хотите потестить xBB, воспользуйтесь кнопкой предварительного просмотра на панели инструментов xBBEditor-а.


© 2007-2017, Дмитрий Скоробогатов.
Разрешается воспроизводить, распространять и/или изменять материалы сайта
в соответствии с условиями GNU Free Documentation License,
версии 1.2 или любой более поздней версии, опубликованной FSF,
если только иное не указано в самих материалах.