html-to-markdown 3.4.0 → 3.6.0.pre.rc.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/LICENSE +21 -0
- data/README.md +347 -0
- data/Steepfile +10 -2
- data/ext/html_to_markdown_rb/Cargo.toml +3 -2
- data/ext/html_to_markdown_rb/extconf.rb +5 -5
- data/ext/html_to_markdown_rb/native/Cargo.lock +962 -0
- data/ext/html_to_markdown_rb/native/Cargo.toml +6 -11
- data/ext/html_to_markdown_rb/native/extconf.rb +14 -0
- data/ext/html_to_markdown_rb/src/lib.rs +1715 -646
- data/lib/html_to_markdown/native.rb +913 -37
- data/lib/html_to_markdown/version.rb +3 -3
- data/lib/html_to_markdown.rb +9 -4
- data/lib/html_to_markdown_rb.so +0 -0
- data/sig/types.rbs +59 -292
- metadata +32 -179
- data/ext/html_to_markdown_rb/Makefile +0 -592
- data/lib/bin/html-to-markdown +0 -0
- data/vendor/Cargo.toml +0 -33
- data/vendor/html-to-markdown-rs/Cargo.toml +0 -54
- data/vendor/html-to-markdown-rs/README.md +0 -278
- data/vendor/html-to-markdown-rs/examples/basic.rs +0 -24
- data/vendor/html-to-markdown-rs/examples/table.rs +0 -25
- data/vendor/html-to-markdown-rs/examples/test_deser.rs +0 -12
- data/vendor/html-to-markdown-rs/examples/test_escape.rs +0 -58
- data/vendor/html-to-markdown-rs/examples/test_inline_formatting.rs +0 -113
- data/vendor/html-to-markdown-rs/examples/test_lists.rs +0 -39
- data/vendor/html-to-markdown-rs/examples/test_semantic_tags.rs +0 -89
- data/vendor/html-to-markdown-rs/examples/test_tables.rs +0 -100
- data/vendor/html-to-markdown-rs/examples/test_task_lists.rs +0 -61
- data/vendor/html-to-markdown-rs/examples/test_whitespace.rs +0 -34
- data/vendor/html-to-markdown-rs/src/convert_api.rs +0 -349
- data/vendor/html-to-markdown-rs/src/converter/block/blockquote.rs +0 -178
- data/vendor/html-to-markdown-rs/src/converter/block/container.rs +0 -114
- data/vendor/html-to-markdown-rs/src/converter/block/div.rs +0 -149
- data/vendor/html-to-markdown-rs/src/converter/block/heading.rs +0 -428
- data/vendor/html-to-markdown-rs/src/converter/block/horizontal_rule.rs +0 -103
- data/vendor/html-to-markdown-rs/src/converter/block/line_break.rs +0 -89
- data/vendor/html-to-markdown-rs/src/converter/block/mod.rs +0 -10
- data/vendor/html-to-markdown-rs/src/converter/block/paragraph.rs +0 -140
- data/vendor/html-to-markdown-rs/src/converter/block/preformatted.rs +0 -298
- data/vendor/html-to-markdown-rs/src/converter/block/table/builder.rs +0 -453
- data/vendor/html-to-markdown-rs/src/converter/block/table/caption.rs +0 -44
- data/vendor/html-to-markdown-rs/src/converter/block/table/cell.rs +0 -276
- data/vendor/html-to-markdown-rs/src/converter/block/table/cells.rs +0 -336
- data/vendor/html-to-markdown-rs/src/converter/block/table/layout.rs +0 -58
- data/vendor/html-to-markdown-rs/src/converter/block/table/mod.rs +0 -266
- data/vendor/html-to-markdown-rs/src/converter/block/table/scanner.rs +0 -146
- data/vendor/html-to-markdown-rs/src/converter/block/table/utils.rs +0 -34
- data/vendor/html-to-markdown-rs/src/converter/block/unknown.rs +0 -138
- data/vendor/html-to-markdown-rs/src/converter/context.rs +0 -208
- data/vendor/html-to-markdown-rs/src/converter/dom_context.rs +0 -337
- data/vendor/html-to-markdown-rs/src/converter/form/elements.rs +0 -770
- data/vendor/html-to-markdown-rs/src/converter/form/mod.rs +0 -82
- data/vendor/html-to-markdown-rs/src/converter/format/djot.rs +0 -64
- data/vendor/html-to-markdown-rs/src/converter/format/markdown.rs +0 -59
- data/vendor/html-to-markdown-rs/src/converter/format/mod.rs +0 -43
- data/vendor/html-to-markdown-rs/src/converter/handlers/blockquote.rs +0 -173
- data/vendor/html-to-markdown-rs/src/converter/handlers/code_block.rs +0 -434
- data/vendor/html-to-markdown-rs/src/converter/handlers/graphic.rs +0 -234
- data/vendor/html-to-markdown-rs/src/converter/handlers/image.rs +0 -282
- data/vendor/html-to-markdown-rs/src/converter/handlers/link.rs +0 -316
- data/vendor/html-to-markdown-rs/src/converter/handlers/mod.rs +0 -26
- data/vendor/html-to-markdown-rs/src/converter/inline/code.rs +0 -306
- data/vendor/html-to-markdown-rs/src/converter/inline/emphasis.rs +0 -345
- data/vendor/html-to-markdown-rs/src/converter/inline/link.rs +0 -428
- data/vendor/html-to-markdown-rs/src/converter/inline/mod.rs +0 -237
- data/vendor/html-to-markdown-rs/src/converter/inline/ruby.rs +0 -337
- data/vendor/html-to-markdown-rs/src/converter/inline/semantic/marks.rs +0 -566
- data/vendor/html-to-markdown-rs/src/converter/inline/semantic/mod.rs +0 -86
- data/vendor/html-to-markdown-rs/src/converter/inline/semantic/typography.rs +0 -558
- data/vendor/html-to-markdown-rs/src/converter/list/definition.rs +0 -232
- data/vendor/html-to-markdown-rs/src/converter/list/item.rs +0 -332
- data/vendor/html-to-markdown-rs/src/converter/list/mod.rs +0 -70
- data/vendor/html-to-markdown-rs/src/converter/list/ordered.rs +0 -201
- data/vendor/html-to-markdown-rs/src/converter/list/unordered.rs +0 -195
- data/vendor/html-to-markdown-rs/src/converter/list/utils.rs +0 -314
- data/vendor/html-to-markdown-rs/src/converter/main.rs +0 -710
- data/vendor/html-to-markdown-rs/src/converter/main_helpers.rs +0 -452
- data/vendor/html-to-markdown-rs/src/converter/media/embedded.rs +0 -393
- data/vendor/html-to-markdown-rs/src/converter/media/graphic.rs +0 -4
- data/vendor/html-to-markdown-rs/src/converter/media/image.rs +0 -183
- data/vendor/html-to-markdown-rs/src/converter/media/mod.rs +0 -87
- data/vendor/html-to-markdown-rs/src/converter/media/svg.rs +0 -280
- data/vendor/html-to-markdown-rs/src/converter/metadata.rs +0 -220
- data/vendor/html-to-markdown-rs/src/converter/mod.rs +0 -156
- data/vendor/html-to-markdown-rs/src/converter/plain_text.rs +0 -516
- data/vendor/html-to-markdown-rs/src/converter/preprocessing_helpers.rs +0 -201
- data/vendor/html-to-markdown-rs/src/converter/reference_collector.rs +0 -69
- data/vendor/html-to-markdown-rs/src/converter/semantic/attributes.rs +0 -269
- data/vendor/html-to-markdown-rs/src/converter/semantic/definition_list.rs +0 -266
- data/vendor/html-to-markdown-rs/src/converter/semantic/figure.rs +0 -391
- data/vendor/html-to-markdown-rs/src/converter/semantic/mod.rs +0 -112
- data/vendor/html-to-markdown-rs/src/converter/semantic/sectioning.rs +0 -85
- data/vendor/html-to-markdown-rs/src/converter/semantic/summary.rs +0 -324
- data/vendor/html-to-markdown-rs/src/converter/text/mod.rs +0 -8
- data/vendor/html-to-markdown-rs/src/converter/text/processing.rs +0 -56
- data/vendor/html-to-markdown-rs/src/converter/text_node.rs +0 -269
- data/vendor/html-to-markdown-rs/src/converter/utility/attributes.rs +0 -151
- data/vendor/html-to-markdown-rs/src/converter/utility/caching.rs +0 -74
- data/vendor/html-to-markdown-rs/src/converter/utility/content.rs +0 -271
- data/vendor/html-to-markdown-rs/src/converter/utility/mod.rs +0 -17
- data/vendor/html-to-markdown-rs/src/converter/utility/preprocessing.rs +0 -1002
- data/vendor/html-to-markdown-rs/src/converter/utility/serialization.rs +0 -126
- data/vendor/html-to-markdown-rs/src/converter/utility/siblings.rs +0 -97
- data/vendor/html-to-markdown-rs/src/converter/visitor_hooks.rs +0 -189
- data/vendor/html-to-markdown-rs/src/error.rs +0 -43
- data/vendor/html-to-markdown-rs/src/exports.rs +0 -24
- data/vendor/html-to-markdown-rs/src/inline_images.rs +0 -336
- data/vendor/html-to-markdown-rs/src/lib.rs +0 -139
- data/vendor/html-to-markdown-rs/src/metadata/collector.rs +0 -457
- data/vendor/html-to-markdown-rs/src/metadata/config.rs +0 -394
- data/vendor/html-to-markdown-rs/src/metadata/extraction.rs +0 -398
- data/vendor/html-to-markdown-rs/src/metadata/mod.rs +0 -288
- data/vendor/html-to-markdown-rs/src/metadata/types.rs +0 -477
- data/vendor/html-to-markdown-rs/src/options/conversion.rs +0 -559
- data/vendor/html-to-markdown-rs/src/options/inline_image.rs +0 -111
- data/vendor/html-to-markdown-rs/src/options/mod.rs +0 -20
- data/vendor/html-to-markdown-rs/src/options/preprocessing.rs +0 -201
- data/vendor/html-to-markdown-rs/src/options/validation.rs +0 -416
- data/vendor/html-to-markdown-rs/src/prelude.rs +0 -1
- data/vendor/html-to-markdown-rs/src/rcdom.rs +0 -487
- data/vendor/html-to-markdown-rs/src/text.rs +0 -358
- data/vendor/html-to-markdown-rs/src/types/document.rs +0 -191
- data/vendor/html-to-markdown-rs/src/types/mod.rs +0 -17
- data/vendor/html-to-markdown-rs/src/types/result.rs +0 -54
- data/vendor/html-to-markdown-rs/src/types/structure_builder.rs +0 -791
- data/vendor/html-to-markdown-rs/src/types/structure_collector.rs +0 -483
- data/vendor/html-to-markdown-rs/src/types/tables.rs +0 -52
- data/vendor/html-to-markdown-rs/src/types/warnings.rs +0 -33
- data/vendor/html-to-markdown-rs/src/validation.rs +0 -158
- data/vendor/html-to-markdown-rs/src/visitor/default_impl.rs +0 -63
- data/vendor/html-to-markdown-rs/src/visitor/mod.rs +0 -41
- data/vendor/html-to-markdown-rs/src/visitor/traits.rs +0 -370
- data/vendor/html-to-markdown-rs/src/visitor/types.rs +0 -319
- data/vendor/html-to-markdown-rs/src/visitor_helpers/helpers/callbacks/mod.rs +0 -1
- data/vendor/html-to-markdown-rs/src/visitor_helpers/helpers/content.rs +0 -126
- data/vendor/html-to-markdown-rs/src/visitor_helpers/helpers/mod.rs +0 -27
- data/vendor/html-to-markdown-rs/src/visitor_helpers/helpers/state.rs +0 -110
- data/vendor/html-to-markdown-rs/src/visitor_helpers/helpers/traversal.rs +0 -250
- data/vendor/html-to-markdown-rs/src/visitor_helpers.rs +0 -597
- data/vendor/html-to-markdown-rs/src/wrapper/sync.rs +0 -413
- data/vendor/html-to-markdown-rs/src/wrapper/utils.rs +0 -290
- data/vendor/html-to-markdown-rs/src/wrapper.rs +0 -9
- data/vendor/html-to-markdown-rs/tests/br_in_inline_test.rs +0 -87
- data/vendor/html-to-markdown-rs/tests/commonmark_compliance_test.rs +0 -297
- data/vendor/html-to-markdown-rs/tests/djot_output_test.rs +0 -153
- data/vendor/html-to-markdown-rs/tests/exclude_selectors_test.rs +0 -132
- data/vendor/html-to-markdown-rs/tests/integration_test.rs +0 -631
- data/vendor/html-to-markdown-rs/tests/issue_121_regressions.rs +0 -49
- data/vendor/html-to-markdown-rs/tests/issue_127_regressions.rs +0 -58
- data/vendor/html-to-markdown-rs/tests/issue_128_regressions.rs +0 -17
- data/vendor/html-to-markdown-rs/tests/issue_131_regressions.rs +0 -41
- data/vendor/html-to-markdown-rs/tests/issue_134_regressions.rs +0 -40
- data/vendor/html-to-markdown-rs/tests/issue_139_regressions.rs +0 -26
- data/vendor/html-to-markdown-rs/tests/issue_140_regressions.rs +0 -185
- data/vendor/html-to-markdown-rs/tests/issue_143_regressions.rs +0 -100
- data/vendor/html-to-markdown-rs/tests/issue_145_regressions.rs +0 -133
- data/vendor/html-to-markdown-rs/tests/issue_146_regressions.rs +0 -144
- data/vendor/html-to-markdown-rs/tests/issue_176_regressions.rs +0 -62
- data/vendor/html-to-markdown-rs/tests/issue_190_regressions.rs +0 -128
- data/vendor/html-to-markdown-rs/tests/issue_199_regressions.rs +0 -20
- data/vendor/html-to-markdown-rs/tests/issue_200_regressions.rs +0 -62
- data/vendor/html-to-markdown-rs/tests/issue_212_regressions.rs +0 -68
- data/vendor/html-to-markdown-rs/tests/issue_216_217_regressions.rs +0 -87
- data/vendor/html-to-markdown-rs/tests/issue_336_regressions.rs +0 -74
- data/vendor/html-to-markdown-rs/tests/issue_339_regressions.rs +0 -92
- data/vendor/html-to-markdown-rs/tests/issue_347_regressions.rs +0 -154
- data/vendor/html-to-markdown-rs/tests/issue_348_visitor_plain.rs +0 -93
- data/vendor/html-to-markdown-rs/tests/json_ld_script_extraction.rs +0 -44
- data/vendor/html-to-markdown-rs/tests/lists_test.rs +0 -199
- data/vendor/html-to-markdown-rs/tests/plain_output_test.rs +0 -273
- data/vendor/html-to-markdown-rs/tests/preprocessing_tests.rs +0 -61
- data/vendor/html-to-markdown-rs/tests/reference_links_test.rs +0 -169
- data/vendor/html-to-markdown-rs/tests/sectioning_elements_test.rs +0 -137
- data/vendor/html-to-markdown-rs/tests/skip_images_test.rs +0 -522
- data/vendor/html-to-markdown-rs/tests/tables_test.rs +0 -743
- data/vendor/html-to-markdown-rs/tests/test_custom_elements.rs +0 -41
- data/vendor/html-to-markdown-rs/tests/test_issue_187.rs +0 -204
- data/vendor/html-to-markdown-rs/tests/test_issue_218.rs +0 -68
- data/vendor/html-to-markdown-rs/tests/test_issue_277.rs +0 -77
- data/vendor/html-to-markdown-rs/tests/test_max_depth.rs +0 -82
- data/vendor/html-to-markdown-rs/tests/test_nested_simple.rs +0 -45
- data/vendor/html-to-markdown-rs/tests/test_script_style_stripping.rs +0 -396
- data/vendor/html-to-markdown-rs/tests/test_spa_bisect.rs +0 -34
- data/vendor/html-to-markdown-rs/tests/visitor_code_integration_test.rs +0 -121
- data/vendor/html-to-markdown-rs/tests/visitor_integration_test.rs +0 -1190
- data/vendor/html-to-markdown-rs/tests/xml_tables_test.rs +0 -372
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
//! Text wrapping functionality for Markdown output.
|
|
2
|
-
//!
|
|
3
|
-
//! This module provides text wrapping capabilities similar to Python's `textwrap.fill()`,
|
|
4
|
-
//! specifically designed to work with Markdown content while preserving formatting.
|
|
5
|
-
|
|
6
|
-
pub use sync::wrap_markdown;
|
|
7
|
-
|
|
8
|
-
mod sync;
|
|
9
|
-
mod utils;
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
#![allow(missing_docs)]
|
|
2
|
-
|
|
3
|
-
fn convert(
|
|
4
|
-
html: &str,
|
|
5
|
-
opts: Option<html_to_markdown_rs::ConversionOptions>,
|
|
6
|
-
) -> html_to_markdown_rs::error::Result<String> {
|
|
7
|
-
html_to_markdown_rs::convert(html, opts).map(|r| r.content.unwrap_or_default())
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
use html_to_markdown_rs::ConversionOptions;
|
|
11
|
-
|
|
12
|
-
#[test]
|
|
13
|
-
fn test_br_inside_bold_tags() {
|
|
14
|
-
let html = "<b>Hello!<br/></b><b>Hola!</b>";
|
|
15
|
-
let result = convert(html, None).unwrap();
|
|
16
|
-
|
|
17
|
-
assert!(result.contains("**Hello!** \n**Hola!**"));
|
|
18
|
-
assert!(!result.contains("**Hello!****Hola!**"));
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
#[test]
|
|
22
|
-
fn test_br_inside_strong_tags() {
|
|
23
|
-
let html = "<strong>First<br/></strong><strong>Second</strong>";
|
|
24
|
-
let result = convert(html, None).unwrap();
|
|
25
|
-
|
|
26
|
-
assert!(result.contains("**First** \n**Second**"));
|
|
27
|
-
assert!(!result.contains("**First****Second**"));
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
#[test]
|
|
31
|
-
fn test_multiple_bolds_with_br() {
|
|
32
|
-
let html = "<b>Line 1<br/></b><b>Line 2<br/></b><b>Line 3</b>";
|
|
33
|
-
let result = convert(html, None).unwrap();
|
|
34
|
-
|
|
35
|
-
assert!(result.matches("**").count() >= 6);
|
|
36
|
-
assert!(result.contains("**Line 1**"));
|
|
37
|
-
assert!(result.contains("**Line 2**"));
|
|
38
|
-
assert!(result.contains("**Line 3**"));
|
|
39
|
-
assert!(result.contains("**Line 1** \n**Line 2**"));
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
#[test]
|
|
43
|
-
fn test_br_inside_em_tags() {
|
|
44
|
-
let html = "<em>First<br/></em><em>Second</em>";
|
|
45
|
-
let result = convert(html, None).unwrap();
|
|
46
|
-
|
|
47
|
-
assert!(result.contains("*First* \n*Second*"));
|
|
48
|
-
assert!(!result.contains("*First**Second*"));
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
#[test]
|
|
52
|
-
fn test_br_inside_italic_tags() {
|
|
53
|
-
let html = "<i>Alpha<br/></i><i>Beta</i>";
|
|
54
|
-
let result = convert(html, None).unwrap();
|
|
55
|
-
|
|
56
|
-
assert!(result.contains("*Alpha* \n*Beta*"));
|
|
57
|
-
assert!(!result.contains("*Alpha**Beta*"));
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
#[test]
|
|
61
|
-
fn test_br_with_backslash_style() {
|
|
62
|
-
let html = "<b>Hello<br/></b><b>World</b>";
|
|
63
|
-
let options = ConversionOptions {
|
|
64
|
-
newline_style: html_to_markdown_rs::NewlineStyle::Backslash,
|
|
65
|
-
..Default::default()
|
|
66
|
-
};
|
|
67
|
-
let result = convert(html, Some(options)).unwrap();
|
|
68
|
-
|
|
69
|
-
assert!(result.contains("**Hello**\\\n**World**"));
|
|
70
|
-
assert!(!result.contains("**Hello****World**"));
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
#[test]
|
|
74
|
-
fn test_br_inside_nested_formatting() {
|
|
75
|
-
let html = "<b><i>Bold italic<br/></i></b><b>Just bold</b>";
|
|
76
|
-
let result = convert(html, None).unwrap();
|
|
77
|
-
|
|
78
|
-
assert!(result.contains("***Bold italic*** \n**Just bold**"));
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
#[test]
|
|
82
|
-
fn test_br_at_end_of_paragraph_with_bold() {
|
|
83
|
-
let html = "<p><b>Line 1<br/></b><b>Line 2</b></p>";
|
|
84
|
-
let result = convert(html, None).unwrap();
|
|
85
|
-
|
|
86
|
-
assert!(result.contains("**Line 1** \n**Line 2**"));
|
|
87
|
-
}
|
|
@@ -1,297 +0,0 @@
|
|
|
1
|
-
#![allow(missing_docs)]
|
|
2
|
-
|
|
3
|
-
use html_to_markdown_rs::ConversionOptions;
|
|
4
|
-
use serde::Deserialize;
|
|
5
|
-
|
|
6
|
-
#[derive(Debug, Deserialize)]
|
|
7
|
-
struct CommonMarkTest {
|
|
8
|
-
markdown: String,
|
|
9
|
-
html: String,
|
|
10
|
-
example: u32,
|
|
11
|
-
start_line: u32,
|
|
12
|
-
#[allow(dead_code)]
|
|
13
|
-
end_line: u32,
|
|
14
|
-
section: String,
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
fn load_spec_tests() -> Vec<CommonMarkTest> {
|
|
18
|
-
let spec_json = include_str!("../../../packages/python/tests/commonmark_spec.json");
|
|
19
|
-
serde_json::from_str(spec_json).expect("Failed to parse commonmark_spec.json")
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
#[test]
|
|
23
|
-
#[allow(clippy::too_many_lines)]
|
|
24
|
-
fn test_commonmark_compliance() {
|
|
25
|
-
let tests = load_spec_tests();
|
|
26
|
-
let mut passed = 0;
|
|
27
|
-
let mut failed = 0;
|
|
28
|
-
let mut skipped = 0;
|
|
29
|
-
let mut failures = Vec::new();
|
|
30
|
-
|
|
31
|
-
for test in &tests {
|
|
32
|
-
let options = ConversionOptions {
|
|
33
|
-
bullets: "-".to_string(),
|
|
34
|
-
..ConversionOptions::default()
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
if !options.escape_misc
|
|
38
|
-
&& !options.escape_asterisks
|
|
39
|
-
&& !options.escape_underscores
|
|
40
|
-
&& !options.escape_ascii
|
|
41
|
-
&& test.section == "Backslash escapes"
|
|
42
|
-
{
|
|
43
|
-
skipped += 1;
|
|
44
|
-
continue;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
if test.section == "HTML blocks" || test.section == "Raw HTML" {
|
|
48
|
-
skipped += 1;
|
|
49
|
-
continue;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
if test.section == "Fenced code blocks" {
|
|
53
|
-
skipped += 1;
|
|
54
|
-
continue;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
// Example 231: expects indented code blocks but we default to backtick-fenced
|
|
58
|
-
if test.example == 231 {
|
|
59
|
-
skipped += 1;
|
|
60
|
-
continue;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
if test.section == "Tabs" {
|
|
64
|
-
skipped += 1;
|
|
65
|
-
continue;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
if test.section == "Entity and numeric character references" {
|
|
69
|
-
skipped += 1;
|
|
70
|
-
continue;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
if test.section == "Thematic breaks" {
|
|
74
|
-
skipped += 1;
|
|
75
|
-
continue;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
if test.section == "Hard line breaks" {
|
|
79
|
-
skipped += 1;
|
|
80
|
-
continue;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
if test.section == "Soft line breaks" {
|
|
84
|
-
skipped += 1;
|
|
85
|
-
continue;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
if test.section == "Blank lines" {
|
|
89
|
-
skipped += 1;
|
|
90
|
-
continue;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
if test.section == "Textual content" {
|
|
94
|
-
skipped += 1;
|
|
95
|
-
continue;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
if test.section == "Lists" {
|
|
99
|
-
skipped += 1;
|
|
100
|
-
continue;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
if test.section == "List items" {
|
|
104
|
-
skipped += 1;
|
|
105
|
-
continue;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
if test.section == "Paragraphs" {
|
|
109
|
-
skipped += 1;
|
|
110
|
-
continue;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
if test.section == "Setext headings" {
|
|
114
|
-
skipped += 1;
|
|
115
|
-
continue;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
if test.section == "Link reference definitions" {
|
|
119
|
-
skipped += 1;
|
|
120
|
-
continue;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
if test.section == "ATX headings" {
|
|
124
|
-
skipped += 1;
|
|
125
|
-
continue;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
if test.section == "Indented code blocks" {
|
|
129
|
-
skipped += 1;
|
|
130
|
-
continue;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
if test.section == "Code spans"
|
|
134
|
-
&& [
|
|
135
|
-
329, 334, 335, 336, 337, 338, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349,
|
|
136
|
-
]
|
|
137
|
-
.contains(&test.example)
|
|
138
|
-
{
|
|
139
|
-
skipped += 1;
|
|
140
|
-
continue;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
if test.section == "Links" {
|
|
144
|
-
if !test.html.contains("<a") {
|
|
145
|
-
skipped += 1;
|
|
146
|
-
continue;
|
|
147
|
-
}
|
|
148
|
-
let passing_examples = [
|
|
149
|
-
482, 483, 484, 486, 496, 498, 501, 512, 514, 516, 517, 518, 519, 521, 522,
|
|
150
|
-
];
|
|
151
|
-
if !passing_examples.contains(&test.example) {
|
|
152
|
-
skipped += 1;
|
|
153
|
-
continue;
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
if test.section == "Images" {
|
|
158
|
-
if !test.html.contains("<img") {
|
|
159
|
-
skipped += 1;
|
|
160
|
-
continue;
|
|
161
|
-
}
|
|
162
|
-
let passing_examples = [572, 578, 581];
|
|
163
|
-
if !passing_examples.contains(&test.example) {
|
|
164
|
-
skipped += 1;
|
|
165
|
-
continue;
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
if test.section == "Emphasis and strong emphasis" {
|
|
170
|
-
let passing_examples = [
|
|
171
|
-
350, 351, 352, 354, 355, 356, 358, 359, 360, 361, 362, 363, 365, 366, 367, 368, 369, 370, 371, 372,
|
|
172
|
-
374, 375, 378, 379, 380, 381, 383, 384, 385, 386, 387, 388, 391, 392, 393, 395, 396, 397, 398, 400,
|
|
173
|
-
401, 404, 405, 409, 410, 411, 412, 413, 414, 415, 416, 418, 419, 420, 421, 422, 423, 428, 429, 430,
|
|
174
|
-
431, 433, 434, 435, 436, 438, 439, 441, 442, 443, 444, 445, 446, 447, 448, 451, 460, 467, 469, 471,
|
|
175
|
-
472, 473, 474, 478, 480, 481,
|
|
176
|
-
];
|
|
177
|
-
if !passing_examples.contains(&test.example) {
|
|
178
|
-
skipped += 1;
|
|
179
|
-
continue;
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
if test.section == "Block quotes" {
|
|
184
|
-
let passing_examples = [228, 231, 234, 243, 245, 248];
|
|
185
|
-
if !passing_examples.contains(&test.example) {
|
|
186
|
-
skipped += 1;
|
|
187
|
-
continue;
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
if test.section == "Autolinks" {
|
|
192
|
-
let passing_examples = [594, 595, 596, 597, 600, 602, 604, 605, 607, 608, 609, 610, 611, 612];
|
|
193
|
-
if !passing_examples.contains(&test.example) {
|
|
194
|
-
skipped += 1;
|
|
195
|
-
continue;
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
let result = convert(&test.html, Some(options));
|
|
200
|
-
|
|
201
|
-
match result {
|
|
202
|
-
Ok(output) => {
|
|
203
|
-
let output_normalized = normalize_markdown(&output);
|
|
204
|
-
let expected_normalized = normalize_markdown(&test.markdown);
|
|
205
|
-
|
|
206
|
-
if output_normalized == expected_normalized {
|
|
207
|
-
passed += 1;
|
|
208
|
-
} else {
|
|
209
|
-
failed += 1;
|
|
210
|
-
failures.push((test, output));
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
Err(e) => {
|
|
214
|
-
failed += 1;
|
|
215
|
-
failures.push((test, format!("Error: {e:?}")));
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
let total = tests.len();
|
|
221
|
-
let tested = passed + failed;
|
|
222
|
-
let pass_rate = if tested > 0 {
|
|
223
|
-
(f64::from(passed) / f64::from(tested)) * 100.0
|
|
224
|
-
} else {
|
|
225
|
-
0.0
|
|
226
|
-
};
|
|
227
|
-
|
|
228
|
-
println!("\n=== CommonMark Compliance Test Results ===");
|
|
229
|
-
println!("Total tests: {total}");
|
|
230
|
-
if skipped > 0 {
|
|
231
|
-
println!("Skipped: {skipped} (escaping tests with escaping disabled)");
|
|
232
|
-
println!("Tested: {tested}");
|
|
233
|
-
}
|
|
234
|
-
println!("Passed: {passed} ({pass_rate:.1}%)");
|
|
235
|
-
println!(
|
|
236
|
-
"Failed: {} ({:.1}%)",
|
|
237
|
-
failed,
|
|
238
|
-
(f64::from(failed) / f64::from(tested)) * 100.0
|
|
239
|
-
);
|
|
240
|
-
|
|
241
|
-
if !failures.is_empty() {
|
|
242
|
-
println!("\n=== Failed Tests (first 20) ===");
|
|
243
|
-
for (test, output) in failures.iter().take(20) {
|
|
244
|
-
println!("\nExample {} ({}:{})", test.example, test.section, test.start_line);
|
|
245
|
-
println!("HTML input:\n{}", test.html);
|
|
246
|
-
println!("Expected markdown:\n{}", test.markdown);
|
|
247
|
-
println!("Got:\n{output}");
|
|
248
|
-
println!("---");
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
println!("\n=== Autolinks Failures ===");
|
|
252
|
-
for (test, output) in &failures {
|
|
253
|
-
if test.section == "Autolinks" {
|
|
254
|
-
println!("\nExample {} ({}:{})", test.example, test.section, test.start_line);
|
|
255
|
-
println!("HTML input:\n{}", test.html);
|
|
256
|
-
println!("Expected markdown:\n{}", test.markdown);
|
|
257
|
-
println!("Got:\n{output}");
|
|
258
|
-
println!("---");
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
let mut section_failures: std::collections::HashMap<&str, usize> = std::collections::HashMap::new();
|
|
263
|
-
for (test, _) in &failures {
|
|
264
|
-
*section_failures.entry(&test.section).or_insert(0) += 1;
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
println!("\n=== Failures by Section ===");
|
|
268
|
-
let mut sections: Vec<_> = section_failures.iter().collect();
|
|
269
|
-
sections.sort_by_key(|(_, count)| std::cmp::Reverse(*count));
|
|
270
|
-
for (section, count) in sections {
|
|
271
|
-
println!("{section}: {count} failures");
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
panic!(
|
|
275
|
-
"\nCommonMark compliance test FAILED: {passed}/{tested} tests passing ({pass_rate:.1}%)\n\
|
|
276
|
-
{skipped} tests skipped (escaping tests with escaping disabled)\n\
|
|
277
|
-
Default library settings must be CommonMark compliant!\n\
|
|
278
|
-
This is a mandatory test for v2.0 release."
|
|
279
|
-
);
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
println!(
|
|
283
|
-
"\n✓ All {tested} CommonMark tests passed! ({skipped} skipped) Library defaults are CommonMark compliant."
|
|
284
|
-
);
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
/// Normalize markdown for comparison
|
|
288
|
-
fn normalize_markdown(md: &str) -> String {
|
|
289
|
-
md.trim_end().to_string()
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
fn convert(
|
|
293
|
-
html: &str,
|
|
294
|
-
opts: Option<html_to_markdown_rs::ConversionOptions>,
|
|
295
|
-
) -> html_to_markdown_rs::error::Result<String> {
|
|
296
|
-
html_to_markdown_rs::convert(html, opts).map(|r| r.content.unwrap_or_default())
|
|
297
|
-
}
|
|
@@ -1,153 +0,0 @@
|
|
|
1
|
-
#![allow(missing_docs)]
|
|
2
|
-
fn convert(
|
|
3
|
-
html: &str,
|
|
4
|
-
opts: Option<html_to_markdown_rs::ConversionOptions>,
|
|
5
|
-
) -> html_to_markdown_rs::error::Result<String> {
|
|
6
|
-
html_to_markdown_rs::convert(html, opts).map(|r| r.content.unwrap_or_default())
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
use html_to_markdown_rs::{ConversionOptions, OutputFormat};
|
|
10
|
-
|
|
11
|
-
fn djot_options() -> ConversionOptions {
|
|
12
|
-
ConversionOptions {
|
|
13
|
-
output_format: OutputFormat::Djot,
|
|
14
|
-
..Default::default()
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
#[test]
|
|
19
|
-
fn test_djot_emphasis() {
|
|
20
|
-
let html = "<p>Text with <em>emphasis</em> word</p>";
|
|
21
|
-
let result = convert(html, Some(djot_options())).unwrap();
|
|
22
|
-
assert!(result.contains("_emphasis_"), "Expected _emphasis_, got: {result}");
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
#[test]
|
|
26
|
-
fn test_djot_italic() {
|
|
27
|
-
let html = "<p>Text with <i>italic</i> word</p>";
|
|
28
|
-
let result = convert(html, Some(djot_options())).unwrap();
|
|
29
|
-
assert!(result.contains("_italic_"), "Expected _italic_, got: {result}");
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
#[test]
|
|
33
|
-
fn test_djot_strong() {
|
|
34
|
-
let html = "<p>Text with <strong>strong</strong> word</p>";
|
|
35
|
-
let result = convert(html, Some(djot_options())).unwrap();
|
|
36
|
-
assert!(result.contains("*strong*"), "Expected *strong*, got: {result}");
|
|
37
|
-
// Should NOT have double asterisks
|
|
38
|
-
assert!(
|
|
39
|
-
!result.contains("**strong**"),
|
|
40
|
-
"Should not have **strong**, got: {result}"
|
|
41
|
-
);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
#[test]
|
|
45
|
-
fn test_djot_bold() {
|
|
46
|
-
let html = "<p>Text with <b>bold</b> word</p>";
|
|
47
|
-
let result = convert(html, Some(djot_options())).unwrap();
|
|
48
|
-
assert!(result.contains("*bold*"), "Expected *bold*, got: {result}");
|
|
49
|
-
// Should NOT have double asterisks
|
|
50
|
-
assert!(
|
|
51
|
-
!result.contains("**bold**"),
|
|
52
|
-
"Should not have double asterisks, got: {result}"
|
|
53
|
-
);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
#[test]
|
|
57
|
-
fn test_djot_options_debug() {
|
|
58
|
-
// Debug test to verify options are set correctly
|
|
59
|
-
let options = djot_options();
|
|
60
|
-
println!("Output format: {:?}", options.output_format);
|
|
61
|
-
assert_eq!(options.output_format, OutputFormat::Djot);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
#[test]
|
|
65
|
-
fn test_djot_strikethrough() {
|
|
66
|
-
let html = "<p>Text with <del>deleted</del> word</p>";
|
|
67
|
-
let result = convert(html, Some(djot_options())).unwrap();
|
|
68
|
-
assert!(result.contains("{-deleted-}"), "Expected {{-deleted-}}, got: {result}");
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
#[test]
|
|
72
|
-
fn test_djot_strikethrough_s_tag() {
|
|
73
|
-
let html = "<p>Text with <s>strikethrough</s> word</p>";
|
|
74
|
-
let result = convert(html, Some(djot_options())).unwrap();
|
|
75
|
-
assert!(
|
|
76
|
-
result.contains("{-strikethrough-}"),
|
|
77
|
-
"Expected {{-strikethrough-}}, got: {result}"
|
|
78
|
-
);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
#[test]
|
|
82
|
-
fn test_djot_inserted() {
|
|
83
|
-
let html = "<p>Text with <ins>inserted</ins> word</p>";
|
|
84
|
-
let result = convert(html, Some(djot_options())).unwrap();
|
|
85
|
-
assert!(
|
|
86
|
-
result.contains("{+inserted+}"),
|
|
87
|
-
"Expected {{+inserted+}}, got: {result}"
|
|
88
|
-
);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
#[test]
|
|
92
|
-
fn test_djot_highlight() {
|
|
93
|
-
let html = "<p>Text with <mark>highlighted</mark> word</p>";
|
|
94
|
-
let result = convert(html, Some(djot_options())).unwrap();
|
|
95
|
-
assert!(
|
|
96
|
-
result.contains("{=highlighted=}"),
|
|
97
|
-
"Expected {{=highlighted=}}, got: {result}"
|
|
98
|
-
);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
#[test]
|
|
102
|
-
fn test_djot_subscript() {
|
|
103
|
-
let html = "<p>H<sub>2</sub>O</p>";
|
|
104
|
-
let result = convert(html, Some(djot_options())).unwrap();
|
|
105
|
-
assert!(result.contains("~2~"), "Expected ~2~, got: {result}");
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
#[test]
|
|
109
|
-
fn test_djot_superscript() {
|
|
110
|
-
let html = "<p>x<sup>2</sup></p>";
|
|
111
|
-
let result = convert(html, Some(djot_options())).unwrap();
|
|
112
|
-
assert!(result.contains("^2^"), "Expected ^2^, got: {result}");
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
#[test]
|
|
116
|
-
fn test_djot_combined_formatting() {
|
|
117
|
-
let html = "<p><strong>Bold</strong> and <em>italic</em> and <del>deleted</del></p>";
|
|
118
|
-
let result = convert(html, Some(djot_options())).unwrap();
|
|
119
|
-
assert!(result.contains("*Bold*"), "Expected *Bold*, got: {result}");
|
|
120
|
-
assert!(result.contains("_italic_"), "Expected _italic_, got: {result}");
|
|
121
|
-
assert!(result.contains("{-deleted-}"), "Expected {{-deleted-}}, got: {result}");
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
#[test]
|
|
125
|
-
fn test_markdown_output_unchanged() {
|
|
126
|
-
// Verify Markdown output still works as expected
|
|
127
|
-
let html = "<p><strong>Bold</strong> and <em>italic</em></p>";
|
|
128
|
-
let result = convert(html, None).unwrap();
|
|
129
|
-
assert!(
|
|
130
|
-
result.contains("**Bold**"),
|
|
131
|
-
"Expected **Bold** for Markdown, got: {result}"
|
|
132
|
-
);
|
|
133
|
-
assert!(
|
|
134
|
-
result.contains("*italic*"),
|
|
135
|
-
"Expected *italic* for Markdown, got: {result}"
|
|
136
|
-
);
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
#[test]
|
|
140
|
-
fn test_markdown_strikethrough_unchanged() {
|
|
141
|
-
let html = "<p><del>deleted</del></p>";
|
|
142
|
-
let result = convert(html, None).unwrap();
|
|
143
|
-
assert!(
|
|
144
|
-
result.contains("~~deleted~~"),
|
|
145
|
-
"Expected ~~deleted~~ for Markdown, got: {result}"
|
|
146
|
-
);
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
#[test]
|
|
150
|
-
fn test_output_format_default_is_markdown() {
|
|
151
|
-
let options = ConversionOptions::default();
|
|
152
|
-
assert_eq!(options.output_format, OutputFormat::Markdown);
|
|
153
|
-
}
|
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
#![allow(missing_docs)]
|
|
2
|
-
|
|
3
|
-
use html_to_markdown_rs::ConversionOptions;
|
|
4
|
-
|
|
5
|
-
fn convert(html: &str, opts: Option<ConversionOptions>) -> html_to_markdown_rs::error::Result<String> {
|
|
6
|
-
html_to_markdown_rs::convert(html, opts).map(|r| r.content.unwrap_or_default())
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
#[test]
|
|
10
|
-
fn test_exclude_selectors_drops_matching_elements() {
|
|
11
|
-
let html = r#"<body>
|
|
12
|
-
<div class="cookie-banner">Accept cookies</div>
|
|
13
|
-
<article><p>Main content here.</p></article>
|
|
14
|
-
<div id="ad-container">Buy stuff</div>
|
|
15
|
-
</body>"#;
|
|
16
|
-
|
|
17
|
-
let options = ConversionOptions {
|
|
18
|
-
exclude_selectors: vec![".cookie-banner".to_string(), "#ad-container".to_string()],
|
|
19
|
-
..Default::default()
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
let result = convert(html, Some(options)).unwrap();
|
|
23
|
-
|
|
24
|
-
assert!(result.contains("Main content"), "Should keep main content");
|
|
25
|
-
assert!(!result.contains("cookie"), "Should drop .cookie-banner element");
|
|
26
|
-
assert!(!result.contains("Buy stuff"), "Should drop #ad-container element");
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
#[test]
|
|
30
|
-
fn test_exclude_selectors_drops_nested_content() {
|
|
31
|
-
let html = r#"<body>
|
|
32
|
-
<aside class="sidebar">
|
|
33
|
-
<h2>Related articles</h2>
|
|
34
|
-
<p>Some sidebar content</p>
|
|
35
|
-
</aside>
|
|
36
|
-
<main><p>Primary content.</p></main>
|
|
37
|
-
</body>"#;
|
|
38
|
-
|
|
39
|
-
let options = ConversionOptions {
|
|
40
|
-
exclude_selectors: vec![".sidebar".to_string()],
|
|
41
|
-
..Default::default()
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
let result = convert(html, Some(options)).unwrap();
|
|
45
|
-
|
|
46
|
-
assert!(result.contains("Primary content"), "Should keep main content");
|
|
47
|
-
assert!(
|
|
48
|
-
!result.contains("Related articles"),
|
|
49
|
-
"Should drop heading inside excluded element"
|
|
50
|
-
);
|
|
51
|
-
assert!(
|
|
52
|
-
!result.contains("sidebar content"),
|
|
53
|
-
"Should drop paragraph inside excluded element"
|
|
54
|
-
);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
#[test]
|
|
58
|
-
fn test_exclude_selectors_empty_list_is_noop() {
|
|
59
|
-
let html = r"<body><p>Hello world</p></body>";
|
|
60
|
-
|
|
61
|
-
let options = ConversionOptions {
|
|
62
|
-
exclude_selectors: vec![],
|
|
63
|
-
..Default::default()
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
let result = convert(html, Some(options)).unwrap();
|
|
67
|
-
assert!(
|
|
68
|
-
result.contains("Hello world"),
|
|
69
|
-
"Empty exclude_selectors should not affect output"
|
|
70
|
-
);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
#[test]
|
|
74
|
-
fn test_exclude_selectors_invalid_selector_is_skipped() {
|
|
75
|
-
let html = r"<body><p>Visible text</p></body>";
|
|
76
|
-
|
|
77
|
-
// An empty string or garbled selector should not panic or error — just be ignored.
|
|
78
|
-
let options = ConversionOptions {
|
|
79
|
-
exclude_selectors: vec![String::new(), "p".to_string()],
|
|
80
|
-
..Default::default()
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
// Should not return an error; whether the paragraph is excluded depends on the
|
|
84
|
-
// selector, but it must not panic.
|
|
85
|
-
let _ = convert(html, Some(options));
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
#[test]
|
|
89
|
-
fn test_exclude_selectors_attribute_selector() {
|
|
90
|
-
let html = r#"<body>
|
|
91
|
-
<div role="complementary">Sidebar</div>
|
|
92
|
-
<p>Main text</p>
|
|
93
|
-
</body>"#;
|
|
94
|
-
|
|
95
|
-
let options = ConversionOptions {
|
|
96
|
-
exclude_selectors: vec!["[role='complementary']".to_string()],
|
|
97
|
-
..Default::default()
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
let result = convert(html, Some(options)).unwrap();
|
|
101
|
-
|
|
102
|
-
assert!(result.contains("Main text"), "Should keep non-excluded content");
|
|
103
|
-
assert!(
|
|
104
|
-
!result.contains("Sidebar"),
|
|
105
|
-
"Should drop element matching attribute selector"
|
|
106
|
-
);
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
#[test]
|
|
110
|
-
fn test_exclude_selectors_plain_text_output() {
|
|
111
|
-
let html = r#"<body>
|
|
112
|
-
<div class="nav">Navigation links</div>
|
|
113
|
-
<p>Article body text.</p>
|
|
114
|
-
</body>"#;
|
|
115
|
-
|
|
116
|
-
let options = ConversionOptions {
|
|
117
|
-
exclude_selectors: vec![".nav".to_string()],
|
|
118
|
-
output_format: html_to_markdown_rs::OutputFormat::Plain,
|
|
119
|
-
..Default::default()
|
|
120
|
-
};
|
|
121
|
-
|
|
122
|
-
let result = convert(html, Some(options)).unwrap();
|
|
123
|
-
|
|
124
|
-
assert!(
|
|
125
|
-
result.contains("Article body text"),
|
|
126
|
-
"Should keep body text in plain output"
|
|
127
|
-
);
|
|
128
|
-
assert!(
|
|
129
|
-
!result.contains("Navigation links"),
|
|
130
|
-
"Should drop excluded element in plain output"
|
|
131
|
-
);
|
|
132
|
-
}
|