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, RTF, legacy .doc/.xls/.ppt — plus scans and page images via OCR.

RAG-native chunking

Section-aware chunks that never split a table row, and repeat its header.

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")
Playground

Try it in your browser.

Paste garbled Vietnamese text, get clean Unicode back. It runs in the page — nothing is uploaded, and it works offline once loaded.

Try
Paste something, or pick a sample.

The conversion tables and the detection thresholds here are generated from viparse 0.1.28 itself, so they cannot drift from the library. What runs in the page is the text path only — the .doc, PDF and spreadsheet engines need a file and are most of what `pip install viparse` gives you.

Benchmark

Measured on real broken files.

96 Vietnamese government documents from 2002–2009 — Word, Excel, RTF, PDF and PowerPoint — transcribed by hand and scored on diacritic accuracy. The corpus, the metric, the raw results and the command that regenerates them are public.

ReadingCharacterDiacriticSyllable
No conversionbytes extracted faithfully0.7870.0190.225
viparse 0.1.2796 documents, end-to-end0.9820.9860.985

The 0.019 row is the honest headline: text that looks 79% intact carries 1.9% of the Vietnamese. viparse's own row is a weaker claim than it looks — the transcripts and the conversion tables were derived from the same corpus, so it measures self-consistency as much as correctness. Both numbers, the method, every document and the command that regenerates them are published so the second one can be argued with.

And on ordinary Unicode documents

DocumentOrderCompletenessHeadings
DOCX · XLSX · PPTX1.0001.0001.000
PDF, one column1.0001.0000.000
PDF, two columns0.6001.0000.000

Nothing is ever lost — completeness is 1.000 everywhere. Both failures are failures of arrangement, which is the harder kind to notice. A PDF has no headings, so every chunk from one carries an empty section; and a multi-column PDF is read across the page rather than down the columns. Recovering columns means layout analysis, which viparse does not do: use a layout-aware loader for those and pass its output through viparse.fix().

FAQ

Questions.

0.982 diacritic accuracy over 96 Vietnamese government documents from 2002-2009 — Word, Excel, RTF, PDF and PowerPoint — against hand-written transcripts. The same reader with conversion switched off scores 0.019 on the same 96 files. The corpus, the metric, the raw results and the command that regenerates them are public, including the ways the number is weaker than it looks.