Metadata-Version: 2.4
Name: txtui
Version: 1.0.0
Summary: A TUI text novel reader
Requires-Python: >=3.10
Requires-Dist: textual>=0.52.0
Description-Content-Type: text/markdown

# txtui

A terminal (TUI) reader for `.txt` novels written in Python, built on [Textual](https://github.com/Textualize/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 `txtui` with 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

```bash
uv sync
```

Run from the checkout:

```bash
uv run txtui /path/to/novel.txt
```

Or install into your environment and use the `txtui` command:

```bash
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:

```bash
txtui my_novel.txt
```

## First time opening a book

1. 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.
2. A full-screen preview shows the text with line numbers. You can flip pages with **space**, scroll lines with **j/k**.
3. Press **Enter** to set up the chapter outline: choose a preset (章体/节体/自定义), or type your own regex.
4. 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:

```json
{
  "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

```bash
uv run pytest          # run the test suite
uv run python -m txtui # launch the app
```

## License

MIT