feat: add best-effort PDF source converters (txt, html, docx)

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-30 09:12:43 +02:00
co-authored by Claude Sonnet 5
parent 16b4f28b42
commit 05ff96b8b3
2 changed files with 106 additions and 0 deletions
+42
View File
@@ -1,6 +1,8 @@
import fs from 'node:fs/promises';
import mammoth from 'mammoth';
import puppeteer from 'puppeteer';
import * as pdfjsLib from 'pdfjs-dist/legacy/build/pdf.mjs';
import { Document, Paragraph, TextRun, Packer } from 'docx';
import { register } from './registry.js';
async function renderHtmlToPdf(html, outputPath) {
@@ -42,9 +44,49 @@ async function convertDocxToPdf(inputPath, outputPath) {
await renderHtmlToPdf(result.value, outputPath);
}
async function extractPdfPageTexts(inputPath) {
const data = new Uint8Array(await fs.readFile(inputPath));
const doc = await pdfjsLib.getDocument({ data }).promise;
const pageTexts = [];
for (let pageNum = 1; pageNum <= doc.numPages; pageNum += 1) {
const page = await doc.getPage(pageNum);
const content = await page.getTextContent();
pageTexts.push(content.items.map((item) => item.str).join(' '));
}
return pageTexts;
}
async function convertPdfToTxt(inputPath, outputPath) {
const pageTexts = await extractPdfPageTexts(inputPath);
await fs.writeFile(outputPath, pageTexts.join('\n\n'));
}
async function convertPdfToHtml(inputPath, outputPath) {
const pageTexts = await extractPdfPageTexts(inputPath);
const body = pageTexts.map((text) => `<p>${escapeHtml(text)}</p>`).join('\n');
await fs.writeFile(outputPath, `<html><body>${body}</body></html>`);
}
async function convertPdfToDocx(inputPath, outputPath) {
const pageTexts = await extractPdfPageTexts(inputPath);
const doc = new Document({
sections: [
{
children: pageTexts.map((text) => new Paragraph({ children: [new TextRun(text)] })),
},
],
});
const buffer = await Packer.toBuffer(doc);
await fs.writeFile(outputPath, buffer);
}
export function registerDocumentConverters() {
register({ family: 'document', sourceFormat: 'docx', targetFormat: 'html', convert: convertDocxToHtml });
register({ family: 'document', sourceFormat: 'txt', targetFormat: 'pdf', convert: convertTxtToPdf });
register({ family: 'document', sourceFormat: 'html', targetFormat: 'pdf', convert: convertHtmlToPdf });
register({ family: 'document', sourceFormat: 'docx', targetFormat: 'pdf', convert: convertDocxToPdf });
register({ family: 'document', sourceFormat: 'pdf', targetFormat: 'txt', convert: convertPdfToTxt });
register({ family: 'document', sourceFormat: 'pdf', targetFormat: 'html', convert: convertPdfToHtml });
register({ family: 'document', sourceFormat: 'pdf', targetFormat: 'docx', convert: convertPdfToDocx });
}