
Liteparse
- 487 installs
- 32.7k repo stars
- Updated August 3, 2026
- k-dense-ai/scientific-agent-skills
Parse scientific PDFs and papers into structured sections, citations, and tables so agents can summarize literature, extract methods, and answer grounded questions.
About
liteparse skill equips Claude to parse scientific PDFs for agents: extract sections, citations, tables, and metadata into structured chunks suitable for literature review, method extraction, and grounded question answering in research automation workflows.
- Scientific PDF and paper parsing
- Section, citation, and table extraction
- Agent-ready structured text chunks
- Literature review and evidence extraction
- Grounded Q&A over parsed manuscripts
Liteparse by the numbers
- 487 all-time installs (skills.sh)
- +42 installs in the week ending Aug 2, 2026 (Skillselion tracking)
- Ranked #1,801 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/k-dense-ai/scientific-agent-skills --skill liteparseAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 487 |
|---|---|
| repo stars | ★ 32.7k |
| Last updated | August 3, 2026 |
| Repository | k-dense-ai/scientific-agent-skills ↗ |
What it does
Parse scientific PDFs and papers into structured sections, citations, and tables so agents can summarize literature, extract methods, and answer grounded questions.
Files
LiteParse — Local Document Parsing
Overview
LiteParse is a fast, open-source document parser (Rust core, Python/Node bindings) focused on local, layout-aware text extraction with bounding boxes. It does not produce Markdown and does not call cloud LLMs. Outputs are plain text (layout-preserved) or structured JSON with per-page text_items (position, font metadata, optional confidence).
Version note: Examples target liteparse 2.0.0 (PyPI, May 2026). The upstream V1 branch is legacy; this skill documents V2 / main only.
For parser selection vs MarkItDown, the pdf skill, or LlamaParse, see references/choosing_a_parser.md.
When to Use This Skill
Use LiteParse when you need:
- Fast local parsing of PDFs or converted Office/image files without cloud dependencies
- Spatial text with bounding boxes for layout-aware RAG, citation grounding, or figure/table region logic
- OCR on scanned PDFs or images (bundled Tesseract, or a user-run HTTP OCR server)
- Page screenshots (PNG) for multimodal agents that must see charts, figures, or handwriting
- Batch ingestion of literature folders, supplementary PDFs, or protocol libraries
- Page subsets or password-protected PDFs
When Not to Use
| Task | Use instead |
|---|---|
| Markdown for LLM ingestion (EPUB, audio, YouTube, HTML) | markitdown skill |
| Merge/split PDFs, forms, watermarks, rotation | pdf skill |
| Dense tables, handwriting, production cloud pipelines | LlamaParse (cloud; sign up separately) |
Installation
uv pip install "liteparse==2.0.0"This installs the Python bindings and the `lit` CLI. Verify:
lit --help
python -c "import liteparse; print(liteparse.__version__)"Optional system tools (for non-PDF inputs):
- LibreOffice — Word, Excel, PowerPoint, OpenDocument, CSV/TSV
- ImageMagick — PNG, JPEG, TIFF, WebP, SVG, etc.
Install commands are in references/ocr_and_formats.md.
Node.js / TypeScript (optional): npm i @llamaindex/liteparse — see references/api_reference.md.
---
Quick Start
Python
from liteparse import LiteParse
parser = LiteParse(quiet=True)
result = parser.parse("paper.pdf")
print(result.text)
for page in result.pages:
print(f"Page {page.page_num}: {len(page.text_items)} items")CLI
# Layout-preserved text (default)
lit parse paper.pdf
# Structured JSON with bounding boxes
lit parse paper.pdf --format json -o paper.json
# Disable OCR on text-native PDFs (faster)
lit parse paper.pdf --no-ocr---
Core Workflows
1. Parse to layout-preserved text
Best for quick full-document text or feeding chunkers that do not need coordinates.
parser = LiteParse(ocr_enabled=True, quiet=True)
result = parser.parse("document.pdf")
full_text = result.textlit parse document.pdf -o output.txt2. Parse to structured JSON (bounding boxes)
Use when building layout-aware RAG, highlighting source regions, or joining text with screenshots.
import json
from liteparse import LiteParse
parser = LiteParse(output_format="json", quiet=True)
result = parser.parse("document.pdf")
# Programmatic access
for page in result.pages:
for item in page.text_items:
bbox = (item.x, item.y, item.width, item.height)
# item.text, item.confidence, item.font_name, item.font_sizelit parse document.pdf --format json -o document.jsonJSON field layout: references/output_formats.md.
3. Parse specific pages
parser = LiteParse(target_pages="1-5,10,15-20", quiet=True)
result = parser.parse("long_paper.pdf")lit parse long_paper.pdf --target-pages "1-5,10"4. Parse from bytes or stdin
Useful for uploads, S3 downloads, or piping remote PDFs.
with open("document.pdf", "rb") as f:
result = parser.parse(f.read())curl -sL https://example.com/report.pdf | lit parse -5. Page screenshots for multimodal agents
Screenshots capture visual content that text extraction alone misses (figures, complex tables, handwriting).
from pathlib import Path
parser = LiteParse(dpi=150, quiet=True)
shots = parser.screenshot("document.pdf", page_numbers=[1, 2, 3])
out = Path("screenshots")
out.mkdir(exist_ok=True)
for s in shots:
(out / f"page_{s.page_num}.png").write_bytes(s.image_bytes)lit screenshot document.pdf --target-pages "1,3,5" -o ./screenshots
lit screenshot document.pdf --dpi 300 -o ./screenshotsCombine JSON parse + screenshots when an agent needs both coordinates and pixels for the same pages.
6. Batch-parse a directory
For large corpora, prefer the CLI (parallel OCR workers) or the bundled script.
lit batch-parse ./papers ./parsed --format json --recursive
lit batch-parse ./papers ./parsed --extension .pdf --no-ocrpython scripts/batch_parse_dir.py ./papers ./parsed --format json --recursiveSee scripts/batch_parse_dir.py for a Python batch wrapper without network calls.
7. OCR configuration
OCR is on by default. Tesseract is bundled; no extra install for basic English OCR.
parser = LiteParse(
ocr_enabled=True,
ocr_language="eng", # Tesseract codes: fra, deu, etc.
num_workers=4, # parallel OCR (default: CPU cores - 1)
dpi=150, # higher DPI → better OCR, slower
)lit parse scan.pdf --ocr-language fra
lit parse scan.pdf --no-ocr
lit parse scan.pdf --ocr-server-url http://localhost:8080/ocrOffline / air-gapped: set TESSDATA_PREFIX to a directory of .traineddata files, or pass --tessdata-path. Details: references/ocr_and_formats.md.
8. Encrypted PDFs
parser = LiteParse(password="secret", quiet=True)
result = parser.parse("protected.pdf")lit parse protected.pdf --password secret9. Search text items by phrase
Merge adjacent items and return combined bounding boxes for a phrase (e.g. section titles).
from liteparse import search_items
page = result.get_page(1)
matches = search_items(page.text_items, "Materials and Methods", case_sensitive=False)---
Multi-Format Inputs
| Category | Extensions (examples) | Requirement |
|---|---|---|
.pdf | Native | |
| Office | .docx, .xlsx, .pptx, .doc, .odt, … | LibreOffice |
| Images | .png, .jpg, .tiff, .webp, .svg, … | ImageMagick |
Files are converted to PDF internally, then parsed. If conversion tools are missing, parsing fails with an actionable error — install the dependency and retry.
---
Performance Tips
- `--no-ocr` on born-digital PDFs — largest speedup
- `target_pages` — parse only methods/supplement sections
- `num_workers` — scale OCR across CPU cores
- `max_pages` — cap very large files (default 1000)
- `lit batch-parse` — directory-scale jobs with
--recursiveand--extension - Lower `dpi` (e.g. 100) when OCR quality is already sufficient
---
Reference Files
| File | Read when |
|---|---|
references/choosing_a_parser.md | Unsure whether to use LiteParse, MarkItDown, pdf, or LlamaParse |
references/api_reference.md | Python/TypeScript API, types, search_items |
references/cli_reference.md | Full lit command flags |
references/output_formats.md | JSON schema, bboxes, confidence scores |
references/ocr_and_formats.md | Tesseract, HTTP OCR, LibreOffice, ImageMagick |
---
Troubleshooting
| Issue | Fix |
|---|---|
| Office file fails | Install LibreOffice; ensure soffice is on PATH (Windows: add LibreOffice program dir) |
| Image fails | Install ImageMagick; verify convert or magick works |
| OCR poor quality | Increase --dpi; try --ocr-language; or HTTP OCR server |
| OCR slow | --no-ocr if not needed; reduce pages; increase num_workers |
| Air-gapped OCR | export TESSDATA_PREFIX=/path/to/tessdata or --tessdata-path |
ParseError on bytes | Ensure input is valid PDF bytes (Office bytes need a file path + conversion) |
---
Resources
- GitHub: https://github.com/run-llama/liteparse
- Docs: https://developers.llamaindex.ai/liteparse/
- PyPI: https://pypi.org/project/liteparse/2.0.0/
- npm: https://www.npmjs.com/package/@llamaindex/liteparse
- OCR API spec: https://github.com/run-llama/liteparse/blob/main/OCR_API_SPEC.md
LiteParse API Reference
Targets liteparse 2.0.0 (Python) and @llamaindex/liteparse (Node). Rust crate: liteparse = "2".
Python: LiteParse
from liteparse import LiteParse, ParseResult, ParsedPage, TextItem, ScreenshotResult, search_itemsConstructor options
| Python parameter | Type | Default | Description |
|---|---|---|---|
ocr_enabled | bool | True | Run OCR on regions needing it |
ocr_language | str | "eng" | Tesseract language code |
ocr_server_url | str \ | None | None |
tessdata_path | str \ | None | None |
max_pages | int | 1000 | Maximum pages to parse |
target_pages | str \ | None | None |
dpi | float | 150 | Render DPI (OCR / screenshots) |
output_format | str | "json" | "json" or "text" (affects native output mode) |
preserve_very_small_text | bool | False | Keep very small text runs |
password | str \ | None | None |
quiet | bool | False | Suppress progress output |
num_workers | int | CPU−1 | Concurrent OCR workers |
parse(file_data)
Input: file path (str / Path) or raw PDF bytes (bytes).
Returns: ParseResult
@dataclass
class ParseResult:
pages: List[ParsedPage]
text: str # full document text (layout-preserved)
@property
def num_pages(self) -> int
def get_page(self, page_num: int) -> Optional[ParsedPage] # 1-indexed@dataclass
class ParsedPage:
page_num: int
width: float
height: float
text: str
text_items: List[TextItem]@dataclass
class TextItem:
text: str
x: float
y: float
width: float
height: float
font_name: Optional[str]
font_size: Optional[float]
confidence: Optional[float] # 0.0–1.0 when from OCRRaises: FileNotFoundError, ParseError
screenshot(file_path, *, page_numbers=None)
Input: path to document (PDF or convertible format).
Returns: List[ScreenshotResult] with PNG bytes.
@dataclass
class ScreenshotResult:
page_num: int
width: int
height: int
image_bytes: bytesNon-PDF formats are converted when LibreOffice/ImageMagick are installed.
get_config()
Returns resolved LiteParseConfig dataclass.
search_items(items, phrase, *, case_sensitive=False)
Search a list of TextItem for a phrase that may span multiple items. Returns merged TextItem objects with combined bounding boxes.
from liteparse import search_items
matches = search_items(page.text_items, "Figure 1", case_sensitive=False)---
TypeScript / Node.js
import { LiteParse } from '@llamaindex/liteparse';
const parser = new LiteParse();
const result = await parser.parse('document.pdf');
console.log(result.text);
for (const page of result.pages) {
console.log(`Page ${page.pageNum}: ${page.textItems.length} items`);
}Constructor options (camelCase)
| TypeScript | Python equivalent |
|---|---|
ocrEnabled | ocr_enabled |
ocrLanguage | ocr_language |
ocrServerUrl | ocr_server_url |
tessdataPath | tessdata_path |
maxPages | max_pages |
targetPages | target_pages |
dpi | dpi |
preserveVerySmallText | preserve_very_small_text |
password | password |
quiet | quiet |
numWorkers | num_workers |
Parse from bytes
import { readFile } from 'fs/promises';
const pdfBytes = await readFile('document.pdf');
const result = await parser.parse(pdfBytes);Screenshots
const screenshots = parser.screenshot('document.pdf', [1, 2, 3]);
for (const s of screenshots) {
// s.pageNum, s.width, s.height, s.imageBuffer (PNG)
}Install: npm i @llamaindex/liteparse (includes lit CLI).
Browser/edge: @llamaindex/liteparse-wasm — see upstream WASM README.
---
Rust (library)
use liteparse::{LiteParse, LiteParseConfig};
let parser = LiteParse::new(LiteParseConfig::default());
let result = parser.parse("document.pdf").await?;Custom OCR: implement OcrEngine trait and .with_ocr_engine(Arc::new(engine)).
CLI: cargo install liteparse
Choosing a Document Parser
Use this guide to pick the right tool in the scientific-agent-skills repo (or LlamaParse for cloud escalation).
flowchart TD
start[User has a document task]
start --> q1{Need PDF merge split forms or encryption utilities?}
q1 -->|yes| pdfSkill[pdf skill]
q1 -->|no| q2{Need Markdown audio video EPUB or Azure table extraction?}
q2 -->|yes| markitdown[markitdown skill]
q2 -->|no| q3{Need bounding boxes fast local parse or page PNGs for agents?}
q3 -->|yes| liteparse[liteparse skill]
q3 -->|no| q4{Complex tables handwriting or production cloud pipeline?}
q4 -->|yes| llamaparse[LlamaParse cloud]
q4 -->|no| liteparseComparison table
| Criterion | LiteParse | MarkItDown | pdf skill | LlamaParse |
|---|---|---|---|---|
| Primary output | Layout text + JSON with bboxes | Markdown | PDF bytes / extracted text | Structured markdown / JSON (cloud) |
| Runs locally | Yes | Yes | Yes | No (cloud API) |
| Bounding boxes | Yes | No | Limited | Yes (cloud) |
| OCR | Tesseract + optional HTTP OCR | Yes (images/PDF) | Via external tools | Advanced |
| Page screenshots | Yes (PNG) | No | Image extract only | Varies |
| Office → text | Via LibreOffice convert | Native converters | N/A | Yes |
| Audio / video / EPUB | No | Yes | No | Some formats |
| PDF merge / split / forms | No | No | Yes | No |
| Best for | RAG grounding, agent vision, batch PDF corpus | LLM-friendly Markdown pipelines | PDF manipulation | Hard documents at scale |
Decision rules
Choose LiteParse when
- You need coordinates for citations, highlighting, or layout-aware chunking.
- You want fast local parsing without API keys.
- You are building multimodal workflows (parse JSON + page screenshots).
- You are batch-processing folders of PDFs for a literature review pipeline.
- Scanned PDFs need OCR with optional custom HTTP OCR backends.
Choose MarkItDown when
- The downstream step expects Markdown (RAG, summarization, notebook ingestion).
- Inputs include HTML, EPUB, audio, YouTube, or you want Azure Document Intelligence for tables.
- You do not need per-span bounding boxes.
Choose the pdf skill when
- The task is PDF file operations: merge, split, rotate, watermark, fill forms, encrypt/decrypt.
- You only need simple text extraction without spatial layout or OCR orchestration.
Choose LlamaParse when
- Documents have dense tables, multi-column layouts, charts, or handwriting beyond what local parsers handle well.
- You are building a production document pipeline and accept cloud dependency and signup.
Link: https://docs.cloud.llamaindex.ai/llamaparse/overview
Combining tools
Common pipelines:
1. LiteParse → chunk + embed — JSON/text for vector store; bboxes for UI highlights. 2. LiteParse screenshots + vision model — figures and tables; text JSON for search. 3. LiteParse text → MarkItDown-style post-processing — only if you must have Markdown; otherwise use LiteParse text directly. 4. pdf skill merge → LiteParse parse — assemble supplementary PDFs, then extract.
Avoid running LiteParse and MarkItDown on the same file unless you have distinct consumers (coordinates vs Markdown).
LiteParse CLI Reference (lit)
The `lit` command ships with liteparse (Python), @llamaindex/liteparse (npm), and cargo install liteparse (Rust). Behavior is the same across installs.
lit --help
lit parse --help
lit batch-parse --help
lit screenshot --help---
lit parse
Parse a single file or stdin.
lit parse [OPTIONS] <file>| Option | Description |
|---|---|
-o, --output <file> | Write output to file (default: stdout) |
--format <format> | json or text (default: text) |
--no-ocr | Disable OCR |
--ocr-language <lang> | Tesseract language (default: eng) |
--ocr-server-url <url> | HTTP OCR server base URL |
--tessdata-path <path> | Tessdata directory |
--max-pages <n> | Max pages (default: 1000) |
--target-pages <pages> | e.g. 1-5,10,15-20 |
--dpi <dpi> | Rendering DPI (default: 150) |
--preserve-small-text | Keep very small text |
--password <password> | Encrypted document password |
--num-workers <n> | Concurrent OCR workers |
-q, --quiet | Suppress progress |
-h, --help | Help |
Examples
lit parse document.pdf
lit parse document.pdf --format json -o output.json
lit parse document.pdf --target-pages "1-5,10" --no-ocr
lit parse scan.pdf --ocr-language fra --dpi 200
lit parse protected.pdf --password secret
curl -sL https://example.com/paper.pdf | lit parse - -o paper.txt---
lit batch-parse
Parse every supported file in a directory.
lit batch-parse [OPTIONS] <input-dir> <output-dir>| Option | Description |
|---|---|
--format <format> | json or text (default: text) |
--no-ocr | Disable OCR |
--ocr-language <lang> | Tesseract language (default: eng) |
--ocr-server-url <url> | HTTP OCR server |
--tessdata-path <path> | Tessdata directory |
--max-pages <n> | Max pages per file (default: 1000) |
--dpi <dpi> | Rendering DPI (default: 150) |
--recursive | Recurse into subdirectories |
--extension <ext> | Only files with extension (e.g. .pdf) |
--password <password> | Password for encrypted documents |
--num-workers <n> | Concurrent OCR workers |
-q, --quiet | Suppress progress |
-h, --help | Help |
Examples
lit batch-parse ./papers ./parsed
lit batch-parse ./papers ./parsed --format json --recursive
lit batch-parse ./pdfs ./out --extension .pdf --no-ocrOutput files mirror input basenames with .txt or .json extension.
---
lit screenshot
Render pages to PNG files.
lit screenshot [OPTIONS] <file>| Option | Description |
|---|---|
-o, --output-dir <dir> | Output directory (default: ./screenshots) |
--target-pages <pages> | Pages to render (e.g. 1,3,5 or 1-5) |
--dpi <dpi> | Rendering DPI (default: 150) |
--password <password> | Encrypted document password |
-q, --quiet | Suppress progress |
-h, --help | Help |
Examples
lit screenshot document.pdf -o ./screenshots
lit screenshot document.pdf --target-pages "1,3,5" --dpi 300---
Environment variables
| Variable | Description |
|---|---|
TESSDATA_PREFIX | Directory containing Tesseract .traineddata files (offline/air-gapped) |
OCR and Supported Input Formats
Built-in OCR (Tesseract)
- Default: OCR enabled on parse.
- Engine: Tesseract bundled with the library (zero extra setup for typical English PDFs).
- Disable when PDFs have selectable text:
--no-ocrorocr_enabled=False.
lit parse document.pdf
lit parse document.pdf --ocr-language fra
lit parse document.pdf --no-ocrparser = LiteParse(ocr_enabled=True, ocr_language="eng", num_workers=4)Language codes
Use Tesseract codes (not ISO alone): eng, fra, deu, spa, chi_sim, etc. Map HTTP OCR language=en separately (see below).
Offline / air-gapped environments
Pre-download .traineddata files, then either:
export TESSDATA_PREFIX=/path/to/tessdata
lit parse document.pdf --ocr-language engor:
lit parse document.pdf --tessdata-path /path/to/tessdata---
HTTP OCR servers (optional)
For higher accuracy or GPU-backed OCR, run a server implementing the LiteParse OCR API and point LiteParse at it:
lit parse document.pdf --ocr-server-url http://localhost:8080/ocrparser = LiteParse(ocr_server_url="http://localhost:8080/ocr")API contract (summary)
- POST
{base_url}/ocr(typicallyhttp://host:8080/ocr) - Content-Type:
multipart/form-data - Fields:
file(image bytes, required),language(optional, ISO 639-1, defaulten) - Response JSON:
{
"results": [
{
"text": "recognized text",
"bbox": [x1, y1, x2, y2],
"confidence": 0.95
}
]
}- Origin top-left; bbox axis-aligned in pixels.
- Full spec: https://github.com/run-llama/liteparse/blob/main/OCR_API_SPEC.md
Reference server implementations (upstream repo)
ocr/easyocr/— EasyOCR wrapperocr/paddleocr/— PaddleOCR wrapper
You only need a server if you choose HTTP OCR; Tesseract is sufficient for many workflows.
---
Supported input formats
PDF (native)
.pdf — no conversion step.
Office documents (LibreOffice)
Requires LibreOffice installed and on PATH.
| Type | Extensions |
|---|---|
| Word | .doc, .docx, .docm, .odt, .rtf, .pages |
| PowerPoint | .ppt, .pptx, .pptm, .odp, .key |
| Spreadsheets | .xls, .xlsx, .xlsm, .ods, .csv, .tsv, .numbers |
Install LibreOffice:
# macOS
brew install --cask libreoffice
# Ubuntu/Debian
sudo apt-get install libreoffice
# Windows (Chocolatey)
choco install libreoffice-freshOn Windows, add LibreOffice program directory to PATH (often C:\Program Files\LibreOffice\program).
Images (ImageMagick)
Requires ImageMagick.
| Formats |
|---|
.jpg, .jpeg, .png, .gif, .bmp, .tiff, .webp, .svg |
Install ImageMagick:
# macOS
brew install imagemagick
# Ubuntu/Debian
sudo apt-get install imagemagick
# Windows
choco install imagemagick.app---
Conversion pipeline
Office / image → (LibreOffice or ImageMagick) → PDF → PDFium extract → optional OCR → grid projection → text + JSONIf conversion fails, install the missing tool and retry. Plain-text-only paths cannot be screenshot-rendered.
LiteParse Output Formats
Text output (--format text)
- CLI: layout-preserved plain text written to stdout or
-ofile. - Python:
ParseResult.text— full document; eachParsedPage.text— page-level text. - Reading order follows reconstructed spatial layout (grid projection), not raw PDF content stream order.
Use text output when feeding chunkers, summarizers, or keyword search that do not need coordinates.
---
JSON output (--format json)
CLI
lit parse document.pdf --format json -o document.jsonThe CLI serializes the native parse result. Structure aligns with the Python object model below.
Python object model
After parser.parse(path), use result.pages and result.text. To emit JSON manually:
import json
from dataclasses import asdict
# Simple serialization pattern (adapt fields as needed)
def page_to_dict(page):
return {
"page_num": page.page_num,
"width": page.width,
"height": page.height,
"text": page.text,
"text_items": [
{
"text": item.text,
"x": item.x,
"y": item.y,
"width": item.width,
"height": item.height,
"font_name": item.font_name,
"font_size": item.font_size,
"confidence": item.confidence,
}
for item in page.text_items
],
}
payload = {
"text": result.text,
"pages": [page_to_dict(p) for p in result.pages],
}
json.dump(payload, open("out.json", "w"), indent=2)Example JSON shape
{
"text": "Full document text...\n",
"pages": [
{
"page_num": 1,
"width": 612.0,
"height": 792.0,
"text": "Page 1 text...",
"text_items": [
{
"text": "Introduction",
"x": 72.0,
"y": 100.0,
"width": 120.0,
"height": 14.0,
"font_name": "Times-Bold",
"font_size": 12.0,
"confidence": null
},
{
"text": "scanned phrase",
"x": 80.0,
"y": 400.0,
"width": 200.0,
"height": 12.0,
"font_name": null,
"font_size": null,
"confidence": 0.94
}
]
}
]
}Exact CLI JSON keys may match upstream serialization; treat text_items geometry as authoritative for grounding.
---
Bounding box coordinate system
- Origin (0, 0) is top-left of the page.
- x increases right; y increases down.
- Each
TextItemuses (x, y, width, height) — top-left corner plus size in page units (typically PDF points). - HTTP OCR servers return
[x1, y1, x2, y2]; LiteParse normalizes intox, y, width, heightinternally.
Convert corner box to width/height
x1, y1, x2, y2 = bbox
x, y, width, height = x1, y1, x2 - x1, y2 - y1---
Confidence scores
- Present on OCR-derived
text_items(since upstream v1.4.0). - Range 0.0–1.0 when set;
nullfor native PDF text extraction. - Filter low-confidence items in downstream pipelines if needed.
---
Phrase search across items
Use search_items() when a query spans multiple text_items:
from liteparse import search_items
hits = search_items(page.text_items, "Supplementary Table 1")
for hit in hits:
# hit.text — matched phrase
# hit.x, hit.y, hit.width, hit.height — merged bbox---
Layout-aware RAG patterns
1. Chunk by page — page.text or group text_items by vertical bands. 2. Ground citations — store (page_num, x, y, width, height) with each chunk. 3. Multimodal — pair JSON chunks with screenshot() PNGs for the same page_num. 4. Quality gate — drop items with confidence below threshold on OCR-heavy pages.
#!/usr/bin/env python3
"""
Batch-parse documents in a directory with LiteParse (local only, no network).
Usage:
python batch_parse_dir.py INPUT_DIR OUTPUT_DIR [--format json|text] [--no-ocr] [--recursive] [--extension .pdf]
"""
from __future__ import annotations
import argparse
import json
import sys
from pathlib import Path
from typing import Iterable, List, Optional
from liteparse import LiteParse, ParseResult
DEFAULT_EXTENSIONS = {
".pdf",
".doc",
".docx",
".docm",
".odt",
".rtf",
".ppt",
".pptx",
".pptm",
".odp",
".xls",
".xlsx",
".xlsm",
".ods",
".csv",
".tsv",
".png",
".jpg",
".jpeg",
".gif",
".bmp",
".tiff",
".webp",
".svg",
}
def _text_item_dict(item) -> dict:
return {
"text": item.text,
"x": item.x,
"y": item.y,
"width": item.width,
"height": item.height,
"font_name": item.font_name,
"font_size": item.font_size,
"confidence": item.confidence,
}
def _result_to_dict(result: ParseResult) -> dict:
return {
"text": result.text,
"pages": [
{
"page_num": p.page_num,
"width": p.width,
"height": p.height,
"text": p.text,
"text_items": [_text_item_dict(i) for i in p.text_items],
}
for p in result.pages
],
}
def iter_files(
input_dir: Path,
*,
recursive: bool,
extension: Optional[str],
) -> Iterable[Path]:
ext_filter = {extension.lower()} if extension else DEFAULT_EXTENSIONS
pattern = "**/*" if recursive else "*"
for path in sorted(input_dir.glob(pattern)):
if path.is_file() and path.suffix.lower() in ext_filter:
yield path
def parse_one(
parser: LiteParse,
file_path: Path,
output_dir: Path,
fmt: str,
) -> tuple[bool, str, str]:
try:
result = parser.parse(file_path)
out_name = f"{file_path.stem}.{'json' if fmt == 'json' else 'txt'}"
out_path = output_dir / out_name
if fmt == "json":
out_path.write_text(
json.dumps(_result_to_dict(result), indent=2),
encoding="utf-8",
)
else:
out_path.write_text(result.text, encoding="utf-8")
return True, str(file_path), f"OK -> {out_name}"
except Exception as exc:
return False, str(file_path), str(exc)
def main(argv: Optional[List[str]] = None) -> int:
p = argparse.ArgumentParser(description="Batch-parse documents with LiteParse")
p.add_argument("input_dir", type=Path, help="Directory of input files")
p.add_argument("output_dir", type=Path, help="Directory for parsed output")
p.add_argument(
"--format",
choices=("json", "text"),
default="text",
help="Output format (default: text)",
)
p.add_argument("--no-ocr", action="store_true", help="Disable OCR")
p.add_argument("--recursive", action="store_true", help="Search subdirectories")
p.add_argument(
"--extension",
help="Only process this extension (e.g. .pdf); default: all supported types",
)
p.add_argument("-q", "--quiet", action="store_true", help="Less console output")
args = p.parse_args(argv)
if not args.input_dir.is_dir():
print(f"Input directory not found: {args.input_dir}", file=sys.stderr)
return 1
args.output_dir.mkdir(parents=True, exist_ok=True)
parser = LiteParse(
ocr_enabled=not args.no_ocr,
output_format=args.format,
quiet=args.quiet,
)
files = list(iter_files(args.input_dir, recursive=args.recursive, extension=args.extension))
if not files:
print("No matching files found.", file=sys.stderr)
return 1
ok, fail = 0, 0
for fp in files:
success, path, msg = parse_one(parser, fp, args.output_dir, args.format)
if success:
ok += 1
if not args.quiet:
print(f"✓ {path}: {msg}")
else:
fail += 1
print(f"✗ {path}: {msg}", file=sys.stderr)
print(f"Done: {ok} succeeded, {fail} failed, {len(files)} total")
return 0 if fail == 0 else 1
if __name__ == "__main__":
sys.exit(main())
Related skills
Forks & variants (2)
Liteparse has 2 known copies in the catalog totaling 14 installs. They canonicalize to this original listing.
- k-dense-ai - 9 installs
- eturkes - 5 installs