UNPKG

legal-markdown-js

Version:

Node.js implementation of LegalMarkdown for processing legal documents with markdown and YAML - Complete feature parity with Ruby version

312 lines 11.8 kB
/** * PDF Generation Module for Legal Markdown Documents * * This module provides functionality to convert processed Legal Markdown content * into professional PDF documents using Puppeteer for HTML-to-PDF conversion. * It builds upon the HTML generator to create print-ready documents with * customizable formatting, page layouts, and styling options. * * Features: * - HTML-to-PDF conversion using Puppeteer * - Multiple page formats (A4, Letter, Legal) * - Customizable margins and page orientation * - Header and footer template support * - Field highlighting for document review * - Temporary file management and cleanup * - Error handling and logging * - Dual PDF generation (normal and highlighted versions) * * @example * ```typescript * import { pdfGenerator } from './pdf-generator.js'; * * const pdf = await pdfGenerator.generatePdf(markdownContent, './output.pdf', { * format: 'A4', * landscape: false, * includeHighlighting: true, * margin: { top: '2cm', bottom: '2cm' } * }); * ``` */ import type { MarkdownString } from '../../types/content-formats.js'; import { HtmlGeneratorOptions } from './html-generator.js'; type PuppeteerModule = typeof import('puppeteer'); declare function loadPuppeteer(): Promise<PuppeteerModule>; export declare function isPdfAvailable(): Promise<boolean>; /** * Configuration options for PDF generation * * @interface PdfGeneratorOptions * @extends HtmlGeneratorOptions */ export interface PdfGeneratorOptions extends HtmlGeneratorOptions { /** Page format for the PDF */ format?: 'A4' | 'Letter' | 'Legal'; /** Whether to use landscape orientation */ landscape?: boolean; /** Page margins configuration */ margin?: { /** Top margin (e.g., '1cm', '0.5in') */ top?: string; /** Right margin (e.g., '1cm', '0.5in') */ right?: string; /** Bottom margin (e.g., '1cm', '0.5in') */ bottom?: string; /** Left margin (e.g., '1cm', '0.5in') */ left?: string; }; /** Whether to display header and footer */ displayHeaderFooter?: boolean; /** HTML template for page headers */ headerTemplate?: string; /** HTML template for page footers */ footerTemplate?: string; /** Whether to print background colors and images */ printBackground?: boolean; /** Whether to prefer CSS page size over format option */ preferCSSPageSize?: boolean; /** Path to CSS file for automatic logo detection */ cssPath?: string; /** Document version to display in footer (optional) */ version?: string; } /** * Detects logo filename from CSS file by parsing --logo-filename custom property * * Searches for CSS custom property `--logo-filename` and extracts the filename value. * Handles quoted and unquoted values, removing whitespace and quotes as needed. * * @param {string} cssPath - Path to the CSS file to parse * @returns {Promise<string | null>} Logo filename or null if not found * @example * ```typescript * // CSS contains: --logo-filename: logo.petalo.png; * const filename = await detectLogoFromCSS('./styles/contract.css'); * // Returns: 'logo.petalo.png' * ``` */ declare function detectLogoFromCSS(cssPath: string): Promise<string | null>; /** * Loads and validates logo image file, converting to base64 * * Performs comprehensive validation: * - File existence and readability * - File size limit (500KB max) * - PNG format validation using magic numbers * - Base64 encoding for embedding * * @param {string} logoPath - Absolute path to the logo image file * @returns {Promise<string>} Base64 encoded image string * @throws {Error} When file validation fails * @example * ```typescript * const base64Logo = await loadAndEncodeImage('./assets/images/logo.png'); * // Returns: 'iVBORw0KGgoAAAANSUhEUgAAA...' * ``` */ declare function loadAndEncodeImage(logoPath: string): Promise<string>; /** * Downloads and validates logo image from external URL, converting to base64 * * Performs comprehensive validation: * - URL accessibility and download * - File size limit (500KB max) * - PNG format validation using magic numbers * - Base64 encoding for embedding * * @param {string} logoUrl - URL to the logo image * @returns {Promise<string>} Base64 encoded image string * @throws {Error} When download or validation fails * @example * ```typescript * const base64Logo = await downloadAndEncodeImage('https://example.com/logo.png'); * // Returns: 'iVBORw0KGgoAAAANSUhEUgAAA...' * ``` */ declare function downloadAndEncodeImage(logoUrl: string): Promise<string>; /** * PDF Generator for Legal Markdown Documents * * Converts processed Legal Markdown content into PDF documents using Puppeteer * for HTML-to-PDF conversion. Provides comprehensive formatting options and * supports both normal and highlighted document versions. * * @class PdfGenerator * @example * ```typescript * const generator = new PdfGenerator(); * const pdf = await generator.generatePdf(content, './output.pdf', { * format: 'A4', * includeHighlighting: true * }); * ``` */ export declare class PdfGenerator { private puppeteerOptions; /** * Creates a new PDF generator instance * */ constructor(); /** * Attempts to find Chrome executable on different platforms * @private */ private getChromeExecutable; /** * Attempts to find system Chrome executable * @private */ private getSystemChromeExecutable; /** * Attempts to find Puppeteer Chrome executable from cache * @private */ private getPuppeteerChromeExecutable; /** * Ensures Chrome is available for Puppeteer, installing it if necessary * @private */ private ensureChrome; /** * Gets the first available Puppeteer cache directory * @private */ private getAvailablePuppeteerCache; /** * Checks if Puppeteer has a Chrome cache available * @private */ private hasChromiumCache; /** * Generates a PDF document from Legal Markdown content * * This method orchestrates the complete PDF generation process: * 1. Converts markdown to HTML using the HTML generator * 2. Creates a temporary HTML file for Puppeteer * 3. Launches a headless Chrome browser * 4. Loads the HTML and generates PDF with specified options * 5. Cleans up temporary files and browser resources * * @param {string} markdownContent - The processed Legal Markdown content * @param {string} outputPath - Path where the PDF will be saved * @param {PdfGeneratorOptions} [options={}] - Configuration options for PDF generation * @returns {Promise<Buffer>} A promise that resolves to the PDF buffer * @throws {Error} When PDF generation fails due to browser, file system, or processing errors * @example * ```typescript * const pdf = await generator.generatePdf( * markdownContent, * './contract.pdf', * { * format: 'A4', * landscape: false, * includeHighlighting: true, * margin: { top: '2cm', bottom: '2cm' } * } * ); * ``` */ /** * Generates a PDF document from Legal Markdown content * * @param {MarkdownString} markdownContent - The processed Legal Markdown content (MUST be Markdown, NOT HTML) * @param {string} outputPath - Path where the PDF file will be saved * @param {PdfGeneratorOptions} [options={}] - Configuration options for PDF generation * @returns {Promise<Buffer>} A promise that resolves to the PDF buffer * @throws {Error} When PDF generation fails * * @example * ```typescript * import { asMarkdown } from '../../types/content-formats.js'; * * // ✅ CORRECT - Pass Markdown * await pdfGenerator.generatePdf( * asMarkdown('# Contract\n\nContent...'), * './output/contract.pdf', * { format: 'A4' } * ); * * // ❌ INCORRECT - Don't pass HTML * await pdfGenerator.generatePdf( * '<h1>Contract</h1>', // Wrong! This will produce incorrect output * './output/contract.pdf', * {} * ); * ``` */ generatePdf(markdownContent: MarkdownString, outputPath: string, options?: PdfGeneratorOptions): Promise<Buffer>; /** * Generate PDF from pre-generated HTML content * * This method accepts HTML that has already been generated by HtmlGenerator * and converts it directly to PDF, avoiding re-processing the markdown. * This is the preferred method for the 3-phase pipeline to avoid double conversion. * * @param {HtmlString} htmlContent - Pre-generated HTML content * @param {string} outputPath - Path where the PDF file will be saved * @param {PdfGeneratorOptions} [options={}] - Configuration options (note: CSS options are ignored since HTML is pre-generated) * @returns {Promise<Buffer>} A promise that resolves to the PDF buffer * @throws {Error} When PDF generation fails * * @example * ```typescript * import { htmlGenerator } from './html-generator.js'; * import { asMarkdown } from '../../types/content-formats.js'; * * // Generate HTML once * const html = await htmlGenerator.generateHtml( * asMarkdown('# Contract\n\nContent...'), * { cssPath: './styles.css', includeHighlighting: true } * ); * * // Use the same HTML for PDF (no re-processing) * await pdfGenerator.generatePdfFromHtml(html, './contract.pdf', { format: 'A4' }); * ``` */ generatePdfFromHtml(htmlContent: string, outputPath: string, options?: PdfGeneratorOptions): Promise<Buffer>; /** * Generate two PDF versions: one normal and one with highlighting * * This method creates two PDF versions of the same document: * 1. A normal version without field highlighting * 2. A highlighted version with field annotations * * This is useful for document review processes where both clean and * annotated versions are needed for different purposes. * * @param {string} markdownContent - The processed Legal Markdown content * @param {string} outputPath - Base path for PDF files (will be modified for each version) * @param {PdfGeneratorOptions} [options={}] - Configuration options for PDF generation * @returns {Promise<Object>} A promise that resolves to both PDF buffers * @returns {Buffer} returns.normal - The normal PDF without highlighting * @returns {Buffer} returns.highlighted - The highlighted PDF with field annotations * @throws {Error} When PDF generation fails for either version * @example * ```typescript * const { normal, highlighted } = await generator.generatePdfVersions( * markdownContent, * './contract.pdf', * { format: 'A4' } * ); * // Creates: contract.normal.pdf and contract.highlighted.pdf * ``` */ generatePdfVersions(markdownContent: MarkdownString, outputPath: string, options?: PdfGeneratorOptions): Promise<{ normal: Buffer; highlighted: Buffer; }>; } /** * Singleton instance of PdfGenerator for convenient importing * * {PdfGenerator} pdfGenerator * @example * ```typescript * import { pdfGenerator } from './pdf-generator.js'; * const pdf = await pdfGenerator.generatePdf(content, './output.pdf'); * ``` */ export declare const pdfGenerator: PdfGenerator; export { loadPuppeteer as _loadPuppeteer, loadAndEncodeImage as _loadAndEncodeImage, downloadAndEncodeImage as _downloadAndEncodeImage, detectLogoFromCSS as _detectLogoFromCSS, }; //# sourceMappingURL=pdf-generator.d.ts.map