html: avoid peek of next event
Try to make rendering of each event independent. The only case where we need to peek is when a backref link should be added to the last paragraph within a footnote. Before, when exiting a paragraph, we would peek and add the link before emitting the close tag if the next event is a the footnote end. Now, the paragraph end event skips emitting a paragraph close tag if it is within a footnote. The next event will then always close the paragraph, and if it is a footnote end, it will add the backref link before closing.
This commit is contained in:
parent
7fcc802415
commit
336927faef
1 changed files with 23 additions and 22 deletions
45
src/html.rs
45
src/html.rs
|
@ -73,8 +73,8 @@ struct Writer<'s, I: Iterator<Item = Event<'s>>, W> {
|
||||||
list_tightness: Vec<bool>,
|
list_tightness: Vec<bool>,
|
||||||
encountered_footnote: bool,
|
encountered_footnote: bool,
|
||||||
footnote_number: Option<std::num::NonZeroUsize>,
|
footnote_number: Option<std::num::NonZeroUsize>,
|
||||||
footnote_backlink_written: bool,
|
|
||||||
first_line: bool,
|
first_line: bool,
|
||||||
|
close_para: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'s, I: Iterator<Item = Event<'s>>, W: std::fmt::Write> Writer<'s, I, W> {
|
impl<'s, I: Iterator<Item = Event<'s>>, W: std::fmt::Write> Writer<'s, I, W> {
|
||||||
|
@ -87,13 +87,22 @@ impl<'s, I: Iterator<Item = Event<'s>>, W: std::fmt::Write> Writer<'s, I, W> {
|
||||||
list_tightness: Vec::new(),
|
list_tightness: Vec::new(),
|
||||||
encountered_footnote: false,
|
encountered_footnote: false,
|
||||||
footnote_number: None,
|
footnote_number: None,
|
||||||
footnote_backlink_written: false,
|
|
||||||
first_line: true,
|
first_line: true,
|
||||||
|
close_para: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write(&mut self) -> std::fmt::Result {
|
fn write(&mut self) -> std::fmt::Result {
|
||||||
while let Some(e) = self.events.next() {
|
while let Some(e) = self.events.next() {
|
||||||
|
let close_para = self.close_para;
|
||||||
|
if close_para {
|
||||||
|
self.close_para = false;
|
||||||
|
if !matches!(&e, Event::End(Container::Footnote { .. })) {
|
||||||
|
// no need to add href before para close
|
||||||
|
self.out.write_str("</p>")?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
match e {
|
match e {
|
||||||
Event::Start(c, attrs) => {
|
Event::Start(c, attrs) => {
|
||||||
if c.is_block() && !self.first_line {
|
if c.is_block() && !self.first_line {
|
||||||
|
@ -143,7 +152,6 @@ impl<'s, I: Iterator<Item = Event<'s>>, W: std::fmt::Write> Writer<'s, I, W> {
|
||||||
.write_str("<section role=\"doc-endnotes\">\n<hr>\n<ol>\n")?;
|
.write_str("<section role=\"doc-endnotes\">\n<hr>\n<ol>\n")?;
|
||||||
}
|
}
|
||||||
write!(self.out, "<li id=\"fn{}\">", number)?;
|
write!(self.out, "<li id=\"fn{}\">", number)?;
|
||||||
self.footnote_backlink_written = false;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Container::Table => self.out.write_str("<table")?,
|
Container::Table => self.out.write_str("<table")?,
|
||||||
|
@ -329,13 +337,15 @@ impl<'s, I: Iterator<Item = Event<'s>>, W: std::fmt::Write> Writer<'s, I, W> {
|
||||||
Container::DescriptionList => self.out.write_str("</dl>")?,
|
Container::DescriptionList => self.out.write_str("</dl>")?,
|
||||||
Container::DescriptionDetails => self.out.write_str("</dd>")?,
|
Container::DescriptionDetails => self.out.write_str("</dd>")?,
|
||||||
Container::Footnote { number, .. } => {
|
Container::Footnote { number, .. } => {
|
||||||
if !self.footnote_backlink_written {
|
if !close_para {
|
||||||
write!(
|
// create a new paragraph
|
||||||
self.out,
|
self.out.write_str("\n<p>")?;
|
||||||
"\n<p><a href=\"#fnref{}\" role=\"doc-backlink\">↩︎︎</a></p>",
|
|
||||||
number,
|
|
||||||
)?;
|
|
||||||
}
|
}
|
||||||
|
write!(
|
||||||
|
self.out,
|
||||||
|
r##"<a href="#fnref{}" role="doc-backlink">↩︎︎</a></p>"##,
|
||||||
|
number,
|
||||||
|
)?;
|
||||||
self.out.write_str("\n</li>")?;
|
self.out.write_str("\n</li>")?;
|
||||||
self.footnote_number = None;
|
self.footnote_number = None;
|
||||||
}
|
}
|
||||||
|
@ -347,20 +357,11 @@ impl<'s, I: Iterator<Item = Event<'s>>, W: std::fmt::Write> Writer<'s, I, W> {
|
||||||
if matches!(self.list_tightness.last(), Some(true)) {
|
if matches!(self.list_tightness.last(), Some(true)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if let Some(num) = self.footnote_number {
|
if self.footnote_number.is_none() {
|
||||||
if matches!(
|
self.out.write_str("</p>")?;
|
||||||
self.events.peek(),
|
} else {
|
||||||
Some(Event::End(Container::Footnote { .. }))
|
self.close_para = true;
|
||||||
) {
|
|
||||||
write!(
|
|
||||||
self.out,
|
|
||||||
r##"<a href="#fnref{}" role="doc-backlink">↩︎︎</a>"##,
|
|
||||||
num
|
|
||||||
)?;
|
|
||||||
self.footnote_backlink_written = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
self.out.write_str("</p>")?;
|
|
||||||
}
|
}
|
||||||
Container::Heading { level, .. } => write!(self.out, "</h{}>", level)?,
|
Container::Heading { level, .. } => write!(self.out, "</h{}>", level)?,
|
||||||
Container::TableCell { head: false, .. } => self.out.write_str("</td>")?,
|
Container::TableCell { head: false, .. } => self.out.write_str("</td>")?,
|
||||||
|
|
Loading…
Reference in a new issue