Разметка
Имеется также Deutsch[link1], Español[link2] и English[link3]Эта довольно длинная статья о том, как появилась "вака-разметка", и почему она такая, какая она сейчас есть. Если вы не знаете, что такое "вака-разметка" и, тем более, что такое "вики", вам стоит подробнее ознакомиться с сайтом проекта WackoWiki и прочитать тут пару статей документации[link4], в особенности статью про вики-концепции[link5].
1. О вака-разметке
Если коротко, то вака-разметка -- это особый способ форматирования текста, который позволяет при минимуме спецсимволов и минимальном визуальном искажении "исходного текста" получать после программного преобразования красивый HTML.Возможностей вака-разметки хватает для полноценного оформления документов, больших и маленьких. Кроме традиционных модификаторов "курсива", "полужирного", "подчёркнутого" и "перечёркнутого" текста, здесь есть и разметка списков (в том числе и многоуровневых), заголовков, таблиц, картинок, выделение цитат и многое.
Вака-разметка используется в вики-движке WackoWiki и в других проектах разных разработчиков. Для того, чтобы внедрить вака-разметку в вашем проекте, вам достаточно скачать и встроить в ваш проект следующие компоненты:
- вака-форматтер[link6], php-класс, превращающий вака-разметку в HTML;
- визуальный редактор[link7] для вики-текстов. Это необязательное, но чрезвычайно удобное дополнение к вака-форматтеру.
Исходный текст этой статьи написан в формате вака-разметки и доступен для просмотра[link8].
2. Принципы, положенные в основу
Хотя вака-разметка изначально досталась нам в наследство от проекта WakkaWiki[link9] (ранее размещавшегося по адресу http://wakkawiki.de, но сейчас недоступного), в её основе были чёткие принципы, которые и определили её дальнейший успех.Таким образом, формирование правил разметки, хотя и происходило "эволюционным" путём, всё же руководствовалось небольшим набором принципов, которые помогли разметке остаться удобной и естественной.
Принципы были придуманы для того, чтобы достичь следующих целей:
- снизить вероятность "случайного срабатывания" (т.е. когда обычный текст воспринимается как какая-то часть разметки);
- добиться "интуитивной" и легко запоминаемой разметки;
- защитить окружение форматированного текста от возможных опечаток автора.
2.1. Семантика должна передаваться через синтаксис
В основе любой вики-разметки лежит принцип WYTIWYG, поэтому каждое правило вака-разметки старается своим оформлением (синтаксисом) отражать смысл (семантику). Поскольку в вака-разметке всё оформление делается средствами простого текста -- символами, которые можно набрать с клавиатуры, то мы старались подобрать такие комбинации, которые бы отражали смысл:-
**жирный**
-- звёздочки для жирного текста, который выделяется из общей массы; -
//курсив//
-- курсив оформляется скошенными же линиями; -
--зачёркивание--
и__подчёркивание__
соответственно; - списки выглядят так же, как мы привыкли писать подобные списки в текстовых полях ввода.
2.2. Парные символы
Как вы заметили, все приведённые выше примеры вака-разметки содержат парные символы. Благодаря этому принципу текст "просто вставленный из какого-нибудь другого редактора" не требует специальной предварительной обработки -- маловероятно, что в нём встретятся таким образом "спаренные" символы.В разметке есть случаи, когда используются тройные, четверные символы (и даже последовательности из 5-6 подряд идущих символов) -- они используются для выделения заголовков разного уровня. Чем больше символов, тем "глубже" уровень заголовка.
2.3. Разметка соприкасается с внутренним текстом
Не исключено, что вы из тех людей, что всегда пишут тире как "два минуса" (вот так:--
). Во всяком случае, авторы явно из числа этих людей. И более того, существует великое множество текстов, содержащих двойной минус как в качестве тире, так и в других качествах.Принцип, согласно которому разметка должна "соприкасаться" с внутренним текстом, позволяет избежать таких случайных превращений "простого текста" в текст с разметкой. Этот принцип введён не для всех правил разметки, но для тех, в которых отдельно стоящий парный символ может встречаться в "исходном тексте" (например, для зачёркивания).
Т.е.
--вот так--
будет работать, а если -- мы сделаем так--
-- то текст не зачёркнётся.Надо заметить что это правило, предыдущее и следующее направлены на то, чтобы добиться минимального количества "случайных срабатываний" разметки, т.е. избавиться от ситуаций, когда какие-то символы в тексте воспринимаются как части разметки.
2.4. Перевод строки -- завершение некоторого фрагмента текста
В отличие от, скажем, разметки OpenWiki, перевод строки в "исходном тексте" вака-разметки воспринимается буквально -- как перевод строки (два перевода начнут новый абзац). Таким образом, мы принимаем, что перевод строки -- это завершение некоторого законченного фрагмента текста, например, предложения или даже абзаца.Некоторые правила вака-разметки: правила, изменяющие параметры шрифта у текста (это жирность, курсив, подчёркивание и другое) и заголовки -- большинство этих правил работают только в масштабах фрагмента текста, ограниченного переводом строки. Использование этого принципа позволяет решить сразу три задачи:
- снизить вероятность "случайного срабатывания";
- упростить восприятие разметки (ведь "начало" и "конец" выделения оказываются недалеко друг от друга);
- свести роль "шрифтового оформления" к выделению малых фрагментов текста -- что положительно сказывается на восприятии результата.
2.5. "Сломанная" разметка не должна ломать HTML вокруг текста
Вышеизложенные принципы позволяют добиться решения одной очень важной задачи -- "защиты" HTML вокруг отформатированного текста от возможных ошибок форматирования. Благодаря правилу "прилипания" мы почти всегда можем определить какая часть разметки является "началом", а какая "концом", а также вставлять сразу оба HTML-тега (или не вставлять ни одного). Для тех правил вака-разметки, которые не имеют столь легко достижимой "парности" должны быть предприняты все усилия, чтобы добиться "герметичности" результата. И, как мы видим, это удалось.2.6. Должен быть способ написать в точности то, что я хочу написать
Любую разметку нужно уметь "экранировать" -- т.е. делать так, чтобы при разборе правила разметки игнорировались и фрагмент текста проходил через форматирование неизменным. Эта статья -- пример того, когда подобное "экранирование" необходимо.2.7. Минимум переключения раскладки клавиатуры
Последний в списке, но очень важный принцип не мог бы возникнуть ни у одного англоговорящего автора, однако, для русскоязычного пользователя этот принцип во многом определяет результирующее удобство.Суть принципа заключается в том, чтобы подбирать правила разметки таким образом, чтобы большинство из них (в особенности часто используемые правила) было можно набирать, оставаясь в русской раскладке. Одновременно с этим нужно не забывать и об аналогичной доступности для англоязычной аудитории.
Таким образом, исходный синтаксис ссылок
[[WikiLink Textual description]]
обрёл своего двойника ((ВикиСсылка Текст на ссылке))
, которого можно использовать как на английской, так и на русской раскладке. Очень многие правила вики-разметки обладают этим ценным свойством.3. Правила формирования разметки
Применяя эти принципы, мы развивали и совершенствовали изначальный набор правил, внимательно изучая разные вики-движки. Если бы я посмел хвастаться, я бы сказал, что итоговая вака-разметка вобрала в себя всё самое лучшее из разных правил разметки, оставшись стройной и простой. Хотя, чёрт возьми! В итоге нашей работы вака-разметка вобрала в себя всё самое лучшее из разных правил разметки, оставшись стройной и простой.В этой главе бегло рассказывается о том, как мы пришли к наиболее ключевым правилам разметки.
3.1. Однострочная разметка
Однострочной разметкой стали все те правила, которые использовали символы, часто употребляемые в "простых текстах", и которые касались какого-то "местного" оформления текста:- жирный, курсив, подчёркивание
- мелкий и
моноширинный
текст - заголовки (просто не имеющие смысла при разбиении на строки)
- ссылки (тексту которых тоже лучше оставаться "короткими")
- возведение в степень и индексы (которые работают лишь в пределах одного слова)
3.2. Многострочная разметка
Остальные правила разметки работают на больших фрагментах строк. Это разрешено главным образом потому, что их оформление часто применяют к большим фрагментам текста.Это, например,зачёркивание.цитирование, которое захватывает весь абзац.
Или
3.3. Экранирование разметки
Экранирование реализуется двумя способами:- экранирование блока с помощью "парных символов"
""
; - escaping (введение специального символа перед экранируемой последовательностью) с помощью символа
~
(тильда).
Если вы откроете исходный текст[link8] статьи, то обнаружите, что экранирование разметки встречается там очень часто -- иначе мы бы не смогли привести ни одного примера разметки в своём непреобразованном виде.
3.4. Ссылки и изображения
Вака-разметка, обнаружив в тексте URL, автоматически превращает его в ссылку. Если понятно, что URL указывает на "картинку" (например, заканчивается на.jpg
или .gif
) -- в отформатированный текст вставляется изображение с помощью тега <img>
. Это удобно, потому что позволяет, не особенно задумываясь, вставлять ссылки из буфера обмена, получая вполне качественный результат.Для установки ссылки с подписью есть два тега, имеющие несколько вариантов использования:
-
((URL Текстовое описание))
-
[[URL Текстовое описание]]
-- то же, только менее удобно -
((Вики Ссылка C Пробелами == Текстовое описание))
-- позволяет вставлять пробелы в "левую часть" вики-ссылки (так же работает и на квадратных скобках)
Концепция вики-ссылок[link11] позволяет вставлять ссылки "внутри сайта" более просто и вака-разметка это тоже учитывает. Все ссылки, которые не являются "внутренними", сразу оформляются как "внешние", то же происходит и с email-адресами.
Подписи к картинкам расставляются очень похоже на подписи к ссылкам:
-
((picture.jpg Подпись))
-- способ задания title картинки -
((URL small_picture.jpg))
-- способ поставить ссылку с картинки
3.5. Списковые структуры
Как наиболее естественно для человека писать списки, нумерованные и ненумерованные, а так же вложенные?
| Что хочется получить:
|
Отступ выбран равным в два символа исходя из принципа "парных символов", которые в обычных текстах почти не встречаются. Некоторые другие вики-форматы используют пять-шесть пробелов -- можно представить себе, как будет выглядеть третий уровень вложенности в
<textarea>
!Оригинальная разметка с c2.com использует символ табуляции, что представляется нам очень непродуманным: в большинстве интерфейсов Tab выполняет функции навигации, а в некоторых браузерах символ табуляции ввести в поле ввода вообще невозможно.
Нумерация в нумерованных списках проставляется автоматически, что позволяет спокойно удалять пункты, добавлять новые и переносить их в иерархии. Если вам нужен нумерованный список, начинающийся с тройки, начните его
1.#3 Вот так
.- Именно так.
3.6. Разметка таблиц
Таблицы -- одно из самых больных мест любой разметки. Наилучшим решением оказался набор правил, разметка которого имитирует вертикальные линии сетки таблицы. Это легче, чем рисовать дефисами, плюсами и вертикальными линиями всю сетку, и одновременно даёт вполне читаемую в "исходном тексте" таблицу. Подробнее о разметке таблиц можно прочитать в синтаксисе вака-разметки[link12]. Там же есть и примеры.К сожалению, разметка таблиц -- самый "уязвимый" фрагмент вака-разметки, позволяющий в некоторых случаях "нарушить" структуру внешнего окружения документа. Эта та небольшая цена, которую мы решили заплатить за наглядность синтаксиса и скорость его разбора.
4. Развитие разметки
Во-первых, выше рассмотрены далеко не все правила вака-разметки, а лишь самые основные. Если вам чего-то не хватает -- посмотрите сперва более полную документацию[link12]. Если же становится ясно, что существующих правил не хватает -- разметку стоит расширять. Так появилось большинство правил нашей разметки.4.1. Когда стоит изменять существующую разметку?
Никогда.Именно так, если речь идёт не о введении новых правил, а о изменении существующих. Изменение поведения разметки, которое кажется полезным вам, может существенно помешать остальным людям, привыкшим работать с такой разметкой. Представьте, если бы на некоторых сайтах
<b>
стало работать как <a>
и наоборот.Конечно, если в рамках вашего конкретного проекта какое-то правило существенно мешает -- тогда можно подумать о его замене. Заменяя/удаляя правило, задумайтесь о том, как это воспримут все те, кто привыкли к стандартной вака-разметке!
4.2. Когда стоит вводить новые сущности разметки?
Как можно реже.У вака-разметки есть концепция "хайлайтеров" -- подключаемых сущностей, которые добавлять легко и просто, не занимая "основное пространство разметки" -- парные символы. О концепции хайлайтеров сказано чуть ниже.
Если вы просто, не задумываясь, введёте новый "парный символ", этим вы заставите задуматься ваших пользователей. То, что они используют вака-разметку не задумываясь, стало возможным лишь благодаря тому, что над каждым новым правилом разработчики долго думали, рассматривая возможные последствия.
Если вы хотите расширить вака-разметку, то лучше всего будет обратиться к авторам данного формата -- может у них уже есть продуманная идея или они с радостью воспримут вашу. Координированные действия всегда оказываются эффективнее.
5. Сложные преобразования и сервис-функции
Идея вака-разметки, заимствованная из WakkaWiki и расширенная авторами, предусматривает два способа существенного расширения возможностей разметки и внедрения в документы разной сложной функциональности.Именно этими двумя способами мы и рекомендуем в первую очередь воспользоваться тем, кто хочет расширить себе правила разметки. Помимо прочего, использование этих способов не требует детального разбора исходного класса вака-форматтера.
5.1. Концепция форматтеров-хайлайтеров (highlighters)
Highlighters -- это концепция, позволяющая разработчику реализовать сложную логику преобразования какого-то блока текста, а пользователю -- легко передать этот блок текста на оформление.В теле вака-разметки использование хайлайтера выглядит так
%%(html)<div class="test">testdiv</div>...%%
-- т.е. используется "парный символ" %%
с указанием в круглых скобках, какой функции-хайлайтеру передать то, что внутри.Разработчик же пишет эти самые функции, принимающие текстовую переменную, совершающие с ней какие-то преобразования и затем возвращающие результат.
Как правило, этот синтаксис используется для разнообразной "расцветки" текста -- для подсветки синтаксиса, оформления ICQ-логов и email, вставки каких-то произвольных блоков текста.
Эта концепция -- способ легко расширить разметку, при этом:
- не задействуя дополнительных "парных символов";
- не разбираясь в деталях работы вака-форматтера.
5.2. Концепция акшнов-действий (actions)
Actions -- это концепция, позволяющая разработчику реализовать какую-то сложную функциональность (возможно, даже требующую диалога с пользователем), а пользователю -- легко обеспечить в нужном месте документа доступ к этой функциональности.В теле вака-разметки использование "действия" выглядит так
{{changes page="/Dev"}}
-- используется "парный символ" {{
с указанием имени "действия" и дополнительных параметров.Разработчик пишет эти функции точно так же, как он пишет и "хайлайтеры".
Именно через "действия" в WackoWiki реализована значительная часть функциональности по работе с документами (построение каталога, списков последних изменений/комментариев, поиск).
Эта концепция -- способ "встроить" в документ какую-то сложную функциональность, при этом так же не влезая в детали работы вака-форматтера.
5.3. Interwiki -- модификация разметки ссылок
Существует также способ расширить синтаксис разметки ссылок, введя в него дополнительные правила вида((repository:address))
или ((repository:address Текст на ссылке))
. Адрес в таком случае указывается как два фрагмента "хранилище" и "имя в этом хранилище". Например, для LiveJournal[link13] адреса будут выглядеть как-то так: ((lj:mendokusee))
, а для ссылки на перевод английского слова можно будет писать ((lingvo:fascinating))
.Эта концепция (как и многое в нашей разметке) унаследована из вики, и изначально предназначалась для указания страниц на других вики-узлах. Как мы заметили, её очень удобно использовать и с другими, менее специфичными целями.
Тем не менее, есть и другие способы реализации аналогичной модификации. На разных сайтах используются следующие форматы разметки:
-
[[ljuser romochka]]
(источник[link14]) -
[[xpointUser280 Владимир Палант]]
(источник[link15]) -
[[php ereg_replace]]
ссылка на документацию (источник[link15])
Вариант interwiki (ссылки через двоеточие) кажется нам более правильным хотя бы потому, что используется во множестве систем и является стандартом де-факто. Кроме того interwiki не вызывает конфликта с обычной разметкой
[[Link Description]]
.6. Технические детали
Эта статья -- не то место, где вы сможете в деталях разобраться, как работает вака-форматтер[link6], однако, некоторые основные моменты стоит назвать.Во-первых, сам по себе форматтер построен на "регулярных выражениях" (а именно Perl Compatible Regular Expressions) и работает по принципу "рекурсивного разбора". Это означает, что он старается разбить текст на "самые крупные" фрагменты разметки, а потом использует себя же для разбора внутри них. Это, в свою очередь, значит, что нельзя вкладывать одинаковые правила разметки: например, вот так --
**пример **вложенной** разметки**
работать не будет. Но, согласитесь, это и не нужно.Во-вторых, для наилучшей защиты от "случайного срабатывания" форматтер работает в несколько проходов. Первым проходом отрабатывается сокращённый набор правил, позволяющий "экранировать" фрагменты текста, запретив в них разметку. В этом же проходе выделяются все "хайлайтеры", защищаясь таким образом от перекрытия хайлайтеров другой разметкой. Второй проход форматтера обрабатывает все оставшиеся правила.
В-третьих, форматтер позволяет осуществить кэширование отформатированного результата. Поскольку разметка содержит в себе функциональность, требующую взаимодействия с пользователем, а также ссылки на страницы (которые могут обрабатываться по-разному для разных пользователей), то для кэширования формируется "полуфабрикат", в котором остались только правила, касающиеся ссылок и "действий". Последний проход форматтера -- самый быстрый и не требующий рекурсии -- осуществляется при выводе содержимого документа на основе этого "полуфабриката" и делает разметку ссылок и вставку "действий".
Если вам интересны более глубокие аспекты функционирования форматтера -- добро пожаловать в код форматтера[link6].
7. Вместо заключения
Эта статья была написана для того, чтобы рассказать о том, как и почему были придуманы правила вака-разметки, откуда взялись те или иные "парные символы" и почему нам хочется надеяться на то, что новые проекты, использующие в качестве формата редактирования вака-разметку, будут следовать тем принципам, что лежат в её основе.Если у вас возникли вопросы -- не стесняйтесь задавать их в комментариях или лично авторам статьи.
С уважением, команда WackoWiki[link16] и авторы статьи:
- Кусо Мендокуси[link17];
- Роман Иванов[link18].
8. Ссылки
- The WackoWiki Project[link19]
- Форматтер[link6] для описываемой разметки
- Визуальный редактор[link7] для описываемой разметки
- WakkaWiki[link20] -- исторические корни WackoWiki
- OpenWiki[link21] -- ещё одни исторические корни вака-разметки
- Описание вики-концепций[link5]
- Синтаксис вака-разметки[link12]
- Примеры классической разметки[link22] на c2.com
- Что такое ВикиИмя[link11] -- концепция вики-ссылок
- [link1] https://wackowiki.org/doc/Doc/Deutsch/Markup
- [link2] https://wackowiki.org/doc/Doc/Español/Markup
- [link3] https://wackowiki.org/doc/Doc/English/Markup
- [link4] https://wackowiki.org/doc/Doc/Русский
- [link5] https://wackowiki.org/doc/Doc/Русский/WikiКонцепции
- [link6] https://wackowiki.org/doc/Dev/Projects/WackoFormatter
- [link7] https://wackowiki.org/doc/Dev/Projects/WikiEdit
- [link8] https://wackowiki.org/doc/Doc/Русский/Разметка/source
- [link9] https://wackowiki.org/doc/Doc/Русский/WakkaWiki
- [link10] http://c2.com/cgi/wiki?TextFormattingExamples
- [link11] https://wackowiki.org/doc/Doc/Русский/ВикиИмя
- [link12] https://wackowiki.org/doc/Doc/Русский/WackoСинтаксис
- [link13] http://livejournal.com
- [link14] http://ilyabirman.ru/meanwhile/wikihelp
- [link15] http://xpoint.ru/help/formatting.xhtml
- [link16] https://wackowiki.org/doc/Org/Team
- [link17] https://wackowiki.org/doc/Users?profile=KusoMendokusee
- [link18] https://wackowiki.org/doc/Users?profile=RomanIvanov
- [link19] http://wackowiki.org
- [link20] https://web.archive.org/web/20050211022800/http://www.wakkawiki.de/WakkaWiki
- [link21] https://web.archive.org/web/20060202001402/http://openwiki.com/
- [link22] https://c2.com/cgi/wiki?TextFormattingExamples