Repository navigation
feat: Write, the direction that did not exist - #7
Merged
Merged
Conversation
This package reads a PDF back as a document. Everything in the fleet that PRODUCES a richdoc -- Word, Excel and PowerPoint through go-ooxml, ODT, ODS, ODP and ODG through go-odf, Markdown, CSV, JSON, XML, plain text, EPUB, MOBI, FB2 and email through go-richdoc -- had nowhere to go afterwards. Measured on 2026-11-05 with fleetverbs: every ToPDF in the fleet was in go-pdfkit/convert, and every one of them took pictures, an SVG, a ZIP of pictures or an XPS package. Seventeen capabilities were missing for want of this (go-pdfkit/app#71). func Write(d *richdoc.Document, opt WriteOptions) ([]byte, error) It COMPOSES rather than typesets: go-richdoc/html.Write renders the document as a page and go-pdfkit/html2pdf.Export lays that page out. Neither half is new, and a typesetter written here would be a third implementation of line breaking, page breaking and table layout in one organisation. What that pair cannot do, this cannot do either, and the doc comment says so rather than leaving it to be discovered. ⛔ NIL Fetch MEANS REFUSE, AND THAT IS THE POINT. A richdoc arrives from something somebody was handed -- a .docx, an EPUB, an email -- and its images carry URLs that whoever wrote the file chose. Fetching them by default would make every conversion a request to an address of the author's choosing, from the converting machine and with its network position: a server-side request forgery with a document as the payload. A caller that wants sub-resources supplies its own Fetcher, and OnRefused says what the document asked for and did not get, so a page with holes in it is not silent. ⛔ AND THE ROUND TRIP FOUND A DEFECT THAT IS NOT OURS: go-pdfkit/extract reports Run.Space as the font SIZE rather than a space's advance (15.06 for a 15.0591 pt font, where the measured gap between "Chapter" and "one" is 3.9). No gap can exceed a whole em, so no word break is ever found and a converted document reads back as "Chapterone". It reaches pdfops text, markdown, word and excel the same way, silently. Filed as go-pdfkit/extract#28 with the measurement this test produced; the test here asserts every word in order and NAMES what it cannot assert yet, rather than quietly comparing something weaker. 100.0% of statements. The three step failures are reachable through seams, because a branch no test can enter is a claim nobody checks. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The direction that did not exist
This package reads a PDF back as a document. Everything in the fleet that produces a richdoc — Word, Excel and PowerPoint through
go-ooxml, ODT, ODS, ODP and ODG throughgo-odf, Markdown, CSV, JSON, XML, plain text, EPUB, MOBI, FB2 and email throughgo-richdoc— had nowhere to go afterwards.Seventeen capabilities were missing for want of this (go-pdfkit/app#71).
It composes rather than typesets:
go-richdoc/html.Write(v0.3.0, written for this) renders the document as a page andgo-pdfkit/html2pdf.Exportlays it out. Neither half is new, and a typesetter written here would be a third implementation of line breaking, page breaking and table layout in one organisation. What that pair cannot do, this cannot either — the doc comment says so rather than leaving it to be found.⛔ A conversion must not reach the network because the file said so
Fetchnil means refuse, and that is the design, not an oversight for a caller to fix.A richdoc arrives from something somebody was handed — a
.docx, an EPUB, an email — and its images carry URLs that whoever wrote the file chose. Fetching them by default would make every conversion a request to an address of the author's choosing, from the converting machine and with its network position. That is a server-side request forgery with a document as the payload.TestAnImageURLIsNotFetchedByDefaulthands ithttp://169.254.169.254/latest/meta-data/and asserts the conversion still succeeds and thatOnRefusedwas told — because a page with holes in it must not be silent. A caller that wants sub-resources supplies its ownFetcher, which is the only way the network is reached.⛔ The round trip found a defect that is not ours
The PDF comes back through this package's own
Parse— and the words have no spaces:Run.SpaceChapter→oneTfsize)A→sentenceTfsize)go-pdfkit/extractreportsRun.Spaceas the font size rather than a space's advance (~0.25 em). No gap can exceed a whole em, so no word break is ever found. It reachespdfops text,markdown,word,exceland the workbench's what this page says the same way, silently — as prose without spaces rather than as an error.Filed as go-pdfkit/extract#28 with the measurement this test produced.
⛔ The test here therefore asserts every word, in order, and names what it cannot assert yet, with the issue number and the condition for tightening it — rather than quietly comparing something weaker and leaving the next reader to think spacing was never checked.
Coverage
100.0 % of statements. The three step failures are reachable through seams (
renderHTML,layOut,writePDF), because a branch no test can enter is a claim nobody checks — and each failure is asserted to say which step it was, since "laying the page out" and "writing the PDF" are different problems.🤖 Generated with Claude Code