Skip to content
Talk to our solutions team

Documents & OCR

This page has two layers:

  1. kis doc, the modern, general document engine (lib-doc): read, convert, classify, and extract from everyday formats (PDF, DOCX, XLSX, PPTX, HTML, Markdown, CSV, images). Reach for this first.
  2. The lower-level, coordinate-aware OCR pipeline for scanned forms, hocr2bboxbboxocr / rules, when you need spatial questions (“the table near this label”) that flat text can’t answer.
OCR engine → HOCR ──hocr2bbox──▶ .bbox files ──bbox / ocr──▶ extracted data / rule results

What is a “bbox” file? A JSON representation of a page where every piece of text carries its bounding-box coordinates, the basis of the spatial pipeline above.

What it is. A general document engine (lib-doc): read, convert, classify, and extract from documents across many formats, Markdown, HTML, DOCX, XLSX, PPTX, PDF, CSV, and images.

Why it exists. Real-world inputs arrive in every format. kis doc normalizes them to text / Markdown / tables you can feed to AI, rules, or storage, without a different tool per format. It’s the front door to documents; the hocr2bbox pipeline below is the specialized path for scanned, coordinate-sensitive forms.

When to reach for it. Getting text, tables, or Markdown out of office/PDF docs, converting between formats, or checking a document’s type and extraction quality before processing it.

Terminal window
kis doc read report.pdf # read & print as Markdown (default)
kis doc convert in.docx out.md # convert one file (or a whole directory)
kis doc text invoice.pdf # plain text (pre-chunking normalization)
kis doc tables sales.xlsx # extract tables
kis doc classify mystery.bin # detect format + type
kis doc formats # list supported read/write formats
kis doc quality scan.pdf # extraction-quality report
SubcommandWhat it does
readRead a document and print it (Markdown by default)
convertConvert a file, or a whole directory, from one format to another
textExtract plain text (pre-chunking normalization)
tablesExtract tables from a document
classifyDetect a document’s format and type
formatsList supported read and write formats
qualityPrint the extraction-quality report
toolsManage external tools lib-doc can use, OCR engines (tesseract, paddleocr) and converters (markitdown, pandoc); install / list

What it is. Converts HOCR (the HTML-with-coordinates format most OCR engines emit) into the bbox JSON the other commands consume.

Why it exists. It’s the on-ramp to the whole document toolchain: nothing else here reads HOCR directly, so this is almost always step one.

When to reach for it. Right after OCR, before any bbox/ocr work. Use the cleanup flags when the OCR text is noisy.

Terminal window
# Single file
kis hocr2bbox -i page.hocr -o page.bbox
# A directory, in parallel, with text cleanup
kis hocr2bbox -i scans/ -o bbox/ --clean -w 4
FlagMeaning
-i, --inputHOCR file or directory
-o, --outputOutput file/dir (defaults to input location)
--cleanNormalize unicode, fix quotes/dashes, drop garbage chars
--clean-formForm-aware cleanup (preserves checkbox/radio markers)
-w, --workersParallel workers for directories (default 4)
-v, --verboseWarn about potentially missed content

What it is. A toolkit for searching and extracting from bbox documents. Each input file is treated as one page; analysis runs across the combined document.

Why it exists. Once text has coordinates, you can extract by position and context, far more robust than regex over a flat text dump for real-world documents.

When to reach for it. Pulling specific values, sections, or tables out of OCR’d documents. It has five subcommands; inputs can be positional (shell globs allowed) or repeated -i flags.

Terminal window
kis bbox --help

phrase, find text with surrounding context

Section titled “phrase, find text with surrounding context”
Terminal window
kis bbox phrase -p "Invoice Number" doc.bbox
kis bbox phrase -p "invoice number" --case-insensitive doc*.bbox
kis bbox phrase -p "total amount due" -B 5 -A 2 doc.bbox # 5 lines before, 2 after
kis bbox phrase -p "Inviice Numbr" --fuzzy doc.bbox # tolerate OCR typos

Key flags: -B/--before, -A/--after, --case-insensitive, --fuzzy (with --max-dist-word / --max-dist-total), -f json, -o output.

Terminal window
kis bbox snippet -s "Section 5:" -e "Section 6:" doc.bbox
kis bbox snippet -s "BEGIN" -e "END" --include-end -f json doc.bbox
Terminal window
kis bbox snippets --snip "section8|Section 8:|Section 9:" doc.bbox
kis bbox snippets --snip "terms|TERMS|SIGNATURE" --snip "privacy|PRIVACY|END" *.bbox

Each --snip is "name|start phrase|end phrase". Output is a JSON object keyed by name.

Terminal window
kis bbox table -a "Invoice Items" doc.bbox
kis bbox table -a "Price List" -H "Item" -H "Price" -H "Qty" doc.bbox # validate headers
kis bbox table -a "Summary" -f json -o table.json doc.bbox

-a/--anchor locates the table; -H/--header (repeatable) asserts expected columns; -f supports text, json, csv.

Terminal window
kis bbox tables *.bbox
kis bbox tables doc.bbox -f csv -o tables.csv

What it is. Runs the rules engine over page pairs, each page is a .json file (the “facts”) paired with a matching .bbox file (the bounding boxes), resolved by basename.

Why it exists. It’s the bridge between document layout and business logic: it feeds both the structured facts and the spatial bbox data into the rules engine so your rules can reason over content and position together.

When to reach for it. Applying extraction/validation rules to OCR’d documents. Choose the mode by whether pages are independent or one logical document.

You pass prefixes, file paths, or directories. Two modes:

page, one execution per page (pages are independent):

Terminal window
kis ocr page -r rules.grl page1
kis ocr page -r rules/ page1 page2 page3
kis ocr page -r rules/ -i pages/ # all *.json in pages/
kis ocr page -r rules/ --update pages/ # write results back into each .json

doc, aggregate all pages, run once (one logical document):

Terminal window
kis ocr doc -r rules/ page1 page2 page3
kis ocr doc -r rules/ -o result.json pages/
kis ocr doc -r rules/ --facts-key documents pages/

In doc mode the per-page facts are injected as an array (under --facts-key, default pages) and the bbox files merge into one multi-page document (under --bbox-name, default doc).

Shared ocr flags: -r/--rules, -i/--input, -o/--output, -p/--pattern, -k/--key, -v/--vars, -f/--facts, --schema/--schemas, --audit, --history, -w/--workers (page mode).

What it is. Runs the Maya rules engine over a directory of JSON files, applying declarative business rules and either reporting or writing back the results.

Why it exists. Business logic that changes often (eligibility, validation, classification, enrichment) is better expressed as data-driven rules than as code recompiled each time. The engine also produces an audit trail of every decision, important for regulated workflows.

When to reach for it. Applying rules to JSON at scale. Use ocr when the input is document page-pairs; use script rules when your logic is easier to write as a script than as rule files.

Terminal window
# Run a ruleset over a folder and write results back in
kis rules -r rules/ -i ./input --update -w 4
# Inject extra facts and a bbox document
kis rules -r rules.grl -i ./input -f customer=customer.json -b invoice=ocr.json
# Auto-pair each file.json with file.bbox
kis rules -r rules/ -i ./pages --with-bbox --update
# Inspect what the rules decided
kis rules -r rules/ -i ./input --audit --history
FlagMeaning
-r, --rulesRule file or directory
-i, --inputInput directory (default .)
-o, --outputOutput directory (defaults to input)
-p, --patternGlob (default *.json)
-f, --factsFacts file(s), key=path
-b, --bboxBbox file(s) to inject, [key=]path
-k, --keyNest results under this key
-v, --varsVariables (key=value)
--with-bboxPair each .json with a same-named .bbox
-R, --recursiveRecurse for rule files
--updateUpdate JSONs in place
--auditShow the rule-decision audit log
--historyShow value-change history
-w, --workersParallel workers (default 1)