import { inflateSync } from 'node:zlib'; /** * The text a pdfkit document prints, for assertions in tests: inflates the * content streams and joins the strings of every text-showing operator * (hex strings of the standard fonts, one line per operator). Not a PDF * parser - it reads what pdfkit writes with the built-in Helvetica. */ export function pdfText(pdf: Buffer): string { const source = pdf.toString('latin1'); const lines: string[] = []; const streams = source.matchAll(/stream\r?\n([\s\S]*?)\r?\nendstream/g); for (const [, raw] of streams) { let content: string; try { content = inflateSync(Buffer.from(raw, 'latin1')).toString('latin1'); } catch { continue; } for (const operator of content.matchAll( /\[([^\]]*)\]\s*TJ|<([0-9a-fA-F]+)>\s*Tj/g, )) { const parts = operator[1] ?? `<${operator[2]}>`; const text = [...parts.matchAll(/<([0-9a-fA-F]*)>/g)] .map(([, hex]) => Buffer.from(hex, 'hex').toString('latin1')) .join(''); lines.push(text); } } return lines.join('\n'); }