Documentation
¶
Overview ¶
Package parity measures how much of another toolkit's published tool list this fleet can be SHOWN to do.
⛔ It refuses to report a figure if any claim cannot be verified. A parity number assembled from a mapping nobody checks is a vibe with a decimal point in it. The first version of this measurement, kept by hand, was wrong by under-counting, and the only reason anybody found out is that somebody said "not sure that map is up to date".
Two kinds of claim, and each is checked against something that was BUILT:
- "verb:NAME" — the verb has to appear in a command's own help output, read off a binary compiled from the source being measured. Not from a README, not from anybody's notes.
- "REPO#SYMBOL" — the symbol has to appear in that repository's Go source.
A tool with no claim counts as NOT covered. That is the conservative direction, and it is deliberate: this must never make the fleet look better than it is.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var BentoPDF = []Claim{
{Tool: "merge-pdf", Claim: "verb:merge"},
{Tool: "split-pdf", Claim: "verb:split"},
{Tool: "extract-pages", Claim: "verb:select"},
{Tool: "delete-pages", Claim: "verb:delete"},
{Tool: "reverse-pages", Claim: "verb:reverse"},
{Tool: "rotate-pdf", Claim: "verb:rotate"},
{Tool: "rotate-custom", Claim: "verb:rotate"},
{Tool: "crop-pdf", Claim: "verb:crop"},
{Tool: "fix-page-size", Claim: "verb:resize"},
{Tool: "organize-pdf", Claim: "verb:move"},
{Tool: "n-up-pdf", Claim: "verb:nup"},
{Tool: "pdf-booklet", Claim: "verb:booklet"},
{Tool: "alternate-merge", Claim: "verb:interleave"},
{Tool: "combine-single-page", Claim: "verb:onepage"},
{Tool: "posterize-pdf", Claim: "verb:poster"},
{Tool: "add-blank-page", Claim: "verb:blank"},
{Tool: "page-dimensions", Claim: "verb:info"},
{Tool: "add-watermark", Claim: "verb:watermark"},
{Tool: "add-stamps", Claim: "verb:stamp"},
{Tool: "page-numbers", Claim: "verb:number"},
{Tool: "add-page-labels", Claim: "verb:labels"},
{Tool: "pdf-layers", Claim: "verb:layers"},
{Tool: "text-color", Claim: "verb:textcolour"},
{Tool: "bates-numbering", Claim: "verb:bates"},
{Tool: "sign-pdf", Claim: "verb:place"},
{Tool: "edit-metadata", Claim: "verb:metadata"},
{Tool: "view-metadata", Claim: "verb:metadata"},
{Tool: "remove-metadata", Claim: "verb:strip"},
{Tool: "sanitize-pdf", Claim: "verb:sanitize"},
{Tool: "compress-pdf", Claim: "verb:compress"},
{Tool: "flatten-pdf", Claim: "verb:flatten"},
{Tool: "bookmark", Claim: "verb:outline"},
{Tool: "table-of-contents", Claim: "verb:outline"},
{Tool: "protect-pdf", Claim: "verb:encrypt"},
{Tool: "unlock-pdf", Claim: "verb:decrypt"},
{Tool: "change-permissions", Claim: "verb:permissions"},
{Tool: "remove-restrictions", Claim: "verb:permissions"},
{Tool: "pdf-to-text", Claim: "verb:text"},
{Tool: "extract-tables", Claim: "verb:tables"},
{Tool: "pdf-to-csv", Claim: "verb:tables"},
{Tool: "pdf-to-markdown", Claim: "verb:markdown"},
{Tool: "prepare-pdf-for-ai", Claim: "verb:markdown"},
{Tool: "pdf-to-word", Claim: "verb:word"},
{Tool: "pdf-to-excel", Claim: "verb:excel"},
{Tool: "pdf-to-json", Claim: "verb:objects"},
{Tool: "extract-images", Claim: "verb:images"},
{Tool: "extract-attachments", Claim: "verb:detach"},
{Tool: "add-attachments", Claim: "verb:attach"},
{Tool: "edit-attachments", Claim: "verb:attachments"},
{Tool: "form-filler", Claim: "verb:fill"},
{Tool: "form-creator", Claim: "verb:addfields"},
{Tool: "rasterize-pdf", Claim: "go-pdfkit/render#func Page"},
{Tool: "invert-colors", Claim: "go-pdfkit/convert#images.Invert"},
{Tool: "pdf-to-greyscale", Claim: "go-pdfkit/convert#images.Grayscale"},
{Tool: "adjust-colors", Claim: "go-pdfkit/convert#images.AdjustContrast"},
{Tool: "background-color", Claim: "go-pdfkit/convert#Background: bg"},
{Tool: "scanner-effect", Claim: "go-pdfkit/convert#type ScannerEffect"},
{Tool: "edit-pdf", Claim: "go-pdfkit/app#func main"},
{Tool: "pdf-multi-tool", Claim: "go-pdfkit/app#func main"},
{Tool: "cbz-to-pdf", Claim: "go-pdfkit/convert#func ArchiveToPDF"},
{Tool: "pdf-to-cbz", Claim: "go-pdfkit/convert#func writeComicInfo"},
{Tool: "pdf-to-zip", Claim: "go-pdfkit/convert#func Bundle"},
{Tool: "svg-to-pdf", Claim: "go-pdfkit/convert#func RasterizeSVG"},
{Tool: "odt-to-pdf", Claim: "go-odf/odf#func Parse"},
{Tool: "ods-to-pdf", Claim: "go-odf/odf#office:spreadsheet"},
{Tool: "odp-to-pdf", Claim: "go-odf/odf#office:presentation"},
{Tool: "rtf-to-pdf", Claim: "go-rtf/rtf#func Parse"},
{Tool: "word-to-pdf", Claim: "go-ooxml/ooxml#func ParseWord"},
{Tool: "excel-to-pdf", Claim: "go-ooxml/ooxml#func ParseWorkbook"},
{Tool: "powerpoint-to-pdf", Claim: "go-ooxml/ooxml#func ParsePresentation"},
{Tool: "markdown-to-pdf", Claim: "go-richdoc/markdown#func Parse"},
{Tool: "fb2-to-pdf", Claim: "go-richdoc/fb2#func Parse"},
{Tool: "epub-to-pdf", Claim: "go-richdoc/epub#func (p *opf) readingOrder"},
{Tool: "email-to-pdf", Claim: "go-richdoc/email#multipart/alternative"},
{Tool: "mobi-to-pdf", Claim: "go-richdoc/mobi#func stripTrailing"},
{Tool: "csv-to-pdf", Claim: "go-richdoc/data#func Sniff"},
{Tool: "json-to-pdf", Claim: "go-richdoc/data#func uniformObjects"},
{Tool: "xml-to-pdf", Claim: "go-richdoc/data#uniformKids"},
{Tool: "txt-to-pdf", Claim: "go-richdoc/data#func laidOut"},
{Tool: "image-to-pdf", Claim: "go-pdfkit/convert#func ToPDF"},
{Tool: "png-to-pdf", Claim: "go-pdfkit/convert#image/png"},
{Tool: "jpg-to-pdf", Claim: "go-pdfkit/convert#image/jpeg"},
{Tool: "bmp-to-pdf", Claim: "go-pdfkit/convert#x/image/bmp"},
{Tool: "tiff-to-pdf", Claim: "go-pdfkit/convert#x/image/tiff"},
{Tool: "webp-to-pdf", Claim: "go-pdfkit/convert#x/image/webp"},
{Tool: "psd-to-pdf", Claim: "go-pdfkit/convert#go-images/psd"},
{Tool: "pdf-to-png", Claim: `go-pdfkit/convert#"png"`},
{Tool: "pdf-to-jpg", Claim: `go-pdfkit/convert#"jpeg"`},
{Tool: "pdf-to-bmp", Claim: `go-pdfkit/convert#"bmp"`},
{Tool: "pdf-to-tiff", Claim: `go-pdfkit/convert#"tiff"`},
{Tool: "pdf-to-webp", Claim: `go-pdfkit/convert#"webp"`},
{Tool: "remove-annotations", Claim: "go-pdfkit/ops#func (d *Doc) RemoveAnnotations("},
{Tool: "header-footer", Claim: `go-pdfkit/ops#"{pages}", strconv.Itoa(pages)`},
{Tool: "duplex-collate", Claim: "verb:duplex"},
{Tool: "divide-pages", Claim: "verb:divide"},
{Tool: "remove-blank-pages", Claim: "verb:deblank"},
{Tool: "repair-pdf", Claim: "verb:repair"},
}
BentoPDF maps BentoPDF's own tool names onto what this fleet can be SHOWN to do. Every entry is checked; absence is the default.
Measured against BentoPDF v2.8.8 at commit 6ce0d69 (its own last commit 2026-10-17, read 2026-10-18): 114 tools.
⛔ The commit is part of the figure. This line named 3a5f146, and that commit is not reachable in the clone the measurement actually reads — so the denominator was attributed to something nobody here can check. The count happens to be the same 114 at both readings, which is why it went unnoticed and why it is worth writing down: it would have gone on agreeing until the day BentoPDF added a tool.
Functions ¶
func ReadTools ¶
ReadTools lists the other toolkit's tools from its own documentation directory: one Markdown file per tool, which is how BentoPDF publishes them.
⛔ Reading its list rather than restating it is the point. A list typed out here would be a snapshot of what somebody believed on the day they typed it, and the denominator of a parity figure is exactly the thing that must not quietly drift.
Types ¶
type Claim ¶
type Claim struct {
Tool string // the other toolkit's own name for it
Claim string // "" means we do not do this
}
A Claim is what a repository is said to do, and how to check it.
type Report ¶
type Report struct {
Tools []string // every tool the other toolkit documents
Covered []string // those a verified claim answers
Uncovered []string // those nothing claims
}
Report is the outcome of a measurement.
func Measure ¶
Measure checks every claim and counts what is covered.
It refuses in three ways before it counts anything, and the three are different mistakes:
- a tool claimed twice. The map keeps the last one and the total comes out short of what the table appears to say, SILENTLY — which is how this check came to exist: ten entries were added and the figure rose by nine.
- a claim for a tool the other toolkit does not have. It inflates nothing by itself, but it means the table is being written against something other than the list, and that error has a direction nobody notices.
- a claim that cannot be shown. An unverified claim is not a capability.