AgentSkillsCN

epub

利用Lightroom Classic收藏集生成EPUB 3.3相册。适用场景如下:(1) 在内部/epub/软件包代码中进行开发;(2) 创建或修改EPUB输出(OPF、XHTML页面、导航结构、CSS样式);(3) 排查EPUB验证错误(epubcheck);(4) 为预先分页的相册页面添加固定布局(FXL)支持;(5) 修改ZIP容器结构(mimetype、META-INF、OEBPS);(6) 处理Dublin Core元数据或呈现属性;(7) 当用户提及EPUB、相册、电子书、OPF、XHTML内容文档,或EPUB打包相关术语时。

SKILL.md
--- frontmatter
name: epub
description: "EPUB 3.3 photo book generation from Lightroom Classic collections. Use when: (1) Working on internal/epub/ package code (2) Creating or modifying EPUB output (OPF, XHTML pages, navigation, CSS) (3) Debugging EPUB validation errors (epubcheck) (4) Adding fixed-layout (FXL) support for pre-paginated photo pages (5) Modifying the ZIP container structure (mimetype, META-INF, OEBPS) (6) Working with Dublin Core metadata or rendition properties (7) User mentions epub, photo book, ebook, opf, xhtml content documents, or epub packaging"

EPUB 3.3 Photo Book Generator

Generate EPUB 3.3 photo books from Lightroom Classic collections via the Go package at internal/epub/.

EPUB 3.3 Spec Essentials

Container Structure

code
mimetype                  ← first file, uncompressed, no extra fields
META-INF/
  container.xml           ← points to OEBPS/content.opf
OEBPS/
  content.opf             ← package document
  toc.xhtml               ← EPUB 3 navigation document
  toc.ncx                 ← EPUB 2 backward compat
  styles/
    book.css
  text/
    cover.xhtml
    title.xhtml
    photo_001.xhtml ...
    map.xhtml             ← optional
  images/
    cover.jpg
    001.jpg ... NNN.jpg
    map.png               ← optional

mimetype File

Must be:

  • First entry in the ZIP archive
  • Uncompressed (stored, no deflation)
  • No extra field data in the local file header
  • Content: application/epub+zip (no trailing newline)

OPF Package Document

xml
<?xml version="1.0" encoding="UTF-8"?>
<package xmlns="http://www.idpf.org/2007/opf" version="3.0" unique-identifier="pub-id">
  <metadata xmlns:dc="http://purl.org/dc/elements/1.1/">
    <dc:identifier id="pub-id">urn:uuid:...</dc:identifier>
    <dc:title>...</dc:title>
    <dc:creator>...</dc:creator>
    <dc:language>en</dc:language>
    <meta property="dcterms:modified">2024-01-01T00:00:00Z</meta>
  </metadata>
  <manifest>
    <item id="nav" href="toc.xhtml" media-type="application/xhtml+xml" properties="nav"/>
    <item id="ncx" href="toc.ncx" media-type="application/x-dtbncx+xml"/>
    <item id="css" href="styles/book.css" media-type="text/css"/>
    <item id="cover" href="text/cover.xhtml" media-type="application/xhtml+xml"/>
    <!-- ... -->
  </manifest>
  <spine toc="ncx">
    <itemref idref="cover"/>
    <itemref idref="title"/>
    <!-- photo pages -->
  </spine>
</package>

Required metadata: dc:identifier, dc:title, dc:language, dcterms:modified.

XHTML Content Documents

All content documents must be valid XHTML5 with the EPUB namespace:

xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops"
      xml:lang="en" lang="en">
<head>
  <meta charset="UTF-8"/>
  <title>Page Title</title>
  <link rel="stylesheet" type="text/css" href="../styles/book.css"/>
</head>
<body>
  <!-- content -->
</body>
</html>

Key requirements:

  • Must include xml:lang and lang attributes on <html>
  • Use xmlns:epub for semantic inflection (epub:type)
  • Self-closing tags for void elements (<meta/>, <link/>, <img/>)
  • All attribute values must be quoted

Navigation Document (toc.xhtml)

Must contain a <nav epub:type="toc"> element. Should also include landmarks:

xml
<nav epub:type="landmarks">
  <ol>
    <li><a epub:type="cover" href="text/cover.xhtml">Cover</a></li>
    <li><a epub:type="toc" href="toc.xhtml">Table of Contents</a></li>
    <li><a epub:type="bodymatter" href="text/photo_001.xhtml">Photos</a></li>
  </ol>
</nav>

Semantic Inflection

Use epub:type for structural semantics:

  • cover — cover page
  • titlepage — title page
  • toc — table of contents
  • bodymatter — main content
  • footnote, endnote, bibliography — back matter (not used in photo books)

CSS in EPUB 3.3

Spec-Guaranteed Support

EPUB 3.3 references CSS 2.1 as the required baseline, plus specific CSS3 modules:

ModuleKey Features
CSS 2.1Selectors, box model, positioning, floats, fonts, colors
CSS Writing Modes 3writing-mode, direction, vertical text
CSS SpeechAural rendering (speak, voice-family)
CSS Fonts 3@font-face, font-feature-settings
CSS Text 3word-spacing, letter-spacing, text-transform
CSS Text Decoration 3text-decoration-color, text-decoration-style

Widely Supported (Not Spec-Guaranteed)

Major reading systems (Apple Books, Kobo, Readium, Thorium) support more CSS3 than the spec requires. These are practically safe but not guaranteed:

  • Flexbox (display: flex)
  • calc()
  • Viewport units (vw, vh, vmin, vmax)
  • object-fit, object-position
  • CSS custom properties (--var)
  • border-radius, box-shadow, opacity
  • CSS Grid (Apple Books, Readium — less universal)

Not Safe / Avoid

  • CSS animations and transitions (inconsistent support)
  • position: fixed (meaningless in paginated context)
  • position: sticky
  • Media queries beyond min-width/max-width (limited in many readers)
  • backdrop-filter
  • Container queries

Current Project CSS Approach

The stylesheet is defined in internal/epub/style.go as the bookCSS constant:

  • Georgia serif font stack
  • Responsive images: max-width: 100%, object-fit: contain
  • Cover: flexbox centering with object-fit: cover
  • Minimal spacing, white background, dark text (#333)
  • Title page: 2.2em heading, muted gray author/date

Fixed-Layout (FXL) Considerations

For pre-paginated photo pages, add to OPF metadata:

xml
<meta property="rendition:layout">pre-paginated</meta>
<meta property="rendition:spread">auto</meta>

Each FXL page needs a viewport meta tag:

xml
<meta name="viewport" content="width=1200, height=1600"/>

FXL pages use absolute positioning — CSS2.1 features are sufficient.

Project Code Structure

Files

FilePurpose
internal/epub/epub.goMain Generate() entry point, ZIP assembly, OPF/XHTML templates
internal/epub/style.goCSS stylesheet constant (bookCSS)
internal/epub/image.goResizeJPEG() — downscale with CatmullRom resampling
internal/config/config.goConfig struct with author, image size, quality settings

Config Defaults

FieldDefaultPurpose
AuthorDC creator metadata
MaxPhotoEdge1200Max long-edge pixels
JPEGQuality85Re-encode quality
MapWidth600Static map pixel width
MapHeight400Static map pixel height

Page Types Generated

  1. Cover (cover.xhtml) — full-bleed image, epub:type="cover"
  2. Title (title.xhtml) — title, summary, author, date; epub:type="titlepage"
  3. Photo (photo_NNN.xhtml) — image + optional h2 title + optional caption
  4. Map (map.xhtml) — optional static map from GPS data

Validation

Use epubcheck to validate output:

bash
# Install
brew install epubcheck

# Validate
epubcheck output.epub

Common validation errors:

  • Missing dc:language or dcterms:modified in OPF
  • mimetype file compressed or not first in ZIP
  • Missing xml:lang / lang on <html> element
  • Nav document missing epub:type="toc" nav element
  • Image referenced in OPF but not in ZIP (or vice versa)
  • Non-self-closing void elements in XHTML

Build & Test

bash
# Build the CLI
scripts/build-mac.sh

# Run Go tests
scripts/test.sh

# End-to-end test
scripts/test-e2e.sh

# Lint Go code
golangci-lint run ./...