# The command Source: https://truecopy.dev/docs/cli/ npx truecopy a-document.pdf is the shortest way to find out whether this library is any use on your own files, before installing anything. ```sh npx truecopy a-document.pdf ``` No install, no project, no line of code. Any file it can open: a PDF, a CSV, a TSV, a table pasted out of a viewer and saved to disk. One engine reads all of them; only the ruler changes, and the output says which one it used. ## What it prints ``` truecopy - statement.pdf pdf, 3 page(s), 128 row(s) page 1 - cut at 68, 229, 356, 411, 490 7 column(s), 41 row(s) col kind filled role 0 - 41% - 1 - 68% - 2 - 24% - ... 1 30/05/2026 | VIR SEPA SALAIRE | 30/05/2026 | 2400,00 2 28/05/2026 | CARTE BOULANGER | 28/05/2026 | 7,90 ... what this reading cannot vouch for: - column 5 of page 1 is filled on only 17% of its rows - the cut may have invented it - the pages disagree on how many columns there are (6 on 2, 7 on 1) ``` Three blocks, and the last one is the point. ### The cut `cut at 68, 229, 356…` is where the columns were placed, in PDF units from the left edge. It is the layer where a reading goes wrong **first**: get the cut wrong and every judgement after it inherits the mistake. The line **names its ruler** when it is not a page's. A list of numbers with no unit is a riddle: ``` page 1 - cut at 100, 290 a PDF page 1 - cut at characters 7, 22 a table pasted with spaces page 1 - cut on the delimiter a CSV, where the columns ARE the fields page 1 - no boundary nothing lined up; every row came back whole ``` Points stay unlabelled: they are what a page has always been measured in. And on a delimited file the numbers themselves say nothing anybody needs, so it names what happened instead. ### The columns How often each column is actually filled. `kind` and `role` stay empty here on purpose: the command names no kinds and no thresholds, because the whole point is to be useful _before_ you have told it anything about your documents. Fill those in and they appear; see [explain](https://truecopy.dev/docs/explain/). ### What it cannot vouch for The list at the bottom is computed without knowing anything about your document: - a page with **no column at all**: either it is prose, or the cut failed and every row came back whole; - a column **filled on a fraction of its rows**: the cut may have invented it out of a letterhead or an address block; - pages **cut differently from one another**: usually a different table, and joining them makes a third that is neither; - a page carrying **no text at all**: a blank page, a scan, or an image. When the list is empty it says so, and says what that means: ``` nothing looked wrong from the shape of this page. that is not the same as "this reading is right". ``` ## Exit codes | Code | When | | ---- | -------------------------------------------- | | `0` | the file was read, whatever the warnings say | | `1` | the file was refused, or no file was given | A refusal is worded for a person and carries its reason in brackets (`empty`, `too-big`, `no-text`, `too-slow`, `not-opened`): ``` This PDF carries no text: it is most likely a scan or a photo. (no-text) ``` ## Why the command exists Because the honest way to sell a reader is to let people run it on the document that worries them. If the cut comes out wrong on your statements, you find that out in thirty seconds instead of after an afternoon of integration, and the output tells you _which_ layer failed, so you know whether the fix is a header anchor, a threshold, or a different library entirely. ## What it deliberately does not do It does not extract to CSV or JSON. That would make it a converter, and a converter that quietly gets a column wrong is exactly what this library exists to avoid. For rows in your own code, [two lines](https://truecopy.dev/docs/quickstart/) do it, with the same warnings attached. Map of this site for a model: https://truecopy.dev/llms.txt Every page in one file: https://truecopy.dev/llms-full.txt