From 57450da4826a86e5c087e7f135919049753f8a98 Mon Sep 17 00:00:00 2001 From: letmutex <155220925+letmutex@users.noreply.github.com> Date: Sat, 6 Jul 2024 14:58:16 +0800 Subject: [PATCH 1/6] Make Send and Sync supertraits of ElementHandler --- src/element_handler/mod.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/element_handler/mod.rs b/src/element_handler/mod.rs index 0186229..e657061 100644 --- a/src/element_handler/mod.rs +++ b/src/element_handler/mod.rs @@ -27,7 +27,7 @@ use markup5ever_rcdom::Node; use std::{collections::HashSet, rc::Rc}; /// The DOM element handler. -pub trait ElementHandler { +pub trait ElementHandler : Send + Sync { fn append(&self) -> Option { None } @@ -47,13 +47,9 @@ pub(crate) struct HandlerRule { pub(crate) handler: Box, } -unsafe impl Send for HandlerRule {} - -unsafe impl Sync for HandlerRule {} - impl ElementHandler for F where - F: Fn(Element) -> Option, + F: (Fn(Element) -> Option) + Send + Sync, { fn on_visit( &self, From f69707095dca55fe4b2acf0dda3a4952dd8af947 Mon Sep 17 00:00:00 2001 From: Lukas Lueg Date: Sat, 6 Jul 2024 10:39:01 +0200 Subject: [PATCH 2/6] Clippy + Fmt --- examples/page-to-markdown/main.rs | 2 +- src/dom_walker.rs | 64 +++++++++++++++++++------------ src/element_handler/anchor.rs | 8 ++-- src/element_handler/code.rs | 23 ++++++----- src/element_handler/img.rs | 8 ++-- src/element_handler/li.rs | 6 +-- src/element_handler/list.rs | 2 +- src/element_handler/mod.rs | 8 ++-- src/lib.rs | 20 +++++++--- src/node_util.rs | 4 +- src/text_util.rs | 2 +- tests/mod.rs | 2 +- 12 files changed, 85 insertions(+), 64 deletions(-) diff --git a/examples/page-to-markdown/main.rs b/examples/page-to-markdown/main.rs index c55c43e..add66a2 100644 --- a/examples/page-to-markdown/main.rs +++ b/examples/page-to-markdown/main.rs @@ -30,6 +30,6 @@ fn convert(html_path: &str, output_filename: &str) { now.elapsed().as_millis() ); - std::fs::write(output_filename, &md).unwrap(); + std::fs::write(output_filename, md).unwrap(); println!("Saved as '{}'", output_filename); } diff --git a/src/dom_walker.rs b/src/dom_walker.rs index 6eaf52c..5795f69 100644 --- a/src/dom_walker.rs +++ b/src/dom_walker.rs @@ -16,7 +16,7 @@ pub(crate) fn walk_node( node: &Rc, parent_tag: Option<&str>, buffer: &mut Vec, - handler: &Box<&dyn ElementHandler>, + handler: &dyn ElementHandler, options: &Options, is_pre: bool, trim_leading_spaces: bool, @@ -82,15 +82,15 @@ fn append_text( let mut chars = text.chars(); if chars.next().is_some_and(|ch| ch == ' ') && chars.next().is_none() - && parent_tag.is_some_and(|tag| is_block_container(tag)) + && parent_tag.is_some_and(is_block_container) { // Ignore whitespace in block containers. return; } let to_add = if trim_leading_spaces - || (text.chars().nth(0).is_some_and(|ch| ch == ' ') - && buffer.last().is_some_and(|text| text.ends_with(" "))) + || (text.chars().next().is_some_and(|ch| ch == ' ') + && buffer.last().is_some_and(|text| text.ends_with(' '))) { // We can't compress spaces between two text blocks/elements, so we compress // them here by trimming the leading space of current text content. @@ -105,16 +105,16 @@ fn append_text( fn visit_element( buffer: &mut Vec, node: &Rc, - handler: &Box<&dyn ElementHandler>, + handler: &dyn ElementHandler, options: &Options, tag: &str, - attrs: &Vec, + attrs: &[Attribute], is_pre: bool, ) { let is_head = tag == "head"; let is_pre = is_pre || tag == "pre" || tag == "code"; let prev_buffer_len = buffer.len(); - let is_block = is_block_element(&tag); + let is_block = is_block_element(tag); walk_children(buffer, node, is_block, handler, options, is_pre); let md = handler.on_visit( node, @@ -153,7 +153,7 @@ fn join_contents(contents: &[String]) -> String { let separator = "\n".repeat(separator_new_lines); let mut next_result = String::with_capacity(left.len() + separator.len() + right.len()); - next_result.push_str(&left); + next_result.push_str(left); next_result.push_str(&separator); next_result.push_str(right); @@ -166,7 +166,7 @@ fn walk_children( buffer: &mut Vec, node: &Rc, is_parent_blok_element: bool, - handler: &Box<&dyn ElementHandler>, + handler: &dyn ElementHandler, options: &Options, is_pre: bool, ) { @@ -175,7 +175,7 @@ fn walk_children( // elements (except pre and code elements) let mut trim_leading_spaces = !is_pre && is_parent_blok_element; for child in node.children.borrow().iter() { - let is_block = get_node_tag_name(child).is_some_and(|tag| is_block_element(&tag)); + let is_block = get_node_tag_name(child).is_some_and(is_block_element); if is_block { // Trim trailing spaces for the previous element @@ -201,7 +201,7 @@ fn walk_children( } } -fn trim_buffer_end(buffer: &mut Vec) { +fn trim_buffer_end(buffer: &mut [String]) { for content in buffer.iter_mut().rev() { let trimmed = content.trim_end_ascii_whitespace(); if trimmed.len() == content.len() { @@ -211,7 +211,7 @@ fn trim_buffer_end(buffer: &mut Vec) { } } -fn trim_buffer_end_spaces(buffer: &mut Vec) { +fn trim_buffer_end_spaces(buffer: &mut [String]) { for content in buffer.iter_mut().rev() { let trimmed = content.trim_end_matches(|ch| ch == ' '); if trimmed.len() == content.len() { @@ -245,7 +245,7 @@ fn escape_if_needed(text: String) -> String { _ => escaped.push(ch), } } - let Some(first) = escaped.chars().nth(0) else { + let Some(first) = escaped.chars().next() else { return escaped; }; match first { @@ -279,7 +279,7 @@ fn escape_if_needed(text: String) -> String { /// '```' -> '\```' // code fence /// '~~~' -> '\~~~' // code fence fn escape_pre_text_if_needed(text: String) -> String { - let Some(first) = text.chars().nth(0) else { + let Some(first) = text.chars().next() else { return text; }; match first { @@ -293,20 +293,36 @@ fn escape_pre_text_if_needed(text: String) -> String { } fn is_block_container(tag: &str) -> bool { - match tag { - "html" | "body" | "div" | "ul" | "ol" | "li" | "table" | "tr" | "header" | "head" - | "footer" | "nav" | "section" | "article" | "aside" | "main" | "blockquote" | "script" - | "style" => true, - _ => false, - } + matches!( + tag, + "html" + | "body" + | "div" + | "ul" + | "ol" + | "li" + | "table" + | "tr" + | "header" + | "head" + | "footer" + | "nav" + | "section" + | "article" + | "aside" + | "main" + | "blockquote" + | "script" + | "style" + ) } fn is_block_element(tag: &str) -> bool { if is_block_container(tag) { return true; } - match tag { - "p" | "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "pre" | "hr" | "br" => true, - _ => false, - } + matches!( + tag, + "p" | "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "pre" | "hr" | "br" + ) } diff --git a/src/element_handler/anchor.rs b/src/element_handler/anchor.rs index 27a67ce..2bc6816 100644 --- a/src/element_handler/anchor.rs +++ b/src/element_handler/anchor.rs @@ -14,7 +14,7 @@ pub(super) struct AnchorElementHandler {} impl AnchorElementHandler { thread_local! { - static LINKS: RefCell> = RefCell::new(vec![]); + static LINKS: RefCell> = const { RefCell::new(vec![]) }; } } @@ -35,7 +35,7 @@ impl ElementHandler for AnchorElementHandler { &self, _node: &Rc, _tag: &str, - attrs: &Vec, + attrs: &[Attribute], content: &str, options: &Options, ) -> Option { @@ -56,7 +56,7 @@ impl ElementHandler for AnchorElementHandler { let process_title = |text: String| { text.lines() - .map(|line| line.trim_ascii_whitespace().replace("\"", "\\\"")) + .map(|line| line.trim_ascii_whitespace().replace('"', "\\\"")) .filter(|line| !line.is_empty()) .join("\n") }; @@ -64,7 +64,7 @@ impl ElementHandler for AnchorElementHandler { // Handle new lines in title let title = title.map(process_title); - let link = link.replace("(", "\\(").replace(")", "\\)"); + let link = link.replace('(', "\\(").replace(')', "\\)"); let md = if options.link_style == LinkStyle::Inlined { self.build_inlined_anchor(content, link, title) diff --git a/src/element_handler/code.rs b/src/element_handler/code.rs index db15fe4..e7249d7 100644 --- a/src/element_handler/code.rs +++ b/src/element_handler/code.rs @@ -11,10 +11,10 @@ use crate::{ }; pub(super) fn code_handler(element: Element) -> Option { - let parent_node = get_parent_node(&element.node); + let parent_node = get_parent_node(element.node); let is_code_block = parent_node .as_ref() - .map(|parent| get_node_tag_name(&parent).is_some_and(|t| t == "pre")) + .map(|parent| get_node_tag_name(parent).is_some_and(|t| t == "pre")) .unwrap_or(false); if is_code_block { handle_code_block(element, &parent_node.unwrap()) @@ -25,7 +25,7 @@ pub(super) fn code_handler(element: Element) -> Option { fn handle_code_block(element: Element, parent: &Rc) -> Option { let content = element.content; - let content = content.strip_suffix("\n").unwrap_or(&content); + let content = content.strip_suffix('\n').unwrap_or(content); if element.options.code_block_style == CodeBlockStyle::Fenced { let fence = if element.options.code_block_fence == CodeBlockFence::Tildes { get_code_fence_marker("~", content) @@ -40,8 +40,8 @@ fn handle_code_block(element: Element, parent: &Rc) -> Option { } }); let mut result = String::from(&fence); - if language.is_some() { - result.push_str(&language.unwrap()); + if let Some(ref lang) = language { + result.push_str(lang); } result.push('\n'); result.push_str(content); @@ -59,9 +59,9 @@ fn handle_code_block(element: Element, parent: &Rc) -> Option { fn get_code_fence_marker(symbol: &str, content: &str) -> String { let three_chars = symbol.repeat(3); - if content.find(&three_chars).is_some() { + if content.contains(&three_chars) { let four_chars = symbol.repeat(4); - if content.find(&four_chars).is_some() { + if content.contains(&four_chars) { symbol.repeat(5) } else { four_chars @@ -71,16 +71,15 @@ fn get_code_fence_marker(symbol: &str, content: &str) -> String { } } -fn find_language_from_attrs(attrs: &Vec) -> Option { +fn find_language_from_attrs(attrs: &[Attribute]) -> Option { attrs .iter() .find(|attr| &attr.name.local == "class") .map(|attr| { attr.value - .to_string() - .split(" ") + .split(' ') .find(|cls| cls.starts_with("language-")) - .map(|lang| lang.split("-").skip(1).join("-")) + .map(|lang| lang.split('-').skip(1).join("-")) }) .unwrap_or(None) } @@ -107,7 +106,7 @@ fn handle_inline_code(element: Element) -> Option { } } let content = if element.options.preformatted_code { - handle_preformatted_code(&content) + handle_preformatted_code(content) } else { content.trim_ascii_whitespace().to_string() }; diff --git a/src/element_handler/img.rs b/src/element_handler/img.rs index 63c2dab..97a3901 100644 --- a/src/element_handler/img.rs +++ b/src/element_handler/img.rs @@ -20,13 +20,11 @@ pub(super) fn img_handler(element: Element) -> Option { } } - if link.is_none() { - return None; - } + link.as_ref()?; let process_alt_title = |text: String| { text.lines() - .map(|line| line.trim_ascii_whitespace().replace("\"", "\\\"")) + .map(|line| line.trim_ascii_whitespace().replace('"', "\\\"")) .filter(|line| !line.is_empty()) .join("\n") }; @@ -37,7 +35,7 @@ pub(super) fn img_handler(element: Element) -> Option { // Handle new lines in title let title = title.map(process_alt_title); - let link = link.map(|text| text.replace("(", "\\(").replace(")", "\\)")); + let link = link.map(|text| text.replace('(', "\\(").replace(')', "\\)")); let has_spaces_in_link = link.as_ref().is_some_and(|link| link.contains(' ')); diff --git a/src/element_handler/li.rs b/src/element_handler/li.rs index 0fd6a8f..664fabb 100644 --- a/src/element_handler/li.rs +++ b/src/element_handler/li.rs @@ -57,7 +57,7 @@ pub(super) fn list_item_handler(element: Element) -> Option { let mut index = 0; for child in parent_node.children.borrow().iter() { - if Rc::ptr_eq(child, &element.node) { + if Rc::ptr_eq(child, element.node) { break; } if get_node_tag_name(child).is_some_and(|tag| tag == "li") { @@ -72,8 +72,8 @@ pub(super) fn list_item_handler(element: Element) -> Option { .map(|attr| attr.value.to_string().parse::().unwrap_or(1)) .unwrap_or(1); - return ol_li(start + index); + ol_li(start + index) } else { - return ul_li(); + ul_li() } } diff --git a/src/element_handler/list.rs b/src/element_handler/list.rs index e830255..27f037d 100644 --- a/src/element_handler/list.rs +++ b/src/element_handler/list.rs @@ -5,7 +5,7 @@ use crate::{ }; pub(super) fn list_handler(element: Element) -> Option { - let parent = get_parent_node(&element.node); + let parent = get_parent_node(element.node); let is_parent_li = parent .map(|p| get_node_tag_name(&p).is_some_and(|tag| tag == "li")) .unwrap_or(false); diff --git a/src/element_handler/mod.rs b/src/element_handler/mod.rs index e657061..8c0c9e4 100644 --- a/src/element_handler/mod.rs +++ b/src/element_handler/mod.rs @@ -27,7 +27,7 @@ use markup5ever_rcdom::Node; use std::{collections::HashSet, rc::Rc}; /// The DOM element handler. -pub trait ElementHandler : Send + Sync { +pub trait ElementHandler: Send + Sync { fn append(&self) -> Option { None } @@ -36,7 +36,7 @@ pub trait ElementHandler : Send + Sync { &self, node: &Rc, tag: &str, - attrs: &Vec, + attrs: &[Attribute], content: &str, options: &Options, ) -> Option; @@ -55,7 +55,7 @@ where &self, node: &Rc, tag: &str, - attrs: &Vec, + attrs: &[Attribute], content: &str, options: &Options, ) -> Option { @@ -141,7 +141,7 @@ impl ElementHandler for ElementHandlers { &self, node: &Rc, tag: &str, - attrs: &Vec, + attrs: &[Attribute], content: &str, options: &Options, ) -> Option { diff --git a/src/lib.rs b/src/lib.rs index 92639cf..2829754 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -34,7 +34,7 @@ pub struct Element<'a> { /// The tag name. pub tag: &'a str, /// The attribute list. - pub attrs: &'a Vec, + pub attrs: &'a [Attribute], /// The content text, can be raw text or converted Markdown text. pub content: &'a str, /// Converter options. @@ -64,6 +64,12 @@ pub struct HtmlToMarkdown { handlers: ElementHandlers, } +impl Default for HtmlToMarkdown { + fn default() -> Self { + Self::new() + } +} + impl HtmlToMarkdown { /// Create a new converter. pub fn new() -> Self { @@ -83,20 +89,18 @@ impl HtmlToMarkdown { } /// Convert HTML to Markdown. - pub fn convert(&self, html: &str) -> Result { + pub fn convert(&self, html: &str) -> std::io::Result { let dom = parse_document(RcDom::default(), Default::default()) .from_utf8() .read_from(&mut html.as_bytes())?; let mut buffer: Vec = Vec::new(); - let handlers: Box<&dyn ElementHandler> = Box::new(&self.handlers); - walk_node( &dom.document, None, &mut buffer, - &handlers, + &self.handlers, &self.options, false, true, @@ -124,6 +128,12 @@ pub struct HtmlToMarkdownBuilder { handlers: ElementHandlers, } +impl Default for HtmlToMarkdownBuilder { + fn default() -> Self { + Self::new() + } +} + impl HtmlToMarkdownBuilder { /// Create a new builder. pub fn new() -> Self { diff --git a/src/node_util.rs b/src/node_util.rs index 52e7748..f7a628b 100644 --- a/src/node_util.rs +++ b/src/node_util.rs @@ -12,9 +12,7 @@ pub(crate) fn get_node_tag_name(node: &Rc) -> Option<&str> { pub(crate) fn get_parent_node(node: &Rc) -> Option> { let value = node.parent.take(); - let Some(parent) = value.as_ref() else { - return None; - }; + let parent = value.as_ref()?; let Some(parent) = parent.upgrade() else { // Put the parent back node.parent.set(value); diff --git a/src/text_util.rs b/src/text_util.rs index 90722ef..2cfd38f 100644 --- a/src/text_util.rs +++ b/src/text_util.rs @@ -105,7 +105,7 @@ where pub(crate) fn compress_whitespace(input: &str) -> String { let mut result = String::new(); - if input.len() == 0 { + if input.is_empty() { return result; } let mut in_whitespace = false; diff --git a/tests/mod.rs b/tests/mod.rs index 1dcccf0..6b6ad6f 100644 --- a/tests/mod.rs +++ b/tests/mod.rs @@ -5,4 +5,4 @@ mod basic_tests; mod turndown_cases_tests; #[cfg(test)] -mod turndown_online_demo_tests; \ No newline at end of file +mod turndown_online_demo_tests; From d134ae549eaf6e1f56dc0cdafa50774952f3fd40 Mon Sep 17 00:00:00 2001 From: letmutex <155220925+letmutex@users.noreply.github.com> Date: Thu, 11 Jul 2024 14:16:50 +0800 Subject: [PATCH 3/6] Run clippy in CI --- .github/workflows/ci.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 74fea90..7251953 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -23,5 +23,8 @@ jobs: - name: Build run: cargo build --verbose + - name: Clippy + run: cargo clippy -- --deny warnings + - name: Test run: cargo test --verbose From 41d618a2872cbf83ebc2af4795392aa6e0a87993 Mon Sep 17 00:00:00 2001 From: letmutex <155220925+letmutex@users.noreply.github.com> Date: Thu, 11 Jul 2024 15:18:51 +0800 Subject: [PATCH 4/6] Fix missing title in referenced links --- src/element_handler/anchor.rs | 10 ++++++---- tests/basic_tests.rs | 19 +++++++++++++++++++ 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/src/element_handler/anchor.rs b/src/element_handler/anchor.rs index 2bc6816..c865e9e 100644 --- a/src/element_handler/anchor.rs +++ b/src/element_handler/anchor.rs @@ -69,7 +69,7 @@ impl ElementHandler for AnchorElementHandler { let md = if options.link_style == LinkStyle::Inlined { self.build_inlined_anchor(content, link, title) } else { - self.build_referenced_anchor(content, link, &options.link_reference_style) + self.build_referenced_anchor(content, link, title, &options.link_reference_style) }; Some(md) @@ -105,24 +105,26 @@ impl AnchorElementHandler { &self, content: &str, link: String, + title: Option, style: &LinkReferenceStyle, ) -> String { AnchorElementHandler::LINKS.with(|links| { + let title = title.map_or(String::new(), |t| concat_strings!(" \"", t, "\"")); let (current, append) = match style { LinkReferenceStyle::Full => { let index = links.borrow().len() + 1; ( concat_strings!("[", content, "][", index.to_string(), "]"), - concat_strings!("[", index.to_string(), "]: ", link), + concat_strings!("[", index.to_string(), "]: ", link, title), ) } LinkReferenceStyle::Collapsed => ( concat_strings!("[", content, "][]"), - concat_strings!("[", content, "]: ", link), + concat_strings!("[", content, "]: ", link, title), ), LinkReferenceStyle::Shortcut => ( concat_strings!("[", content, "]"), - concat_strings!("[", content, "]: ", link), + concat_strings!("[", content, "]: ", link, title), ), }; links.borrow_mut().push(append); diff --git a/tests/basic_tests.rs b/tests/basic_tests.rs index 55a000a..713c230 100644 --- a/tests/basic_tests.rs +++ b/tests/basic_tests.rs @@ -27,6 +27,25 @@ fn links_with_spaces() { assert_eq!("[Example]()", &md) } +#[test] +fn referenced_links_with_title() { + let html = r#" + Example + "#; + let md = HtmlToMarkdown::builder() + .options(Options { + link_style: LinkStyle::Referenced, + ..Default::default() + }) + .build() + .convert(html) + .unwrap(); + assert_eq!( + "[Example][1]\n\n[1]: https://example.com \"Some title\"", + &md + ) +} + #[test] fn images() { let html = r#" From 04bcdb8ba06a5ce76583b35f4f63cf6022393104 Mon Sep 17 00:00:00 2001 From: letmutex <155220925+letmutex@users.noreply.github.com> Date: Thu, 11 Jul 2024 15:30:34 +0800 Subject: [PATCH 5/6] Use free function convert in tests when possible --- tests/basic_tests.rs | 64 +++++++++++++++++++------------------------- 1 file changed, 28 insertions(+), 36 deletions(-) diff --git a/tests/basic_tests.rs b/tests/basic_tests.rs index 713c230..8a29463 100644 --- a/tests/basic_tests.rs +++ b/tests/basic_tests.rs @@ -1,6 +1,7 @@ use std::{sync::Arc, thread::JoinHandle}; use htmd::{ + convert, options::{BrStyle, LinkStyle, Options}, Element, HtmlToMarkdown, }; @@ -11,10 +12,9 @@ fn links() { Link 1 Link 2 "#; - let md = HtmlToMarkdown::new().convert(html).unwrap(); assert_eq!( "[Link 1](https://example.com)[Link 2](https://example.com \"Hello\")", - &md + convert(html).unwrap(), ) } @@ -23,8 +23,10 @@ fn links_with_spaces() { let html = r#" Example "#; - let md = HtmlToMarkdown::new().convert(html).unwrap(); - assert_eq!("[Example]()", &md) + assert_eq!( + "[Example]()", + convert(html).unwrap(), + ) } #[test] @@ -53,11 +55,10 @@ fn images() { Image 1 Image 2 "#; - let md = HtmlToMarkdown::new().convert(html).unwrap(); assert_eq!( "![](https://example.com)![Image 1](https://example.com)\ ![Image 2](https://example.com \"Hello\")", - &md + convert(html).unwrap(), ) } @@ -66,8 +67,10 @@ fn images_with_spaces_in_url() { let html = r#" "#; - let md = HtmlToMarkdown::new().convert(html).unwrap(); - assert_eq!("![]()", &md) + assert_eq!( + "![]()", + convert(html).unwrap(), + ) } #[test] @@ -79,8 +82,7 @@ fn unordered_lists() {
  • Item 3
  • "#; - let md = HtmlToMarkdown::new().convert(html).unwrap(); - assert_eq!("* Item 1\n* Item 2\n* Item 3", &md) + assert_eq!("* Item 1\n* Item 2\n* Item 3", convert(html).unwrap()) } #[test] @@ -93,11 +95,10 @@ fn headings() {
    Heading 5
    Heading 6
    "#; - let md = HtmlToMarkdown::new().convert(html).unwrap(); assert_eq!( "# Heading 1\n\n## Heading 2\n\n### Heading 3\n\n\ #### Heading 4\n\n##### Heading 5\n\n###### Heading 6", - &md + convert(html).unwrap(), ) } @@ -106,8 +107,7 @@ fn code_blocks() { let html = r#"
    println!("Hello");
    "#; - let md = HtmlToMarkdown::new().convert(html).unwrap(); - assert_eq!("```\nprintln!(\"Hello\");\n```", &md); + assert_eq!("```\nprintln!(\"Hello\");\n```", convert(html).unwrap()); } #[test] @@ -115,8 +115,7 @@ fn code_blocks_with_lang_class() { let html = r#"
    println!("Hello");
    "#; - let md = HtmlToMarkdown::new().convert(html).unwrap(); - assert_eq!("```rust\nprintln!(\"Hello\");\n```", &md); + assert_eq!("```rust\nprintln!(\"Hello\");\n```", convert(html).unwrap()); } #[test] @@ -124,8 +123,7 @@ fn code_blocks_with_lang_class_on_pre_tag() { let html = r#"
    println!("Hello");
    "#; - let md = HtmlToMarkdown::new().convert(html).unwrap(); - assert_eq!("```rust\nprintln!(\"Hello\");\n```", &md); + assert_eq!("```rust\nprintln!(\"Hello\");\n```", convert(html).unwrap()); } #[test] @@ -134,8 +132,7 @@ fn paragraphs() {

    The first.

    The second.

    "#; - let md = HtmlToMarkdown::new().convert(html).unwrap(); - assert_eq!("The first.\n\nThe second.", &md); + assert_eq!("The first.\n\nThe second.", convert(html).unwrap()); } #[test] @@ -143,8 +140,7 @@ fn quotes() { let html = r#"
    Once upon a time
    "#; - let md = HtmlToMarkdown::new().convert(html).unwrap(); - assert_eq!("> Once upon a time", &md); + assert_eq!("> Once upon a time", convert(html).unwrap()); } #[test] @@ -152,8 +148,7 @@ fn br() { let html = r#" Hi
    there

    ! "#; - let md = HtmlToMarkdown::new().convert(html).unwrap(); - assert_eq!("Hi \nthere \n \n!", &md); + assert_eq!("Hi \nthere \n \n!", convert(html).unwrap()); let md = HtmlToMarkdown::builder() .options(Options { @@ -169,22 +164,19 @@ fn br() { #[test] fn hr() { let html = r#"Hi
    there"#; - let md = HtmlToMarkdown::new().convert(html).unwrap(); - assert_eq!("Hi\n\n* * *\n\nthere", &md); + assert_eq!("Hi\n\n* * *\n\nthere", convert(html).unwrap()); } #[test] fn strong_italic() { let html = r#"Italic Also italic Strong"#; - let md = HtmlToMarkdown::new().convert(html).unwrap(); - assert_eq!("_Italic__Also italic_**Strong**", &md); + assert_eq!("_Italic__Also italic_**Strong**", convert(html).unwrap()); } #[test] fn raw_text() { let html = r#"Hello world!"#; - let md = HtmlToMarkdown::new().convert(html).unwrap(); - assert_eq!("Hello world!", &md); + assert_eq!("Hello world!", convert(html).unwrap()); } #[test] @@ -198,8 +190,7 @@ fn nested_divs() {
    there
    "#; - let md = HtmlToMarkdown::new().convert(html).unwrap(); - assert_eq!("Hi\n\nthere", &md); + assert_eq!("Hi\n\nthere", convert(html).unwrap()); } #[test] @@ -216,8 +207,10 @@ fn with_head() { "#; - let md = HtmlToMarkdown::new().convert(html).unwrap(); - assert_eq!("Demo\n\nconsole.log('Hello');\n\nbody {}\n\nContent", &md); + assert_eq!( + "Demo\n\nconsole.log('Hello');\n\nbody {}\n\nContent", + convert(html).unwrap() + ); } #[test] @@ -235,8 +228,7 @@ fn with_custom_rules() { #[test] fn upper_case_tags() { let html = r#"

    Hello

    World

    "#; - let md = HtmlToMarkdown::new().convert(html).unwrap(); - assert_eq!("# Hello\n\nWorld", &md); + assert_eq!("# Hello\n\nWorld", convert(html).unwrap()); } #[test] From 5fd47044c5befa90e14b5b8be6c95a6c05d2eb1c Mon Sep 17 00:00:00 2001 From: letmutex <155220925+letmutex@users.noreply.github.com> Date: Thu, 11 Jul 2024 15:41:25 +0800 Subject: [PATCH 6/6] v0.1.6 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7ec8ac0..2ad44dd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -325,7 +325,7 @@ dependencies = [ [[package]] name = "htmd" -version = "0.1.5" +version = "0.1.6" dependencies = [ "criterion", "html5ever 0.27.0", diff --git a/Cargo.toml b/Cargo.toml index d1c6000..200e58b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "htmd" -version = "0.1.5" +version = "0.1.6" edition = "2021" authors = ["letmutex"] description = "A turndown.js inspired HTML to Markdown converter."