paddleocr-doc-parsing
Skill35 starsChanged 4 months agoApache-2.0View on GitHub
Use this skill to extract structured Markdown/JSON from PDFs and document images—tables with cell-level precision, formulas as LaTeX, figures, seals, charts, headers/footers, multi-column layout and correct reading order. Trigger terms: 文档解析, 版面分析, 版面还原, 表格提取, 公式识别, 多栏排版, 扫描件结构化, 发票, 财报, 复杂 PDF, PDF转Markdown, 图表, 阅读顺序; reading order, formula, LaTeX, layout parsing, structure extraction, PP-StructureV3, PaddleOCR-VL.
- Reads credentials
- Installs packages
5 other projects use a version of this, 2 of them edited.
Adopted by
Most recently taken up by
- weininghui/skillstheir own version, first seen Oct 30, 2026
- PaddlePaddle/PaddleOCRedited, first seen Oct 8, 2026
- Aidenwu0209/dsh-PaddleOCR-Skillstheir own version, first seen Aug 14, 2026
- aresbit/claude-skillstheir own version, first seen Jul 12, 2026
- freestylefly/canghe-skillsedited, first seen Feb 24, 2026
Other versions5 projects use a version of this.
Word for word · 0
None found.
Edited · 2
- PaddlePaddle/PaddleOCR★ 91k46% same
- freestylefly/canghe-skills★ 46137% same
Wrote their own version · 3
- Aidenwu0209/dsh-PaddleOCR-Skills★ 3same name
- weininghui/skills★ 1same name
- aresbit/claude-skills★ 0same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repositoryOne other file it gives its agents.
The file
Show its rules and text
We split this skill into the rules it gives an agent
21 rules. 0 are common, 10 are distinctive, and 11 are very specific to this project.
0
Common
Most of the 4 edited versions we read keep these.
10
Distinctive
This author's own choices. Worth a look.
11
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 87
If omitted, the type is auto-detected from the file extension.
- Very specific: line 92
If --output is omitted, the script saves automatically under the system temp directory
- Very specific: line 93
Default path pattern: <system-temp>/paddleocr/doc-parsing/results/result_<timestamp>_<id>.json
- Very specific: line 94
If --output is provided, it overrides the default temp-file destination
- Very specific: line 95
If --stdout is provided, JSON is printed to stdout and no file is saved
- Very specific: line 98
Use --stdout only when you explicitly want to skip file persistence
- Very specific: line 101
Check the ok field: true means success, false means error
- Distinctive: line 103
Use the appropriate field based on what the user needs:
- Distinctive: line 111
If the content is empty, the document may contain no extractable text
- Very specific: line 118
Save as Markdown: Write the text field to a .md file — tables, headings, and formulas are preserved
- Very specific: line 127
If user asks for "all text", show the entire text field
- Distinctive: line 128
If user asks for "tables", show ALL tables in the document
- Distinctive: line 129
If user asks for "main content", filter out headers/footers but show ALL body text
- Distinctive: line 130
Do not truncate with "..." unless content is excessively long (>10,000 chars)
- Distinctive: line 131
Do not say "Here's a preview" when user expects complete output
- Very specific: line 238
Run paddleocr api --help for the full option list.
- Distinctive: line 305
User configured via the host UI: ask the user to confirm, then retry.
- Distinctive: line 333
If you only need certain pages from a large PDF, extract them first:
- Very specific: line 348
All errors return JSON with ok: false.
- Distinctive: line 365
Document may be blank, image-only, or contain no extractable text
- Distinctive: line 369
If parsing quality is poor:
“Common” is measured: kept by at least 6 in 10 of the 4 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
PaddleOCR Document Parsing Skill
When to Use This Skill
Trigger keywords (routing): Bilingual trigger terms (Chinese and English) are listed in the YAML description above—use that field for discovery and routing.
Use this skill for:
- Documents with tables (invoices, financial reports, spreadsheets)
- Documents with mathematical formulas (academic papers, scientific documents)
- Documents with charts and diagrams
- Multi-column layouts (newspapers, magazines, brochures)
- Complex document structures requiring layout analysis
- Any document requiring structured understanding
Do not use for:
- Simple text-only extraction
- Quick OCR tasks where speed is critical
- Screenshots or simple images with clear text
Installation
Scripts declare their dependencies inline (PEP 723). No separate install step is needed — uv resolves dependencies automatically:
uv run scripts/layout_caller.py --helpHow to Use This Skill
Working directory: All
uv run scripts/...commands below should be run from this skill's root directory (the directory containing this SKILL.md file).
Basic Workflow
- Identify the input source:
- User provides URL: Use the
--file-urlparameter - User provides local file path: Use the
--file-pathparameter
- User provides URL: Use the
Execute document parsing:
uv run scripts/layout_caller.py --file-url "URL provided by user" --prettyOr for local files:
uv run scripts/layout_caller.py --file-path "file path" --prettyOptional: explicitly set file type:
uv run scripts/layout_caller.py --file-url "URL provided by user" --file-type 0 --pretty--file-type 0: PDF--file-type 1: image- If omitted, the type is auto-detected from the file extension. For local files, a recognized extension (
.pdf,.png,.jpg,.jpeg,.bmp,.tiff,.tif,.webp) is required; otherwise pass--file-typeexplicitly. For URLs with unrecognized extensions, the service attempts inference.
Performance note: Parsing time scales with document complexity. Single-page images typically complete in 1-5 seconds; large PDFs (50+ pages) may take several minutes. Allow adequate time before assuming a timeout.
Default behavior: save raw JSON to a temp file:
- If
--outputis omitted, the script saves automatically under the system temp directory - Default path pattern:
<system-temp>/paddleocr/doc-parsing/results/result_<timestamp>_<id>.json - If
--outputis provided, it overrides the default temp-file destination - If
--stdoutis provided, JSON is printed to stdout and no file is saved - In save mode, the script prints the absolute saved path on stderr:
Result saved to: /absolute/path/... - In default/custom save mode, read and parse the saved JSON file before responding
- Use
--stdoutonly when you explicitly want to skip file persistence
- Parse JSON response:
- Check the
okfield:truemeans success,falsemeans error - The output contains complete document data: text, tables, formulas (LaTeX), figures, seals, headers/footers, and reading order
- Use the appropriate field based on what the user needs:
text— full document text across all pagesresult.result.layoutParsingResults[n].markdown.text— page-level markdownresult.result.layoutParsingResults[n].prunedResult— structured layout data with positions and confidence
- Handle errors: If
okis false, displayerror.message
- Check the
- Present results to user:
- Display content based on what the user requested (see "Complete Output Display" below)
- If the content is empty, the document may contain no extractable text
- In save mode, always tell the user the saved file path and that full raw JSON is available there
What to Do After Parsing
Common next steps once you have the structured output:
- Save as Markdown: Write the
textfield to a.mdfile — tables, headings, and formulas are preserved - Extract specific tables: Navigate
result.result.layoutParsingResults[n].prunedResultto access individual layout elements with position and confidence data - Feed to RAG / search pipeline: The
textfield is structured markdown, ready for chunking and indexing - Poor results: See "Tips for Better Results" below before retrying
Complete Output Display
Display the COMPLETE extracted content based on what the user asked for. The parsed output is only useful if the user receives all of it — truncation silently drops data.
- If user asks for "all text", show the entire
textfield - If user asks for "tables", show ALL tables in the document
- If user asks for "main content", filter out headers/footers but show ALL body text
- Do not truncate with "..." unless content is excessively long (>10,000 chars)
- Do not say "Here's a preview" when user expects complete output
Example - Correct:
User: "Extract all the text from this document"
Agent: I've parsed the complete document. Here's all the extracted text:
[Display entire text field or concatenated regions in reading order]
Document Statistics:
- Total regions: 25
- Text blocks: 15
- Tables: 3
- Formulas: 2
Quality: Excellent (confidence: 0.92)Example - Incorrect:
User: "Extract all the text"
Agent: "I found a document with multiple sections. Here's the beginning:
'Introduction...' (content truncated for brevity)"Understanding the Output
The script returns an envelope with ok, text, result, and error. Use text for the full document content; navigate result.result.layoutParsingResults[n] for per-page structured data.
For the complete schema and field-level details, see references/output_schema.md.
Raw result location (default): the temp-file path printed by the script on stderr
Alternative: paddleocr CLI
This mirror keeps the bundled scripts/layout_caller.py as the default path. The upstream PaddleOCR project (since PR #18090, 2026-06-03) also ships an official CLI that calls the same API directly. If the paddleocr package is installed, you can use it as a drop-in alternative — no uv run or local scripts required.
Install (one-time):
pip install "paddleocr>=3.7.0"Environment: the CLI only needs PADDLEOCR_ACCESS_TOKEN. It resolves the API endpoint internally, so PADDLEOCR_DOC_PARSING_API_URL is not required when using the CLI (the URL is still required by the script).
Basic document parsing:
# From URL
paddleocr api --model_type doc_parsing --file_url "https://example.com/report.pdf"
# From local file
paddleocr api --model_type doc_parsing --file_path "./document.pdf"Common options:
# Specific model
paddleocr api --model_type doc_parsing --model PP-StructureV3 --file_path "./report.pdf"
# Disable preprocessing (faster, for flat/well-oriented images)
paddleocr api --model_type doc_parsing --file_path "./document.pdf" \
--use_doc_unwarping False --use_doc_orientation_classify False
# Page ranges (replaces split_pdf.py for most cases)
paddleocr api --model_type doc_parsing --file_path "./large.pdf" --page_ranges "1-5,10,15-20"
# Save result and extracted resources (images)
paddleocr api --model_type doc_parsing --file_url "https://..." \
--output result.json --save_resources ./resources
# Prettify markdown output
paddleocr api --model_type doc_parsing --file_path "./document.pdf" --prettify_markdown TrueCLI output format — different from the script envelope:
{
"jobId": "job-xxx",
"pages": [
{
"markdownText": "# Title\n\nContent...",
"markdownImages": { "img1": "https://...", "img2": "https://..." },
"outputImages": { "layout1": "https://..." }
}
]
}The CLI prints {jobId, pages:[...]} to stdout. It does not wrap the response in the script's {ok, text, result, error} envelope, does not auto-save to a temp file, and does not concatenate a top-level text field for you. Field names also differ from the script's raw result.result.layoutParsingResults[n].markdown.text path. If you switch paths, update your parsing logic accordingly.
Scripts vs CLI — at a glance:
| Scripts (default) | paddleocr CLI (alternative) | |
| Install | uv resolves PEP 723 inline deps | pip install "paddleocr>=3.7.0" |
| Required env | PADDLEOCR_DOC_PARSING_API_URL + PADDLEOCR_ACCESS_TOKEN | PADDLEOCR_ACCESS_TOKEN only |
| Entry | uv run scripts/layout_caller.py ... | paddleocr api --model_type doc_parsing ... |
| Page selection | Pre-split with scripts/split_pdf.py | Native --page_ranges "1-5,10" |
| Image optimization | scripts/optimize_file.py before upload | Same, or rely on CLI defaults |
| Output | {ok, text, result, error} envelope, auto-saved to temp file | {jobId, pages:[...]} to stdout |
| Result location | Path printed on stderr (or --output/--stdout) | stdout (or --output) |
| Best for | Skills runtimes, offline-friendly, no extra install | Already have paddleocr installed, want the upstream-canonical flow |
Run paddleocr api --help for the full option list.
Usage Examples
Example 1: Extract Full Document Text
uv run scripts/layout_caller.py \
--file-url "https://example.com/paper.pdf" \
--prettyThen use:
- Top-level
textfor quick full-text output result.result.layoutParsingResults[n].markdownwhen page-level output is needed
Example 2: Extract Structured Page Data
uv run scripts/layout_caller.py \
--file-path "./financial_report.pdf" \
--prettyThen use:
result.result.layoutParsingResults[n].prunedResultfor structured parsing data (layout/content/confidence)
Example 3: Print JSON to stdout (without saving to file)
uv run scripts/layout_caller.py \
--file-url "URL" \
--stdout \
--prettyBy default the script writes JSON to a temp file and prints the path to stderr. Add --stdout to print the full JSON directly to stdout instead. Use this when you need to inspect the result inline or pipe it to another tool.
First-Time Configuration
When API is not configured, the script outputs:
{
"ok": false,
"text": "",
"result": null,
"error": {
"code": "CONFIG_ERROR",
"message": "PADDLEOCR_DOC_PARSING_API_URL not configured. Get your API at: https://paddleocr.com"
}
}Configuration workflow:
- Show the exact error message to the user.
Guide the user to obtain credentials: Visit the PaddleOCR website, click API, select a model (
PP-StructureV3,PaddleOCR-VL, orPaddleOCR-VL-1.5), then copy theAPI_URLandToken. They map to these environment variables:PADDLEOCR_DOC_PARSING_API_URL— full endpoint URL ending with/layout-parsingPADDLEOCR_ACCESS_TOKEN— 40-character alphanumeric string
Optionally configure
PADDLEOCR_DOC_PARSING_TIMEOUTfor request timeout. Recommend using the host application's standard configuration method rather than pasting credentials in chat.- Apply credentials — one of:
- User configured via the host UI: ask the user to confirm, then retry.
- User pastes credentials in chat: warn that they may be stored in conversation history, help the user persist them using the host's standard configuration method, then retry.
Handling Large Files
For PDFs, the maximum is 100 pages per request.
Optimize Large Images Before Parsing
For large image files, compress before uploading — this reduces upload time and can improve processing stability:
uv run scripts/optimize_file.py input.png output.jpg --quality 85
uv run scripts/layout_caller.py --file-path "output.jpg" --pretty--quality controls JPEG/WebP lossy compression (1-100, default 85); it has no effect on PNG output. Use --target-size (in MB, default 20) to set the max file size — the script iteratively downscales until the target is met.
Use URL for Large Local Files (Recommended)
For very large local files, prefer --file-url over --file-path to avoid base64 encoding overhead:
uv run scripts/layout_caller.py --file-url "https://your-server.com/large_file.pdf"Process Specific Pages (PDF Only)
If you only need certain pages from a large PDF, extract them first:
# Extract pages 1-5
uv run scripts/split_pdf.py large.pdf pages_1_5.pdf --pages "1-5"
# Mixed ranges are supported
uv run scripts/split_pdf.py large.pdf selected_pages.pdf --pages "1-5,8,10-12"
# Then process the smaller file
uv run scripts/layout_caller.py --file-path "pages_1_5.pdf"Error Handling
All errors return JSON with ok: false. Show the error message and stop — do not fall back to your own vision capabilities. Identify the issue from error.code and error.message:
Authentication failed (403) — error.message contains "Authentication failed"
- Token is invalid, reconfigure with correct credentials
Quota exceeded (429) — error.message contains "API rate limit exceeded"
- Daily API quota exhausted, inform user to wait or upgrade
Unsupported format — error.message contains "Unsupported file format"
- File format not supported, convert to PDF/PNG/JPG
No content detected:
textfield is empty- Document may be blank, image-only, or contain no extractable text
Tips for Better Results
If parsing quality is poor:
- Large or high-resolution images: Compress with
optimize_file.pybefore parsing — oversized inputs can degrade layout detection:uv run scripts/optimize_file.py input.png optimized.jpg --quality 85 - Check confidence:
result.result.layoutParsingResults[n].prunedResultincludes confidence scores per layout element — low values indicate regions worth reviewing
Reference Documentation
references/output_schema.md— Full output schema, field descriptions, and command examples
Note: Model version and capabilities are determined by your API endpoint (
PADDLEOCR_DOC_PARSING_API_URL).
Testing the Skill
To verify the skill is working properly:
uv run scripts/smoke_test.py
uv run scripts/smoke_test.py --skip-api-test
uv run scripts/smoke_test.py --test-url "https://..."The first form tests configuration and API connectivity. --skip-api-test checks configuration only. --test-url overrides the default sample document URL.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

