Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Usage — Rust

Basic Conversion

use mdka::html_to_markdown;

fn main() {
    let html = r#"
        <h1>Getting Started</h1>
        <p>mdka converts <strong>HTML</strong> to <em>Markdown</em>.</p>
        <ul>
            <li>Fast</li>
            <li>Configurable</li>
            <li>Crash-resistant</li>
        </ul>
    "#;

    let md = html_to_markdown(html);
    println!("{md}");
}

Output:

# Getting Started

mdka converts **HTML** to *Markdown*.

- Fast
- Configurable
- Crash-resistant

Conversion with Options

Use html_to_markdown_with to control the conversion pipeline via ConversionOptions.

use mdka::{html_to_markdown_with};
use mdka::options::{ConversionMode, ConversionOptions};

// Strip navigation and extract body text — good for LLM input
let mut opts = ConversionOptions::for_mode(ConversionMode::Minimal);
opts.drop_interactive_shell = true;

let html = r#"
    <header><nav><a href="/">Home</a></nav></header>
    <main>
        <article>
            <h1>Article Title</h1>
            <p>The main content of the page.</p>
        </article>
    </main>
    <footer>Copyright 2025</footer>
"#;

let md = html_to_markdown_with(html, &opts);
assert!(md.contains("# Article Title"));
assert!(!md.contains("Home"));       // nav removed
assert!(!md.contains("Copyright"));  // footer removed

Converting Multiple Strings

use mdka::{html_to_markdown_many, html_to_markdown_many_with};
use mdka::options::{ConversionMode, ConversionOptions};

let pages = vec!["<h1>A</h1>", "<p>B</p>", "<ul><li>C</li></ul>"];
let results = html_to_markdown_many(&pages);
assert_eq!(results, vec!["# A\n", "B\n", "- C\n"]);

let opts = ConversionOptions::for_mode(ConversionMode::Minimal);
let results = html_to_markdown_many_with(&pages, &opts);

Each input is converted independently and the results keep the input order. When the parallel feature is on (the default), the conversions run across CPU cores via rayon; with the feature off, the same functions run sequentially instead.

Converting a Single File

use mdka::html_file_to_markdown;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Output goes to the same directory as the input: page.html → page.md
    let dest = html_file_to_markdown("page.html", None::<&str>)?;
    println!("page.html → {}", dest.display());

    // Output goes to a specific directory
    let dest = html_file_to_markdown("page.html", Some("out/"))?;
    Ok(())
}

Bulk Parallel Conversion

use mdka::html_files_to_markdown;
use std::path::Path;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let files = vec!["a.html", "b.html", "c.html"];
    let out_dir = Path::new("out/");
    std::fs::create_dir_all(out_dir)?;

    // One `FileOutcome` per input, in input order: a failing file does not stop
    // the others, and the outcome names the file it belongs to.
    for outcome in html_files_to_markdown(&files, out_dir) {
        let src = outcome.src.display();
        match outcome.result {
            Ok(dest) => println!("{src} → {}", dest.display()),
            Err(e)   => eprintln!("Error: {src}: {e}"),
        }
    }
    Ok(())
}

A single file returns the destination path or an error; only the bulk function reports per file, because one failure must not hide the rest.

Conversion runs in parallel using rayon. The number of threads defaults to the number of logical CPU cores.

Bulk Conversion with Options

use mdka::{html_files_to_markdown_with};
use mdka::options::{ConversionMode, ConversionOptions};
use std::path::Path;

let opts = ConversionOptions::for_mode(ConversionMode::Minimal);
let files = vec!["a.html", "b.html"];
let results = html_files_to_markdown_with(&files, Path::new("out/"), &opts);

Conversion Modes at a Glance

ModeBest for
BalancedGeneral use; default
MinimalLLM pre-processing, compression — the only mode that converts differently

There were five modes until 3.0. Strict, Semantic and Preserve were aliases of Balanced that produced identical output and could not differ; they were removed, and "strict".parse::<ConversionMode>() now returns an error that says so. See Conversion Modes for why.

Error Handling

use mdka::{html_file_to_markdown, MdkaError};

match html_file_to_markdown("missing.html", None::<&str>) {
    Ok(dest) => println!("→ {}", dest.display()),
    Err(MdkaError::Io(e)) => eprintln!("IO error: {e}"),
}

MdkaError currently has one variant: Io, wrapping std::io::Error. html_to_markdown and html_to_markdown_with are infallible — they always return a String and never panic on any input, no matter how malformed.

Crate Version

println!("{}", mdka::version()); // the installed version, e.g. "3.0.0"

Returns the crate’s version as declared in Cargo.toml.