Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 22 additions & 9 deletions crates/mdbook-markdown/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ pub fn render_markdown_with_path(
let mut in_footnote_name = String::new();
// This is the list of events to build the footnote definition.
let mut in_footnote = Vec::new();
// This is used to add space between consecutive footnotes. I was unable
// to figure out a way to do this just with pure CSS.
let mut prev_was_footnote = false;

let events = new_cmark_parser(text, smart_punctuation)
.map(clean_codeblock_headers)
Expand All @@ -93,6 +96,7 @@ pub fn render_markdown_with_path(
.filter_map(|event| {
match event {
Event::Start(Tag::FootnoteDefinition(name)) => {
prev_was_footnote = false;
if !in_footnote.is_empty() {
log::warn!("internal bug: nested footnote not expected in {path:?}");
}
Expand All @@ -119,14 +123,19 @@ pub fn render_markdown_with_path(
let len = footnote_numbers.len() + 1;
let (n, count) = footnote_numbers.entry(name.clone()).or_insert((len, 0));
*count += 1;
let html = Event::Html(
format!(
"<sup class=\"footnote-reference\" id=\"fr-{name}-{count}\">\
<a href=\"#footnote-{name}\">{n}</a>\
</sup>"
)
.into(),
);
let mut html = String::new();
if prev_was_footnote {
write!(html, " ").unwrap();
}
prev_was_footnote = true;
write!(
html,
"<sup class=\"footnote-reference\" id=\"fr-{name}-{count}\">\
<a href=\"#footnote-{name}\">{n}</a>\
</sup>"
)
.unwrap();
let html = Event::Html(html.into());
if in_footnote_name.is_empty() {
Some(html)
} else {
Expand All @@ -138,9 +147,13 @@ pub fn render_markdown_with_path(
// While inside a footnote, accumulate all events into a local.
_ if !in_footnote_name.is_empty() => {
in_footnote.push(event);
prev_was_footnote = false;
None
}
_ => Some(event),
_ => {
prev_was_footnote = false;
Some(event)
}
}
});

Expand Down
10 changes: 10 additions & 0 deletions tests/testsuite/markdown/footnotes/expected/footnotes.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ <h1 id="footnote-tests"><a class="header" href="#footnote-tests">Footnote tests<
<p>Testing when referring to something earlier.<sup class="footnote-reference" id="fr-define-before-use-1"><a href="#footnote-define-before-use">6</a></sup></p>
<p>Footnote that is defined multiple times.<sup class="footnote-reference" id="fr-multiple-definitions-1"><a href="#footnote-multiple-definitions">7</a></sup></p>
<p>And another<sup class="footnote-reference" id="fr-in-between-1"><a href="#footnote-in-between">8</a></sup> that references the duplicate again.<sup class="footnote-reference" id="fr-multiple-definitions-2"><a href="#footnote-multiple-definitions">7</a></sup></p>
<p>Multiple footnotes in a row.<sup class="footnote-reference" id="fr-a-1"><a href="#footnote-a">9</a></sup> <sup class="footnote-reference" id="fr-b-1"><a href="#footnote-b">10</a></sup> <sup class="footnote-reference" id="fr-c-1"><a href="#footnote-c">11</a></sup></p>
<hr>
<ol class="footnote-definition"><li id="footnote-1">
<p>This is a footnote. <a href="#fr-1-1">↩</a> <a href="#fr-1-2">↩2</a></p>
Expand Down Expand Up @@ -43,4 +44,13 @@ <h1 id="footnote-tests"><a class="header" href="#footnote-tests">Footnote tests<
<li id="footnote-in-between">
<p>Footnote between duplicates. <a href="#fr-in-between-1">↩</a></p>
</li>
<li id="footnote-a">
<p>Footnote 1 <a href="#fr-a-1">↩</a></p>
</li>
<li id="footnote-b">
<p>Footnote 2 <a href="#fr-b-1">↩</a></p>
</li>
<li id="footnote-c">
<p>Footnote 3 <a href="#fr-c-1">↩</a></p>
</li>
</ol>
6 changes: 6 additions & 0 deletions tests/testsuite/markdown/footnotes/src/footnotes.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,9 @@ And another[^in-between] that references the duplicate again.[^multiple-definiti
[^in-between]: Footnote between duplicates.

[^multiple-definitions]: This is the second definition of the footnote with tag multiple-definitions

Multiple footnotes in a row.[^a][^b][^c]

[^a]: Footnote 1
[^b]: Footnote 2
[^c]: Footnote 3
Loading