blog/_posts/coding/2023-05-27-captioning-jekyll-highlighted-code-block.tl
2023-06-23 00:44:00 +02:00

61 lines
2.3 KiB
Plaintext

---
layout: default
title: Captioning Jekyll highlighted code block
date: 2023-05-27 19:22 +0200
tags: Ruby Jekyll
---
Jekyll encloses code highlighted with @{% raw %}{% highlight_ %}{% endraw %}@
Liquid tag inside @<figure>@ HTML tag. That in turn allows embeeding
@<figcaption>@ tag and captioning code, e.g. with file path. Jekyll (v4.3.2)
does not provide captioning, but can be extended with simple plugin.
Plugin code presented here and used by this blog is
"here.":https://gitea.michalczyk.pro/michalczyk.pro/blog/src/branch/master/_plugins/highlight-caption-option.rb
The plugin overrides @Jekyll::Tags::HighlightBlock.render()@ method. HTML
code returned by this method can be manipulated using parser library like
_Nokogiri_, but inserting a single tag is simple enough to be succesfully
performed without additional libraries:
{% highlight ruby caption=_plugins/highlight-caption-option.rb %}
module HighlightCaption
...
def render(*args)
caption = "<figcaption>#{@highlight_options[:caption]}</figcaption>"
match = super.match('<figure[^>]*>')
match.pre_match + match.to_s + caption + match.post_match
end
end
{% endhighlight %}
Caption generating code can be freely modified. It can even
process additional options passed to @{% raw %}{% highlight %}{% endraw %}@ tag.
Options are only allowed to consist of alphanumeric characters and underscore.
Passing file path as option requires loosening this restriction. We allow any
"non-blank character":https://ruby-doc.org/current/Regexp.html, except those
used to control option format (options are allowed to be expressed as: _name_,
_name=value_ and _name="quoted list"_)
{% highlight ruby caption=_plugins/highlight-caption-option.rb %}
module HighlightCaption
def self.prepended(mod)
syntax = mod.send(:remove_const, :SYNTAX).source.gsub('\\w', '[^[:^graph:]"=]')
mod.const_set(:SYNTAX, Regexp.new(syntax))
options = mod.send(:remove_const, :OPTIONS_REGEX).source.gsub('\\w', '[^[:^graph:]"=]')
mod.const_set(:OPTIONS_REGEX, Regexp.new(options))
end
...
end
{% endhighlight %}
Finally the modifications have to be @prepend@-ed to original class:
{% highlight ruby caption=_plugins/highlight-caption-option.rb %}
Jekyll::Hooks.register :site, :pre_render do |site|
Jekyll::Tags::HighlightBlock.prepend JekyllTagsExtensions::HighlightCaption
end
{% endhighlight %}