diff --git a/Cargo.lock b/Cargo.lock index 4a72ac2df..d2c56a520 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1028,6 +1028,15 @@ dependencies = [ "windows-targets 0.48.5", ] +[[package]] +name = "getopts" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5" +dependencies = [ + "unicode-width", +] + [[package]] name = "getrandom" version = "0.2.12" @@ -1695,7 +1704,6 @@ dependencies = [ "maple_derive", "maple_lsp", "maple_markdown", - "markdown", "matcher", "once_cell", "parking_lot", @@ -1760,9 +1768,9 @@ version = "0.1.52" dependencies = [ "axum", "axum-extra", - "markdown", "once_cell", "percent-encoding", + "pulldown-cmark", "regex", "serde_json", "tokio", @@ -1771,15 +1779,6 @@ dependencies = [ "webbrowser", ] -[[package]] -name = "markdown" -version = "1.0.0-alpha.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0f0025e8c0d89b84d6dc63e859475e40e8e82ab1a08be0a93ad5731513a508" -dependencies = [ - "unicode-id", -] - [[package]] name = "matcher" version = "0.1.52" @@ -2169,6 +2168,25 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "pulldown-cmark" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f0530d13d87d1f549b66a3e8d0c688952abe5994e204ed62615baaf25dc029c" +dependencies = [ + "bitflags 2.4.2", + "getopts", + "memchr", + "pulldown-cmark-escape", + "unicase", +] + +[[package]] +name = "pulldown-cmark-escape" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5d8f9aa0e3cbcfaf8bf00300004ee3b72f74770f9cbac93f6928771f613276b" + [[package]] name = "quick-xml" version = "0.31.0" @@ -3256,16 +3274,19 @@ dependencies = [ ] [[package]] -name = "unicode-bidi" -version = "0.3.15" +name = "unicase" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" +checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" +dependencies = [ + "version_check", +] [[package]] -name = "unicode-id" -version = "0.3.4" +name = "unicode-bidi" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1b6def86329695390197b82c1e244a54a131ceb66c996f2088a3876e2ae083f" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" [[package]] name = "unicode-ident" diff --git a/Cargo.toml b/Cargo.toml index 1bea1c93a..cd7d0bc85 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -63,11 +63,11 @@ indicatif = "0.16" itertools = "0.10" lsp = { package = "lsp-types", version = "0.94" } memchr = "2.5" -markdown = "1.0.0-alpha.16" num_cpus = "1.13" once_cell = "1.7" -percent-encoding = "2.2.0" parking_lot = "0.12" +percent-encoding = "2.2.0" +pulldown-cmark = "0.10.2" rayon = "1.5" regex = "1" rgb2ansi256 = "0.1.1" diff --git a/crates/maple_core/Cargo.toml b/crates/maple_core/Cargo.toml index c2fac1fdc..37ed13bd6 100644 --- a/crates/maple_core/Cargo.toml +++ b/crates/maple_core/Cargo.toml @@ -23,7 +23,6 @@ grep-matcher = { workspace = true } ignore = { workspace = true } itertools = { workspace = true } tokio = { workspace = true, features = ["fs", "rt", "process", "macros", "rt-multi-thread", "sync", "time"] } -markdown = { workspace = true } once_cell = { workspace = true } parking_lot = { workspace = true } rayon = { workspace = true } diff --git a/crates/maple_core/src/stdio_server/plugin/markdown.rs b/crates/maple_core/src/stdio_server/plugin/markdown.rs index d90813ff5..eff3eee1f 100644 --- a/crates/maple_core/src/stdio_server/plugin/markdown.rs +++ b/crates/maple_core/src/stdio_server/plugin/markdown.rs @@ -79,9 +79,7 @@ impl ClapPlugin for Markdown { // TODO: incremental update? let lines = self.vim.getbufline(bufnr, 1, "$").await?; let markdown_content = lines.join("\n"); - let html = - markdown::to_html_with_options(&markdown_content, &markdown::Options::gfm()) - .map_err(PluginError::Other)?; + let html = maple_markdown::to_html(&markdown_content)?; if let Some(msg_tx) = self.bufs.get(&bufnr) { msg_tx.send_replace(Message::UpdateContent(html)); } @@ -135,8 +133,10 @@ impl ClapPlugin for Markdown { let bufnr = self.vim.bufnr("").await?; tokio::spawn(async move { - if let Err(err) = maple_markdown::open_preview(listener, msg_rx).await { - tracing::error!(?err, "Failed to open markdown preview in browser"); + if let Err(err) = + maple_markdown::open_preview_in_browser(listener, msg_rx).await + { + tracing::error!(?err, "Failed to open markdown preview"); } tracing::debug!(bufnr, "markdown preview exited"); }); diff --git a/crates/maple_markdown/Cargo.toml b/crates/maple_markdown/Cargo.toml index 71a203a5c..1f3234cc3 100644 --- a/crates/maple_markdown/Cargo.toml +++ b/crates/maple_markdown/Cargo.toml @@ -11,9 +11,9 @@ publish.workspace = true [dependencies] axum = { version = "0.7.5", features = ["ws"] } axum-extra = { version = "0.9.3", features = ["typed-header"] } -markdown = { workspace = true } once_cell = { workspace = true } percent-encoding = { workspace = true } +pulldown-cmark = { workspace = true } regex = { workspace = true } serde_json = { workspace = true } tokio = { workspace = true, features = ["full"] } diff --git a/crates/maple_markdown/src/lib.rs b/crates/maple_markdown/src/lib.rs index c68422d69..121c2034a 100644 --- a/crates/maple_markdown/src/lib.rs +++ b/crates/maple_markdown/src/lib.rs @@ -48,20 +48,20 @@ async fn handle_websocket(mut socket: WebSocket, mut msg_rx: Receiver) let _ = socket.send(WsMessage::Close(None)).await; } +pub fn to_html(markdown_content: &str) -> Result { + let parser = pulldown_cmark::Parser::new(markdown_content); + + let mut html_output = String::new(); + pulldown_cmark::html::push_html(&mut html_output, parser); + + Ok(html_output) +} + fn process_message(msg: Message) -> Result { let res = match msg { Message::FileChanged(path) => { let markdown_content = std::fs::read_to_string(path)?; - let html = markdown::to_html_with_options( - &markdown_content, - &markdown::Options { - parse: markdown::ParseOptions::gfm(), - compile: markdown::CompileOptions { - gfm_task_list_item_checkable: true, - ..markdown::CompileOptions::gfm() - }, - }, - )?; + let html = to_html(&markdown_content)?; serde_json::json!({ "type": "update_content", "data": html, @@ -83,7 +83,7 @@ fn process_message(msg: Message) -> Result { Ok(res) } -// Message type between the server and ws clients. +// Worker message that the websocket server deals with. #[derive(Debug, Clone)] pub enum Message { /// Markdown file was modified. @@ -94,7 +94,7 @@ pub enum Message { Scroll(usize), } -pub async fn open_preview( +pub async fn open_preview_in_browser( listener: tokio::net::TcpListener, msg_rx: Receiver, ) -> Result<(), Error> { @@ -104,11 +104,10 @@ pub async fn open_preview( let port = listener.local_addr()?.port(); - if let Err(err) = webbrowser::open(&format!("http://127.0.0.1:{port}")) { - tracing::error!("Error serving connection: {:?}", err); - } + webbrowser::open(&format!("http://127.0.0.1:{port}"))?; tracing::debug!("Listening on {listener:?}"); + axum::serve( listener, app.into_make_service_with_connect_info::(), @@ -140,7 +139,7 @@ mod tests { .await .unwrap(); - open_preview(listener, msg_rx) + open_preview_in_browser(listener, msg_rx) .await .expect("Failed to open markdown preview"); }