EPUB HyperCard Obsidian
Create an Obsidian folder from an EPUB card book. Each EPUB正文 card becomes one Markdown file. The output uses the four-table HyperCard format:
- Luhmann/code + card title
- Card content
- Index-card hyperlinks
- Previous/home/next navigation
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.
Quick Start
Run the generator:
python3 scripts/epub_to_hypercard_obsidian.py INPUT.epub --out OUTPUT_DIR --zip
Recommended portable mode:
python3 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 directory
card-*.md: one正文 card per EPUB article/chapter
keyword-index.md: keyword directory
key-*.md: one keyword index card per keyword
OUTPUT_DIR.zip: shareable zip, when --zip is set
Workflow
Inspect the EPUB before converting.
- Confirm it has
META-INF/container.xml, OEBPS/content.opf, XHTML text files, and a spine.
- Treat
Text/toc.xhtml or the first non-article spine item as the directory card.
- Treat
Text/index.xhtml or the XHTML with .index-card sections as the keyword index card.
- Treat XHTML files with
<article> as正文 HyperCards.
Generate Markdown card files.
- Use
p.code text for the card code, such as 3.4.1|113字.
- Use
h1 as the visible card title.
- Put body paragraphs into table 2 as one cell, separated with
<br><br>.
- Link keyword occurrences to
key-*.md.
- Keep Markdown table links as
[label](file.md) to avoid Obsidian heading-anchor drift.
Generate keyword cards.
- Parse
index.xhtml sections into K001, keyword, weight, and target cards.
- Make one
key-*.md per keyword.
- Add previous/home/next navigation across keyword cards.
Verify all links.
- Every
[label](target.md) must resolve to a file in the output folder.
- Do not rely on
[[#heading]] same-file anchors for this workflow.
- Prefer
--portable for sharing with AI tools, GitHub, macOS Finder, Windows, or zip upload workflows.
Deliver the folder and zip.
- Give the user the output folder path and zip path.
- Report card count, keyword count, and link verification result.
Filename Modes
| 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 |
Four-Table Card Contract
| 魯曼編號 | 卡片標題 |
|---|---|
| `{{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}} |
Link Rules
- Use relative Markdown file links:
[TARS](key-k001.md).
- Do not use Obsidian alias wikilinks inside tables, because
[[target|alias]] contains | and can break table columns.
- Do not use same-file heading anchors for card navigation when the user wants a folder or zip.
- Escape Markdown table pipes in extracted text as
\|.
Validation Output
Before finishing, run or report the script validation:
cards: ...
keywords: ...
missing_links: 0
zip: ...
If missing_links is not zero, fix the generated links or parser before delivery.
1---2name: epub-hypercard-obsidian3description: 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.4---56# EPUB HyperCard Obsidian78Create an Obsidian folder from an EPUB card book. Each EPUB正文 card becomes one Markdown file. The output uses the four-table HyperCard format:9101. Luhmann/code + card title112. Card content123. Index-card hyperlinks134. Previous/home/next navigation1415Use 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.1617## Quick Start1819Run the generator:2021```bash22python3 scripts/epub_to_hypercard_obsidian.py INPUT.epub --out OUTPUT_DIR --zip23```2425Recommended portable mode:2627```bash28python3 scripts/epub_to_hypercard_obsidian.py INPUT.epub --out 3.4-centaur-hypercard-obsidian-portable --zip --portable29```3031The script writes:3233- `index.md`: stack home and chapter directory34- `card-*.md`: one正文 card per EPUB article/chapter35- `keyword-index.md`: keyword directory36- `key-*.md`: one keyword index card per keyword37- `OUTPUT_DIR.zip`: shareable zip, when `--zip` is set3839## Workflow40411. Inspect the EPUB before converting.42 - Confirm it has `META-INF/container.xml`, `OEBPS/content.opf`, XHTML text files, and a spine.43 - Treat `Text/toc.xhtml` or the first non-article spine item as the directory card.44 - Treat `Text/index.xhtml` or the XHTML with `.index-card` sections as the keyword index card.45 - Treat XHTML files with `<article>` as正文 HyperCards.46472. Generate Markdown card files.48 - Use `p.code` text for the card code, such as `3.4.1|113字`.49 - Use `h1` as the visible card title.50 - Put body paragraphs into table 2 as one cell, separated with `<br><br>`.51 - Link keyword occurrences to `key-*.md`.52 - Keep Markdown table links as `[label](file.md)` to avoid Obsidian heading-anchor drift.53543. Generate keyword cards.55 - Parse `index.xhtml` sections into `K001`, keyword, weight, and target cards.56 - Make one `key-*.md` per keyword.57 - Add previous/home/next navigation across keyword cards.58594. Verify all links.60 - Every `[label](target.md)` must resolve to a file in the output folder.61 - Do not rely on `[[#heading]]` same-file anchors for this workflow.62 - Prefer `--portable` for sharing with AI tools, GitHub, macOS Finder, Windows, or zip upload workflows.63645. Deliver the folder and zip.65 - Give the user the output folder path and zip path.66 - Report card count, keyword count, and link verification result.6768## Filename Modes6970| Mode | Shape | Use |71|---|---|---|72| `--portable` | `card-3-4-1.md`, `key-k001.md` | Default recommendation for zip/GitHub/AI upload |73| no `--portable` | `3.4.1-標題.md`, `K001-關鍵字.md` | More human-readable inside Obsidian, less portable across zip tools |7475## Four-Table Card Contract7677```markdown78| 魯曼編號 | 卡片標題 |79|---|---|80| `{{code}}` | **{{title}}** |8182| 內容 |83|---|84| {{content_with_links}} |8586| 索引 | | | |87|---|---|---|---|88| {{keyword_link_1}} | {{keyword_link_2}} | {{keyword_link_3}} | {{keyword_link_4}} |8990| ← 上一張 | Card {{n}} / {{total}} | 下一張 → |91|---|---|---|92| {{previous_card}} | [Home](index.md) | {{next_card}} |93```9495## Link Rules9697- Use relative Markdown file links: `[TARS](key-k001.md)`.98- Do not use Obsidian alias wikilinks inside tables, because `[[target|alias]]` contains `|` and can break table columns.99- Do not use same-file heading anchors for card navigation when the user wants a folder or zip.100- Escape Markdown table pipes in extracted text as `\|`.101102## Validation Output103104Before finishing, run or report the script validation:105106```text107cards: ...108keywords: ...109missing_links: 0110zip: ...111```112113If `missing_links` is not zero, fix the generated links or parser before delivery.