Sidemark is a lightweight PDF annotator for Linux with a live Markdown notes panel. Open a PDF — lecture slides, papers, or any document — draw directly on it, and write structured notes beside it.
If Sidemark is useful to you, please ⭐ star it on GitHub and 🗳️ vote for it on the AUR — it's the main way other people discover the project.
▶ Online demo — no install, and your files stay on your machine. It runs a subset of the features below (there's a six-step tour of the parts worth knowing). Use a Chromium-based browser: Firefox draws just as well but can't save in place, only download. More in web/README.md.
Sidemark was built for taking lecture notes. It works with two plain files and nothing else: your document stays a .pdf and your notes are a .md sidecar you can open in any editor. Annotations are written straight back into the PDF as native ink, so what you draw and write stays in formats you already use everywhere.
- Just PDF and Markdown — strokes save as native PDF ink annotations; notes save as a standard
.mdsidecar that's Obsidian-compatible and readable anywhere - Markdown notes built for lectures — a full Markdown editor sits beside the page, scoped to whichever page you're on, with fast inline math for the things that actually come up in a lecture: indices, exponents, and Greek letters (
x^2,\alpha,\sum…) - Open PowerPoints directly — and present on them — a
.pptxconverts to PDF automatically with each slide's speaker notes imported into the notes sidebar; presenter view (F5) mirrors the slide to a second screen and shows your ink live while you teach - Anchor notes to the page —
Ctrl+Alt+clickdrops a numbered marker that links an exact spot on the PDF to the matching paragraph in your notes; callouts render the note right on the page with an arrow - Rearrange pages by drag-and-drop — reorder, import, and export pages from the thumbnail sidebar by dragging (drag pages out to a file manager to export, drop a PDF in to insert), inspired by Apple's Preview
- GoodNotes-style lasso — loop around existing ink to select it, then drag to move, recolour, or delete it as a single undo step
- Draw with a configurable pen — strokes are saved as native PDF ink annotations and are individually erasable by right-click-dragging. Handwriting is pressure-sensitive on a stylus, and blank pages can be ruled (lines, squares or dots) from the ☰ menu so you write straighter
- Shape snap — hold still mid-stroke to clean up what you drew: a straight line, or a neat rectangle or ellipse from a rough loop. Draw a line inside a box and it becomes an evenly-spaced grid divider — handy for tables and matrices. Set it to lines-only or off in the pen settings
- Highlighter — wide translucent strokes with their own color and width, saved like any annotation. Long-press the tool for mark text, which lays clean highlight bands over the words you drag across — still ink, so erase and undo work unchanged
- Lasso ink (middle-drag, or the lasso tool on any button) — loop around strokes to select them (GoodNotes-style), or just click one;
Shiftadds more to the selection. The loop stays as the selection's outline: drag anywhere inside it to move, or tap the chip at its top-left to swap it for a resize box — corner handle to resize (a side handle stretches one axis), the knob above to rotate.Ctrl+Dto duplicate,Deleteto remove, or pick a new colour/width to recolour — each a single undo step - Paste images (
Ctrl+V) — drop a picture from the clipboard onto a PDF page or a text page and it behaves like ink: move, resize and rotate it with the lasso, forever — never a flattened stamp. Whatever tool you're holding, a fresh paste is ready to drag straight away.Ctrl+Ccopies a selection back out — Sidemark gets the real strokes and images, every other app gets a picture. ☰ → Import this page's images does the same for the pictures that came with the PDF, so a figure on a slide becomes something you can move — and it only takes the ones that will still look identical to every other reader - Undo / redo (
Ctrl+Z/Ctrl+Y) — works across both the canvas and notes; undo a stroke, an erase, or a burst of typing in the order you made them
- Live Markdown with syntax highlighting, inline math (
x^2,\alpha,\sum…) and formatting shortcuts (Ctrl+B,Ctrl+I,Ctrl+E). Task boxes (- [ ]) render as a checkbox you click to tick, andEntercarries a bullet, numbered or task list on to the next item. Symbols render for display only — the.mdalways keeps the source\commands, so notes round-trip cleanly through other editors.Ctrl+±/Ctrl+scrollzooms the notes font (remembered between sessions) - Anchor markers (
Ctrl+Alt+click) — numbered circles placed on the PDF that link to the corresponding paragraph in your notes - Callout boxes (
Ctrl+Alt+drag) — an anchor plus its note paragraph rendered in a box on the PDF, arrow included; drag the anchor or the box to reposition. Renders the same inline math and Markdown as the notes; included in exports - Standalone text boxes (
Ctrl+Alt+right-click) — drop typed text straight on the page, no anchor; edit it in the notes panel, drag it to reposition; included in exports - Notes that run over several pages — tick Continue from page N in the notes header and this page shares the previous page's notes, so a thought started on slide 12 keeps going on 13 and 14 without copying anything. One tick carries on through the blank pages that follow, stopping where notes already exist; unticking splits the run from that page onwards
- Hide pages — right-click a page in the thumbnail strip (or several, Ctrl+click) and hide it: hidden pages are skipped as you page through the document and while presenting, and are left out of an export — so one deck can produce a shorter handout. They stay in the file, dimmed in the strip, and unhide the same way
- Bookmarks — mark a page with the bookmark button (or
Ctrl+B): a name field opens with a suggestion ready to overtype, andEntermakes the bookmark (Esccancels it); hold the button for a list of every mark to jump to. Your bookmarks appear in the outline with a ★ (tick "Bookmarks" there to hide them), so a deck with no outline of its own still gets one. Sidemark also reopens each document on the page you last read - Date / time snippets — type
/date,/time, or/nowthen Space to expand - Choose where notes live — each PDF gets a
<filename>-notes.mdsidecar, created only once you actually write something; pick Notes file… from the ☰ menu to point several PDFs at one shared Markdown file (remembered per PDF) - Slide between the two modes — drag the notes divider all the way left and your notes become one full sheet you can write on; the page is still there behind it, so drag the same edge back out and it slides in again. Nothing is converted or written, so an accidental drag costs nothing, and each document reopens in the view you left it in
- Text-first mode — open a bare
.md(or New text page,Ctrl+Alt+N) and the window becomes one endless A4 sheet of live Markdown you can draw on with the same pen, highlighter, eraser and lasso — shape snap, smoothing, move/resize/duplicate included (ink rides along with the text you anchor it to). Drag the paper's side edge to set the sheet width — handy on a half-screen window — and it's remembered per document. The file stays pure Markdown — ink lives in a<name>-ink.jsonsidecar — and Export as PDF renders text and ink to A4 pages. There's also a persistent scratchpad page, always waiting at the bottom of Recent files
- Pan & zoom — scroll to pan,
Ctrl+scrollor pinch to zoom (centered on the cursor),Ctrl+dragto pan,Shift+dragto zoom to region,Shift+clickto fit page - Page flip —
PageDown/PageUpor the mouse back/forward side buttons (they work even while typing notes); scrolling past a page edge flips automatically - Follow links —
Alt+clicka footnote, citation, or cross-reference to jump to its target (scrolling to the exact spot, even on the same page);Alt+Leftjumps back to where you were reading. External URLs open in your browser. Links light up whileAltis held, or whenever the text-cursor tool is in hand - Outline & thumbnails —
Ctrl+Ttoggles a sidebar between table of contents and page thumbnails; drag thumbnails to reorder pages, drop documents onto the sidebar to import them as chapters at that spot, drag a chapter in the outline to move all of its pages at once, or drag pages out to a file manager to export them as a standalone PDF (annotations and notes included), like macOS Preview - Add / delete pages — insert blank pages with the same dimensions as the current page
- Presenter view (
F5) — mirrors the current page fullscreen on a second screen, your ink updating live while you draw, and can be driven from either side (clicker-friendly). Your own window switches to a presenter layout — current slide, a peek at the next one, a presentation timer and large prev/next buttons — none of it visible to the audience
- Formats — opens
.pdf,.pptx(auto-converted via LibreOffice) and.mdfiles (a<name>-notes.mdsidecar reopens its PDF; other text files open as a text-first page); drag files from your file manager onto the window - Merge a semester into one document — drop several files at once and choose Merge: each becomes a chapter in the outline, in filename order that counts numbers as numbers (
1,2,10,101), and their notes and pasted images come along with the page numbers adjusted - OCR for scans — a scanned PDF with no text layer triggers an offer to make it searchable in the background (also on demand from the ☰ menu). Needs the optional
ocrmypdftool —./install.sh --with-ocrinstalls it - Share to phone (live) — the QR-code button opens a live view in a phone's browser that follows along as you draw, annotate and flip pages, with a download of the fully exported PDF — so an audience can watch on their own phones while you teach. Works on the same Wi-Fi, or from anywhere via Tailscale; the QR code needs the optional
qrencodetool - Tabs — files open as tabs (the strip appears only with more than one document);
Ctrl+Wcloses,Ctrl+Shift+Treopens, and tabs drag out into their own window or between windows. Sidemark runs as a single instance: every launch lands as a tab in the window you were last using (SIDEMARK_NEW_WINDOW=1gives each launch its own window) - Recent files — in-app menu, XDG recent-files integration (GTK / GNOME / KDE file dialogs), and an optional walker / Omarchy launcher menu
- Text selection —
Alt+dragselects words in reading order and copies them (or put the text-cursor tool on a button to make plain drags select); long-press the select tool for a rectangular marquee, handy for tables and code - Design scheme — inherits accent color and dark / light mode from Omarchy, GNOME, or KDE automatically
- Tools live on mouse buttons — there is no "active tool" to switch between: left draws, right erases and middle lassos at the same time, and every button and modifier chord is rebindable. Click a tool in the header with the button you want it on, and it goes there — coloured stripes under each tool show which buttons run it, and they repaint live as you hold a modifier, so the bar is always a readout of what your hand would do right now
- Stylus and touchscreen — a pen's ends are mouse buttons: the tip draws, the eraser barrel button erases, the other barrel button lassos, so the defaults work the moment you pick up a stylus. A finger pans rather than draws, which keeps a resting palm from scribbling on the page while you write — rebind it like any other button if you'd rather draw with your finger
- Responsive header — the compact single-row toolbar folds progressively as the window narrows (file actions live in the ☰ menu), so the core controls stay reachable at any width
yay -S sidemark # latest release
yay -S sidemark-git # latest development version (master)git clone https://github.com/brokkoli71/sidemark
cd sidemark
./install.shInstalls the app, creates a launcher entry, registers it as the default handler for PDF and Markdown files, and installs bash tab-completion for the sidemark command. If OCR support isn't already present it offers to install it (see below). Run ./install.sh --help for all flags; the main ones are --with-ocr (install OCR support for scanned PDFs without prompting), --walker-menu (launcher recent-files menu, see below) and --register-pptx (also become the default handler for PowerPoint files, which open via LibreOffice conversion).
./install.sh --uninstallsidemark [OPTIONS] [FILE] # FILE: a .pdf, .pptx, .md, or text file
sidemark --help # full option list
sidemark --page 5 lecture.pdf # open at a given page
sidemark --new # start on a blank page (--new-text for paper)
sidemark --tmp # scratch page that closes without asking to saveTab-completion for the sidemark command's options and files is installed automatically (start a new shell to pick it up). To complete ./install.sh's own flags, source extras/install.sh.bash from the repo (both work in zsh after autoload -U +X bashcompinit && bashcompinit).
git clone https://github.com/brokkoli71/sidemark
cd sidemark
python sidemark.py [file.pdf]
# Add -v / --verbose for debug loggingDependencies:
Arch / EndeavourOS:
sudo pacman -S python python-gobject gtk4 libadwaita python-pymupdf python-numpy python-cairo gtksourceview5Ubuntu / Debian:
sudo apt install python3 python3-gi python3-gi-cairo python3-numpy \
gir1.2-gtk-4.0 gir1.2-adw-1 gir1.2-gtksource-5 \
libgtk-4-1 libadwaita-1-0 libgtksourceview-5-0
pip install pymupdf| Input | Action |
|---|---|
| Left-drag | Draw stroke |
| Hold still mid-stroke | Snaps to a clean line, rectangle or ellipse — or, for a line inside a box, an even grid divider (GoodNotes-style); keep holding and move to aim a line, release to commit |
| Right-drag | Erase stroke (including from previous sessions) |
| Middle-drag | Lasso: loop around strokes to select them, then drag inside the loop to move · chip at its corner for the resize box · Ctrl+D to duplicate · Delete to remove · change colour/width to recolour · Escape to clear |
| Click a tool with any button | Binds that tool to that button — every row in this table is a default you can change |
Ctrl+Z |
Undo the last action — a stroke, an erase, or a burst of typing — works across drawing and notes regardless of where the cursor is |
Ctrl+Y / Ctrl+Shift+Z |
Redo the last undone action |
Alt+drag |
Select & copy text (snaps to whole words) — works in either mode |
| Long-press select tool | Switch text selection between reading-order (default) and rectangular |
| Long-press highlighter tool | Switch highlighter between free-hand (default) and mark-text (drag over words to highlight whole lines) |
| Key | Action |
|---|---|
PageDown |
Next page (keeps current zoom) |
PageUp |
Previous page (keeps current zoom) |
| Mouse forward / back buttons | Next / previous page — works anywhere in the window, even while editing notes |
Alt+click |
Follow the link under the cursor — a footnote, citation, or cross-reference jumps to its target (URLs open in your browser) |
Alt+Left |
Jump back to where you were before following a link |
Ctrl+Shift+N |
Add blank page after current |
Ctrl+Shift+Delete |
Delete current page |
F5 |
Toggle presenter view — mirror the page fullscreen on a second screen (Esc to close) |
Ctrl+T |
Toggle outline / page-thumbnail sidebar (Outline ⇄ Pages switcher when the PDF has both) |
Click / Shift / Ctrl+click thumbnail |
Click selects a single page; Shift+click marks every page between it and the last one you clicked; Ctrl+click adds or removes one |
| Drag thumbnail → thumbnail | Reorder pages (in the page-thumbnail sidebar) |
| Drop a PDF → between thumbnails | Insert that PDF's pages at the drop point (a drop line shows where) |
| Drag thumbnail(s) → file manager / desktop | Export the dragged page(s) as a standalone PDF (notes appended), like macOS Preview |
| Input | Action |
|---|---|
| Two-finger drag (touchpad) / scroll wheel | Pan — a touchpad pans smoothly in any direction (no axis lock) |
| Scroll past page edge | Flip to next / previous page (keeps zoom) |
Ctrl+scroll |
Zoom in/out (centered on the cursor) |
| Pinch (two-finger) | Zoom and pan together — the points under your fingers stay fixed on the page |
Ctrl+drag |
Pan (every mouse button is rebindable — click a tool in the bar with the button you want it on) |
Shift+drag |
Zoom to region |
Shift+click |
Fit page |
| Key | Action |
|---|---|
Ctrl+B |
Bold selection while writing notes; bookmarks the page otherwise (hold the bookmark button for the list) |
( [ { " … |
Surround the selection with the bracket / quote pair |
Ctrl+I |
Italic selection |
Ctrl+E |
Inline code selection |
Ctrl+D |
Duplicate the current line (or every line the selection spans) |
Ctrl++ / Ctrl+- |
Bigger / smaller notes font (also Ctrl+scroll) — handy for reading presenter notes; remembered between sessions |
Ctrl+0 |
Reset the notes font to the default size |
Alt+↑ / Alt+↓ |
Move the current line (or selected lines) up / down |
/date /time /now |
Type the snippet then Space/Enter — expands to today's date, the time, or both |
Ctrl+\ |
Toggle notes panel |
Ctrl+Alt+click |
Place a numbered anchor on the PDF, linked to the note paragraph at the current cursor position |
| Drag an anchor | Move a placed anchor to a new spot (a click without dragging still jumps to its note) |
| Drag a callout box | Move a placed callout box to a new spot — the arrow re-aims from its anchor automatically |
Ctrl+Alt+drag |
Place an anchor and a callout box at the drag end — the anchor's note paragraph is rendered on the PDF with an arrow pointing from the anchor |
Ctrl+Alt+right-click |
Drop a standalone text box on the page (no anchor) — type into the placeholder in the notes panel; drag the box to reposition |
Renders automatically on lines where the cursor isn't; move the cursor to a line to edit the raw syntax.
| Syntax | Renders as |
|---|---|
x^2 or x^{n+1} |
superscript (until next space, or braced) |
x_ij or x_{i,j} |
subscript (until next space, or braced) |
x^\alpha x_\mu |
a \command can be the script itself (x^α, x_μ) |
\alpha \beta … \omega |
Greek letters (α β … ω) |
\sum \prod \int \sqrt |
Σ Π ∫ √ (the radical sign only — no overbar) |
\infty \approx \neq \leq \geq \propto |
∞ ≈ ≠ ≤ ≥ ∝ |
\in \notin \subset \cup \cap \emptyset |
∈ ∉ ⊂ ∪ ∩ ∅ |
\forall \exists \partial \nabla \to |
∀ ∃ ∂ ∇ → |
\R \N \Q \Z \C |
number sets ℝ ℕ ℚ ℤ ℂ (also spelled \realnum, \natnum, \ratnum, \intnum, \compnum) |
\hat{x} \bar{x} \tilde{x} \vec{x} |
accents x̂ x̄ x̃ x⃗ (also \dot / \ddot; braces optional: \hat x) |
The space that ends a command or an unbraced script is a terminator, not a gap, so it is not drawn: \alpha x reads "αx" and x^2 y reads "x²y". Type two spaces where you want one — \alpha + \beta → "α + β".
Inside an inline `code` span nothing above is applied — the text renders verbatim (so `snake_case`, `2^10` or `\alpha` stay literal), matching how a Markdown viewer treats code.
Stored as plain text in the .md sidecar — renders cleanly in Obsidian and any Markdown viewer.
Wiki-style [[…]] links in the notes jump to another slide — in the same deck or a different document — which is handy for pointing "this builds on that earlier slide." They render as a styled link (brackets hidden); Ctrl+click follows one:
| Syntax | Follows to |
|---|---|
[[#Eigenvalues]] |
the bookmark or chapter of that name, in this document |
[[lecture2.pdf#Eigenvalues]] |
opens lecture2.pdf at that bookmark or chapter |
[[lecture2.pdf]] |
opens lecture2.pdf (in a tab) |
[[#page=12]] or [[#12]] |
page 12 of the current document |
[[lecture2.pdf#page=5|the proof]] |
page 5, shown as the proof in the text |
Point at a name, not a page number — a bookmark or a chapter follows its page when you insert a slide, reorder a chapter or merge two decks, and a page number does not.
Ctrl+K (or ☰ ▸ Link to a page…) starts one and offers this document's
bookmarks and chapters, the other open tabs and your recent files; typing [[
opens the same picker, and # after a filename lists that document's names.
A link whose target is not there is struck through. After following one,
the notes header offers ↩ Back to where you came from until you turn the
page. ☰ ▸ Copy link to this page puts a link to where you
are on the clipboard, to paste into another document's notes. The .md keeps
the plain [[…]] text, so links round-trip through Obsidian.
| Key | Action |
|---|---|
Ctrl+F |
Open search bar (searches the PDF text and the Markdown notes); press it again to select the term you last searched for |
Enter / ↓ |
Next match |
↑ |
Previous match |
Escape |
Close search |
| Key | Action |
|---|---|
Ctrl+O |
Open file (in a new tab) |
Ctrl+Shift+O |
Open recent |
Ctrl+N |
New blank PDF (in a new tab) |
Ctrl+Alt+N |
New text page — endless Markdown paper you can draw on |
| Drawing on a text page | The pen, highlighter, eraser, lasso, pan and zoom tools all work on the paper exactly as they do on a PDF, and every mouse button is rebindable the same way — switching modes needs no relearning |
Ctrl+Scroll / pinch |
On a text page: zoom the sheet — paper, text and ink together (Ctrl+0 resets; Shift+click with a drawing tool fits the width) |
Ctrl+S |
Save (prompts for name if untitled) |
Ctrl+W |
Close the current tab (prompts to save unsaved changes; closes the window with the last tab) |
Ctrl+Shift+T |
Reopen the most recently closed tab |
PDF-level shortcuts — PageUp / PageDown (page flip), the mouse back/forward side buttons, Ctrl+\ (toggle notes), Ctrl+W (close tab), Ctrl+Shift+T (reopen closed tab) — work no matter which side has focus, so flipping pages while typing notes works as expected.
| Distro | Unit tests | Install |
|---|---|---|
| Arch Linux | ✓ | ✓ CI |
| Ubuntu 24.04 | ✓ CI | ✓ CI |
| Fedora 41 | ✓ CI |
"✓ CI" = verified on every push via GitHub Actions. Arch unit tests run locally (Omarchy is the primary development environment).
While there are unsaved changes, Sidemark snapshots the document and notes (text-first pages included) every 60 seconds to ~/.local/state/sidemark/autosave/ — the original file is never modified until you explicitly save. If Sidemark closes uncleanly, reopening the file offers to recover the snapshot. Snapshots are removed on save or discard, and pruned after 30 days.
Opened and saved files are tracked in ~/.local/share/sidemark/recent.json (last used first, 15 entries) and accessible three ways. Launching Sidemark without a file reopens the top of that list — the document you were last reading — and the scratchpad always keeps its place at the bottom of it:
-
In-app — the clock-arrow button next to Open lists them.
-
XDG recent files — opens are registered in
recently-used.xbel, so GTK/GNOME file dialogs and KDE (including krunner's recent-documents results) pick them up automatically. -
walker / Omarchy launcher (opt-in) —
./install.sh --walker-menudropsextras/sidemark_recent.luainto~/.config/elephant/menus/(needsjq). Reach it via walker's provider list (/by default), or bind a prefix in~/.config/walker/config.toml:[[providers.prefixes]] prefix = "p:" provider = "menus:sidemarkrecent"
For other launchers (rofi, fuzzel, …) sidemark --list-recent prints name<TAB>path lines and exits — useful for scripting or building your own menu.
Notes are saved alongside the PDF as <filename>-notes.md (or a custom file you pick via Notes file…, remembered per PDF; the file is created lazily, only once you write something) using invisible <!-- page:N --> markers, so the file renders cleanly in any Markdown viewer or Obsidian vault. Anchor markers (<!-- anchor:X:Y -->) and callout markers (<!-- callout:X:Y -->) are stored the same way — invisible in external viewers. Inside Sidemark, anchors appear as numbered circles on the PDF canvas; a callout additionally renders its anchor's note paragraph in a box at the callout position, with an arrow from the anchor. Callouts are included in exports.
When you export with notes (☰ menu), every page keeps its on-page marks and each annotated page is followed by its notes (short notes from several pages are grouped onto shared notes pages; options in the export dialog).
