No description
Find a file
agent 2df91b561d Bring spec and README up to date
The spec still listed undo, the eraser, colours and smoothing as
missing. Describe the ink engine and palm rejection as built (draw vs
navigate intents, settings toggles, cancelled pointers), the plus
buttons, fling offer, grid and page size dialog, note that sync is
GitHub-only, and replace the stale open item with the real ones.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GaoZtJQZwLXkEgWs8twCia
2026-09-27 21:31:54 +00:00
.claude Init 2026-09-26 19:13:02 +02:00
docker Fix imported PDFs not rendering in the Docker image 2026-09-27 09:37:15 +00:00
memos/memos Init 2026-09-26 19:13:02 +02:00
scripts Init 2026-09-26 19:13:02 +02:00
src Add background grid settings 2026-09-27 21:31:12 +00:00
static Init 2026-09-26 19:13:02 +02:00
.dockerignore Show the build's version and commit in Settings 2026-09-27 20:08:19 +00:00
.gitignore Init 2026-09-26 19:13:02 +02:00
compose.yaml Add Dockerfile and compose setup for self-hosting 2026-09-26 22:33:08 +00:00
Dockerfile Add Dockerfile and compose setup for self-hosting 2026-09-26 22:33:08 +00:00
package-lock.json Init 2026-09-26 19:13:02 +02:00
package.json Init 2026-09-26 19:13:02 +02:00
palm-rejection-test.html Init 2026-09-26 19:13:02 +02:00
README.md Bring spec and README up to date 2026-09-27 21:31:54 +00:00
spec.md Bring spec and README up to date 2026-09-27 21:31:54 +00:00
svelte.config.js Init 2026-09-26 19:13:02 +02:00
tsconfig.json Init 2026-09-26 19:13:02 +02:00
vite.config.ts Show the build's version and commit in Settings 2026-09-27 20:08:19 +00:00

Papure

Lecture notes as a tree of pages ("comb") — live-preview markdown underneath, vector ink on top — stored as one dual-layer PDF per canvas and synced through a GitHub repo. See spec.md for the design.

Run

npm install
npm run dev        # http://localhost:5173
npm test           # unit tests (tree, markdown, PDF round trip, sync against a fake GitHub)
npm run check      # type-check
npm run build      # static PWA in build/ — serve it from any static host (HTTPS for PWA install)

Docker

docker compose up -d --build    # http://localhost:8080 (set PAPURE_PORT to change)

The image builds the PWA and serves it with nginx. Put an HTTPS reverse proxy in front of it: installing the PWA and the offline service worker both need HTTPS. To update, git pull and run the same command again.

Using it

  • Tools (bottom bar): Text T, Pen P, Highlighter H, Eraser E, Import PDF, Undo/Redo, zoom. The pen's eraser end erases too.
  • Pages: the "+" circles beside the active page add a page there (a quick finger fling past a free edge highlights that side's "+"); Alt+Arrow moves to (or creates) the neighbour. Right-click a page or use its ⋯ button to insert, resize or delete it.
  • Grid: the faint background grid has one cell per active page; Settings → Appearance can hide it or subdivide it.
  • Importing a PDF into a non-empty canvas shows every free spot; click one to place the chain. Into a blank canvas it simply replaces the empty page. The Files panel can also import a PDF as a new canvas.
  • View: wheel/trackpad pans, Ctrl+wheel or pinch zooms, Ctrl+0 fits the page, Ctrl+9 shows the whole tree, space-drag or middle-drag pans.
  • Sync: Settings → Sync. Use a fine-grained token with Contents: read & write on the repo. Edits autosave locally; pushes happen every N minutes and on Ctrl+S / the sync button. Conflicts: newer wins.

Layout

  • src/lib/model — page tree (pure functions: insert/remove/flatten/layout).
  • src/lib/editor — markdown analysis shared by the CodeMirror live preview and the PDF text layout.
  • src/lib/pdf — PDF writer (vector text, Ink annotations, embedded source-of-truth files) and reader.
  • src/lib/ink — stroke recording/outlines and palm rejection (ported from palm-rejection-test.html).
  • src/lib/storage, src/lib/sync — IndexedDB vault and GitHub sync.

Fonts in static/fonts are pre-subset (scripts/subset-fonts.sh) because pdf-lib's own subsetter drops glyphs.