/** * PDF'ten metin çıkarma (tarayıcı içinde, pdfjs-dist ile). * Dinamik import edilir — ana bundle'a girmez. */ export async function extractPdfText(file, { maxPages = 40 } = {}) { const pdfjs = await import('pdfjs-dist'); // Worker'ı Vite'ın bundle ettiği dosyadan al (CDN'e çıkmaz) const workerUrl = (await import('pdfjs-dist/build/pdf.worker.min.mjs?url')).default; pdfjs.GlobalWorkerOptions.workerSrc = workerUrl; const buf = await file.arrayBuffer(); const doc = await pdfjs.getDocument({ data: buf }).promise; const pages = Math.min(doc.numPages, maxPages); const parts = []; for (let i = 1; i <= pages; i++) { const page = await doc.getPage(i); const content = await page.getTextContent(); parts.push(content.items.map((it) => it.str).join(' ')); } const text = parts.join('\n\n').replace(/[ \t]+/g, ' ').trim(); return { text, pageCount: doc.numPages, usedPages: pages }; } // Metin dosyaları için basit okuyucu export async function extractPlainText(file) { const text = await file.text(); return { text: text.trim(), pageCount: 1, usedPages: 1 }; } /** * Taranmış (görüntü) PDF için OCR — tesseract.js, Türkçe dil paketi, * tarayıcıda. Ölçüldü: sentetik teklif cetvelinde güven 87, sayfa başı * ~0,3 sn (Node). Yalnızca metin katmanı boşsa devreye girer; ilk 8 sayfa. */ export async function ocrPdfText(file, { maxPages = 8, onProgress } = {}) { const pdfjs = await import('pdfjs-dist'); const workerUrl = (await import('pdfjs-dist/build/pdf.worker.min.mjs?url')).default; pdfjs.GlobalWorkerOptions.workerSrc = workerUrl; const { createWorker } = await import('tesseract.js'); const doc = await pdfjs.getDocument({ data: await file.arrayBuffer() }).promise; const pages = Math.min(doc.numPages, maxPages); const worker = await createWorker('tur'); const parts = []; try { for (let i = 1; i <= pages; i++) { onProgress?.({ sayfa: i, toplam: pages }); const page = await doc.getPage(i); const viewport = page.getViewport({ scale: 2 }); // ~150 dpi: OCR için yeterli, hızlı const canvas = document.createElement('canvas'); canvas.width = viewport.width; canvas.height = viewport.height; await page.render({ canvasContext: canvas.getContext('2d'), viewport }).promise; const { data } = await worker.recognize(canvas); parts.push(data.text); } } finally { await worker.terminate(); } const text = parts.join('\n\n').replace(/[ \t]+/g, ' ').trim(); return { text, pageCount: doc.numPages, usedPages: pages, ocr: true }; } export async function extractText(file, { ocr = true, onProgress } = {}) { const name = (file.name || '').toLowerCase(); if (name.endsWith('.pdf') || file.type === 'application/pdf') { const r = await extractPdfText(file); // Metin katmanı yoksa taranmış PDF'tir — OCR'a düş if (ocr && (r.text || '').replace(/\s/g, '').length < 100) { try { return await ocrPdfText(file, { onProgress }); } catch { return r; } } return r; } return extractPlainText(file); }