Владимир Зарыпов (krre31) wrote,
Владимир Зарыпов
krre31

Океан. BBCode

Сделал великую фичу, на которую я потратил аж целых две утомительных недели. Очень сложной она для меня оказалась. Называется BBCode - обёртка в виде тегов для специальной разметки текста. Сейчас понятие это по большей части устарело и передаёт нам привет из 90-х и начала нулевых, но кое-где на форумах ещё используется. Я решил тоже её заюзать, потому что лучше пока ничего не придумал. Нужна фича для двух основных целей - форматирование текста и добавление мультимедийного контента, и выглядит приблизительно так:

[b]Это жирный текст[/b]

Когда программный код разберёт этот тайный шифр, получится строка вида:

Это жирный текст

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

Казалось бы ничего сложного, что тут делать - работы на один вечер, и оно так и было бы, если бы не одно противное НО. Эти сучьи BB-коды могут быть рекурсивными. Например, если хочется сделать жирный текст да ещё и курсивный:

[b][i]Это жирный курсивный текст[/i][/b]

Результат:

Это жирный курсивный текст

То есть i-код вложен в b-код, и таких вложений может быть сколько угодно. Рекурсивная грамматика просто так не парсится - это целая наука, так что не удивительно, что я на этом застрял. Первую неделю потратил только на то, чтобы решить, взять ли какую-то готовую библиотеку для парсинга BB-кодов или написать свою. А если написать свою, то каким способом?

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

К началу второй недели я пришёл к выводу, что надо писать что-то своё, но что-то своё у меня тоже никак не шло. Ни один из вариантов реализации BB-кодов, которые я нашёл в чужих библиотеках, мне не нравились. Как обычно бывает в таких случаях, захотелось уже забить на эту фичу и вернуться к ней когда-нибудь потом, когда залечится стресс и затянутся душевные раны, пока вдруг я не наткнулся на замечательную статью на Хабре Как писать парсеры на JavaScript. Это было как раз то, что мне нужно. Правда, предлагаемый там метод использовал функциональное программирование, и мне понадобилось дней пять, чтобы сломать моск и понять, как это чудо враждебной техники устроено. Плюс ещё там были примеры кода для парсинга XML-текста, а мне нужны были BB-коды, что тоже несколько добавило хлопот, пока я разбирался, как всё это сконвертировать под свои нужды.

В конечном итоге у меня получился чудесный парсер BB-кодов, но он, сцуко, работал только для идеального сферического текста в вакууме. Проблема была в квадратных скобках [ и ]. Если где-то в тексте встречались эти скобки, не относящиеся к BB-кодам, то всё нахрен ломалось, и показывалось только то, что было до этих скобок. Я так извёлся, решая эту проблему, что тоже был на грани того, чтобы забить на BB-коды, несмотря на протраченные две недели, и вернуться к ним через полгода или через год. Но, как всегда, в последний момент, я придумал гениальное решение! Вовка-вундеркинд!

Я вспомнил, что есть такая замечательная штука, как Unicode, таблица символов, состоящая из десятков тысяч оных. В этих символах можно найти что-то похожее на квадратные скобки, которые имеют практически нулевые шансы, что они случайно окажутся в нашем тексте. Я такие символы нашёл, вот они: ⁅⁆. Это почти квадратные скобки, только с какими-то засечками посередине. Когда я их заюзал, все проблемы были мигом решены. Уверен, что если бы BB-коды изобретали в то время, когда Юникод уже был в широком распространении, то там бы тоже взяли какие-нибудь редкие символы и не морочили себе голову. А то сейчас пол-Интернета завалены вопросами офигевших программистов, пытающихся эти квадратные скобки как-то заэкранировать, чтобы они не ломали парсер.

А теперь показываю, как это всё работает.

Я добавил в редактор сообщения четыре новых иконки для создания жирного, курсивного, подчёркнутого и зачёркнутого текста. Использование традиционное - выделяем нужный фрагмент текста и нажимаем одну из иконок.

Результат после отправки сообщения:


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

Ссылка оформляется аналогично, как здесь в ЖЖ. Если хочется завернуть в ссылку какой-то фрагмент текста, то выделяем его и нажимаем иконку ссылки (пятая слева), после чего в появившемся диалоге вводим URL. Если текст не выделять, то в тексте будет показан просто URL.

Результат:


Добавление картинок делается аналогично, как описано в статье Океан. Ссылки на ресурсы. Разница только в том, что тогда генерировался HTML-код, а теперь BB-код. Сравните для примера старый и новый варианты:

Новый очевидно короче и понятнее. Это потому, что когда этот код рендерится, он скрытно добавляет ещё и кликабельную ссылку на картинку. Тогда как в первом варианте её приходилось добавлять явно.

А теперь апофеоз. Для добавления видео я сделал специальный BB-код youtube, который скрыто рендерит километровой длины настройки. Сравните, как было и как стало:

Меня такая возможность скрыть настройки YouTube-контейнера радует неимоверно. Это означает, что в базе будет храниться только ссылка, а если я захочу когда-нибудь поменять настройки, то сделаю это в коде сайта, и они применятся на всех ссылках, которые были добавлены через BB-код youtube. Именно по этой причине я отказался от HTML-кодов, но не только. Вторая серьёзная причина - это возможность при помощи BB-кодов создавать сложные конструкции разметки, которая будет доступна для редактирования в каком-то очень простом виде. Например, теперь я могу легко сделать цитирование текста в сообщениях или указывать, кто на что отвечает. А в дальнейшем добавить возможность пользователям создавать опросы к своим темам на форуме.

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

Однако это только малая часть того, что я запланировал. Фичей, ждущих своей очереди, очень много. Также я хочу написать большую конспирологическую статью о нашем мрачном будущем, которое я недавно придумал на основе долгих размышлений (да и когда я писал о чём-то счастливом?), так что одна надежда на новогодние праздники, чтобы побольше успеть за них сделать.

Tags: океан
Subscribe

Posts from This Journal “океан” Tag

  • Океан. Камбэк

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

  • Океан. Блэкаут

    Выключил сервер. Устал читать ругань и ненависть, которая льётся на сайте бесконечным потоком. Уже давно не обсуждают манделы и редко добавляют…

  • Океан. Манделы пользователя

    Облегчим задачу спецслужбам. Предположим, спецслужбы захотели проверить все манделы конкретного пользователя. Сделать это теперь как нельзя просто.…

  • Post a new comment

    Error

    default userpic
    When you submit the form an invisible reCAPTCHA check will be performed.
    You must follow the Privacy Policy and Google Terms of use.
  • 12 comments

Posts from This Journal “океан” Tag

  • Океан. Камбэк

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

  • Океан. Блэкаут

    Выключил сервер. Устал читать ругань и ненависть, которая льётся на сайте бесконечным потоком. Уже давно не обсуждают манделы и редко добавляют…

  • Океан. Манделы пользователя

    Облегчим задачу спецслужбам. Предположим, спецслужбы захотели проверить все манделы конкретного пользователя. Сделать это теперь как нельзя просто.…