html: rm events/out from Writer
separate input/output from rendering state
This commit is contained in:
		
					parent
					
						
							
								f5724fcc9c
							
						
					
				
			
			
				commit
				
					
						3d1b5f2115
					
				
			
		
					 1 changed files with 168 additions and 160 deletions
				
			
		
							
								
								
									
										294
									
								
								src/html.rs
									
										
									
									
									
								
							
							
						
						
									
										294
									
								
								src/html.rs
									
										
									
									
									
								
							|  | @ -39,7 +39,7 @@ impl Render for Renderer { | ||||||
|         events: I, |         events: I, | ||||||
|         out: W, |         out: W, | ||||||
|     ) -> std::fmt::Result { |     ) -> std::fmt::Result { | ||||||
|         Writer::new(events, out).write() |         Writer::default().write(events, out) | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -49,9 +49,7 @@ enum Raw { | ||||||
|     Other, |     Other, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| struct Writer<'s, I: Iterator<Item = Event<'s>>, W> { | struct Writer { | ||||||
|     events: I, |  | ||||||
|     out: W, |  | ||||||
|     raw: Raw, |     raw: Raw, | ||||||
|     img_alt_text: usize, |     img_alt_text: usize, | ||||||
|     list_tightness: Vec<bool>, |     list_tightness: Vec<bool>, | ||||||
|  | @ -61,11 +59,9 @@ struct Writer<'s, I: Iterator<Item = Event<'s>>, W> { | ||||||
|     close_para: bool, |     close_para: bool, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl<'s, I: Iterator<Item = Event<'s>>, W: std::fmt::Write> Writer<'s, I, W> { | impl Default for Writer { | ||||||
|     fn new(events: I, out: W) -> Self { |     fn default() -> Self { | ||||||
|         Self { |         Self { | ||||||
|             events, |  | ||||||
|             out, |  | ||||||
|             raw: Raw::None, |             raw: Raw::None, | ||||||
|             img_alt_text: 0, |             img_alt_text: 0, | ||||||
|             list_tightness: Vec::new(), |             list_tightness: Vec::new(), | ||||||
|  | @ -75,9 +71,15 @@ impl<'s, I: Iterator<Item = Event<'s>>, W: std::fmt::Write> Writer<'s, I, W> { | ||||||
|             close_para: false, |             close_para: false, | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
|     fn write(&mut self) -> std::fmt::Result { | impl Writer { | ||||||
|         while let Some(e) = self.events.next() { |     fn write<'s>( | ||||||
|  |         &mut self, | ||||||
|  |         events: impl Iterator<Item = Event<'s>>, | ||||||
|  |         mut out: impl std::fmt::Write, | ||||||
|  |     ) -> std::fmt::Result { | ||||||
|  |         for e in events { | ||||||
|             if matches!(&e, Event::Blankline | Event::Escape) { |             if matches!(&e, Event::Blankline | Event::Escape) { | ||||||
|                 continue; |                 continue; | ||||||
|             } |             } | ||||||
|  | @ -87,32 +89,30 @@ impl<'s, I: Iterator<Item = Event<'s>>, W: std::fmt::Write> Writer<'s, I, W> { | ||||||
|                 self.close_para = false; |                 self.close_para = false; | ||||||
|                 if !matches!(&e, Event::End(Container::Footnote { .. })) { |                 if !matches!(&e, Event::End(Container::Footnote { .. })) { | ||||||
|                     // no need to add href before para close
 |                     // no need to add href before para close
 | ||||||
|                     self.out.write_str("</p>")?; |                     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 { | ||||||
|                         self.out.write_char('\n')?; |                         out.write_char('\n')?; | ||||||
|                     } |                     } | ||||||
|                     if self.img_alt_text > 0 && !matches!(c, Container::Image(..)) { |                     if self.img_alt_text > 0 && !matches!(c, Container::Image(..)) { | ||||||
|                         continue; |                         continue; | ||||||
|                     } |                     } | ||||||
|                     match &c { |                     match &c { | ||||||
|                         Container::Blockquote => self.out.write_str("<blockquote")?, |                         Container::Blockquote => out.write_str("<blockquote")?, | ||||||
|                         Container::List { kind, tight } => { |                         Container::List { kind, tight } => { | ||||||
|                             self.list_tightness.push(*tight); |                             self.list_tightness.push(*tight); | ||||||
|                             match kind { |                             match kind { | ||||||
|                                 ListKind::Unordered | ListKind::Task => { |                                 ListKind::Unordered | ListKind::Task => out.write_str("<ul")?, | ||||||
|                                     self.out.write_str("<ul")? |  | ||||||
|                                 } |  | ||||||
|                                 ListKind::Ordered { |                                 ListKind::Ordered { | ||||||
|                                     numbering, start, .. |                                     numbering, start, .. | ||||||
|                                 } => { |                                 } => { | ||||||
|                                     self.out.write_str("<ol")?; |                                     out.write_str("<ol")?; | ||||||
|                                     if *start > 1 { |                                     if *start > 1 { | ||||||
|                                         write!(self.out, r#" start="{}""#, start)?; |                                         write!(out, r#" start="{}""#, start)?; | ||||||
|                                     } |                                     } | ||||||
|                                     if let Some(ty) = match numbering { |                                     if let Some(ty) = match numbering { | ||||||
|                                         Decimal => None, |                                         Decimal => None, | ||||||
|  | @ -121,65 +121,64 @@ impl<'s, I: Iterator<Item = Event<'s>>, W: std::fmt::Write> Writer<'s, I, W> { | ||||||
|                                         RomanLower => Some('i'), |                                         RomanLower => Some('i'), | ||||||
|                                         RomanUpper => Some('I'), |                                         RomanUpper => Some('I'), | ||||||
|                                     } { |                                     } { | ||||||
|                                         write!(self.out, r#" type="{}""#, ty)?; |                                         write!(out, r#" type="{}""#, ty)?; | ||||||
|                                     } |                                     } | ||||||
|                                 } |                                 } | ||||||
|                             } |                             } | ||||||
|                         } |                         } | ||||||
|                         Container::ListItem | Container::TaskListItem { .. } => { |                         Container::ListItem | Container::TaskListItem { .. } => { | ||||||
|                             self.out.write_str("<li")?; |                             out.write_str("<li")?; | ||||||
|                         } |                         } | ||||||
|                         Container::DescriptionList => self.out.write_str("<dl")?, |                         Container::DescriptionList => out.write_str("<dl")?, | ||||||
|                         Container::DescriptionDetails => self.out.write_str("<dd")?, |                         Container::DescriptionDetails => out.write_str("<dd")?, | ||||||
|                         Container::Footnote { number, .. } => { |                         Container::Footnote { number, .. } => { | ||||||
|                             assert!(self.footnote_number.is_none()); |                             assert!(self.footnote_number.is_none()); | ||||||
|                             self.footnote_number = Some((*number).try_into().unwrap()); |                             self.footnote_number = Some((*number).try_into().unwrap()); | ||||||
|                             if !self.encountered_footnote { |                             if !self.encountered_footnote { | ||||||
|                                 self.encountered_footnote = true; |                                 self.encountered_footnote = true; | ||||||
|                                 self.out |                                 out.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!(out, "<li id=\"fn{}\">", number)?; | ||||||
|                             continue; |                             continue; | ||||||
|                         } |                         } | ||||||
|                         Container::Table => self.out.write_str("<table")?, |                         Container::Table => out.write_str("<table")?, | ||||||
|                         Container::TableRow { .. } => self.out.write_str("<tr")?, |                         Container::TableRow { .. } => out.write_str("<tr")?, | ||||||
|                         Container::Section { .. } => self.out.write_str("<section")?, |                         Container::Section { .. } => out.write_str("<section")?, | ||||||
|                         Container::Div { .. } => self.out.write_str("<div")?, |                         Container::Div { .. } => out.write_str("<div")?, | ||||||
|                         Container::Paragraph => { |                         Container::Paragraph => { | ||||||
|                             if matches!(self.list_tightness.last(), Some(true)) { |                             if matches!(self.list_tightness.last(), Some(true)) { | ||||||
|                                 continue; |                                 continue; | ||||||
|                             } |                             } | ||||||
|                             self.out.write_str("<p")?; |                             out.write_str("<p")?; | ||||||
|                         } |                         } | ||||||
|                         Container::Heading { level, .. } => write!(self.out, "<h{}", level)?, |                         Container::Heading { level, .. } => write!(out, "<h{}", level)?, | ||||||
|                         Container::TableCell { head: false, .. } => self.out.write_str("<td")?, |                         Container::TableCell { head: false, .. } => out.write_str("<td")?, | ||||||
|                         Container::TableCell { head: true, .. } => self.out.write_str("<th")?, |                         Container::TableCell { head: true, .. } => out.write_str("<th")?, | ||||||
|                         Container::Caption => self.out.write_str("<caption")?, |                         Container::Caption => out.write_str("<caption")?, | ||||||
|                         Container::DescriptionTerm => self.out.write_str("<dt")?, |                         Container::DescriptionTerm => out.write_str("<dt")?, | ||||||
|                         Container::CodeBlock { .. } => self.out.write_str("<pre")?, |                         Container::CodeBlock { .. } => out.write_str("<pre")?, | ||||||
|                         Container::Span | Container::Math { .. } => self.out.write_str("<span")?, |                         Container::Span | Container::Math { .. } => out.write_str("<span")?, | ||||||
|                         Container::Link(dst, ty) => { |                         Container::Link(dst, ty) => { | ||||||
|                             if matches!(ty, LinkType::Span(SpanLinkType::Unresolved)) { |                             if matches!(ty, LinkType::Span(SpanLinkType::Unresolved)) { | ||||||
|                                 self.out.write_str("<a")?; |                                 out.write_str("<a")?; | ||||||
|                             } else { |                             } else { | ||||||
|                                 self.out.write_str(r#"<a href=""#)?; |                                 out.write_str(r#"<a href=""#)?; | ||||||
|                                 if matches!(ty, LinkType::Email) { |                                 if matches!(ty, LinkType::Email) { | ||||||
|                                     self.out.write_str("mailto:")?; |                                     out.write_str("mailto:")?; | ||||||
|                                 } |                                 } | ||||||
|                                 self.write_attr(dst)?; |                                 write_attr(dst, &mut out)?; | ||||||
|                                 self.out.write_char('"')?; |                                 out.write_char('"')?; | ||||||
|                             } |                             } | ||||||
|                         } |                         } | ||||||
|                         Container::Image(..) => { |                         Container::Image(..) => { | ||||||
|                             self.img_alt_text += 1; |                             self.img_alt_text += 1; | ||||||
|                             if self.img_alt_text == 1 { |                             if self.img_alt_text == 1 { | ||||||
|                                 self.out.write_str("<img")?; |                                 out.write_str("<img")?; | ||||||
|                             } else { |                             } else { | ||||||
|                                 continue; |                                 continue; | ||||||
|                             } |                             } | ||||||
|                         } |                         } | ||||||
|                         Container::Verbatim => self.out.write_str("<code")?, |                         Container::Verbatim => out.write_str("<code")?, | ||||||
|                         Container::RawBlock { format } | Container::RawInline { format } => { |                         Container::RawBlock { format } | Container::RawInline { format } => { | ||||||
|                             self.raw = if format == &"html" { |                             self.raw = if format == &"html" { | ||||||
|                                 Raw::Html |                                 Raw::Html | ||||||
|  | @ -188,19 +187,19 @@ impl<'s, I: Iterator<Item = Event<'s>>, W: std::fmt::Write> Writer<'s, I, W> { | ||||||
|                             }; |                             }; | ||||||
|                             continue; |                             continue; | ||||||
|                         } |                         } | ||||||
|                         Container::Subscript => self.out.write_str("<sub")?, |                         Container::Subscript => out.write_str("<sub")?, | ||||||
|                         Container::Superscript => self.out.write_str("<sup")?, |                         Container::Superscript => out.write_str("<sup")?, | ||||||
|                         Container::Insert => self.out.write_str("<ins")?, |                         Container::Insert => out.write_str("<ins")?, | ||||||
|                         Container::Delete => self.out.write_str("<del")?, |                         Container::Delete => out.write_str("<del")?, | ||||||
|                         Container::Strong => self.out.write_str("<strong")?, |                         Container::Strong => out.write_str("<strong")?, | ||||||
|                         Container::Emphasis => self.out.write_str("<em")?, |                         Container::Emphasis => out.write_str("<em")?, | ||||||
|                         Container::Mark => self.out.write_str("<mark")?, |                         Container::Mark => out.write_str("<mark")?, | ||||||
|                     } |                     } | ||||||
| 
 | 
 | ||||||
|                     for (a, v) in attrs.iter().filter(|(a, _)| *a != "class") { |                     for (a, v) in attrs.iter().filter(|(a, _)| *a != "class") { | ||||||
|                         write!(self.out, r#" {}=""#, a)?; |                         write!(out, r#" {}=""#, a)?; | ||||||
|                         v.parts().try_for_each(|part| self.write_attr(part))?; |                         v.parts().try_for_each(|part| write_attr(part, &mut out))?; | ||||||
|                         self.out.write_char('"')?; |                         out.write_char('"')?; | ||||||
|                     } |                     } | ||||||
| 
 | 
 | ||||||
|                     if let Container::Heading { |                     if let Container::Heading { | ||||||
|  | @ -211,9 +210,9 @@ impl<'s, I: Iterator<Item = Event<'s>>, W: std::fmt::Write> Writer<'s, I, W> { | ||||||
|                     | Container::Section { id } = &c |                     | Container::Section { id } = &c | ||||||
|                     { |                     { | ||||||
|                         if !attrs.iter().any(|(a, _)| a == "id") { |                         if !attrs.iter().any(|(a, _)| a == "id") { | ||||||
|                             self.out.write_str(r#" id=""#)?; |                             out.write_str(r#" id=""#)?; | ||||||
|                             self.write_attr(id)?; |                             write_attr(id, &mut out)?; | ||||||
|                             self.out.write_char('"')?; |                             out.write_char('"')?; | ||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
| 
 | 
 | ||||||
|  | @ -229,7 +228,7 @@ impl<'s, I: Iterator<Item = Event<'s>>, W: std::fmt::Write> Writer<'s, I, W> { | ||||||
|                                 | Container::TaskListItem { .. } |                                 | Container::TaskListItem { .. } | ||||||
|                         ) |                         ) | ||||||
|                     { |                     { | ||||||
|                         self.out.write_str(r#" class=""#)?; |                         out.write_str(r#" class=""#)?; | ||||||
|                         let mut first_written = false; |                         let mut first_written = false; | ||||||
|                         if let Some(cls) = match c { |                         if let Some(cls) = match c { | ||||||
|                             Container::List { |                             Container::List { | ||||||
|  | @ -243,7 +242,7 @@ impl<'s, I: Iterator<Item = Event<'s>>, W: std::fmt::Write> Writer<'s, I, W> { | ||||||
|                             _ => None, |                             _ => None, | ||||||
|                         } { |                         } { | ||||||
|                             first_written = true; |                             first_written = true; | ||||||
|                             self.out.write_str(cls)?; |                             out.write_str(cls)?; | ||||||
|                         } |                         } | ||||||
|                         for cls in attrs |                         for cls in attrs | ||||||
|                             .iter() |                             .iter() | ||||||
|  | @ -251,19 +250,20 @@ impl<'s, I: Iterator<Item = Event<'s>>, W: std::fmt::Write> Writer<'s, I, W> { | ||||||
|                             .map(|(_, cls)| cls) |                             .map(|(_, cls)| cls) | ||||||
|                         { |                         { | ||||||
|                             if first_written { |                             if first_written { | ||||||
|                                 self.out.write_char(' ')?; |                                 out.write_char(' ')?; | ||||||
|                             } |                             } | ||||||
|                             first_written = true; |                             first_written = true; | ||||||
|                             cls.parts().try_for_each(|part| self.write_attr(part))?; |                             cls.parts() | ||||||
|  |                                 .try_for_each(|part| write_attr(part, &mut out))?; | ||||||
|                         } |                         } | ||||||
|                         // div class goes after classes from attrs
 |                         // div class goes after classes from attrs
 | ||||||
|                         if let Container::Div { class: Some(cls) } = c { |                         if let Container::Div { class: Some(cls) } = c { | ||||||
|                             if first_written { |                             if first_written { | ||||||
|                                 self.out.write_char(' ')?; |                                 out.write_char(' ')?; | ||||||
|                             } |                             } | ||||||
|                             self.out.write_str(cls)?; |                             out.write_str(cls)?; | ||||||
|                         } |                         } | ||||||
|                         self.out.write_char('"')?; |                         out.write_char('"')?; | ||||||
|                     } |                     } | ||||||
| 
 | 
 | ||||||
|                     match c { |                     match c { | ||||||
|  | @ -276,102 +276,101 @@ impl<'s, I: Iterator<Item = Event<'s>>, W: std::fmt::Write> Writer<'s, I, W> { | ||||||
|                                 Alignment::Center => "center", |                                 Alignment::Center => "center", | ||||||
|                                 Alignment::Right => "right", |                                 Alignment::Right => "right", | ||||||
|                             }; |                             }; | ||||||
|                             write!(self.out, r#" style="text-align: {};">"#, a)?; |                             write!(out, r#" style="text-align: {};">"#, a)?; | ||||||
|                         } |                         } | ||||||
|                         Container::CodeBlock { lang } => { |                         Container::CodeBlock { lang } => { | ||||||
|                             if let Some(l) = lang { |                             if let Some(l) = lang { | ||||||
|                                 self.out.write_str(r#"><code class="language-"#)?; |                                 out.write_str(r#"><code class="language-"#)?; | ||||||
|                                 self.write_attr(l)?; |                                 write_attr(l, &mut out)?; | ||||||
|                                 self.out.write_str(r#"">"#)?; |                                 out.write_str(r#"">"#)?; | ||||||
|                             } else { |                             } else { | ||||||
|                                 self.out.write_str("><code>")?; |                                 out.write_str("><code>")?; | ||||||
|                             } |                             } | ||||||
|                         } |                         } | ||||||
|                         Container::Image(..) => { |                         Container::Image(..) => { | ||||||
|                             if self.img_alt_text == 1 { |                             if self.img_alt_text == 1 { | ||||||
|                                 self.out.write_str(r#" alt=""#)?; |                                 out.write_str(r#" alt=""#)?; | ||||||
|                             } |                             } | ||||||
|                         } |                         } | ||||||
|                         Container::Math { display } => { |                         Container::Math { display } => { | ||||||
|                             self.out |                             out.write_str(if display { r#">\["# } else { r#">\("# })?; | ||||||
|                                 .write_str(if display { r#">\["# } else { r#">\("# })?; |  | ||||||
|                         } |                         } | ||||||
|                         _ => self.out.write_char('>')?, |                         _ => out.write_char('>')?, | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|                 Event::End(c) => { |                 Event::End(c) => { | ||||||
|                     if c.is_block_container() && !matches!(c, Container::Footnote { .. }) { |                     if c.is_block_container() && !matches!(c, Container::Footnote { .. }) { | ||||||
|                         self.out.write_char('\n')?; |                         out.write_char('\n')?; | ||||||
|                     } |                     } | ||||||
|                     if self.img_alt_text > 0 && !matches!(c, Container::Image(..)) { |                     if self.img_alt_text > 0 && !matches!(c, Container::Image(..)) { | ||||||
|                         continue; |                         continue; | ||||||
|                     } |                     } | ||||||
|                     match c { |                     match c { | ||||||
|                         Container::Blockquote => self.out.write_str("</blockquote>")?, |                         Container::Blockquote => out.write_str("</blockquote>")?, | ||||||
|                         Container::List { |                         Container::List { | ||||||
|                             kind: ListKind::Unordered | ListKind::Task, |                             kind: ListKind::Unordered | ListKind::Task, | ||||||
|                             .. |                             .. | ||||||
|                         } => { |                         } => { | ||||||
|                             self.list_tightness.pop(); |                             self.list_tightness.pop(); | ||||||
|                             self.out.write_str("</ul>")?; |                             out.write_str("</ul>")?; | ||||||
|                         } |                         } | ||||||
|                         Container::List { |                         Container::List { | ||||||
|                             kind: ListKind::Ordered { .. }, |                             kind: ListKind::Ordered { .. }, | ||||||
|                             .. |                             .. | ||||||
|                         } => self.out.write_str("</ol>")?, |                         } => out.write_str("</ol>")?, | ||||||
|                         Container::ListItem | Container::TaskListItem { .. } => { |                         Container::ListItem | Container::TaskListItem { .. } => { | ||||||
|                             self.out.write_str("</li>")?; |                             out.write_str("</li>")?; | ||||||
|                         } |                         } | ||||||
|                         Container::DescriptionList => self.out.write_str("</dl>")?, |                         Container::DescriptionList => out.write_str("</dl>")?, | ||||||
|                         Container::DescriptionDetails => self.out.write_str("</dd>")?, |                         Container::DescriptionDetails => out.write_str("</dd>")?, | ||||||
|                         Container::Footnote { number, .. } => { |                         Container::Footnote { number, .. } => { | ||||||
|                             if !close_para { |                             if !close_para { | ||||||
|                                 // create a new paragraph
 |                                 // create a new paragraph
 | ||||||
|                                 self.out.write_str("\n<p>")?; |                                 out.write_str("\n<p>")?; | ||||||
|                             } |                             } | ||||||
|                             write!( |                             write!( | ||||||
|                                 self.out, |                                 out, | ||||||
|                                 r##"<a href="#fnref{}" role="doc-backlink">↩︎︎</a></p>"##, |                                 r##"<a href="#fnref{}" role="doc-backlink">↩︎︎</a></p>"##, | ||||||
|                                 number, |                                 number, | ||||||
|                             )?; |                             )?; | ||||||
|                             self.out.write_str("\n</li>")?; |                             out.write_str("\n</li>")?; | ||||||
|                             self.footnote_number = None; |                             self.footnote_number = None; | ||||||
|                         } |                         } | ||||||
|                         Container::Table => self.out.write_str("</table>")?, |                         Container::Table => out.write_str("</table>")?, | ||||||
|                         Container::TableRow { .. } => self.out.write_str("</tr>")?, |                         Container::TableRow { .. } => out.write_str("</tr>")?, | ||||||
|                         Container::Section { .. } => self.out.write_str("</section>")?, |                         Container::Section { .. } => out.write_str("</section>")?, | ||||||
|                         Container::Div { .. } => self.out.write_str("</div>")?, |                         Container::Div { .. } => out.write_str("</div>")?, | ||||||
|                         Container::Paragraph => { |                         Container::Paragraph => { | ||||||
|                             if matches!(self.list_tightness.last(), Some(true)) { |                             if matches!(self.list_tightness.last(), Some(true)) { | ||||||
|                                 continue; |                                 continue; | ||||||
|                             } |                             } | ||||||
|                             if self.footnote_number.is_none() { |                             if self.footnote_number.is_none() { | ||||||
|                                 self.out.write_str("</p>")?; |                                 out.write_str("</p>")?; | ||||||
|                             } else { |                             } else { | ||||||
|                                 self.close_para = true; |                                 self.close_para = true; | ||||||
|                             } |                             } | ||||||
|                         } |                         } | ||||||
|                         Container::Heading { level, .. } => write!(self.out, "</h{}>", level)?, |                         Container::Heading { level, .. } => write!(out, "</h{}>", level)?, | ||||||
|                         Container::TableCell { head: false, .. } => self.out.write_str("</td>")?, |                         Container::TableCell { head: false, .. } => out.write_str("</td>")?, | ||||||
|                         Container::TableCell { head: true, .. } => self.out.write_str("</th>")?, |                         Container::TableCell { head: true, .. } => out.write_str("</th>")?, | ||||||
|                         Container::Caption => self.out.write_str("</caption>")?, |                         Container::Caption => out.write_str("</caption>")?, | ||||||
|                         Container::DescriptionTerm => self.out.write_str("</dt>")?, |                         Container::DescriptionTerm => out.write_str("</dt>")?, | ||||||
|                         Container::CodeBlock { .. } => self.out.write_str("</code></pre>")?, |                         Container::CodeBlock { .. } => out.write_str("</code></pre>")?, | ||||||
|                         Container::Span => self.out.write_str("</span>")?, |                         Container::Span => out.write_str("</span>")?, | ||||||
|                         Container::Link(..) => self.out.write_str("</a>")?, |                         Container::Link(..) => out.write_str("</a>")?, | ||||||
|                         Container::Image(src, ..) => { |                         Container::Image(src, ..) => { | ||||||
|                             if self.img_alt_text == 1 { |                             if self.img_alt_text == 1 { | ||||||
|                                 if !src.is_empty() { |                                 if !src.is_empty() { | ||||||
|                                     self.out.write_str(r#"" src=""#)?; |                                     out.write_str(r#"" src=""#)?; | ||||||
|                                     self.write_attr(&src)?; |                                     write_attr(&src, &mut out)?; | ||||||
|                                 } |                                 } | ||||||
|                                 self.out.write_str(r#"">"#)?; |                                 out.write_str(r#"">"#)?; | ||||||
|                             } |                             } | ||||||
|                             self.img_alt_text -= 1; |                             self.img_alt_text -= 1; | ||||||
|                         } |                         } | ||||||
|                         Container::Verbatim => self.out.write_str("</code>")?, |                         Container::Verbatim => out.write_str("</code>")?, | ||||||
|                         Container::Math { display } => { |                         Container::Math { display } => { | ||||||
|                             self.out.write_str(if display { |                             out.write_str(if display { | ||||||
|                                 r#"\]</span>"# |                                 r#"\]</span>"# | ||||||
|                             } else { |                             } else { | ||||||
|                                 r#"\)</span>"# |                                 r#"\)</span>"# | ||||||
|  | @ -380,62 +379,80 @@ impl<'s, I: Iterator<Item = Event<'s>>, W: std::fmt::Write> Writer<'s, I, W> { | ||||||
|                         Container::RawBlock { .. } | Container::RawInline { .. } => { |                         Container::RawBlock { .. } | Container::RawInline { .. } => { | ||||||
|                             self.raw = Raw::None; |                             self.raw = Raw::None; | ||||||
|                         } |                         } | ||||||
|                         Container::Subscript => self.out.write_str("</sub>")?, |                         Container::Subscript => out.write_str("</sub>")?, | ||||||
|                         Container::Superscript => self.out.write_str("</sup>")?, |                         Container::Superscript => out.write_str("</sup>")?, | ||||||
|                         Container::Insert => self.out.write_str("</ins>")?, |                         Container::Insert => out.write_str("</ins>")?, | ||||||
|                         Container::Delete => self.out.write_str("</del>")?, |                         Container::Delete => out.write_str("</del>")?, | ||||||
|                         Container::Strong => self.out.write_str("</strong>")?, |                         Container::Strong => out.write_str("</strong>")?, | ||||||
|                         Container::Emphasis => self.out.write_str("</em>")?, |                         Container::Emphasis => out.write_str("</em>")?, | ||||||
|                         Container::Mark => self.out.write_str("</mark>")?, |                         Container::Mark => out.write_str("</mark>")?, | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|                 Event::Str(s) => match self.raw { |                 Event::Str(s) => match self.raw { | ||||||
|                     Raw::None if self.img_alt_text > 0 => self.write_attr(&s)?, |                     Raw::None if self.img_alt_text > 0 => write_attr(&s, &mut out)?, | ||||||
|                     Raw::None => self.write_text(&s)?, |                     Raw::None => write_text(&s, &mut out)?, | ||||||
|                     Raw::Html => self.out.write_str(&s)?, |                     Raw::Html => out.write_str(&s)?, | ||||||
|                     Raw::Other => {} |                     Raw::Other => {} | ||||||
|                 }, |                 }, | ||||||
|                 Event::FootnoteReference(_tag, number) => { |                 Event::FootnoteReference(_tag, number) => { | ||||||
|                     if self.img_alt_text == 0 { |                     if self.img_alt_text == 0 { | ||||||
|                         write!( |                         write!( | ||||||
|                             self.out, |                             out, | ||||||
|                             r##"<a id="fnref{}" href="#fn{}" role="doc-noteref"><sup>{}</sup></a>"##, |                             r##"<a id="fnref{}" href="#fn{}" role="doc-noteref"><sup>{}</sup></a>"##, | ||||||
|                             number, number, number |                             number, number, number | ||||||
|                         )?; |                         )?; | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|                 Event::Symbol(sym) => write!(self.out, ":{}:", sym)?, |                 Event::Symbol(sym) => write!(out, ":{}:", sym)?, | ||||||
|                 Event::LeftSingleQuote => self.out.write_str("‘")?, |                 Event::LeftSingleQuote => out.write_str("‘")?, | ||||||
|                 Event::RightSingleQuote => self.out.write_str("’")?, |                 Event::RightSingleQuote => out.write_str("’")?, | ||||||
|                 Event::LeftDoubleQuote => self.out.write_str("“")?, |                 Event::LeftDoubleQuote => out.write_str("“")?, | ||||||
|                 Event::RightDoubleQuote => self.out.write_str("”")?, |                 Event::RightDoubleQuote => out.write_str("”")?, | ||||||
|                 Event::Ellipsis => self.out.write_str("…")?, |                 Event::Ellipsis => out.write_str("…")?, | ||||||
|                 Event::EnDash => self.out.write_str("–")?, |                 Event::EnDash => out.write_str("–")?, | ||||||
|                 Event::EmDash => self.out.write_str("—")?, |                 Event::EmDash => out.write_str("—")?, | ||||||
|                 Event::NonBreakingSpace => self.out.write_str(" ")?, |                 Event::NonBreakingSpace => out.write_str(" ")?, | ||||||
|                 Event::Hardbreak => self.out.write_str("<br>\n")?, |                 Event::Hardbreak => out.write_str("<br>\n")?, | ||||||
|                 Event::Softbreak => self.out.write_char('\n')?, |                 Event::Softbreak => out.write_char('\n')?, | ||||||
|                 Event::Escape | Event::Blankline => unreachable!("filtered out"), |                 Event::Escape | Event::Blankline => unreachable!("filtered out"), | ||||||
|                 Event::ThematicBreak(attrs) => { |                 Event::ThematicBreak(attrs) => { | ||||||
|                     self.out.write_str("\n<hr")?; |                     out.write_str("\n<hr")?; | ||||||
|                     for (a, v) in attrs.iter() { |                     for (a, v) in attrs.iter() { | ||||||
|                         write!(self.out, r#" {}=""#, a)?; |                         write!(out, r#" {}=""#, a)?; | ||||||
|                         v.parts().try_for_each(|part| self.write_attr(part))?; |                         v.parts().try_for_each(|part| write_attr(part, &mut out))?; | ||||||
|                         self.out.write_char('"')?; |                         out.write_char('"')?; | ||||||
|                     } |                     } | ||||||
|                     self.out.write_str(">")?; |                     out.write_str(">")?; | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             self.first_line = false; |             self.first_line = false; | ||||||
|         } |         } | ||||||
|         if self.encountered_footnote { |         if self.encountered_footnote { | ||||||
|             self.out.write_str("\n</ol>\n</section>")?; |             out.write_str("\n</ol>\n</section>")?; | ||||||
|         } |         } | ||||||
|         self.out.write_char('\n')?; |         out.write_char('\n')?; | ||||||
|         Ok(()) |         Ok(()) | ||||||
|     } |     } | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
|     fn write_escape(&mut self, mut s: &str, escape_quotes: bool) -> std::fmt::Result { | fn write_text<W>(s: &str, out: W) -> std::fmt::Result | ||||||
|  | where | ||||||
|  |     W: std::fmt::Write, | ||||||
|  | { | ||||||
|  |     write_escape(s, false, out) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | fn write_attr<W>(s: &str, out: W) -> std::fmt::Result | ||||||
|  | where | ||||||
|  |     W: std::fmt::Write, | ||||||
|  | { | ||||||
|  |     write_escape(s, true, out) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | fn write_escape<W>(mut s: &str, escape_quotes: bool, mut out: W) -> std::fmt::Result | ||||||
|  | where | ||||||
|  |     W: std::fmt::Write, | ||||||
|  | { | ||||||
|     let mut ent = ""; |     let mut ent = ""; | ||||||
|     while let Some(i) = s.find(|c| { |     while let Some(i) = s.find(|c| { | ||||||
|         match c { |         match c { | ||||||
|  | @ -450,18 +467,9 @@ impl<'s, I: Iterator<Item = Event<'s>>, W: std::fmt::Write> Writer<'s, I, W> { | ||||||
|             true |             true | ||||||
|         }) |         }) | ||||||
|     }) { |     }) { | ||||||
|             self.out.write_str(&s[..i])?; |         out.write_str(&s[..i])?; | ||||||
|             self.out.write_str(ent)?; |         out.write_str(ent)?; | ||||||
|         s = &s[i + 1..]; |         s = &s[i + 1..]; | ||||||
|     } |     } | ||||||
|         self.out.write_str(s) |     out.write_str(s) | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     fn write_text(&mut self, s: &str) -> std::fmt::Result { |  | ||||||
|         self.write_escape(s, false) |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     fn write_attr(&mut self, s: &str) -> std::fmt::Result { |  | ||||||
|         self.write_escape(s, true) |  | ||||||
|     } |  | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue