Skip to content

Commit

Permalink
Add support for a range to toc_depth.
Browse files Browse the repository at this point in the history
Closes #786.
  • Loading branch information
Klaus Mueller authored and waylan committed Feb 23, 2019
1 parent 12864d2 commit 90833a1
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 10 deletions.
6 changes: 6 additions & 0 deletions docs/change_log/release-3.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ The following new features have been included in the release:
not valid in HTML5. The `refs` and `backrefs` classes already exist and
serve the same purpose (#723).

* A new option for `toc_depth` to set not only the bottom section level,
but also the top section level. A string consisting of two digits
separated by a hyphen in between ("2-5"), defines the top (t) and the
bottom (b) (<ht>..<hb>). A single integer still defines the bottom
section level (<h1>..<hb>) only. (#787).

## Bug fixes

The following bug fixes are included in the 3.1 release:
Expand Down
18 changes: 12 additions & 6 deletions docs/extensions/toc.md
Original file line number Diff line number Diff line change
Expand Up @@ -197,9 +197,15 @@ The following options are provided to configure the output:
Word separator. Character which replaces white space in id. Defaults to "`-`".

* **`toc_depth`**
Define up to which section level "n" (`<h1>` to `<hn>`, where `1 <= n <= 6`)
to include in the Table of Contents. Defaults to `6`.

When used with conjunction with `baselevel` this parameter will limit the
resulting (adjusted) heading. That is, if both `toc_depth` and `baselevel`
are 3, then only the highest level will be present in the table.
Define the range of section levels to include in the Table of Contents.
A single integer (b) defines the bottom section level (<h1>..<hb>) only.
A string consisting of two digits separated by a hyphen in between ("2-5"),
define the top (t) and the bottom (b) (<ht>..<hb>). Defaults to `6` (bottom).

When used with conjunction with `baselevel`, this parameter will not
take the fitted hierarchy from `baselevel` into account. That is, if
both `toc_depth` and `baselevel` are 3, then only the highest level
will be present in the table. If you set `baselevel` to 3 and
`toc_depth` to '2-6', the *first* headline will be `<h3>` and so still
included in the Table of Contents. To exclude this first level, you
have to set `toc_depth` to '4-6'.
16 changes: 12 additions & 4 deletions markdown/extensions/toc.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,11 @@ def __init__(self, md, config):
if self.use_permalinks is None:
self.use_permalinks = config["permalink"]
self.header_rgx = re.compile("[Hh][123456]")
self.toc_depth = config["toc_depth"]
if isinstance(config["toc_depth"], string_type) and '-' in config["toc_depth"]:
self.toc_top, self.toc_bottom = [int(x) for x in config["toc_depth"].split('-')]
else:
self.toc_top = 1
self.toc_bottom = int(config["toc_depth"])

def iterparent(self, node):
''' Iterator wrapper to get allowed parent and child all at once. '''
Expand Down Expand Up @@ -235,7 +239,7 @@ def run(self, doc):
for el in doc.iter():
if isinstance(el.tag, string_type) and self.header_rgx.match(el.tag):
self.set_level(el)
if int(el.tag[-1]) > int(self.toc_depth):
if int(el.tag[-1]) < self.toc_top or int(el.tag[-1]) > self.toc_bottom:
continue
text = ''.join(el.itertext()).strip()

Expand Down Expand Up @@ -296,8 +300,12 @@ def __init__(self, **kwargs):
"Defaults to the headerid ext's slugify function."],
'separator': ['-', 'Word separator. Defaults to "-".'],
"toc_depth": [6,
"Define up to which section level n (<h1>..<hn>) to "
"include in the TOC"]
'Define the range of section levels to include in'
'the Table of Contents. A single integer (b) defines'
'the bottom section level (<h1>..<hb>) only.'
'A string consisting of two digits separated by a hyphen'
'in between ("2-5"), define the top (t) and the'
'bottom (b) (<ht>..<hb>). Defaults to `6` (bottom).'],
}

super(TocExtension, self).__init__(**kwargs)
Expand Down
55 changes: 55 additions & 0 deletions tests/test_extensions.py
Original file line number Diff line number Diff line change
Expand Up @@ -1021,6 +1021,34 @@ def testTocInHeaders(self):
'<h1 id="toc"><em>[TOC]</em></h1>' # noqa
)

def testMinMaxLevel(self):
""" Test toc_height setting """
md = markdown.Markdown(
extensions=[markdown.extensions.toc.TocExtension(toc_depth='3-4')]
)
text = '# Header 1 not in TOC\n\n## Header 2 not in TOC\n\n### Header 3\n\n####Header 4'
self.assertEqual(
md.convert(text),
'<h1>Header 1 not in TOC</h1>\n'
'<h2>Header 2 not in TOC</h2>\n'
'<h3 id="header-3">Header 3</h3>\n'
'<h4 id="header-4">Header 4</h4>'
)
self.assertEqual(
md.toc,
'<div class="toc">\n'
'<ul>\n' # noqa
'<li><a href="#header-3">Header 3</a>' # noqa
'<ul>\n' # noqa
'<li><a href="#header-4">Header 4</a></li>\n' # noqa
'</ul>\n' # noqa
'</li>\n' # noqa
'</ul>\n' # noqa
'</div>\n'
)

self.assertNotIn("Header 1", md.toc)

def testMaxLevel(self):
""" Test toc_depth setting """
md = markdown.Markdown(
Expand Down Expand Up @@ -1048,6 +1076,33 @@ def testMaxLevel(self):

self.assertNotIn("Header 3", md.toc)

def testMinMaxLevelwithBaseLevel(self):
""" Test toc_height setting together with baselevel """
md = markdown.Markdown(
extensions=[markdown.extensions.toc.TocExtension(toc_depth='4-6',
baselevel=3)]
)
text = '# First Header\n\n## Second Level\n\n### Third Level'
self.assertEqual(
md.convert(text),
'<h3>First Header</h3>\n'
'<h4 id="second-level">Second Level</h4>\n'
'<h5 id="third-level">Third Level</h5>'
)
self.assertEqual(
md.toc,
'<div class="toc">\n'
'<ul>\n' # noqa
'<li><a href="#second-level">Second Level</a>' # noqa
'<ul>\n' # noqa
'<li><a href="#third-level">Third Level</a></li>\n' # noqa
'</ul>\n' # noqa
'</li>\n' # noqa
'</ul>\n' # noqa
'</div>\n'
)
self.assertNotIn("First Header", md.toc)

def testMaxLevelwithBaseLevel(self):
""" Test toc_depth setting together with baselevel """
md = markdown.Markdown(
Expand Down

0 comments on commit 90833a1

Please sign in to comment.