Open source · MIT · Python 3.11+

Vietnamese documents, finally readable by your RAG stack.

viparse turns legacy Vietnamese files — TCVN3/VNI/VISCII fonts, scanned PDFs, old .doc/.xls — into clean Unicode NFC Markdown or JSON. One function call, ready for your vector DB.

Star on GitHub →
Inputwhat generic loaders give you
B¸o c¸o tµi chÝnh quý II n¨m 2026 cña c«ng ty.
ThÞ tr­êng ViÖt Nam ph¸t triÓn m¹nh.
viparse.load()
OutputUnicode NFC
Báo cáo tài chính quý II năm 2026 của công ty.
Thị trường Việt Nam phát triển mạnh.
The problem

Your parser reads the file. It doesn't read Vietnamese.

Millions of Vietnamese documents were authored in pre-Unicode fonts — .VnTime, VNI, VISCII. Generic loaders like Unstructured or LlamaParse extract the bytes faithfully and hand your pipeline garbage: "Tiªu ®Ò" instead of "Tiêu đề". Embeddings built on garbled text retrieve nothing. viparse handles exactly that layer: detect the legacy encoding, convert to Unicode, enforce NFC — then get out of your way.

How it works

Three steps, one call.

01

Detect

Font signals and syllable-frequency scoring identify TCVN3, VNI, VISCII or VPS — per run, not per file, so mixed documents convert cleanly.

02

Convert

Legacy sequences are mapped to correct Vietnamese letters and normalized to NFC. Already-Unicode text is never touched.

03

Load

Get Markdown, text or JSON with headings, tables and provenance — chunked for retrieval, with LangChain and LlamaIndex adapters built in.

Features

Built for pipelines, not demos.

Legacy encodings

TCVN3 · VNI · VISCII · VPS → Unicode NFC, round-trip tested.

Every format

DOCX, XLSX, PDF, scanned PDF (OCR), RTF, legacy .doc/.xls.

RAG-native chunking

Section-aware chunks that never split a table row.

Zero-dep core

Pure stdlib; heavy engines live behind extras like viparse[ocr].

Safe on untrusted files

Size limits, zip-bomb guard, per-engine timeouts.

CLI included

viparse ./docs/**/*.pdf -o md, plus viparse doctor.

Quickstart

Two lines to clean text.

quickstart.py
import viparse

docs = viparse.load("bao_cao_cu.doc")          # list[Document], already NFC
docs = viparse.load("scan.pdf", ocr=True, output="markdown")
PlaygroundComing soon

Try it in your browser.

Paste garbled Vietnamese text, get clean Unicode back — runs entirely client-side via Pyodide. No upload, no server.

Wiring up the Pyodide build — ships with v0.2.
BenchmarkComing soon

Measured on real broken files.

A public corpus of real-world legacy documents, scored on diacritic accuracy against Unstructured, LlamaParse and docling. Numbers coming with v0.2.

ToolDiacritic accuracyFormatsSpeed
viparse
unstructured
llamaparse
docling
FAQ

Questions.

MIT-licensed, free forever as a library. A hosted API for teams is planned.