Andolika Labs / Sulekha
1.0 alpha सुलेख · fair handwriting · Linux
The PDF viewer for people who write LaTeX and teach from it.
Sulekha is a small, stylus-first PDF viewer and annotator. It reloads your paper as LaTeX rebuilds it, follows every cross-reference, and turns a Beamer deck into a lecture: presenter view, speaker notes, ink that clears itself, and a recording you can publish as video.
Notes · slides 12–14
Cost is O(N log N); stability needs Δt ≤ h²/2α. Say why before the proof.
# two ghost cells each side u = pad(u, 2) u[2:-2] += dt * laplacian(u, h) # explicit
Made for what LaTeX produces
Most viewers treat a PDF as a picture. Sulekha treats it as the output of a build: a file that changes, that points at itself, and that sometimes moves.
Rebuild, and it is already on screen
Reading mode never holds the file open. Run latexmk in one window and the page redraws in the other, on the page you were reading. No lock, no stale copy, no reopen.
- Opens read-only by default. A file from the command line, a file manager or a browser is for reading. One key switches to annotating when you meant to write on it.
- Dark reading inverts the display without touching the file, so a paper reads at night and prints the right way up.
- Fast cold start, parallel rasterisation with prefetch, and anchored zoom that stays sharp at every scale.
# one terminal latexmk -pvc -pdf paper.tex # the other, once; it follows the file from then on sulekha paper.pdf # open a paper at the proof you are checking sulekha --page 14 --find "Lemma 3" paper.pdf
Cross-references that show, not just jump
Rest the pointer on a \cite and the bibliography entry appears where you are. Rest on a \ref to a figure and you get the figure with its caption. Following the link is optional, which is most of the work of reading a paper with references in it.
- The item itself, not a slice of the page: entries are found by their hanging indent, captions by their gap.
- Click to turn to the target; URLs open in your browser. Only
http,httpsandmailtoare honoured, neverjavascript:orfile:. - Contents sidebar from the document's outline, text selection and copy, and find with match navigation.
animate package
\animateinline and \animategraphics play at the rate the file asks for, looping or in palindrome, several to a slide, restarting each time you arrive. No JavaScript is run; Sulekha reads the frames and keeps the clock itself.
media9 video
\includemedia clips play inside the slide, on page open or on a click. The H.264 inside the PDF is pulled out and played directly, so it works years after Flash stopped.
Beamer overlays
Speaker notes accept a range, ## Slides 4-6, so one note covers every overlay of a logical slide. Chapter marks in an exported video follow the deck's table of contents.
Teach from your Beamer deck
Press F5, or start the lecture in one command. The deck goes fullscreen on the projector and the presenter view opens on your screen.
A presenter view that is a mirror
It shows the slide the room sees, the next one, the slide number, an elapsed timer and the time of day. Ink, laser and spotlight appear on it live, exactly as the audience sees them. And because that is where your hands are, drawing on the presenter view lands on the screen behind you.
- Ink is ephemeral. Draw over a slide and it clears when you move on, so next year's deck does not carry this year's arrows. Press e to keep it.
- Laser pointer and spotlight, blank to black or white, and the screen is held awake for the whole talk.
- d swaps the displays when the compositor puts the deck on the laptop and the presenter view on the projector. Every lecture starts that way somewhere.
- A pen is in hand the moment the talk begins. The eraser reaches stage ink too, from the stylus's other end or 5.
| → ← Space | Next / previous slide, what a clicker sends |
| b / w | Blank to black / white |
| l / s | Laser pointer / spotlight |
| 1–4 / 5 | Take up an instrument / the eraser |
| x / e | Wipe this slide's ink / keep ink instead of clearing |
| a / Shift+A | Hold animations / play them from the start |
| v | Start or stop the video on this slide |
| t / Shift+R | Start or pause the timer / reset it |
| d | Swap the displays |
| r | Pause or resume the recording |
| Esc F5 q | End the presentation |
Speaker notes in Markdown, beside the deck
lec01.pdf gets lec01.notes.md, a heading per slide. It lives beside the PDF rather than inside it, because a deck is regenerated and anything written into it is lost on the next build. The file is re-read every time you save it, including mid-rehearsal with the presenter view open.
- Maths renders.
$\Delta t \le \frac{h^2}{2\alpha}$comes out as symbols, fractions and roots. What it does not understand is shown as written, never swallowed. - Code is coloured for Python, C/C++/CUDA, Julia, MATLAB, Fortran, Rust, shell and TeX. Pipe tables line up.
- The layout fits the screen. A full-height column on an ultrawide at the lectern, the band under a 16:9 deck on a 16:10 laptop, or a sidebar. Long notes set in two balanced columns, with type that grows with the pane.
- Edit Speaker Notes… writes the template for you, with each slide's title from the outline, and never overwrites a file that exists.
## Slide 1 Welcome them. Names, office hours, and **why this course exists**. ## Slides 4-6 One note for the whole overlay build-up. ## Slide 12: Stability Cost is $\mathcal{O}(N \log N)$, stability needs $\Delta t \le \frac{h^2}{2\alpha}$. Say why before the proof. ```python u = pad(u, 2) # two ghost cells u[2:-2] += dt * laplacian(u, h) # explicit ```
Record the lecture. Publish the video.
Your voice, the slide changes and every stroke of ink, with its own timing, so a line replays as it was drawn rather than appearing whole.
A recording you can read without Sulekha
The talk lands in a directory beside the deck: a plain-text timeline and a WAV file. The timeline is written as the talk happens, so a laptop that dies at minute fifty leaves fifty minutes behind. The audio has no encoder in the path, because an encoder is one more thing to fail an hour into a lecture.
- Replay in place, navigating by slide rather than by minute. The sound is the clock, so an hour in, a stroke still lands on the sentence that explains it.
- Pause for questions with r. The presenter view shows a red recording indicator and warns when no sound is arriving.
- Animations and video are in the recording, at the moment the room saw them, with ink on top.
lec05.pdf
lec05.notes.md
lec05-20260929-1430.talk/
talk.txt the timeline, plain text
audio.wav the voice
lec05-20260929-1430.mp4 after export
lec05-20260929-1430.chapters.txt for the description box
sulekha-talk 1 deck lec05.pdf 0 slide 1 14320 slide 2 19022 ink 2 pen ballpoint 2.5 e02020ff | 120.4,88.1,1,0 … 41880 clear 2 42110 blank black
Export to video, with a chapter per slide
One H.264 file beside the recording, 1920 pixels wide at the deck's aspect ratio by default. An hour of lecture encodes in about two minutes. Chapters are named from the deck's table of contents, so the slide where a section begins reads Slide 6, Truncation error and the slides under it are just numbered.
- YouTube-ready chapter list written alongside as plain timestamps, ready to paste into a description.
- Scriptable. Record, export and upload from a shell script with no window ever opening.
- Only the export needs ffmpeg. Recording and replay work without it.
# start the lecture in one command sulekha --present lec05.pdf # present and record together sulekha --record lec05.pdf # watch the newest recording back sulekha --replay lec05.pdf # export it to video and quit, no window sulekha --export-width 2560 lec05.pdf
# lec05-20260929-1430.chapters.txt
0:00 Slide 1 — Introduction
1:05 Slide 2
4:31 Slide 3 — Truncation error
And a serious annotator the rest of the week
Marking papers, grading, signing forms, keeping a notebook. The editing verbs are deliberately few: draw, highlight, erase, add page, delete page, reorder page. That restriction is the product.
Pressure-sensitive ink
Four nibs, a translucent highlighter that sits behind the text, a stroke eraser and one that rubs out part of a stroke. Low latency with retroactive palm rejection.
Four instruments
Each slot is a complete pen with its own kind, nib, width and colour, set from one popup and shown in its own colour on the palette.
Text-snap highlights
Select words and highlight them as real PDF highlight annotations. Every note and highlight is listed in the sidebar.
Shapes and lasso
Line, arrow, rectangle and ellipse with whatever pen is in hand. Loop ink to move or resize it.
Typed notes and forms
Tap and type a note saved as FreeText. Fill text fields, checkboxes, radios and menus, with the fillable parts washed pale blue so a form says it is one.
Signatures
Sign once, then tap to place from a library. Saving in place keeps an existing digital signature intact.
Pages
Insert, delete, reorder, rotate and extract a selection to a new file, from a thumbnail sidebar with drag-to-reorder.
Notebooks
New documents from paper templates: blank, ruled, grid, dotted or Cornell, with a coloured cover, in a library with folders.
Print with the ink on it
The paper turns to suit a landscape deck by itself, and the preview opens in Sulekha when the desktop has no previewer.
Never lose ink
Undo and redo, crash recovery that offers unsaved ink back, and a prompt before anything would discard it.
Everything is a PDF
A notebook is a PDF whose pages came from a template. No second format, no import or export step, no sidecar to lose. Ink is written as standard annotations that every other reader renders, with the raw pressure samples alongside so Sulekha can reopen a stroke losslessly instead of degrading it to a polyline.
Saving in place is incremental: the original bytes are untouched and only the changes are appended. A save costs what the edit cost, not what the document weighs.
/InkList | The centreline, so a basic viewer shows something sane |
/AP /N | The exact variable-width outline a conforming viewer draws |
/Sulekha_Data | Raw pressure samples, for lossless re-editing |
/BM /Multiply | Highlighters sit behind the text in every reader |
/FreeText /Highlight | Typed notes and text highlights, as any reader expects them |
Get Sulekha
Free software under the AGPL-3.0. One small binary: Rust, GTK4 and libadwaita, with MuPDF underneath. Currently at 1.0 alpha and in daily use.
Arch Linux
A package built from the release tarball with the whole test suite run during the build. ffmpeg is optional, for video export only.
cd packaging && makepkg -f sudo pacman -U sulekha-*.pkg.tar.zst
Flatpak
Builds against the GNOME 48 runtime with no network in the sandbox. The first build is slow because MuPDF is compiled from source.
flatpak-builder --user --install \ --force-clean build \ build-aux/org.andolika.Sulekha.yaml
From source
Needs Rust 1.85 or newer, GTK 4.16, libadwaita 1.6 and a C toolchain. Installs the binary, desktop entry, icon and AppStream metadata.
cargo build --release
make install # into ~/.local
Questions about Sulekha?
Teaching from a deck Sulekha trips over, or a paper it should handle better? Tell us. Bugs and decks that break things are especially welcome.