epubhv: turning horizontal EPUBs into vertical ones, with translation and furigana
Make your epub books vertical or horizontal.
At a glance
- What is it?
- epubhv is a Python package that rewrites EPUB books into vertical writing mode, and along the way it can convert between simplified and traditional Chinese, apply punctuation styles, add ruby annotations for Japanese and Chinese, and handle Cantonese. It works as a command line tool, a pipx one-liner, a Streamlit web app, or a library.
- Who is it for?
- epubhv suits someone reading Japanese or Chinese novels on a device that prefers vertical layout, since it handles the CSS and markup changes that make an EPUB vertical rather than horizontal, and it can add ruby and convert between simplified and traditional in the same pass. It does not suit a general EPUB processing pipeline, since the tool is built for one transformation.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 101 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
One transformation, done carefully: horizontal to vertical layout
epubhv is a Python package whose stated purpose is to make your epub books vertical or horizontal. The project description is the same line in lowercase, and the topic tags are epub, japanese-language and japanese-study.
The problem it solves is narrow but real. A Japanese novel distributed as an EPUB is normally laid out horizontally, which means the reader has to scroll sideways through paragraphs and the text runs in the wrong direction for the language. Reflowing that properly is not a matter of flipping a CSS property. The writing mode has to change, the text direction reverses, punctuation has to be repositioned for vertical setting, and the ruby annotations for furigana have to survive the transformation rather than land in the wrong place.
So the tool is a rewriter, not a renderer. It reads an EPUB, transforms the document content and the stylesheets, and writes a new EPUB out.
The naming is a bit of a puzzle until you look at the output convention, which the CLI section spells out. Running the tool on a.epub will generate a file a-v.epub that is vertical, and running it with the --h flag on b.epub will generate a file b-h.epub that is horizontal.
So the vertical and horizontal options are not two different transformations of the same book. The tool produces whichever direction you ask for, and the default is vertical, and the output filename encodes which one you got.
The licence is MIT, declared as a text field in the pyproject, the primary language is Python, and the homepage is epubhv.streamlit.app. The last push was on 2026-07-14, and the release history is sparse: v0.5.1 from January 2024, v0.3.0 from September 2023 and v0.2.0 from September 2023. The pyproject version is 0.6.0, so there is work in the tree that has not been tagged.
The CLI does the whole job in one command
The usage section is a list of invocations, and reading them together tells you the whole feature set.
epubhv a.epub # will generate a file a-v.epub that is vertical
# or
epubhv b.epub --h # will generate a file b-h.epub that is horizontal
# if you also want to translate from `简体 -> 繁体`
epubhv c.epub --convert s2t
# if you also want to translate from `繁体 -> 简体`
epubhv d.epub --h --convert t2sSo the core call is the filename, and the flags layer on top. The --convert option takes s2t or t2s for simplified to traditional and traditional to simplified Chinese, and it composes with --h, so you can ask for horizontal layout and a script conversion in one pass.
Then there is directory handling.
epubhv tests/test_epub # will generate all epub files to epub-vPoint it at a folder and it processes every EPUB inside, writing the results into an epub-v directory. That is the mode you want for a library rather than a single book.
And the punctuation and ruby options.
epubhv e.epub --convert s2t --punctuation auto
# you can add `ruby` for Japanese(furigana) and Chinese(pinyin)
epubhv e.epub --h --ruby
# if you want to learn `cantonese` 粤语
epubhv f.epub --h --ruby --cantoneseThe --punctuation option takes a style, and auto is one of the values, which means the tool can pick the punctuation convention rather than forcing you to name one. The --ruby option adds ruby annotations, and the README is specific that these are furigana for Japanese and pinyin for Chinese, which are not the same thing despite the shared term. The --cantonese option adds a third annotation form for Cantonese, and the README links the Jyutping documentation for it.
The script conversion and the ruby generation are therefore independent passes over the same text, and the CLI lets you combine them freely.
The dependency list is where the linguistics lives
The pyproject dependencies are the best evidence of what the tool actually does, because they name the linguistics rather than the layout.
For Chinese script conversion there is opencc-python-reimplemented, which is a Python reimplementation of OpenCC. The README credits @jiak94 with support for OpenCC, and the OpenCC project is the reference implementation the name comes from.
For segmentation and ruby there are three separate libraries. jieba is the Chinese word segmenter, pypinyin generates pinyin, and the Japanese side uses unidic-lite for the dictionary and fugashi for the tokeniser. Fugashi is a wrapper around the MeCab analyser, which is why a Japanese dictionary appears as a dependency at all.
For Cantonese there is ToJyutping at 3.2, which is a Cantonese romanisation library, and the README credits the ToJyutping project alongside jt-wang for the Type and PDM work.
For the document side it is lxml for XML parsing, beautifulsoup4 with soupsieve for HTML, cssutils for stylesheet manipulation, and typed-argument-parser for the command line arguments. langdetect is there for language detection, which is what lets the tool decide which ruby or pinyin treatment to apply when it is not told explicitly.
So the tool is not a layout converter with a translation bolt-on. It is a text processing pipeline that handles Chinese and Japanese script conversion, ruby annotation and romanisation, and then rewrites the EPUB so the result reads correctly in vertical mode.
The web variant adds streamlit at 1.59, and the console entry point is registered as epubhv = epubhv.cli:main, so the same code path backs both the command line and the Streamlit front end. The package is built with pdm-backend and the build includes only the epubhv package directory.
Four ways to run it, and a Streamlit app in the browser
The install section offers the usual routes and the web section offers the hosted one.
pip install epubhv
or
git clone https://github.com/yihong0618/epubhv.git
cd epubhv && bash ./setup.shFor pipx users there is a one-liner that does not install anything permanently.
pipx run epubhv a.epubAnd the web interface is a separate extra.
pip install epubhv[web]
streamlit run web.pyThe web extra installs streamlit, and the web.py file at the repository root is the Streamlit application. There is also a hosted instance at epubhv.streamlit.app, which the README offers as the first option, so the quickest way to see what the tool produces is to open a page and upload a book.
The development workflow is PDM based and worth noting because it is spelled out.
# install all dependencies
pdm install
# format code
pdm run format
# run the following scripts and make sure all pass before you start a Pull Request
pdm run allThe pdm run all target is a composite of three tasks defined in the pyproject: lint runs black in check mode, typing runs pyright, and test runs pytest with verbose output. So the same command is what you run before opening a pull request.
The pyright configuration is worth a look too. It includes the epubhv package and the tests directory, excludes a set of directories including src/experimental and src/typestubs, and excludes one specific module, epubhv/yomituki.py, which is named after the Japanese reading of the character for omission and is therefore a file whose name is not ASCII.
The typing configuration is strict in the ways that matter. reportMissingImports is on and reportMissingTypeStubs is off, so an untyped third party library is acceptable but a missing import is not.
Where epubhv is the wrong tool
The first wrong-tool case is a general EPUB processing pipeline. This tool does one transformation. If you want to convert EPUB to PDF, reflow a fixed layout book, extract the content, or fix a malformed EPUB, none of that is here, and the dependency list confirms it: there is no PDF library, no calibre-style converter and no repair logic.
The second case is a user who does not read vertically. If you read Chinese or Japanese in horizontal mode comfortably, the layout change is at best neutral and at worst an annoyance, because you have also got to accept the punctuation repositioning that vertical setting requires.
The third case is a language outside Chinese and Japanese. The script conversion handles simplified and traditional Chinese, the ruby options handle Japanese furigana, Chinese pinyin and Cantonese Jyutping, and langdetect is there to choose between them. A book in Korean or Vietnamese gets the layout treatment and none of the linguistic help, so a Vietnamese novel with Chinese quotes in it would come out with the wrong annotation.
There is a subtler limitation in the ruby path. The pinyin and furigana are generated from the text, which means they are derived from a dictionary or a segmenter rather than from an authoritative per-word reading. That is fine for a novel where the readings are predictable, and wrong wherever a character has a context-dependent reading, where a name has an irregular reading, or where a term has an established reading that a general dictionary does not know. The tool is a reading aid for a book, not a linguistic authority.
On the maintenance side, the version numbers do not line up. The release tags stop at v0.5.1 from 2024-01-02, the pyproject declares 0.6.0, and the last push was on 2026-07-14. So the pip package on PyPI is likely older than the source in the repository, and installing from git gives you code that has not been through a tagged release. Given that this is a tool whose output depends on the behaviour of several dictionary and segmenter libraries, being a few versions behind on those matters.
One more practical point is the input side. The tool takes EPUB files, and the directory mode processes everything inside tests/test_epub, which suggests the expected input is a well formed EPUB with a normal structure. A file with unusual packaging or a DRM-protected EPUB is not something the README addresses, so it is worth checking before you rely on it for a large batch.
The project is MIT licensed with a LICENSE file at the root, which permits commercial use and modification, and the author asks that you just enjoy it.
Editorial conclusion
epubhv suits someone reading Japanese or Chinese novels on a device that prefers vertical layout, since it handles the CSS and markup changes that make an EPUB vertical rather than horizontal, and it can add ruby and convert between simplified and traditional in the same pass. It does not suit a general EPUB processing pipeline, since the tool is built for one transformation. Before adopting, note that the release tags stop at v0.5.1 from January 2024 while the pyproject declares version 0.6.0, and that the ruby annotation path pulls in unidic-lite and fugashi for Japanese tokenisation and pypinyin for Chinese pinyin.
Frequently asked questions
What does epubhv do?
epubhv rewrites EPUB books into vertical writing mode, and can also produce horizontal output. It additionally converts between simplified and traditional Chinese, applies punctuation styles, and adds ruby annotations for Japanese furigana, Chinese pinyin and Cantonese.
How do I install epubhv?
Run pip install epubhv, or clone the repository and run bash ./setup.sh in it. With pipx you can run the tool without installing it, using pipx run epubhv a.epub. For the web interface, install the web extra with pip install epubhv[web] and run streamlit run web.py.
What do the epubhv command line flags do?
The --h flag produces horizontal output rather than the default vertical, --convert takes s2t or t2s for simplified and traditional Chinese conversion, --punctuation selects a punctuation style such as auto, --ruby adds furigana or pinyin annotations, and --cantonese adds Cantonese Jyutping.
Can epubhv process a whole folder of books?
Yes. Pointing the command at a directory such as tests/test_epub processes every EPUB file inside it and writes the results to an epub-v directory.
Which libraries does epubhv use for Japanese and Chinese text?
Chinese conversion uses opencc-python-reimplemented, Chinese segmentation uses jieba, pinyin comes from pypinyin, and the Japanese side uses unidic-lite for the dictionary and fugashi as the tokeniser, with ToJyutping at 3.2 handling Cantonese romanisation. langdetect is used to pick between these treatments.
What license is epubhv released under?
epubhv is released under the MIT license, declared as a text field in the pyproject with a LICENSE file at the root of the repository. The current version in the manifest is 0.6.0, and the last release tag is v0.5.1 from 2024-01-02.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/yihong0618-epubhv)Was this useful?