A small Python toolkit for building XTC ebooks.
The package has two deliberately separate layers:
- toxtc.write_xtc writes rendered Pillow images to XTC, independent of the input format.
- aozora2xtc parses Aozora Bunko text and renders it vertically.
This keeps the format writer reusable for future BMP or other image-based converters without complicating the current command.
Note: Generated XTC files have currently been tested only on Xteink X3 with CrossPoint Reader1.
- Python 3.10 or later
- A Japanese TrueType/OpenType font for aozora2xtc
uv syncConvert a text file with:
uv run aozora2xtc INPUT.txt OUTPUT.xtc --font FONT.ttfThe following commands download a Japanese font and Natsume Soseki's Ten Nights of Dreams from Aozora Bunko, then convert it to XTC:
mkdir -p .debug
curl -fL --retry 3 \
-o .debug/NotoSansJP-VF.ttf \
https://github.com/notofonts/noto-cjk/raw/main/Sans/Variable/TTF/Subset/NotoSansJP-VF.ttf
curl -fL --retry 3 \
-o /tmp/yume_juya.zip \
https://www.aozora.gr.jp/cards/000148/files/799_ruby_6024.zip
unzip -jo /tmp/yume_juya.zip yume_juya.txt -d .debug
uv run aozora2xtc .debug/yume_juya.txt .debug/yume_juya.xtc \
--font .debug/NotoSansJP-VF.ttfUse --device x3 (the default) or --device x4 to select the page size. The command detects common Japanese encodings and accepts --encoding when the input needs an explicit codec. Run uv run aozora2xtc --help for the remaining metadata and cover options.
The supported Aozora notation is intentionally limited to:
- explicit and implicit ruby
- emphasis marks
- page breaks
- large, medium, and small headings
Unknown Aozora control annotations are omitted from the rendered text.
The core already accepts Pillow images, including images loaded from BMP. Images should be resized and ordered by the caller:
from pathlib import Path
from PIL import Image
from toxtc import BookMetadata, write_xtc
with Image.open("page.bmp") as source:
page = source.copy()
write_xtc(
Path("book.xtc"),
[page],
BookMetadata(title="Example"),
)This is a library-level extension point; a dedicated image CLI is not included yet.
uv run python -m unittest discover
uv run black --check .
uv run ruff check .The XTC writer was implemented with reference to the XTC type definitions and parser behavior in CrossPoint Reader.
Additional format documentation published by the Xteink community, including material 2 3 by CrazyCoder, was also helpful during development.
This repository contains an independent Python implementation written from scratch.
MIT