Когда писал предыдущую статью, столкнулся с одной простой проблемой: большие куски кода занимали больше места, чем сам текст.
Поиск готового решения для спойлеров привел меня на вот эту страничку. Решение простое и гениальное, но имело один большой недостаток: текст внутри спойлера не форматировался.
Свое решение я опишу в этой статье.
TL;DR. Для тех, кому лень читать целиком
Это нужно положить в папку _plugins
:
module Jekyll
class SpoilerBlock < Liquid::Block
def initialize (tag_name, markup, tokens)
super
@summary = markup.strip
end
def render(context)
site = context.registers[:site]
converter = site.find_converter_instance(Jekyll::Converters::Markdown)
output = '<details class="spoiler">'
output << "<summary class=\"spoiler-title\">#{@summary.empty? ? 'Открыть' : @summary}</summary>"
output << '<div class="spoiler-body">'
output << converter.convert(super)
output << '</div>'
output << '</details>'
end
end
end
Liquid::Template.register_tag('spoiler', Jekyll::SpoilerBlock)
И использовать в постах так:
{% spoiler Заголовок спойлера %}
```yaml
content:
- "some string"
```
{% endspoiler %}
В Github Pages это работать не будет!
Любые плагины и дополнения работают только при самостоятельной сборке проекта (например, на Gitlab'е)
Проблема #
Если любой код поместить внутрь HTML тега, то он будет отрисован как есть. То есть вот этот кусок кода:
<details class="spoiler">
<summary class="spoiler-title">Заголовок спойлера</summary>
<div class="spoiler-body">
**Тут должен быть жирный текст**
```
А это *должен* быть кусок кода
```
</div>
</details>
Выдаст вот такой результат:
Заголовок спойлера
Мы можем заставить Jekyll парсить код внутри HTML элементов:
# _config.yml
kramdown:
parse_block_html: true
Но результат сильно лучше не станет:
Решение #
Решение напрашивается само собой: нужно содержание спойлера индивидуально прогонять через конвертёр.
Когда-то я читал спецификацию по Ruby, но для меня он до сей поры остается языком инопланетян. (Говорят, что Ruby очень популярен в Японии. Кажется, это все объясняет). Я даже кажется нашел используемый в Liquid фильтр для конвертации. Но так и не смог его победить.
В итоге после короткого гугления нашел вот этот рецепт:
site = context.registers[:site]
converter = site.find_converter_instance(Jekyll::Converters::Markdown)
converter.convert(text)
Остается все это дело собрать воедино вот так:
Все то же, что и в TL;DR выше
module Jekyll
class SpoilerBlock < Liquid::Block
def initialize (tag_name, markup, tokens)
super
@summary = markup.strip
end
def render(context)
site = context.registers[:site]
converter = site.find_converter_instance(Jekyll::Converters::Markdown)
output = '<details class="spoiler">'
output << "<summary class=\"spoiler-title\">#{@summary.empty? ? 'Открыть' : @summary}</summary>"
output << '<div class="spoiler-body">'
output << converter.convert(super)
output << '</div>'
output << '</details>'
end
end
end
Liquid::Template.register_tag('spoiler', Jekyll::SpoilerBlock)
Положить в папку _plugins
. И далее можно использовать в любом Markdown документе вот так:
{% spoiler Заголовок спойлера %}
```yaml
content:
- "some string"
```
{% endspoiler %}
Вот с таким вот результатом:
Заголовок спойлера
content:
- "some string"
Используйте на здоровье :grin: