Files
paperlessmanager/paperless-backend/src/paperless/vergleich-kennzahlen.util.ts
T

57 lines
1.7 KiB
TypeScript

import { PDFDocument } from 'pdf-lib';
import { PDFParse } from 'pdf-parse';
/** Kennzahlen eines Belegs; `null` = nicht ermittelbar. */
export interface Kennzahlen {
seiten: number | null;
woerter: number | null;
}
/** Kennzahlen des vorhandenen (Paperless) und des neuen Belegs. */
export interface VergleichKennzahlen {
vorhanden: Kennzahlen;
neu: Kennzahlen;
}
/**
* Zählt Wörter: Tokens zwischen Leerraum, die mindestens einen Buchstaben oder
* eine Ziffer enthalten. Seitenmarker von pdf-parse („-- 1 of 2 --“) zählen
* nicht. Kein Wort → `null` (z. B. Scan ohne Textebene).
*/
export function zaehleWoerter(text: string | null | undefined): number | null {
if (!text) return null;
const ohneMarker = text.replace(/-- \d+ of \d+ --/g, ' ');
const anzahl = ohneMarker
.split(/\s+/)
.filter((token) => /[\p{L}\p{N}]/u.test(token)).length;
return anzahl > 0 ? anzahl : null;
}
async function seitenzahl(pdf: Buffer): Promise<number | null> {
try {
const doc = await PDFDocument.load(pdf, { ignoreEncryption: true });
return doc.getPageCount();
} catch {
return null;
}
}
async function wortzahl(pdf: Buffer): Promise<number | null> {
// pdf.js übernimmt den Puffer, deshalb eine Kopie übergeben
const parser = new PDFParse({ data: new Uint8Array(pdf) });
try {
const { text } = await parser.getText();
return zaehleWoerter(text);
} catch {
return null;
} finally {
await parser.destroy().catch(() => undefined);
}
}
/** Seiten- und Wortzahl eines PDFs; Lesefehler ergeben `null`. */
export async function kennzahlenAusPdf(pdf: Buffer): Promise<Kennzahlen> {
const [seiten, woerter] = await Promise.all([seitenzahl(pdf), wortzahl(pdf)]);
return { seiten, woerter };
}