Add YamlFrontMatterFilter to the PreProcessPipeline

This filter will detect YAML Front Matter and convert it to an HTML
table for prettier formatting.
This commit is contained in:
Robert Speicher 2016-02-21 19:22:02 -05:00
parent 74751791a8
commit 8eaeda0816
3 changed files with 83 additions and 1 deletions

View File

@ -0,0 +1,28 @@
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

View File

@ -2,7 +2,8 @@ module Banzai
module Pipeline
class PreProcessPipeline < BasePipeline
def self.filters
[
FilterArray[
Filter::YamlFrontMatterFilter
]
end

View File

@ -0,0 +1,53 @@
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