From 44a88b611b981f9fb8a4fa50a993a33cbe242b0f Mon Sep 17 00:00:00 2001 From: Paolo Melchiorre Date: Sun, 11 Sep 2022 20:54:47 +0200 Subject: [PATCH 1/6] Fix #1293 Support more customizable toc --- docs/extensions/toc.md | 9 ++ markdown/extensions/toc.py | 22 ++++- tests/test_syntax/extensions/test_toc.py | 111 +++++++++++++++++++++++ 3 files changed, 138 insertions(+), 4 deletions(-) diff --git a/docs/extensions/toc.md b/docs/extensions/toc.md index f8d747902..71237b8e8 100644 --- a/docs/extensions/toc.md +++ b/docs/extensions/toc.md @@ -151,9 +151,18 @@ The following options are provided to configure the output: * **`title`**: Title to insert in the Table of Contents' `
`. Defaults to `None`. +* **`title_class`**: + CSS class used for the title contained in the Table of Contents. Defaults to `toctitle`. + +* **`title_tag`**: + HTML tag used for the title contained in the Table of Contents. Defaults to `span`. + * **`toc_class`**: CSS class(es) used for the `
` containing the Table of Contents. Defaults to `toc`. +* **`toc_tag`**: + HTML tag used for the element containing the Table of Contents. Defaults to `div`. + * **`anchorlink`**: Set to `True` to cause all headers to link to themselves. Default is `False`. diff --git a/markdown/extensions/toc.py b/markdown/extensions/toc.py index 33746d5e6..3acaa44c2 100644 --- a/markdown/extensions/toc.py +++ b/markdown/extensions/toc.py @@ -161,6 +161,9 @@ def __init__(self, md, config): self.slugify = config["slugify"] self.sep = config["separator"] self.toc_class = config["toc_class"] + self.toc_tag = config["toc_tag"] + self.title_tag = config["title_tag"] + self.title_class = config["title_class"] self.use_anchors = parseBoolValue(config["anchorlink"]) self.anchorlink_class = config["anchorlink_class"] self.use_permalinks = parseBoolValue(config["permalink"], False) @@ -245,13 +248,15 @@ def add_permalink(self, c, elem_id): def build_toc_div(self, toc_list): """ Return a string div given a toc list. """ - div = etree.Element("div") - div.attrib["class"] = self.toc_class + div = etree.Element(self.toc_tag) + if self.toc_class: + div.attrib["class"] = self.toc_class # Add title to the div if self.title: - header = etree.SubElement(div, "span") - header.attrib["class"] = "toctitle" + header = etree.SubElement(div, self.title_tag) + if self.title_class: + header.attrib["class"] = self.title_class header.text = self.title def build_etree_ul(toc_list, parent): @@ -335,9 +340,18 @@ def __init__(self, **kwargs): "title": ["", "Title to insert into TOC
- " "Defaults to an empty string"], + "title_class": ['toctitle', + 'CSS class used for the title. ' + 'Defaults to "toctitle"'], + "title_tag": ['span', + 'HTML tag used for the title. ' + 'Defaults to "span"'], "toc_class": ['toc', 'CSS class(es) used for the link. ' 'Defaults to "toclink"'], + "toc_tag": ['div', + 'HTML tag used for the toc. ' + 'Defaults to "div"'], "anchorlink": [False, "True if header should be a self link - " "Defaults to False"], diff --git a/tests/test_syntax/extensions/test_toc.py b/tests/test_syntax/extensions/test_toc.py index d64c6d391..a59a2b619 100644 --- a/tests/test_syntax/extensions/test_toc.py +++ b/tests/test_syntax/extensions/test_toc.py @@ -629,3 +629,114 @@ def testTOCWithCustomClasses(self): ), extensions=[TocExtension(toc_class="custom1 custom2")] ) + + def testTOCWithEmptyClass(self): + + self.assertMarkdownRenders( + self.dedent( + ''' + [TOC] + # Header + ''' + ), + self.dedent( + ''' +
+ +
+

Header

+ ''' + ), + extensions=[TocExtension(toc_class="")] + ) + + def testTOCWithCustomTag(self): + + self.assertMarkdownRenders( + self.dedent( + ''' + [TOC] + # Header + ''' + ), + self.dedent( + ''' +
+ +
+

Header

+ ''' + ), + extensions=[TocExtension(toc_tag="details")] + ) + + def testTOCWithCustomTitleTag(self): + + self.assertMarkdownRenders( + self.dedent( + ''' + [TOC] + # Header + ''' + ), + self.dedent( + ''' +
+
ToC
+ +
+

Header

+ ''' + ), + extensions=[TocExtension(title_tag="div", title='ToC')] + ) + + def testTOCWithCustomTitleClass(self): + + self.assertMarkdownRenders( + self.dedent( + ''' + [TOC] + # Header + ''' + ), + self.dedent( + ''' +
ToC +
+

Header

+ ''' + ), + extensions=[TocExtension(title_class="tocname", title='ToC')] + ) + + def testTOCAsDetailsWithSummary(self): + + self.assertMarkdownRenders( + self.dedent( + ''' + [TOC] + # Header + ''' + ), + self.dedent( + ''' +
+ Summary + +
+

Header

+ ''' + ), + extensions=[TocExtension(title='Summary', title_class="", title_tag="summary", toc_class="", toc_tag="details")] + ) From 7fa74c772169c833770d576cf1449ce4898c78e4 Mon Sep 17 00:00:00 2001 From: Paolo Melchiorre Date: Wed, 26 Jul 2023 09:28:29 +0200 Subject: [PATCH 2/6] Remove not accepted changes --- docs/extensions/toc.md | 6 --- markdown/extensions/toc.py | 18 ++----- tests/test_syntax/extensions/test_toc.py | 68 ------------------------ 3 files changed, 4 insertions(+), 88 deletions(-) diff --git a/docs/extensions/toc.md b/docs/extensions/toc.md index 71237b8e8..1f80c7ea6 100644 --- a/docs/extensions/toc.md +++ b/docs/extensions/toc.md @@ -154,15 +154,9 @@ The following options are provided to configure the output: * **`title_class`**: CSS class used for the title contained in the Table of Contents. Defaults to `toctitle`. -* **`title_tag`**: - HTML tag used for the title contained in the Table of Contents. Defaults to `span`. - * **`toc_class`**: CSS class(es) used for the `
` containing the Table of Contents. Defaults to `toc`. -* **`toc_tag`**: - HTML tag used for the element containing the Table of Contents. Defaults to `div`. - * **`anchorlink`**: Set to `True` to cause all headers to link to themselves. Default is `False`. diff --git a/markdown/extensions/toc.py b/markdown/extensions/toc.py index 3acaa44c2..0880c6513 100644 --- a/markdown/extensions/toc.py +++ b/markdown/extensions/toc.py @@ -161,8 +161,6 @@ def __init__(self, md, config): self.slugify = config["slugify"] self.sep = config["separator"] self.toc_class = config["toc_class"] - self.toc_tag = config["toc_tag"] - self.title_tag = config["title_tag"] self.title_class = config["title_class"] self.use_anchors = parseBoolValue(config["anchorlink"]) self.anchorlink_class = config["anchorlink_class"] @@ -248,15 +246,13 @@ def add_permalink(self, c, elem_id): def build_toc_div(self, toc_list): """ Return a string div given a toc list. """ - div = etree.Element(self.toc_tag) - if self.toc_class: - div.attrib["class"] = self.toc_class + div = etree.Element("div") + div.attrib["class"] = self.toc_class # Add title to the div if self.title: - header = etree.SubElement(div, self.title_tag) - if self.title_class: - header.attrib["class"] = self.title_class + header = etree.SubElement(div, "span") + header.attrib["class"] = "toctitle" header.text = self.title def build_etree_ul(toc_list, parent): @@ -343,15 +339,9 @@ def __init__(self, **kwargs): "title_class": ['toctitle', 'CSS class used for the title. ' 'Defaults to "toctitle"'], - "title_tag": ['span', - 'HTML tag used for the title. ' - 'Defaults to "span"'], "toc_class": ['toc', 'CSS class(es) used for the link. ' 'Defaults to "toclink"'], - "toc_tag": ['div', - 'HTML tag used for the toc. ' - 'Defaults to "div"'], "anchorlink": [False, "True if header should be a self link - " "Defaults to False"], diff --git a/tests/test_syntax/extensions/test_toc.py b/tests/test_syntax/extensions/test_toc.py index a59a2b619..fc2df5187 100644 --- a/tests/test_syntax/extensions/test_toc.py +++ b/tests/test_syntax/extensions/test_toc.py @@ -652,51 +652,6 @@ def testTOCWithEmptyClass(self): extensions=[TocExtension(toc_class="")] ) - def testTOCWithCustomTag(self): - - self.assertMarkdownRenders( - self.dedent( - ''' - [TOC] - # Header - ''' - ), - self.dedent( - ''' -
- -
-

Header

- ''' - ), - extensions=[TocExtension(toc_tag="details")] - ) - - def testTOCWithCustomTitleTag(self): - - self.assertMarkdownRenders( - self.dedent( - ''' - [TOC] - # Header - ''' - ), - self.dedent( - ''' -
-
ToC
- -
-

Header

- ''' - ), - extensions=[TocExtension(title_tag="div", title='ToC')] - ) - def testTOCWithCustomTitleClass(self): self.assertMarkdownRenders( @@ -717,26 +672,3 @@ def testTOCWithCustomTitleClass(self): ), extensions=[TocExtension(title_class="tocname", title='ToC')] ) - - def testTOCAsDetailsWithSummary(self): - - self.assertMarkdownRenders( - self.dedent( - ''' - [TOC] - # Header - ''' - ), - self.dedent( - ''' -
- Summary - -
-

Header

- ''' - ), - extensions=[TocExtension(title='Summary', title_class="", title_tag="summary", toc_class="", toc_tag="details")] - ) From 00b2228733151becba68d1478fdcadc4f2216211 Mon Sep 17 00:00:00 2001 From: Paolo Melchiorre Date: Thu, 10 Aug 2023 08:43:53 +0200 Subject: [PATCH 3/6] Fix tests --- markdown/extensions/toc.py | 3 ++- tests/test_syntax/extensions/test_toc.py | 7 +++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/markdown/extensions/toc.py b/markdown/extensions/toc.py index 0880c6513..9978a9dda 100644 --- a/markdown/extensions/toc.py +++ b/markdown/extensions/toc.py @@ -252,7 +252,8 @@ def build_toc_div(self, toc_list): # Add title to the div if self.title: header = etree.SubElement(div, "span") - header.attrib["class"] = "toctitle" + if self.title_class: + header.attrib["class"] = self.title_class header.text = self.title def build_etree_ul(toc_list, parent): diff --git a/tests/test_syntax/extensions/test_toc.py b/tests/test_syntax/extensions/test_toc.py index fc2df5187..797643643 100644 --- a/tests/test_syntax/extensions/test_toc.py +++ b/tests/test_syntax/extensions/test_toc.py @@ -630,7 +630,7 @@ def testTOCWithCustomClasses(self): extensions=[TocExtension(toc_class="custom1 custom2")] ) - def testTOCWithEmptyClass(self): + def testTOCWithEmptyTitleClass(self): self.assertMarkdownRenders( self.dedent( @@ -641,15 +641,14 @@ def testTOCWithEmptyClass(self): ), self.dedent( ''' -
-
    +
    ToC

    Header

    ''' ), - extensions=[TocExtension(toc_class="")] + extensions=[TocExtension(title_class="", title='ToC')] ) def testTOCWithCustomTitleClass(self): From 57bbef2c8f95527b60252c1c87283350387e799d Mon Sep 17 00:00:00 2001 From: Paolo Melchiorre Date: Thu, 10 Aug 2023 08:49:08 +0200 Subject: [PATCH 4/6] Update documentation --- docs/change_log/index.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/change_log/index.md b/docs/change_log/index.md index b16c372c6..90b228eef 100644 --- a/docs/change_log/index.md +++ b/docs/change_log/index.md @@ -6,6 +6,9 @@ Python-Markdown Change Log *under development*: version 3.5 ([Notes](release-3.5.md)) +* Add customizable TOC title class (#1293). + + July 25, 2023: version 3.4.4 (a bug-fix release). * Add a special case for initial `'s` to smarty extension (#1305). From 134a2ff78bd3b81c7bc35d761c16c6e7253899b4 Mon Sep 17 00:00:00 2001 From: Waylan Limberg Date: Fri, 11 Aug 2023 13:42:28 -0400 Subject: [PATCH 5/6] Update to new changelog --- docs/changelog.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/changelog.md b/docs/changelog.md index 5d4e800f3..d233abfda 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -25,7 +25,8 @@ links to the header, placing them after all other header content. * Add support for cPython version 3.12 (and PyPy 3.10) and drop support for Python version 3.7 (#1357). * Refactor changelog to use the format defined at . -* Updated the list of empty HTML tags (#1353). +* Update the list of empty HTML tags (#1353). +* Add customizable TOC title class to TOC extension (#1293). ## [3.4.4] -- 2023-07-25 From 83c2a38f09ea62dce44ba75973e6087312b0d972 Mon Sep 17 00:00:00 2001 From: Waylan Limberg Date: Fri, 11 Aug 2023 13:49:48 -0400 Subject: [PATCH 6/6] Fix linter issues --- .spell-dict | 1 + markdown/extensions/toc.py | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.spell-dict b/.spell-dict index 87198833b..91cd7bd10 100644 --- a/.spell-dict +++ b/.spell-dict @@ -28,6 +28,7 @@ Cogumbreiro CommonMark convertFile CSS +customizable dedent deliminators deregister diff --git a/markdown/extensions/toc.py b/markdown/extensions/toc.py index 9978a9dda..6d080deb7 100644 --- a/markdown/extensions/toc.py +++ b/markdown/extensions/toc.py @@ -338,8 +338,8 @@ def __init__(self, **kwargs): "Title to insert into TOC
    - " "Defaults to an empty string"], "title_class": ['toctitle', - 'CSS class used for the title. ' - 'Defaults to "toctitle"'], + 'CSS class used for the title. ' + 'Defaults to "toctitle"'], "toc_class": ['toc', 'CSS class(es) used for the link. ' 'Defaults to "toclink"'],