star — Speaking Terminal Access Reader: an accessible document reader with built-in text-to-speech
Project description
⭐ star — Speaking Terminal Access Reader
Version 0.1.8 — star is an accessible, GUI-first document reader with built-in text-to-speech: it opens PDFs, Word/EPUB/PowerPoint, web pages, spreadsheets and more, reads them aloud, and highlights each word as it is spoken. Now on PyPI:
pip install star-reader(orpipx install star-reader), with automated CI testing every change across Windows, macOS, and Linux and one-command release builds. Recent reader features: document translation — translate the open document into 15 languages with no API key (Tools ▸ Translate Document,Ctrl+Shift+X); RSS / Atom feed reading — open a feed and read any article in place (File ▸ Open Feed,Ctrl+Shift+M); a difficult-word overlay — tint uncommon academic vocabulary before you read (View ▸ Reading Aids ▸ Highlight Difficult Words,Ctrl+Alt+O); andstar --deps, a one-command report of which optional dependencies are installed and how to add the rest. These join earlier work — document summarization, Anki flashcard export, spell-check in edit mode, playback-synced highlighting via in-process eSpeak-NG, batch conversion, and hot-folder watching — with the Qt GUI as the primary interface and a keyboard shortcut for every command. The keyboard-driven terminal UI remains available with--tui.
A lightweight, installable Python application that reads your documents aloud while you follow along — one pip install (or a single-file star.pyz) away, with no cloud account and no internet required.
star is an accessible document reader built for students with print disabilities. It opens PDFs, DOCX files, EPUBs, PowerPoint decks, web pages, spreadsheets, and more, then reads them aloud using your platform's built-in text-to-speech engine while highlighting each spoken word. The Qt GUI is star's primary interface — it launches by default and is where ongoing development is focused. A full-featured curses terminal interface remains available as a secondary option with --tui, for headless or text-only environments.
star was designed with graduate nursing, public health, and biomedical engineering students in mind — people who work with dense, heavily formatted documents and need a reading tool that gets out of the way. The interface is intentionally simple enough for a high school student to pick up in under five minutes, while the keyboard command set scales to the needs of power users.
star draws design inspiration from Emacspeak, Kurzweil 1000, Natural Reader, and Central Access Reader.
✨ Features
| Feature | Detail |
|---|---|
| Qt GUI (primary) | The main interface: windowed application with menu bar, toolbar, dock panels, and a keyboard shortcut for every command; launches by default when PyQt6/PyQt5 is installed |
| Terminal TUI (secondary) | Full-featured, fully keyboard-driven curses interface for headless / text-only use; force it with --tui |
| Built-in TTS | pyttsx3 (SAPI5 / NSSpeechSynthesizer / eSpeak-NG), macOS say (native, default on Mac), eSpeak-NG (in-process libespeak-ng, or CLI), DECtalk, Festival, Piper (neural, offline, free), Coqui |
| Native macOS voices | Apple system voices (incl. Eloquence US English) work out of the box with no extra packages |
| eSpeak-NG playback sync | Driven in-process via libespeak-ng (ctypes); its per-word events carry their audio position, so the highlight follows the actual audio, not a timer estimate |
| Default reading rate | 265 wpm — intentionally brisk; adjustable at runtime |
| TTS word highlighting | Spoken word highlighted live; works in both Qt and terminal modes |
| Highlight granularity | Highlight by word (default), whole sentence (less flicker), or both — Qt and TUI |
| User text highlights | Select any passage and highlight it in yellow, green, cyan, pink, or orange; persists across sessions and exports to PDF |
| Annotations / notes panel | Add tagged notes anywhere in a document via a dock panel (Qt) or pager (TUI); full-text + #tag search; persists per-document; exports to Markdown, JSON, BibTeX, or RIS |
| Citation manager | Import/export BibTeX, RIS, and CSL-JSON; link citations to notes |
| Voice dictation & transcription | Transcribe audio files and dictate notes by voice via Whisper; bundled (offline) in the self-contained Windows binary, optional from source |
| Keyboard cheat sheet | Built-in shortcut reference (? in TUI, Help → Keyboard Shortcuts in Qt); GUI/TUI bindings aligned |
| Table of Contents panel | Auto-built from document headings in Qt mode; click any entry to jump there |
| EPUB NCX / NAV navigation | Parses EPUB 2 NCX and EPUB 3 NAV documents for chapter-level navigation |
| Async document loading | Documents load in a background thread — the UI never freezes |
| Document caching | Parsed documents are cached in ~/.config/star/cache/; reopening a large file is instant |
| Markdown rendering | All documents are converted to clean Markdown for display |
| Clean TTS text | Markup is stripped before speech — no symbols read aloud |
| Math normalization | LaTeX and inline math expressions converted to natural spoken English |
| Footnote handling | Markdown / Pandoc footnotes can be read inline, deferred, or skipped |
| Code block skipping | Code fences skipped during TTS by default (configurable) |
| Speed presets | Named presets (skim/normal/study/slow) switchable at runtime |
| Bookmarks | Set named bookmarks and jump back to them; persist in settings |
| History navigation | Alt+Left / Alt+Right navigate the within-session position history |
| Document editing | Ctrl+E toggles edit mode (raw Markdown); Ctrl+S saves back to the original file |
| Table navigation | Ctrl+T / Ctrl+Shift+T jump to the next / previous table |
| Screen-reader navigation | Ctrl+H/P/T mirror NVDA/JAWS heading/paragraph/table conventions |
| Regex search | Toggle regex mode for pattern-based document search |
| Emacs-style keybindings | Full Emacs navigation plus vi-style j/k/gg/G shortcuts (TUI) |
| M-x command palette | Tab-completed command palette with persistent history (TUI) |
| Export | Save as Markdown, PDF (with highlights), BRF braille, or TTS audio from the File menu |
| Braille export | Reliable built-in Grade 1 BRF (no dependencies); contracted Grade 2 via liblouis (bundled in the self-contained Windows build) |
| Audio export | Synthesize the document to audio; defaults to WAV (no extra tools); MP3/OGG/MP4 via ffmpeg (bundled in the self-contained Windows build) |
| Subtitle export | Emit timestamped SRT / VTT captions synchronized to the speech, on their own or alongside an audio export |
| Reading statistics | Per-document time read, progress %, and session count, with totals and a most-read dashboard |
| Library / bookshelf | Searchable list of every opened document with progress and last-opened time; reopen with one click |
| Live HTML preview | Optional split-pane preview that re-renders the Markdown live while you edit |
| Voice & profile presets | Save voice, rate, theme, font, spacing, and highlight settings as named profiles; switch in one step |
| Pronunciation lexicon | User-editable term → spoken-form dictionary so drug names, anatomy, and acronyms are read correctly |
| Document translation | Translate the current document into 15 common languages from Tools → Translate Document (Google backend, no API key); optional via deep-translator |
| RSS / journal feeds | Paste a feed URL in File → Open Feed…, browse the articles, and open any one in the reader; optional via feedparser |
| Difficult-word overlay | View → Reading Aids → Highlight Difficult Words tints uncommon / academic vocabulary by word frequency so dense terms stand out before reading; optional via wordfreq |
| Dependency status report | star --deps lists every optional dependency, whether it is installed, and how to add the rest |
| Screen reader compatible | AT-SPI2 accessibility metadata; cursor parked at minibuffer (TUI) |
| Four built-in themes | dark (default), light, contrast, phosphor — all colorblind-friendly |
| CSS theme customization | Drop any .css file into the themes folder; star picks it up instantly via View → Reload CSS Themes |
| High-DPI display support | Qt GUI scales correctly on 4K and HiDPI screens |
| Font selection | Full OS font picker via View → Change Font…; defaults to an accessible sans-serif face |
| Reading level | Flesch-Kincaid grade and ease score on demand |
| Persistent settings | User preferences saved to settings.json |
--plain mode |
Extracts clean text to stdout for piping to other tools |
| Batch & hot-folder convert | Convert many files / a folder at once, or auto-convert a watched folder — from the CLI, the Qt GUI, or the TUI |
| Installable package, graceful degradation | Ships as the star package — run it with pip install, python -m star, or a single-file star.pyz. Every third-party dependency is optional and guarded, so the core runs on the standard library alone |
📦 Requirements & Installation
Minimum Python version: 3.11
star runs with nothing beyond the Python standard library. Every optional package below unlocks additional file formats or features. Install only what you need.
Easiest: install from PyPI
star is published on PyPI, so on any platform with Python 3.11+:
pipx install star-reader # isolated app install (recommended)
# or
pip install star-reader # into the current environment
Then run star (or python -m star). This pulls the GUI, TTS, and common document loaders; add optional features with extras — pip install "star-reader[all]" for everything, or individual groups such as star-reader[translate,vocab]. Run star --deps to see what's installed and what each missing piece unlocks.
From a source checkout: the installer scripts
The installer creates an isolated virtual environment (.venv) and pulls in the GUI, TTS, and common document-format packages for your platform. It never modifies your system Python unless you pass --no-venv.
# Linux / macOS
chmod +x install.sh
./install.sh # recommended: GUI + TTS + common formats
./install.sh --all # every optional package
./install.sh --minimal # GUI + TTS only
# Windows (PowerShell)
powershell -ExecutionPolicy Bypass -File .\install.ps1
powershell -ExecutionPolicy Bypass -File .\install.ps1 -Profile all
The scripts also add the platform-specific pieces automatically — pyobjc on macOS (so pyttsx3 can drive Apple voices) and windows-curses on Windows (for --tui mode) — and tell you which optional external tools (ffmpeg, tesseract) are missing and what they're for.
Install from the wheel (macOS / Linux / Windows)
A single pure-Python wheel (star_reader-<version>-py3-none-any.whl) installs star and its star command into any environment — no per-platform build required. Build it once with python -m build --wheel (output lands in dist/), then copy that one file anywhere and:
# Recommended dependencies (Qt GUI + TTS + common formats) come with the wheel
pip install star_reader-0.1.8-py3-none-any.whl
# Or pull in every optional Python feature (OCR, ODT/XLSX, Pandoc, Braille,
# transcription, audio conversion):
pip install "star_reader-0.1.8-py3-none-any.whl[all]"
The wheel then exposes a star console command and python -m star:
star # launch the Qt GUI
star document.pdf # open a file
star --tui # force the terminal UI
Extras let you install exactly what you need: [ocr], [formats], [markup], [braille], [audio], [transcribe], [watch], or [all].
The wheel covers the Python side. The native engines below (ffmpeg, Tesseract, liblouis, Pandoc, eSpeak-NG) are not Python packages; on macOS/Linux install them from your system package manager —
python tools/install_native.pydoes this for you (see External Binary Dependencies).
Single-file build: star.pyz
For a build that needs no pip install step at all, star can be packaged as a
"fat" zipapp: one file, star.pyz, that bundles star together with its Python
dependencies (the [all] extras group). Build it on the same platform you intend
to run it on:
python build_zipapp.py # output: dist/star.pyz
Run it with any Python interpreter:
starz # launch the Qt GUI
starz document.pdf # open a file
starz --tui # force the terminal UI
On first run, star.pyz extracts its bundled packages into your per-user config
directory (the same place star keeps its settings and document cache) and then
starts normally; later runs reuse that extracted copy.
What the fat zipapp does and does not remove:
- It removes the dependency-install step — you do not need to
pip installstaror its Python packages separately. - It does not bundle the external engines (ffmpeg, Tesseract, liblouis,
eSpeak-NG, DECtalk). Those still have to be on your
PATHfor the features that use them (see External Binary Dependencies). - Because it bundles compiled packages (PyQt6, PyMuPDF),
star.pyzis platform-specific: a file built on Linux runs only on Linux, one built on Windows only on Windows, and so on. Build a separatestar.pyzfor each platform you target.
How it differs from the self-contained Windows star.exe: the PyInstaller
star.exe additionally bundles the external engines above (plus Whisper and a
speech-recognition model), so it runs on a clean Windows machine with nothing
preinstalled. star.pyz is lighter, but it still relies on both a Python
interpreter and the external engines already being present — it only removes the
Python dependency-install step, not the system-dependency story.
Optional Packages
| Package | Purpose | Install |
|---|---|---|
PyQt6 or PyQt5 |
Qt GUI (default mode; highly recommended) | pip install PyQt6 |
pyttsx3 |
TTS via SAPI5 (Windows), NSSpeechSynthesizer (macOS), eSpeak-NG (Linux); gives accurate word-boundary highlighting | pip install pyttsx3 |
pyobjc |
macOS only — required for pyttsx3 to drive Apple voices (not needed for the built-in say backend) |
pip install pyobjc |
pdfminer.six |
PDF text extraction (text-layer PDFs) | pip install pdfminer.six |
pytesseract |
OCR for scanned/image PDFs and standalone image files | pip install pytesseract |
pymupdf |
PDF page rendering required by pytesseract | pip install pymupdf |
python-docx |
Microsoft Word DOCX support | pip install python-docx |
python-pptx |
PowerPoint PPTX support | pip install python-pptx |
odfpy |
OpenDocument ODT support | pip install odfpy |
openpyxl |
Excel XLSX spreadsheet support | pip install openpyxl |
pypandoc |
Pandoc conversion for formats without a native loader | pip install pypandoc |
louis |
Optional contracted Grade 2 Braille (Grade 1 BRF export is built in and needs nothing) | pip install louis |
pydub |
Audio format conversion fallback (MP3 / OGG / MP4) when ffmpeg is absent | pip install pydub |
openai-whisper or faster-whisper |
Speech recognition for audio transcription and voice dictation of notes | pip install openai-whisper |
sounddevice + numpy |
Microphone capture for voice dictation (transcription of files needs only Whisper) | pip install sounddevice numpy |
windows-curses |
Windows terminal (curses) support for --tui mode |
pip install windows-curses |
watchdog |
Hot-folder watching (--watch / GUI Watch Folder); falls back to directory polling if absent |
pip install watchdog |
sumy |
Extractive document summarization (Tools ▸ Summarize Document) | pip install sumy |
genanki |
Anki flashcard (.apkg) export (File ▸ Export ▸ Anki Flashcards) |
pip install genanki |
pyspellchecker |
Spell checking in edit mode (Edit ▸ Check Spelling) | pip install pyspellchecker |
External Binary Dependencies
Self-contained Windows binary: since v.0.1.3, the portable
star.exebundles ffmpeg, the Tesseract engine + English data, liblouis + tables, Pandoc, the DECtalk engine (DECtalk.dll+ dictionary), and eSpeak-NG (libespeak-ng.dll+ data, driven in-process via ctypes for playback-synced word highlighting), and Whisper (with PyTorch and thebasespeech-recognition model) for offline voice dictation & transcription, so none of the tools below need to be installed on the target machine.
macOS / Linux: these engines come from your system package manager. Run
python tools/install_native.pyto install whatever is missing (ffmpeg, Tesseract + English data, liblouis, Pandoc, and eSpeak-NG on Linux) via Homebrew / apt / dnf / pacman / zypper. Add--dry-runto preview the commands or name specific engines (e.g.python tools/install_native.py ffmpeg pandoc).
- Tesseract — required by
pytesseractfor OCR. Download from github.com/tesseract-ocr/tesseract or install via your system package manager. (Bundled in the self-contained Windows build.) - liblouis — only for contracted Grade 2 Braille; Grade 1 BRF export is built in and needs nothing. (Bundled in the self-contained Windows build.)
- eSpeak-NG — the eSpeak voice. (The self-contained Windows build bundles
libespeak-ng.dll+ data and drives it in-process via ctypes for playback-synced highlighting.) On macOS/Linux, install eSpeak-NG from your package manager;starloads the systemlibespeak-ngin-process when present, or falls back to theespeak-ngCLI. See TTS Backends. - DECtalk — the self-contained Windows build drives
DECtalk.dllin-process (no setup needed). Otherwise setDECTALK_BINto the path of adtalk/dectalkCLI, or install system DECtalk. Source: github.com/dectalk/dectalk. (Bundled in the self-contained Windows build.) - Pandoc — optional fallback for exotic formats. See pandoc.org. (Bundled in the self-contained Windows build.)
- ffmpeg — needed for audio export (MP3, OGG, MP4). WAV export works without it. Download from ffmpeg.org or install via your package manager (
sudo apt install ffmpeg,brew install ffmpeg). (Bundled in the self-contained Windows build.)
Platform Notes
| Platform | Notes |
|---|---|
| Linux | curses is built into the standard library. No extra terminal package needed. |
| macOS | curses is built in. Native speech works out of the box via the say command (Apple voices incl. Eloquence). For pyttsx3 word-callback highlighting, also pip install pyobjc pyttsx3. |
| Windows | TUI mode requires windows-curses (pip install windows-curses). The Qt GUI works without it. |
Quick Install
# Recommended: Qt GUI + PDF + DOCX + TTS
pip install PyQt6 pyttsx3 pdfminer.six python-docx python-pptx
# Add OCR support for scanned PDFs and image files
pip install pytesseract pymupdf
# Windows TUI mode
pip install windows-curses
# Everything
pip install PyQt6 pyttsx3 pdfminer.six pytesseract pymupdf python-docx python-pptx odfpy openpyxl pypandoc louis pydub windows-curses
▶️ Running
star # launch Qt GUI (default when PyQt6/PyQt5 is installed)
star document.pdf # open a PDF in the Qt GUI
star https://example.com # fetch and read a URL
star notes.md # open a Markdown file
star --tui report.docx # force terminal UI mode
star --plain paper.pdf # extract clean text to stdout (no UI)
star --rate 200 book.epub # open with a slower reading speed
star --theme contrast # start with the high-contrast theme
star --list-themes # print available theme names and exit
star --list-voices # list available TTS voices and exit
star --keytest # open the key-code diagnostic tool (TUI)
The star command is provided by the wheel and the installer scripts. Running from a source checkout instead? Use python -m star … (or python run_star.py …) with the same arguments.
Default mode: The Qt GUI is star's primary interface — it opens automatically when PyQt6/PyQt5 is installed. Without Qt, star falls back to the secondary terminal TUI; use --tui to force the terminal interface even when Qt is available.
🖥️ Screen Layout
Qt GUI
┌──────────────────────────────────────────────────────────────────────────────┐
│ File Highlight View │ ← menu bar
├─────┬────────────────────────────────────────────────────────────────────── │
│ │ [Open] [Play/Pause ▶⏸] [Stop ■] [+ Speed] [− Speed] [SC ○] [Voice…] │ ← toolbar
│ ToC │ [Theme] [Help] [Quit] [Copy] [Level] [Highlight] │
│ ├────────────────────────────────────────────────────────────────────────│
│ Ch1 │ │
│ Ch2 │ # Chapter 1: Introduction │ ← document
│ Ch3 │ │ view
│ ... │ This paragraph is being read aloud. The [current] │ ← TTS word
│ │ word is shown with a cyan background highlight. │ highlight
│ │ │
│ │ ════════════════════════════════════════ │
│ │ │
├─────┴────────────────────────────────────────────────────────────────────────│
│ ▶ "word" — 42% — 265 wpm │ ← status bar
└──────────────────────────────────────────────────────────────────────────────┘
Terminal TUI
┌──────────────────────────────────────────────────────────────────────┐
│ star │ Document Title ▶ Speaking 265 wpm pyttsx3 │ ← title bar
├──────────────────────────────────────────────────────────────────────┤
│ │
│ # Chapter 1: Introduction │ ← document
│ ══════════════════════ │ view
│ │
│ This paragraph is being read aloud. The [current] │ ← word
│ word is shown with a cyan background highlight. │ highlight
│ │
│ ▼ │ ← scroll
├──────────────────────────────────────────────────────────────────────┤
│ Document Title Line 42/380 11% │ ← status bar
│ Space:read/pause ↑↓:scroll Ctrl-O:open Ctrl-F:search │ ← key hints
│ M-x/F2:command F1:help q:quit │
│ M-x: open█ │ ← minibuffer
└──────────────────────────────────────────────────────────────────────┘
TUI Regions
Title bar — Application name, document title, TTS status (▶ / ‖ / ■), reading rate, and active backend.
Document view — Main reading area. Rendered as formatted Markdown. Scrolls automatically to track the spoken word.
Word highlight — Currently spoken word highlighted with a distinct background. The cursor does not move here — it stays at the minibuffer so screen readers are not disrupted.
Status bar — Document title, current line, total lines, and scroll percentage.
Key hints — Two-line quick-reference for the most common keybindings. Always visible.
Minibuffer — Input area for file paths, search queries, M-x commands, and all interactive prompts. Terminal cursor always parked here.
⌨️ Keyboard Shortcuts
Both interfaces share the same navigation philosophy — single-letter or Ctrl+letter shortcuts follow NVDA / JAWS browse-mode conventions so screen-reader users have the same muscle memory in both modes.
Every Qt GUI menu item has a keyboard shortcut. The shortcut is shown next to each command in its menu, and the full set is listed below (and in Help → Keyboard Shortcuts,
F3). Each binding is owned by exactly one action, so there are no “ambiguous shortcut” conflicts. Any binding can be remapped from Help → Customize Shortcuts… (Ctrl+Alt+Q).Modifier scheme:
Ctrl+letter= forward / primary action,Ctrl+Shift+letter= backward / secondary,Alt+punctuation= sentence navigation, andCtrl+Alt+letter= exports, citations, tools, and reading aids.
Play / pause with the Ctrl key (JAWS habit)
Tapping (pressing and releasing) the Ctrl key on its own toggles speech, mirroring the JAWS muscle memory of hitting Ctrl to silence speech. Using Ctrl as a modifier in a chord (Ctrl+O, Ctrl+H, …) never triggers it — only a clean solo tap does. It is active while the document view has focus and can be turned off with the qt_ctrl_pause setting.
Playback (both modes)
| Action | Qt GUI | TUI |
|---|---|---|
| Play / pause | Space · tap Ctrl |
Space |
| Stop | Esc |
Esc |
| Speed up (+20 wpm) | Ctrl+= |
+ |
| Slow down (−20 wpm) | Ctrl+- |
- |
| Play from cursor / selection | Ctrl+Return |
— |
| Choose TTS engine | Ctrl+Shift+G |
M-x tts-backend |
| Choose voice | Ctrl+Shift+V |
Ctrl+T |
| Pronunciation lexicon | Ctrl+Shift+I |
M-x pron-add / pron-list |
| Speech Cursor mode | Tab |
Tab |
| Toggle SSML prosody | Ctrl+Alt+Y |
M-x ssml |
| Cycle speed preset | F8 |
F8 |
The default reading rate is 265 wpm. New users should start at 150–180 wpm and increase gradually.
Profiles (saved setting bundles)
| Action | Qt GUI | TUI |
|---|---|---|
| Save current settings as a profile | Ctrl+Shift+K |
M-x profile-save <name> |
| Load a profile | Ctrl+Shift+J |
M-x profile-load <name> |
| Delete a profile | Ctrl+Shift+Y |
M-x profile-delete <name> |
| List profiles | Profiles menu | M-x profile-list |
Structure navigation (both modes)
Keys are shared between the Qt GUI and the TUI. The TUI also accepts the legacy bracket keys as fallbacks.
| Action | Qt GUI | TUI |
|---|---|---|
| Next heading (reads aloud) | Ctrl+H |
h > } (legacy) |
| Previous heading (reads aloud) | Ctrl+Shift+H |
< { (legacy) |
| Next paragraph | Ctrl+P |
p Ctrl+P ] (legacy) |
| Previous paragraph | Ctrl+Shift+P |
P [ (legacy) |
| Replay paragraph | Ctrl+R |
r Ctrl+R |
| Next table | Ctrl+T |
t |
| Previous table | Ctrl+Shift+T |
T |
| Next sentence | Alt+. |
. |
| Previous sentence | Alt+, |
, |
| Replay sentence | Alt+; |
; |
| Play from cursor / selection | Ctrl+Return |
— |
Scroll navigation (TUI)
| Key | Action |
|---|---|
↑ / k |
Scroll one line up |
↓ / j |
Scroll one line down |
PgUp / b |
Page up |
PgDn |
Page down |
Home |
Jump to beginning of document |
End |
Jump to end of document |
H |
History: go back to previous position |
L |
History: go forward |
File & export
| Action | Qt GUI | TUI |
|---|---|---|
| Open a file | Ctrl+O |
Ctrl+O |
| Open a URL | Ctrl+Shift+O |
M-x open-url |
| Library / Bookshelf | Ctrl+Shift+B |
M-x library |
| Export as Markdown | Ctrl+Alt+M |
M-x export-markdown |
| Export as PDF | Ctrl+Alt+P |
— |
| Export as Braille (BRF) | Ctrl+Alt+B |
M-x export-braille |
| Export as Audio | Ctrl+Alt+A |
M-x export-audio |
| Export Subtitles (SRT/VTT) | Ctrl+Alt+U |
M-x export-subtitles |
| Reload document | — | F9 |
| Quit | Ctrl+Q |
Ctrl+Q q |
Editing (Qt GUI only)
| Key | Action |
|---|---|
Ctrl+E |
Toggle edit mode (raw Markdown ↔ rendered view) |
Ctrl+S |
Save in edit mode; export as Markdown in read mode |
Ctrl+Shift+L |
Toggle the live HTML preview pane (enters edit mode if needed) |
Ctrl+Z / Ctrl+Y |
Undo / redo |
Ctrl+X / Ctrl+C / Ctrl+V |
Cut / copy / paste |
Ctrl+C |
Copy selection or current paragraph (read mode) |
Search
| Action | Qt GUI | TUI |
|---|---|---|
| Search forward | Ctrl+F |
Ctrl+F / |
| Search backward | — | Ctrl+R ? |
| Next match | — | n |
| Previous match | — | N |
| Clear search | Esc |
Esc C-g |
All matches are highlighted: current match in magenta, others in blue.
View & reading aids
| Action | Qt GUI | TUI |
|---|---|---|
| Cycle color theme | F5 |
F5 |
| Choose theme by name | Ctrl+Alt+T |
M-x theme <name> |
| Reload CSS themes | Ctrl+Shift+R |
— |
| Open themes folder | Ctrl+Shift+F |
— |
| Toggle Contents panel | Ctrl+\ |
— |
| Toggle Notes panel | Ctrl+Shift+N |
M-x annotations-list |
| Change font | Ctrl+Alt+F |
— |
| Text spacing | Ctrl+Alt+W |
— |
| Tune karaoke highlight | Ctrl+Alt+K |
— |
| Highlight granularity (word/sentence/both) | Ctrl+Alt+K (dialog) |
M-x highlight-granularity |
| Dyslexia-friendly font | Ctrl+Alt+X |
— |
| Bionic reading | Ctrl+Alt+J |
— |
| Current-line highlight | Ctrl+Alt+L |
— |
| Live HTML preview (edit mode) | Ctrl+Shift+L |
— |
| Show reading level | Ctrl+L |
M-x reading-level |
| Toggle line numbers | — | F6 |
| Toggle syntax highlight | — | F7 |
Highlights (Qt GUI)
| Action | Shortcut |
|---|---|
| Highlight selection — Yellow / Green / Cyan / Pink / Orange | Ctrl+Shift+1 … Ctrl+Shift+5 |
| Clear all highlights | Ctrl+Shift+0 |
Notes / annotations
| Action | Qt GUI | TUI |
|---|---|---|
| Add note at cursor | Ctrl+Shift+A |
a M-x annotate |
| Edit selected note | Ctrl+Shift+E |
M-x annotation-goto |
| Delete selected note | Ctrl+Shift+D |
M-x annotation-delete |
| Toggle Notes panel | Ctrl+Shift+N |
M-x annotations-list |
| Export notes | Ctrl+Alt+N |
M-x annotations-export |
Citations (Qt GUI)
| Action | Shortcut |
|---|---|
| Import citations | Ctrl+Alt+I |
| Export citations | Ctrl+Alt+E |
| Add citation | Ctrl+Alt+C |
| Add citation by DOI | Ctrl+Alt+D |
| Insert citation at cursor | Ctrl+Alt+R |
| Manage / browse citations | Ctrl+Alt+G |
Tools & help
| Action | Qt GUI | TUI |
|---|---|---|
| Transcribe audio file | Ctrl+Alt+S |
— |
| Dictate note (record) | Ctrl+Alt+V |
— |
| Toggle transcript timestamps | Ctrl+Alt+Z |
— |
| Reading statistics | Ctrl+Shift+S |
M-x reading-stats |
| Clear document cache | Ctrl+Shift+Delete |
M-x cache-clear |
| Command palette | F2 |
F2 M-x : |
| Keyboard cheat sheet | F3 |
M-x shortcuts ? |
| Customize shortcuts | Ctrl+Alt+Q |
— |
| Open README.md (help) | F1 |
F1 |
| About star | Ctrl+F1 |
M-x about |
Highlighting (Qt GUI)
| Action | How |
|---|---|
| Highlight selection in yellow | Ctrl+H toolbar button or Highlight menu |
| Choose highlight color | Highlight menu (yellow / green / cyan / pink / orange) |
| Clear all highlights | Clear Highlights toolbar button or Highlight menu |
Annotations / Notes (Qt GUI)
| Action | Shortcut |
|---|---|
| Add note at cursor / selection | Ctrl+Shift+A |
| Toggle the Notes panel | Ctrl+Shift+N |
| Navigate to a note | Single-click / Enter in the Notes panel |
| Read aloud from a note | Double-click in the Notes panel |
| Edit / delete / export notes | Notes menu or the panel's buttons |
M-x Command Palette (TUI)
| Key | Action |
|---|---|
M-x / ESC x / F2 / : |
Open the command palette |
Tab |
Cycle through completions |
↑ / ↓ |
Browse command history |
Enter |
Execute the current command |
C-g / Esc |
Cancel |
All standard Emacs line-editing keys work inside the minibuffer (C-a, C-e, C-f, C-b, C-d, C-k, C-u, C-w, C-y, etc.).
🅼 M-x Commands
These are the commands of the secondary terminal UI, opened with M-x, F2, or : — begin typing any part of a command name and press Tab to complete.
In the primary Qt GUI you rarely need the palette: the same actions live in the menus, each with its own keyboard shortcut (see Keyboard Shortcuts above, and Help → Keyboard Shortcuts,
F3).
Document
| Command | Description |
|---|---|
open |
Open a local file |
open-url |
Fetch and open a URL |
close |
Close the current document |
reload |
Reload the current document from disk |
export-markdown |
Save the rendered document as a .md file |
batch-convert |
Convert many files / a folder to one format (Markdown, text, or Braille) |
export-braille |
Export a BRF braille file (requires louis) |
export-audio [fmt] |
Synthesize document to audio; fmt is mp3 (default), ogg, mp4, or wav |
export-subtitles |
Write a timestamped SRT/VTT caption track synchronized to the speech |
subtitle-format srt|vtt |
Set the caption format used for subtitle export |
subtitle-word-level |
Toggle one cue per word vs. sentence-grouped cues |
subtitles-with-audio |
Toggle emitting captions automatically alongside audio export |
recent |
Pick from recently opened files |
library (bookshelf) |
Browse the document library and reopen a document |
reading-stats (stats) |
Show the reading-statistics dashboard |
cache-clear |
Delete the cached version of the current document |
Speech
| Command | Description |
|---|---|
play |
Begin or resume TTS |
stop |
Stop TTS |
pause |
Pause TTS |
speak-line |
Read the current line without advancing |
rate-up |
Increase reading rate by 20 wpm |
rate-down |
Decrease reading rate by 20 wpm |
volume-up |
Increase TTS volume |
volume-down |
Decrease TTS volume |
tts-backend |
Switch TTS engine at runtime (pyttsx3/espeak/festival/piper/coqui/dectalk/none) |
highlight-granularity word|sentence|both |
Highlight the spoken word, the whole sentence, or both |
tts-voice |
Switch TTS voice by ID |
ssml-on / ssml-off |
Enable/disable SSML prosody markup |
speed <name> |
Apply a named speed preset: skim, normal, study, slow |
speed-add <name> <wpm> |
Define a new speed preset |
speed-list |
List all defined speed presets |
Search & Navigation
| Command | Description |
|---|---|
search |
Search forward |
search-backward |
Search backward |
search-regex |
Search with a regular expression |
goto-line |
Jump to a line number |
chapter-list |
List document chapters / headings |
chapter-next / chapter-prev |
Navigate to adjacent chapter |
chapter-goto |
Jump to a named chapter |
bookmark-set |
Set a named bookmark at the current position |
bookmark-goto |
Jump to a named bookmark |
bookmark-list |
List all bookmarks for this document |
bookmark-delete |
Delete a named bookmark |
Display
| Command | Description |
|---|---|
theme [name] |
Switch color theme |
line-numbers |
Toggle line numbers |
syntax-highlight |
Toggle code syntax highlighting |
wrap-width |
Set text wrap width in columns |
font-size-up / font-size-down |
Adjust font size (Qt GUI) |
font <family> |
Set font family (Qt GUI) |
table-mode |
Switch table reading: structured, flat, or skip |
footnote-mode |
Switch footnote handling: inline, deferred, or skip |
reading-level |
Show Flesch-Kincaid grade and ease score |
Abbreviations, Pronunciations & Numbers
| Command | Description |
|---|---|
abbrev-add |
Add a custom abbreviation expansion for TTS |
abbrev-list |
List all active abbreviation expansions |
pron-add <term> <spoken> |
Add/update a pronunciation override for a term |
pron-remove <term> |
Remove a pronunciation override |
pron-list |
List all pronunciation overrides |
pronunciations |
Toggle the pronunciation lexicon on/off |
Voice & Profile Presets
| Command | Description |
|---|---|
profile-save <name> |
Save the current settings as a named profile |
profile-load <name> |
Apply a saved profile (voice, rate, theme, font, spacing, highlight) |
profile-list |
List saved profiles |
profile-delete <name> |
Delete a saved profile |
Notes & Annotations
| Command | Description |
|---|---|
annotate |
Add a note at the current reading position (also a) |
annotations-list [query] |
Browse all notes, optionally filtered (also A) |
annotations-search |
Prompt for a filter (text or #tag) and list matches |
annotation-goto <n> |
Jump to note number n |
annotation-delete <n> |
Delete note number n |
annotations-export |
Export notes to .md / .json / .bib / .ris / .txt |
System
| Command | Description |
|---|---|
shortcuts |
Show the keyboard cheat sheet (also ?) |
help |
Open the built-in help manual |
about |
Version, author, and license |
license |
Full GPL v3 license text |
settings |
Open settings.json in your system editor |
quit |
Exit star |
📄 Supported File Formats
| Format | Extension(s) | Package(s) Required |
|---|---|---|
| PDF (text layer) | .pdf |
pdfminer.six |
| PDF (scanned / image) | .pdf |
pytesseract, pymupdf |
| Microsoft Word | .docx |
python-docx |
| Microsoft Word (legacy) | .doc |
python-docx or antiword |
| PowerPoint | .pptx |
python-pptx |
| OpenDocument Text | .odt |
odfpy (or Pandoc fallback) |
| EPUB 2 / 3 | .epub |
built-in |
| HTML / XHTML | .html, .htm |
built-in |
| DAISY / DTBook | .xml, .daisy |
built-in |
| DAISY ZIP | .zip |
built-in |
| Markdown | .md, .markdown |
built-in |
| Plain text | .txt |
built-in |
| reStructuredText | .rst, .rest |
built-in |
| AsciiDoc | .adoc, .asciidoc, .asc |
built-in (or Pandoc) |
| MediaWiki markup | .wiki, .mediawiki |
built-in |
| Textile | .textile |
built-in |
| Creole | .creole |
built-in |
| LaTeX | .tex, .ltx |
built-in (Pandoc for complex files) |
| Org-mode | .org |
built-in |
| R source | .r |
built-in |
| R Markdown | .rmd |
built-in |
| Jupyter Notebook | .ipynb |
built-in |
| CSV | .csv |
built-in |
| TSV | .tsv |
built-in |
| Excel spreadsheet | .xlsx |
openpyxl |
| Images (OCR) | .png, .jpg, .jpeg, .gif, .bmp, .tiff, .webp |
pytesseract |
| Python source | .py |
built-in |
| URL (HTTP / HTTPS) | http://…, https://… |
built-in |
| Pandoc fallback | any Pandoc-supported format | pandoc binary or pypandoc |
PowerPoint: Slide titles are rendered as headings, body text as paragraphs, and speaker notes are appended after each slide.
Spreadsheets: CSV, TSV, and XLSX files are rendered as Markdown tables. Only cell values are spoken — delimiters and pipe characters are never read aloud.
Code block skipping: Fenced code blocks are skipped during TTS by default. Set "tts_skip_code": false to include them.
🔊 TTS Backends
In auto mode (the default), star chooses the first available backend in this
order: pyttsx3 → macOS say → eSpeak-NG → Festival → DECtalk → silent. On a
Mac this guarantees a native Apple voice even without any Python packages.
Exception — the self-contained Windows binary: when the bundled DECtalk
engine is present and actually starts, it is chosen first, so the binary
defaults to the classic Perfect Paul voice. star probes a real DECtalk
startup before preferring it, so on machines without a working DECtalk the
order above is used unchanged. Switch engines any time with Speech → Choose
TTS Engine… (Ctrl+Shift+G) or M-x tts-backend.
pyttsx3 (preferred when installed)
pyttsx3 wraps the platform's native TTS engine and provides word-boundary
callbacks for the most accurate word-by-word highlighting.
- Windows — SAPI5 (all Control Panel voices available)
- macOS — NSSpeechSynthesizer (requires
pip install pyobjc) - Linux — eSpeak-NG
pip install pyttsx3 # plus `pip install pyobjc` on macOS
macOS say (native — default on Mac)
The applesay backend drives macOS's built-in /usr/bin/say command, so Mac
users get Apple's high-quality system voices with no extra dependencies — no
pyobjc, no Homebrew, no eSpeak. It is ranked above eSpeak in auto mode, which
fixes the long-standing issue of Macs falling back to the robotic eSpeak voice.
- Preferred default voice: when no voice is set,
starauto-selects a voice matching thetts_prefer_voicesetting (default"eloquence"), favoring a US-English variant — so the bundled Eloquence (US English) voice is used by default when available. List voices withsay -v ?and set one via Speech → Voice… or thetts_voicesetting. - Word highlighting uses the highlight timer (the same path as Festival/Coqui),
since
saydoes not emit per-word events.
eSpeak-NG
star prefers to drive eSpeak-NG in process through libespeak-ng (via ctypes). The library reports a per-word event for every spoken word, tagged with the word's audio position (milliseconds into the output stream), which star forwards to the reading highlight — so the highlight follows actual playback instead of a free-running estimate. This is used automatically when the shared library is available: the bundled libespeak-ng.dll in the self-contained Windows build, or a system libespeak-ng on Linux/macOS.
When the library is not present, star falls back to driving the espeak-ng command-line binary as a subprocess. The CLI reports no per-word events, so in that mode the highlight is paced by the reading-rate timer.
| Platform | Install |
|---|---|
| Linux (Debian/Ubuntu) | sudo apt install espeak-ng |
| macOS | brew install espeak |
| Windows | Download from github.com/espeak-ng/espeak-ng/releases |
Installing eSpeak-NG provides both the libespeak-ng shared library (which star loads in-process) and the espeak-ng binary (the subprocess fallback); for that fallback the binary must be on your PATH.
Festival
Festival speech synthesis (Linux). The festival binary must be on your PATH.
Piper (neural, offline, free)
Piper gives natural, neural-quality speech
entirely offline with no subscription or network dependency — the best fit
for an accessibility-first reader. It ships as a standalone piper binary (no
Python package needed) that STAR drives behind the scenes.
Setup:
- Install the
piperbinary so it is on yourPATH(releases: github.com/rhasspy/piper). - Download a voice model — a
.onnxfile and its.onnx.jsonconfig (voices: huggingface.co/rhasspy/piper-voices). - Point STAR at the model by any of:
- setting
piper_modelto the.onnxpath insettings.json, - exporting the
PIPER_MODELenvironment variable, or - dropping the files into a Piper voice directory (e.g.
<config>/piper,~/.local/share/piper, or%APPDATA%\piper;PIPER_VOICE_DIRis also honored).
- setting
- Select it with Speech → Choose TTS Engine… or
M-x tts-backend piper.
Like Coqui, Piper is opt-in and never chosen in auto mode. Word
highlighting uses the timer (Piper synthesizes a whole utterance to audio, so
no per-word events are available). The reading rate maps to Piper's length
scale; if your piper build rejects that flag, synthesis falls back to the
model's default rate automatically.
Coqui TTS
Neural TTS via the Coqui TTS Python library. High quality but requires a GPU-capable machine for real-time synthesis.
pip install TTS
DECtalk
The legendary "Perfect Paul" synthesizer, now open source.
- In the self-contained Windows build,
stardrives the bundledDECtalk.dllin-process viactypes(the architecture-matched 64-/32-bit engine plus its dictionary are bundled), so the classic DECtalk voice works with no setup — and it is the default engine/voice on that build (see the auto-mode note above). - All nine classic speakers are listed in the voice picker (Speech → Choose Voice…,
Ctrl+Shift+V, orM-x voice-picker): Perfect Paul (default), Beautiful Betty, Huge Harry, Frail Frank, Doctor Dennis, Kit the Kid, Uppity Ursula, Rough Rita, and Whispering Wendy. - Otherwise
staruses a system DECtalk: setDECTALK_BINto the full path of adtalk/dectalkCLI (or have one onPATH). - Source: github.com/dectalk/dectalk
- Word highlighting uses a timer-based approximation.
Silent (fallback)
When no TTS engine is available, star falls back to silent mode. All display, navigation, search, and export features continue to work.
Switching Backends at Runtime
M-x tts-backend pyttsx3
M-x tts-backend applesay # macOS native `say`
M-x tts-backend espeak
M-x tts-backend festival
M-x tts-backend piper # neural, offline, free (needs a .onnx model)
M-x tts-backend coqui
M-x tts-backend dectalk
M-x tts-backend none
In the Qt GUI the same engines are reachable from Speech → Choose TTS Engine….
🖍️ Word Highlighting
While TTS is playing, star highlights the word currently being spoken and keeps it scrolled into view.
How it works:
- pyttsx3 — Word-boundary callbacks from the native SAPI5 / NSSpeechSynthesizer engine confirm the exact audio position. A background timer advances the highlight at the configured speech rate; callbacks correct the timer's estimate to keep the two in sync.
- eSpeak-NG — When libespeak-ng is available it is driven in-process. It synthesizes a whole sentence's audio in a burst and reports every word event at once, so rather than highlight on the raw events (which would race ahead of the sound),
starpaces each word to the audio position the engine reports for it — the highlight follows what is actually being heard, not what was just synthesized. Theespeak_highlight_offset_mssetting (default 120) nudges that timing to compensate for audio-output latency: raise it if highlights still lead the speech, lower it toward 0 if they lag. With only theespeak-ngCLI available, no per-word events are reported and the highlight falls back to the reading-rate timer. - DECtalk / Festival / Piper / Coqui — No word-level events are available.
staruses the current reading rate (wpm) to advance the highlight on a timer.
The document view scrolls automatically to keep the highlighted word visible. In the terminal TUI the cursor tracks the highlighted line; in Qt the word is scrolled into view without stealing keyboard focus.
Granularity (word / sentence / both): by default the single spoken word is highlighted. For readers who find rapid word-by-word movement distracting, switch to sentence highlighting (the whole current sentence is banded) or both (a soft sentence band with the current word marked on top). Set it in View → Reading Aids → Karaoke Highlight… (the Granularity selector) or with M-x highlight-granularity word|sentence|both. Works in both the Qt GUI and the terminal TUI.
🎬 Subtitle Export (SRT / VTT)
When you export a document as audio, STAR can also produce a synchronized caption track so the highlight "travels" with the audio into any media player — handy for review and for creating accessible study recordings.
- On their own: File → Export → Export Subtitles (SRT / VTT)… in the Qt
GUI, or
M-x export-subtitlesin the TUI. The format follows the file extension you choose (.srtor.vtt). - Alongside audio: enable
M-x subtitles-with-audio(or theexport_subtitles_with_audiosetting) and every audio export drops a matching caption file next to it. - Cue size: captions are grouped into readable sentence-length lines by
default;
M-x subtitle-word-levelswitches to one cue per word. - Default format:
M-x subtitle-format srt|vtt(settingsubtitle_format).
Timing is estimated from the synthesized audio's total duration (apportioned across spoken tokens by length), because file-based TTS synthesis exposes no per-word callbacks. No external tools are required.
📊 Reading Statistics & Progress
STAR keeps a running tally of your reading so you can see progress at a glance — useful when managing heavy reading loads.
- What's tracked (per document): total time read (accrued only while speech is actually playing), the furthest word reached, progress %, and the number of sessions.
- Dashboard: Tools → Reading Statistics… (
Ctrl+Shift+S) in the Qt GUI, orM-x reading-statsin the TUI. It shows overall totals (time and words across all documents), the current document's progress, and a most-read list. - Storage: everything lives in
settings.jsonunderreading_statsand is flushed periodically and on exit, so it survives restarts.
🏛️ Library / Bookshelf
Every document you open is remembered in a central library, turning STAR from a per-file viewer into a study hub.
- Open it: File → Library / Bookshelf… (
Ctrl+Shift+B) in the Qt GUI, orM-x library(bookshelf) in the TUI. - What it shows: each document's title, format, progress %, time read, and last-opened date, newest first. Type in the filter box to search by title or path.
- Reopen: press Enter or double-click an entry (Qt), or pick its number (TUI). Progress is read from your saved reading position so you resume right where you left off.
- Storage: the
librarysetting records metadata for every opened document; progress and time merge in fromreading_positionsandreading_stats.
👁️ Live HTML Preview (edit mode)
While editing Markdown source you can show a live HTML preview beside the editor that re-renders as you type.
- Toggle: View → Live HTML Preview or
Ctrl+Shift+L. Turning it on outside edit mode automatically enters edit mode; the editor and preview sit in a draggable split pane. - Live updates: the preview re-renders ~300 ms after your last keystroke (debounced) so typing stays responsive, and it follows the current theme.
- Preference: the
qt_edit_previewsetting remembers whether the preview is shown the next time you enter edit mode. The preview pane is hidden automatically when you leave edit mode.
🎚️ Voice & Profile Presets
Profiles bundle your most important settings so you can adapt STAR to a task or your current fatigue level in one step — e.g. a fast “Skim” profile, a slower “Deep Study” profile, or a high-contrast “Low-Light” profile.
- What's captured: TTS backend, voice, rate, volume, SSML toggle, theme, font family/size, letter/word/line spacing, the dyslexia-friendly font, bionic reading, current-line highlight, and all karaoke-highlight settings (style, color, speed, lead, granularity).
- Qt GUI: the Profiles menu — Save Current Settings as Profile…
(
Ctrl+Shift+K), Load Profile… (Ctrl+Shift+J), Delete Profile… (Ctrl+Shift+Y). Loading applies everything immediately (re-themes, re-fonts, and re-selects the voice/engine). - TUI:
M-x profile-save <name>,profile-load <name>,profile-list,profile-delete <name>. - Storage: profiles live in
settings.jsonunderprofiles.
🗣️ Pronunciation Lexicon
Domain vocabulary — drug names, anatomy, gene symbols, acronyms — routinely defeats default TTS. The pronunciation lexicon lets you map any term to a spoken form so it is read correctly and consistently, on every backend.
- Editor (Qt GUI): Speech → Pronunciation Lexicon… (
Ctrl+Shift+I) opens a manager to add, edit, and delete entries, with a checkbox to enable or disable the whole lexicon. - TUI:
M-x pron-add <term> <spoken form>,pron-list,pron-remove <term>, andpronunciationsto toggle it on/off. - How it works: matching is whole-word and case-insensitive, longer terms
win over shorter ones, and overrides are applied first — before
abbreviation expansion and number normalization — so they are never reshaped
by later steps. Example:
CHF → congestive heart failure, or a phonetic respelling likeXa cept → zah-sept. - Storage: entries live in
settings.jsonunderpronunciations; theuse_pronunciationsflag toggles the feature.
Highlight timer and SAPI5 pacing (pyttsx3 backend):
The highlight is driven by a background timer that fires once per word at the configured rate (highlight_speed × tts_rate). When pyttsx3 word callbacks are actively firing, the timer also applies a pacing guard: it will not run more than 4 words ahead of the last callback-confirmed position, keeping the visual close to actual audio during engine startup or sentence transitions.
SAPI5 word callbacks can arrive 1–3 words late and sometimes stop firing entirely mid-utterance. To prevent the highlight from freezing while speech continues, the guard has a 1.5-second timeout: if no callback has arrived within 1.5 s the guard is bypassed and the timer runs freely until the next callback resumes. This means a highlight that is slightly ahead of audio is always preferred over one that is stuck.
Word-position map:
At document load time star builds a word-position map that links every TTS word to its display line and column. The map uses a monotonically advancing, column-aware search: when the same word appears multiple times on a single line (the cat and the dog) each occurrence is matched in document order rather than all mapping back to the first. The search position never moves backward between words, which prevents common words from cascade-matching several lines before their actual display position and making the highlight appear stuck.
🪟 Qt GUI Mode
The Qt GUI is the default mode when PyQt6 or PyQt5 is installed. No special flag is needed:
star document.pdf
star # opens to the welcome screen
To force the terminal interface even when Qt is available:
star --tui document.pdf
Menu Bar
File menu
| Item | Action |
|---|---|
| Open… | Open a file via a standard file dialog |
| Export › Export as Markdown… | Save document as .md |
| Export › Export as PDF… | Save document as .pdf (user highlights included) |
| Export › Export as Braille (BRF)… | Save document as .brf (built-in Grade 1; Grade 2 via bundled/installed liblouis) |
| Export › Export as Audio (MP3 / OGG / MP4)… | Synthesize document to an audio file (WAV always works; MP3/OGG/MP4 via bundled/installed ffmpeg) |
| Quit | Exit the application |
Highlight menu
| Item | Shortcut | Action |
|---|---|---|
| Highlight Yellow | — | Highlight selected text in yellow |
| Highlight Green | — | Highlight selected text in green |
| Highlight Cyan | — | Highlight in cyan |
| Highlight Pink | — | Highlight in pink |
| Highlight Orange | — | Highlight in orange |
| Clear All Highlights | — | Remove all highlights for this document |
Ctrl+His now the Next Heading shortcut (matching NVDA/JAWS convention). Use the toolbar Highlight button or the Highlight menu to apply colors.
View menu
| Item | Shortcut | Action |
|---|---|---|
| Toggle Contents Panel | Ctrl+\ |
Show/hide the Table of Contents dock |
| Toggle Notes Panel | Ctrl+Shift+N |
Show/hide the Notes dock (hidden by default) |
| Next Theme | F5 |
Cycle through all themes (built-in + CSS) |
| Choose Theme… | — | Pick any theme by name from a list |
| Reload CSS Themes | — | Rescan the themes folder without restarting |
| Open Themes Folder | — | Open the themes folder in the system file manager |
| Change Font… | — | Open the OS font picker to choose family, style, and size |
| Reading Level | Ctrl+L |
Show Flesch-Kincaid reading level |
| Reading Aids › Text Spacing… | — | Adjust line height, letter and word spacing (WCAG 1.4.12) |
| Reading Aids › Karaoke Highlight… | — | Tune the spoken-word highlight style, color, speed, and lead/lag |
| Reading Aids › Dyslexia-Friendly Font | — | Prefer an installed dyslexia-friendly font (toggle) |
| Reading Aids › Bionic Reading | — | Embolden the leading part of each word (toggle) |
| Reading Aids › Current-Line Highlight | — | Tint the line being read with a focus band (toggle) |
Toolbar
The toolbar is divided into labeled groups separated by dividers:
| Group | Buttons |
|---|---|
| File | Open · URL |
| Playback | Play/Pause ▶⏸ · Stop ■ · − Speed · + Speed |
| Navigate | ◀ S (prev sentence) · ↺ S (replay sentence) · S ▶ (next sentence) · ◀ ¶ · ↺ ¶ · ¶ ▶ · ◀ H (prev heading, read) · H ▶ (next heading, read) |
| Voice / Mode | Voice… · SC ○ |
| Text | Copy · Highlight · Clear Highlights |
| View | Theme · ToC · Level · Font |
| Edit | Edit · Save |
| App | Help · Quit |
Every button shows a tooltip describing its action and keyboard shortcut.
Table of Contents Panel
The left-side dock panel lists all headings found in the current document. It is populated automatically when a file is opened and updates whenever the document changes. Click any entry to scroll the document to that heading and stop at that position. Toggle the panel with Ctrl+\ or View → Toggle Contents Panel; its visibility is saved in settings.
User Text Highlighting
Select any range of text with the mouse or keyboard, then use the Highlight toolbar button (yellow) or choose a color from the Highlight menu. Ctrl+H is reserved for heading navigation and no longer triggers highlighting.
Highlights are stored in settings.json keyed by document path and restored automatically the next time the file is opened. When you export the document as a PDF (File → Export → Export as PDF…), the highlights are baked into the output.
To remove all highlights for the current document, use the Clear Highlights toolbar button or choose Highlight → Clear All Highlights.
Font Selection
View → Change Font… opens the operating system's native font picker. You can choose:
- Family — any font installed on your system (scrollable, searchable list)
- Style — Regular, Bold, Italic, Bold Italic
- Size — numeric point size with live preview
The dialog opens pre-populated with your current family and size. Both selections are applied immediately and persisted in settings.json under qt_font_family and qt_font_size.
Fonts well-suited for readers with dyslexia include OpenDyslexic, Lexie Readable, and Atkinson Hyperlegible. Install the font on your system, then select it here — or simply enable View → Reading Aids → Dyslexia-Friendly Font (see below) to have star pick an installed one automatically.
Reading Aids
View → Reading Aids collects low-friction, high-impact accommodations for dyslexic and low-vision readers. All settings persist in settings.json and apply to the Qt GUI.
- Text Spacing… — a live-preview dialog to independently adjust line height, letter spacing, and word spacing. Generous, adjustable spacing reduces crowding effects and directly supports WCAG 1.4.12 (Text Spacing). Stored in
qt_line_height(default1.5),qt_letter_spacing(extra %), andqt_word_spacing(extra px). Cancel reverts; OK keeps. - Karaoke Highlight… — a live-preview dialog to tune the spoken-word highlight:
- Granularity (
highlight_granularity):word(default),sentence(band-highlight the whole current sentence — less flicker), orboth(a soft sentence band with the current word marked on top). Applies to both the Qt GUI and the TUI (M-x highlight-granularity). - Style (
highlight_style):background(filled),underline,box(wavy underline),bold, orcolor(colored text). - Color (
highlight_color): any Qt/CSS color name or#rrggbb. - Speed (
highlight_speed): highlight pacing as a fraction of the speech rate; applies on the next play. - Lead / lag (
highlight_lead_words): advance the visual highlight ahead of (+) or behind (−) the audio for readers who track best slightly ahead.
- Granularity (
- Dyslexia-Friendly Font (toggle,
qt_dyslexia_font) — prefer an installed dyslexia-friendly face.starsearches for OpenDyslexic, Atkinson Hyperlegible, Lexend, and Comic Sans (in that order) and uses the first one found, falling back to your chosen font and prompting you if none is installed. (Fonts are not bundled — install one on your system first.) - Bionic Reading (toggle,
qt_bionic_reading) — embolden the leading part of each word to pull the eye forward. Code spans are left verbatim. - Current-Line Highlight (toggle,
qt_current_line_highlight) — tint the line being read with a focus band so it stands out from surrounding text.
High-DPI Support
star applies HighDpiScaleFactorRoundingPolicy.PassThrough (PyQt6) or AA_EnableHighDpiScaling (PyQt5) before creating the QApplication, so the window renders crisp on 4K and HiDPI displays. Set "qt_hidpi": false in settings.json to disable this if it causes scaling problems.
AT-SPI2 Accessibility
The document view has accessibleName and accessibleDescription set so that Orca and other AT-SPI2 consumers can inspect it. On Linux, running star alongside Orca in a standard GNOME session should work without special configuration.
🌈 User Highlights
User-created highlights are saved per document path in settings.json under the user_highlights key:
"user_highlights": {
"/home/user/papers/thesis.pdf": [
{"start": 1240, "end": 1298, "color": "#ffff00"},
{"start": 3500, "end": 3612, "color": "#90ee90"}
]
}
startandendare character offsets in the rendered Qt document text.coloris any CSS hex color string.- Highlights are displayed using
QTextEdit.setExtraSelections()— they do not modify the document and do not interfere with TTS word highlighting, which is layered on top. - PDF export temporarily applies the highlight formats to the document before printing, then reverts by reloading the HTML.
🗒️ Annotations / Notes
Attach notes anywhere in a document — ideal for study notes, review comments, or building a reading bibliography. Notes are available in both interfaces and share the same per-document store, anchored by reading position so they survive re-rendering.
Qt GUI — the Notes dock panel:
- Add a note: place the cursor (or select a passage) and press Ctrl+Shift+A, choose Notes → Add Note at Cursor…, or click + Note on the toolbar. A second prompt accepts optional tags (comma-separated). A text selection becomes the note's anchor/quote.
- Navigate: single-click (or Enter) a note to scroll to its anchor; double-click to start reading aloud from there.
- Search / filter: type in the panel's filter box — plain terms match the note text, anchor, and tags; a
#tagterm filters by tag. The dock title showsNotes (shown/total). - Edit / delete / link: use the panel buttons or the Notes menu. A note can be linked to a citation (see below).
- Toggle the panel: Ctrl+Shift+N, the Notes toolbar button, or Notes → Toggle Notes Panel.
Terminal TUI — the notes pager:
| Action | Key / Command |
|---|---|
| Add a note at the reading position | a (prompts for note, then tags) |
| Browse all notes | A or M-x annotations-list |
| Search / filter notes | M-x annotations-search (then type text or #tag) |
| Jump to a note | M-x annotation-goto <n> |
| Delete a note | M-x annotation-delete <n> |
| Export notes | M-x annotations-export |
Notes persist per-document in settings.json under the annotations key:
"annotations": {
"/home/user/papers/thesis.pdf": [
{"char_pos": 1240, "word_idx": 318, "anchor": "cellular respiration",
"note": "Define for exam", "tags": ["bio", "exam"], "cite": "smith2020",
"ts": "2026-06-13T22:45:36"}
]
}
Notes carry both a Qt character offset (char_pos) and a word_idx, so a note created in one interface navigates correctly in the other.
Exporting notes (bibliographic formats)
Notes → Export Notes… (or the panel's Export… button) writes the current document's notes to a file; the format is chosen by the extension:
| Extension | Format | Notes |
|---|---|---|
.md |
Markdown | Human-readable list with a citation header (title, author, source, date) — the default |
.json |
JSON | Full structured data including document metadata |
.bib |
BibTeX | A single @misc reference for the source document with all notes in the annote field |
.ris |
RIS | A reference-manager entry with each note as an N1 line |
.txt |
Plain text | Simple numbered list |
The BibTeX/RIS output draws the title and author from the document's metadata (e.g. EPUB/PDF/DOCX properties) so exported notes drop cleanly into Zotero, Mendeley, or a .bib bibliography.
📚 Citation Manager (Qt GUI)
A lightweight citation library lives in the Citations menu and is shared across all documents (stored under the citations key in settings.json).
- Import… — read references from a BibTeX (
.bib), RIS (.ris), or CSL-JSON (.json) file. Entries with a matching key are refreshed; new ones are added. - Export… — write the whole library to BibTeX, RIS, or CSL-JSON (format chosen by extension).
- Add Citation… — enter a reference by hand via a short series of prompts.
- Manage / Browse… — pick a citation to copy its key, link it to the selected note, or delete it.
Linking a citation to a note records its key in the note's cite field (shown as @key in the Notes panel), so exported study notes carry proper attribution back to the source.
🎙️ Voice Dictation & Transcription (optional)
With Whisper installed, star can turn speech into text — a major accessibility win for users who find typing slow or impossible.
- Tools → Transcribe Audio File… — pick an audio file (WAV/MP3/M4A/OGG/FLAC/…); the transcription opens as a new readable, navigable document. Runs in a background thread so the UI stays responsive.
- Tools → Dictate Note (record)… — record a short voice memo from your microphone; the transcribed text is saved as a note (tagged
dictated) at the current position.
Install the optional dependencies:
pip install openai-whisper # transcription of audio files
pip install sounddevice numpy # plus this for microphone dictation
faster-whisper is also supported as a lighter alternative. The model size is configurable with the whisper_model setting (tiny, base, small, medium, large). When Whisper is not installed, these menu items simply explain how to enable them — nothing else is affected.
Bundled in the self-contained Windows binary — the
star.exeshipsopenai-whisper(with its PyTorch backend),sounddevicefor microphone capture, and the Whisperbasemodel, so transcription and dictation work offline with no install and no first-run download. This is the single biggest contributor to the binary's size (seeBUILD.md).
🧭 Table of Contents
The Contents panel is populated by scanning the document's Markdown for heading lines (#, ##, etc.). Each heading becomes a list entry; heading level is indicated by indentation. Clicking an entry calls QTextDocument.find() to locate the heading text and scrolls to it.
For EPUB files, the chapter list is also derived from the NCX or NAV navigation document (see EPUB Navigation) and made available through M-x chapter-list and M-x chapter-goto in both TUI and Qt modes.
📖 EPUB Navigation
star parses EPUB navigation data to provide chapter-level navigation for long books:
- EPUB 3 NAV — Reads the
<nav epub:type="toc">element from the navigation document listed in the OPF manifest withproperties="nav". - EPUB 2 NCX — Falls back to the
.ncxfile referenced by the<spine toc="…">attribute or identified bymedia-type="application/x-dtbncx+xml"in the manifest.
Extracted chapters are available via:
M-x chapter-list # list all chapters with their indices
M-x chapter-goto # jump to a chapter by name or index
M-x chapter-next # move to the next chapter
M-x chapter-prev # move to the previous chapter
In the Qt GUI the Contents panel shows all headings extracted from the rendered text; for EPUBs this closely mirrors the NCX/NAV structure.
🌼 DAISY / DTBook Support
star parses DTBook XML natively and supports the DAISY 3 digital talking book format:
- DTBook XML (
.xml,.daisy) — parsed directly. - Bookshare ZIP downloads — pass the
.zippath;starunpacks and locates the content automatically. - Archive.org DAISY books — pass the direct URL to an
.xmlor.zipfile.
Structure navigation follows the DTBook element hierarchy. Reading order follows the <spine> or <book> element sequence.
⚡ Document Caching
star caches the parsed text and word map for each document in:
| Platform | Cache path |
|---|---|
| Linux | ~/.config/star/cache/ |
| macOS | ~/Library/Application Support/star/cache/ |
| Windows | %APPDATA%\star\cache\ |
On subsequent opens star checks the file's modification time; if the file hasn't changed and the settings fingerprint matches, the cached result is used immediately — making reopening a large PDF or running Pandoc conversion on startup instant.
Cache files are JSON-formatted and named by a hash of the file path and settings. To force a fresh parse:
M-x cache-clear
Configure caching in settings.json:
"document_cache": true,
"cache_max_size_mb": 100
🔖 Footnote Handling
Markdown and Pandoc-style footnotes ([^1], [^label]) are recognized and handled according to the footnote_mode setting:
| Mode | Behavior |
|---|---|
inline (default) |
Footnote text is inserted at the reference point: word (footnote: text) |
deferred |
Footnote references are removed; footnote text is collected and appended as a "## Footnotes" section at the end |
skip |
All footnote markers and definitions are silently removed |
Change at runtime:
M-x footnote-mode inline
M-x footnote-mode deferred
M-x footnote-mode skip
🔍 OCR Support
star uses Tesseract via pytesseract for image-based PDFs and standalone image files.
Bundled in the self-contained Windows binary — the
star.exeships the Tesseract engine and English (eng) data, so OCR works out of the box with no separate install. The steps below are for running from source or other platforms.
pip install pytesseract pymupdf
| Platform | Tesseract install |
|---|---|
| Linux (Debian/Ubuntu) | sudo apt install tesseract-ocr tesseract-ocr-eng |
| macOS | brew install tesseract |
| Windows | Download from github.com/tesseract-ocr/tesseract/releases (or use the bundled engine in the self-contained build) |
Configure the language pack in settings.json:
"ocr_lang": "eng+spa"
star uses PyMuPDF to render each page to a bitmap, then Tesseract to recognize the text. Text-layer PDFs are always preferred; OCR is triggered only when no text layer is detected.
➗ Math Normalization
When "normalize_math": true (the default), star converts common LaTeX and inline math expressions to natural English before TTS:
x^2→ "x squared"\sqrt{x}→ "square root of x"\frac{a}{b}→ "a over b"x_i→ "x sub i"- Greek letters:
\alpha→ "alpha",\pi→ "pi", etc. - Operators:
\times→ "times",\leq→ "less than or equal to", etc.
This normalization also applies to MathML-embedded math extracted from EPUB and HTML documents.
⠎ Braille Support
Braille display passthrough — On Linux, BrlTTY intercepts curses output and routes it to a connected braille display automatically. On Windows, NVDA and JAWS handle braille display routing.
BRF file export — Export the current document to a Braille Ready Format file:
- TUI:
M-x export-braille - Qt GUI: File → Export → Export as Braille (BRF)…
Reliable out-of-the-box (Grade 1)
BRF export works with no dependencies. star includes a pure-Python
uncontracted Grade 1 translator using the North-American Braille-ASCII
(NABCC) character set, with proper number signs, capital signs, common
punctuation, and standard 40-cell × 25-line page geometry (form-feed paged,
CRLF line endings) that embossers expect.
Why this changed: earlier versions relied solely on liblouis, and a missing translation table could make liblouis call
exit()at the C level — abruptly closing the whole window. The built-in translator is now the default and can never crash the process.
Optional contracted Grade 2 (liblouis)
For contracted Grade 2 output, opt in (the self-contained Windows binary already bundles liblouis + tables; from source, install the louis binding and liblouis):
pip install louis
"braille_grade2": true,
"braille_table": "en-ueb-g2.ctb"
When braille_grade2 is enabled and the requested table resolves, star uses
liblouis; any failure falls back automatically to the built-in Grade 1
translator (still no crash). Useful tables:
| Table file | Description |
|---|---|
en-ueb-g1.ctb |
UEB Grade 1 (uncontracted) |
en-ueb-g2.ctb |
UEB Grade 2 (contracted) |
es-g1.ctb |
Spanish Grade 1 |
nemeth.ctb |
Nemeth Code for mathematics |
🎧 Audio Export
star can synthesize an entire document to an audio file using whatever TTS backend is currently active. This is useful for creating offline listening copies, sharing recordings, or integrating with other tools.
Defaults to WAV — because WAV needs no external tools, it is the default container (audio_export_format setting). MP3/OGG/MP4 require ffmpeg, which is bundled in the self-contained Windows binary (see BUILD.md); from source they work whenever ffmpeg (or pydub) is available.
How to export:
- Qt GUI: File → Export → Export as Audio… — opens a save dialog (defaulting to
.wav); synthesis runs in a background thread so the window stays responsive. - TUI:
M-x export-audio [fmt]— prompts for a file path (defaulting to youraudio_export_format); synthesis is synchronous (the TUI is unresponsive until complete). Use a short document or a fast backend (pyttsx3/eSpeak/say) to minimize wait time.
Output formats:
| Format | Extension | Extra requirement |
|---|---|---|
| WAV | .wav |
None — always works (default) |
| MP3 | .mp3 |
ffmpeg (recommended) or pydub |
| OGG Vorbis | .ogg |
ffmpeg or pydub |
| MP4 (audio-only AAC) | .mp4 |
ffmpeg or pydub |
The output format is inferred automatically from the file extension you choose.
Backend support for audio export:
| Backend | Mechanism |
|---|---|
| pyttsx3 | engine.save_to_file() → WAV |
| eSpeak-NG | -w wav_path flag |
| Festival | text2wave helper (or Festival Scheme fallback) |
| Piper | --output_file → WAV (neural, offline) |
| Coqui TTS | Coqui synthesis API → WAV |
| DECtalk | DECtalk.dll WAV-out (in-process) on Windows; -w flag with a CLI |
| Silent | Not supported (raises an error) |
Subtitles: audio export can also emit a synchronized SRT/VTT caption
track — see Subtitle Export. Enable
M-x subtitles-with-audio to write one beside every audio file automatically,
or export captions on their own with File → Export → Export Subtitles… /
M-x export-subtitles.
Format conversion pipeline: The backend always produces a WAV file first. If the requested format is not WAV, star converts it using:
- ffmpeg (preferred) — install from ffmpeg.org or via your package manager.
- pydub (pure-Python fallback) —
pip install pydub. - If neither is available and the format is not WAV, export raises a clear error with installation instructions.
# Install ffmpeg (Linux)
sudo apt install ffmpeg
# Install ffmpeg (macOS)
brew install ffmpeg
# Pure-Python fallback (all platforms)
pip install pydub
Example workflow:
M-x export-audio # prompts for path; defaults to <docname>.wav
M-x export-audio mp3 # defaults to <docname>.mp3 (needs ffmpeg/pydub)
M-x export-audio ogg # defaults to <docname>.ogg
In the Qt GUI, the file dialog filter shows *.wav *.mp3 *.ogg *.mp4; you can type any extension and the format will be inferred.
🏃 Speed Presets
Named speed presets let you switch reading rate with a single command:
| Preset | Default wpm | Use case |
|---|---|---|
skim |
350 | Quick overview |
normal |
265 | General reading (default) |
study |
200 | Careful study |
slow |
150 | Difficult or unfamiliar material |
M-x speed skim # switch to skim preset
M-x speed normal # switch to normal preset
M-x speed-add fast 400 # define a new preset named "fast" at 400 wpm
M-x speed-list # show all presets and their rates
Presets are stored in settings.json under speed_presets and can be freely edited.
🔖 Bookmarks
Set named bookmarks at the current reading position and jump back to them later:
M-x bookmark-set introduction # bookmark the current position as "introduction"
M-x bookmark-goto introduction # jump to the "introduction" bookmark
M-x bookmark-list # show all bookmarks for this document
M-x bookmark-delete introduction # remove the "introduction" bookmark
Bookmarks are stored per document path in settings.json under bookmarks and survive between sessions.
🕑 History Navigation
star tracks recently visited positions within a session. Navigate the history with:
| TUI key | Action |
|---|---|
Alt+Left |
Go back to the previous position |
Alt+Right |
Go forward |
The history depth defaults to 50 entries and is configurable via "nav_history_size" in settings.json.
✏️ Document Editing (Qt GUI)
star includes a Markdown edit mode that lets you correct OCR errors, add notes, or revise any document in place.
Entering and leaving edit mode
| Action | Key / button |
|---|---|
| Enter edit mode | Ctrl+E or the Edit toolbar button |
| Exit edit mode (discard changes) | Ctrl+E again |
| Save and return to read mode | Ctrl+S or the Save toolbar button |
When edit mode is active the status bar shows ✏ EDIT MODE — Markdown source. The editor switches from rendered HTML to the raw Markdown source so you are editing the actual document text, not an HTML approximation.
Editing shortcuts (standard text-editor conventions)
| Key | Action |
|---|---|
Ctrl+Z |
Undo |
Ctrl+Y (or Ctrl+Shift+Z) |
Redo |
Ctrl+X |
Cut |
Ctrl+C |
Copy |
Ctrl+V |
Paste |
Ctrl+A |
Select all |
Delete / Backspace |
Delete forward / backward |
| Arrow keys | Move cursor |
Shift+Arrow |
Extend selection |
Ctrl+Arrow |
Move by word |
Home / End |
Start / end of line |
Ctrl+Home / Ctrl+End |
Start / end of document |
Saving
Ctrl+S writes the edited Markdown back to the original file when the source has a text-based extension (.md, .markdown, .txt, .rst, .org, .adoc). For PDF, DOCX, EPUB, and other binary formats a Save As dialog opens so you can choose a Markdown output path. After saving, star re-renders the HTML, rebuilds the Table of Contents, and rebuilds the TTS word maps.
What “edit mode” edits
The editor works on the Markdown representation of the document (the same text that M-x export-markdown would produce). For formats like PDF or DOCX this is a converted approximation — useful for fixing OCR errors or adding annotations, but not a round-trip back to the original binary format.
🧠 Study & Writing Aids
These optional helpers turn star from a reader into a study tool. Each is gated behind an optional package and degrades gracefully — the menu item always appears and tells you what to pip install when its package is missing, so the rest of star is unaffected.
Summarize a document
Tools ▸ Summarize Document (Ctrl+Shift+U) condenses the open document to its most important sentences using the extractive LexRank algorithm, and shows the result in a read-only dialog you can read aloud or copy. The number of sentences is controlled by the summary_sentences setting (default 7). Summarization runs on a background thread, so the window stays responsive even on a long document.
pip install sumy # or: pip install "star-reader[summarize]"
The first run quietly downloads the small NLTK sentence-tokenizer data it needs.
Export notes as Anki flashcards
File ▸ Export ▸ Anki Flashcards… (Ctrl+Alt+H) turns the current document's notes into an Anki deck (.apkg): each note becomes one card with the highlighted passage on the front and your note on the back. Import the file into Anki to study. (Add a note or two first — the command tells you if the document has none.)
pip install genanki # or: pip install "star-reader[flashcards]"
Spell check while editing
In edit mode (Ctrl+E), misspelled words are underlined with a red squiggle and re-checked as you type. Edit ▸ Check Spelling (F7) counts the misspellings and lists them in a dialog, whether or not you are currently editing.
pip install pyspellchecker # or: pip install "star-reader[spellcheck]"
Translate a document
Tools ▸ Translate Document (Ctrl+Shift+X) translates the open document into any of 15 common languages using Google Translate — no API key and no account required. A small dialog picks the target language and shows the translation in a read-only pane you can read aloud or copy. The request runs on a background thread so the window stays responsive, and the input is capped at 15,000 characters per request to stay within the free service's limits (the status bar tells you when a long document was truncated).
pip install deep-translator # or: pip install "star-reader[translate]"
Translation is the one study aid that needs a network connection; everything else in star works fully offline.
Highlight difficult words
View ▸ Reading Aids ▸ Highlight Difficult Words (Ctrl+Alt+O) tints uncommon and academic vocabulary directly in the document, so dense terminology stands out before you start reading. Words are judged by their frequency in everyday English — anything rarer than a configurable threshold (and at least four letters long) gets a soft yellow background. The overlay is non-destructive: it sits beneath your own highlights and the spoken-word highlight, persists across sessions (qt_vocab_highlight), and recomputes whenever you open a new document. Toggle it off from the same menu item.
pip install wordfreq # or: pip install "star-reader[vocab]"
Read RSS / Atom feeds
File ▸ Open Feed… (Ctrl+Shift+M) fetches a feed URL — an arXiv listing, a PubMed search, a journal's table of contents, a blog — and lists its articles in a chooser. Pick one (double-click or Open) and it loads in star's reader like any other web page, ready to be read aloud. It turns star into the single place you track new literature, instead of a tool you only reach for after finding something elsewhere.
pip install feedparser # or: pip install "star-reader[feeds]"
🦮 Screen Reader Compatibility
| Screen Reader | Platform | Notes |
|---|---|---|
| NVDA | Windows | Full compatibility; braille routing via NVDA braille display support |
| JAWS | Windows | Full compatibility; use virtual cursor mode |
| Orca | Linux | Full compatibility; AT-SPI2 metadata exposed on the Qt document view |
| VoiceOver | macOS | Compatible with Terminal.app and iTerm2 |
Design decisions:
- Cursor parking (TUI) — The terminal cursor stays at the minibuffer. Screen readers tracking the system cursor receive text echoed in one predictable location.
- AT-SPI2 (Qt) — The document view widget has
accessibleName="Document View"and a descriptiveaccessibleDescription, enabling Orca to inspect the reading area. - Screen-reader navigation conventions — Qt GUI navigation shortcuts follow NVDA/JAWS/VoiceOver muscle memory:
Ctrl+Hnext heading,Ctrl+Shift+Hprevious heading,Ctrl+P/Ctrl+Tfor paragraph/table, and so on. - No auto-scrolling interference — The document scrolls visually, but the cursor does not follow.
- High-contrast theme —
--theme contrastorM-x theme contrastfor maximum legibility. --plainmode — Extracts clean text to stdout, ideal for piping to other AT tools.
🎨 Color Themes
Built-in themes
| Name | Description |
|---|---|
dark |
Polished neutral-dark (Zed/Ghostty-inspired) with blue, cyan, purple, and teal accents (default) |
light |
Dark text on white with blue and magenta accents |
contrast |
Bold white and cyan on pure black — maximum legibility for low-vision users |
phosphor |
Classic green phosphor monochrome |
No built-in theme places red and green as adjacent accent colors, ensuring usability for deuteranopia and protanopia. Luminance contrast ratios meet or exceed WCAG 2.1 AA.
Switch themes:
- Qt GUI:
F5to cycle, or View → Choose Theme… to pick by name - TUI:
F5to cycle, orM-x theme <name> - Command line:
star --theme contrast
🎨 CSS Theme Customization (Qt GUI)
The Qt GUI supports fully custom CSS themes. Each theme is a plain .css file stored in the themes folder. star discovers all .css files there automatically.
Themes folder location
| Platform | Path |
|---|---|
| Linux | ~/.config/star/themes/ |
| macOS | ~/Library/Application Support/star/themes/ |
| Windows | %APPDATA%\star\themes\ |
The folder is created on first launch. The four built-in themes are written there as .css files so you have ready-made starting points to copy and edit.
Creating a custom theme
- Open the themes folder — View → Open Themes Folder opens it in your system file manager.
- Copy any existing
.cssfile and give it a new name, e.g.solarized.css. - Edit it with any text editor — it is standard CSS.
- Reload — View → Reload CSS Themes (or restart
star) makes the new theme available. - Switch — press
F5to cycle to it, or use View → Choose Theme… to pick it by name.
CSS file format
A theme file is a plain .css file. The filename (without extension) becomes the theme name. Any valid CSS that Qt’s HTML renderer understands can be used.
star parses the following rules to extract the palette values it needs for the editor widget (background-color, color, selection-background-color):
| CSS rule | Palette key extracted |
|---|---|
body { background: …; } |
Editor background color |
body { color: …; } |
Editor foreground / text color |
::selection { background: …; } |
Text selection highlight color |
h1 { color: …; } |
Heading level 1 color |
h2 { color: …; } |
Heading level 2 color |
h3 { color: …; } |
Heading level 3 color |
h4 { color: …; } |
Heading level 4 color |
code { color: …; } |
Inline code color |
Any rule not present in the file falls back to the built-in dark palette value, so a minimal theme file only needs to specify the colors it wants to change.
The full CSS in the file is injected verbatim into the <style> block of every rendered document, so any additional selectors you write (blockquote, table, a, custom classes, etc.) are applied directly.
Annotated example: Solarized Dark
/* star CSS theme: Solarized Dark
* Copy this file, rename it, and edit freely.
* star picks up any *.css file in this directory automatically.
* Run View → Reload CSS Themes (or restart) to apply changes.
*/
body {
background: #002b36; /* base03 — dark background */
color: #839496; /* base0 — body text */
font-family: Georgia, serif;
margin: 14px;
line-height: 1.6;
}
::selection {
background: #073642; /* base02 — selection highlight */
}
h1 { color: #268bd2; } /* blue */
h2 { color: #2aa198; } /* cyan */
h3 { color: #859900; } /* green */
h4 { color: #b58900; } /* yellow */
code {
color: #cb4b16; /* orange */
font-family: monospace;
}
pre {
color: #cb4b16;
font-family: monospace;
white-space: pre-wrap;
}
/* Extra styling beyond the built-in palette — fully supported */
blockquote {
border-left: 3px solid #586e75;
margin-left: 8px;
padding-left: 12px;
color: #657b83;
}
table {
border-collapse: collapse;
width: 100%;
}
th, td {
border: 1px solid #073642;
padding: 4px 8px;
}
th {
background: #073642;
color: #93a1a1;
}
Tips
- Qt’s HTML renderer supports a useful subset of CSS 2.1. Most color, font, margin, padding, and border properties work. CSS variables (
var()) and:root {}are not supported. - Hex colors (
#rrggbb,#rrggbbaa), named colors (white,salmon), andrgb()/rgba()all work. - Any extra selectors you add (
a,blockquote,table,td,th,ul,ol,li, etc.) are applied directly to the rendered document. - The themes folder is never cleared by
star. Your custom files are always preserved across updates. - Reload without restarting — View → Reload CSS Themes rescans the folder and re-applies the current theme in one click.
- To share a theme, give someone your
.cssfile; they drop it in their own themes folder.
⚙️ Settings
star stores preferences in settings.json, created automatically on first run.
File location:
| Platform | Path |
|---|---|
| Linux | ~/.config/star/settings.json |
| macOS | ~/Library/Application Support/star/settings.json |
| Windows | %APPDATA%\star\settings.json |
All settings keys:
| Key | Default | Description |
|---|---|---|
theme |
"dark" |
Color theme: dark, light, contrast, phosphor |
tts_backend |
"auto" |
TTS engine: auto, pyttsx3, espeak, festival, piper, coqui, dectalk, none |
piper_model |
"" |
Path to a Piper .onnx voice model for the piper backend (neural, offline). The matching .onnx.json must sit beside it. Also honored: PIPER_MODEL env var and Piper voice directories. |
tts_rate |
265 |
Reading speed in words per minute |
tts_volume |
1.0 |
Volume from 0.0 (silent) to 1.0 (full) |
tts_voice |
"" |
Voice ID; empty = system default (auto-resolved via tts_prefer_voice) |
tts_prefer_voice |
"eloquence" |
Substring of the voice to auto-select when tts_voice is empty (favors US English) |
tts_auto_play |
false |
Start TTS automatically on file open |
tts_skip_code |
true |
Skip fenced code blocks during TTS |
tts_auto_resume |
true |
Restore the reading position automatically on open |
wrap_width |
0 |
Text wrap column; 0 = terminal width |
tab_width |
4 |
Spaces per tab character |
show_line_numbers |
false |
Show line numbers in the left margin |
syntax_highlight |
true |
Syntax-highlight code blocks |
scroll_margin |
3 |
Lines of context above/below current position |
font_size |
0 |
Display font size in pt; 0 = default; meaningful in Qt GUI |
ocr_lang |
"eng" |
Tesseract language code(s) |
braille_table |
"en-ueb-g2.ctb" |
liblouis translation table (only used when braille_grade2 is true) |
braille_grade2 |
false |
Opt in to contracted Grade 2 via liblouis; otherwise the built-in Grade 1 translator is used |
audio_export_format |
"wav" |
Default audio export container (WAV needs no external tools) |
subtitle_format |
"srt" |
Caption format for subtitle export: srt or vtt |
subtitle_word_level |
false |
Emit one subtitle cue per word instead of sentence-grouped cues |
export_subtitles_with_audio |
false |
Also write an SRT/VTT caption track next to every audio export |
highlight_current_word |
true |
Highlight the spoken word during TTS |
highlight_color |
"cyan" |
TTS word highlight color (any Qt/CSS color name or #rrggbb) |
highlight_style |
"background" |
Qt karaoke highlight style: background (filled), underline, box (wavy underline), bold, color (colored text). Tune via View → Reading Aids → Karaoke Highlight… |
highlight_lead_words |
0 |
Qt only: words the visual highlight leads (+) or lags (-) the audio |
highlight_granularity |
"word" |
Highlight by word, whole sentence (less flicker), or both (sentence band + word). Qt + TUI; set via Karaoke Highlight… or M-x highlight-granularity |
highlight_speed |
1.0 |
Highlight timer speed as a fraction of tts_rate; 1.0 = match speech exactly. Values below 1.0 slow the timer (highlight lags audio); values above 1.0 run it faster. The pacing guard caps how far the timer can lead confirmed audio, so raising this above 1.0 does not cause runaway drift. |
recent_files |
[] |
Recently opened files (populated automatically) |
recent_files_limit |
20 |
Maximum entries in the recent files list |
gui_width |
1000 |
Qt window width in pixels |
gui_height |
700 |
Qt window height in pixels |
qt_font_family |
platform sans-serif | Qt display font family (Helvetica Neue / Segoe UI / DejaVu Sans); serif faces are discouraged for accessibility |
qt_font_size |
14 |
Qt display font size in pt |
qt_hidpi |
true |
Enable high-DPI scaling in the Qt GUI |
qt_ctrl_pause |
true |
Tap the Ctrl key alone to play/pause speech (JAWS habit); chords like Ctrl+O never trigger it |
qt_edit_preview |
false |
Show a live-rendered HTML preview beside the editor in edit mode (toggle with Ctrl+Shift+L) |
reading_stats |
{} |
Per-document reading time, progress, and session counts (populated automatically) |
library |
{} |
Library/bookshelf metadata for every opened document (populated automatically) |
profiles |
{} |
Named setting bundles (voice, rate, theme, font, spacing, highlight) saved via the Profiles menu |
pronunciations |
{} |
Pronunciation lexicon: {term: spoken form} applied before other TTS normalization |
use_pronunciations |
true |
Apply the pronunciation lexicon while reading |
qt_show_toc |
true |
Show the Contents panel at startup |
qt_show_notes |
false |
Show the Notes/annotations panel at startup (hidden by default to maximize the reading area; toggle with Ctrl+Shift+N) |
qt_line_height |
1.5 |
Qt line-height multiplier (WCAG 1.4.12). Adjust via View → Reading Aids → Text Spacing… |
qt_letter_spacing |
0.0 |
Qt extra letter spacing, percent of font size (0 = normal) |
qt_word_spacing |
0.0 |
Qt extra word spacing in pixels (0 = normal) |
qt_dyslexia_font |
false |
Prefer an installed dyslexia-friendly font (OpenDyslexic / Atkinson Hyperlegible / Lexend / Comic Sans) when available |
qt_current_line_highlight |
false |
Tint the line being read with a focus band |
qt_bionic_reading |
false |
Embolden the leading part of each word (bionic reading) |
annotations |
{} |
Per-document notes: {path: [{char_pos, word_idx, anchor, note, tags, cite, ts}]} |
citations |
[] |
Shared citation library (BibTeX/RIS/CSL-JSON import/export) |
whisper_model |
"base" |
Whisper model size for transcription/dictation (tiny…large) |
user_highlights |
{} |
Persistent text highlights per document path |
document_cache |
true |
Cache parsed documents for instant reopening |
cache_max_size_mb |
100 |
Maximum cache directory size in MB |
footnote_mode |
"inline" |
Footnote handling: inline, deferred, skip |
epub_show_chapters |
true |
Include chapter headings in EPUB rendering |
normalize_math |
true |
Convert math expressions to spoken English |
normalize_numbers |
true |
Convert numbers/dates/times/currency to spoken form |
expand_abbreviations |
true |
Expand common abbreviations before TTS |
abbrev_expansions |
{} |
Custom abbreviation overrides |
table_reading_mode |
"structured" |
Table TTS: structured, flat, skip |
use_ssml |
false |
Wrap TTS text in SSML for prosody (pyttsx3/eSpeak) |
ssml_sentence_pause_ms |
350 |
SSML pause after sentence-ending punctuation |
ssml_clause_pause_ms |
150 |
SSML pause after clause punctuation |
speak_image_alts |
true |
Read image alt-text aloud |
show_reading_level |
true |
Enable reading-level computation |
speed_presets |
(see below) | Named speed presets |
bookmarks |
{} |
Named bookmarks per document |
reading_positions |
{} |
Saved reading positions per document |
nav_history_size |
50 |
Within-session navigation history depth |
regex_search |
false |
Enable regex mode for search |
Default speed presets:
"speed_presets": {
"skim": 350,
"normal": 265,
"study": 200,
"slow": 150
}
📰 Plain-Text Mode
star --plain document.pdf
--plain skips all UI and writes clean, stripped plain text to stdout — the same text the TTS engine would receive. Useful for:
- Piping —
star --plain paper.pdf | festival --tts - Batch processing — extract text from many files in a shell script
- Word counting —
star --plain thesis.pdf | wc -w - Headless server use — where no display is available
🗂️ Batch Conversion & Hot-Folder Watching
Both features drive the same single-file load → export pipeline star already
uses, over the headless export formats: markdown (.md), text (.txt),
and braille (.brf). (Audio and subtitle export need speech synthesis and
stay in the interactive export-audio / export-subtitles commands.)
Batch conversion
Convert many documents — selected files or a whole folder — to one format in a single step:
- Qt GUI: File ▸ Batch Convert (
Ctrl+Shift+C). - Terminal UI:
M-x batch-convert.
You pick the inputs, one output format, and one output directory. Each file is
converted independently: a corrupt, password-protected, or unsupported file is
recorded and skipped, never aborting the run. Outputs reuse the source
basename (collisions are disambiguated, never overwritten), and a timestamped
summary — what succeeded, what failed and why, and where outputs were written
— is saved as star-batch-<timestamp>.log in the output directory.
Hot-folder watching
Watch a folder and convert anything dropped into it, unattended.
# Headless: convert every file added to ./inbox into ./out as Markdown
star --watch ./inbox --output ./out --format markdown
--format accepts the same names as batch conversion (markdown, text,
braille; default markdown). You can also start/stop it from the Qt GUI
with File ▸ Watch Folder (Ctrl+Shift+W, a toggle) while you keep working.
Behavior:
- Partial-write safe: a file is converted only after its size has stayed steady for a moment, so a file still being copied in is never read half-written.
- Source disposition: on success the source moves to
<input>/processed/; on failure it moves to<input>/failed/(so failures aren't reprocessed on restart or mistaken for successes). Name clashes are disambiguated. - Logging: every attempt is logged with a timestamp to
<output>/star-watch.log. - Clean shutdown: Ctrl+C / SIGTERM stop it without interrupting a file that is mid-conversion.
- Uses
watchdogfor real filesystem events when installed (the[watch]extra); otherwise it falls back to directory polling.
🧰 Command-Line Options
star [OPTIONS] [FILE_OR_URL]
| Option | Description |
|---|---|
FILE_OR_URL |
File path or HTTP/HTTPS URL to open on launch |
--gui |
Force Qt GUI mode (errors if PyQt6/PyQt5 not installed) |
--tui |
Force terminal UI mode even when Qt is available |
--plain |
Extract clean text to stdout; no UI |
--rate RATE |
Initial TTS reading rate in wpm |
--theme THEME |
Initial color theme: dark, light, contrast, phosphor |
--backend BACKEND |
TTS backend: auto, pyttsx3, espeak, festival, coqui, dectalk, none |
--watch DIR |
Watch DIR and convert files dropped into it (headless hot-folder mode); requires --output |
--output DIR |
Output directory for --watch conversions |
--format FMT |
Output format for --watch: markdown, text, or braille (default: markdown) |
--keytest |
Open the key-code diagnostic tool (TUI only) |
--list-themes |
Print available theme names and exit |
--list-voices |
Print available TTS voice IDs and exit |
--deps |
Print the status of every optional dependency (installed or not, with install hints) and exit |
--version |
Print version number and exit |
--help |
Print help summary and exit |
🗺️ Project Docs
See the companion documents:
| Document | What's in it |
|---|---|
CHANGELOG.md |
Full record of changes, starting with the 0.1.2 release |
BUILD.md |
Building the portable / fully self-contained Windows star.exe, and the cross-platform wheel |
build-vendor.py |
Downloads the bundled native engines (ffmpeg, Tesseract, liblouis, Pandoc, DECtalk) into vendor/ |
build_zipapp.py |
Builds the single-file fat star.pyz (bundles star plus its Python dependencies; see Project Layout) |
run_star.py |
Thin source-tree entry script (from star.app import main), used by python run_star.py and the PyInstaller build |
tools/install_native.py |
Installs the native engines on macOS/Linux via the system package manager |
pyproject.toml |
Wheel packaging metadata (star console command, dependency extras) |
Recently shipped:
-
Fully self-contained Windows binary —
star.execan now bundle ffmpeg (MP3/OGG/MP4 export), the Tesseract OCR engine with English data, liblouis with its tables (Grade 2 Braille), Pandoc (markup conversion), the DECtalk engine (DECtalk.dll+ dictionary, driven in-process via ctypes), and Whisper + PyTorch with thebasemodel for offline voice dictation & transcription, so a single file does everything on a clean PC. On that build DECtalk is the default engine with the classic Perfect Paul voice, and all nine DECtalk speakers appear in the voice picker. SeeBUILD.md. -
Reading accessibility aids (Qt GUI) under View → Reading Aids: adjustable letter/word/line spacing (WCAG 1.4.12), a dyslexia-friendly font preference, bionic reading, a current-line focus band, and karaoke highlight tuning (style / color / speed / lead).
-
Notes dock hidden by default to maximize the reading area (toggle with
Ctrl+Shift+N). -
Annotations / notes in both the Qt GUI and the TUI, with tags, full-text +
#tagsearch, and bibliography-aware export (Markdown / JSON / BibTeX / RIS). -
Citation manager — BibTeX / RIS / CSL-JSON import & export, with notes linkable to citations.
-
Whisper voice dictation & audio transcription (optional dependency).
-
GUI/TUI keyboard parity with a built-in cheat sheet, and full menu coverage so every command is reachable without the keyboard.
The core focus remains text-to-speech with active, synchronized word highlighting.
🧩 Project Layout
star is a small, importable Python package under star/, and it is
the canonical source — there is no longer a single-file star.py monolith.
Optional dependencies are imported lazily with graceful fallbacks, so the core
package runs on nothing but the Python standard library; add extras only for the
formats and features you want.
Run it as the installed star console command, with python -m star, or
straight from a checkout with python run_star.py. The same package is the unit
that ships in every distribution form: the cross-platform wheel, the fat
star.pyz zipapp, and the self-contained Windows star.exe. Its modules:
| Module | Responsibility |
|---|---|
star/_runtime.py |
Foundational shared state: stdlib imports, vendored-tool wiring, optional-dependency detection, app metadata and config paths. Re-exported wholesale via from ._runtime import *. |
star/settings.py |
Persistent settings store and defaults. |
star/ttstext.py |
TTS text preprocessing (SSML/DECtalk markup, abbreviation/number/date normalization). |
star/markup.py |
Lightweight markup → Markdown converters and the Pandoc bridge. |
star/documents.py |
Document model and the multi-format loaders (PDF, EPUB, DOCX, …). |
star/render.py · star/search.py |
Markdown → styled terminal lines; in-document search and the line editor. |
star/braille.py · star/annotations.py · star/citations.py · star/transcribe.py |
Braille export, notes, citation management, Whisper transcription. |
star/cache.py · star/stats.py · star/themes.py |
Document cache, reading statistics, color/CSS themes. |
star/tts.py |
TTS backends (pyttsx3, eSpeak-NG, DECtalk, Piper, Coqui, Apple say, …) and the manager. |
star/tui.py · star/gui.py |
The curses terminal UI and the Qt GUI. |
star/app.py |
Command-line entry point (star.app:main). |
star/__main__.py · run_star.py |
python -m star, and the source-tree entry script. |
Edit the package directly. Changes belong in the relevant
star/module. When you touch user-facing docs, refresh the copies bundled with the package (star/README.md,star/LICENSE,star/CHANGELOG.md) so F1 Help reflects the latest text. SeeBUILD.mdfor the wheel andstar.exebuilds, andbuild_zipapp.pyfor thestar.pyzbuild.
🤝 Contributing
Contributions are welcome. Please open an issue before submitting a pull request for anything beyond small bug fixes.
Keep dependencies optional. Every third-party package is imported at runtime with graceful fallbacks, and that pattern must be maintained — the core star package must keep working with nothing beyond the Python standard library installed. Contributions go into the relevant module under star/ (see Project Layout); there is no single-file monolith to keep in sync. The cross-platform wheel, the fat star.pyz, and the self-contained Windows star.exe are all built from the package — none of them is required to run from source (python -m star or python run_star.py).
Other guidelines:
- Target Python 3.11 compatibility. Do not use syntax or standard library features introduced after 3.11.
- All new keybindings must be documented in
README.md(opened byF1in the Qt GUI) and in this file. - New M-x commands must be added to both the command dispatch table and the Tab-completion list.
- New file format handlers should degrade gracefully when the required package is absent.
- Register every new optional dependency. When you add a guarded import (
try: import x … except ImportError), add a matching entry toOPTIONAL_DEPENDENCIESinstar/diagnostics.pyso it shows up instar --deps. The test suite enforces this — a new import guard with no registry entry failstests/test_dependencies.py. - Follow the existing code style — no external formatters mandated, but keep lines ≤ 100 characters and write docstrings for all public functions.
- This project is licensed under the GPL v3. By submitting a pull request you agree your contribution will be released under the same license.
Running the tests
The suite lives in tests/ and runs on pytest:
pip install -e ".[test]" # installs pytest
pytest # run everything
pytest tests/test_dependencies.py -v # just the dependency harness
The tests are written to pass with none of the optional packages installed — checks that need a given package skip when it is absent rather than failing, so a clean pip install -e ".[test]" checkout goes green. Two suites are worth knowing about:
tests/test_dependencies.py— the dependency harness. It treatsstar.diagnostics.OPTIONAL_DEPENDENCIESas the source of truth and enforces two guarantees: completeness (every import guard in the codebase is registered, so nothing is silently dropped fromstar --deps) and consistency (anything the harness reports as available really does import). Install an optional extra and re-run to exercise its real behavior.tests/test_features.py— unit tests for the study/reading features, including each one's graceful-degradation path (a clear error or empty result when its package is absent).
📜 License
star — Speaking Terminal Access Reader
Copyright 2026 Jon Pielaet
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License version 3 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful, but without any warranty — without even the implied warranty of merchantability or fitness for a particular purpose. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program. If not, see https://www.gnu.org/licenses/.
To view the full license text from within star, run:
M-x license
Project details
Release history Release notifications | RSS feed
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 star_reader-0.1.8.tar.gz.
File metadata
- Download URL: star_reader-0.1.8.tar.gz
- Upload date:
- Size: 409.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f26537a6b38dbcb90aad16f709acc36a2ff2e9246949ea21d9aab75c84c2fa78
|
|
| MD5 |
477158ea53c282c6dac6a5e4a766c2c3
|
|
| BLAKE2b-256 |
0695d6b6c7a1f3e5eb0b9186dc864aa92d69bb7e5bb3d68831fd3ab42159cc3e
|
Provenance
The following attestation bundles were made for star_reader-0.1.8.tar.gz:
Publisher:
release.yml on leavesofgrass/star
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
star_reader-0.1.8.tar.gz -
Subject digest:
f26537a6b38dbcb90aad16f709acc36a2ff2e9246949ea21d9aab75c84c2fa78 - Sigstore transparency entry: 1932907455
- Sigstore integration time:
-
Permalink:
leavesofgrass/star@836627ba967268ef6ab2e4e9dc0efb70f4fe0007 -
Branch / Tag:
refs/tags/v0.1.8 - Owner: https://github.com/leavesofgrass
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@836627ba967268ef6ab2e4e9dc0efb70f4fe0007 -
Trigger Event:
push
-
Statement type:
File details
Details for the file star_reader-0.1.8-py3-none-any.whl.
File metadata
- Download URL: star_reader-0.1.8-py3-none-any.whl
- Upload date:
- Size: 337.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2e5c529fc1547d433bf009817a79178725f2c435496d5a91004ef145ffe6a51c
|
|
| MD5 |
111acc5b4111c216a993e4b129d790b0
|
|
| BLAKE2b-256 |
44760af62ef13b0cbaf9d33676dbe26be5803b459c930fe1649210bab306f084
|
Provenance
The following attestation bundles were made for star_reader-0.1.8-py3-none-any.whl:
Publisher:
release.yml on leavesofgrass/star
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
star_reader-0.1.8-py3-none-any.whl -
Subject digest:
2e5c529fc1547d433bf009817a79178725f2c435496d5a91004ef145ffe6a51c - Sigstore transparency entry: 1932907599
- Sigstore integration time:
-
Permalink:
leavesofgrass/star@836627ba967268ef6ab2e4e9dc0efb70f4fe0007 -
Branch / Tag:
refs/tags/v0.1.8 - Owner: https://github.com/leavesofgrass
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@836627ba967268ef6ab2e4e9dc0efb70f4fe0007 -
Trigger Event:
push
-
Statement type: