Skip to content

Commit ec7f3ea

Browse files
authored
Add missing footnote logic for helpful error messages (hellt#13)
1 parent c707237 commit ec7f3ea

File tree

3 files changed

+65
-1
lines changed

3 files changed

+65
-1
lines changed

fnsort.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@
1919
import re
2020

2121

22+
class MissingFootnoteError(Exception):
23+
pass
24+
25+
2226
def parse_arguments():
2327
parser = argparse.ArgumentParser(description="Tidy Markdown footnotes")
2428
parser.add_argument(
@@ -100,7 +104,13 @@ def sort_footnotes(text):
100104

101105
# Make a list of the footnote-references in order of appearance the original footnotes in text.
102106
# this is not the order of the footnote contents, but the order of the footnote references in the text.
103-
newlabels = [f"[^{i+1}]: {labels[j]}" for (i, j) in enumerate(order)]
107+
try:
108+
newlabels = [f"[^{i+1}]: {labels[j]}" for (i, j) in enumerate(order)]
109+
except KeyError as e:
110+
# add custom exception to improve error output
111+
raise MissingFootnoteError(
112+
f"Missing footnote or inline reference = {repr(e)}"
113+
)
104114
# print(f"newlabels: {newlabels}")
105115

106116
# Remove the old footnote-references and put the new ones at the end of the text.

tests/missing/missing.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# HTTP Methods
2+
3+
1. CONNECT[^c]
4+
1. DELETE[^d] - intentionally no footnote below
5+
1. GET [^g]
6+
1. HEAD [^h]
7+
1. OPTIONS[^o]
8+
1. PATCH[^pa]
9+
1. POST [^po]
10+
1. PUT [^pu]
11+
1. TRACE[^t]
12+
13+
credit[^cr] where it's due, Thank you Mozilla
14+
15+
[^t]: performs a message loop-back test along the path to the target resource
16+
[^o]: requests permitted communication options for a given URL or server
17+
[^g]: requests a representation of the specified resource
18+
[^c]: requests a proxy server establish a HTTP tunnel to a destination server
19+
[^cr]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods
20+
[^oops]: ooops, did I add a footnote that doesn't exist in the inline text?
21+
[^pa]: applies partial modifications to a resource
22+
[^po]: sends data to the server
23+
[^pu]: creates a new resource or replaces a representation of the target resource with the request content
24+
[^h]: requests the metadata of a resource in the form of headers that the server would have sent if GET was used instead

tests/test_footnote_sorting.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,5 +174,35 @@ def test_adjacent_footnote_sort(self):
174174
self.assertEqual(fnsort.sort_footnotes(self.text), self.expected_text)
175175

176176

177+
class TestMissingFootnotes(unittest.TestCase):
178+
@classmethod
179+
def setUpClass(self):
180+
path = "tests/missing"
181+
182+
with open(f"{path}/missing.md") as fh:
183+
self.text = fh.read()
184+
185+
# missing footnotes or inline refs throw exceptions so there's no
186+
# sense in "expected" test file
187+
188+
# technically there is also a "file" kwarg by default
189+
args = {"adjacent": False}
190+
self.args = set_command_line_args(args)
191+
192+
# allow for full diff output
193+
# self.maxDiff = None
194+
195+
196+
def test_missing_footnotes(self):
197+
"""
198+
[negative test] Entire footnote sort process with missing footnotes and inline references
199+
"""
200+
if self.args.adjacent:
201+
self.text = fnsort.space_adjacent_references(self.text)
202+
203+
with self.assertRaises(fnsort.MissingFootnoteError):
204+
fnsort.sort_footnotes(self.text)
205+
206+
177207
if __name__ == "__main__":
178208
unittest.main()

0 commit comments

Comments
 (0)