summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKlaus Mueller <earth@klml.de>2019-02-23 03:04:40 +0100
committerWaylan Limberg <waylan.limberg@icloud.com>2019-02-22 21:04:40 -0500
commit90833a19eae63f6e787d7718180bd48ca906575a (patch)
treeb459b3766dfb65efa1f107c8a19011d8c225d6cd
parent12864d276855231c1d72f0da8efd8dace20a9062 (diff)
downloadpython-markdown-90833a19eae63f6e787d7718180bd48ca906575a.tar.gz
Add support for a range to toc_depth.
Closes #786.
-rw-r--r--docs/change_log/release-3.1.md6
-rw-r--r--docs/extensions/toc.md18
-rw-r--r--markdown/extensions/toc.py16
-rw-r--r--tests/test_extensions.py55
4 files changed, 85 insertions, 10 deletions
diff --git a/docs/change_log/release-3.1.md b/docs/change_log/release-3.1.md
index 55dde79..b95eb16 100644
--- a/docs/change_log/release-3.1.md
+++ b/docs/change_log/release-3.1.md
@@ -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:
diff --git a/docs/extensions/toc.md b/docs/extensions/toc.md
index f6111b2..ae54cba 100644
--- a/docs/extensions/toc.md
+++ b/docs/extensions/toc.md
@@ -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'. \ No newline at end of file
diff --git a/markdown/extensions/toc.py b/markdown/extensions/toc.py
index f6121c2..0985e0f 100644
--- a/markdown/extensions/toc.py
+++ b/markdown/extensions/toc.py
@@ -135,7 +135,11 @@ class TocTreeprocessor(Treeprocessor):
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. '''
@@ -235,7 +239,7 @@ class TocTreeprocessor(Treeprocessor):
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()
@@ -296,8 +300,12 @@ class TocExtension(Extension):
"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)
diff --git a/tests/test_extensions.py b/tests/test_extensions.py
index 2203a78..b4c0779 100644
--- a/tests/test_extensions.py
+++ b/tests/test_extensions.py
@@ -1021,6 +1021,34 @@ class TestTOC(TestCaseWithAssertStartsWith):
'<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(
@@ -1048,6 +1076,33 @@ class TestTOC(TestCaseWithAssertStartsWith):
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(