Skip to content

Commit

Permalink
chore: update pulldown-cmark to 0.10.0
Browse files Browse the repository at this point in the history
Fixes: #13509
  • Loading branch information
bryangarza committed Mar 4, 2024
1 parent f772ec0 commit 604d2e4
Show file tree
Hide file tree
Showing 34 changed files with 192 additions and 158 deletions.
13 changes: 10 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ pathdiff = "0.2"
percent-encoding = "2.3"
pkg-config = "0.3.30"
proptest = "1.4.0"
pulldown-cmark = { version = "0.9.3", default-features = false }
pulldown-cmark = { version = "0.10.0", default-features = false, features = ["html"] }
rand = "0.8.5"
regex = "1.10.3"
rusqlite = { version = "0.31.0", features = ["bundled"] }
Expand Down
80 changes: 45 additions & 35 deletions crates/mdman/src/format/man.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
use crate::util::{header_text, parse_name_and_section};
use crate::EventIter;
use anyhow::{bail, Error};
use pulldown_cmark::{Alignment, Event, HeadingLevel, LinkType, Tag};
use pulldown_cmark::{Alignment, Event, HeadingLevel, LinkType, Tag, TagEnd};
use std::fmt::Write;
use url::Url;

Expand Down Expand Up @@ -110,6 +110,7 @@ impl<'e> ManRenderer<'e> {
let mut suppress_paragraph = false;
let mut table_cell_index = 0;

let mut last_seen_link_data = None;
while let Some((event, range)) = self.parser.next() {
let this_suppress_paragraph = suppress_paragraph;
suppress_paragraph = false;
Expand All @@ -122,7 +123,7 @@ impl<'e> ManRenderer<'e> {
self.output.push_str(".sp\n");
}
}
Tag::Heading(level, ..) => {
Tag::Heading { level, .. } => {
if level == HeadingLevel::H1 {
self.push_top_header()?;
} else if level == HeadingLevel::H2 {
Expand Down Expand Up @@ -212,7 +213,12 @@ impl<'e> ManRenderer<'e> {
Tag::Strong => self.push_font(Font::Bold),
// Strikethrough isn't usually supported for TTY.
Tag::Strikethrough => self.output.push_str("~~"),
Tag::Link(link_type, dest_url, _title) => {
Tag::Link {
link_type,
dest_url,
..
} => {
last_seen_link_data = Some((link_type.clone(), dest_url.to_owned()));
if dest_url.starts_with('#') {
// In a man page, page-relative anchors don't
// have much meaning.
Expand Down Expand Up @@ -247,68 +253,71 @@ impl<'e> ManRenderer<'e> {
}
}
}
Tag::Image(_link_type, _dest_url, _title) => {
Tag::Image { .. } => {
bail!("images are not currently supported")
}
Tag::HtmlBlock { .. } | Tag::MetadataBlock { .. } => {}
}
}
Event::End(tag) => {
match &tag {
Tag::Paragraph => self.flush(),
Tag::Heading(..) => {}
Tag::BlockQuote => {
Event::End(tag_end) => {
match &tag_end {
TagEnd::Paragraph => self.flush(),
TagEnd::Heading(..) => {}
TagEnd::BlockQuote => {
self.flush();
// restore left margin, restore line length
self.output.push_str(".br\n.RE\n.ll\n");
}
Tag::CodeBlock(_kind) => {
TagEnd::CodeBlock => {
self.flush();
// Restore fill mode, move margin back one level.
self.output.push_str(".fi\n.RE\n");
}
Tag::List(_) => {
TagEnd::List(_) => {
list.pop();
}
Tag::Item => {
TagEnd::Item => {
self.flush();
// Move margin back one level.
self.output.push_str(".RE\n");
}
Tag::FootnoteDefinition(_label) => {}
Tag::Table(_) => {
TagEnd::FootnoteDefinition => {}
TagEnd::Table => {
// Table end
// I don't know why, but the .sp is needed to provide
// space with the following content.
self.output.push_str("\n.TE\n.sp\n");
}
Tag::TableHead => {}
Tag::TableRow => {}
Tag::TableCell => {
TagEnd::TableHead => {}
TagEnd::TableRow => {}
TagEnd::TableCell => {
// End text block.
self.output.push_str("\nT}");
}
Tag::Emphasis | Tag::Strong => self.pop_font(),
Tag::Strikethrough => self.output.push_str("~~"),
Tag::Link(link_type, dest_url, _title) => {
if dest_url.starts_with('#') {
continue;
}
match link_type {
LinkType::Autolink | LinkType::Email => {}
LinkType::Inline
| LinkType::Reference
| LinkType::Collapsed
| LinkType::Shortcut => {
self.pop_font();
self.output.push(' ');
TagEnd::Emphasis | TagEnd::Strong => self.pop_font(),
TagEnd::Strikethrough => self.output.push_str("~~"),
TagEnd::Link => {
if let Some((link_type, ref dest_url)) = last_seen_link_data {
if dest_url.starts_with('#') {
continue;
}
_ => {
panic!("unexpected tag {:?}", tag);
match link_type {
LinkType::Autolink | LinkType::Email => {}
LinkType::Inline
| LinkType::Reference
| LinkType::Collapsed
| LinkType::Shortcut => {
self.pop_font();
self.output.push(' ');
}
_ => {
panic!("unexpected tag {:?}", tag_end);
}
}
write!(self.output, "<{}>", escape(&dest_url)?)?;
}
write!(self.output, "<{}>", escape(&dest_url)?)?;
}
Tag::Image(_link_type, _dest_url, _title) => {}
TagEnd::Image | TagEnd::HtmlBlock | TagEnd::MetadataBlock(..) => {}
}
}
Event::Text(t) => {
Expand Down Expand Up @@ -346,6 +355,7 @@ impl<'e> ManRenderer<'e> {
self.output.push_str("\\l'\\n(.lu'\n");
}
Event::TaskListMarker(_b) => unimplemented!(),
Event::InlineHtml(..) => unimplemented!(),
}
}
Ok(())
Expand Down
90 changes: 50 additions & 40 deletions crates/mdman/src/format/text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
use crate::util::{header_text, unwrap};
use crate::EventIter;
use anyhow::{bail, Error};
use pulldown_cmark::{Alignment, Event, HeadingLevel, LinkType, Tag};
use pulldown_cmark::{Alignment, Event, HeadingLevel, LinkType, Tag, TagEnd};
use std::fmt::Write;
use std::mem;
use url::Url;
Expand Down Expand Up @@ -102,6 +102,7 @@ impl<'e> TextRenderer<'e> {
// Whether or not word-wrapping is enabled.
let mut wrap_text = true;

let mut last_seen_link_data = None;
while let Some((event, range)) = self.parser.next() {
let this_suppress_paragraph = suppress_paragraph;
// Always reset suppression, even if the next event isn't a
Expand All @@ -116,7 +117,7 @@ impl<'e> TextRenderer<'e> {
self.flush();
}
}
Tag::Heading(level, ..) => {
Tag::Heading { level, .. } => {
self.flush();
if level == HeadingLevel::H1 {
let text = header_text(&mut self.parser)?;
Expand Down Expand Up @@ -180,7 +181,12 @@ impl<'e> TextRenderer<'e> {
Tag::Strong => {}
// Strikethrough isn't usually supported for TTY.
Tag::Strikethrough => self.word.push_str("~~"),
Tag::Link(link_type, dest_url, _title) => {
Tag::Link {
link_type,
dest_url,
..
} => {
last_seen_link_data = Some((link_type.clone(), dest_url.to_owned()));
if dest_url.starts_with('#') {
// In a man page, page-relative anchors don't
// have much meaning.
Expand Down Expand Up @@ -213,59 +219,62 @@ impl<'e> TextRenderer<'e> {
}
}
}
Tag::Image(_link_type, _dest_url, _title) => {
Tag::Image { .. } => {
bail!("images are not currently supported")
}
Tag::HtmlBlock { .. } | Tag::MetadataBlock { .. } => {}
}
}
Event::End(tag) => match &tag {
Tag::Paragraph => {
Event::End(tag_end) => match &tag_end {
TagEnd::Paragraph => {
self.flush();
self.hard_break();
}
Tag::Heading(..) => {}
Tag::BlockQuote => {
TagEnd::Heading(..) => {}
TagEnd::BlockQuote => {
self.indent -= 3;
}
Tag::CodeBlock(_kind) => {
TagEnd::CodeBlock => {
self.hard_break();
wrap_text = true;
self.indent -= 4;
}
Tag::List(_) => {
TagEnd::List(..) => {
list.pop();
}
Tag::Item => {
TagEnd::Item => {
self.flush();
self.indent -= 3;
self.hard_break();
}
Tag::FootnoteDefinition(_label) => {}
Tag::Table(_) => {}
Tag::TableHead => {}
Tag::TableRow => {}
Tag::TableCell => {}
Tag::Emphasis => {}
Tag::Strong => {}
Tag::Strikethrough => self.word.push_str("~~"),
Tag::Link(link_type, dest_url, _title) => {
if dest_url.starts_with('#') {
continue;
}
match link_type {
LinkType::Autolink | LinkType::Email => {}
LinkType::Inline
| LinkType::Reference
| LinkType::Collapsed
| LinkType::Shortcut => self.flush_word(),
_ => {
panic!("unexpected tag {:?}", tag);
TagEnd::FootnoteDefinition => {}
TagEnd::Table => {}
TagEnd::TableHead => {}
TagEnd::TableRow => {}
TagEnd::TableCell => {}
TagEnd::Emphasis => {}
TagEnd::Strong => {}
TagEnd::Strikethrough => self.word.push_str("~~"),
TagEnd::Link => {
if let Some((link_type, ref dest_url)) = last_seen_link_data {
if dest_url.starts_with('#') {
continue;
}
match link_type {
LinkType::Autolink | LinkType::Email => {}
LinkType::Inline
| LinkType::Reference
| LinkType::Collapsed
| LinkType::Shortcut => self.flush_word(),
_ => {
panic!("unexpected tag {:?}", tag_end);
}
}
self.flush_word();
write!(self.word, "<{}>", dest_url)?;
}
self.flush_word();
write!(self.word, "<{}>", dest_url)?;
}
Tag::Image(_link_type, _dest_url, _title) => {}
TagEnd::Image | TagEnd::HtmlBlock | TagEnd::MetadataBlock(..) => {}
},
Event::Text(t) | Event::Code(t) => {
if wrap_text {
Expand Down Expand Up @@ -337,6 +346,7 @@ impl<'e> TextRenderer<'e> {
self.flush();
}
Event::TaskListMarker(_b) => unimplemented!(),
Event::InlineHtml(..) => unimplemented!(),
}
}
Ok(())
Expand Down Expand Up @@ -451,20 +461,20 @@ impl Table {
| Tag::Strong => {}
Tag::Strikethrough => self.cell.push_str("~~"),
// Links not yet supported, they usually won't fit.
Tag::Link(_, _, _) => {}
Tag::Link { .. } => {}
_ => bail!("unexpected tag in table: {:?}", tag),
},
Event::End(tag) => match tag {
Tag::Table(_) => return self.render(indent),
Tag::TableCell => {
Event::End(tag_end) => match tag_end {
TagEnd::Table => return self.render(indent),
TagEnd::TableCell => {
let cell = mem::replace(&mut self.cell, String::new());
self.row.push(cell);
}
Tag::TableHead | Tag::TableRow => {
TagEnd::TableHead | TagEnd::TableRow => {
let row = mem::replace(&mut self.row, Vec::new());
self.rows.push(row);
}
Tag::Strikethrough => self.cell.push_str("~~"),
TagEnd::Strikethrough => self.cell.push_str("~~"),
_ => {}
},
Event::Text(t) | Event::Code(t) => {
Expand Down
21 changes: 14 additions & 7 deletions crates/mdman/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! mdman markdown to man converter.
use anyhow::{bail, Context, Error};
use pulldown_cmark::{CowStr, Event, LinkType, Options, Parser, Tag};
use pulldown_cmark::{CowStr, Event, LinkType, Options, Parser, Tag, TagEnd};
use std::collections::HashMap;
use std::fs;
use std::io::{self, BufRead};
Expand Down Expand Up @@ -74,14 +74,21 @@ pub(crate) fn md_parser(input: &str, url: Option<Url>) -> EventIter<'_> {
let parser = parser.into_offset_iter();
// Translate all links to include the base url.
let parser = parser.map(move |(event, range)| match event {
Event::Start(Tag::Link(lt, dest_url, title)) if !matches!(lt, LinkType::Email) => (
Event::Start(Tag::Link(lt, join_url(url.as_ref(), dest_url), title)),
range,
),
Event::End(Tag::Link(lt, dest_url, title)) if !matches!(lt, LinkType::Email) => (
Event::End(Tag::Link(lt, join_url(url.as_ref(), dest_url), title)),
Event::Start(Tag::Link {
link_type,
dest_url,
title,
id,
}) if !matches!(link_type, LinkType::Email) => (
Event::Start(Tag::Link {
link_type,
dest_url: join_url(url.as_ref(), dest_url),
title,
id,
}),
range,
),
Event::End(TagEnd::Link) => (Event::End(TagEnd::Link), range),
_ => (event, range),
});
Box::new(parser)
Expand Down
Loading

0 comments on commit 604d2e4

Please sign in to comment.