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
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file txtui-1.0.0.tar.gz.
File metadata
- Download URL: txtui-1.0.0.tar.gz
- Upload date:
- Size: 23.8 kB
- Tags: Source
- Uploaded using 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}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5b6c2f679ce729279905964ae943f3b5005058db33d05deab78c86aa98763625
|
|
| MD5 |
fb61281738332c60e68b0d1d2b395008
|
|
| BLAKE2b-256 |
4bfb8c4052853b1f571b647cbdffa19cc1ad2c50952b4fb33d6495d764ba3d84
|
File details
Details for the file txtui-1.0.0-py3-none-any.whl.
File metadata
- Download URL: txtui-1.0.0-py3-none-any.whl
- Upload date:
- Size: 14.8 kB
- Tags: Python 3
- Uploaded using 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}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ad6d12b0adddb792327e1851d23c4d62cbafe9befff3735ba4e8cf3cd1898e79
|
|
| MD5 |
ec7c926560a88f1579e16db76bde3cb1
|
|
| BLAKE2b-256 |
9ceaf7d2e1ec8a4e74527567e0d24262c072f6336cdb5187318e021f5e1254e5
|