Metadata-Version: 2.4
Name: txtui
Version: 0.1.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 two-level chapter outline with presets or custom regexes, 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%), with a collapsible, current-chapter-highlighting outline
- **Preset chapter matching** — 章节体 (章/节), 卷章体 (卷/章), and single-level auto-detection
- **Custom regex matching** — validate your own level-1 regex (and optional level-2), with validation feedback when it matches nothing
- **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** — config file path via `TXTUI_CONFIG_FILE`, or 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/`). |

### Environment variables

| Variable | Meaning |
|---|---|
| `TXTUI_CONFIG_FILE` | Full path to the state/config JSON file. Overrides the default `~/.local/share/txtui/state.json` (takes precedence over `--data-dir`). |

Example:

```bash
TXTUI_CONFIG_FILE=~/novels/txtui-state.json 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 level-1 regex (and optional level-2 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 |
| `space` | Collapse / expand a level-1 entry (only when it has children) |
| `enter` | Jump to the selected chapter and return to the content (level-1 entries can be entered only when there is no second level); otherwise it collapses/expands |
| `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]+卷",
        "level2_pattern": "^\\s*第[一二三四五六七八九十百千\\d]+章",
        "preset_name": "卷章体"
      },
      "chapter_index": 2,
      "line": 48,
      "last_read": 1721800000.0,
      "total_reading_time": 3600.0
    }
  }
}
```

Override its location with `TXTUI_CONFIG_FILE` or the default directory with `--data-dir`.

## Development

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

## License

MIT