Needs `pdftotext` and `pdfinfo` on `PATH`. Both ship with poppler. Without
either, the tool exits `69` and says so rather than guessing.
## Example
A book whose text is fine:
```
$ pdftriage book.pdf
healthy, no OCR needed
1805 characters on the opening pages
1805 characters over 5 sample pages, ascii text score 1.00
letters 0.98, latin-1 0.00
361 characters a page
english function words 0.44
$ echo $?
1
```
A scan with no text at all:
```
$ pdftriage scan.pdf
absent, needs OCR
0 characters on the opening pages
$ echo $?
0
```
The exit code is the answer, so a shell can act on it directly:
```sh
for f in *.pdf;do pdftriage --quiet "$f"&& ocrmypdf "$f""ocr/$f";done
```
The record form:
```
$ pdftriage --json book.pdf
{"v":1,"path":"book.pdf","kind":"pdf","declared_ext":"pdf","bytes":17595,"pages":20,"language":null,"text_layer":"healthy","needs_ocr":false,"notes":["1805 characters on the opening pages","1805 characters over 5 sample pages, ascii text score 1.00","letters 0.98, latin-1 0.00","361 characters a page","english function words 0.44"]}
| `-q`, `--quiet` | Write no verdict; answer with the exit code alone. Diagnostics still go to stderr, because a silent failure is worse than a quiet one |
## Exit codes
| Code | Meaning |
|---|---|
| `0` | The layer needs OCR |
| `1` | It does not |
| `2` | Could not tell — the extractor could not read the file |
| `64` | The command line was wrong |
| `69` | `pdftotext` or `pdfinfo` is not installed |
| `74` | The file could not be read |
## The verdicts
| Verdict | What it means | OCR? |
|---|---|---|
| `healthy` | Extractable and readable as it stands | no |
| `reflected-font` | Permuted by a non-standard font encoding, and recoverable without OCR once the permutation is undone | no |
| `garbled` | Present but mojibake — extraction yields characters, not words | yes |
| `sparse` | Present but too thin to be the whole page: a scan whose layer holds only the page numbers and the running heads | yes |
| `absent` | No text at all | yes |
The sample comes from the middle of the document, not the front. Front matter
is often a bare scan in a book whose body carries good text, and often cleanly
typeset boilerplate in a book whose body is damaged — judging a book by its
title page gets both wrong.
The thresholds are measurements rather than guesses. Each one sits in the
middle of a gap observed across a few thousand real PDFs, and the reason is
recorded beside it in the source.
## As a library
The judging is a pure function over already-extracted text, so it can be