use std::{sync::Arc, thread::JoinHandle}; use htmd::{ convert, options::{BrStyle, LinkStyle, Options}, Element, HtmlToMarkdown, }; #[test] fn links() { let html = r#" Link 1 Link 2 "#; assert_eq!( "[Link 1](https://example.com)[Link 2](https://example.com \"Hello\")", convert(html).unwrap(), ) } #[test] fn links_with_spaces() { let html = r#" Example "#; assert_eq!( "[Example]()", convert(html).unwrap(), ) } #[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#" Image 1 Image 2 "#; assert_eq!( "![](https://example.com)![Image 1](https://example.com)\ ![Image 2](https://example.com \"Hello\")", convert(html).unwrap(), ) } #[test] fn images_with_spaces_in_url() { let html = r#" "#; assert_eq!( "![]()", convert(html).unwrap(), ) } #[test] fn unordered_lists() { let html = r#" "#; assert_eq!("* Item 1\n* Item 2\n* Item 3", convert(html).unwrap()) } #[test] fn headings() { let html = r#"

Heading 1

Heading 2

Heading 3

Heading 4

Heading 5
Heading 6
"#; assert_eq!( "# Heading 1\n\n## Heading 2\n\n### Heading 3\n\n\ #### Heading 4\n\n##### Heading 5\n\n###### Heading 6", convert(html).unwrap(), ) } #[test] fn code_blocks() { let html = r#"
println!("Hello");
"#; assert_eq!("```\nprintln!(\"Hello\");\n```", convert(html).unwrap()); } #[test] fn code_blocks_with_lang_class() { let html = r#"
println!("Hello");
"#; assert_eq!("```rust\nprintln!(\"Hello\");\n```", convert(html).unwrap()); } #[test] fn code_blocks_with_lang_class_on_pre_tag() { let html = r#"
println!("Hello");
"#; assert_eq!("```rust\nprintln!(\"Hello\");\n```", convert(html).unwrap()); } #[test] fn paragraphs() { let html = r#"

The first.

The second.

"#; assert_eq!("The first.\n\nThe second.", convert(html).unwrap()); } #[test] fn quotes() { let html = r#"
Once upon a time
"#; assert_eq!("> Once upon a time", convert(html).unwrap()); } #[test] fn br() { let html = r#" Hi
there

! "#; assert_eq!("Hi \nthere \n \n!", convert(html).unwrap()); let md = HtmlToMarkdown::builder() .options(Options { br_style: BrStyle::Backslash, ..Default::default() }) .build() .convert(html) .unwrap(); assert_eq!("Hi\\\nthere\\\n\\\n!", &md); } #[test] fn hr() { let html = r#"Hi
there"#; assert_eq!("Hi\n\n* * *\n\nthere", convert(html).unwrap()); } #[test] fn strong_italic() { let html = r#"Italic Also italic Strong"#; assert_eq!("_Italic__Also italic_**Strong**", convert(html).unwrap()); } #[test] fn raw_text() { let html = r#"Hello world!"#; assert_eq!("Hello world!", convert(html).unwrap()); } #[test] fn nested_divs() { let html = r#"
Hi
there
"#; assert_eq!("Hi\n\nthere", convert(html).unwrap()); } #[test] fn with_head() { let html = r#" Demo Content "#; assert_eq!( "Demo\n\nconsole.log('Hello');\n\nbody {}\n\nContent", convert(html).unwrap() ); } #[test] fn with_custom_rules() { // Remove element let html = r#""#; let md = HtmlToMarkdown::builder() .add_handler(vec!["img"], |_: Element| None) .build() .convert(html) .unwrap(); assert_eq!("", &md); } #[test] fn upper_case_tags() { let html = r#"

Hello

World

"#; assert_eq!("# Hello\n\nWorld", convert(html).unwrap()); } #[test] fn multithreading() { let html = r#"Example Example Example Example Example "#; let expected = "[Example][1][Example][2][Example][3][Example][4][Example][5]\n\n\ [1]: https://example.com\n[2]: https://example.com\n[3]: https://example.com\n\ [4]: https://example.com\n[5]: https://example.com"; let converter = HtmlToMarkdown::builder() .options(Options { // We use a global vec to store all referenced links of the doc in the anchor // element handler, this is unsafe for multithreading usage if we do nothing link_style: LinkStyle::Referenced, ..Default::default() }) .build(); let converter = Arc::new(converter); let mut handlers: Vec> = vec![]; for _ in 0..20 { let converter_clone = converter.clone(); let handle = std::thread::spawn(move || { let md = converter_clone.convert(html).unwrap(); assert_eq!(expected, md); }); handlers.push(handle); } for handle in handlers { handle.join().unwrap(); } }