From 5f9dd2560cd4bb4012aecd5a1fd6ad63900d4cdf Mon Sep 17 00:00:00 2001 From: Christopher Hoskin Date: Wed, 24 Jul 2024 19:52:12 +0100 Subject: [PATCH 1/4] Replace markdown with pulldown-cmark --- Cargo.lock | 39 ++++++----- Cargo.toml | 2 +- src/elan-cli/main.rs | 2 +- src/elan-cli/term2.rs | 148 ++++++++++++++++++++++++++---------------- 4 files changed, 116 insertions(+), 75 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 47f8ad2..f04c05e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -405,7 +405,7 @@ dependencies = [ "itertools", "json", "libc", - "markdown", + "pulldown-cmark", "rand", "regex", "remove_dir_all", @@ -967,17 +967,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "markdown" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef3aab6a1d529b112695f72beec5ee80e729cb45af58663ec902c8fac764ecdd" -dependencies = [ - "lazy_static", - "pipeline", - "regex", -] - [[package]] name = "memchr" version = "2.5.0" @@ -1186,12 +1175,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" -[[package]] -name = "pipeline" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d15b6607fa632996eb8a17c9041cb6071cb75ac057abd45dece578723ea8c7c0" - [[package]] name = "pkg-config" version = "0.3.26" @@ -1213,6 +1196,17 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "pulldown-cmark" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c205cc82214f3594e2d50686730314f817c67ffa80fe800cf0db78c3c2b9d9e" +dependencies = [ + "bitflags", + "memchr", + "unicase", +] + [[package]] name = "quote" version = "1.0.26" @@ -1797,6 +1791,15 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e79c4d996edb816c91e4308506774452e55e95c3c9de07b6729e17e15a5ef81" +[[package]] +name = "unicase" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" +dependencies = [ + "version_check", +] + [[package]] name = "unicode-bidi" version = "0.3.13" diff --git a/Cargo.toml b/Cargo.toml index d5dad10..4be5b83 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,7 +31,7 @@ clap = "2.33.3" error-chain = "0.12.4" itertools = "0.10.0" libc = "0.2.82" -markdown = "0.3.0" +pulldown-cmark = { version = "0.6", default-features = false } rand = "0.8.2" regex = "1.4.3" remove_dir_all = "0.8.0" diff --git a/src/elan-cli/main.rs b/src/elan-cli/main.rs index dc8c74b..3bf4845 100644 --- a/src/elan-cli/main.rs +++ b/src/elan-cli/main.rs @@ -24,7 +24,7 @@ extern crate elan; extern crate flate2; extern crate itertools; extern crate json; -extern crate markdown; +extern crate pulldown_cmark; extern crate rand; extern crate regex; extern crate same_file; diff --git a/src/elan-cli/term2.rs b/src/elan-cli/term2.rs index c323c5d..a34da6b 100644 --- a/src/elan-cli/term2.rs +++ b/src/elan-cli/term2.rs @@ -3,10 +3,9 @@ //! if TERM isn't defined. use elan_utils::tty; -use markdown::tokenize; -use markdown::{Block, ListItem, Span}; use std::io; use term; +use pulldown_cmark::{Event, Tag}; pub use term::color; pub use term::Attr; @@ -137,6 +136,7 @@ impl<'a, T: io::Write + 'a> LineWrapper<'a, T> { // Handles the formatting of text struct LineFormatter<'a, T: Instantiable + Isatty + io::Write + 'a> { + is_code_block: bool, wrapper: LineWrapper<'a, Terminal>, attrs: Vec, } @@ -144,6 +144,7 @@ struct LineFormatter<'a, T: Instantiable + Isatty + io::Write + 'a> { impl<'a, T: Instantiable + Isatty + io::Write + 'a> LineFormatter<'a, T> { fn new(w: &'a mut Terminal, indent: u32, margin: u32) -> Self { LineFormatter { + is_code_block: false, wrapper: LineWrapper::new(w, indent, margin), attrs: Vec::new(), } @@ -159,70 +160,107 @@ impl<'a, T: Instantiable + Isatty + io::Write + 'a> LineFormatter<'a, T> { let _ = self.wrapper.w.attr(*attr); } } - fn do_spans(&mut self, spans: Vec) { - for span in spans { - match span { - Span::Break => {} - Span::Text(text) => { - self.wrapper.write_span(&text); - } - Span::Code(code) => { - self.push_attr(Attr::Bold); - self.wrapper.write_word(&code); - self.pop_attr(); - } - Span::Emphasis(spans) => { - self.push_attr(Attr::ForegroundColor(color::BRIGHT_RED)); - self.do_spans(spans); - self.pop_attr(); - } - _ => {} + + fn start_tag(&mut self, tag: Tag<'a>) { + match tag { + Tag::Paragraph => { + self.wrapper.write_line(); } - } - } - fn do_block(&mut self, b: Block) { - match b { - Block::Header(spans, _) => { + + Tag::Heading(_level) => { self.push_attr(Attr::Bold); self.wrapper.write_line(); - self.do_spans(spans); + } + Tag::Table(_alignments) => {} + Tag::TableHead => {} + Tag::TableRow => {} + Tag::TableCell => {} + Tag::BlockQuote => {} + Tag::CodeBlock(_lang) => { self.wrapper.write_line(); - self.pop_attr(); + self.wrapper.indent += 2; + self.is_code_block = true; } - Block::CodeBlock(_, code) => { + Tag::List(_) => { self.wrapper.write_line(); self.wrapper.indent += 2; - for line in code.lines() { - // Don't word-wrap code lines - self.wrapper.write_word(line); - self.wrapper.write_line(); - } - self.wrapper.indent -= 2; } - Block::Paragraph(spans) => { + Tag::Item => { self.wrapper.write_line(); - self.do_spans(spans); + } + Tag::Emphasis => { + self.push_attr(Attr::ForegroundColor(color::BRIGHT_RED)); + } + Tag::Strong => {} + Tag::Strikethrough => {} + Tag::Link(_link_type, _dest, _title) => {} + Tag::Image(_link_type, _dest, _title) => {} + Tag::FootnoteDefinition(_name) => {} + } + } + + fn end_tag(&mut self, tag: Tag<'a>) { + match tag { + Tag::Paragraph => { self.wrapper.write_line(); } - Block::UnorderedList(items) => { + Tag::Heading(_level) => { self.wrapper.write_line(); - for item in items { - self.wrapper.indent += 2; - match item { - ListItem::Simple(spans) => { - self.do_spans(spans); - } - ListItem::Paragraph(blocks) => { - for block in blocks { - self.do_block(block); - } - } - } - self.wrapper.write_line(); - self.wrapper.indent -= 2; + self.pop_attr(); + } + Tag::Table(_) => {} + Tag::TableHead => {} + Tag::TableRow => {} + Tag::TableCell => {} + Tag::BlockQuote => {} + Tag::CodeBlock(_) => { + self.is_code_block = false; + self.wrapper.indent -= 2; + } + Tag::List(_) => { + self.wrapper.indent -= 2; + self.wrapper.write_line(); + } + Tag::Item => {} + Tag::Emphasis => { + self.pop_attr(); + } + Tag::Strong => {} + Tag::Strikethrough => {} + Tag::Link(_, _, _) => {} + Tag::Image(_, _, _) => {} // shouldn't happen, handled in start + Tag::FootnoteDefinition(_) => {} + } + } + + fn process_event(&mut self, event: Event<'a>) { + use self::Event::*; + match event { + Start(tag) => self.start_tag(tag), + End(tag) => self.end_tag(tag), + Text(text) => { + if self.is_code_block { + self.wrapper.write_word(&text); + } else { + self.wrapper.write_span(&text); } } - _ => {} + Code(code) => { + self.push_attr(Attr::Bold); + self.wrapper.write_word(&code); + self.pop_attr(); + } + Html(_html) => {} + SoftBreak => { + self.wrapper.write_line(); + } + HardBreak => { + self.wrapper.write_line(); + } + Rule => {} + FootnoteReference(_name) => {} + TaskListMarker(true) => {} + TaskListMarker(false) => {} } } } @@ -294,9 +332,9 @@ impl Terminal { pub fn md>(&mut self, content: S) { let mut f = LineFormatter::new(self, 0, 79); - let blocks = tokenize(content.as_ref()); - for b in blocks { - f.do_block(b); + let parser = pulldown_cmark::Parser::new(content.as_ref()); + for event in parser { + f.process_event(event); } } } From 06c751eea943a21f4ab5f5a27cb5dc2afb89ef10 Mon Sep 17 00:00:00 2001 From: Christopher Hoskin Date: Thu, 25 Jul 2024 08:31:03 +0100 Subject: [PATCH 2/4] Bump pulldown-cmark from 0.6 to 0.9 --- Cargo.lock | 26 ++++++++++++++++---------- Cargo.toml | 2 +- src/elan-cli/term2.rs | 4 ++-- 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f04c05e..5131df0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -115,6 +115,12 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + [[package]] name = "block-buffer" version = "0.9.0" @@ -204,7 +210,7 @@ checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" dependencies = [ "ansi_term", "atty", - "bitflags", + "bitflags 1.3.2", "strsim", "textwrap", "unicode-width", @@ -1024,7 +1030,7 @@ version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a" dependencies = [ - "bitflags", + "bitflags 1.3.2", "cfg-if", "libc", "static_assertions", @@ -1076,7 +1082,7 @@ version = "0.10.51" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97ea2d98598bf9ada7ea6ee8a30fb74f9156b63bbe495d64ec2b87c269d2dda3" dependencies = [ - "bitflags", + "bitflags 1.3.2", "cfg-if", "foreign-types", "libc", @@ -1198,11 +1204,11 @@ dependencies = [ [[package]] name = "pulldown-cmark" -version = "0.6.1" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c205cc82214f3594e2d50686730314f817c67ffa80fe800cf0db78c3c2b9d9e" +checksum = "57206b407293d2bcd3af849ce869d52068623f19e1b5ff8e8778e3309439682b" dependencies = [ - "bitflags", + "bitflags 2.6.0", "memchr", "unicase", ] @@ -1252,7 +1258,7 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] @@ -1261,7 +1267,7 @@ version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] @@ -1357,7 +1363,7 @@ version = "0.37.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9b864d3c18a5785a05953adeed93e2dca37ed30f18e69bba9f30079d51f363f" dependencies = [ - "bitflags", + "bitflags 1.3.2", "errno", "io-lifetimes", "libc", @@ -1407,7 +1413,7 @@ version = "2.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a332be01508d814fed64bf28f798a146d73792121129962fdf335bb3c49a4254" dependencies = [ - "bitflags", + "bitflags 1.3.2", "core-foundation", "core-foundation-sys", "libc", diff --git a/Cargo.toml b/Cargo.toml index 4be5b83..398529c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,7 +31,7 @@ clap = "2.33.3" error-chain = "0.12.4" itertools = "0.10.0" libc = "0.2.82" -pulldown-cmark = { version = "0.6", default-features = false } +pulldown-cmark = { version = "0.9", default-features = false } rand = "0.8.2" regex = "1.4.3" remove_dir_all = "0.8.0" diff --git a/src/elan-cli/term2.rs b/src/elan-cli/term2.rs index a34da6b..1d9e0e1 100644 --- a/src/elan-cli/term2.rs +++ b/src/elan-cli/term2.rs @@ -167,7 +167,7 @@ impl<'a, T: Instantiable + Isatty + io::Write + 'a> LineFormatter<'a, T> { self.wrapper.write_line(); } - Tag::Heading(_level) => { + Tag::Heading(_level, _identifier, _classes) => { self.push_attr(Attr::Bold); self.wrapper.write_line(); } @@ -204,7 +204,7 @@ impl<'a, T: Instantiable + Isatty + io::Write + 'a> LineFormatter<'a, T> { Tag::Paragraph => { self.wrapper.write_line(); } - Tag::Heading(_level) => { + Tag::Heading(_level, _identifier, _classes) => { self.wrapper.write_line(); self.pop_attr(); } From 8c40d4a29c14e926d21eef7a5bb7fa6d9f7cc3db Mon Sep 17 00:00:00 2001 From: Christopher Hoskin Date: Thu, 25 Jul 2024 08:41:59 +0100 Subject: [PATCH 3/4] Bump pulldown-cmark from 0.9 to 0.10 --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- src/elan-cli/term2.rs | 47 +++++++++++++++++++++++-------------------- 3 files changed, 28 insertions(+), 25 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5131df0..bfbc37a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1204,9 +1204,9 @@ dependencies = [ [[package]] name = "pulldown-cmark" -version = "0.9.6" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57206b407293d2bcd3af849ce869d52068623f19e1b5ff8e8778e3309439682b" +checksum = "76979bea66e7875e7509c4ec5300112b316af87fa7a252ca91c448b32dfe3993" dependencies = [ "bitflags 2.6.0", "memchr", diff --git a/Cargo.toml b/Cargo.toml index 398529c..8c26b19 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,7 +31,7 @@ clap = "2.33.3" error-chain = "0.12.4" itertools = "0.10.0" libc = "0.2.82" -pulldown-cmark = { version = "0.9", default-features = false } +pulldown-cmark = { version = "0.10", default-features = false } rand = "0.8.2" regex = "1.4.3" remove_dir_all = "0.8.0" diff --git a/src/elan-cli/term2.rs b/src/elan-cli/term2.rs index 1d9e0e1..a5da8ee 100644 --- a/src/elan-cli/term2.rs +++ b/src/elan-cli/term2.rs @@ -5,7 +5,7 @@ use elan_utils::tty; use std::io; use term; -use pulldown_cmark::{Event, Tag}; +use pulldown_cmark::{Event, Tag, TagEnd}; pub use term::color; pub use term::Attr; @@ -167,16 +167,17 @@ impl<'a, T: Instantiable + Isatty + io::Write + 'a> LineFormatter<'a, T> { self.wrapper.write_line(); } - Tag::Heading(_level, _identifier, _classes) => { + Tag::Heading { .. } => { self.push_attr(Attr::Bold); self.wrapper.write_line(); } + Tag::MetadataBlock(_) => {} Tag::Table(_alignments) => {} Tag::TableHead => {} Tag::TableRow => {} Tag::TableCell => {} Tag::BlockQuote => {} - Tag::CodeBlock(_lang) => { + Tag::CodeBlock(_) | Tag::HtmlBlock { .. } => { self.wrapper.write_line(); self.wrapper.indent += 2; self.is_code_block = true; @@ -193,43 +194,44 @@ impl<'a, T: Instantiable + Isatty + io::Write + 'a> LineFormatter<'a, T> { } Tag::Strong => {} Tag::Strikethrough => {} - Tag::Link(_link_type, _dest, _title) => {} - Tag::Image(_link_type, _dest, _title) => {} + Tag::Link { .. } => {} + Tag::Image { .. } => {} Tag::FootnoteDefinition(_name) => {} } } - fn end_tag(&mut self, tag: Tag<'a>) { + fn end_tag(&mut self, tag: TagEnd) { match tag { - Tag::Paragraph => { + TagEnd::Paragraph => { self.wrapper.write_line(); } - Tag::Heading(_level, _identifier, _classes) => { + TagEnd::Heading { .. } => { self.wrapper.write_line(); self.pop_attr(); } - Tag::Table(_) => {} - Tag::TableHead => {} - Tag::TableRow => {} - Tag::TableCell => {} - Tag::BlockQuote => {} - Tag::CodeBlock(_) => { + TagEnd::Table => {} + TagEnd::TableHead => {} + TagEnd::TableRow => {} + TagEnd::TableCell => {} + TagEnd::BlockQuote => {} + TagEnd::CodeBlock | TagEnd::HtmlBlock => { self.is_code_block = false; self.wrapper.indent -= 2; } - Tag::List(_) => { + TagEnd::List(_) => { self.wrapper.indent -= 2; self.wrapper.write_line(); } - Tag::Item => {} - Tag::Emphasis => { + TagEnd::Item => {} + TagEnd::Emphasis => { self.pop_attr(); } - Tag::Strong => {} - Tag::Strikethrough => {} - Tag::Link(_, _, _) => {} - Tag::Image(_, _, _) => {} // shouldn't happen, handled in start - Tag::FootnoteDefinition(_) => {} + TagEnd::Strong => {} + TagEnd::Strikethrough => {} + TagEnd::Link { .. } => {} + TagEnd::Image { .. } => {} // shouldn't happen, handled in start + TagEnd::FootnoteDefinition => {} + TagEnd::MetadataBlock(_) => {} } } @@ -261,6 +263,7 @@ impl<'a, T: Instantiable + Isatty + io::Write + 'a> LineFormatter<'a, T> { FootnoteReference(_name) => {} TaskListMarker(true) => {} TaskListMarker(false) => {} + InlineHtml(_) => {} } } } From 829a2b4f6d14d7c5112f6bbd23a36b544d39060e Mon Sep 17 00:00:00 2001 From: Christopher Hoskin Date: Thu, 25 Jul 2024 08:51:46 +0100 Subject: [PATCH 4/4] Bump pulldown-cmark from 0.10 to 0.11 --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- src/elan-cli/term2.rs | 4 +++- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bfbc37a..d6f80a7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1204,9 +1204,9 @@ dependencies = [ [[package]] name = "pulldown-cmark" -version = "0.10.3" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76979bea66e7875e7509c4ec5300112b316af87fa7a252ca91c448b32dfe3993" +checksum = "8746739f11d39ce5ad5c2520a9b75285310dbfe78c541ccf832d38615765aec0" dependencies = [ "bitflags 2.6.0", "memchr", diff --git a/Cargo.toml b/Cargo.toml index 8c26b19..228321e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,7 +31,7 @@ clap = "2.33.3" error-chain = "0.12.4" itertools = "0.10.0" libc = "0.2.82" -pulldown-cmark = { version = "0.10", default-features = false } +pulldown-cmark = { version = "0.11", default-features = false } rand = "0.8.2" regex = "1.4.3" remove_dir_all = "0.8.0" diff --git a/src/elan-cli/term2.rs b/src/elan-cli/term2.rs index a5da8ee..c574f41 100644 --- a/src/elan-cli/term2.rs +++ b/src/elan-cli/term2.rs @@ -176,7 +176,7 @@ impl<'a, T: Instantiable + Isatty + io::Write + 'a> LineFormatter<'a, T> { Tag::TableHead => {} Tag::TableRow => {} Tag::TableCell => {} - Tag::BlockQuote => {} + Tag::BlockQuote(_) => {} Tag::CodeBlock(_) | Tag::HtmlBlock { .. } => { self.wrapper.write_line(); self.wrapper.indent += 2; @@ -264,6 +264,8 @@ impl<'a, T: Instantiable + Isatty + io::Write + 'a> LineFormatter<'a, T> { TaskListMarker(true) => {} TaskListMarker(false) => {} InlineHtml(_) => {} + InlineMath(_) => {} + DisplayMath(_) => {} } } }