PDF files are a list of objects and after the objects there is an xref table that has pointers to each object from start of file. You could edit text and keep exactly the same amount of characters without updating pointers. Or, if you change/add/remove text then you must update every xref pointer in table after the text that you added as well as updating startxref pointer. It's a bit tricky especially for big files but it is do-able.
See the below example .pdf xref table, values are decimal.
The first object is 58 bytes into file, the next is 346, etc ..
xref
0 5
0000000000 65535 f
0000000058 00000 n
0000000346 00000 n
0000000558 00000 n
0000000705 00000 n
0000000782 00000 n
See also the startxref pointer must be updated, the "xref" start of xref table is at 1193 bytes from start of file.
startxref
1193
Please forgive me if I have pointer errors in here! Thanks @K J for pointing them out, I have, I think, corrected them below for uniz.
And see further below for xref table and startxref pointer value that should work with this example if windows/dos line endings are used.
Example file - tested this copies ok into local file and parses as PDF. Tested DUH with evince which is great but which actually fixes a broken xref table and ignores size errors. Clever. But not a good test on my part. Apologies!
If you change anything below startxref you don't have to update any pointers.
Anything above and you have to adjust the pointers.
%PDF-1.6
% First object defines a stream with red square
1 0 obj
<<
/Length 54
>>
stream
1 0 0 RG
5 w
100 100 m
200 100 l
200 200 l
100 200 l
s
endstream
endobj
% The second object. Page containing object 1 red square.
% The "R" means "Reference", and `1 0 R` is saying "look at object number 1 0
% It also points to a "Pages" object `3 0 R`.
2 0 obj
<<
/Type /Page
/Parent 3 0 R
/MediaBox [0 0 320 500]
/Contents [1 0 R]
>>
endobj
% The third object. "Pages" object. The `2 0 R` is reference to the "Page" object. 1 page in this doc.
3 0 obj
<<
/Type /Pages
/Kids [2 0 R ]
/Count 1
>>
endobj
% The fourth object. A "Catalog" object that provides the main structure of the PDF.
4 0 obj
<<
/Type /Catalog
/Pages 3 0 R
>>
endobj
% A fifth object - title
5 0 obj
<<
/Title (Test PDF Title)
/Producer (James hand edit emacs FTW)
>>
endobj
% The xref table. Lookup table, lists all the objects with pointer from start of file (emacs count-words-region helps fix up).
% (defun wh/byte-offset-at-point () "Report the byte offset (0-indexed) in the file corresponding to the position of point." (interactive) (message "byte offset: %d" (1- (position-bytes (point)))))
xref
0 5
0000000000 65535 f
0000000058 00000 n
0000000349 00000 n
0000000573 00000 n
0000000729 00000 n
0000000812 00000 n
% The trailer contains some metadata about the PDF.
% - There are 4 entries in the `xref` table.
% - The root of the document is object 4 (the "Catalog" object)
trailer
<<
/Size 5
/Root 4 0 R
/Info 5 0 R
>>
% The startxref marker tells us that we can find the xref table ? bytes after the start of the file.
startxref
1229
% WE can add any comments below here without need to adjust pointers.
% From https://alexwlchan.net/2024/big-pdf/?utm_source=tldrnewsletter
% "it got very fiddly to redo all the lookup tables!"
% https://help.callassoftware.com/a/798383-how-to-create-a-simple-pdf-file
% https://superuser.com/questions/300405/is-it-possible-to-edit-a-pdf-file-directly
% https://www.oreilly.com/library/view/pdf-explained/9781449321581/ch04.html
% https://superuser.com/questions/1045351/pdf-corrupt-after-opening-and-saving-in-raw-text
% The end-of-file marker.
%%EOF
Note that if you copy this into windows/dos editor that uses dos style line endings you will have to ADJUST pointers so the xref table becomes like this:
xref
0 5
0000000000 65535 f
0000000061 00000 n
0000000370 00000 n
0000000604 00000 n
0000000769 00000 n
0000000860 00000 n
And the startxref pointer becomes like this:
startxref
1286
Credit to this for example: https://alexwlchan.net/2024/big-pdf/?utm_source=tldrnewsletter "it got very fiddly to redo all the lookup tables!"
And he got it from here: https://help.callassoftware.com/a/798383-how-to-create-a-simple-pdf-file
Useful reference: https://www.oreilly.com/library/view/pdf-explained/9781449321581/ch04.html