Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
9f5d4574
Commit
9f5d4574
authored
Feb 10, 2020
by
Brett Walker
Committed by
Heinrich Lee Yu
Feb 10, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Enable wiki table of contents tag for GFM
`[[_TOC_]]` now gets converted for normal GDM markdown
parent
4d6dc20d
Changes
8
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
112 additions
and
48 deletions
+112
-48
changelogs/unreleased/21901-support-for-toc-in-readme-files.yml
...logs/unreleased/21901-support-for-toc-in-readme-files.yml
+5
-0
lib/banzai/filter/gollum_tags_filter.rb
lib/banzai/filter/gollum_tags_filter.rb
+5
-31
lib/banzai/filter/table_of_contents_tag_filter.rb
lib/banzai/filter/table_of_contents_tag_filter.rb
+45
-0
lib/banzai/pipeline/gfm_pipeline.rb
lib/banzai/pipeline/gfm_pipeline.rb
+1
-0
spec/lib/banzai/filter/gollum_tags_filter_spec.rb
spec/lib/banzai/filter/gollum_tags_filter_spec.rb
+0
-15
spec/lib/banzai/filter/table_of_contents_tag_filter_spec.rb
spec/lib/banzai/filter/table_of_contents_tag_filter_spec.rb
+23
-0
spec/lib/banzai/pipeline/full_pipeline_spec.rb
spec/lib/banzai/pipeline/full_pipeline_spec.rb
+31
-0
spec/support/helpers/filter_spec_helper.rb
spec/support/helpers/filter_spec_helper.rb
+2
-2
No files found.
changelogs/unreleased/21901-support-for-toc-in-readme-files.yml
0 → 100644
View file @
9f5d4574
---
title
:
Support for table of contents tag in GitLab Flavored Markdown
merge_request
:
24196
author
:
type
:
added
lib/banzai/filter/gollum_tags_filter.rb
View file @
9f5d4574
...
@@ -25,12 +25,10 @@ module Banzai
...
@@ -25,12 +25,10 @@ module Banzai
# * [[http://example.com/images/logo.png]]
# * [[http://example.com/images/logo.png]]
# * [[http://example.com/images/logo.png|alt=Logo]]
# * [[http://example.com/images/logo.png|alt=Logo]]
#
#
# - Insert a Table of Contents list:
#
# * [[_TOC_]]
#
# Based on Gollum::Filter::Tags
# Based on Gollum::Filter::Tags
#
#
# Note: the table of contents tag is now handled by TableOfContentsTagFilter
#
# Context options:
# Context options:
# :project_wiki (required) - Current project wiki.
# :project_wiki (required) - Current project wiki.
#
#
...
@@ -64,23 +62,11 @@ module Banzai
...
@@ -64,23 +62,11 @@ module Banzai
def
call
def
call
doc
.
search
(
".//text()"
).
each
do
|
node
|
doc
.
search
(
".//text()"
).
each
do
|
node
|
next
if
has_ancestor?
(
node
,
IGNORED_ANCESTOR_TAGS
)
next
if
has_ancestor?
(
node
,
IGNORED_ANCESTOR_TAGS
)
next
unless
node
.
content
=~
TAGS_PATTERN
# 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
)
process_toc_tag
(
node
)
else
content
=
node
.
content
next
unless
content
=~
TAGS_PATTERN
html
=
process_tag
(
$1
)
html
=
process_tag
(
$1
)
if
html
&&
html
!=
node
.
content
node
.
replace
(
html
)
if
html
&&
html
!=
node
.
content
node
.
replace
(
html
)
end
end
end
end
doc
doc
...
@@ -88,12 +74,6 @@ module Banzai
...
@@ -88,12 +74,6 @@ module Banzai
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
].
presence
||
''
)
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).
...
@@ -129,12 +109,6 @@ module Banzai
...
@@ -129,12 +109,6 @@ 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
...
...
lib/banzai/filter/table_of_contents_tag_filter.rb
0 → 100644
View file @
9f5d4574
# frozen_string_literal: true
module
Banzai
module
Filter
# Using `[[_TOC_]]`, inserts a Table of Contents list.
# This syntax is based on the Gollum syntax. This way we have
# some consistency between with wiki and normal markdown.
# If there ever emerges a markdown standard, we can implement
# that here.
#
# The support for this has been removed from GollumTagsFilter
#
# Based on Banzai::Filter::GollumTagsFilter
class
TableOfContentsTagFilter
<
HTML
::
Pipeline
::
Filter
TEXT_QUERY
=
%q(descendant-or-self::text()[ancestor::p and contains(., 'TOC')])
def
call
return
doc
if
context
[
:no_header_anchors
]
doc
.
xpath
(
TEXT_QUERY
).
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
process_toc_tag
(
node
)
if
toc_tag?
(
node
)
end
doc
end
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
].
presence
||
''
)
end
def
toc_tag?
(
node
)
node
.
content
==
'TOC'
&&
node
.
parent
.
name
==
'em'
&&
node
.
parent
.
parent
.
text
==
'[[TOC]]'
end
end
end
end
lib/banzai/pipeline/gfm_pipeline.rb
View file @
9f5d4574
...
@@ -32,6 +32,7 @@ module Banzai
...
@@ -32,6 +32,7 @@ module Banzai
Filter
::
InlineMetricsFilter
,
Filter
::
InlineMetricsFilter
,
Filter
::
InlineGrafanaMetricsFilter
,
Filter
::
InlineGrafanaMetricsFilter
,
Filter
::
TableOfContentsFilter
,
Filter
::
TableOfContentsFilter
,
Filter
::
TableOfContentsTagFilter
,
Filter
::
AutolinkFilter
,
Filter
::
AutolinkFilter
,
Filter
::
ExternalLinkFilter
,
Filter
::
ExternalLinkFilter
,
Filter
::
SuggestionFilter
,
Filter
::
SuggestionFilter
,
...
...
spec/lib/banzai/filter/gollum_tags_filter_spec.rb
View file @
9f5d4574
...
@@ -100,19 +100,4 @@ describe Banzai::Filter::GollumTagsFilter do
...
@@ -100,19 +100,4 @@ describe Banzai::Filter::GollumTagsFilter do
expect
(
doc
.
at_css
(
'code'
).
text
).
to
eq
'[[link-in-backticks]]'
expect
(
doc
.
at_css
(
'code'
).
text
).
to
eq
'[[link-in-backticks]]'
end
end
end
end
context
'table of contents'
do
it
'replaces [[<em>TOC</em>]] with ToC result'
do
doc
=
described_class
.
call
(
"<p>[[<em>TOC</em>]]</p>"
,
{
project_wiki:
project_wiki
},
{
toc:
"FOO"
})
expect
(
doc
.
to_html
).
to
eq
(
"FOO"
)
end
it
'handles an empty ToC result'
do
input
=
"<p>[[<em>TOC</em>]]</p>"
doc
=
described_class
.
call
(
input
,
project_wiki:
project_wiki
)
expect
(
doc
.
to_html
).
to
eq
''
end
end
end
end
spec/lib/banzai/filter/table_of_contents_tag_filter_spec.rb
0 → 100644
View file @
9f5d4574
# frozen_string_literal: true
require
'spec_helper'
describe
Banzai
::
Filter
::
TableOfContentsTagFilter
do
include
FilterSpecHelper
context
'table of contents'
do
let
(
:html
)
{
'<p>[[<em>TOC</em>]]</p>'
}
it
'replaces [[<em>TOC</em>]] with ToC result'
do
doc
=
filter
(
html
,
{},
{
toc:
"FOO"
})
expect
(
doc
.
to_html
).
to
eq
(
"FOO"
)
end
it
'handles an empty ToC result'
do
doc
=
filter
(
html
)
expect
(
doc
.
to_html
).
to
eq
''
end
end
end
spec/lib/banzai/pipeline/full_pipeline_spec.rb
View file @
9f5d4574
...
@@ -99,4 +99,35 @@ describe Banzai::Pipeline::FullPipeline do
...
@@ -99,4 +99,35 @@ describe Banzai::Pipeline::FullPipeline do
end
end
end
end
end
end
describe
'table of contents'
do
let
(
:project
)
{
create
(
:project
,
:public
)
}
let
(
:markdown
)
do
<<-
MARKDOWN
.
strip_heredoc
[[_TOC_]]
# Header
MARKDOWN
end
let
(
:invalid_markdown
)
do
<<-
MARKDOWN
.
strip_heredoc
test [[_TOC_]]
# Header
MARKDOWN
end
it
'inserts a table of contents'
do
output
=
described_class
.
to_html
(
markdown
,
project:
project
)
expect
(
output
).
to
include
(
"<ul class=
\"
section-nav
\"
>"
)
expect
(
output
).
to
include
(
"<li><a href=
\"
#header
\"
>Header</a></li>"
)
end
it
'does not insert a table of contents'
do
output
=
described_class
.
to_html
(
invalid_markdown
,
project:
project
)
expect
(
output
).
to
include
(
"test [[<em>TOC</em>]]"
)
end
end
end
end
spec/support/helpers/filter_spec_helper.rb
View file @
9f5d4574
...
@@ -15,7 +15,7 @@ module FilterSpecHelper
...
@@ -15,7 +15,7 @@ module FilterSpecHelper
# context - Hash context for the filter. (default: {project: project})
# context - Hash context for the filter. (default: {project: project})
#
#
# Returns a Nokogiri::XML::DocumentFragment
# Returns a Nokogiri::XML::DocumentFragment
def
filter
(
html
,
context
=
{})
def
filter
(
html
,
context
=
{}
,
result
=
nil
)
if
defined?
(
project
)
if
defined?
(
project
)
context
.
reverse_merge!
(
project:
project
)
context
.
reverse_merge!
(
project:
project
)
end
end
...
@@ -25,7 +25,7 @@ module FilterSpecHelper
...
@@ -25,7 +25,7 @@ module FilterSpecHelper
context
=
context
.
merge
(
render_context:
render_context
)
context
=
context
.
merge
(
render_context:
render_context
)
described_class
.
call
(
html
,
context
)
described_class
.
call
(
html
,
context
,
result
)
end
end
# Get an instance of the Filter class
# Get an instance of the Filter class
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment