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…
	
	Add table
		Add a link
		
	
		Reference in a new issue