txtui
A terminal (TUI) reader for .txt novels written in Python, built on Textual.
Designed for Chinese text novels: it auto-detects UTF-8/GBK encoding, helps you match a single-level chapter outline with presets or a custom regex, and remembers your reading position and time spent in each book.
Features
- Recent list — open
txtuiwith no arguments to pick a book from your reading history, sorted by most recently closed - Chapter outline — outline on the left (25%) vs. content on the right (75%), flat chapter list that highlights and auto-scrolls to the current chapter
- Preset chapter matching — 章体 (第X章), 节体 (第X节), and 自定义 (custom regex)
- Custom regex matching — validate your own regex, with feedback when it matches no chapters
- Encoding handling — auto-detects UTF-8 vs. GBK; for GBK it asks before converting the file in place to UTF-8
- Reading state — per-book position (chapter + line), timestamps, accumulated reading time, and chapter config, persisted to JSON
- Configurable location — data directory via
--data-dir
Requirements
- Python 3.10+
Installation
uv sync
Run from the checkout:
uv run txtui /path/to/novel.txt
Or install into your environment and use the txtui command:
uv pip install -e .
txtui /path/to/novel.txt
Usage
txtui [-d/--data-dir PATH] [target.txt]
| Argument | Meaning |
|---|---|
target.txt |
The novel to open. If omitted, the recent-list screen is shown. |
-d, --data-dir PATH |
Directory where the state file lives (default ~/.local/share/txtui/). |
Example:
txtui my_novel.txt
First time opening a book
- Its encoding is checked (UTF-8 first, then GBK). If it is GBK you are asked whether to convert it to UTF-8 in place.
- A full-screen preview shows the text with line numbers. You can flip pages with space, scroll lines with j/k.
- Press Enter to set up the chapter outline: choose a preset (章体/节体/自定义), or type your own regex.
- If a valid outline already exists for the book (or you finish configuring), you land in the reader.
Keybindings
Recent list
| Key | Action |
|---|---|
j / down |
Move down |
k / up |
Move up |
enter |
Open the selected book |
q |
Quit |
Chapter config screen
| Key | Action |
|---|---|
space |
Page down |
j / down |
Scroll down a line |
k / up |
Scroll up a line |
enter |
Set up the chapter outline |
q |
Quit |
Reader — content mode
| Key | Action |
|---|---|
space |
Page down |
j / down |
Scroll down a line |
k / up |
Scroll up a line |
home |
Jump to top of current chapter |
end |
Jump to bottom of current chapter |
h / left |
Previous chapter |
l / right |
Next chapter |
esc |
Focus the chapter outline |
q |
Save reading state and quit |
Reader — outline mode
Entered with esc. Press esc again to return to the content at your previous spot.
| Key | Action |
|---|---|
j / k |
Move the selection up/down |
enter |
Jump to the selected chapter and return to the content |
esc |
Back to the content view |
Dialogs
| Key | Action |
|---|---|
y / n |
Confirm / decline (e.g. the encoding-conversion prompt) |
enter |
Confirm |
esc |
Cancel |
Data layout
By default state is stored in ~/.local/share/txtui/state.json and looks like:
{
"records": {
"/abs/path/novel.txt": {
"path": "/abs/path/novel.txt",
"title": "小说名",
"encoding": "utf-8",
"chapter_config": {
"level1_pattern": "^\\s*第[一二三四五六七八九十百千\\d]+章",
"preset_name": "章体"
},
"chapter_index": 2,
"line": 48,
"last_read": 1721800000.0,
"total_reading_time": 3600.0
}
}
}
Override its location with --data-dir.
Development
uv run pytest # run the test suite
uv run python -m txtui # launch the app
License
MIT
Metadata
Release files for txtui 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| txtui-1.0.0.tar.gz | 23.8 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| txtui-1.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 38.6 kB
Release files / txtui-1.0.0.tar.gz
| Download URL | txtui-1.0.0.tar.gz |
|---|---|
| Size | 23.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
5b6c2f679ce729279905964ae943f3b5005058db33d05deab78c86aa98763625
|
|
BLAKE2b-256 checksum How to use checksums |
4bfb8c4052853b1f571b647cbdffa19cc1ad2c50952b4fb33d6495d764ba3d84
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.1 {"installer":{"name":"uv","version":"0.12.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / txtui-1.0.0-py3-none-any.whl
| Download URL | txtui-1.0.0-py3-none-any.whl |
|---|---|
| Size | 14.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
ad6d12b0adddb792327e1851d23c4d62cbafe9befff3735ba4e8cf3cd1898e79
|
|
BLAKE2b-256 checksum How to use checksums |
9ceaf7d2e1ec8a4e74527567e0d24262c072f6336cdb5187318e021f5e1254e5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.1 {"installer":{"name":"uv","version":"0.12.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Security for txtui 1.0.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.