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,201 +0,0 @@
|
|
|
1
|
-
#![allow(clippy::cast_precision_loss, clippy::cast_sign_loss, clippy::unused_self)]
|
|
2
|
-
|
|
3
|
-
//! HTML preprocessing configuration options.
|
|
4
|
-
//!
|
|
5
|
-
//! This module provides configuration for document cleanup before conversion,
|
|
6
|
-
//! including preset levels and granular control over element removal.
|
|
7
|
-
|
|
8
|
-
use crate::options::validation::normalize_token;
|
|
9
|
-
|
|
10
|
-
/// HTML preprocessing aggressiveness level.
|
|
11
|
-
///
|
|
12
|
-
/// Controls the extent of cleanup performed before conversion. Higher levels remove more elements.
|
|
13
|
-
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
|
|
14
|
-
pub enum PreprocessingPreset {
|
|
15
|
-
/// Minimal cleanup. Remove only essential noise (scripts, styles).
|
|
16
|
-
Minimal,
|
|
17
|
-
/// Standard cleanup. Default. Removes navigation, forms, and other auxiliary content.
|
|
18
|
-
#[default]
|
|
19
|
-
Standard,
|
|
20
|
-
/// Aggressive cleanup. Remove extensive non-content elements and structure.
|
|
21
|
-
Aggressive,
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
impl PreprocessingPreset {
|
|
25
|
-
/// Parse a preprocessing preset from a string.
|
|
26
|
-
///
|
|
27
|
-
/// Accepts "minimal", "aggressive", or defaults to Standard.
|
|
28
|
-
/// Input is normalized (lowercased, alphanumeric only).
|
|
29
|
-
#[must_use]
|
|
30
|
-
pub fn parse(value: &str) -> Self {
|
|
31
|
-
match normalize_token(value).as_str() {
|
|
32
|
-
"minimal" => Self::Minimal,
|
|
33
|
-
"aggressive" => Self::Aggressive,
|
|
34
|
-
_ => Self::Standard,
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/// HTML preprocessing options for document cleanup before conversion.
|
|
40
|
-
#[derive(Debug, Clone)]
|
|
41
|
-
#[cfg_attr(
|
|
42
|
-
any(feature = "serde", feature = "metadata"),
|
|
43
|
-
derive(serde::Serialize, serde::Deserialize)
|
|
44
|
-
)]
|
|
45
|
-
#[cfg_attr(any(feature = "serde", feature = "metadata"), serde(default, deny_unknown_fields))]
|
|
46
|
-
pub struct PreprocessingOptions {
|
|
47
|
-
/// Enable HTML preprocessing globally
|
|
48
|
-
pub enabled: bool,
|
|
49
|
-
|
|
50
|
-
/// Preprocessing preset level (Minimal, Standard, Aggressive)
|
|
51
|
-
pub preset: PreprocessingPreset,
|
|
52
|
-
|
|
53
|
-
/// Remove navigation elements (nav, breadcrumbs, menus, sidebars)
|
|
54
|
-
pub remove_navigation: bool,
|
|
55
|
-
|
|
56
|
-
/// Remove form elements (forms, inputs, buttons, etc.)
|
|
57
|
-
pub remove_forms: bool,
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/// Partial update for `PreprocessingOptions`.
|
|
61
|
-
///
|
|
62
|
-
/// This struct uses `Option<T>` to represent optional fields that can be selectively updated.
|
|
63
|
-
/// Only specified fields (Some values) will override existing options; None values leave the
|
|
64
|
-
/// corresponding fields unchanged when applied via [`PreprocessingOptions::apply_update`].
|
|
65
|
-
#[derive(Debug, Clone, Default)]
|
|
66
|
-
#[cfg_attr(
|
|
67
|
-
any(feature = "serde", feature = "metadata"),
|
|
68
|
-
derive(serde::Serialize, serde::Deserialize)
|
|
69
|
-
)]
|
|
70
|
-
#[cfg_attr(any(feature = "serde", feature = "metadata"), serde(deny_unknown_fields))]
|
|
71
|
-
pub struct PreprocessingOptionsUpdate {
|
|
72
|
-
/// Optional global preprocessing enablement override
|
|
73
|
-
pub enabled: Option<bool>,
|
|
74
|
-
|
|
75
|
-
/// Optional preprocessing preset level override (Minimal, Standard, Aggressive)
|
|
76
|
-
pub preset: Option<PreprocessingPreset>,
|
|
77
|
-
|
|
78
|
-
/// Optional navigation element removal override (nav, breadcrumbs, menus, sidebars)
|
|
79
|
-
pub remove_navigation: Option<bool>,
|
|
80
|
-
|
|
81
|
-
/// Optional form element removal override (forms, inputs, buttons, etc.)
|
|
82
|
-
pub remove_forms: Option<bool>,
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
impl Default for PreprocessingOptions {
|
|
86
|
-
fn default() -> Self {
|
|
87
|
-
Self {
|
|
88
|
-
enabled: true,
|
|
89
|
-
preset: PreprocessingPreset::default(),
|
|
90
|
-
remove_navigation: true,
|
|
91
|
-
remove_forms: true,
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
impl PreprocessingOptions {
|
|
97
|
-
/// Apply a partial update to these preprocessing options.
|
|
98
|
-
///
|
|
99
|
-
/// Any specified fields in the update will override the current values.
|
|
100
|
-
/// Unspecified fields (None) are left unchanged.
|
|
101
|
-
///
|
|
102
|
-
/// # Arguments
|
|
103
|
-
///
|
|
104
|
-
/// * `update` - Partial preprocessing options update
|
|
105
|
-
#[allow(clippy::needless_pass_by_value)]
|
|
106
|
-
pub const fn apply_update(&mut self, update: PreprocessingOptionsUpdate) {
|
|
107
|
-
if let Some(enabled) = update.enabled {
|
|
108
|
-
self.enabled = enabled;
|
|
109
|
-
}
|
|
110
|
-
if let Some(preset) = update.preset {
|
|
111
|
-
self.preset = preset;
|
|
112
|
-
}
|
|
113
|
-
if let Some(remove_navigation) = update.remove_navigation {
|
|
114
|
-
self.remove_navigation = remove_navigation;
|
|
115
|
-
}
|
|
116
|
-
if let Some(remove_forms) = update.remove_forms {
|
|
117
|
-
self.remove_forms = remove_forms;
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
/// Create new preprocessing options from a partial update.
|
|
122
|
-
///
|
|
123
|
-
/// Creates a new `PreprocessingOptions` struct with defaults, then applies the update.
|
|
124
|
-
/// Fields not specified in the update keep their default values.
|
|
125
|
-
///
|
|
126
|
-
/// # Arguments
|
|
127
|
-
///
|
|
128
|
-
/// * `update` - Partial preprocessing options update
|
|
129
|
-
///
|
|
130
|
-
/// # Returns
|
|
131
|
-
///
|
|
132
|
-
/// New `PreprocessingOptions` with specified updates applied to defaults
|
|
133
|
-
#[must_use]
|
|
134
|
-
pub fn from_update(update: PreprocessingOptionsUpdate) -> Self {
|
|
135
|
-
let mut options = Self::default();
|
|
136
|
-
options.apply_update(update);
|
|
137
|
-
options
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
impl From<PreprocessingOptionsUpdate> for PreprocessingOptions {
|
|
142
|
-
fn from(update: PreprocessingOptionsUpdate) -> Self {
|
|
143
|
-
Self::from_update(update)
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
#[cfg(any(feature = "serde", feature = "metadata"))]
|
|
148
|
-
mod serde_impls {
|
|
149
|
-
use super::PreprocessingPreset;
|
|
150
|
-
use serde::{Deserialize, Serializer};
|
|
151
|
-
|
|
152
|
-
impl<'de> Deserialize<'de> for PreprocessingPreset {
|
|
153
|
-
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
|
154
|
-
where
|
|
155
|
-
D: serde::Deserializer<'de>,
|
|
156
|
-
{
|
|
157
|
-
let value = String::deserialize(deserializer)?;
|
|
158
|
-
Ok(Self::parse(&value))
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
impl serde::Serialize for PreprocessingPreset {
|
|
163
|
-
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
|
164
|
-
where
|
|
165
|
-
S: Serializer,
|
|
166
|
-
{
|
|
167
|
-
let s = match self {
|
|
168
|
-
Self::Minimal => "minimal",
|
|
169
|
-
Self::Standard => "standard",
|
|
170
|
-
Self::Aggressive => "aggressive",
|
|
171
|
-
};
|
|
172
|
-
serializer.serialize_str(s)
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
#[cfg(all(test, any(feature = "serde", feature = "metadata")))]
|
|
178
|
-
mod tests {
|
|
179
|
-
use super::*;
|
|
180
|
-
|
|
181
|
-
#[test]
|
|
182
|
-
fn test_preprocessing_options_serde() {
|
|
183
|
-
let options = PreprocessingOptions {
|
|
184
|
-
enabled: true,
|
|
185
|
-
preset: PreprocessingPreset::Aggressive,
|
|
186
|
-
remove_navigation: false,
|
|
187
|
-
..Default::default()
|
|
188
|
-
};
|
|
189
|
-
|
|
190
|
-
// Serialize to JSON
|
|
191
|
-
let json = serde_json::to_string(&options).expect("Failed to serialize");
|
|
192
|
-
|
|
193
|
-
// Deserialize back
|
|
194
|
-
let deserialized: PreprocessingOptions = serde_json::from_str(&json).expect("Failed to deserialize");
|
|
195
|
-
|
|
196
|
-
// Verify values
|
|
197
|
-
assert!(deserialized.enabled);
|
|
198
|
-
assert_eq!(deserialized.preset, PreprocessingPreset::Aggressive);
|
|
199
|
-
assert!(!deserialized.remove_navigation);
|
|
200
|
-
}
|
|
201
|
-
}
|
|
@@ -1,416 +0,0 @@
|
|
|
1
|
-
//! Validation and parsing utilities for option enums.
|
|
2
|
-
//!
|
|
3
|
-
//! This module provides parsing and serialization logic for configuration
|
|
4
|
-
//! enums (HeadingStyle, ListIndentType, etc.) with string conversion support.
|
|
5
|
-
|
|
6
|
-
/// Heading style options for Markdown output.
|
|
7
|
-
///
|
|
8
|
-
/// Controls how headings (h1-h6) are rendered in the output Markdown.
|
|
9
|
-
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
|
|
10
|
-
pub enum HeadingStyle {
|
|
11
|
-
/// Underlined style (=== for h1, --- for h2).
|
|
12
|
-
Underlined,
|
|
13
|
-
/// ATX style (# for h1, ## for h2, etc.). Default.
|
|
14
|
-
#[default]
|
|
15
|
-
Atx,
|
|
16
|
-
/// ATX closed style (# title #, with closing hashes).
|
|
17
|
-
AtxClosed,
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
impl HeadingStyle {
|
|
21
|
-
/// Parse a heading style from a string.
|
|
22
|
-
///
|
|
23
|
-
/// Accepts "atx", "atxclosed", or defaults to Underlined.
|
|
24
|
-
/// Input is normalized (lowercased, alphanumeric only).
|
|
25
|
-
#[must_use]
|
|
26
|
-
pub fn parse(value: &str) -> Self {
|
|
27
|
-
match normalize_token(value).as_str() {
|
|
28
|
-
"atx" => Self::Atx,
|
|
29
|
-
"atxclosed" => Self::AtxClosed,
|
|
30
|
-
_ => Self::Underlined,
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/// List indentation character type.
|
|
36
|
-
///
|
|
37
|
-
/// Controls whether list items are indented with spaces or tabs.
|
|
38
|
-
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
|
|
39
|
-
pub enum ListIndentType {
|
|
40
|
-
/// Use spaces for indentation. Default. Width controlled by `list_indent_width`.
|
|
41
|
-
#[default]
|
|
42
|
-
Spaces,
|
|
43
|
-
/// Use tabs for indentation.
|
|
44
|
-
Tabs,
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
impl ListIndentType {
|
|
48
|
-
/// Parse a list indentation type from a string.
|
|
49
|
-
///
|
|
50
|
-
/// Accepts "tabs" or defaults to Spaces.
|
|
51
|
-
/// Input is normalized (lowercased, alphanumeric only).
|
|
52
|
-
#[must_use]
|
|
53
|
-
pub fn parse(value: &str) -> Self {
|
|
54
|
-
match normalize_token(value).as_str() {
|
|
55
|
-
"tabs" => Self::Tabs,
|
|
56
|
-
_ => Self::Spaces,
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/// Whitespace handling strategy during conversion.
|
|
62
|
-
///
|
|
63
|
-
/// Determines how sequences of whitespace characters (spaces, tabs, newlines) are processed.
|
|
64
|
-
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
|
|
65
|
-
pub enum WhitespaceMode {
|
|
66
|
-
/// Collapse multiple whitespace characters to single spaces. Default. Matches browser behavior.
|
|
67
|
-
#[default]
|
|
68
|
-
Normalized,
|
|
69
|
-
/// Preserve all whitespace exactly as it appears in the HTML.
|
|
70
|
-
Strict,
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
impl WhitespaceMode {
|
|
74
|
-
/// Parse a whitespace mode from a string.
|
|
75
|
-
///
|
|
76
|
-
/// Accepts "strict" or defaults to Normalized.
|
|
77
|
-
/// Input is normalized (lowercased, alphanumeric only).
|
|
78
|
-
#[must_use]
|
|
79
|
-
pub fn parse(value: &str) -> Self {
|
|
80
|
-
match normalize_token(value).as_str() {
|
|
81
|
-
"strict" => Self::Strict,
|
|
82
|
-
_ => Self::Normalized,
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/// Line break syntax in Markdown output.
|
|
88
|
-
///
|
|
89
|
-
/// Controls how soft line breaks (from `<br>` or line breaks in source) are rendered.
|
|
90
|
-
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
|
|
91
|
-
pub enum NewlineStyle {
|
|
92
|
-
/// Two trailing spaces at end of line. Default. Standard Markdown syntax.
|
|
93
|
-
#[default]
|
|
94
|
-
Spaces,
|
|
95
|
-
/// Backslash at end of line. Alternative Markdown syntax.
|
|
96
|
-
Backslash,
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
impl NewlineStyle {
|
|
100
|
-
/// Parse a newline style from a string.
|
|
101
|
-
///
|
|
102
|
-
/// Accepts "backslash" or defaults to Spaces.
|
|
103
|
-
/// Input is normalized (lowercased, alphanumeric only).
|
|
104
|
-
#[must_use]
|
|
105
|
-
pub fn parse(value: &str) -> Self {
|
|
106
|
-
match normalize_token(value).as_str() {
|
|
107
|
-
"backslash" => Self::Backslash,
|
|
108
|
-
_ => Self::Spaces,
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
/// Code block fence style in Markdown output.
|
|
114
|
-
///
|
|
115
|
-
/// Determines how code blocks (`<pre><code>`) are rendered in Markdown.
|
|
116
|
-
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
|
|
117
|
-
pub enum CodeBlockStyle {
|
|
118
|
-
/// Indented code blocks (4 spaces). `CommonMark` standard.
|
|
119
|
-
Indented,
|
|
120
|
-
/// Fenced code blocks with backticks (```). Default (GFM). Supports language hints.
|
|
121
|
-
#[default]
|
|
122
|
-
Backticks,
|
|
123
|
-
/// Fenced code blocks with tildes (~~~). Supports language hints.
|
|
124
|
-
Tildes,
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
impl CodeBlockStyle {
|
|
128
|
-
/// Parse a code block style from a string.
|
|
129
|
-
///
|
|
130
|
-
/// Accepts "backticks", "tildes", or defaults to Indented.
|
|
131
|
-
/// Input is normalized (lowercased, alphanumeric only).
|
|
132
|
-
#[must_use]
|
|
133
|
-
pub fn parse(value: &str) -> Self {
|
|
134
|
-
match normalize_token(value).as_str() {
|
|
135
|
-
"backticks" => Self::Backticks,
|
|
136
|
-
"tildes" => Self::Tildes,
|
|
137
|
-
_ => Self::Indented,
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
/// Highlight rendering style for `<mark>` elements.
|
|
143
|
-
///
|
|
144
|
-
/// Controls how highlighted text is rendered in Markdown output.
|
|
145
|
-
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
|
|
146
|
-
pub enum HighlightStyle {
|
|
147
|
-
/// Double equals syntax (==text==). Default. Pandoc-compatible.
|
|
148
|
-
#[default]
|
|
149
|
-
DoubleEqual,
|
|
150
|
-
/// Preserve as HTML (==text==). Original HTML tag.
|
|
151
|
-
Html,
|
|
152
|
-
/// Render as bold (**text**). Uses strong emphasis.
|
|
153
|
-
Bold,
|
|
154
|
-
/// Strip formatting, render as plain text. No markup.
|
|
155
|
-
None,
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
impl HighlightStyle {
|
|
159
|
-
/// Parse a highlight style from a string.
|
|
160
|
-
///
|
|
161
|
-
/// Accepts "doubleequal", "html", "bold", "none", or defaults to None.
|
|
162
|
-
/// Input is normalized (lowercased, alphanumeric only).
|
|
163
|
-
#[must_use]
|
|
164
|
-
pub fn parse(value: &str) -> Self {
|
|
165
|
-
match normalize_token(value).as_str() {
|
|
166
|
-
"doubleequal" => Self::DoubleEqual,
|
|
167
|
-
"html" => Self::Html,
|
|
168
|
-
"bold" => Self::Bold,
|
|
169
|
-
"none" => Self::None,
|
|
170
|
-
_ => Self::None,
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
/// Link rendering style in Markdown output.
|
|
176
|
-
///
|
|
177
|
-
/// Controls whether links and images use inline `[text](url)` syntax or
|
|
178
|
-
/// reference-style `[text][1]` syntax with definitions collected at the end.
|
|
179
|
-
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
|
|
180
|
-
pub enum LinkStyle {
|
|
181
|
-
/// Inline links: `[text](url)`. Default.
|
|
182
|
-
#[default]
|
|
183
|
-
Inline,
|
|
184
|
-
/// Reference-style links: `[text][1]` with `[1]: url` at end of document.
|
|
185
|
-
Reference,
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
impl LinkStyle {
|
|
189
|
-
/// Parse a link style from a string.
|
|
190
|
-
///
|
|
191
|
-
/// Accepts "reference" or defaults to Inline.
|
|
192
|
-
/// Input is normalized (lowercased, alphanumeric only).
|
|
193
|
-
#[must_use]
|
|
194
|
-
pub fn parse(value: &str) -> Self {
|
|
195
|
-
match normalize_token(value).as_str() {
|
|
196
|
-
"reference" => Self::Reference,
|
|
197
|
-
_ => Self::Inline,
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
/// Output format for conversion.
|
|
203
|
-
///
|
|
204
|
-
/// Specifies the target markup language format for the conversion output.
|
|
205
|
-
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
|
|
206
|
-
pub enum OutputFormat {
|
|
207
|
-
/// Standard Markdown (CommonMark compatible). Default.
|
|
208
|
-
#[default]
|
|
209
|
-
Markdown,
|
|
210
|
-
/// Djot lightweight markup language.
|
|
211
|
-
Djot,
|
|
212
|
-
/// Plain text output (no markup, visible text only).
|
|
213
|
-
Plain,
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
impl OutputFormat {
|
|
217
|
-
/// Parse an output format from a string.
|
|
218
|
-
///
|
|
219
|
-
/// Accepts "djot" or defaults to Markdown.
|
|
220
|
-
/// Input is normalized (lowercased, alphanumeric only).
|
|
221
|
-
#[must_use]
|
|
222
|
-
pub fn parse(value: &str) -> Self {
|
|
223
|
-
match normalize_token(value).as_str() {
|
|
224
|
-
"djot" => Self::Djot,
|
|
225
|
-
"plain" | "plaintext" | "text" => Self::Plain,
|
|
226
|
-
_ => Self::Markdown,
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
/// Normalize a configuration string by lowercasing and removing non-alphanumeric characters.
|
|
232
|
-
pub(crate) fn normalize_token(value: &str) -> String {
|
|
233
|
-
let mut out = String::with_capacity(value.len());
|
|
234
|
-
for ch in value.chars() {
|
|
235
|
-
if ch.is_ascii_alphanumeric() {
|
|
236
|
-
out.push(ch.to_ascii_lowercase());
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
out
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
#[cfg(any(feature = "serde", feature = "metadata"))]
|
|
243
|
-
mod serde_impls {
|
|
244
|
-
use super::{
|
|
245
|
-
CodeBlockStyle, HeadingStyle, HighlightStyle, LinkStyle, ListIndentType, NewlineStyle, OutputFormat,
|
|
246
|
-
WhitespaceMode,
|
|
247
|
-
};
|
|
248
|
-
use serde::{Deserialize, Serialize, Serializer};
|
|
249
|
-
|
|
250
|
-
macro_rules! impl_deserialize_from_parse {
|
|
251
|
-
($ty:ty, $parser:expr) => {
|
|
252
|
-
impl<'de> Deserialize<'de> for $ty {
|
|
253
|
-
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
|
254
|
-
where
|
|
255
|
-
D: serde::Deserializer<'de>,
|
|
256
|
-
{
|
|
257
|
-
let value = String::deserialize(deserializer)?;
|
|
258
|
-
Ok($parser(&value))
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
};
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
impl_deserialize_from_parse!(HeadingStyle, HeadingStyle::parse);
|
|
265
|
-
impl_deserialize_from_parse!(ListIndentType, ListIndentType::parse);
|
|
266
|
-
impl_deserialize_from_parse!(WhitespaceMode, WhitespaceMode::parse);
|
|
267
|
-
impl_deserialize_from_parse!(NewlineStyle, NewlineStyle::parse);
|
|
268
|
-
impl_deserialize_from_parse!(CodeBlockStyle, CodeBlockStyle::parse);
|
|
269
|
-
impl_deserialize_from_parse!(HighlightStyle, HighlightStyle::parse);
|
|
270
|
-
impl_deserialize_from_parse!(LinkStyle, LinkStyle::parse);
|
|
271
|
-
impl_deserialize_from_parse!(OutputFormat, OutputFormat::parse);
|
|
272
|
-
|
|
273
|
-
// Serialize implementations that convert enum variants to their string representations
|
|
274
|
-
impl Serialize for HeadingStyle {
|
|
275
|
-
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
|
276
|
-
where
|
|
277
|
-
S: Serializer,
|
|
278
|
-
{
|
|
279
|
-
let s = match self {
|
|
280
|
-
Self::Underlined => "underlined",
|
|
281
|
-
Self::Atx => "atx",
|
|
282
|
-
Self::AtxClosed => "atxclosed",
|
|
283
|
-
};
|
|
284
|
-
serializer.serialize_str(s)
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
impl Serialize for ListIndentType {
|
|
289
|
-
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
|
290
|
-
where
|
|
291
|
-
S: Serializer,
|
|
292
|
-
{
|
|
293
|
-
let s = match self {
|
|
294
|
-
Self::Spaces => "spaces",
|
|
295
|
-
Self::Tabs => "tabs",
|
|
296
|
-
};
|
|
297
|
-
serializer.serialize_str(s)
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
impl Serialize for WhitespaceMode {
|
|
302
|
-
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
|
303
|
-
where
|
|
304
|
-
S: Serializer,
|
|
305
|
-
{
|
|
306
|
-
let s = match self {
|
|
307
|
-
Self::Normalized => "normalized",
|
|
308
|
-
Self::Strict => "strict",
|
|
309
|
-
};
|
|
310
|
-
serializer.serialize_str(s)
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
impl Serialize for NewlineStyle {
|
|
315
|
-
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
|
316
|
-
where
|
|
317
|
-
S: Serializer,
|
|
318
|
-
{
|
|
319
|
-
let s = match self {
|
|
320
|
-
Self::Spaces => "spaces",
|
|
321
|
-
Self::Backslash => "backslash",
|
|
322
|
-
};
|
|
323
|
-
serializer.serialize_str(s)
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
impl Serialize for CodeBlockStyle {
|
|
328
|
-
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
|
329
|
-
where
|
|
330
|
-
S: Serializer,
|
|
331
|
-
{
|
|
332
|
-
let s = match self {
|
|
333
|
-
Self::Indented => "indented",
|
|
334
|
-
Self::Backticks => "backticks",
|
|
335
|
-
Self::Tildes => "tildes",
|
|
336
|
-
};
|
|
337
|
-
serializer.serialize_str(s)
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
impl Serialize for HighlightStyle {
|
|
342
|
-
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
|
343
|
-
where
|
|
344
|
-
S: Serializer,
|
|
345
|
-
{
|
|
346
|
-
let s = match self {
|
|
347
|
-
Self::DoubleEqual => "doubleequal",
|
|
348
|
-
Self::Html => "html",
|
|
349
|
-
Self::Bold => "bold",
|
|
350
|
-
Self::None => "none",
|
|
351
|
-
};
|
|
352
|
-
serializer.serialize_str(s)
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
impl Serialize for LinkStyle {
|
|
357
|
-
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
|
358
|
-
where
|
|
359
|
-
S: Serializer,
|
|
360
|
-
{
|
|
361
|
-
let s = match self {
|
|
362
|
-
Self::Inline => "inline",
|
|
363
|
-
Self::Reference => "reference",
|
|
364
|
-
};
|
|
365
|
-
serializer.serialize_str(s)
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
impl Serialize for OutputFormat {
|
|
370
|
-
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
|
371
|
-
where
|
|
372
|
-
S: Serializer,
|
|
373
|
-
{
|
|
374
|
-
let s = match self {
|
|
375
|
-
Self::Markdown => "markdown",
|
|
376
|
-
Self::Djot => "djot",
|
|
377
|
-
Self::Plain => "plain",
|
|
378
|
-
};
|
|
379
|
-
serializer.serialize_str(s)
|
|
380
|
-
}
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
#[cfg(all(test, any(feature = "serde", feature = "metadata")))]
|
|
385
|
-
mod tests {
|
|
386
|
-
use super::*;
|
|
387
|
-
|
|
388
|
-
#[test]
|
|
389
|
-
fn test_enum_serialization() {
|
|
390
|
-
// Test that enums serialize to lowercase strings
|
|
391
|
-
let heading = HeadingStyle::AtxClosed;
|
|
392
|
-
let json = serde_json::to_string(&heading).expect("Failed to serialize");
|
|
393
|
-
assert_eq!(json, r#""atxclosed""#);
|
|
394
|
-
|
|
395
|
-
let list_indent = ListIndentType::Tabs;
|
|
396
|
-
let json = serde_json::to_string(&list_indent).expect("Failed to serialize");
|
|
397
|
-
assert_eq!(json, r#""tabs""#);
|
|
398
|
-
|
|
399
|
-
let whitespace = WhitespaceMode::Strict;
|
|
400
|
-
let json = serde_json::to_string(&whitespace).expect("Failed to serialize");
|
|
401
|
-
assert_eq!(json, r#""strict""#);
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
#[test]
|
|
405
|
-
fn test_enum_deserialization() {
|
|
406
|
-
// Test that enums deserialize from strings (case insensitive)
|
|
407
|
-
let heading: HeadingStyle = serde_json::from_str(r#""atxclosed""#).expect("Failed");
|
|
408
|
-
assert_eq!(heading, HeadingStyle::AtxClosed);
|
|
409
|
-
|
|
410
|
-
let heading: HeadingStyle = serde_json::from_str(r#""ATXCLOSED""#).expect("Failed");
|
|
411
|
-
assert_eq!(heading, HeadingStyle::AtxClosed);
|
|
412
|
-
|
|
413
|
-
let list_indent: ListIndentType = serde_json::from_str(r#""tabs""#).expect("Failed");
|
|
414
|
-
assert_eq!(list_indent, ListIndentType::Tabs);
|
|
415
|
-
}
|
|
416
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
//! Prelude module for convenient internal imports.
|