Commit 0c7626f3 authored by Robert Speicher's avatar Robert Speicher

Merge branch 'rs-frontmatter-pre' into 'master'

Properly display YAML front matter in Markdown

See merge request !3072
parents 2f6ded6d 8eaeda08
......@@ -50,6 +50,8 @@ module GitlabMarkdownHelper
context[:project] ||= @project
text = Banzai.pre_process(text, context)
html = Banzai.render(text, context)
context.merge!(
......
......@@ -7,6 +7,10 @@ module Banzai
Renderer.render_result(text, context)
end
def self.pre_process(text, context)
Renderer.pre_process(text, context)
end
def self.post_process(html, context)
Renderer.post_process(html, context)
end
......
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
module Banzai
module Pipeline
class PreProcessPipeline < BasePipeline
def self.filters
FilterArray[
Filter::YamlFrontMatterFilter
]
end
def self.transform_context(context)
context.merge(
pre_process: true
)
end
end
end
end
......@@ -31,6 +31,12 @@ module Banzai
Pipeline[context[:pipeline]].call(text, context)
end
def self.pre_process(text, context)
pipeline = Pipeline[:pre_process]
pipeline.to_html(text, context)
end
# Perform post-processing on an HTML String
#
# This method is used to perform state-dependent changes to a String of
......
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