Skip to content

Commit efec51a

Browse files
authored
Footnotes improvements
* footnotes: Allow to use backlink title without footnote number - The placeholder '{}' is optional. So a user can choose to include or not the footnote number in the backlink text. - The modification is backward compatible with configurations using the old '%d' placeholder. * footnotes: Allow to use custom superscript text - The addition of a new SUPERSCRIPT_TEXT option allows to specify a placeholder receiving the footnote number for the superscript text.
1 parent 0f5f8af commit efec51a

File tree

4 files changed

+68
-7
lines changed

4 files changed

+68
-7
lines changed

docs/change_log/release-3.4.md

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ title: Release Notes for v3.4
22

33
# Python-Markdown 3.4 Release Notes
44

5-
Python-Markdown version 3.4 supports Python versions 3.6, 3.7, 3.8, 3.9 and PyPy3.
5+
Python-Markdown version 3.4 supports Python versions 3.6, 3.7, 3.8, 3.9, 3.10 and
6+
PyPy3.
67

78
## Backwards-incompatible changes
89

@@ -37,8 +38,19 @@ The following new features have been included in the 3.3 release:
3738
inter-operation. The old behavior is available by setting `use_align_attribute=True` when
3839
adding the extension.
3940

40-
## Bug fixes
41+
* Some new configuration options have been added to the [footnotes](../extensions/footnotes.md)
42+
extension (#1218):
4143

42-
The following bug fixes are included in the 3.4 release:
44+
* Small refactor of the `BACKLINK_TITLE` option; The use of `format()` instead
45+
of "old" `%d` formatter allows to specify text without the need to have the
46+
number of the footnote in it (like footnotes on Wikipedia for example).
47+
The modification is backward compatible so no configuration change is required.
4348

49+
* Addition of a new option `SUPERSCRIPT_TEXT` that allows to specify a custom
50+
placeholder for the footnote itself in the text.
51+
Ex: `[{}]` will give <sup>[1]</sup>, `({})` will give <sup>(1)</sup>,
52+
or just by default, the current behavior: <sup>1</sup>.
4453

54+
## Bug fixes
55+
56+
The following bug fixes are included in the 3.4 release:

docs/extensions/footnotes.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,10 +86,14 @@ The following options are provided to configure the output:
8686
The text string that links from the footnote definition back to the position
8787
in the document. Defaults to `&#8617;`.
8888

89+
* **`SUPERSCRIPT_TEXT`**:
90+
The text string that links from the position in the document to the footnote
91+
definition. Defaults to `{}`, i.e. only the footnote's number.
92+
8993
* **`BACKLINK_TITLE`**:
9094
The text string for the `title` HTML attribute of the footnote definition link.
91-
`%d` will be replaced by the footnote number. Defaults to `Jump back to
92-
footnote %d in the text`
95+
The placeholder `{}` will be replaced by the footnote number. Defaults to
96+
`Jump back to footnote {} in the text`.
9397

9498
* **`SEPARATOR`**:
9599
The text string used to set the footnote separator. Defaults to `:`.

markdown/extensions/footnotes.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ def __init__(self, **kwargs):
4747
["&#8617;",
4848
"The text string that links from the footnote "
4949
"to the reader's place."],
50+
"SUPERSCRIPT_TEXT":
51+
["{}",
52+
"The text string that links from the reader's place "
53+
"to the footnote."],
5054
"BACKLINK_TITLE":
5155
["Jump back to footnote %d in the text",
5256
"The text string used for the title HTML attribute "
@@ -170,6 +174,9 @@ def makeFootnotesDiv(self, root):
170174
ol = etree.SubElement(div, "ol")
171175
surrogate_parent = etree.Element("div")
172176

177+
# Backward compatibility with old '%d' placeholder
178+
backlink_title = self.getConfig("BACKLINK_TITLE").replace("%d", "{}")
179+
173180
for index, id in enumerate(self.footnotes.keys(), start=1):
174181
li = etree.SubElement(ol, "li")
175182
li.set("id", self.makeFootnoteId(id))
@@ -185,7 +192,7 @@ def makeFootnotesDiv(self, root):
185192
backlink.set("class", "footnote-backref")
186193
backlink.set(
187194
"title",
188-
self.getConfig("BACKLINK_TITLE") % (index)
195+
backlink_title.format(index)
189196
)
190197
backlink.text = FN_BACKLINK_TEXT
191198

@@ -303,7 +310,9 @@ def handleMatch(self, m, data):
303310
sup.set('id', self.footnotes.makeFootnoteRefId(id, found=True))
304311
a.set('href', '#' + self.footnotes.makeFootnoteId(id))
305312
a.set('class', 'footnote-ref')
306-
a.text = str(list(self.footnotes.footnotes.keys()).index(id) + 1)
313+
a.text = self.footnotes.getConfig("SUPERSCRIPT_TEXT").format(
314+
list(self.footnotes.footnotes.keys()).index(id) + 1
315+
)
307316
return sup, m.start(0), m.end(0)
308317
else:
309318
return None, None, None

tests/test_syntax/extensions/test_footnotes.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,3 +300,39 @@ def test_footnote_separator(self):
300300
'</div>',
301301
extension_configs={'footnotes': {'SEPARATOR': '-'}}
302302
)
303+
304+
def test_backlink_title(self):
305+
"""Test backlink title configuration without placeholder."""
306+
307+
self.assertMarkdownRenders(
308+
'paragraph[^1]\n\n[^1]: A Footnote',
309+
'<p>paragraph<sup id="fnref:1"><a class="footnote-ref" href="#fn:1">1</a></sup></p>\n'
310+
'<div class="footnote">\n'
311+
'<hr />\n'
312+
'<ol>\n'
313+
'<li id="fn:1">\n'
314+
'<p>A Footnote&#160;<a class="footnote-backref" href="#fnref:1"'
315+
' title="Jump back to footnote">&#8617;</a></p>\n'
316+
'</li>\n'
317+
'</ol>\n'
318+
'</div>',
319+
extension_configs={'footnotes': {'BACKLINK_TITLE': 'Jump back to footnote'}}
320+
)
321+
322+
def test_superscript_text(self):
323+
"""Test superscript text configuration."""
324+
325+
self.assertMarkdownRenders(
326+
'paragraph[^1]\n\n[^1]: A Footnote',
327+
'<p>paragraph<sup id="fnref:1"><a class="footnote-ref" href="#fn:1">[1]</a></sup></p>\n'
328+
'<div class="footnote">\n'
329+
'<hr />\n'
330+
'<ol>\n'
331+
'<li id="fn:1">\n'
332+
'<p>A Footnote&#160;<a class="footnote-backref" href="#fnref:1"'
333+
' title="Jump back to footnote 1 in the text">&#8617;</a></p>\n'
334+
'</li>\n'
335+
'</ol>\n'
336+
'</div>',
337+
extension_configs={'footnotes': {'SUPERSCRIPT_TEXT': '[{}]'}}
338+
)

0 commit comments

Comments
 (0)