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,271 +0,0 @@
|
|
|
1
|
-
//! Content extraction and manipulation utilities.
|
|
2
|
-
//!
|
|
3
|
-
//! Functions for extracting and processing element content, including text collection
|
|
4
|
-
//! and empty element detection.
|
|
5
|
-
|
|
6
|
-
use crate::text;
|
|
7
|
-
use std::borrow::Cow;
|
|
8
|
-
#[cfg(feature = "visitor")]
|
|
9
|
-
use std::collections::BTreeMap;
|
|
10
|
-
|
|
11
|
-
// Forward declare DomContext from parent module to avoid circular imports
|
|
12
|
-
pub use crate::converter::DomContext;
|
|
13
|
-
|
|
14
|
-
/// Collect all attributes from an HTML tag as a `BTreeMap<String, String>`.
|
|
15
|
-
///
|
|
16
|
-
/// Boolean attributes (those with `None` as the value) are skipped; only
|
|
17
|
-
/// attributes that carry an explicit value are included.
|
|
18
|
-
#[cfg(feature = "visitor")]
|
|
19
|
-
pub fn collect_tag_attributes(tag: &tl::HTMLTag) -> BTreeMap<String, String> {
|
|
20
|
-
tag.attributes()
|
|
21
|
-
.iter()
|
|
22
|
-
.filter_map(|(k, v)| v.as_ref().map(|val| (k.to_string(), val.to_string())))
|
|
23
|
-
.collect()
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/// Chomp whitespace from inline element content, preserving line breaks.
|
|
27
|
-
///
|
|
28
|
-
/// Similar to `text::chomp` but handles line breaks from `<br>` tags specially.
|
|
29
|
-
/// Line breaks are extracted as suffix to be placed outside formatting.
|
|
30
|
-
/// Returns (prefix, suffix, `trimmed_text`).
|
|
31
|
-
pub fn chomp_inline(text: &str) -> (&str, &str, &str) {
|
|
32
|
-
if text.is_empty() {
|
|
33
|
-
return ("", "", "");
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
let prefix = if text.starts_with(&[' ', '\t'][..]) { " " } else { "" };
|
|
37
|
-
|
|
38
|
-
let has_trailing_linebreak = text.ends_with(" \n") || text.ends_with("\\\n");
|
|
39
|
-
|
|
40
|
-
let suffix = if has_trailing_linebreak {
|
|
41
|
-
if text.ends_with(" \n") { " \n" } else { "\\\n" }
|
|
42
|
-
} else if text.ends_with(&[' ', '\t'][..]) {
|
|
43
|
-
" "
|
|
44
|
-
} else {
|
|
45
|
-
""
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
let trimmed = if has_trailing_linebreak {
|
|
49
|
-
text.strip_suffix(" \n").map_or_else(
|
|
50
|
-
|| text.strip_suffix("\\\n").map_or_else(|| text.trim(), |s| s.trim()),
|
|
51
|
-
|s| s.trim(),
|
|
52
|
-
)
|
|
53
|
-
} else {
|
|
54
|
-
text.trim()
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
(prefix, suffix, trimmed)
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/// Get the text content of a node and its children.
|
|
61
|
-
#[allow(clippy::trivially_copy_pass_by_ref)]
|
|
62
|
-
pub fn get_text_content(node_handle: &tl::NodeHandle, parser: &tl::Parser, dom_ctx: &DomContext) -> String {
|
|
63
|
-
dom_ctx.text_content(*node_handle, parser)
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/// Collect inline text for link labels, skipping block-level descendants.
|
|
67
|
-
#[allow(clippy::match_wildcard_for_single_variants)]
|
|
68
|
-
pub fn collect_link_label_text(
|
|
69
|
-
children: &[tl::NodeHandle],
|
|
70
|
-
parser: &tl::Parser,
|
|
71
|
-
dom_ctx: &DomContext,
|
|
72
|
-
) -> (String, Vec<tl::NodeHandle>, bool) {
|
|
73
|
-
let mut text = String::new();
|
|
74
|
-
let mut saw_block = false;
|
|
75
|
-
let mut block_nodes = Vec::new();
|
|
76
|
-
let mut stack: Vec<_> = children.iter().rev().copied().collect();
|
|
77
|
-
|
|
78
|
-
while let Some(handle) = stack.pop() {
|
|
79
|
-
if let Some(node) = handle.get(parser) {
|
|
80
|
-
match node {
|
|
81
|
-
tl::Node::Raw(bytes) => {
|
|
82
|
-
let raw = bytes.as_utf8_str();
|
|
83
|
-
let decoded = text::decode_html_entities_cow(raw.as_ref());
|
|
84
|
-
text.push_str(decoded.as_ref());
|
|
85
|
-
}
|
|
86
|
-
tl::Node::Tag(tag) => {
|
|
87
|
-
let is_block = dom_ctx.tag_info(handle.get_inner(), parser).map_or_else(
|
|
88
|
-
|| {
|
|
89
|
-
let tag_name = normalized_tag_name(tag.name().as_utf8_str());
|
|
90
|
-
is_block_level_element(tag_name.as_ref())
|
|
91
|
-
},
|
|
92
|
-
|info| info.is_block,
|
|
93
|
-
);
|
|
94
|
-
if is_block {
|
|
95
|
-
saw_block = true;
|
|
96
|
-
block_nodes.push(handle);
|
|
97
|
-
continue;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
if let Some(children) = dom_ctx.children_of(handle.get_inner()) {
|
|
101
|
-
for child in children.iter().rev() {
|
|
102
|
-
stack.push(*child);
|
|
103
|
-
}
|
|
104
|
-
} else {
|
|
105
|
-
let tag_children = tag.children();
|
|
106
|
-
let mut child_nodes: Vec<_> = tag_children.top().iter().copied().collect();
|
|
107
|
-
child_nodes.reverse();
|
|
108
|
-
stack.extend(child_nodes);
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
_ => {}
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
(text, block_nodes, saw_block)
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
/// Normalize a link label by collapsing newlines and normalizing whitespace.
|
|
120
|
-
#[allow(clippy::trivially_copy_pass_by_ref)]
|
|
121
|
-
pub fn normalize_link_label(label: &str) -> String {
|
|
122
|
-
let mut needs_collapse = false;
|
|
123
|
-
for ch in label.chars() {
|
|
124
|
-
if ch == '\n' || ch == '\r' {
|
|
125
|
-
needs_collapse = true;
|
|
126
|
-
break;
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
let collapsed = if needs_collapse {
|
|
131
|
-
let mut collapsed = String::with_capacity(label.len());
|
|
132
|
-
for ch in label.chars() {
|
|
133
|
-
if ch == '\n' || ch == '\r' {
|
|
134
|
-
collapsed.push(' ');
|
|
135
|
-
} else {
|
|
136
|
-
collapsed.push(ch);
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
Cow::Owned(collapsed)
|
|
140
|
-
} else {
|
|
141
|
-
Cow::Borrowed(label)
|
|
142
|
-
};
|
|
143
|
-
|
|
144
|
-
let normalized = text::normalize_whitespace_cow(collapsed.as_ref());
|
|
145
|
-
normalized.as_ref().trim().to_string()
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
/// Normalize a tag name to lowercase, preserving borrowed input when possible.
|
|
149
|
-
pub fn normalized_tag_name(raw: Cow<'_, str>) -> Cow<'_, str> {
|
|
150
|
-
if raw.as_bytes().iter().any(u8::is_ascii_uppercase) {
|
|
151
|
-
let mut owned = raw.into_owned();
|
|
152
|
-
owned.make_ascii_lowercase();
|
|
153
|
-
Cow::Owned(owned)
|
|
154
|
-
} else {
|
|
155
|
-
raw
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
/// Check if an element is block-level (not inline).
|
|
160
|
-
pub fn is_block_level_element(tag_name: &str) -> bool {
|
|
161
|
-
is_block_level_name(tag_name, crate::converter::main_helpers::is_inline_element(tag_name))
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
/// Returns the largest valid char boundary index at or before `index`.
|
|
165
|
-
///
|
|
166
|
-
/// If `index` is already a char boundary it is returned unchanged.
|
|
167
|
-
/// Otherwise it walks backwards to find one. Returns 0 if no boundary
|
|
168
|
-
/// is found before `index`.
|
|
169
|
-
pub fn floor_char_boundary(s: &str, index: usize) -> usize {
|
|
170
|
-
if index >= s.len() {
|
|
171
|
-
s.len()
|
|
172
|
-
} else {
|
|
173
|
-
let mut i = index;
|
|
174
|
-
while i > 0 && !s.is_char_boundary(i) {
|
|
175
|
-
i -= 1;
|
|
176
|
-
}
|
|
177
|
-
i
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
/// Escape special Markdown characters in a link label.
|
|
182
|
-
///
|
|
183
|
-
/// Handles bracket escaping to prevent unintended link label termination.
|
|
184
|
-
/// Tracks bracket depth and escapes closing brackets when depth is zero.
|
|
185
|
-
///
|
|
186
|
-
/// # Examples
|
|
187
|
-
/// ```text
|
|
188
|
-
/// Input: "[link]"
|
|
189
|
-
/// Output: "[link\\]"
|
|
190
|
-
///
|
|
191
|
-
/// Input: "[outer [inner]]"
|
|
192
|
-
/// Output: "[outer [inner]]"
|
|
193
|
-
/// ```
|
|
194
|
-
pub fn escape_link_label(text: &str) -> String {
|
|
195
|
-
if text.is_empty() {
|
|
196
|
-
return String::new();
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
let mut result = String::with_capacity(text.len());
|
|
200
|
-
let mut backslash_count = 0usize;
|
|
201
|
-
let mut bracket_depth = 0usize;
|
|
202
|
-
|
|
203
|
-
for ch in text.chars() {
|
|
204
|
-
if ch == '\\' {
|
|
205
|
-
result.push('\\');
|
|
206
|
-
backslash_count += 1;
|
|
207
|
-
continue;
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
let is_escaped = backslash_count % 2 == 1;
|
|
211
|
-
backslash_count = 0;
|
|
212
|
-
|
|
213
|
-
match ch {
|
|
214
|
-
'[' if !is_escaped => {
|
|
215
|
-
bracket_depth = bracket_depth.saturating_add(1);
|
|
216
|
-
result.push('[');
|
|
217
|
-
}
|
|
218
|
-
']' if !is_escaped => {
|
|
219
|
-
if bracket_depth == 0 {
|
|
220
|
-
result.push('\\');
|
|
221
|
-
} else {
|
|
222
|
-
bracket_depth -= 1;
|
|
223
|
-
}
|
|
224
|
-
result.push(']');
|
|
225
|
-
}
|
|
226
|
-
_ => result.push(ch),
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
result
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
/// Helper for block-level element detection.
|
|
234
|
-
pub fn is_block_level_name(tag_name: &str, is_inline: bool) -> bool {
|
|
235
|
-
!is_inline
|
|
236
|
-
&& matches!(
|
|
237
|
-
tag_name,
|
|
238
|
-
"address"
|
|
239
|
-
| "article"
|
|
240
|
-
| "aside"
|
|
241
|
-
| "blockquote"
|
|
242
|
-
| "canvas"
|
|
243
|
-
| "dd"
|
|
244
|
-
| "div"
|
|
245
|
-
| "dl"
|
|
246
|
-
| "dt"
|
|
247
|
-
| "fieldset"
|
|
248
|
-
| "figcaption"
|
|
249
|
-
| "figure"
|
|
250
|
-
| "footer"
|
|
251
|
-
| "form"
|
|
252
|
-
| "h1"
|
|
253
|
-
| "h2"
|
|
254
|
-
| "h3"
|
|
255
|
-
| "h4"
|
|
256
|
-
| "h5"
|
|
257
|
-
| "h6"
|
|
258
|
-
| "header"
|
|
259
|
-
| "hr"
|
|
260
|
-
| "li"
|
|
261
|
-
| "main"
|
|
262
|
-
| "nav"
|
|
263
|
-
| "ol"
|
|
264
|
-
| "p"
|
|
265
|
-
| "pre"
|
|
266
|
-
| "section"
|
|
267
|
-
| "table"
|
|
268
|
-
| "tfoot"
|
|
269
|
-
| "ul"
|
|
270
|
-
)
|
|
271
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
//! Utility module: helper functions for common operations.
|
|
2
|
-
//!
|
|
3
|
-
//! This module contains utility functions used across conversion logic
|
|
4
|
-
//! including sibling handling, content extraction, serialization, preprocessing,
|
|
5
|
-
//! caching, and attribute processing.
|
|
6
|
-
//!
|
|
7
|
-
//! These functions are re-exported from the main converter module to provide
|
|
8
|
-
//! organized access to utility functions by category.
|
|
9
|
-
|
|
10
|
-
pub mod attributes;
|
|
11
|
-
pub mod caching;
|
|
12
|
-
pub mod content;
|
|
13
|
-
pub mod preprocessing;
|
|
14
|
-
pub mod serialization;
|
|
15
|
-
pub mod siblings;
|
|
16
|
-
|
|
17
|
-
// Re-export commonly used functions for convenience
|