The terminal PDF reader. Written in Rust.
A PDF is two documents in one: the words, and the page they were set on. Most readers show only the second. folio shows either, or both at once, because reading a paper and quoting from it want different things. Built on Crust and Glow, part of the Fe2O3 suite.
- Read a page at full width:
zin page mode blows the page up until it is as wide as the terminal, and↑↓walk down it a row at a time,PgUpPgDna screen.+and-step the zoom. Small print in a scan becomes readable without leaving the terminal. - Three modes on
tpv, or cycled withm: the page's text full width, the page as an image full width, or text on the left with the page on the right. The config picks which one a document opens in. - Edit the real document:
eopens the.md,.texor.htmlsitting beside the PDF, rebuilds it on save, and reloads the page. A small change is a real edit, not a patch painted over the page. - Sign a PDF:
iputs a picture on the page, a signature most often. Move it, size it, andEnterwrites a signed copy beside the original. No office program needed. - Chapters and links:
clists the chapters the PDF carries, and Enter goes to one.flists the links on the page. One inside the document turns to its page; a web or mail link opens in your browser or mail program.Ctrl-Ogoes back to where you were. - Corpus search:
ssearches every indexed PDF, not just the open one, and opens the document on the page that carries the phrase. - Quote with a citation:
ycopies the page's text with the file name and page number attached. - Reads scans too: a scanned PDF has no text layer, so folio says so and shows you the page.
- Re-read on demand:
rre-reads a document changed outside folio: new text, new pages, no stale cache. - Remembers where you were, per document, in plain text you can edit.
- Zero idle cost: nothing runs while you read. Text is extracted once per document, a page image rendered once per size, and both are kept.
Download the prebuilt binary from Releases, or build from source:
cargo build --release
cp target/release/folio ~/.local/bin/Run folio somefile.pdf, or run it bare and pick up where you left off.
To make it the system PDF reader, so file managers and browsers hand PDFs to it, install the desktop file that ships with this repo:
cp folio.desktop ~/.local/share/applications/
xdg-mime default folio.desktop application/pdfIt declares Terminal=true, which is how a TUI program advertises itself. A
terminal file manager that reads the desktop entry, pointer
among them, then gives folio the terminal instead of launching it detached.
Needs pdftotext and pdfinfo (poppler-utils) for text, and mutool (mupdf-tools) for page images.
| Key | Action |
|---|---|
t p v |
text / page / split |
m M |
cycle the modes forward / back |
j k ↑ ↓ |
scroll, turning the page at either end |
Space b |
next / previous page |
z |
in page mode: full width, and back to the whole page |
+ - |
zoom in / out, between the whole page and full width |
gg G |
top of the first page / foot of the last (also Home / End) |
10g |
go to page 10 |
/ n N |
find in this document, next match, previous |
s |
find across every indexed document |
c |
the document's own chapter list; Enter goes to a chapter |
f |
the links on this page; Enter follows one |
Ctrl-O |
back to the page a chapter or a link was followed from |
e |
edit the source if there is one, else a text sidecar |
y Y |
yank this page with a citation / the document's path |
o |
open another document |
w W |
widen / narrow the text pane in split mode, as in pointer |
x |
in split mode: swap the sides, page left or right |
i |
stamp the config's picture on the page (see below) |
Ctrl-B |
borders: none, page pane, both, text pane |
Ctrl-W |
write the whole text beside the PDF, asking first if that file exists |
Ctrl-A |
a Claude session about the page on screen (claude on the PATH); /exit comes back |
? |
help |
q |
quit |
A PDF cannot be edited as text. It places each glyph at a fixed coordinate, and the font it carries usually holds only the characters the document already uses. So a replacement of a different length mis-spaces the line, and a character the font lacks cannot be typed at all.
What works is editing the source. If notes.hl, paper.md or book.tex sits beside the PDF, e opens that, and saving rebuilds the PDF and reloads the page. A HyperList is looked for first, since that is often the file the document was written in. In split mode you edit on the left and see the result on the right. The build commands are configurable, and default to pandoc for Markdown, pdflatex for LaTeX, and a headless Chrome print (build_html) for a page written as HTML. build_hl is empty by default, since a HyperList has no one way to become a PDF: with nothing set, e saves your edit and leaves the PDF alone rather than half-rebuilding it.
With no source beside it, e gives you the extracted text in a .txt sidecar. That is a note about the document, not the document.
Name a picture in the config, your signature for one:
stamp = ~/signature.png
Then i in page or split mode puts it on the page in front of you.
| Key | Action |
|---|---|
h j k l or arrows |
move it |
H J K L or Shift+arrows |
move it a tenth as far |
+ - |
bigger / smaller |
Enter |
write <name>_signed.pdf beside the original, and open it |
Esc |
leave, nothing written |
What you see while placing it is what gets written: the same mutool script draws both. The original file is never changed. The picture's white stays see-through, so a scanned signature on white paper does not cover the line it sits on. The width you end on is kept as stamp_width, in percent of the page's width, so a signature is sized once.
Zoom in first (z, +) for a finer placement. It is a picture on the page, as a pen would leave. It is not a digital signature.
Most PDFs made from LaTeX, Word or a web page carry their own chapter list, and their links work.
cshows that list, with the cursor on the chapter you are reading.jk,PgDnPgUpandgGmove,Entergoes there,qleaves.fshows the links on the page: the words each one sits on, and where it leads.- A link into the document turns to that page.
Ctrl-Ogoes back, as many times as you jumped. - A web or mail link is handed to
xdg-open(openon a Mac). You see the address before you open it. - No other kind of link is followed. A PDF can name a file or a program in a link, and folio starts neither.
Both lists are read with mutool when you ask for them, so a document you only read costs nothing more.
folio --index # indexes everything under `library` in the config
folio --index ~/Papers # or one directoryIndexing extracts and caches the text of every PDF it finds. A directory of 39 documents takes about five seconds. Then s inside folio searches all of them and opens the one you pick.
~/.folio/config:mode,split,page_side(leftorright),border,border_fg,editor,build_tex,build_md,build_hl,library,stamp,stamp_width. All optional.~/.folio/state: where you were in each document, one tab-separated line each.~/.folio/index: the list of indexed documents.~/.folio/cache/: extracted text and rendered pages. Keyed by file and modification time, so a rebuilt PDF never shows a stale page. Safe to delete.
Example config:
mode = split
split = 55
border = 2
editor = scribe
library = /home/you/Documents
Public domain (Unlicense). Created by Geir Isene.