Original-language reader for Kant, Aristotle & more: select any passage to gloss, translate, or hear it read aloud, with exact citations.
TypeScript 89%
CSS 10%
JavaScript 1%
HTML <1%
<1%

README.md

lekterion #

A reader and language-study tool for philosophical texts in their original languages — German (Kant, Husserl), Ancient Greek (Aristotle), and Latin (Descartes). Inspired by the Perseus Hopper reader: select any span of text to gloss it, translate it, or hear it read aloud, with page-accurate citations (Akademie, Bekker, AT …) and side-by-side facsimile scans.

Features #

  • Reading view with locus anchors and canonical citation schemes — every selection carries a citation like KrV A 51 or Met. 980a21, and every position is a shareable URL.
  • Gloss & translate — select a word or passage and one Claude call returns a contextual gloss, a full translation, and a word-by-word literal alignment, in the reader's chosen target language. Results are cached content-addressed by hash(quote + citation), so each span is generated at most once, shared by all readers, and reopenable via ?art= links.
  • Read aloud — OpenAI TTS synthesizes the original-language span once and caches the clip; single words are warmed from multi-word clips.
  • Facsimile pane — synchronized page scans (Husserl page images in-repo; PDF rendering via pdf.js) alongside the transcription.
  • Fluency tracking — per-reader word-fluency signals tint the text, doing triple duty as reading aid, study signal, and OCR-proofreading radar.
  • Corrections — readers can propose text corrections stored as diffs over the immutable canonical source; admins can promote them globally.
  • Agent/CLI-friendly corpus — each text is also served as canonical Markdown (/corpus/<id>.md, discoverable via /llms.txt), no JS required.

Stack #

Vite + React SPA (shadcn/Radix UI) · Convex backend (state, AI-result cache, AI proxying via actions) · Cloudflare Workers static hosting · Claude (gloss/translation) · OpenAI (TTS). The canonical texts are Markdown files in sources/, compiled at build time by a deterministic ingest (scripts/ingest/) into a static document model — Convex holds only mutable, per-reader, and cache data.

Getting started #

Prereqs: bun.

bun install
bunx convex dev        # provisions a dev deployment, writes .env.local
bun run dev            # ingests sources/ then starts Vite

The AI features need provider keys in the Convex environment (they never reach the client). Put LEKTERION_ANTHROPIC_API_KEY and LEKTERION_OPENAI_API_KEY in .env.local, then:

bun run convex:env     # forwards the keys to the Convex deployment

Paid AI calls (gloss/translate, new TTS synthesis) require a signed-in reader and are per-reader rate limited (convex/limits.ts); anonymous readers get every cached result for free. Sign-in goes through a small external JWT broker (src/auth/, convex/auth.config.ts) — a fork will want to point those at its own issuer.

Corpus and licensing #

  • Code is MIT-licensed.
  • Texts in sources/ are public-domain works: Kant (Kritik der reinen Vernunft A/B, Grundlegung, Was heißt: sich im Denken orientieren?), Husserl (Ideen I), Aristotle (Metaphysics, Physics, Rhetoric, De Interpretatione), Descartes (Meditationes, Principia). Transcription provenance is credited in each file's header; the Kant KrV A text is rebuilt from the Deutsches Textarchiv double-keyed transcription (CC BY-SA 4.0 — see scripts/sources/), and the Aristotle texts come from PerseusDL.
  • The ingest also supports local-only texts that are not part of the repository (editions that may not be redistributed): anything under a gitignored sources/ subdirectory is served in the app but gets no Markdown export, no /llms.txt entry, and is never committed.