feat: extract text from fetched PDFs
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
export function createPdf(pages: string[], encrypted = false): Uint8Array {
|
||||
const fontId = 3 + pages.length * 2;
|
||||
const objects = [
|
||||
"<< /Type /Catalog /Pages 2 0 R >>",
|
||||
`<< /Type /Pages /Kids [${pages.map((_, index) => `${3 + index * 2} 0 R`).join(" ")}] /Count ${pages.length} >>`,
|
||||
];
|
||||
for (let index = 0; index < pages.length; index += 1) {
|
||||
const pageId = 3 + index * 2;
|
||||
const contentId = pageId + 1;
|
||||
const text = pages[index]!;
|
||||
const operators = Array.from({ length: Math.ceil(text.length / 100) }, (_, partIndex) => {
|
||||
const part = text.slice(partIndex * 100, (partIndex + 1) * 100);
|
||||
const escaped = part.replaceAll("\\", "\\\\").replaceAll("(", "\\(").replaceAll(")", "\\)");
|
||||
return `(${escaped}) Tj`;
|
||||
});
|
||||
const content = text ? `BT /F1 12 Tf 72 720 Td ${operators.join(" ")} ET` : "";
|
||||
objects.push(
|
||||
`<< /Type /Page /Parent 2 0 R /MediaBox [0 0 612 792] /Resources << /Font << /F1 ${fontId} 0 R >> >> /Contents ${contentId} 0 R >>`,
|
||||
`<< /Length ${Buffer.byteLength(content)} >>\nstream\n${content}\nendstream`,
|
||||
);
|
||||
}
|
||||
objects.push("<< /Type /Font /Subtype /Type1 /BaseFont /Helvetica >>");
|
||||
const encryptionId = objects.length + 1;
|
||||
if (encrypted) objects.push(`<< /Filter /Standard /V 1 /R 2 /O <${"00".repeat(32)}> /U <${"00".repeat(32)}> /P -4 >>`);
|
||||
|
||||
let output = "%PDF-1.4\n";
|
||||
const offsets = [0];
|
||||
objects.forEach((object, index) => {
|
||||
offsets.push(Buffer.byteLength(output));
|
||||
output += `${index + 1} 0 obj\n${object}\nendobj\n`;
|
||||
});
|
||||
const xrefOffset = Buffer.byteLength(output);
|
||||
output += `xref\n0 ${objects.length + 1}\n0000000000 65535 f \n`;
|
||||
for (const offset of offsets.slice(1)) output += `${String(offset).padStart(10, "0")} 00000 n \n`;
|
||||
output += `trailer\n<< /Size ${objects.length + 1} /Root 1 0 R${encrypted ? ` /Encrypt ${encryptionId} 0 R` : ""} >>\nstartxref\n${xrefOffset}\n%%EOF`;
|
||||
return new TextEncoder().encode(output);
|
||||
}
|
||||
Reference in New Issue
Block a user