### Install dependencies Source: https://github.com/hyscaler/pdfexcavator/blob/main/CONTRIBUTING.md Installs required project packages. ```bash npm install ``` -------------------------------- ### Install Optional Dependencies Source: https://github.com/hyscaler/pdfexcavator/blob/main/README.md Install additional packages for image rendering and OCR support. ```bash # For rendering pages to images npm install canvas # For OCR support (scanned documents) npm install tesseract.js ``` -------------------------------- ### Install Tesseract.js Source: https://github.com/hyscaler/pdfexcavator/blob/main/docs/api/ocr.md Install the Tesseract.js library using npm. This is a prerequisite for OCR functionality. ```bash npm install tesseract.js ``` -------------------------------- ### Run in development mode Source: https://github.com/hyscaler/pdfexcavator/blob/main/CONTRIBUTING.md Starts the development server with file watching enabled. ```bash npm run dev ``` -------------------------------- ### Install PDFExcavator and dependencies Source: https://github.com/hyscaler/pdfexcavator/blob/main/docs/getting-started.md Commands to install the core library and optional dependencies for rendering or OCR. ```bash npm install pdfexcavator ``` ```bash npm install canvas ``` ```bash npm install tesseract.js ``` -------------------------------- ### Install PDF Excavator CLI Source: https://github.com/hyscaler/pdfexcavator/blob/main/docs/guides/cli.md Install the tool globally using npm or run it directly with npx. ```bash npm install -g pdfexcavator ``` ```bash npx pdfexcavator document.pdf ``` -------------------------------- ### Install PDFExcavator via npm Source: https://github.com/hyscaler/pdfexcavator/blob/main/docs/README.md Use this command to install the library in your Node.js project. ```bash npm install pdfexcavator ``` -------------------------------- ### CLI Usage Source: https://github.com/hyscaler/pdfexcavator/blob/main/README.md Commands for global installation and performing extraction tasks via the command line. ```bash # Install globally npm install -g pdfexcavator # Extract text pdfexcavator text document.pdf # Extract tables pdfexcavator tables document.pdf # Get help pdfexcavator --help ``` -------------------------------- ### JSON Output Format Example Source: https://github.com/hyscaler/pdfexcavator/blob/main/docs/guides/cli.md Example structure of the JSON output, showing page number and extracted objects with their properties. ```json { "pageNumber": 1, "objects": [ { "type": "char", "text": "H", "x0": 72.0, "y0": 100.5 } ] } ``` -------------------------------- ### Check Tesseract.js Availability Source: https://github.com/hyscaler/pdfexcavator/blob/main/docs/api/ocr.md Verifies if Tesseract.js is installed and available for use. Displays a message if it's not installed, prompting the user to install it for OCR support. ```typescript import { isTesseractAvailable } from 'pdfexcavator'; const available = await isTesseractAvailable(); if (!available) { console.log('Install tesseract.js for OCR support'); } ``` -------------------------------- ### CSV Output Format Example (Tables) Source: https://github.com/hyscaler/pdfexcavator/blob/main/docs/guides/cli.md Example structure of the CSV output for extracted tables, showing rows and columns. ```csv Column1,Column2,Column3 Value1,Value2,Value3 Value4,Value5,Value6 ``` -------------------------------- ### lineMargin Parameter Example Source: https://github.com/hyscaler/pdfexcavator/blob/main/docs/advanced/layout-analysis.md Provides examples for the lineMargin parameter, controlling the minimum vertical gap between lines. ```typescript // Tight line spacing { lineMargin: 0.3 } ``` ```typescript // Normal spacing { lineMargin: 0.5 } ``` -------------------------------- ### Get PDF Page Information Source: https://github.com/hyscaler/pdfexcavator/blob/main/docs/guides/cli.md Display information about each page, including dimensions and orientation. ```bash pdfexcavator info document.pdf ``` -------------------------------- ### charMargin Parameter Example Source: https://github.com/hyscaler/pdfexcavator/blob/main/docs/advanced/layout-analysis.md Shows how to modify the charMargin parameter to define the maximum gap between characters within a word. ```typescript // Tight: characters must be close { charMargin: 1.0 } ``` ```typescript // Loose: allow larger gaps { charMargin: 3.0 } ``` -------------------------------- ### lineOverlap Parameter Example Source: https://github.com/hyscaler/pdfexcavator/blob/main/docs/advanced/layout-analysis.md Demonstrates adjusting the lineOverlap parameter to control how strictly characters must overlap to be considered on the same line. ```typescript // Strict: characters must overlap significantly { lineOverlap: 0.7 } ``` ```typescript // Loose: small overlap is enough { lineOverlap: 0.3 } ``` -------------------------------- ### detectVertical Parameter Example Source: https://github.com/hyscaler/pdfexcavator/blob/main/docs/advanced/layout-analysis.md Demonstrates how to use the detectVertical parameter to enable or disable the detection of vertical text. ```typescript { detectVertical: true } // Detect rotated text ``` ```typescript { detectVertical: false } // Ignore vertical text ``` -------------------------------- ### Get Text Lines Source: https://github.com/hyscaler/pdfexcavator/blob/main/docs/api/page.md Retrieve text grouped into lines. ```typescript const lines = await page.getTextLines(); for (const line of lines) { console.log(line.text); } ``` -------------------------------- ### wordMargin Parameter Example Source: https://github.com/hyscaler/pdfexcavator/blob/main/docs/advanced/layout-analysis.md Illustrates adjusting the wordMargin parameter to set the minimum gap required to identify a word break. ```typescript // Small gap triggers word break { wordMargin: 0.1 } ``` ```typescript // Require larger gap { wordMargin: 0.3 } ``` -------------------------------- ### Quick Start PDF Extraction Source: https://github.com/hyscaler/pdfexcavator/blob/main/README.md Open a PDF, retrieve metadata, and extract text and tables using the asynchronous API. ```typescript import pdfexcavator from 'pdfexcavator'; // Open a PDF const pdf = await pdfexcavator.open('document.pdf'); // Get metadata const metadata = await pdf.metadata; console.log(`Title: ${metadata.title}`); console.log(`Pages: ${metadata.pageCount}`); // Extract text from each page for (const page of pdf.pages) { const text = await page.extractText(); console.log(text); } // Extract tables for (const page of pdf.pages) { const tables = await page.extractTables(); for (const table of tables) { console.log(table.rows); } } // Close when done await pdf.close(); ``` -------------------------------- ### Get PDF Metadata Source: https://github.com/hyscaler/pdfexcavator/blob/main/docs/guides/cli.md Retrieve metadata information such as title, author, page count, and PDF version. ```bash pdfexcavator metadata document.pdf ``` -------------------------------- ### Open PDF from Buffer Source: https://github.com/hyscaler/pdfexcavator/blob/main/docs/guides/basic-usage.md Loads a PDF document from a Buffer object. This is useful when the PDF content is already in memory, for example, after downloading it. ```typescript import { PDFExcavator } from 'pdfexcavator'; import fs from 'fs'; const buffer = fs.readFileSync('document.pdf'); const pdf = await PDFExcavator.fromBuffer(buffer); ``` -------------------------------- ### Get CMap Configuration Source: https://github.com/hyscaler/pdfexcavator/blob/main/docs/api/utilities.md Retrieve the CMap configuration required for PDF rendering. ```typescript const config = await getDefaultCMapConfig(); // { cMapUrl: '...', cMapPacked: true } ``` -------------------------------- ### PDF State Tracker Usage Source: https://github.com/hyscaler/pdfexcavator/blob/main/docs/advanced/precision-mode.md Creates and uses a PDF state tracker to get graphics and text states at a specific position, and to calculate precise character positions. Requires importing `PDFStateTracker` and `createStateTracker`. ```typescript import { PDFStateTracker, createStateTracker } from 'pdfexcavator'; // Create tracker const tracker = await createStateTracker(page.pdfPage, page.height); // Get state at position const state = tracker.getStateAt(x, y); if (state) { console.log('Text state:', state.textState); console.log('Graphics state:', state.graphicsState); console.log('Transform matrix:', state.combinedMatrix); } // Calculate precise position const position = tracker.calculatePrecisePosition(x, y, fontSize, charWidth); console.log('Adjusted X:', position.x); console.log('Adjusted Y:', position.y); console.log('Text rise:', position.textRise); console.log('Rotation:', position.rotationAngle); ``` -------------------------------- ### Custom Layout for Dense Text Extraction Source: https://github.com/hyscaler/pdfexcavator/blob/main/docs/advanced/layout-analysis.md Example function demonstrating how to extract text from a PDF using custom, tighter layout analysis parameters suitable for dense text. ```typescript async function extractDenseText(pdfPath: string) { const pdf = await pdfexcavator.open(pdfPath); const page = pdf.pages[0]; // Tighter parameters for dense text const result = await page.analyzeLayout({ lineOverlap: 0.6, // Stricter line detection charMargin: 1.5, // Tighter character grouping wordMargin: 0.15, // Slightly larger word breaks lineMargin: 0.4 // Tighter line spacing }); await pdf.close(); return result.text; } ``` -------------------------------- ### Page Methods for Layout Analysis Source: https://github.com/hyscaler/pdfexcavator/blob/main/docs/advanced/layout-analysis.md Utilize page methods to perform layout analysis with custom parameters, get words, lines, or extract text with layout options. ```typescript // Analyze with custom params const result = await page.analyzeLayout({ charMargin: 2.0, wordMargin: 0.2 }); // Get words with layout analysis const words = await page.getWordsWithLayout(); // Get lines with layout analysis const lines = await page.getLinesWithLayout(); // Extract text with layout params const text = await page.extractTextWithLayout({ lineOverlap: 0.5, charMargin: 2.0 }); ``` -------------------------------- ### Filter Content by Position Source: https://github.com/hyscaler/pdfexcavator/blob/main/docs/guides/basic-usage.md Selects content within a specified bounding box on the page. This example extracts text only from the top half of the page. ```typescript // Get content in top half of page const topHalf = page.withinBBox([0, 0, page.width, page.height / 2]); const text = await topHalf.extractText(); ``` -------------------------------- ### OCR Integration with Tesseract.js Source: https://context7.com/hyscaler/pdfexcavator/llms.txt Perform optical character recognition on scanned documents using Tesseract.js. Supports multiple languages and automatic detection of scanned pages. Ensure `tesseract.js` is installed. ```typescript import pdfexcavator, { isTesseractAvailable, terminateOCR, PSM_MODES, OEM_MODES } from 'pdfexcavator'; // Check if Tesseract.js is installed const available = await isTesseractAvailable(); if (!available) { console.log('Install tesseract.js: npm install tesseract.js'); } const pdf = await pdfexcavator.open('scanned.pdf'); const page = pdf.pages[0]; // Check if page needs OCR (has images but no/little text) const needsOcr = await page.needsOCR(); const isScanned = await page.isScannedPage(); if (needsOcr) { // Perform OCR const result = await page.performOCR({ lang: 'eng', psm: PSM_MODES.AUTO, oem: OEM_MODES.DEFAULT, minConfidence: 60 }); console.log(result.text); console.log(result.confidence); console.log(result.words); console.log(result.lines); console.log(result.processingTime); } // Extract text with automatic OCR fallback const text = await page.extractTextWithOCR(); // Process scanned PDF with OCR async function processScannedPDF(pdfPath: string) { const pdf = await pdfexcavator.open(pdfPath); const results: string[] = []; for (const page of pdf.pages) { if (await page.needsOCR()) { const result = await page.performOCR({ lang: 'eng' }); results.push(result.text); console.log(`Page ${page.pageNumber + 1}: OCR confidence ${result.confidence}%`); } else { results.push(await page.extractText()); } } await pdf.close(); await terminateOCR(); return results.join('\n\n'); } await pdf.close(); ``` -------------------------------- ### Example: Extract Subscript/Superscript Text Source: https://github.com/hyscaler/pdfexcavator/blob/main/docs/advanced/precision-mode.md Opens a PDF, extracts characters with precision, filters for characters with a significant text rise (absolute value > 1), and logs the character and its type (subscript/superscript) along with the rise value. Closes the PDF at the end. ```typescript async function extractSubSuperscript(pdfPath: string) { const pdf = await pdfexcavator.open(pdfPath); const page = pdf.pages[0]; const chars = await extractCharsWithPrecision( page.pdfPage, page.pageNumber, page.height, 0 ); // Find characters with text rise const raised = chars.filter(c => Math.abs(c.textRise || 0) > 1 ); for (const char of raised) { const type = (char.textRise || 0) > 0 ? 'superscript' : 'subscript'; console.log(`${char.text}: ${type} (rise: ${char.textRise})`); } await pdf.close(); } ``` -------------------------------- ### Filter Content by Properties Source: https://github.com/hyscaler/pdfexcavator/blob/main/docs/guides/basic-usage.md Filters page objects based on their properties, such as size or font name. This example shows how to get large text or bold text. ```typescript // Get only large text const largeText = page.filter(obj => obj.size > 14); // Get bold text const boldText = page.filter(obj => obj.fontName?.includes('Bold')); ``` -------------------------------- ### Clone the repository Source: https://github.com/hyscaler/pdfexcavator/blob/main/CONTRIBUTING.md Initial step to download the project source code. ```bash git clone https://github.com/hyscaler/pdfexcavator.git cd pdfexcavator ``` -------------------------------- ### Open PDF documents Source: https://github.com/hyscaler/pdfexcavator/blob/main/docs/getting-started.md Methods to initialize a PDF instance from a file path, with a password, or from a buffer. ```typescript import pdfexcavator from 'pdfexcavator'; // From file path const pdf = await pdfexcavator.open('document.pdf'); // With password (encrypted PDFs) const pdf = await pdfexcavator.open('encrypted.pdf', { password: 'secret' }); // From Buffer import { PDFExcavator } from 'pdfexcavator'; import fs from 'fs'; const buffer = fs.readFileSync('document.pdf'); const pdf = await PDFExcavator.fromBuffer(buffer); ``` -------------------------------- ### Opening PDF Documents Source: https://github.com/hyscaler/pdfexcavator/blob/main/docs/api/pdfexcavator.md Methods for initializing a PDF document from different sources. ```typescript const pdf = await pdfexcavator.open('document.pdf'); // With options const pdf = await pdfexcavator.open('encrypted.pdf', { password: 'secret', repair: true }); ``` ```typescript import { PDFExcavator } from 'pdfexcavator'; import fs from 'fs'; const buffer = fs.readFileSync('document.pdf'); const pdf = await PDFExcavator.fromBuffer(buffer); ``` ```typescript const pdf = await PDFExcavator.fromUint8Array(uint8Array); ``` -------------------------------- ### Build and test changes Source: https://github.com/hyscaler/pdfexcavator/blob/main/CONTRIBUTING.md Verifies the project build and runs the test suite. ```bash npm run build npm test ``` -------------------------------- ### Build the project Source: https://github.com/hyscaler/pdfexcavator/blob/main/CONTRIBUTING.md Compiles the TypeScript source code. ```bash npm run build ``` -------------------------------- ### Configure PDF Excavator Options Source: https://github.com/hyscaler/pdfexcavator/blob/main/docs/guides/cli.md Adjust options like JSON indentation, coordinate precision, or provide a password for encrypted PDFs. ```bash pdfexcavator document.pdf -f json --indent 4 ``` ```bash pdfexcavator chars document.pdf --precision 3 ``` ```bash pdfexcavator document.pdf --password secret123 ``` -------------------------------- ### Get Unique Y Positions Source: https://github.com/hyscaler/pdfexcavator/blob/main/docs/api/utilities.md Use getUniqueYPositions to extract all unique y-coordinates from a collection of lines. ```typescript const yPositions = getUniqueYPositions(lines); ``` -------------------------------- ### Show PDF Excavator Help and Version Source: https://github.com/hyscaler/pdfexcavator/blob/main/docs/guides/cli.md Display the help message or the version of the PDF Excavator CLI tool. ```bash pdfexcavator --help ``` ```bash pdfexcavator --version ``` -------------------------------- ### Project directory structure Source: https://github.com/hyscaler/pdfexcavator/blob/main/CONTRIBUTING.md Overview of the file and folder organization within the repository. ```text pdfexcavator/ ├── src/ │ ├── index.ts # Main exports │ ├── PDFExcavator.ts # PDF document class │ ├── Page.ts # Page class │ ├── PageImage.ts # Image rendering │ ├── cli.ts # CLI tool │ ├── types.ts # TypeScript types │ ├── extractors/ # Extraction modules │ │ ├── text.ts # Text extraction │ │ ├── table.ts # Table extraction │ │ ├── chars.ts # Character extraction │ │ └── ... │ └── utils/ # Utility functions │ ├── bbox.ts # Bounding box utilities │ ├── geometry.ts # Geometry helpers │ └── ... ├── dist/ # Compiled output ├── examples/ # Example scripts └── tests/ # Test files ``` -------------------------------- ### Get Unique X Positions Source: https://github.com/hyscaler/pdfexcavator/blob/main/docs/api/utilities.md Use getUniqueXPositions to extract all unique x-coordinates from a collection of lines. ```typescript const xPositions = getUniqueXPositions(lines); ``` -------------------------------- ### Import CJK Utilities Source: https://github.com/hyscaler/pdfexcavator/blob/main/docs/api/utilities.md Import tools for handling CJK fonts and text normalization. ```typescript import { getDefaultCMapConfig, isCJKFont, normalizeCJKText, } from 'pdfexcavator'; ``` -------------------------------- ### Create a feature branch Source: https://github.com/hyscaler/pdfexcavator/blob/main/CONTRIBUTING.md Command to create a new branch for development. ```bash git checkout -b feature/your-feature-name ``` -------------------------------- ### Import Bounding Box Utilities Source: https://github.com/hyscaler/pdfexcavator/blob/main/docs/api/utilities.md Import all available bounding box utility functions from the pdfexcavator library. ```typescript import { normalizeBBox, isValidBBox, pointInBBox, bboxOverlaps, bboxWithin, bboxOutside, bboxIntersection, bboxUnion, getBBox, bboxArea, bboxCenter, bboxExpand, filterWithinBBox, filterOverlapsBBox, filterOutsideBBox, } from 'pdfexcavator'; ``` -------------------------------- ### Get PDF Metadata Source: https://github.com/hyscaler/pdfexcavator/blob/main/docs/guides/basic-usage.md Retrieves metadata associated with the PDF document, such as title, author, page count, and encryption status. ```typescript const pdf = await pdfexcavator.open('document.pdf'); const meta = await pdf.metadata; console.log('Title:', meta.title); console.log('Author:', meta.author); console.log('Pages:', meta.pageCount); console.log('PDF Version:', meta.pdfVersion); console.log('Encrypted:', meta.isEncrypted); ``` -------------------------------- ### Import Font Utilities Source: https://github.com/hyscaler/pdfexcavator/blob/main/docs/api/utilities.md Import font-related analysis and substitution tools. ```typescript import { findFontSubstitution, classifyFont, parseFontStyle, getSubstituteFontMetrics, PDF_BASE_FONTS, FONT_SUBSTITUTION_MAP, STANDARD_FONT_METRICS, } from 'pdfexcavator'; ``` -------------------------------- ### Static Utility Methods Source: https://github.com/hyscaler/pdfexcavator/blob/main/docs/api/pdfexcavator.md Helper methods for analyzing PDF files without full instantiation. ```typescript const isPdf = PDFExcavator.isPDFLike(buffer); // true/false ``` ```typescript const analysis = PDFExcavator.analyzePDF(buffer); console.log(analysis.version); // '1.7' console.log(analysis.encrypted); // false console.log(analysis.objectCount); // 150 console.log(analysis.issues); // ['Missing %%EOF marker'] ``` -------------------------------- ### Complete PDF processing workflow Source: https://github.com/hyscaler/pdfexcavator/blob/main/docs/api/pdfexcavator.md Demonstrates opening a PDF, retrieving metadata, and iterating through pages to extract text and tables. ```typescript import pdfexcavator from 'pdfexcavator'; async function processPDF(filePath: string) { const pdf = await pdfexcavator.open(filePath); try { // Get metadata const meta = await pdf.metadata; console.log(`Processing: ${meta.title || filePath}`); console.log(`Pages: ${pdf.pageCount}`); // Process each page for (const page of pdf.pages) { const text = await page.extractText(); const tables = await page.extractTables(); console.log(`Page ${page.pageNumber + 1}:`); console.log(` Text length: ${text.length}`); console.log(` Tables found: ${tables.length}`); } } finally { await pdf.close(); } } ``` -------------------------------- ### Regex Search in PDF Source: https://github.com/hyscaler/pdfexcavator/blob/main/docs/guides/basic-usage.md Performs a search using a regular expression across the entire PDF. This example finds phone numbers in the format XXX-XXX-XXXX. ```typescript const results = await pdf.search(/\d{3}-\d{3}-\d{4}/g); // Phone numbers ``` -------------------------------- ### Manage Font Substitutions Source: https://github.com/hyscaler/pdfexcavator/blob/main/docs/advanced/fonts.md Utilizes the FontSubstitutionManager class to get specific font substitutions by name and to retrieve all recorded substitutions. Instantiate 'FontSubstitutionManager' from 'pdfexcavator'. ```typescript import { FontSubstitutionManager } from 'pdfexcavator'; const manager = new FontSubstitutionManager(); // Get substitution const sub = manager.getSubstitution('ArialMT'); console.log(sub); // { original: 'ArialMT', substitute: 'Helvetica', ... } // Get all substitutions made console.log(manager.getAllSubstitutions()); ``` -------------------------------- ### Normalize CJK Text Source: https://github.com/hyscaler/pdfexcavator/blob/main/docs/advanced/fonts.md Converts CJK characters to their standard or half-width equivalents. Import 'normalizeCJKText' from 'pdfexcavator'. Currently, this example shows no change for ASCII input. ```typescript import { normalizeCJKText } from 'pdfexcavator'; // Convert fullwidth to halfwidth normalizeCJKText('ABC'); // 'ABC' normalizeCJKText('123'); // '123' ``` -------------------------------- ### Security configurations Source: https://github.com/hyscaler/pdfexcavator/blob/main/docs/getting-started.md Using basePath to restrict file access and safe search patterns to prevent ReDoS. ```typescript // Restrict file access to uploads directory const pdf = await pdfexcavator.open(userProvidedPath, { basePath: '/app/uploads' }); ``` ```typescript // Safe - user input is escaped const results = await page.search(userInput); ``` -------------------------------- ### Get Font Information for Each Character Source: https://github.com/hyscaler/pdfexcavator/blob/main/docs/advanced/fonts.md Iterates through characters on a page to log their text, font name, and size. Requires accessing the 'chars' property of a page object. ```typescript const chars = await page.chars; for (const char of chars) { console.log({ text: char.text, fontName: char.fontName, fontSize: char.size }); } ``` -------------------------------- ### PDF Document Workflow Source: https://github.com/hyscaler/pdfexcavator/blob/main/docs/api/pdfexcavator.md Demonstrates the complete workflow for opening a PDF, retrieving metadata, and extracting content page by page. ```APIDOC ## PDF Document Processing Workflow ### Description Standard workflow for opening a PDF file, accessing metadata, and iterating through pages to extract text and tables. ### Methods - **pdfexcavator.open(filePath)**: Opens a PDF file. - **pdf.metadata**: Retrieves document metadata. - **pdf.pageCount**: Returns the total number of pages. - **page.extractText()**: Extracts text from a specific page. - **page.extractTables()**: Extracts tables from a specific page. - **pdf.close()**: Closes the document instance. ``` -------------------------------- ### Open PDF from URL Source: https://github.com/hyscaler/pdfexcavator/blob/main/docs/guides/basic-usage.md Opens a PDF from a URL by first fetching its content into a buffer. This requires the 'fetch' API and Node.js 'Buffer'. ```typescript const response = await fetch('https://example.com/document.pdf'); const buffer = Buffer.from(await response.arrayBuffer()); const pdf = await PDFExcavator.fromBuffer(buffer); ``` -------------------------------- ### Get Default CMap Configuration Source: https://github.com/hyscaler/pdfexcavator/blob/main/docs/advanced/fonts.md Retrieves the default configuration for CMap (Character Map) files, typically used by pdf.js for font handling. Import 'getDefaultCMapConfig' from 'pdfexcavator'. ```typescript import { getDefaultCMapConfig } from 'pdfexcavator'; // Get CMap config for pdf.js const config = await getDefaultCMapConfig(); // { cMapUrl: '/node_modules/pdfjs-dist/cmaps/', cMapPacked: true } ``` -------------------------------- ### Open PDF from File Path Source: https://github.com/hyscaler/pdfexcavator/blob/main/docs/guides/basic-usage.md Opens a PDF document from a given file path. Ensure the file exists and is accessible. Remember to close the PDF when done. ```typescript import pdfexcavator from 'pdfexcavator'; const pdf = await pdfexcavator.open('document.pdf'); // ... work with PDF await pdf.close(); ``` -------------------------------- ### Debug Table Finder Functionality Source: https://github.com/hyscaler/pdfexcavator/blob/main/docs/api/table-extraction.md Utilize `debugTableFinder` to get detailed information about the table detection process, including detected edges and their intersections. This is useful for diagnosing detection issues. ```typescript import { debugTableFinder } from 'pdfexcavator'; const debug = debugTableFinder(chars, lines, rects); console.log('Edges:', debug.edges.length); console.log('Intersections:', debug.intersections.length); ``` -------------------------------- ### Complete Structured Document Extraction Source: https://github.com/hyscaler/pdfexcavator/blob/main/docs/examples/structured-data.md Use this function to open a PDF, extract metadata, and then process each page to get structured data including paragraphs and sentences. Ensure the pdfexcavator library is imported. ```typescript import pdfexcavator, { clusterObjects } from 'pdfexcavator'; interface BBox { x0: number; y0: number; x1: number; y1: number; } interface Sentence { text: string; bbox: BBox; } interface Paragraph { text: string; bbox: BBox; sentences: Sentence[]; } interface PageData { pageNumber: number; content: string; bbox: BBox; paragraphs: Paragraph[]; } interface DocumentData { metadata: { title?: string; author?: string; pageCount: number; }; pages: PageData[]; fullText: string; } async function extractStructuredDocument(pdfPath: string): Promise { const pdf = await pdfexcavator.open(pdfPath); const meta = await pdf.metadata; const result: DocumentData = { metadata: { title: meta.title, author: meta.author, pageCount: meta.pageCount }, pages: [], fullText: '' }; const allTexts: string[] = []; for (const page of pdf.pages) { const pageData = await extractPageStructure(page); result.pages.push(pageData); allTexts.push(pageData.content); } result.fullText = allTexts.join('\n\n'); await pdf.close(); return result; } async function extractPageStructure(page): Promise { const words = await page.extractWords(); if (!words.length) { return { pageNumber: page.pageNumber + 1, content: '', bbox: { x0: 0, y0: 0, x1: 0, y1: 0 }, paragraphs: [] }; } // Group into lines const lineGroups = clusterObjects(words, w => w.y0, 3); const lines = lineGroups.map(lineWords => { lineWords.sort((a, b) => a.x0 - b.x0); return { text: lineWords.map(w => w.text).join(' '), words: lineWords, bbox: computeBBox(lineWords) }; }); // Sort top to bottom lines.sort((a, b) => a.bbox.y0 - b.bbox.y0); // Filter headers/footers const contentLines = lines.filter(line => !isHeaderOrFooter(line, page.height) ); // Group into paragraphs const paragraphs = groupIntoParagraphs(contentLines); // Build page content const content = paragraphs.map(p => p.text).join('\n\n'); const pageBBox = computeBBox(contentLines.flatMap(l => l.words)); return { pageNumber: page.pageNumber + 1, content, bbox: pageBBox, paragraphs }; } function computeBBox(objects: { x0: number; y0: number; x1: number; y1: number }[]): BBox { if (!objects.length) return { x0: 0, y0: 0, x1: 0, y1: 0 }; return { x0: Math.min(...objects.map(o => o.x0)), y0: Math.min(...objects.map(o => o.y0)), x1: Math.max(...objects.map(o => o.x1)), y1: Math.max(...objects.map(o => o.y1)) }; } function isHeaderOrFooter(line, pageHeight: number): boolean { const y = line.bbox.y0; const text = line.text.toLowerCase(); // Position check const inHeader = y < pageHeight * 0.08; const inFooter = y > pageHeight * 0.92; if (!inHeader && !inFooter) return false; // Content patterns const patterns = [ /^page\s+\d+/i, /confidential/i, /^[-_=]{5,}$/ ]; return patterns.some(p => p.test(text)); } function groupIntoParagraphs(lines): Paragraph[] { if (!lines.length) return []; const paragraphs: Paragraph[] = []; let currentLines = [lines[0]]; const GAP_THRESHOLD = 15; for (let i = 1; i < lines.length; i++) { const prevLine = lines[i - 1]; const currLine = lines[i]; const gap = currLine.bbox.y0 - prevLine.bbox.y1; if (gap > GAP_THRESHOLD) { paragraphs.push(createParagraph(currentLines)); currentLines = [currLine]; } else { currentLines.push(currLine); } } if (currentLines.length) { paragraphs.push(createParagraph(currentLines)); } return paragraphs; } function createParagraph(lines): Paragraph { const text = lines.map(l => l.text).join(' '); const bbox = computeBBox(lines.flatMap(l => l.words)); const sentences = extractSentences(lines); return { text, bbox, sentences }; } function extractSentences(lines): Sentence[] { const sentences: Sentence[] = []; let currentWords = []; let currentText = ''; for (const line of lines) { currentWords.push(...line.words); currentText += (currentText ? ' ' : '') + line.text; if (/[.!?]/.test(line.text)) { sentences.push({ text: currentText.trim(), bbox: computeBBox(currentWords) }); currentWords = []; currentText = ''; } } if (currentText.trim()) { sentences.push({ text: currentText.trim(), bbox: computeBBox(currentWords) }); } return sentences; } ``` -------------------------------- ### Initialize and Use OCREngine Source: https://github.com/hyscaler/pdfexcavator/blob/main/docs/api/ocr.md Provides advanced control over OCR processing. Initialize an OCREngine with specific language and segmentation modes, then check its availability and use it to recognize text from an image buffer. ```typescript import { OCREngine } from 'pdfexcavator'; const engine = new OCREngine({ lang: 'eng+jpn', psm: PSM_MODES.SINGLE_BLOCK }); const available = await engine.isAvailable(); if (available) { const result = await engine.recognize(imageBuffer); console.log(result.text); } ``` -------------------------------- ### Configure OCR Engine Modes (OEM) Source: https://github.com/hyscaler/pdfexcavator/blob/main/docs/api/ocr.md Selects the underlying OCR engine. Use OEM_MODES to toggle between legacy and neural network-based engines. ```typescript import { OEM_MODES } from 'pdfexcavator'; // OEM_MODES values: // 0 - Legacy engine only // 1 - Neural nets LSTM engine only // 2 - Legacy + LSTM engines // 3 - Default (based on what is available) const result = await page.performOCR({ oem: OEM_MODES.LSTM_ONLY // 1 }); ``` -------------------------------- ### Example: Extract Rotated Text Source: https://github.com/hyscaler/pdfexcavator/blob/main/docs/advanced/precision-mode.md Opens a PDF, extracts characters with precision, filters for rotated characters (angle > 5 degrees), groups them by angle, and logs the text content for each angle. Closes the PDF at the end. ```typescript async function extractRotatedText(pdfPath: string) { const pdf = await pdfexcavator.open(pdfPath); const page = pdf.pages[0]; const chars = await extractCharsWithPrecision( page.pdfPage, page.pageNumber, page.height, 0 ); // Find rotated characters const rotated = chars.filter(c => Math.abs(c.rotationAngle || 0) > 5 ); console.log(`Found ${rotated.length} rotated characters`); // Group by rotation angle const byAngle = new Map(); for (const char of rotated) { const angle = Math.round(char.rotationAngle || 0); if (!byAngle.has(angle)) byAngle.set(angle, []); byAngle.get(angle)!.push(char); } for (const [angle, chars] of byAngle) { const text = chars.map(c => c.text).join(''); console.log(`${angle}°: "${text}"`); } await pdf.close(); } ``` -------------------------------- ### Safe PDF Opening with Error Handling Source: https://github.com/hyscaler/pdfexcavator/blob/main/docs/guides/basic-usage.md Demonstrates a robust way to open PDF files by wrapping the operation in a try-catch block. It specifically handles common errors like incorrect passwords or invalid PDF formats. ```typescript import pdfexcavator from 'pdfexcavator'; async function safePDFOpen(path) { try { const pdf = await pdfexcavator.open(path); return pdf; } catch (error) { if (error.message.includes('password')) { console.error('PDF is encrypted'); } else if (error.message.includes('Invalid PDF')) { console.error('File is not a valid PDF'); } else { console.error('Error opening PDF:', error.message); } return null; } } ``` -------------------------------- ### Import Geometry Utilities Source: https://github.com/hyscaler/pdfexcavator/blob/main/docs/api/utilities.md Import various geometry utility functions for analyzing lines and shapes from the pdfexcavator library. ```typescript import { isHorizontalLine, isVerticalLine, lineLength, linesIntersect, getHorizontalLines, getVerticalLines, groupHorizontalLines, groupVerticalLines, rectsToLines, getUniqueXPositions, getUniqueYPositions, clusterObjects, clusterObjectsByMean, } from 'pdfexcavator'; ``` -------------------------------- ### Custom Text Processing to Extract Paragraphs Source: https://github.com/hyscaler/pdfexcavator/blob/main/docs/api/text-extraction.md An example function that opens a PDF, extracts words from the first page, clusters them into lines based on y-position, sorts the lines, and then groups them into paragraphs by detecting large vertical gaps. Requires `extractWords` and `clusterObjects` from `pdfexcavator`. ```typescript import pdfexcavator, { extractWords, clusterObjects } from 'pdfexcavator'; async function extractParagraphs(pdfPath: string) { const pdf = await pdfexcavator.open(pdfPath); const page = pdf.pages[0]; // Get words const words = await page.extractWords(); // Group into lines by y-position const lines = clusterObjects(words, w => w.y0, 5); // Sort lines top to bottom lines.sort((a, b) => Math.min(...a.map(w => w.y0)) - Math.min(...b.map(w => w.y0))); // Build paragraphs based on gaps const paragraphs: string[] = []; let currentPara = ''; let lastY = 0; for (const lineWords of lines) { lineWords.sort((a, b) => a.x0 - b.x0); const lineText = lineWords.map(w => w.text).join(' '); const lineY = Math.min(...lineWords.map(w => w.y0)); if (lastY && lineY - lastY > 20) { // Large gap = new paragraph paragraphs.push(currentPara.trim()); currentPara = lineText; } else { currentPara += ' ' + lineText; } lastY = lineY; } if (currentPara) { paragraphs.push(currentPara.trim()); } await pdf.close(); return paragraphs; } ``` -------------------------------- ### Opening PDFs Source: https://github.com/hyscaler/pdfexcavator/blob/main/docs/api/pdfexcavator.md Methods for opening PDF documents from file paths, buffers, or Uint8Arrays. ```APIDOC ## pdfexcavator.open(path, options?) ### Description Opens a PDF from a file path. ### Method POST ### Endpoint /hyscaler/pdfexcavator/open ### Parameters #### Path Parameters - **path** (string) - Required - Path to the PDF file #### Query Parameters - **options** (OpenOptions) - Optional - Optional settings - **password** (string) - Optional - Password for encrypted PDFs - **repair** (boolean) - Optional - Attempt to repair malformed PDFs (default: false) - **basePath** (string) - Optional - Restrict file access to this directory (security) - **unicodeNorm** (string) - Optional - Unicode normalization: 'NFC', 'NFD', 'NFKC', 'NFKD' - **enableCMap** (boolean) - Optional - Enable CMap support for CJK characters (default: true) - **enableFontSubstitution** (boolean) - Optional - Enable font substitution for missing fonts (default: true) - **verbose** (boolean) - Optional - Enable verbose logging for debugging (default: false) ### Request Example ```json { "path": "document.pdf", "options": { "password": "secret", "repair": true } } ``` ### Response #### Success Response (200) - **pdf** (PDFExcavator) - The opened PDF document object #### Response Example ```json { "pdf": "PDFExcavator object" } ``` ## PDFExcavator.fromBuffer(buffer, options?) ### Description Opens a PDF from a Buffer. ### Method POST ### Endpoint /hyscaler/pdfexcavator/fromBuffer ### Parameters #### Path Parameters - **buffer** (Buffer) - Required - The PDF data as a Buffer #### Query Parameters - **options** (OpenOptions) - Optional - Optional settings (same as pdfexcavator.open) ### Request Example ```json { "buffer": "", "options": {} } ``` ### Response #### Success Response (200) - **pdf** (PDFExcavator) - The opened PDF document object #### Response Example ```json { "pdf": "PDFExcavator object" } ``` ## PDFExcavator.fromUint8Array(data, options?) ### Description Opens a PDF from a Uint8Array. ### Method POST ### Endpoint /hyscaler/pdfexcavator/fromUint8Array ### Parameters #### Path Parameters - **data** (Uint8Array) - Required - The PDF data as a Uint8Array #### Query Parameters - **options** (OpenOptions) - Optional - Optional settings (same as pdfexcavator.open) ### Request Example ```json { "data": "", "options": {} } ``` ### Response #### Success Response (200) - **pdf** (PDFExcavator) - The opened PDF document object #### Response Example ```json { "pdf": "PDFExcavator object" } ``` ``` -------------------------------- ### Correct OCR and Encoding Issues Source: https://github.com/hyscaler/pdfexcavator/blob/main/docs/api/text-extraction.md Use autoCorrectText for automatic detection and fixing of common OCR and encoding problems. Manual options like numberToLetter, expandLigatures, normalizeQuotes, normalizeDashes, and normalizeWhitespace can be configured for more specific corrections. detectEncodingIssues can be used to check for potential issues and get a score. ```typescript import { correctText, autoCorrectText, detectEncodingIssues } from 'pdfexcavator'; // Auto-detect and fix const result = autoCorrectText(text); console.log(result.text); // Corrected text // Manual options const fixed = correctText(text, { numberToLetter: true, // 0→o, 1→l, 3→e expandLigatures: true, // fi→fi, fl→fl normalizeQuotes: true, // Normalize quotes normalizeDashes: true, // Normalize dashes normalizeWhitespace: true // Fix whitespace }); // Check for issues const issues = detectEncodingIssues(text); console.log('Issues:', issues.issues); console.log('Score:', issues.score); ``` -------------------------------- ### Analyze page layout Source: https://github.com/hyscaler/pdfexcavator/blob/main/docs/api/page.md Perform layout analysis using LAParams to identify words and lines. ```typescript const result = await page.analyzeLayout({ lineOverlap: 0.5, charMargin: 2.0, wordMargin: 0.1 }); console.log(result.words); console.log(result.lines); console.log(result.text); ``` -------------------------------- ### Basic Layout Analysis Source: https://github.com/hyscaler/pdfexcavator/blob/main/docs/advanced/layout-analysis.md Perform layout analysis on characters using default or custom LAParams. Imports the analyzeLayout function and DEFAULT_LAPARAMS. ```typescript import { analyzeLayout, DEFAULT_LAPARAMS } from 'pdfexcavator'; const chars = await page.chars; const result = analyzeLayout(chars, { lineOverlap: 0.5, charMargin: 2.0, wordMargin: 0.1, lineMargin: 0.5 }); console.log(result.words); // Grouped words console.log(result.lines); // Grouped lines console.log(result.text); // Reconstructed text ``` -------------------------------- ### Process Scanned PDF Source: https://github.com/hyscaler/pdfexcavator/blob/main/docs/api/ocr.md Demonstrates a full workflow for opening a PDF, checking for OCR requirements, extracting text, and cleaning up resources. ```typescript import pdfexcavator, { isTesseractAvailable, terminateOCR } from 'pdfexcavator'; async function processScannedPDF(pdfPath: string) { // Check OCR availability const ocrAvailable = await isTesseractAvailable(); if (!ocrAvailable) { throw new Error('Install tesseract.js: npm install tesseract.js'); } const pdf = await pdfexcavator.open(pdfPath); const results: string[] = []; for (const page of pdf.pages) { const needsOcr = await page.needsOCR(); if (needsOcr) { console.log(`Page ${page.pageNumber + 1}: Running OCR...`); const result = await page.performOCR({ lang: 'eng' }); results.push(result.text); console.log(` Confidence: ${result.confidence}%`); } else { console.log(`Page ${page.pageNumber + 1}: Extracting text...`); const text = await page.extractText(); results.push(text); } } await pdf.close(); await terminateOCR(); // Clean up return results.join('\n\n'); } ``` -------------------------------- ### Perform Safe Text Searches Source: https://github.com/hyscaler/pdfexcavator/blob/main/README.md Demonstrates default literal searching and how to opt-in to regex patterns. ```typescript // Safe - pattern is escaped automatically const results = await page.search(userInput); // If you need regex, pass a RegExp object (use with caution on user input) const results = await page.search(/pattern/gi); // Or explicitly enable regex mode const results = await page.search(userInput, { literal: false }); ``` -------------------------------- ### Static Methods Source: https://github.com/hyscaler/pdfexcavator/blob/main/docs/api/pdfexcavator.md Utility methods available on the PDFExcavator class. ```APIDOC ## Static Methods ### PDFExcavator.isPDFLike(buffer) #### Description Check if data looks like a PDF. #### Method POST #### Endpoint /hyscaler/pdfexcavator/isPDFLike #### Parameters ##### Path Parameters - **buffer** (Buffer) - Required - The data to check #### Response ##### Success Response (200) - **isPdfLike** (boolean) - True if the data appears to be a PDF, false otherwise #### Response Example ```json { "isPdfLike": true } ``` ### PDFExcavator.analyzePDF(buffer) #### Description Analyze PDF structure. #### Method POST #### Endpoint /hyscaler/pdfexcavator/analyzePDF #### Parameters ##### Path Parameters - **buffer** (Buffer) - Required - The PDF data as a Buffer #### Response ##### Success Response (200) - **analysis** (object) - An object containing PDF analysis details - **version** (string) - The PDF version (e.g., '1.7') - **encrypted** (boolean) - Whether the PDF is encrypted - **objectCount** (number) - The number of objects in the PDF structure - **issues** (Array) - A list of detected issues in the PDF structure #### Response Example ```json { "analysis": { "version": "1.7", "encrypted": false, "objectCount": 150, "issues": ["Missing %%EOF marker"] } } ``` ``` -------------------------------- ### Rendering Methods Source: https://github.com/hyscaler/pdfexcavator/blob/main/docs/api/page.md Methods for rendering PDF pages to images. ```APIDOC ## toImage(options?) ### Description Render the page to an image (requires canvas). ### Parameters - **options** (object) - Optional - Rendering options including scale (number) and resolution (number). ``` -------------------------------- ### LayoutAnalyzer Class Usage Source: https://github.com/hyscaler/pdfexcavator/blob/main/docs/advanced/layout-analysis.md Instantiate and use the LayoutAnalyzer class for more direct control over the analysis process, including analyzing characters to words, lines, or performing a full analysis. ```typescript import { LayoutAnalyzer } from 'pdfexcavator'; const analyzer = new LayoutAnalyzer({ lineOverlap: 0.5, charMargin: 2.0, wordMargin: 0.1 }); const chars = await page.chars; // Analyze to words const words = analyzer.analyzeCharsToWords(chars); // Analyze to lines const lines = analyzer.analyzeCharsToLines(chars); // Full analysis const result = analyzer.analyze(chars); ``` -------------------------------- ### CommonJS usage Source: https://github.com/hyscaler/pdfexcavator/blob/main/docs/getting-started.md Using dynamic imports to load the ESM-only package in CommonJS environments. ```javascript async function main() { const { default: pdfexcavator } = await import('pdfexcavator'); const pdf = await pdfexcavator.open('document.pdf'); // ... work with PDF await pdf.close(); } main(); ``` -------------------------------- ### Render page to image Source: https://github.com/hyscaler/pdfexcavator/blob/main/docs/api/page.md Convert a page to an image buffer. Requires the canvas library. ```typescript const image = await page.toImage({ scale: 2 }); const buffer = image.toBuffer(); fs.writeFileSync('page.png', buffer); ``` -------------------------------- ### Initialize TableFinder for Advanced Detection Source: https://github.com/hyscaler/pdfexcavator/blob/main/docs/api/table-extraction.md Instantiate `TableFinder` with character, line, and rectangle data from a page for advanced table detection. Configure detection strategies for vertical and horizontal edges. ```typescript import { TableFinder } from 'pdfexcavator'; const chars = await page.chars; const lines = await page.getLines(); const rects = await page.getRects(); const finder = new TableFinder(chars, lines, rects, page.pageNumber, { verticalStrategy: 'lines', horizontalStrategy: 'lines' }); const result = finder.findTables(); console.log(result.tables); ``` -------------------------------- ### Layout Analysis Methods Source: https://github.com/hyscaler/pdfexcavator/blob/main/docs/api/page.md Methods for analyzing text layout and column detection. ```APIDOC ## analyzeLayout(params?) ### Description Analyze text layout using LAParams. ## detectColumns(minGapRatio?) ### Description Detect text columns on the page. ### Parameters - **minGapRatio** (number) - Optional - Minimum gap ratio for column detection. ## extractTextByColumns(columns?, options?) ### Description Extract text while respecting the detected column layout. ``` -------------------------------- ### Manually Cluster Words to Detect Columns Source: https://github.com/hyscaler/pdfexcavator/blob/main/docs/guides/multi-column.md Manually detects columns by clustering words based on their x-position and analyzing the gaps between these clusters. Requires importing `clusterObjects`. ```typescript import { clusterObjects } from 'pdfexcavator'; const words = await page.extractWords(); // Cluster by x-position to find columns const xClusters = clusterObjects(words, w => w.x0, 50); // Analyze gaps between clusters const columnBounds = xClusters.map(cluster => ({ x0: Math.min(...cluster.map(w => w.x0)), x1: Math.max(...cluster.map(w => w.x1)) })); ```