#![allow(clippy::too_many_arguments)]
#![allow(clippy::too_many_lines)]
#![allow(clippy::trivially_copy_pass_by_ref)]
#![allow(clippy::struct_excessive_bools, clippy::fn_params_excessive_bools)]
#![allow(clippy::cast_possible_truncation)]
#![allow(clippy::cast_precision_loss, clippy::cast_sign_loss)]
#![allow(clippy::unused_self)]
#![allow(clippy::collapsible_if, clippy::collapsible_else_if, clippy::collapsible_match)]
#![allow(
clippy::map_unwrap_or,
clippy::manual_let_else,
clippy::option_if_let_else,
clippy::match_same_arms,
clippy::branches_sharing_code,
clippy::items_after_statements,
clippy::match_wildcard_for_single_variants,
clippy::needless_pass_by_value
)]
#![allow(clippy::doc_markdown, clippy::missing_errors_doc)]
#![allow(clippy::default_trait_access)]
pub mod error;
#[cfg(feature = "metadata")]
pub mod metadata;
pub mod options;
pub mod types;
#[cfg(feature = "visitor")]
pub mod visitor;
mod convert_api;
#[allow(dead_code)]
pub(crate) mod converter;
mod exports;
#[cfg(any(test, feature = "testkit"))]
#[allow(unused_imports)]
pub mod testkit {
pub use crate::converter::prescan;
pub use crate::converter::tier1;
}
#[cfg(any(test, feature = "testkit"))]
pub use converter::prescan;
#[cfg(any(test, feature = "testkit"))]
pub use converter::tier1;
#[cfg(feature = "inline-images")]
mod inline_images;
pub(crate) mod prelude;
mod rcdom;
pub(crate) mod text;
mod validation;
#[cfg(feature = "visitor")]
#[allow(clippy::ref_option)]
pub(crate) mod visitor_helpers;
pub(crate) mod wrapper;
pub use exports::*;
pub use types::{
AnnotationKind, ConversionResult, DocumentNode, DocumentStructure, GridCell, ImageDimensions, MetadataEntry,
NodeContent, ProcessingWarning, TableData, TableGrid, TextAnnotation, WarningKind,
};
#[cfg(feature = "visitor")]
pub use visitor::{NodeContext, NodeType, VisitResult, VisitorHandle};
pub use convert_api::convert;
#[cfg(test)]
mod basic_tests {
use super::*;
#[test]
fn test_binary_input_rejected() {
let html = format!("abc{}def", "\0".repeat(20));
let result = convert(&html, None);
assert!(matches!(result, Err(ConversionError::InvalidInput(_))));
}
#[test]
fn test_binary_magic_rejected() {
let html = "%PDF-1.7";
let result = convert(html, None);
assert!(matches!(result, Err(ConversionError::InvalidInput(_))));
}
#[test]
fn test_utf16_hint_recovered() {
let html = String::from_utf8_lossy(b"\xFF\xFE<\0h\0t\0m\0l\0>\0").to_string();
let result = convert(&html, None);
assert!(result.is_ok(), "UTF-16 input should be recovered instead of rejected");
}
#[test]
fn test_plain_text_allowed() {
let result = convert("Just text", None).unwrap();
let content = result.content.unwrap_or_default();
assert!(content.contains("Just text"));
}
#[test]
fn test_plain_text_escaped_when_enabled() {
let options = ConversionOptions {
escape_asterisks: true,
escape_underscores: true,
..ConversionOptions::default()
};
let result = convert("Text *asterisks* _underscores_", Some(options)).unwrap();
let content = result.content.unwrap_or_default();
assert!(content.contains(r"\*asterisks\*"));
assert!(content.contains(r"\_underscores\_"));
}
}