Skip to main content

HandleMyFile

Crates.io PyPI NPM License: MIT

High-precision, edge-native PDF to DOCX converter engine in Pure Rust, WebAssembly, and Python.

Rust Guide • Python Guide • WebAssembly / JS • Known Limitations • Architecture


Overview

HandleMyFile is an edge-native, zero-egress document conversion engine. It converts raw Portable Document Format (PDF) files into cleanly structured, editable Microsoft Word (.docx) files using deep Document Layout Analysis (DLA).

Key Features

  • 100% Client-Side & Zero-Egress: Runs completely in-memory in pure Rust, WebAssembly (in-browser or Node.js), or Python without sending private documents to any remote cloud API.
  • Advanced Document Layout Analysis (DLA): Recursive spatial analysis (R-XY-Cut) coupled with 2D R*-Tree spatial indexing.
  • Planar Graph Table Reconstruction: Detects contiguous ruling lines, intersections, and cells to rebuild true native OOXML <w:tbl> tables with dynamic cell margins and border styling.
  • Clean Document Flow: Automatically detects chapter headings, hierarchical sub-sections, cover pages, and front matter without spurious page breaks.
  • Dynamic Header & Footer Detection: Extracts headers, footers, and page numbers into native Word field codes (<w:fldSimple w:instr="PAGE"/>).

Known Limitations (Kekurangan Saat Ini)


1. Rust (Crates.io)

Installation

Add handlemyfile to your Cargo.toml:

[dependencies]
handlemyfile = "0.1.0"

Usage

use handlemyfile::ConverterEngine;
use std::fs;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Read PDF file
    let pdf_bytes = fs::read("document.pdf")?;

    // Initialize converter engine
    let engine = ConverterEngine::new();

    // Convert to DOCX bytes
    let docx_bytes = engine.convert(&pdf_bytes)?;

    // Save to disk
    fs::write("output.docx", docx_bytes)?;
    println!("Conversion successful!");

    Ok(())
}

Rust CLI

You can install the CLI directly with Cargo:

cargo install handlemyfile
handlemyfile input.pdf output.docx

2. Python (PyPI)

Installation

Install via pip:

pip install handlemyfile

Usage

import handlemyfile

# Option 1: File-to-file conversion (with optional progress callback)
def on_progress(current, total, stage):
    print(f"Page {current}/{total} [{stage}]")

handlemyfile.convert_file("input.pdf", "output.docx", on_progress=on_progress)

# Option 2: In-memory byte conversion with typed errors
with open("document.pdf", "rb") as f:
    pdf_bytes = f.read()

try:
    docx_bytes = handlemyfile.convert(pdf_bytes)
    with open("converted.docx", "wb") as f:
        f.write(docx_bytes)
except handlemyfile.PasswordProtectedError:
    print("This PDF requires a password to open!")
except handlemyfile.InvalidPdfError:
    print("Invalid PDF file header.")

Python CLI

Installing via pip also provides a standalone CLI command:

handlemyfile input.pdf output.docx

3. JavaScript / TypeScript (NPM & WebAssembly)

The package compiles to WebAssembly with zero external dependencies, making it ideal for browser client-side execution or Node.js services.

Installation

npm install handlemyfile

1-Line Universal Usage (Browser, Vite, Next.js, Node.js)

handlemyfile v0.2.0 introduces zero-config auto-initialization. You don't need to manually configure wasm asset URLs or call init():

import { convert } from 'handlemyfile';

// Auto-initializes WASM seamlessly in Browser or Node.js!
const docxBytes = await convert(pdfBytes);

Real-Time Progress Callback

For rich interactive progress bars (0% - 100%):

import { convert } from 'handlemyfile';

const docxBytes = await convert(pdfBytes, {
  onProgress: ({ current, total, stage }) => {
    console.log(`Page ${current}/${total} [${stage}]`);
  }
});

Non-Blocking Web Worker (Silky 60fps UI)

To convert large (100+ page) PDFs without freezing the browser's main thread:

import { convert } from 'handlemyfile';

// Automatically offloads computation to a background Web Worker!
const docxBytes = await convert(pdfBytes, {
  worker: true,
  onProgress: ({ current, total }) => {
    updateProgressBar(current / total);
  }
});

Granular Error Handling

import { convert, HandleMyFileError } from 'handlemyfile';

try {
  const docxBytes = await convert(pdfBytes);
} catch (err) {
  if (err instanceof HandleMyFileError) {
    switch (err.code) {
      case 'ERR_PASSWORD_PROTECTED':
        alert('This PDF is password-protected.');
        break;
      case 'ERR_INVALID_HEADER':
        alert('Invalid PDF format.');
        break;
      case 'ERR_CORRUPT_PDF':
        alert('The PDF file is corrupted.');
        break;
      default:
        console.error('Conversion failed:', err.message);
    }
  }
}

Architecture

HandleMyFile is built with a multi-stage Document Layout Analysis pipeline:

[Raw PDF Bytes]
       │
       ▼
 [PDF Object & Stream Parser (lopdf / Flate2)]
       │
       ▼
 [Text, Glyphs & Vector Graphic Extraction]
       │
       ▼
 [2D R*-Tree Spatial Indexing & Graph Intersections]
       │
  ┌────┴───────────────────────────┐
  │                                │
  ▼                                ▼
[Planar Graph Table Detector]    [Recursive R-XY-Cut & Classifier]
  │                                │
  └────┬───────────────────────────┘
       │
       ▼
 [OOXML Builder & Package Generator]
       │
       ▼
 [Final .docx ZIP Container]
  1. Stream Decompression: Parses PDF streams, xref tables, font dictionaries (ToUnicode CMaps, TrueType/Type0), and graphic states.
  2. Document Layout Analysis (DLA): Analyzes spatial bounding boxes, baseline alignments, and gap thresholds to cluster text lines into coherent paragraphs and headings.
  3. Table Structure Recognition (TSR): Extracts planar path segments, computes intersection points, and infers tabular grid geometry.
  4. OOXML Generation: Directly writes validated Office Open XML schemas (word/document.xml, styles.xml, numbering.xml, headers/footers) packaged into a standard ZIP archive.

Development & Building

Prerequisites

Build Commands

# 1. Build Rust Native CLI & Library
cargo build --release

# 2. Build WebAssembly (Web target)
wasm-pack build --target web --out-name handlemyfile

# 3. Build Python Wheels locally
maturin build --features python

License

This project is licensed under the MIT License.

Metadata

Release files for handlemyfile 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for handlemyfile 0.2.0
File Size Uploaded Provenance Actions
handlemyfile-0.2.0.tar.gz 180.1 kB Without provenance Details for handlemyfile-0.2.0.tar.gz

Release files / handlemyfile-0.2.0.tar.gz

Download URL handlemyfile-0.2.0.tar.gz
Size 180.1 kB
Tags Source
SHA-256 checksum
How to use checksums
10e3e7a39fddfa39dec016027974a1f03abc56117ae2b8b8514fc3cddd5164da
BLAKE2b-256 checksum
How to use checksums
3f9acf4a764976902bfd80f34bb2c8b655274f437ebea32976eb23eaeac00e54
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.2

Security for handlemyfile 0.2.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page