agentleFS
jyjeannejyjeanne/dita-skills/pdf-to-dita/SKILL.md

pdf-to-dita

Skill2 starsChanged 6 months agoMITView on GitHub

Converts a PDF document into a complete DITA 1.3 guide by running a 5-stage automated pipeline: PDF text extraction, topic chunking, validation, best-practices optimization, and full-guide review. Use this skill when you need to migrate legacy PDF documentation into structured DITA XML, bootstrap a DITA project from an existing PDF manual, or verify the quality of the generated DITA output. Integrates with validate-dita-topic, validate-ditamap, dita-best-practices, and review-dita-guide.

  • Installs packages

The file

Files
SKILL.md

Overview

pdf-to-dita orchestrates a five-stage pipeline that transforms any PDF into a well-structured DITA 1.3 guide, validates every generated file, applies best-practices fixes, and produces a consolidated quality report.

PDF  →  [1] Extract  →  [2] Chunk  →  [3] Validate  →  [4] Optimize  →  [5] Review
         extracted.json   topics/*.dita  validation_       optimization_    review_
                          root.ditamap   report.json       report.json      report.json

Pipeline stages

Stage 1 — Extract (extract_pdf.py)

Reads the PDF with pdfplumber and produces a structural JSON document.

  • Detects heading levels from font-size ratios (body text = most common size; ratio ≥ 1.15 → heading).
  • Preserves paragraphs, ordered/unordered lists, and tables.
  • Outputs extracted.json with a nested sections tree.
python pdf-to-dita/scripts/extract_pdf.py input.pdf > extracted.json

Output excerpt:

{
  "source": "/abs/path/input.pdf",
  "title":  "Getting Started Guide",
  "pages":  42,
  "sections": [
    {
      "level": 1,
      "title": "Installation",
      "content": [
        {"type": "paragraph", "text": "This guide covers..."},
        {"type": "list", "ordered": true, "items": ["Download the package", "Run setup.sh"]}
      ],
      "subsections": []
    }
  ]
}

Stage 2 — Chunk (chunk_to_dita.py)

Converts the extracted JSON into DITA 1.3 XML topics and a root ditamap.

Topic-type heuristics:

SignalAssigned type
Title matches action verbs (configure, install, create, …)task
Title matches (reference, parameters, api, settings, …)reference
Content has ≥ 3 ordered-list itemstask
Table headers include name, parameter, propertyreference
Defaultconcept

Output structure:

output_dir/
├── root.ditamap
└── topics/
    ├── installation.dita        (task)
    ├── configuration-options.dita (reference)
    └── overview.dita             (concept)
python pdf-to-dita/scripts/chunk_to_dita.py extracted.json ./output --map-title "My Guide"

Stage 3 — Validate (validate_output.py)

Calls validate_dita_topic.py and validate_ditamap.py on every generated file.

python pdf-to-dita/scripts/validate_output.py ./output

Output excerpt:

{
  "summary": {
    "total_files": 8, "valid": 7, "invalid": 1,
    "total_errors": 2, "total_warnings": 5
  },
  "files": [
    { "file": "topics/installation.dita", "is_valid": true, "errors": [], "warnings": [] }
  ]
}

Stage 4 — Optimize (optimize_dita.py)

Calls best_practices.py on each topic, auto-fixes common violations, then re-validates.

Auto-fixes applied:

ViolationFix
missing-shortdescInserts <shortdesc> from first sentence of first paragraph

Remaining errors and warnings after auto-fix are reported but not auto-corrected (require human review).

python pdf-to-dita/scripts/optimize_dita.py ./output

Stage 5 — Review (review_dita_guide.py)

Runs the full hierarchical guide review via review-dita-guide, traversing the generated map → topics and checking for:

  • Missing href targets
  • Duplicate topic @id values across the guide
  • Cross-file structural issues
python review-dita-guide/scripts/review_dita_guide.py ./output/root.ditamap --best-practices

Running the full pipeline

# Full pipeline (all 5 stages)
python pdf-to-dita/scripts/pipeline.py input.pdf ./output

# With custom map title
python pdf-to-dita/scripts/pipeline.py input.pdf ./output --map-title "My Product Guide"

# Skip Stage 5 for faster iteration
python pdf-to-dita/scripts/pipeline.py input.pdf ./output --skip-review

# Resume from extracted JSON (skip PDF re-extraction)
python pdf-to-dita/scripts/pipeline.py --from-json extracted.json ./output

# Full verbose report
python pdf-to-dita/scripts/pipeline.py input.pdf ./output --format full

Summary report output:

{
  "overall": "ok",
  "output_dir": "./output",
  "stages": [
    { "stage": "extract",  "status": "ok", "elapsed_s": 3.2 },
    { "stage": "chunk",    "status": "ok", "elapsed_s": 0.4 },
    { "stage": "validate", "status": "warnings", "elapsed_s": 1.1 },
    { "stage": "optimize", "status": "ok", "elapsed_s": 1.3 },
    { "stage": "review",   "status": "ok", "elapsed_s": 2.0 }
  ],
  "validation":   { "total_files": 8, "valid": 8, "total_errors": 0, "total_warnings": 3 },
  "optimization": { "total_topics": 7, "fixes_applied": 4, "remaining_errors": 0 },
  "review":       { "maps": 1, "topics": 7, "errors": 0, "warnings": 3 }
}

Exit codes

CodeMeaning
0All stages succeeded, no validation errors
1Validation errors found (DITA invalid)
2Pipeline failure (PDF read error, missing dependency)

Integration with other skills

SkillRole in pipeline
validate-dita-topicStage 3 — validates each generated .dita
validate-ditamapStage 3 — validates the generated root.ditamap
dita-best-practicesStage 4 — detects and auto-fixes best-practice violations
review-dita-guideStage 5 — cross-guide structural review
generate-dita-topicReference — topic templates match Stage 2 output format
generate-ditamapReference — map template matches Stage 2 output format
refactor-dita-contentPost-pipeline — split oversized topics, add conref

Installation

# Required for Stage 1 (PDF extraction)
pip install pdfplumber

# Or install with the project optional dependency group
pip install "dita-skills[pdf]"

Common issues

ProblemCauseFix
All topics are conceptPDF uses uniform font size (no headings detected)Increase --heading-ratio threshold or pre-process PDF
Empty <steps> in task topicsSteps detected but content was plain textManually convert paragraphs to <cmd> elements
KeyError: 'DITA_OT_DIR' in review stageDITA-OT not configuredSet DITA_OT_DIR env var or skip review with --skip-review
ImportError: pdfplumberpdfplumber not installedpip install pdfplumber
Garbled text from scanned PDFPDF contains images, not selectable textRun OCR first (e.g., ocrmypdf input.pdf ocr_output.pdf)
Short-desc truncated mid-wordFirst sentence > 50 wordsManually edit <shortdesc> after pipeline run

See also

  • validate-dita-topic — standalone topic validation
  • validate-ditamap — standalone map validation
  • dita-best-practices — standalone best-practices analysis
  • review-dita-guide — full hierarchical guide review
  • refactor-dita-content — improve reuse and modularity of generated topics

Download now (ZIP)

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
What did you use it for? e.g. Reviewing pull requests in a Rails app

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.