Commit 8eaeda08 authored by Robert Speicher's avatar Robert Speicher

Add YamlFrontMatterFilter to the PreProcessPipeline

This filter will detect YAML Front Matter and convert it to an HTML
table for prettier formatting.
parent 74751791
require 'html/pipeline/filter'
require 'yaml'
module Banzai
module Filter
class YamlFrontMatterFilter < HTML::Pipeline::Filter
DELIM = '---'.freeze
# Hat-tip to Middleman: https://git.io/v2e0z
PATTERN = %r{
\A(?:[^\r\n]*coding:[^\r\n]*\r?\n)?
(?<start>#{DELIM})[ ]*\r?\n
(?<frontmatter>.*?)[ ]*\r?\n?
^(?<stop>#{DELIM})[ ]*\r?\n?
\r?\n?
(?<content>.*)
}mx.freeze
def call
match = PATTERN.match(html)
return html unless match
"```yaml\n#{match['frontmatter']}\n```\n\n#{match['content']}"
end
end
end
end
......@@ -2,7 +2,8 @@ module Banzai
module Pipeline
class PreProcessPipeline < BasePipeline
def self.filters
[
FilterArray[
Filter::YamlFrontMatterFilter
]
end
......
require 'rails_helper'
describe Banzai::Filter::YamlFrontMatterFilter, lib: true do
include FilterSpecHelper
it 'allows for `encoding:` before the frontmatter' do
content = <<-MD.strip_heredoc
# encoding: UTF-8
---
foo: foo
---
# Header
Content
MD
output = filter(content)
expect(output).not_to match 'encoding'
end
it 'converts YAML frontmatter to a fenced code block' do
content = <<-MD.strip_heredoc
---
bar: :bar_symbol
---
# Header
Content
MD
output = filter(content)
aggregate_failures do
expect(output).not_to include '---'
expect(output).to include "```yaml\nbar: :bar_symbol\n```"
end
end
context 'on content without frontmatter' do
it 'returns the content unmodified' do
content = <<-MD.strip_heredoc
# This is some Markdown
It has no YAML frontmatter to parse.
MD
expect(filter(content)).to eq content
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment