Commit bc43ad71 authored by Robert Speicher's avatar Robert Speicher

Replace Gollum `[[_TOC_]]` tag with result of TableOfContentsFilter

Closes #2494
parent 9f80118e
...@@ -50,16 +50,24 @@ module Banzai ...@@ -50,16 +50,24 @@ module Banzai
# See https://github.com/gollum/gollum/wiki # See https://github.com/gollum/gollum/wiki
# #
# Rubular: http://rubular.com/r/7dQnE5CUCH # Rubular: http://rubular.com/r/7dQnE5CUCH
TAGS_PATTERN = %r{\[\[(.+?)\]\]} TAGS_PATTERN = %r{\[\[(.+?)\]\]}.freeze
# Pattern to match allowed image extensions # Pattern to match allowed image extensions
ALLOWED_IMAGE_EXTENSIONS = %r{.+(jpg|png|gif|svg|bmp)\z}i ALLOWED_IMAGE_EXTENSIONS = %r{.+(jpg|png|gif|svg|bmp)\z}i.freeze
def call def call
search_text_nodes(doc).each do |node| search_text_nodes(doc).each do |node|
# A Gollum ToC tag is `[[_TOC_]]`, but due to MarkdownFilter running
# before this one, it will be converted into `[[<em>TOC</em>]]`, so it
# needs special-case handling
if toc_tag?(node)
next unless result[:toc].present?
process_toc_tag(node)
else
content = node.content content = node.content
next unless content.match(TAGS_PATTERN) next unless content =~ TAGS_PATTERN
html = process_tag($1) html = process_tag($1)
...@@ -67,12 +75,19 @@ module Banzai ...@@ -67,12 +75,19 @@ module Banzai
node.replace(html) node.replace(html)
end end
end end
end
doc doc
end end
private private
# Replace an entire `[[<em>TOC</em>]]` node with the result generated by
# TableOfContentsFilter
def process_toc_tag(node)
node.parent.parent.replace(result[:toc])
end
# Process a single tag into its final HTML form. # Process a single tag into its final HTML form.
# #
# tag - The String tag contents (the stuff inside the double brackets). # tag - The String tag contents (the stuff inside the double brackets).
...@@ -108,6 +123,12 @@ module Banzai ...@@ -108,6 +123,12 @@ module Banzai
end end
end end
def toc_tag?(node)
node.content == 'TOC' &&
node.parent.name == 'em' &&
node.parent.parent.text == '[[TOC]]'
end
def image?(path) def image?(path)
path =~ ALLOWED_IMAGE_EXTENSIONS path =~ ALLOWED_IMAGE_EXTENSIONS
end end
......
...@@ -4,7 +4,11 @@ module Banzai ...@@ -4,7 +4,11 @@ module Banzai
module Pipeline module Pipeline
class WikiPipeline < FullPipeline class WikiPipeline < FullPipeline
def self.filters def self.filters
super.insert(1, Filter::GollumTagsFilter) @filters ||= begin
filters = super
toc = filters.index(Filter::TableOfContentsFilter)
filters.insert(toc + 1, Filter::GollumTagsFilter)
end
end end
end end
end end
......
...@@ -86,4 +86,56 @@ describe Banzai::Filter::GollumTagsFilter, lib: true do ...@@ -86,4 +86,56 @@ describe Banzai::Filter::GollumTagsFilter, lib: true do
expect(doc.at_css('a')['href']).to eq 'wiki-slug' expect(doc.at_css('a')['href']).to eq 'wiki-slug'
end end
end end
context 'table of contents' do
let(:pipeline) { Banzai::Pipeline[:wiki] }
it 'replaces the tag with the TableOfContentsFilter result' do
markdown = <<-MD.strip_heredoc
[[_TOC_]]
## Header
Foo
MD
result = pipeline.call(markdown, project_wiki: project_wiki, project: project)
aggregate_failures do
expect(result[:output].text).not_to include '[[_TOC_]]'
expect(result[:output].text).not_to include '[['
expect(result[:output].to_html).to include(result[:toc])
end
end
it 'is case-sensitive' do
markdown = <<-MD.strip_heredoc
[[_toc_]]
# Header 1
Foo
MD
output = pipeline.to_html(markdown, project_wiki: project_wiki, project: project)
expect(output).to include('[[<em>toc</em>]]')
end
it 'handles an empty pipeline result' do
# No Markdown headers in this doc, so `result[:toc]` will be empty
markdown = <<-MD.strip_heredoc
[[_TOC_]]
Foo
MD
output = pipeline.to_html(markdown, project_wiki: project_wiki, project: project)
aggregate_failures do
expect(output).not_to include('<ul>')
expect(output).to include('[[<em>TOC</em>]]')
end
end
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