Использование Maruku (часть №3)
-
08 октября 2008 11:29
-
Комментарии

Как я и обещал, сейчас я расскажу вам о возможностях расширения Markdown. Так как есть два способа расширить функциональность, то в этом посте я расскажу про первый, а в следующем про второй.
Первый способ позволяет создавать свои span-подобные теги т.е. теги состоящие из одной строки. Например можно преобразовывать конструкцию вида
( ximg: ruby.jpg : Логотип Ruby : center )
в изображение с подписью. Или например вставлять на место смайликов их изображения, чем мы сейчас и займёмся.
В качестве заготовки для span-расширений можно использовать код приведённый ниже:
RegExp = /<регулярное выражение>/
MaRuKu::In::Markdown::register_span_extension(
:chars => [<символы с которых могут начинаться ваши span-теги>],
:regexp => RegExp,
:handler => lambda { |doc, src, context|
# Здесь находиться ваш код который преобразует span-тег в HTML разметку
# Код возвращает true если тег успешно обработан, иначе возвращает false
}
)
Этот код используя метод register_span_extension регистрирует обработчик span-тегов.
В аргументе :chars указывается символ или массив символов при встрече которых срабатывает обработчик. Причём символы не должны попадать в диапазон [a-zA-Z].
В аргументе :regexp указывается регулярное выражение которое будет выполнятся при встрече символа указанного в :chars и проверять является ли последовательность символов (начиная с текущего) вашим span-тегом. Не забудьте добавить символы из :chars в начало своего регулярного выражения, я потратил довольно много времени пытаясь понять почему обработчик не срабатывает.
В аргументе :handler в виде лямбда выражения находиться ваш обработчик. Который собственно говоря и занимается преобразованием вашего span-тега в нужную вам разметку. У этого обработчика тоже есть аргументы:
Аргумент doc это экземпляр класса Maruku который вы создали. В него подмешены методы из модуля MaRuKu::Helpers которые позволяют конструировать элементы на основе которых генерируется конечная разметка (понятно что формат мета-информации о том является ли текст курсивом в XHTML, PDF и LaTeX различаются, поэтому эти методы создают промежуточные объекты в которых храниться эта мета-информация, а уже из этих объектов по вашему требованию строится или XHTML или PDF или LaTeX)
Аргумент src предоставляет объект который содержит обрабатываемый текст и методы для его обработки.
Аргумент context предоставляет объект в который ваше расширение складывает результат своей работы (т.е. элемент или элементы полученные с помощью вспомогательных методов аргумента doc и заполненные мета-информацией необходимой для генерации разметки)
Остаётся добавить что если вы успешно обработали свой span-тег, то лямбда выражение должно вернуть true, тогда обработчики идущие за ним не будут вызваны и по окончанию преобразований ваш span-тег будет замещён генерированной в обработчике разметкой. А если вернуть false, то представление вашего span-тега без изменений будет помещено в выходную разметку.
Теперь мы готовы к написанию обработчика span-тегов. Как я уже сказал выше мы будем преобразовывать текстовые смайлики в HTML разметку содержащую изображение смайлика. Так как я суровый программист, то смайликов у меня будет всего лишь два (улыбающийся смайлик - :) или :-) и расстроенный смайлик - :( или :-( )
RegSmiles = /:-?(\(|\))/
MaRuKu::In::Markdown::register_span_extension(
:chars => [?:],
:regexp => RegSmiles,
:handler => lambda { |doc, src, context|
attrs = src.read_regexp(RegSmiles).captures
bracket = attrs[0]
case bracket
when ")"
image = doc.md_im_image([], "/images/smile1.gif", ":-)", {:style => "padding:0;margin:0", :alt => ":-)"})
when "("
image = doc.md_im_image([], "/images/smile0.gif", ":-(", {:style => "padding:0;margin:0", :alt => ":-("})
end
context.push_element image
true
}
)
Вот такой вот код у меня получился. Так как мои смайлики начинаются с :, то аргумент :chars содержит этот символ. Регулярное выражение RegSmiles проверяет наличие смайлика при встречи символа двоеточия, а так же захватывает один символ (символ скобки) который после проверяется в case-е и на его основе формируется элемент на основе которого будет сформировано изображение. Затем этот элемент с помощью метода push_element помещается в контейнер context и лямбда выражение сигнализирует об успешной обработке возвращая true.
Это вот пример строк которые я использовал для тестирования:
Test :)
Тест :(
К сожалению этот код не заработал… не заработал с первого раза. Только для первой строки где содержались латинские символы появился смайлик, в строке же с русскими символами текст остался без изменений. Потратив больше часа на поиски проблемы я нашел решение и даже готовый патч (но ещё не включенный в основную версию). Порадовал меня и тот факт что я нашел то же место, но не стал писать заплатку, а решил отправить баг автору :)
А вот получившаяся разметка:
<p>Test <img src='/images/smile1.gif' alt='' style='padding:0;margin:0' /></p>
<p>Тест <img src='/images/smile0.gif' alt='' style='padding:0;margin:0' /></p>
На всякий случай приведу патч:
*** lib/maruku/input/charsource.rb.bak 2008-03-20 20:06:04.000000000 +0200
--- lib/maruku/input/charsource.rb 2008-03-20 20:28:34.000000000 +0200
***************
*** 88,95 ****
end
def next_matches(r)
! r2 = /^.{#{@buffer_index}}#{r}/m
! md = r2.match @buffer
return !!md
end
--- 88,94 ----
end
def next_matches(r)
! md = /#{r}/um.match @buffer[@buffer_index, @buffer.size-@buffer_index]
return !!md
end
Думаю он потребуется нам и в следующей части. А пока всё.
в формате RSS. Присоединяйся!
Добавить новый комментарий
Вы можете использовать следующие BBCode теги в комментариях:
| BBCode тег | Результат |
|---|---|
| [b]Жирный текст[/b] | Жирный текст |
| [i]Курсив[/i] | Курсив |
| [u]Подчёркнутый текст[/u] | Подчёркнутый текст |
| [url]http://example.com[/url] | http://example.com |
| [url=http://example.com]Example[/url] | Example |
|
[code]for message in @messages puts message.name end[/code] |
|
|
[quote] IE6 must die! [/quote] |
IE6 must die! |

