Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 33 additions & 1 deletion content/working-with-a-file/operations.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,39 @@ has been walked. A row more than one level under the row before it is a
`*ops.DepthError` naming the row. The browser workbench reads a document's own
bookmarks that way before adding one to them, and `pdfops outline -from` reads
the file; both go through the same code, so there is one grammar rather than
two that have to be kept in step.
two that have to be kept in step. `ops.Flatten` is `Nest` the other way round.

### The printed kind

The `/Outlines` tree is the table of contents a reader *navigates* by.
`Doc.ContentsPage` writes the one that gets **printed** — a page with a line for
each entry, its page number at the right and dots leading to it — from the same
entries:

```go
n, err := doc.ContentsPage(marks, ops.ContentsOptions{})
if err != nil {
return err
}
doc.SetOutline(ops.ShiftBookmarks(marks, 1, n)) // if you want both
```

⛔ **The numbers it prints are moved by the pages it adds.** A contents page put
in front of a document pushes every page of it down, so an entry that pointed at
page 7 is on page 8 afterwards, and printing the 7 would send a reader one page
short of every heading in the book. `ContentsPage` returns how many pages it
added, and `ShiftBookmarks(marks, from, by)` is the same rule for the tree —
a function rather than a line in each caller because of its edge: an entry
pointing at a page *before* the insertion has not moved, and shifting that too
goes wrong in exactly the documents that have a preface.

It runs onto as many pages as it needs, and refuses rather than printing a line
whose title has no room at all: a page number with nothing to read beside it
cannot be told from a document whose headings have no names. The refusal comes
before a page is inserted, so a document that was refused is untouched.

`pdfops contents -from toc.txt -bookmarks book.pdf out.pdf` does both from one
file, and `-title`, `-before`, `-size` and `-margin` set the rest.

## On the command line

Expand Down
9 changes: 9 additions & 0 deletions content/working-with-a-file/workbench.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,15 @@ a page number a line, two spaces of indent per level, which is the file
`pdfops outline -from` takes, read by the library's own `ops.ParseOutline`
rather than by a second parser written here.

*Write a contents page* is the other kind of table of contents: the **printed**
one, a page at the front with a line for each bookmark, its page number at the
right and dots leading to it, built from the entries the rail is already
showing. The numbers account for the page it adds. It does not rewrite the
bookmarks — `ops` carries a document's own outline over and remaps each entry to
the page object it still points at, so the tree follows its pages across the
insertion, where writing it back from the workbench's own walk would lose the
entries that point nowhere and anything past the thousand it reads.

The last three are the ones worth telling apart. **Read** is where you look at
what a page says — read it, search it, copy it — and nothing on it changes the
document. **Mark up** is where you act on the words you selected: mark them,
Expand Down
Loading