KERT is a tool that generates DAISY4/EPUB3 ebooks with Media Overlay (audio synchronization) from text files. It is written in Python.
It supports extended CommonMark notation (.txt / .md), XML format (.xml), and PDF format (.pdf) as input formats.
Input file (.txt / .md / .xml)
| Text parsing & reading text generation
| TTS (text-to-speech) generates WAV
| FFmpeg converts to MP3
| Montreal Forced Aligner performs audio alignment (TextGrid generation)
| XHTML + SMIL generation & EPUB packaging
EPUB3 file (with audio synchronization)
PDF input (.pdf)
| pdfplumber: text extraction + heading detection (3 modes)
| Pillow: figure image extraction → intermediate_products/figures/
| TTS → WAV → MP3 → TextGrid (MFA) → EPUB packaging
EPUB3 file (with audio synchronization)
PDF → Markdown export (no audio):
| pdfplumber: text extraction
Markdown file (.md) ← annotate with yomikae/ruby, then reprocess as CommonMark
Installer scripts for macOS and Windows are available in the easy_installer/ folder.
See easy_installer/INSTALL_GUIDE.md to find the right installer for your OS and language.
For manual installation, follow the steps in Requirements below.
Windows: Double-click start_kert.bat in the KERT folder to launch.
macOS: Double-click start_kert.command in the KERT folder to launch.
The following window will appear:
Configure the settings in order and click the "実行 / Run" button.
- Language: Select Japanese / English (US) / Deutsch
- Input format: Select CommonMark (.txt/.md) / XML / PDF
- Processing mode: Select Single file / Folder / PDF → MD only
- (PDF only) Heading detection: Select Layout-based / Legal language / Numbered & symbol
- Path: Enter the path to the input file or folder ("参照... / Browse..." button or drag & drop onto the window also supported)
- Intermediate files: Check "中間ファイルを残す / Keep intermediate files" to retain files after processing
Progress is shown in the log area at the bottom of the window. A dialog appears upon completion.
Close the window when processing is complete (title bar close button, or Cmd+Q on macOS).
Note: Closing the window during processing immediately stops it. Partially generated EPUB files may remain.
To run from the command line (advanced):
# Windows
py -3.12 main.py
# macOS
python3 main.pyThe generated EPUB file is output to the same directory as the input file.
Filename format: {input_filename}_{mode_number}_{timestamp}.epub
- Mode number: A concatenation of the selected language, format, and processing mode numbers (e.g.,
111) - Timestamp:
YYYYMMDDHHmmssformat
Example: mybook_111_20250219143000.epub
KERT supports three input formats: extended CommonMark notation, XML format, and PDF format. A metadata file (metadata.txt) is required for all input formats.
Write in CommonMark (Markdown)-based notation in text files with .txt or .md extensions.
Use # (1 to 5) to write headings. Each heading is split into a separate page (XHTML file) within the EPUB, and the hierarchical structure is reflected in the table of contents (nav.xhtml).
# Book Title
First paragraph.
## Chapter 1
Chapter 1 content.
### Section 1
Section 1 content.#becomes the book title (h1).##and beyond are structured as chapters and sections.- Files without headings can also be processed (in which case, the title from metadata.txt is used).
| Notation | Description | Example | EPUB Display |
|---|---|---|---|
[kanji](-furigana) |
Ruby (furigana) | [kanji](-reading) |
Ruby annotation above text |
[display text](+reading) |
Alternative reading | [display](+read) |
Shows "display", reads aloud "read" |
**text** |
Bold | **important** |
important |
[text]{.underline} |
Underline | [note]{.underline} |
note |
[text]{.frame} |
Framed box | [A]{.frame} |
Text with border |
~text~ |
Subscript | H~2~O |
H2O |
^text^ |
Superscript | 10^3^ |
103 |
$formula$ |
Inline math (TeX) | $x^2 + y^2$ |
Inline MathML |
$$formula$$ |
Display math (TeX) | $$\int_0^1 x\,dx$$ |
Block MathML (centered) |
- The alternative reading notation
[display](+reading)is used when you want different display text and spoken text. - Formatting notations support nesting. Example:
[**bold underline**]{.underline}
- Place image files in the same directory as the input file, or specify a relative path.
- Images are copied to the
images/directory within the EPUB. - Supported formats: SVG, PNG, JPEG, GIF, WebP
Use GFM (GitHub Flavored Markdown) pipe table notation to create tables.
| Column 1 | Column 2 | Column 3 |
| --- | --- | --- |
| Data A | Data B | Data C |
| Data D | Data E | Data F |- The first row becomes the header row (
<th>); rows from the third onward become data rows (<td>). - The second row (
---) is the separator row that defines the number of columns. - Highlighted cell by cell. Header cells (
<th>) are also read aloud. - Formatting notations (ruby, alternative reading, bold, etc.) can be used within cells.
XML Editor: You can easily create XML format documents using the dedicated editor KERT XMLEditor. It allows you to edit schema-compliant XML through a GUI without writing code directly.
Write XML files conforming to the XML schema (resources/document_schema.xsd).
<?xml version="1.0" encoding="UTF-8"?>
<root>
<title1>Book Title</title1>
<p>A paragraph of body text.</p>
<p>The next paragraph.</p>
</root>The root element is <root>, with heading elements (title1 to title5) and paragraph elements (p) placed directly under it.
| Element | Description | Example |
|---|---|---|
<p> |
Paragraph | <p>Body text</p> |
<title1> to <title5> |
Heading (level 1-5) | <title1>Title</title1> |
<ruby yomi="reading">base text</ruby> |
Ruby | <ruby yomi="reading">kanji</ruby> |
<yomikae yomi="reading">display</yomikae> |
Alternative reading | <yomikae yomi="read">display</yomikae> |
<u> |
Underline | <u>underlined text</u> |
<g> |
Emphasis (bold) | <g>emphasized text</g> |
<frame> |
Framed box | <frame>A</frame> |
<sub> |
Subscript | <sub>2</sub> |
<sup> |
Superscript | <sup>3</sup> |
<math> |
MathML formula | <math xmlns="...">...</math> |
<table> |
Table | <table>...</table> |
<tr> |
Row | <tr>...</tr> |
<th> |
Header cell | <th>Column name</th> |
<td> |
Data cell | <td>Value</td> |
- Decoration elements can be nested. Example:
<u><g>bold underline</g></u>
<img src="photo.jpg" alt="A little bird"/>- Place image files in the same directory as the input file, or specify a relative path.
- Images are copied to the
images/directory within the EPUB. - Supported formats: SVG, PNG, JPEG, GIF, WebP
Use the <table> element to create tables.
<table>
<tr><th>Column 1</th><th>Column 2</th></tr>
<tr><td>Data A</td><td>Data B</td></tr>
<tr><td>Data D</td><td>Data E</td></tr>
</table><tr>is a row,<th>is a header cell, and<td>is a data cell.- Highlighted cell by cell.
<th>cells are also read aloud. - Decoration elements (
<ruby>,<u>, etc.) can be used within cells.
Using title1 to title5 splits the content into separate pages within the EPUB at each heading and generates a hierarchical table of contents. These correspond to CommonMark's # through #####.
<root>
<title1>Book Title</title1>
<title2>Chapter 1</title2>
<p>Chapter 1 content.</p>
<title3>Section 1</title3>
<p>Section 1 content.</p>
<title2>Chapter 2</title2>
<p>Chapter 2 content.</p>
</root>KERT extracts text and figures from PDF files and generates an EPUB or Markdown file.
Note: Only PDFs with embedded text are supported. Scanned (image-only) PDFs are not.
When processing a PDF, KERT prompts you to select one of three heading detection modes:
| Mode | Best for | Detection method |
|---|---|---|
| 1. Layout-based | Web pages, brochures, designed documents | Font size, color, background rectangles |
| 2. Legal language | Laws, regulations, contracts | Patterns such as 第n章, 第n条 |
| 3. Numbered / symbol | Reports, manuals, outlines | ■, 【...】, 1., ①, ⑴ |
resources/pdf_heading_patterns.json contains the regex patterns used for each detection mode. You can add or remove patterns by editing this file directly.
Images embedded in the PDF are automatically extracted to intermediate_products/figures/ and included in the generated EPUB. Requires Pillow (pip install Pillow).
You can export a PDF as a Markdown file (.md) without generating audio or an EPUB. The generated Markdown can be annotated with yomikae/ruby notation and then reprocessed as CommonMark input.
A text file containing bibliographic information (title, author, etc.) for the EPUB. The title is required.
- Single file input: Place
{input_filename_without_extension}_metadata.txtin the same directory as the input file.- Example:
mybook.txt->mybook_metadata.txt - Example:
document.xml->document_metadata.txt
- Example:
- Folder input: Place
{folder_name}_metadata.txtin the parent directory of the folder.- Example: folder
chapters/->chapters_metadata.txtin the parent directory
- Example: folder
A UTF-8 encoded text file with each line in key: value format.
title: Book Title
author: Author Name
contributor: Contributor
publisher: Publisher Name
rights: (C) 2026 Author Name
subject: Genre
| Key | Description | Required |
|---|---|---|
title |
Book title | Required |
author |
Author name | |
contributor |
Contributor | |
publisher |
Publisher name | |
rights |
Rights statement | |
subject |
Genre / category |
You can add EPUB accessibility information.
accessMode: textual
accessModeSufficient: textual
accessibilityFeature: index
accessibilityHazard: noFlashingHazard
accessibilityHazard: noMotionSimulationHazard
accessibilityHazard: noSoundHazard
accessibilitySummary: No special notes
For details, see the DAISY website.
KERT supports two processing modes.
Single file mode: Generates one EPUB from a single input file. Audio is combined into a single file.
Folder mode: Combines multiple files in a folder into one EPUB. Each file becomes one chapter, with individual audio files generated per file.
chapters/
+-- 01_prologue.txt -> chapter1.xhtml + chapter1.mp3
+-- 02_chapter1.txt -> chapter2.xhtml + chapter2.mp3
+-- 03_chapter2.txt -> chapter3.xhtml + chapter3.mp3
- Files are sorted in natural order by filename (numeric parts are compared as numbers).
- For CommonMark, both
.txtand.mdfiles are collected. - For XML,
.xmlfiles are collected. - Place the
_metadata.txtfor folders in the parent directory.
If you used Quick Installation: If you set up using the installer scripts in
easy_installer/, all steps in this section have already been completed except for math formula support. Only add math formula support (optional) if needed.
Python 3.12 or later is required (due to the use of X | None type hint syntax).
Montreal Forced Aligner (MFA) is used for audio-text alignment (analyzing which words correspond to which positions in the audio).
Conda is required as the runtime environment for MFA. Install Miniforge or Miniconda.
Note for Windows: KERT automatically detects the conda executable (searching PATH, the
CONDA_EXEenvironment variable, and common installation paths such as%USERPROFILE%\miniforge3). If automatic detection fails, add the CondaScriptsdirectory to your system PATH, or set theCONDA_EXEenvironment variable to the full path of conda.exe.
MFA is installed in a Conda environment. The default environment name is mfa.
# Create Conda environment and install MFA
conda create -n mfa -c conda-forge montreal-forced-aligner
conda activate mfaAfter installing MFA, download the dictionary and acoustic models for the languages you plan to use (see "Installing MFA Models" for details).
Note: During KERT execution, MFA is automatically invoked via
conda run -n mfa, so you do not need to runconda activate mfabeforehand.
The Japanese MFA model (japanese_mfa) internally uses spacy / sudachipy. After installing MFA, install the additional packages with the following commands:
conda activate mfa
pip install spacy sudachipy sudachidict_coreVOICEVOX is used for Japanese text-to-speech synthesis.
- Start the VOICEVOX engine before running KERT.
- The default connection URL is
http://localhost:50021. - The default speaker is ID 109 (Tohoku Itako).
VOICEVOX is not required if you only use English or German.
Important: VOICEVOX Terms of Use
When distributing or publishing EPUBs containing audio generated by VOICEVOX, you must review the VOICEVOX Terms of Use and the individual character terms of use. Some characters have restrictions on commercial use or require credit attribution. The default speaker in KERT is "Tohoku Itako" (ID 109). For details on the terms of use, see the Tohoku Itako official site.
Built-in OS TTS is used for English and German text-to-speech synthesis.
- macOS:
saycommand (English: Samantha, German: Anna) - Windows: Uses System.Speech.Synthesis (SAPI) via PowerShell. Automatically falls back from macOS say with the same language settings.
Note for Windows: The language pack for the target language must be installed in advance. Go to Windows Settings > Time & Language > Language, add English or German, and make sure Speech is enabled.
FFmpeg is used to convert WAV files generated by TTS to MP3.
# macOS (Homebrew)
brew install ffmpeg
# Windows (Chocolatey)
choco install ffmpegEnsure the ffmpeg command is available in your PATH.
pip install -r requirements.txtInstalled packages:
| Package | Purpose |
|---|---|
textgrid |
Reading TextGrid files generated by MFA |
saxonche |
XSLT 3.0 processor |
pdfplumber |
PDF text/image extraction |
Pillow |
PDF figure image export |
saxonche is used for XML input conversion. It is not required if you only use CommonMark or PDF input. pdfplumber and Pillow are required for PDF input. Pillow is only needed when extracting figures from PDFs.
Math formulas in TeX notation ($...$, $$...$$) in CommonMark files and MathML (<math>) in XML files are supported. The following tools are required to enable this feature.
| Tool | Purpose | Installation |
|---|---|---|
| pandoc | TeX → MathML conversion | brew install pandoc / pandoc.org |
| Node.js | Runtime for speech-rule-engine | brew install node / nodejs.org |
| speech-rule-engine | MathML → speech text | See below |
Math formula display (MathML in EPUB) works regardless of language. However, speech output (reading formulas aloud during playback) requires both speech-rule-engine and MFA to support the language.
For supported languages, see speechruleengine.org.
| KERT Language | Math Display | Math Speech |
|---|---|---|
| Japanese (ja_JP) | ✓ | ✗ Not available (as of March 2026, SRE does not support Japanese) |
| English (en_US) | ✓ | ✓ |
| Deutsch (de_DE) | ✓ | ✓ |
For Japanese input, math formulas appear as MathML in the EPUB but are not read aloud correctly. Surrounding text is processed normally.
speech-rule-engine must be installed locally in the KERT project root directory.
Important: Run
npm installfrom the KERT project root directory. Installing in a different directory will not be recognized by KERT, even though npm will not report an error.
cd /path/to/KERT # Navigate to KERT project root
npm install speech-rule-engineIf any of these tools are missing when math formulas are detected in the input file, KERT will display a warning and prompt you to abort or continue without math support.
| Language Code | Language | TTS Engine | MFA Dictionary / Acoustic Model |
|---|---|---|---|
ja_JP |
Japanese | VOICEVOX | japanese_mfa |
en_US |
English (US) | macOS say (Samantha) / Windows SAPI | english_us_arpa |
de_DE |
Deutsch | macOS say (Anna) / Windows SAPI | german_mfa |
Download the dictionary and acoustic models for the languages you plan to use.
# Japanese
conda run -n mfa mfa model download dictionary japanese_mfa
conda run -n mfa mfa model download acoustic japanese_mfa
# English (US)
conda run -n mfa mfa model download dictionary english_us_arpa
conda run -n mfa mfa model download acoustic english_us_arpa
# German
conda run -n mfa mfa model download dictionary german_mfa
conda run -n mfa mfa model download acoustic german_mfaLanguages beyond the three listed above can be supported. To add a language, follow these steps:
-
Prepare MFA models: Install the dictionary and acoustic models for the target language. See the MFA documentation for available models.
-
Add an entry to
LANGUAGE_CONFIGSincore/config.py: Use the following format:
"fr_FR": LanguageConfig(
code="fr_FR",
display_name="Fran\u00e7ais",
epub_lang="fr",
mfa_dictionary="french_mfa", # MFA dictionary model name
mfa_acoustic="french_mfa", # MFA acoustic model name
tts_engine="say", # "voicevox" or "say"
tts_voice="Thomas", # macOS say voice name (when using say)
),tts_engine: Use"voicevox"for Japanese,"say"for other languages. On Windows, specifying"say"automatically falls back to SAPI.tts_voice: The voice name for macOS say. Runsay -v '?'to list available voices.
Defines how special characters are converted for TTS/MFA audio alignment. Built-in mappings cover circle numbers (①②…), Roman numerals (Ⅰ Ⅱ…), and common brackets. You can add or override entries by editing resources/reading_map.json:
{
"〔": "",
"〕": "",
"①": "いち"
}Set a character to "" to remove it from the reading text (useful for characters MFA cannot handle). Set it to a reading string to override the built-in reading.
Defines regex patterns for each PDF heading detection mode (layout-based, legal, numbered/symbol). Edit this file to add or remove patterns to suit your document type. The visual mode thresholds (font size ratio, score thresholds) are also configurable here.
If you select "Keep intermediate files", the following are saved in the intermediate_products/ directory.
Single file mode:
| File | Content |
|---|---|
audio.txt |
Reading text passed to TTS |
audio.wav |
WAV audio generated by TTS |
audio.mp3 |
MP3 audio converted by FFmpeg |
audio.TextGrid |
Alignment information generated by MFA |
META-INF/ |
EPUB container information |
OEBPS/ |
EPUB content (XHTML, SMIL, CSS, etc.) |
Folder mode:
| File | Content |
|---|---|
work_multi/audio/ |
MP3 audio for each chapter |
work_multi/textgrid/ |
TextGrid for each chapter |
META-INF/ |
EPUB container information |
OEBPS/ |
EPUB content |
You can debug formatting conversion results and span splitting by inspecting the intermediate XHTML files.
The internal structure of the generated EPUB3 is as follows.
Single file input (with headings):
book.epub
+-- mimetype
+-- META-INF/
| +-- container.xml
+-- OEBPS/
+-- content.opf <- Package document
+-- text/
| +-- nav.xhtml <- Hierarchical table of contents
| +-- chapter1.xhtml <- # Heading 1
| +-- chapter2.xhtml <- ## Heading 2
| +-- ...
+-- smil/
| +-- chapter1.smil <- Audio synchronization info
| +-- chapter2.smil
| +-- ...
+-- audio/
| +-- audio.mp3 <- Single audio file
+-- styles/
+-- style.css <- CSS for highlight display
Folder input:
book.epub
+-- mimetype
+-- META-INF/
| +-- container.xml
+-- OEBPS/
+-- content.opf
+-- text/
| +-- nav.xhtml
| +-- chapter1.xhtml <- File 1
| +-- chapter2.xhtml <- File 2
| +-- ...
+-- smil/
| +-- chapter1.smil
| +-- chapter2.smil
| +-- ...
+-- audio/
| +-- chapter1.mp3 <- Audio for file 1
| +-- chapter2.mp3 <- Audio for file 2
| +-- ...
+-- styles/
+-- style.css
During playback, highlighted text is displayed with a yellow background using the CSS class .-epub-media-overlay-active.
To change the highlight color, edit the background-color and color values in CSS_CONTENT in epub/packaging.py.
The EPUB3 files generated by this tool have been tested in the following environments:
- Display & Media Overlay playback: Thorium Reader
- EPUB3 compliance check: Ace by DAISY
The tools/ directory contains standalone tools for preparing input files.
Splits a long CommonMark file into multiple files by heading. Useful as a preprocessing step for folder mode processing.
python tools/split_commonmark.py- Sections starting with
#(h1) are output to{original_filename}_0{extension} - Sections starting with
##(h2) are output to{original_filename}_1{extension},{original_filename}_2{extension}, ...
Replaces line breaks within paragraphs with spaces. Useful for preprocessing files where paragraphs are broken across lines, such as English text.
python tools/unwrap_lines.py- Recognizes blank lines as paragraph separators and converts line breaks within paragraphs to spaces.
- The output file has
_appended to the original filename (e.g.,input.txt->input_.txt).
A dedicated editor for creating and editing KERT XML files (.xml) through a GUI. You can create schema-compliant documents without writing XML code directly.
- Repository: https://github.com/quwano/KERT_XMLEditor
I sincerely thank the following person for their testing and valuable feedback during the development of this tool:
Tsubasa Miyazaki - Manual review and Windows testing
Kazuyuki Kuwano
See LICENSE.md.