summaryrefslogtreecommitdiff
path: root/lib/banzai/filter/front_matter_filter.rb
blob: 544231adea44ab63d9b39ffea54722a27630ba64 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# frozen_string_literal: true

module Banzai
  module Filter
    class FrontMatterFilter < HTML::Pipeline::Filter
      DELIM_LANG = {
        '---' => 'yaml',
        '+++' => 'toml',
        ';;;' => 'json'
      }.freeze

      DELIM = Regexp.union(DELIM_LANG.keys)

      PATTERN = %r{
        \A(?:[^\r\n]*coding:[^\r\n]*)?         # optional encoding line
        \s*
        ^(?<delim>#{DELIM})[ \t]*(?<lang>\S*)  # opening front matter marker (optional language specifier)
        \s*
        ^(?<front_matter>.*?)                  # front matter (not greedy)
        \s*
        ^\k<delim>                             # closing front matter marker
        \s*
      }mx.freeze

      def call
        html.sub(PATTERN) do |_match|
          lang = $~[:lang].presence || DELIM_LANG[$~[:delim]]

          ["```#{lang}", $~[:front_matter], "```", "\n"].join("\n")
        end
      end
    end
  end
end