Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Convert EPUB card books into Obsidian-ready HyperCard Markdown folders and portable zip files. Use when Codex needs to turn an EPUB with XHTML chapters, table-of-contents cards, keyword index cards, backlinks, Luhmann/Zettelkasten numbers, or cross-links into one Markdown file per card with verified relative links, keyword cards, previous/home/next navigation, and GitHub/shareable zip output.
.claude/skills/twhsi-epub-hypercard-obsidian/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-07 | ✗→✓ | ▲ Improved | -28% | 0% |
| case-09 | ✗→✓ | ▲ Improved | -39% | 0% |
| case-10 | ✗→✓ | ▲ Improved | -11% | 0% |
| case-12 | ✗→✓ | ▲ Improved | 15% | 0% |
| case-15 | ✗→✓ | ▲ Improved | -30% | 0% |
Create an Obsidian folder from an EPUB card book. Each EPUB正文 card becomes one Markdown file. The output uses the four-table HyperCard format:
Use this skill for EPUBs generated from project notes, Luhmann/Zettelkasten chunks, chapter cards, keyword index cards, or book-check editions that need to become clickable Obsidian Markdown.
Run the generator:
bashpython3 scripts/epub_to_hypercard_obsidian.py INPUT.epub --out OUTPUT_DIR --zip
Recommended portable mode:
bashpython3 scripts/epub_to_hypercard_obsidian.py INPUT.epub --out 3.4-centaur-hypercard-obsidian-portable --zip --portable
The script writes:
index.md: stack home and chapter directorycard-*.md: one正文 card per EPUB article/chapterkeyword-index.md: keyword directorykey-*.md: one keyword index card per keywordOUTPUT_DIR.zip: shareable zip, when --zip is setMETA-INF/container.xml, OEBPS/content.opf, XHTML text files, and a spine.Text/toc.xhtml or the first non-article spine item as the directory card.Text/index.xhtml or the XHTML with .index-card sections as the keyword index card.<article> as正文 HyperCards.p.code text for the card code, such as 3.4.1|113字.h1 as the visible card title.<br><br>.key-*.md.[label](file.md) to avoid Obsidian heading-anchor drift.index.xhtml sections into K001, keyword, weight, and target cards.key-*.md per keyword.[label](target.md) must resolve to a file in the output folder.[[#heading]] same-file anchors for this workflow.--portable for sharing with AI tools, GitHub, macOS Finder, Windows, or zip upload workflows.| Mode | Shape | Use | |---|---|---| | --portable | card-3-4-1.md, key-k001.md | Default recommendation for zip/GitHub/AI upload | | no --portable | 3.4.1-標題.md, K001-關鍵字.md | More human-readable inside Obsidian, less portable across zip tools |
markdown| 魯曼編號 | 卡片標題 | |---|---| | `{{code}}` | **{{title}}** | | 內容 | |---| | {{content_with_links}} | | 索引 | | | | |---|---|---|---| | {{keyword_link_1}} | {{keyword_link_2}} | {{keyword_link_3}} | {{keyword_link_4}} | | ← 上一張 | Card {{n}} / {{total}} | 下一張 → | |---|---|---| | {{previous_card}} | [Home](index.md) | {{next_card}} |
[TARS](key-k001.md).[[target|alias]] contains | and can break table columns.\|.Before finishing, run or report the script validation:
textcards: ... keywords: ... missing_links: 0 zip: ...
If missing_links is not zero, fix the generated links or parser before delivery.
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→fail | 31,050 | 16,657 | -46% | 1 | 1 | 0% | 5,768 | 1,518 | -74% | 0 | 0 | — |
case-02 | fail→fail | 31,687 | 5,991 | -81% | 1 | 1 | 0% | 4,919 | 1,382 | -72% | 0 | 0 | — |
case-03 | fail→fail | 36,026 | 4,969 | -86% | 1 | 1 | 0% | 5,728 | 1,292 | -77% | 0 | 0 | — |
case-04 | pass→pass | 7,477 | 4,637 | -38% | 1 | 1 | 0% | 1,201 | 1,859 | +55% | 0 | 0 | — |
case-05 | pass→pass | 7,084 | 5,499 | -22% | 1 | 1 | 0% | 1,229 | 1,999 | +63% | 0 | 0 | — |
case-06 | pass→pass | 9,435 | 6,202 | -34% | 1 | 1 | 0% | 1,868 | 2,328 | +25% | 0 | 0 | — |
case-07 | fail→pass | 16,905 | 4,160 | -75% | 1 | 1 | 0% | 2,469 | 1,780 | -28% | 0 | 0 | — |
case-08 | pass→pass | 10,531 | 8,118 | -23% | 1 | 1 | 0% | 1,775 | 2,379 | +34% | 0 | 0 | — |
case-09 | fail→pass | 17,804 | 4,290 | -76% | 1 | 1 | 0% | 2,797 | 1,707 | -39% | 0 | 0 | — |
case-10 | fail→pass | 14,609 | 5,565 | -62% | 1 | 1 | 0% | 2,022 | 1,792 | -11% | 0 | 0 | — |
case-11 | pass→pass | 16,549 | 3,509 | -79% | 1 | 1 | 0% | 2,377 | 1,625 | -32% | 0 | 0 | — |
case-12 | fail→pass | 12,006 | 5,112 | -57% | 1 | 1 | 0% | 1,711 | 1,969 | +15% | 0 | 0 | — |
case-17 | pass→pass | 13,989 | 4,009 | -71% | 1 | 1 | 0% | 2,259 | 1,744 | -23% | 0 | 0 | — |
case-13 | pass→pass | 8,593 | 4,083 | -52% | 1 | 1 | 0% | 1,326 | 1,707 | +29% | 0 | 0 | — |
case-14 | pass→pass | 15,014 | 4,988 | -67% | 1 | 1 | 0% | 2,230 | 1,915 | -14% | 0 | 0 | — |
case-15 | fail→pass | 11,750 | 1,738 | -85% | 1 | 1 | 0% | 1,874 | 1,304 | -30% | 0 | 0 | — |
case-16 | fail→pass | 16,932 | 3,580 | -79% | 1 | 1 | 0% | 2,681 | 1,634 | -39% | 0 | 0 | — |
case-18 | fail→pass | 10,690 | 3,739 | -65% | 1 | 1 | 0% | 1,691 | 1,712 | +1% | 0 | 0 | — |
case-19 | fail→pass | 7,871 | 2,726 | -65% | 1 | 1 | 0% | 1,211 | 1,454 | +20% | 0 | 0 | — |
case-20 | fail→pass | 15,979 | 2,600 | -84% | 1 | 1 | 0% | 2,727 | 1,482 | -46% | 0 | 0 | — |
case-21 | fail→pass | 15,544 | 2,968 | -81% | 1 | 1 | 0% | 2,264 | 1,535 | -32% | 0 | 0 | — |
case-22 | pass→pass | 14,094 | 7,923 | -44% | 1 | 1 | 0% | 2,227 | 2,463 | +11% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted, and 19 counted toward the lift figure. The other 3 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +45 percentage points is the difference between those two pass rates over the 19 comparable cases. 1 case got worse with the skill loaded, and it is included in that figure.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.