--- 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 @
@ HTML tag. That in turn allows embeeding @
@ 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 = "
#{@highlight_options[:caption]}
" match = super.match(']*>') 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 %}