drpwchen/textbook-to-note/textbook-to-md
Claude Code and agent skill by drpwchen/textbook-to-note
- community
Checking that the SKILL.md file is still in the repository.
Convert PDF/EPUB textbooks to searchable markdown files for an AI agent's own reference. Use this skill whenever: (1) the user asks to convert a textbook/PDF chapter to markdown, (2) you need to search textbook content and no markdown version exists yet, (3) batch-converting a set of reference books into a knowledge base. This is a 0-token local conversion — no vision model needed.
Install
npx vskill@latest install drpwchen/textbook-to-note/textbook-to-mdSKILL.md
Textbook-to-Markdown Converter
This skill calls scripts in your clone of the textbook-to-note repo. Atinstall time, replace{REPO}below with the absolute path of the clone.
Purpose
Convert PDF or EPUB textbooks into searchable markdown that the agent can grep/read directly, eliminating the need for PDF-library extraction at every query.
Output lives outside the note vault, at the path configured by OUTPUT_DIR in shared/config.py (default ./output/), and is for the agent's consumption, not for the user's reading.
Figures are on-demand, not pre-extracted. This skill produces markdowntext only. Figures are extracted one at a time when a note needs them,via thefigure-remapskill's entrypoint (QC-gated). Do not batch-extracta whole book's figures into afigures/folder — that approach does notscale and is unnecessary since the on-demand path already handles it. Alegacyfigures/folder may exist for books converted before this design;new conversions are markdown-only.
When to use
- User explicitly asks to convert a textbook or chapter
- You need to search textbook content and want to avoid per-query PDF
re-parsing overhead
- Building up a knowledge base from a personal library of reference books
- Before starting work on a new topic, convert the relevant chapters first
Quick reference
Batch mode skips files whose markdown already exists and is newer than the source PDF. Batch-dir mode saves progress to batch_progress.json — if interrupted, re-running resumes where it stopped. --batch-dir also picks up .epub files automatically.
EPUB support
- Uses
pandoc(epub → gfm). EPUBs are reflowable, so there are no
<!-- page N --> markers; files carry a <!-- SOURCE: epub --> marker instead.
- If pandoc emits proper heading markup, that drives the chapter split. If
the EPUB is CSS-styled with no semantic headings (common), headings are rebuilt from the TOC link table + body anchors before splitting.
- Output is a folder of
chNN_*.md+full_text.md(same shape as a PDF
book) — the single-file 2nd argument is the output directory, not a .md path.
- Requires
pandoconPATH. Figures are not extracted from EPUB (the
on-demand figure flow is PDF-only).
Batch-dir features
- Recursively finds all PDFs, auto-outputs to
<OUTPUT_DIR>/{PDF_stem}/
(OUTPUT_DIR from shared/config.py; default ./output)
- Produces
full_text.md(complete with<!-- page N -->markers) plus a
chapter split
- Chapter-splitting priority: PDF bookmarks → pattern detection →
force-split (every 30 pages)
- Writes PDF bookmarks to source PDFs if none exist
- Auto-routes OCR-needed PDFs to the local OCR engine (GPU). Two
triggers: (1) a page is scan-only (near-zero extractable characters); (2) fitz-silent-failure is detected (see docs/ocr-ladder.md). Falls back to skip-with-explanation if the OCR environment is missing. Output is full_text.md with page markers, and a chapter split is attempted on the OCR'd text too (numbered-heading patterns often survive OCR); it is best-effort and simply yields no chapters when heading detection fails
Output structure
Figure-registry generation (figure_registry.json) is an optional external hook, not a shipped script — set the FIGURE_REGISTRY_SCRIPT env var to a generator script if you have one; if unset, post_convert.py skips that step.
==Conversion writes .md files only.== A figures/ subdirectory is legacy — present only on books converted before the on-demand switch. New conversions never create one; figures are pulled on demand by figure-remap.
What the converter produces
Each markdown file contains:
- Page markers:
<!-- page X -->at every page boundary, to map content
back to the source PDF
- Cleaned text: control characters removed, broken/hyphenated words
rejoined, grep-searchable
- Tables: extracted as markdown tables (a low content-cell threshold is
used to avoid discarding real tables)
- Figure/table reference markers: when the text mentions a figure or
table (Fig. 32.1, Table 31.2, etc.), an HTML comment <!-- REF: Fig. 32.1 → see PDF page X --> is inserted so the agent knows where to look in the original PDF
Searching converted textbooks
Two search methods:
1. Keyword search (grep) — exact match, 0 tokens
2. Semantic search (optional) — concept match
If you've set up the optional semantic index (LanceDB + a local embedding model — see docs/architecture.md), a textbook_search tool becomes available for concept-level queries that don't depend on exact wording.
Search strategy
- Known keyword → grep first (fastest, exact)
- Concept/topic exploration → semantic search (finds related content
even with different phrasing)
- Both → grep for precision, semantic search for coverage
Post-conversion pipeline
After converting new books, run the post-pipeline:
The pipeline does not extract figures — it only verifies page markers, refreshes index.md + figure_registry.json from whatever figures already exist, and (optionally) builds the semantic index. Figure extraction is never a batch post-step.
Missing page markers do not block indexing by design — EPUBs (reflowable) and some vector-glyph PDFs legitimately lack <!-- page N -->; the indexer handles this gracefully (page metadata = 0). After indexing, a coverage audit compares the markdown corpus against the index and auto-backfills any book that has markdown but no index rows, so every converted book ends up searchable even if a step was skipped.
Figures — do NOT batch-extract
No pre-extraction step. A whole-book batch figure dump is retired and should not be run on new books. When a note needs a figure, figure-remap extracts that single figure on demand with QC. See "Using figures in notes" below.
Chapter splitting (batch mode)
Chapter detection patterns (in priority order)
Chapter N/CHAPTER N— standardPart N/PART N— with roman numerals (Part III)Section N/SECTION N/Unit N- Numbered headings:
1 Introduction,23 Shoulder(digit + title-case
text)
Running header deduplication
Many textbooks repeat Chapter N Title as a running header on every page. Only count the first occurrence of each unique chapter number — track a seen_chapters set and skip duplicates.
Force-split rules
- No chapter breaks detected AND >200 pages → split every 30 pages
(pages_0001-0030.md)
- Single output file >500K words → re-split (likely missed chapter breaks)
Output naming
- Folder name = PDF filename without
.pdf(use an
Author_Title_Edition_Year convention)
- Chapter files:
ch01_Chapter_Title.md,ch00_Front_Matter.md - Forced splits:
pages_0001-0030.md
Quality verification
After conversion, check:
- Total words < 500 for a book → likely scanned; batch-dir auto-routes
to OCR. If it ran the text-extraction path anyway, the OCR-trigger heuristic missed and needs tuning
- Single file > 500K words → chapter detection failed, re-split needed
- 0 chars extracted from sample pages → pure scan; batch-dir handles
this automatically. Single-file mode does not auto-route — use batch-dir on a temp folder for OCR needs
- Garbled glyphs (high char count, mostly private-use-area codepoints)
→ CID-encoded font without a Unicode map; detected by the silent-failure check, auto-routes to OCR in batch-dir
Always cite with year when referencing converted content: (Author 2e, 2021), not just (Author).
Using figures in notes (on-demand)
When writing or supplementing a note that needs a figure (anatomy, classification, imaging, algorithm), extract that one figure on demand — never batch-dump a book. The markdown's <!-- REF: Fig. 5.1 → see PDF page 42 --> markers tell you which figure exists and what PDF page it's on; hand that to the gate.
On-demand workflow — single entry point
Call the figure-remap skill's public entrypoint (figure_remap.py extract — not the internal gate script). The entrypoint runs deterministic geometric matching by default and returns a stable contract:
Contract: {status: pass|fail|escalate, match_quality: exact|uncertain|failed, hard_fail, file, fig_id, reason, qc_degraded, qc_skipped} — those eight keys exactly (figures/figure_remap.py CONTRACT_KEYS; the validator raises on any extra or missing key, so branching on the engine's internal match_method is not just discouraged, it is impossible). status:fail (exit 1) is a deterministic miss — a correct refusal, not a wrong crop; fix --page, escalate to vision, or leave a <!-- TODO -->. Read the real caption to confirm the figure depicts what you intend.
On pass (exit 0), embed the --out path (result.file) in the note:
When writing a fresh note via the note-writing workflow (see workflows/note-writing.md), figure harvest is Phase 3.5 — don't call the gate manually there, the workflow does it. The manual call above is for ad-hoc figure needs outside that workflow. Full fallback ladder + per-book calibration: see the figure-remap skill.
When to include figures
- Always: anatomy diagrams, classification systems, algorithm
flowcharts, key reference images
- Skip: decorative images, author photos, generic stock photos
- Ask the user if unsure whether a figure adds value
This is the start of the file. Read the full SKILL.md on GitHub.
Security
- Security scanPassed, 95 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingskills/textbook-to-md/SKILL.md
Popularity
- Repository stars
- 104
- Repository forks
- 25
- 7-day trend score
- 23
Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/drpwchen/textbook-to-note/textbook-to-md)