mirror of
https://github.com/magnus919/agent-skills.git
synced 2026-09-17 06:26:31 +03:00
Complete EPUB creation, editing, validation, and knowledge extraction skill for the Agent Skills open format. Built from spec research, real EPUB testing on 2.1MB commercial Apress title, and Apple Books compatibility verification on macOS 26. Scripts (11): epub-scaffold — Create valid EPUB3 with cover XHTML, Apple Books CSS epub-edit — Surgical editing (8 subcommands, epublib) epub-info — Structure/metadata dump as JSON epub-text — Clean text extraction, per-chapter or single-file epub-extract-knowledge — Heuristic + LLM extraction (env var auto-detect) epub-validate — EPUBCheck or Python fallback validation epub-images — List/extract all images with cover detection epub-batch — Multi-file processing (extract-text, validate, metadata) epub-convert — EPUB2→EPUB3 conversion with validation epub-repair — Diagnose & auto-fix common structural issues epub-cover — Add cover XHTML wrapper for Apple Books compatibility References (9): epub-format-internals.md, python-libraries.md, spec-and-validation.md, tutorials-and-guides.md, agent-capability-discovery.md, fixed-layout-epub.md, accessibility.md, media-overlays.md, apple-books-compatibility.md (NEW — verified on macOS 26) Test: 46/46 passing (test_epub_skill.sh)
6.4 KiB
6.4 KiB
Tutorials & Guides
Curated references for learning EPUB creation, editing, and programmatic manipulation. Organized from beginner to advanced.
Beginner: Understanding EPUB Structure
Hands-On: Unzip and Explore
The fastest way to understand EPUB internals:
# Unzip an EPUB (it's just a ZIP)
unzip book.epub -d book_unzipped/
# Explore the structure
ls -la book_unzipped/
cat book_unzipped/mimetype
cat book_unzipped/META-INF/container.xml
cat book_unzipped/OEBPS/content.opf
Interactive Tutorials
- FileFormat.com EPUB guide: https://products.fileformat.com/ebook/ — Step-by-step walkthrough of EPUB structure with diagrams
- EDRLab Readium documentation: https://github.com/readium — Reading system implementations that demonstrate EPUB processing
Intermediate: Programmatic Creation
EbookLib Tutorials
- PyPI examples: https://pypi.org/project/EbookLib/ — The most complete reference. Shows reading, writing, images, CSS, metadata.
- FileFormat.com EbookLib guide: https://products.fileformat.com/ebook/python/ebooklib/ — Step-by-step Python tutorial with code examples
- DeepWiki EbookLib architecture: https://deepwiki.com/aerkalov/ebooklib — Internal architecture overview. Useful for understanding how EbookLib models EPUB.
Creating a Minimal EPUB3 Programmatically
The minimal valid EPUB3 requires:
mimetypefile (uncompressed)META-INF/container.xmlpointing to OPFcontent.opfwith metadata + manifest + spine- At least one XHTML content document (typically
nav.xhtml) - All files zipped with
mimetypeas the first entry
See scripts/epub-scaffold in this skill for a working implementation.
Advanced: EPUB Surgery
Editing Existing EPUBs
The epublib library excels at non-intrusive editing:
from epublib import EPUB
with EPUB('book.epub') as book:
# Change metadata
book.metadata.title = 'Revised Title'
# Reorder spine
book.spine.move_item('chapter3', 0) # move to front
# Add a stylesheet
css = create_resource(css_bytes, 'Styles/dark-mode.css')
book.resources.add(resource=css)
# Inject CSS link into every document
for doc in book.documents:
link = doc.soup.new_tag('link', rel='stylesheet',
href='../Styles/dark-mode.css',
type='text/css')
doc.soup.head.append(link)
book.write('book-revised.epub')
Batch Operations
For processing multiple EPUBs:
from pathlib import Path
from ebooklib import epub
for epub_path in Path('books/').glob('*.epub'):
book = epub.read_epub(str(epub_path))
# Extract text, update metadata, etc.
Converting EPUB2 to EPUB3
Key differences to handle:
- Add
<meta property="dcterms:modified">to metadata - Create a
nav.xhtmlwith<nav epub:type="toc">section - Add
properties="nav"to the nav manifest item - Update XHTML namespace to XHTML5
- The NCX can remain for backward compatibility
Manual OPF/NCX Editing
When working with EPUB internals directly:
from xml.etree import ElementTree as ET
# Parse OPF
opf = ET.parse('content.opf')
ns = {'opf': 'http://www.idpf.org/2007/opf',
'dc': 'http://purl.org/dc/elements/1.1/'}
# Read metadata
title = opf.find('.//dc:title', ns).text
# Read manifest items
for item in opf.findall('.//opf:item', ns):
print(item.get('id'), item.get('href'), item.get('media-type'))
# Read spine order
for itemref in opf.findall('.//opf:itemref', ns):
print(itemref.get('idref'))
Validation Workflow
- Create/edit the EPUB programmatically
- Run EPUBCheck:
java -jar epubcheck.jar book.epub - Fix any errors (EPUBCheck output is quite specific)
- Re-validate
- For accessibility, also run Ace:
ace book.epub
Common Pitfalls
- mimetype compression: If
mimetypeis compressed, the EPUB is invalid. Python'szipfilecompresses by default — explicitly useZIP_STORED. - Missing manifest entries: Every file in the EPUB must be in the manifest. Images, CSS, fonts — no exceptions.
- Wrong media-type: Using
text/htmlinstead ofapplication/xhtml+xmlfor content documents. - Duplicate IDs: Manifest item
idvalues must be unique. Spineidrefvalues must match. - XHTML vs HTML: Use self-closing tags (
<br/>,<img/>), proper namespaces, and XML well-formedness. Normal HTML5 will fail validation. - Navigation order: The NAV document should be early in the spine (usually first or second, after any cover).
- EPUB3 requires NCX? No, but including an NCX improves compatibility with older reading systems.
Further Reading
- EPUB 3 Best Practices (O'Reilly): Practical guidance from EPUB practitioners
- MobileRead EPUB forum: https://www.mobileread.com/forums/forumdisplay.php?f=179 — Active community, real-world edge cases
- W3C EPUB 3 Samples: https://github.com/w3c/epub-samples — Official test EPUBs for every feature
V2 Workflows
Batch Extract Text from a Library
epub-batch extract-text "books/*.epub" --output texts/
Batch Validate a Collection
epub-batch validate "books/*.epub" --json | python3 -c "
import json, sys
data = json.load(sys.stdin)
for r in data['results']:
if r['status'] != 'valid':
print(f'{r[\"file\"]}: {r.get(\"errors\", \"?\")} errors')"
Edit Metadata Programmatically
epub-edit metadata book.epub --title "Revised Title" --author "New Author" --output revised.epub
Add a Chapter
epub-edit add-chapter book.epub --content new-chapter.xhtml --after chapter3 --output expanded.epub
Inject a Dark Theme
epub-edit inject-css book.epub --css dark-theme.css --output book-dark.epub
Convert EPUB2 to EPUB3
epub-convert old-book.epub --output old-book-v3.epub --validate
Diagnose and Repair a Broken EPUB
epub-repair broken.epub --diagnose --json # see what's fixable
epub-repair broken.epub --output fixed.epub # auto-fix
Full Pipeline: Extract Knowledge from Library
# Set LLM config once
export EPUB_LLM_URL="https://api.deepseek.com/v1"
export EPUB_LLM_KEY="sk-..."
# Batch extract text
epub-batch extract-text "books/*.epub" --output texts/
# Run knowledge extraction on each
for f in texts/*.txt; do
epub-extract-knowledge book.epub --format atoms >> knowledge.md
done