--- 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 used by this blog is "here.":https://gitea.michalczyk.pro/michalczyk.pro/blog/src/branch/master/_plugins/highlight-capion-options.rb The plugin will override @Jekyll::Tags::HighlightBlock.render()@ method. HTML code returned by this method can be manipulated using parser library like _Nokogiri_. Adding a single tag is simple enough, that it can 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 %}