pub mod core;
pub mod extensions;
pub mod process;
pub mod types;
pub use core::{ProcessorFeature, collect_markdown_files, extract_inline_text};
#[cfg(feature = "gfm")]
pub use extensions::apply_gfm_extensions;
#[cfg(feature = "nixpkgs")]
pub use extensions::process_manpage_references;
pub use extensions::process_myst_autolinks;
#[cfg(feature = "ndg-flavored")]
pub use extensions::process_option_references;
#[cfg(any(feature = "nixpkgs", feature = "ndg-flavored"))]
pub use extensions::process_role_markup;
#[cfg(feature = "nixpkgs")]
pub use extensions::{
process_block_elements,
process_file_includes,
process_inline_anchors,
};
pub use process::{
ProcessorPreset,
create_processor,
process_batch,
process_markdown_file,
process_markdown_file_with_basedir,
process_markdown_string,
process_safe,
process_with_recovery,
};
pub use types::{
AstTransformer,
MarkdownOptions,
MarkdownOptionsBuilder,
MarkdownProcessor,
PromptTransformer,
};
#[cfg(test)]
mod tests {
use html_escape;
use super::{MarkdownOptions, MarkdownProcessor, types::TabStyle};
#[test]
fn test_html_escaped_roles() {
#[cfg(any(feature = "nixpkgs", feature = "ndg-flavored"))]
{
let result = super::extensions::format_role_markup(
"option",
"hjem.users.<name>.enable",
None,
true,
None,
);
assert!(result.contains("<name>"));
assert!(!result.contains("<code>hjem.users.<name>.enable</code>"));
assert!(result.contains(
"<code class=\"nixos-option\">hjem.users.<name>.enable</code>"
));
assert!(result.contains("option-hjem-users-<name>-enable"));
}
}
#[test]
fn test_html_escape_util() {
let input = "test<>&\"'";
let escaped = html_escape::encode_text(input);
assert_eq!(escaped, "test<>&\"'");
}
#[test]
fn test_various_role_types_with_html_characters() {
#[cfg(any(feature = "nixpkgs", feature = "ndg-flavored"))]
{
let content = "<script>alert('xss')</script>";
let command_result = super::extensions::format_role_markup(
"command", content, None, true, None,
);
assert!(command_result.contains("<script>"));
assert!(!command_result.contains("<script>alert"));
let env_result =
super::extensions::format_role_markup("env", content, None, true, None);
assert!(env_result.contains("<script>"));
assert!(!env_result.contains("<script>alert"));
let file_result = super::extensions::format_role_markup(
"file", content, None, true, None,
);
assert!(file_result.contains("<script>"));
assert!(!file_result.contains("<script>alert"));
}
}
#[test]
fn test_option_role_escaping() {
#[cfg(any(feature = "nixpkgs", feature = "ndg-flavored"))]
{
let result = super::extensions::format_role_markup(
"option",
"hjem.users.<name>.enable",
None,
true,
None,
);
assert!(!result.contains("</name>"));
assert!(result.contains("<name>"));
assert!(result.contains(
"<code class=\"nixos-option\">hjem.users.<name>.enable</code>"
));
assert!(result.contains("options.html#option-hjem-users-<name>-enable"));
}
}
#[test]
fn test_option_role_special_chars_preserved() {
#[cfg(any(feature = "nixpkgs", feature = "ndg-flavored"))]
{
let result = super::extensions::format_role_markup(
"option",
"services.foo.<bar>.enable",
None,
true,
None,
);
assert!(result.contains("option-services-foo-<bar>-enable"));
assert!(result.contains("<bar>"));
}
}
#[test]
fn test_hardtab_handling_none() {
let options = MarkdownOptions {
tab_style: TabStyle::None,
highlight_code: false,
..Default::default()
};
let processor = MarkdownProcessor::new(options);
let markdown = r#"
# Test Code
```rust
fn main() {
println!("Hello, world!");
}
```
"#;
let result = processor.render(markdown);
assert!(result.html.contains("\tprintln"));
}
#[test]
fn test_hardtab_handling_warn() {
let options = MarkdownOptions {
tab_style: TabStyle::Warn,
highlight_code: false,
..Default::default()
};
let processor = MarkdownProcessor::new(options);
let markdown = r#"
# Test Code
```rust
fn main() {
println!("Hello, world!");
}
```
"#;
let result = processor.render(markdown);
assert!(result.html.contains("\tprintln"));
}
#[test]
fn test_hardtab_handling_normalize() {
let options = MarkdownOptions {
tab_style: TabStyle::Normalize,
highlight_code: false,
..Default::default()
};
let processor = MarkdownProcessor::new(options);
let markdown = r#"
# Test Code
```rust
fn main() {
println!("Hello, world!");
}
```
"#;
let result = processor.render(markdown);
assert!(!result.html.contains("\tprintln"));
assert!(result.html.contains(" println"));
}
#[test]
fn test_hardtab_handling_no_tabs() {
let options = MarkdownOptions {
tab_style: TabStyle::Warn,
highlight_code: false,
..Default::default()
};
let processor = MarkdownProcessor::new(options);
let markdown = r#"
# Test Code
```rust
fn main() {
println!("Hello, world!");
}
```
"#;
let result = processor.render(markdown);
assert!(result.html.contains(" println"));
assert!(!result.html.contains("\t"));
}
#[test]
fn test_hardtab_handling_mixed_content() {
let options = MarkdownOptions {
tab_style: TabStyle::Normalize,
highlight_code: false,
..Default::default()
};
let processor = MarkdownProcessor::new(options);
let markdown = r#"
# Test Code
```rust
fn main() {
println!("Hello"); // tab here
println!("World"); // spaces here
}
```
"#;
let result = processor.render(markdown);
assert!(!result.html.contains("\tprintln"));
assert!(result.html.contains(" println"));
assert!(result.html.contains(" println"));
}
}