Skip to content

Commit

Permalink
Allow configuring HTML writer for footnotes
Browse files Browse the repository at this point in the history
Ultimately, it may be possible to work around this, but at present I'm
not clear on that, especially without *other* breaking changes. This
preserves the existing public API and simply adds handling for this
scenario.

One option, which *would* be a breaking change but would also address a
long-standing request (pulldown-cmark#142) is to simply add support for back-links in
*all* footnote types. In that case, there would once again be no need
for configuration. However, that may need to be an *option*, since it's
otherwise a breaking change for all existing users (including any who
may be adding those manually!).
  • Loading branch information
chriskrycho committed Nov 19, 2021
1 parent c4a1fae commit 45d189f
Showing 1 changed file with 46 additions and 3 deletions.
49 changes: 46 additions & 3 deletions src/html.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use std::io::{self, Write};
use crate::escape::{escape_href, escape_html, StrWrite, WriteWrapper};
use crate::strings::CowStr;
use crate::Event::*;
use crate::{Alignment, CodeBlockKind, Event, LinkType, Tag};
use crate::{Alignment, CodeBlockKind, Event, LinkType, Options, Tag};

enum TableState {
Head,
Expand All @@ -47,6 +47,7 @@ struct HtmlWriter<'a, I, W> {
table_alignments: Vec<Alignment>,
table_cell_index: usize,
numbers: HashMap<CowStr<'a>, usize>,
options: Option<super::Options>,
}

impl<'a, I, W> HtmlWriter<'a, I, W>
Expand All @@ -63,6 +64,20 @@ where
table_alignments: vec![],
table_cell_index: 0,
numbers: HashMap::new(),
options: None,
}
}

fn new_with_options(iter: I, writer: W, options: Options) -> Self {
Self {
iter,
writer,
end_newline: true,
table_state: TableState::Head,
table_alignments: vec![],
table_cell_index: 0,
numbers: HashMap::new(),
options: Some(options),
}
}

Expand Down Expand Up @@ -121,6 +136,13 @@ where
let len = self.numbers.len() + 1;
self.write("<sup class=\"footnote-reference\"><a href=\"#")?;
escape_html(&mut self.writer, &name)?;

if self.has_option(Options::ENABLE_STANDARD_FOOTNOTES) {
self.write("\" id=\"")?;
let link_id = String::from(name.as_ref()) + "-ref";
escape_html(&mut self.writer, &link_id)?;
}

self.write("\">")?;
let number = *self.numbers.entry(name).or_insert(len);
write!(&mut self.writer, "{}", number)?;
Expand Down Expand Up @@ -346,8 +368,14 @@ where
self.write("</a>")?;
}
Tag::Image(_, _, _) => (), // shouldn't happen, handled in start
Tag::FootnoteDefinition(_) => {
self.write("</div>\n")?;
Tag::FootnoteDefinition(name) => {
let closing_tag = if self.has_option(Options::ENABLE_STANDARD_FOOTNOTES) {
"</li>\n"
} else {
"</div>\n"
};

self.write(closing_tag)?;
}
}
Ok(())
Expand Down Expand Up @@ -383,6 +411,13 @@ where
}
Ok(())
}

fn has_option(&self, option: Options) -> bool {
match self.options {
Some(options) => options.contains(option),
None => false,
}
}
}

/// Iterate over an `Iterator` of `Event`s, generate HTML for each `Event`, and
Expand Down Expand Up @@ -459,3 +494,11 @@ where
{
HtmlWriter::new(iter, WriteWrapper(writer)).run()
}

pub fn write_html_with_options<'a, I, W>(writer: W, iter: I, options: Options) -> io::Result<()>
where
I: Iterator<Item = Event<'a>>,
W: Write,
{
HtmlWriter::new_with_options(iter, WriteWrapper(writer), options).run()
}

0 comments on commit 45d189f

Please sign in to comment.