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
fe7d45b1
Commit
fe7d45b1
authored
Aug 03, 2021
by
Jan Beckmann
Committed by
Heinrich Lee Yu
Aug 03, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add support for [TOC] as alias for [[_TOC_]] in Markdown
parent
a20f106e
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
107 additions
and
42 deletions
+107
-42
doc/user/markdown.md
doc/user/markdown.md
+1
-1
lib/banzai/filter/table_of_contents_tag_filter.rb
lib/banzai/filter/table_of_contents_tag_filter.rb
+30
-14
spec/lib/banzai/filter/table_of_contents_tag_filter_spec.rb
spec/lib/banzai/filter/table_of_contents_tag_filter_spec.rb
+31
-7
spec/lib/banzai/pipeline/full_pipeline_spec.rb
spec/lib/banzai/pipeline/full_pipeline_spec.rb
+29
-17
spec/lib/banzai/pipeline/wiki_pipeline_spec.rb
spec/lib/banzai/pipeline/wiki_pipeline_spec.rb
+16
-3
No files found.
doc/user/markdown.md
View file @
fe7d45b1
...
...
@@ -410,7 +410,7 @@ To create a task list, follow the format of an ordered or unordered list:
A table of contents is an unordered list that links to subheadings in the document.
To add a table of contents to a Markdown file, wiki page, issue request, or merge request
description, add
the `[[_TOC_]
]` tag on its own line.
description, add
either the `[[_TOC_]]` or `[TOC
]` tag on its own line.
NOTE:
You can add a table of contents to issues and merge requests, but you can't add one
...
...
lib/banzai/filter/table_of_contents_tag_filter.rb
View file @
fe7d45b1
...
...
@@ -2,26 +2,31 @@
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.
# Using `[[_TOC_]]` or `[TOC]` (both case insensitive), inserts a Table of Contents list.
#
# `[[_TOC_]]` is based on the Gollum syntax. This way we have
# some consistency between with wiki and normal markdown.
# The support for this has been removed from GollumTagsFilter
#
# `[toc]` is a generally accepted form, used by Typora for example.
#
# Based on Banzai::Filter::GollumTagsFilter
class
TableOfContentsTagFilter
<
HTML
::
Pipeline
::
Filter
TEXT_QUERY
=
%q(descendant-or-self::text()[ancestor::p and contains(
., 'TOC
')])
TEXT_QUERY
=
%q(descendant-or-self::text()[ancestor::p and contains(
translate(., 'TOC', 'toc'), '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
)
if
toc_tag?
(
node
)
# Support [TOC] / [toc] tags, which don't have a wrapping <em>-tag
process_toc_tag
(
node
)
elsif
toc_tag_em?
(
node
)
# Support Gollum like ToC tag (`[[_TOC_]]` / `[[_toc_]]`), which will be converted
# into `[[<em>TOC</em>]]` by the markdown filter, so it
# needs special-case handling
process_toc_tag_em
(
node
)
end
end
doc
...
...
@@ -31,14 +36,25 @@ module Banzai
# Replace an entire `[[<em>TOC</em>]]` node with the result generated by
# TableOfContentsFilter
def
process_toc_tag_em
(
node
)
process_toc_tag
(
node
.
parent
)
end
# Replace an entire `[TOC]` node with the result generated by
# TableOfContentsFilter
def
process_toc_tag
(
node
)
node
.
parent
.
parent
.
replace
(
result
[
:toc
].
presence
||
''
)
# we still need to go one step up to also replace the surrounding <p></p>
node
.
parent
.
replace
(
result
[
:toc
].
presence
||
''
)
end
def
toc_tag?
(
node
)
node
.
content
==
'TOC'
&&
def
toc_tag
_em
?
(
node
)
node
.
content
.
casecmp?
(
'toc'
)
&&
node
.
parent
.
name
==
'em'
&&
node
.
parent
.
parent
.
text
==
'[[TOC]]'
node
.
parent
.
parent
.
text
.
casecmp?
(
'[[toc]]'
)
end
def
toc_tag?
(
node
)
node
.
parent
.
text
.
casecmp?
(
'[toc]'
)
end
end
end
...
...
spec/lib/banzai/filter/table_of_contents_tag_filter_spec.rb
View file @
fe7d45b1
...
...
@@ -6,18 +6,42 @@ RSpec.describe Banzai::Filter::TableOfContentsTagFilter do
include
FilterSpecHelper
context
'table of contents'
do
let
(
:html
)
{
'<p>[[<em>TOC</em>]]</p>'
}
shared_examples
'table of contents tag'
do
it
'replaces toc tag with ToC result'
do
doc
=
filter
(
html
,
{},
{
toc:
"FOO"
})
it
'replaces [[<em>TOC</em>]] with ToC result'
do
doc
=
filter
(
html
,
{},
{
toc:
"FOO"
})
expect
(
doc
.
to_html
).
to
eq
(
"FOO"
)
end
expect
(
doc
.
to_html
).
to
eq
(
"FOO"
)
it
'handles an empty ToC result'
do
doc
=
filter
(
html
)
expect
(
doc
.
to_html
).
to
eq
''
end
end
context
'[[_TOC_]] as tag'
do
it_behaves_like
'table of contents tag'
do
let
(
:html
)
{
'<p>[[<em>TOC</em>]]</p>'
}
end
end
it
'handles an empty ToC result'
do
doc
=
filter
(
html
)
context
'[[_toc_]] as tag'
do
it_behaves_like
'table of contents tag'
do
let
(
:html
)
{
'<p>[[<em>toc</em>]]</p>'
}
end
end
context
'[TOC] as tag'
do
it_behaves_like
'table of contents tag'
do
let
(
:html
)
{
'<p>[TOC]</p>'
}
end
end
expect
(
doc
.
to_html
).
to
eq
''
context
'[toc] as tag'
do
it_behaves_like
'table of contents tag'
do
let
(
:html
)
{
'<p>[toc]</p>'
}
end
end
end
end
spec/lib/banzai/pipeline/full_pipeline_spec.rb
View file @
fe7d45b1
...
...
@@ -102,33 +102,45 @@ RSpec.describe Banzai::Pipeline::FullPipeline do
describe
'table of contents'
do
let
(
:project
)
{
create
(
:project
,
:public
)
}
let
(
:markdown
)
do
<<-
MARKDOWN
.
strip_heredoc
[[_TOC_]]
shared_examples
'table of contents tag'
do
|
tag
,
tag_html
|
let
(
:markdown
)
do
<<-
MARKDOWN
.
strip_heredoc
#{
tag
}
# Header
MARKDOWN
end
MARKDOWN
end
let
(
:invalid_markdown
)
do
<<-
MARKDOWN
.
strip_heredoc
test
[[_TOC_]]
let
(
:invalid_markdown
)
do
<<-
MARKDOWN
.
strip_heredoc
test
#{
tag
}
# Header
MARKDOWN
end
MARKDOWN
end
it
'inserts a table of contents'
do
output
=
described_class
.
to_html
(
markdown
,
project:
project
)
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>"
)
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
#{
tag_html
}
"
)
end
end
it
'does not insert a table of contents'
do
output
=
described_class
.
to_html
(
invalid_markdown
,
project:
project
)
context
'with [[_TOC_]] as tag'
do
it_behaves_like
'table of contents tag'
,
'[[_TOC_]]'
,
'[[<em>TOC</em>]]'
end
expect
(
output
).
to
include
(
"test [[<em>TOC</em>]]"
)
context
'with [toc] as tag'
do
it_behaves_like
'table of contents tag'
,
'[toc]'
,
'[toc]'
it_behaves_like
'table of contents tag'
,
'[TOC]'
,
'[TOC]'
end
end
...
...
spec/lib/banzai/pipeline/wiki_pipeline_spec.rb
View file @
fe7d45b1
...
...
@@ -27,7 +27,7 @@ RSpec.describe Banzai::Pipeline::WikiPipeline do
end
end
it
'is case-sensitive'
do
it
'is
not
case-sensitive'
do
markdown
=
<<-
MD
.
strip_heredoc
[[_toc_]]
...
...
@@ -36,9 +36,22 @@ RSpec.describe Banzai::Pipeline::WikiPipeline do
Foo
MD
output
=
described_class
.
to_html
(
markdown
,
project:
project
,
wiki:
wiki
)
result
=
described_class
.
call
(
markdown
,
project:
project
,
wiki:
wiki
)
expect
(
result
[
:output
].
to_html
).
to
include
(
result
[
:toc
])
end
it
'works with alternative [toc] tag'
do
markdown
=
<<-
MD
.
strip_heredoc
[toc]
expect
(
output
).
to
include
(
'[[<em>toc</em>]]'
)
# Header 1
Foo
MD
result
=
described_class
.
call
(
markdown
,
project:
project
,
wiki:
wiki
)
expect
(
result
[
:output
].
to_html
).
to
include
(
result
[
:toc
])
end
it
'handles an empty pipeline result'
do
...
...
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