API Reference

This section documents the Python API for using epub2text as a library.

Core Classes

EPUBParser

class epub2text.EPUBParser(filepath: str, paragraph_separator: str = '\n\n')[source]

Bases: object

Parse EPUB files to extract chapters and metadata.

Supports both NAV HTML (EPUB3) and NCX (EPUB2) navigation formats. Handles nested chapter structures and accurately slices content between navigation points.

__init__(filepath: str, paragraph_separator: str = '\n\n')[source]

Initialize parser with EPUB file.

Args:

filepath: Path to the EPUB file paragraph_separator: String to use between paragraphs (default: “nn”)

Raises:

FileNotFoundError: If file doesn’t exist ValueError: If file is not a valid EPUB

get_metadata() Metadata[source]

Extract metadata from EPUB.

Returns:

Metadata object with title, authors, etc.

get_chapters(include_text: bool = True) list[Chapter][source]

Extract all chapters from the EPUB using navigation.

Args:
include_text: If True, include full chapter text. If False, return only

metadata (title, id, level, char_count). Default: True.

Returns:

List of Chapter objects

extract_chapters(chapter_ids: list[str] | None = None, deduplicate_chapter_titles: bool = True, skip_toc: bool = False, include_chapter_title: bool = False) str[source]

Extract text from selected chapters.

Parameters:
  • chapter_ids – List of chapter IDs to extract. If None, extract all.

  • deduplicate_chapter_titles – If True, removes duplicate chapter titles that appear as the first line of chapter content. Default is True.

  • skip_toc – If True, skip TOC and front matter chapters. Default is False.

  • include_chapter_title – If True, includes chapter titles in the output. Default is False.

Returns:

Combined text from all selected chapters with chapter titles separated by 4 linebreaks before the title and 2 linebreaks after.

get_pages(synthetic_page_size: int = 2000, use_words: bool = False) list[Page][source]

Extract pages from the EPUB.

First attempts to use EPUB page-list navigation (original print pages). If no page-list is found, generates synthetic pages based on content.

Parameters:
  • synthetic_page_size – Size of synthetic pages in characters, or words if use_words is True. Default is 2000 characters or about 350 words.

  • use_words – If True, synthetic_page_size is interpreted as word count.

Returns:

List of Page objects.

has_page_list() bool[source]

Check if the EPUB contains a page-list navigation.

Returns:

True if page-list navigation exists, False otherwise

extract_pages(page_numbers: list[str] | None = None, deduplicate_chapter_titles: bool = True, skip_toc: bool = False) str[source]

Extract text from selected pages.

Parameters:
  • page_numbers – List of page numbers to extract. If None, extract all.

  • deduplicate_chapter_titles – If True, removes duplicate chapter titles that appear as the first line of page content. Default is True.

  • skip_toc – If True, skip pages from TOC/Introduction chapter. Default is False.

Returns:

Combined text from all selected pages with chapter titles separated by 4 linebreaks before the title and 2 linebreaks after.

inspect_package() EpubPackageInfo[source]

Return read-only package, manifest, and spine metadata.

get_spine_documents(raw: bool = True, include_byte_offsets: bool = True, include_non_linear: bool = False, include_nav_documents: bool = False) list[SourceDocument][source]

Return decoded source documents for spine items.

get_navigation() list[NavigationEntry][source]

Return structured navigation entries.

extract_structured(*, policy: ExtractionPolicy | None = None, include_raw_documents: bool = False, include_offsets: bool = True, include_inline_runs: bool = True, include_segments: bool = False, include_xhtml_fragments: bool = False, include_markdown_fragments: bool = False, markdown_flavor: Literal['commonmark', 'gfm'] | None = None, segment_mode: str = 'sentence') StructuredEpubExtraction[source]

Return a structured, loss-aware EPUB extraction model.

extract_segments(mode: str = 'sentence', *, policy: ExtractionPolicy | None = None) list[TextSegment][source]

Return structured text segments for the EPUB.

Data Models

Chapter

class epub2text.Chapter(id: str, title: str, text: str, char_count: int, parent_id: str | None = None, level: int = 0)[source]

Bases: object

Represents a single chapter or section in an EPUB.

id: str
title: str
text: str
char_count: int
parent_id: str | None = None
level: int = 0

Page

class epub2text.Page(page_number: str, text: str, char_count: int, source: PageSource, chapter_id: str | None = None, chapter_title: str | None = None)[source]

Bases: object

Represents a single page in an EPUB.

Pages can come from two sources: 1. EPUB page-list navigation (original print book pages) 2. Synthetic generation (arbitrary page size based on characters/words)

page_number: str
text: str
char_count: int
source: PageSource
chapter_id: str | None = None
chapter_title: str | None = None

PageSource

class epub2text.PageSource(*values)[source]

Bases: Enum

Source of page information.

EPUB_PAGE_LIST = 'epub_page_list'
SYNTHETIC = 'synthetic'

Metadata

class epub2text.Metadata(title: str | None = None, authors: list[str] = <factory>, publisher: str | None = None, publication_year: str | None = None, description: str | None = None, identifier: str | None = None, language: str | None = None, contributors: list[str] = <factory>, rights: str | None = None, coverage: str | None = None)[source]

Bases: object

EPUB metadata.

title: str | None = None
authors: list[str]
publisher: str | None = None
publication_year: str | None = None
description: str | None = None
identifier: str | None = None
language: str | None = None
contributors: list[str]
rights: str | None = None
coverage: str | None = None

Structured extraction

StructuredEpubExtraction

class epub2text.StructuredEpubExtraction(source_path: 'str', source_sha256: 'str', package: 'EpubPackageInfo', documents: 'list[SourceDocument]', navigation: 'list[NavigationEntry]', blocks: 'list[TextBlock]', segments: 'list[TextSegment]', diagnostics: 'list[Diagnostic]')[source]

Bases: object

source_path: str
source_sha256: str
package: EpubPackageInfo
documents: list[SourceDocument]
navigation: list[NavigationEntry]
blocks: list[TextBlock]
segments: list[TextSegment]
diagnostics: list[Diagnostic]
to_dict(*, include_raw: bool = False, include_runs: bool = True, include_segments: bool = True, include_xhtml_fragments: bool = False, include_markdown_fragments: bool = False) dict[str, Any][source]
to_json(*, include_raw: bool = False, include_runs: bool = True, include_segments: bool = True, include_xhtml_fragments: bool = False, include_markdown_fragments: bool = False, indent: int | None = None) str[source]

TextBlock

class epub2text.TextBlock(id: 'str', document_id: 'str', document_href: 'str', spine_index: 'int | None', block_index: 'int', tag_name: 'str', element_path: 'str', attrs: 'tuple[tuple[str, str], ...]', outer_char_start: 'int', outer_char_end: 'int', inner_char_start: 'int', inner_char_end: 'int', outer_byte_start: 'int | None', outer_byte_end: 'int | None', inner_byte_start: 'int | None', inner_byte_end: 'int | None', text: 'str', text_sha256: 'str', runs: 'list[ContentRun]', chapter_id: 'str | None', chapter_title: 'str | None', page_number: 'str | None', extraction_policy: 'str', diagnostics: 'list[Diagnostic]', xhtml_fragment: 'XhtmlFragment | None' = None, markdown_fragment: 'MarkdownFragment | None' = None)[source]

Bases: object

id: str
document_id: str
document_href: str
spine_index: int | None
block_index: int
tag_name: str
element_path: str
attrs: tuple[tuple[str, str], ...]
outer_char_start: int
outer_char_end: int
inner_char_start: int
inner_char_end: int
outer_byte_start: int | None
outer_byte_end: int | None
inner_byte_start: int | None
inner_byte_end: int | None
text: str
text_sha256: str
runs: list[TextRun | InlineTagRun | EntityRun]
chapter_id: str | None
chapter_title: str | None
page_number: str | None
extraction_policy: str
diagnostics: list[Diagnostic]
xhtml_fragment: XhtmlFragment | None = None
markdown_fragment: MarkdownFragment | None = None

TextSegment

class epub2text.TextSegment(id: 'str', block_id: 'str', mode: 'str', index: 'int', text: 'str', block_text_start: 'int', block_text_end: 'int', document_text_ranges: 'tuple[SourceRange, ...]', chapter_id: 'str | None', page_number: 'str | None', diagnostics: 'list[Diagnostic]', xhtml_fragment: 'XhtmlFragment | None' = None, markdown_fragment: 'MarkdownFragment | None' = None)[source]

Bases: object

id: str
block_id: str
mode: str
index: int
text: str
block_text_start: int
block_text_end: int
document_text_ranges: tuple[SourceRange, ...]
chapter_id: str | None
page_number: str | None
diagnostics: list[Diagnostic]
xhtml_fragment: XhtmlFragment | None = None
markdown_fragment: MarkdownFragment | None = None

XhtmlFragment

class epub2text.XhtmlFragment(text: 'str', xhtml: 'str', tag_skeleton: 'tuple[str, ...]', source_char_start: 'int | None', source_char_end: 'int | None', diagnostics: 'list[Diagnostic]')[source]

Bases: object

text: str
xhtml: str
tag_skeleton: tuple[str, ...]
source_char_start: int | None
source_char_end: int | None
diagnostics: list[Diagnostic]

ExtractionPolicy

class epub2text.ExtractionPolicy(block_tags: 'frozenset[str]' = frozenset({'h6', 'li', 'td', 'figcaption', 'blockquote', 'h2', 'h4', 'h1', 'th', 'h5', 'h3', 'p', 'caption', 'dt', 'dd'}), skip_tags: 'frozenset[str]' = frozenset({'head', 'noscript', 'script', 'style', 'title'}), opaque_inline_tags: 'frozenset[str]' = frozenset({'kbd', 'samp', 'tt', 'var', 'code'}), include_footnotes: 'bool' = True, include_sup_sub: 'bool' = True, normalize_whitespace: 'bool' = False, remove_duplicate_titles: 'bool' = False, include_nav_documents: 'bool' = False, include_non_linear_spine: 'bool' = False, strict_offsets: 'bool' = False, allowed_inline_fragment_tags: 'frozenset[str]' = frozenset({'em', 'rt', 'strong', 'dfn', 'rp', 'code', 'sub', 'sup', 'b', 'small', 'samp', 'a', 'data', 'cite', 'wbr', 'span', 'q', 'u', 's', 'br', 'abbr', 'var', 'kbd', 'i', 'time', 'bdo', 'ruby', 'bdi', 'mark'}), allowed_inline_fragment_attrs: 'tuple[tuple[str, frozenset[str]], ...]' = (('*', frozenset({'id', 'lang', 'dir', 'epub:type', 'class', 'title', 'xml:lang'})), ('a', frozenset({'href'})), ('span', frozenset({'id', 'lang', 'dir', 'epub:type', 'class', 'title', 'xml:lang'}))), markdown_flavor: 'MarkdownFlavor' = 'commonmark', markdown_unknown_inline: "Literal['unwrap', 'drop']" = 'unwrap', markdown_preserve_raw_html_for: 'frozenset[str]' = frozenset(), allowed_markdown_inline_tags: 'frozenset[str]' = frozenset({'em', 'rt', 'strong', 'ins', 'rp', 'code', 'dfn', 'sub', 'sup', 'small', 'b', 'samp', 'a', 'data', 'cite', 'wbr', 'span', 'q', 'u', 's', 'br', 'abbr', 'del', 'var', 'kbd', 'i', 'time', 'bdo', 'ruby', 'bdi', 'mark'}), allowed_markdown_raw_html_tags: 'frozenset[str]' = frozenset({'rt', 'ruby', 'sub', 'rp', 'sup'}), allowed_markdown_raw_html_attrs: 'tuple[tuple[str, frozenset[str]], ...]' = (('*', frozenset({'lang', 'dir', 'epub:type', 'class', 'title', 'xml:lang'})),), allowed_markdown_link_schemes: 'frozenset[str]' = frozenset({'', 'mailto', 'https', 'http'}))[source]

Bases: object

block_tags: frozenset[str] = frozenset({'blockquote', 'caption', 'dd', 'dt', 'figcaption', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'li', 'p', 'td', 'th'})
skip_tags: frozenset[str] = frozenset({'head', 'noscript', 'script', 'style', 'title'})
opaque_inline_tags: frozenset[str] = frozenset({'code', 'kbd', 'samp', 'tt', 'var'})
include_footnotes: bool = True
include_sup_sub: bool = True
normalize_whitespace: bool = False
remove_duplicate_titles: bool = False
include_nav_documents: bool = False
include_non_linear_spine: bool = False
strict_offsets: bool = False
allowed_inline_fragment_tags: frozenset[str] = frozenset({'a', 'abbr', 'b', 'bdi', 'bdo', 'br', 'cite', 'code', 'data', 'dfn', 'em', 'i', 'kbd', 'mark', 'q', 'rp', 'rt', 'ruby', 's', 'samp', 'small', 'span', 'strong', 'sub', 'sup', 'time', 'u', 'var', 'wbr'})
allowed_inline_fragment_attrs: tuple[tuple[str, frozenset[str]], ...] = (('*', frozenset({'class', 'dir', 'epub:type', 'id', 'lang', 'title', 'xml:lang'})), ('a', frozenset({'href'})), ('span', frozenset({'class', 'dir', 'epub:type', 'id', 'lang', 'title', 'xml:lang'})))
markdown_flavor: Literal['commonmark', 'gfm'] = 'commonmark'
markdown_unknown_inline: Literal['unwrap', 'drop'] = 'unwrap'
markdown_preserve_raw_html_for: frozenset[str] = frozenset({})
allowed_markdown_inline_tags: frozenset[str] = frozenset({'a', 'abbr', 'b', 'bdi', 'bdo', 'br', 'cite', 'code', 'data', 'del', 'dfn', 'em', 'i', 'ins', 'kbd', 'mark', 'q', 'rp', 'rt', 'ruby', 's', 'samp', 'small', 'span', 'strong', 'sub', 'sup', 'time', 'u', 'var', 'wbr'})
allowed_markdown_raw_html_tags: frozenset[str] = frozenset({'rp', 'rt', 'ruby', 'sub', 'sup'})
allowed_markdown_raw_html_attrs: tuple[tuple[str, frozenset[str]], ...] = (('*', frozenset({'class', 'dir', 'epub:type', 'lang', 'title', 'xml:lang'})),)

extract_epub_structure

epub2text.extract_epub_structure(filepath: str, *, include_raw_documents: bool = False, include_offsets: bool = True, include_inline_runs: bool = True, include_segments: bool = False, include_xhtml_fragments: bool = False, include_markdown_fragments: bool = False, markdown_flavor: Literal['commonmark', 'gfm'] | None = None, policy: ExtractionPolicy | None = None) StructuredEpubExtraction[source]

Bookmarks

Bookmark

class epub2text.Bookmark(chapter_index: int, line_offset: int, percentage: float, last_read: str, title: str)[source]

Bases: object

Represents a reading position bookmark.

chapter_index: int
line_offset: int
percentage: float
last_read: str
title: str
classmethod create(chapter_index: int, line_offset: int, percentage: float, title: str) Bookmark[source]

Create a new bookmark with current timestamp.

classmethod from_dict(data: dict[str, Any]) Bookmark[source]

Create a Bookmark from a dictionary.

BookmarkManager

class epub2text.BookmarkManager(bookmark_file: Path | None = None)[source]

Bases: object

Manages bookmarks for EPUB files.

__init__(bookmark_file: Path | None = None) None[source]

Initialize bookmark manager.

Args:
bookmark_file: Path to bookmark JSON file.

Defaults to ~/.epub2text/bookmarks.json

save(epub_path: str, bookmark: Bookmark) None[source]

Save bookmark for a specific EPUB file.

Args:

epub_path: Path to the EPUB file bookmark: Bookmark data to save

load(epub_path: str) Bookmark | None[source]

Load bookmark for a specific EPUB file.

Args:

epub_path: Path to the EPUB file

Returns:

Bookmark if found, None otherwise

delete(epub_path: str) bool[source]

Delete bookmark for a specific EPUB file.

Args:

epub_path: Path to the EPUB file

Returns:

True if bookmark was deleted, False if not found

list_all() dict[str, Bookmark][source]

List all bookmarks.

Returns:

Dictionary mapping file paths to bookmarks

Interactive Reader

EpubReader

class epub2text.EpubReader(content: str, chapters: list[Chapter], title: str, epub_path: str, page_size: int | None = None, show_header: bool = True, show_footer: bool = True, start_line: int = 0, start_chapter: int | None = None, bookmark_manager: BookmarkManager | None = None, width: int | None = None)[source]

Bases: object

Interactive terminal reader for EPUB content.

__init__(content: str, chapters: list[Chapter], title: str, epub_path: str, page_size: int | None = None, show_header: bool = True, show_footer: bool = True, start_line: int = 0, start_chapter: int | None = None, bookmark_manager: BookmarkManager | None = None, width: int | None = None) None[source]

Initialize the EPUB reader.

Args:

content: Full text content with chapter titles separated by 4 linebreaks chapters: List of Chapter objects title: Book title epub_path: Path to the EPUB file (for bookmarks) page_size: Lines per page (None for auto-detect) show_header: Show header with chapter title show_footer: Show footer with progress start_line: Initial line to display start_chapter: Initial chapter index to jump to bookmark_manager: Optional bookmark manager instance width: Maximum content width (None for full terminal width)

run() ReaderState[source]

Run the interactive reader.

Returns:

ReaderState with final position

ReaderState

class epub2text.ReaderState(current_line: int, chapter_index: int, percentage: float, quit_requested: bool)[source]

Bases: object

State returned when reader exits.

current_line: int
chapter_index: int
percentage: float
quit_requested: bool

Text Cleaning

TextCleaner

class epub2text.TextCleaner(remove_page_numbers: bool = True, remove_footnotes: bool = True, replace_single_newlines: bool = True, normalize_whitespace: bool = True, preserve_single_newlines: bool = False)[source]

Bases: object

Smart text cleaning with configurable options.

__init__(remove_page_numbers: bool = True, remove_footnotes: bool = True, replace_single_newlines: bool = True, normalize_whitespace: bool = True, preserve_single_newlines: bool = False)[source]

Initialize text cleaner with options.

Parameters:
  • remove_page_numbers – Remove standalone and end-of-line page numbers.

  • remove_footnotes – Remove bracketed footnote markers like [1].

  • replace_single_newlines – Replace single newlines with spaces while preserving paragraphs.

  • normalize_whitespace – Collapse multiple spaces to a single space.

  • preserve_single_newlines – Keep single newlines as paragraph separators. This overrides replace_single_newlines.

clean(text: str) str[source]

Clean text with configured options.

Args:

text: Raw text to clean

Returns:

Cleaned text

apply_gutenberg_spacing(text: str) str[source]

Apply Gutenberg Project formatting: two spaces after sentences and colons.

Args:

text: Text to format

Returns:

Text with Gutenberg spacing

calculate_length(text: str) int[source]

Calculate text length excluding chapter markers and metadata.

Args:

text: Text to measure

Returns:

Character count

clean_text

epub2text.clean_text(text: str, remove_page_numbers: bool = True, remove_footnotes: bool = True, replace_single_newlines: bool = True, normalize_whitespace: bool = True, preserve_single_newlines: bool = False) str[source]

Clean text with smart options (convenience function).

Args:

text: Raw text to clean remove_page_numbers: Remove standalone and end-of-line page numbers remove_footnotes: Remove bracketed footnote markers like [1] replace_single_newlines: Replace single newlines with spaces normalize_whitespace: Collapse multiple spaces to single space preserve_single_newlines: Keep single newlines as paragraph separators

Returns:

Cleaned text

Text Formatting

format_paragraphs

epub2text.formatters.format_paragraphs(text: str, separator: str = '  ', one_line_per_paragraph: bool = False) str[source]

Format text with paragraph separators.

This function works without phrasplit.

Args:

text: Input text with paragraph breaks (double newlines) separator: String to prepend to new paragraphs (default: “ “ two spaces) one_line_per_paragraph: If True, collapse each paragraph to single line

Returns:

Formatted text with separator at start of each new paragraph. Chapter titles (lines preceded by 4+ newlines) are preserved.

format_sentences

epub2text.formatters.format_sentences(text: str, separator: str = '  ', language_model: str = 'en_core_web_sm') str[source]

Format text with one sentence per line.

Args:

text: Input text with paragraph breaks separator: String to prepend at paragraph boundaries (default: “ “) language_model: spaCy language model to use

Returns:

Text with one sentence per line, separator at paragraph boundaries. Chapter titles are preserved.

format_clauses

epub2text.formatters.format_clauses(text: str, separator: str = '  ', language_model: str = 'en_core_web_sm') str[source]

Format text with one clause per line (split at commas).

Uses spaCy for sentence detection, then splits each sentence at commas. The comma stays at the end of each clause, creating natural pause points for text-to-speech processing.

Requires phrasplit to be installed.

Parameters:
  • text – Input text with paragraph breaks.

  • separator – String to prepend at paragraph boundaries. Default is two spaces.

  • language_model – spaCy language model to use.

Returns:

Text with one clause per line, separator at paragraph boundaries. Chapter titles are preserved.

Example:

Input: "I do like coffee, and I like wine."
Output:
    "I do like coffee,
    and I like wine."

split_long_lines

epub2text.formatters.split_long_lines(text: str, max_length: int, separator: str = '  ', language_model: str = 'en_core_web_sm') str[source]

Split lines exceeding max_length at clause/sentence boundaries.

Strategy: 1. First try to split at sentence boundaries 2. If still too long, split at clause boundaries (commas, semicolons, etc.) 3. If still too long, split at word boundaries

Args:

text: Input text (may already be formatted) max_length: Maximum line length in characters separator: Paragraph separator (preserved) language_model: spaCy language model to use

Returns:

Text with long lines split. Chapter titles are preserved.

collapse_paragraph

epub2text.formatters.collapse_paragraph(paragraph: str) str[source]

Collapse a paragraph to a single line.

Replaces internal newlines with spaces.

Args:

paragraph: Single paragraph text

Returns:

Paragraph as single line

split_paragraphs

epub2text.formatters.split_paragraphs(text: str) list[str][source]

Split text into paragraphs (separated by double newlines).

Applies preprocessing to fix hyphenated line breaks and normalize whitespace.

Args:

text: Input text

Returns:

List of paragraphs (non-empty, stripped)

Compatibility Function

epub2txt

epub2text.epub2txt(filepath: str, outputlist: bool = False, clean: bool = True, timeout: float | tuple[float, float] = (10.0, 30.0), max_bytes: int = 209715200, user_agent: str | None = None, allowed_schemes: tuple[str, ...] = ('https', 'http')) str | list[str][source]

Extract text from EPUB file (compatibility function for old epub2txt API).

Parameters:
  • filepath – Path to EPUB file or URL.

  • outputlist – If True, return list of chapter texts. If False, return a single string.

  • clean – If True, apply text cleaning. If False, use minimal processing.

  • timeout – Connection/read timeout for URL downloads, in seconds.

  • max_bytes – Maximum allowed download size for URLs.

  • user_agent – Optional User-Agent header for URL downloads.

  • allowed_schemes – Allowed URL schemes for downloads.

Returns:

Either a single string of all text when outputlist is False, or list of chapter texts when outputlist is True.

Examples:

>>> text = epub2txt("book.epub")
>>> chapters = epub2txt("book.epub", outputlist=True)
>>> raw_text = epub2txt("book.epub", clean=False)
>>> text = epub2txt("https://example.com/book.epub")

Usage Examples

Basic Usage

Parse an EPUB file and extract metadata:

from epub2text import EPUBParser

parser = EPUBParser("book.epub")

# Get metadata
metadata = parser.get_metadata()
print(f"Title: {metadata.title}")
print(f"Authors: {', '.join(metadata.authors)}")
print(f"Language: {metadata.language}")

# Get all chapters
chapters = parser.get_chapters()
for chapter in chapters:
    print(f"{chapter.title}: {chapter.char_count:,} characters")

# Extract all text
full_text = parser.extract_chapters()

Working with Pages

Extract and work with pages:

from epub2text import EPUBParser

parser = EPUBParser("book.epub")

# Check if EPUB has page-list navigation
if parser.has_page_list():
    print("EPUB contains original page numbers")

# Get pages (from page-list or generate synthetic pages)
pages = parser.get_pages(synthetic_page_size=2000, use_words=False)

for page in pages:
    print(f"Page {page.page_number}: {page.char_count} chars")
    print(f"  Source: {page.source.value}")
    print(f"  Chapter: {page.chapter_title}")

# Extract text organized by pages
page_text = parser.extract_pages(
    page_numbers=["1", "2", "3"],
    deduplicate_chapter_titles=True,
    skip_toc=True  # Skip table of contents
)

Chapter Selection

Extract specific chapters:

from epub2text import EPUBParser

parser = EPUBParser("book.epub")
chapters = parser.get_chapters()

# Extract first 3 chapters
chapter_ids = [chapters[0].id, chapters[1].id, chapters[2].id]
text = parser.extract_chapters(chapter_ids)

Custom Text Cleaning

Apply custom cleaning options:

from epub2text import EPUBParser, TextCleaner

parser = EPUBParser("book.epub")
text = parser.extract_chapters()

# Custom cleaning
cleaner = TextCleaner(
    remove_footnotes=True,
    remove_page_numbers=True,
    normalize_whitespace=True,
    replace_single_newlines=True,
)
cleaned_text = cleaner.clean(text)

Sentence Formatting

Format text with one sentence per line:

from epub2text import EPUBParser
from epub2text.formatters import format_sentences

parser = EPUBParser("book.epub")
text = parser.extract_chapters()

# One sentence per line
formatted = format_sentences(text, separator="  ")

Clause Formatting

Format text with one clause per line:

from epub2text import EPUBParser
from epub2text.formatters import format_clauses

parser = EPUBParser("book.epub")
text = parser.extract_chapters()

# One clause per line (split at commas, semicolons)
formatted = format_clauses(text, separator="  ")

Line Splitting

Split long lines at clause boundaries:

from epub2text import EPUBParser
from epub2text.formatters import split_long_lines

parser = EPUBParser("book.epub")
text = parser.extract_chapters()

# Split lines exceeding 80 characters
split_text = split_long_lines(text, max_length=80)

URL Support

Extract from EPUB files hosted online:

from epub2text import epub2txt

# Download and extract from URL
text = epub2txt("https://example.com/book.epub")

# Get list of chapters from URL
chapters = epub2txt("https://example.com/book.epub", outputlist=True)

Bookmark Management

Manage reading bookmarks:

from epub2text.bookmarks import BookmarkManager, Bookmark

# Create bookmark manager (uses ~/.epub2text/bookmarks.json)
manager = BookmarkManager()

# Save bookmark
bookmark = Bookmark.create(
    chapter_index=3,
    line_offset=150,
    percentage=45.5,
    title="My Book Title"
)
manager.save("/path/to/book.epub", bookmark)

# Load bookmark
bookmark = manager.load("/path/to/book.epub")
if bookmark:
    print(f"Resume at {bookmark.percentage:.1f}%")

# List all bookmarks
all_bookmarks = manager.list_all()
for path, bm in all_bookmarks.items():
    print(f"{bm.title}: {bm.percentage:.1f}%")

Full Metadata Access

Access all Dublin Core metadata fields:

from epub2text import EPUBParser

parser = EPUBParser("book.epub")
metadata = parser.get_metadata()

print(f"Title: {metadata.title}")
print(f"Authors: {metadata.authors}")
print(f"Contributors: {metadata.contributors}")
print(f"Publisher: {metadata.publisher}")
print(f"Publication Year: {metadata.publication_year}")
print(f"Identifier: {metadata.identifier}")
print(f"Language: {metadata.language}")
print(f"Rights: {metadata.rights}")
print(f"Coverage: {metadata.coverage}")
print(f"Description: {metadata.description}")

Module Index

epub2text

Main package exports:

  • EPUBParser - Main parser class

  • Chapter - Chapter data model

  • Page - Page data model

  • PageSource - Page source enumeration

  • Metadata - Metadata data model

  • TextCleaner - Text cleaning class

  • clean_text - Convenience function for text cleaning

  • epub2txt - Compatibility function

  • Bookmark - Bookmark data model

  • BookmarkManager - Bookmark management class

  • EpubReader - Interactive terminal reader

  • ReaderState - Reader state data model

epub2text.formatters

Text formatting utilities:

  • format_paragraphs - Format text with paragraph separators

  • format_sentences - One sentence per line formatting

  • format_clauses - One clause per line formatting

  • split_long_lines - Split long lines at clause boundaries

  • split_paragraphs - Split text into paragraph list

  • collapse_paragraph - Collapse paragraph to single line

epub2text.cleaner

Text cleaning utilities:

  • TextCleaner - Configurable text cleaner class

  • clean_text - Convenience function

  • calculate_text_length - Calculate text length excluding markers

epub2text.bookmarks

Bookmark management:

  • Bookmark - Bookmark data class

  • BookmarkManager - Bookmark persistence manager

epub2text.reader

Interactive terminal reader:

  • EpubReader - Main reader class

  • ReaderState - State information when reader exits