legal-markdown-js
Version:
Node.js implementation of LegalMarkdown for processing legal documents with markdown and YAML - Complete feature parity with Ruby version
214 lines • 7.4 kB
TypeScript
/**
* Phase 3: Format Generation from Cached AST
*
* This module implements Phase 3 of the 3-phase pipeline architecture.
* It generates all requested output formats (HTML, PDF, DOCX, Markdown, Metadata)
* from the cached AST and processed content produced by Phase 2.
*
* Key benefits:
* - Single processing run regardless of output formats
* - Parallel format generation from cached AST
* - ~75% reduction in processing time for multi-format output
* - Compatible with existing HTML/PDF/DOCX generation
*
* @module core/pipeline/format-generator
*/
import type { ProcessingOptions } from '../../types/index.js';
import { LegalMarkdownProcessorResult } from '../../extensions/remark/legal-markdown-processor.js';
import type { PdfConnector } from '../../extensions/generators/pdf-connectors/index.js';
/**
* Configuration for format generation
*/
export interface FormatGenerationOptions {
/** Output directory for generated files */
outputDir: string;
/** Base filename (without extension) */
baseFilename: string;
/** Generate PDF output */
pdf?: boolean;
/** Generate HTML output */
html?: boolean;
/** Generate DOCX output */
docx?: boolean;
/** Generate Markdown output */
markdown?: boolean;
/** Generate metadata output */
metadata?: boolean;
/** Enable field highlighting */
highlight?: boolean;
/** CSS file path for styling */
cssPath?: string;
/** Highlight CSS path */
highlightCssPath?: string;
/** Document title */
title?: string;
/** Include highlighting in output */
includeHighlighting?: boolean;
/** PDF format */
format?: 'A4' | 'Letter' | 'Legal';
/** Landscape orientation */
landscape?: boolean;
/** Custom DOCX header HTML template */
docxHeaderTemplate?: string;
/** Custom DOCX footer HTML template */
docxFooterTemplate?: string;
pdfConnector?: PdfConnector;
pdfMargin?: {
top: string;
bottom: string;
left: string;
right: string;
};
/** Export format for metadata */
exportFormat?: 'yaml' | 'json';
/** Metadata export path */
exportPath?: string;
}
/**
* Build format generation options with force-commands support
*
* This helper ensures that options from force-commands (in context.options)
* take precedence over CLI/interactive options. This prevents bugs where
* force-commands are ignored in Phase 3.
*
* @param contextOptions - Options from Phase 1 (includes force-commands)
* @param baseOptions - Partial options to merge with context
* @returns Complete FormatGenerationOptions with force-commands applied
*
* @example
* ```typescript
* // In CLI service:
* const formatOptions = buildFormatGenerationOptions(context.options, {
* outputDir: dirName,
* baseFilename: baseName,
* pdf: options.pdf,
* html: options.html,
* // ... other base options
* });
*
* await generateAllFormats(processedResult, formatOptions);
* ```
*/
export declare function buildFormatGenerationOptions(contextOptions: ProcessingOptions, baseOptions: Partial<FormatGenerationOptions>): FormatGenerationOptions;
/**
* Result from format generation
*/
export interface FormatGenerationResult {
/** Generated file paths */
generatedFiles: string[];
/** Format-specific results */
results: {
pdf?: {
normal?: string;
highlight?: string;
};
html?: {
normal?: string;
highlight?: string;
};
docx?: {
normal?: string;
highlight?: string;
};
markdown?: string;
metadata?: string[];
};
/** Generation statistics */
stats: {
totalFiles: number;
processingTime: number;
};
}
/**
* Generate all requested formats from cached processing result
*
* This is the main entry point for Phase 3. It takes the cached result
* from Phase 2 and generates all requested output formats in parallel
* without re-running the processing pipeline.
*
* @param processedResult - Result from Phase 2 (with cached AST)
* @param options - Format generation options
* @returns Promise resolving to generation result with file paths
*
* @example
* ```typescript
* // After Phase 2 processing:
* const processed = await processLegalMarkdown(content, options);
*
* // Generate all formats:
* const result = await generateAllFormats(processed, {
* outputDir: '/path/to/output',
* baseFilename: 'contract',
* pdf: true,
* html: true,
* highlight: true
* });
*
* console.log(`Generated ${result.stats.totalFiles} files`);
* ```
*/
export declare function generateAllFormats(processedResult: LegalMarkdownProcessorResult, options: FormatGenerationOptions): Promise<FormatGenerationResult>;
/**
* Result from HTML generation including both file paths and content
* @internal
*/
interface HtmlGenerationResult {
normal?: {
path: string;
content: string;
};
highlight?: {
path: string;
content: string;
};
}
/**
* Generate HTML formats (normal and/or highlight)
*
* @param processedResult - Processed result with cached content
* @param options - Generation options
* @returns Promise resolving to HTML file paths and content (for reuse in PDF generation)
* @internal
*/
declare function generateHtmlFormats(processedResult: LegalMarkdownProcessorResult, options: FormatGenerationOptions): Promise<HtmlGenerationResult>;
/**
* Generate DOCX formats (normal and/or highlight)
*
* Reuses cached HTML when available to avoid duplicated HTML generation.
*
* @param processedResult - Processed result with cached content
* @param options - Generation options
* @param cachedHtml - Optional pre-generated HTML content to reuse
* @returns Promise resolving to DOCX file paths
* @internal
*/
declare function generateDocxFormats(processedResult: LegalMarkdownProcessorResult, options: FormatGenerationOptions, cachedHtml?: HtmlGenerationResult): Promise<{
normal?: string;
highlight?: string;
}>;
/**
* Generate PDF formats (normal and/or highlight)
*
* Uses the 3-phase pipeline approach: generates HTML once, then converts to PDF.
* This avoids re-processing the markdown and ensures the PDF uses exactly the
* same HTML that would be saved to disk.
*
* IMPORTANT: This function calls generatePdfFromHtml() to avoid double-conversion.
* The old approach called generatePdf(markdown) which would regenerate HTML internally,
* violating the 3-phase pipeline's "process once, output many" principle.
*
* When cachedHtml is provided, it will be reused instead of regenerating HTML,
* achieving the ideal "process once, output many" architecture.
*
* @param processedResult - Processed result with cached content
* @param options - Generation options
* @param cachedHtml - Optional pre-generated HTML content to reuse
* @returns Promise resolving to PDF file paths
* @internal
*/
declare function generatePdfFormats(processedResult: LegalMarkdownProcessorResult, options: FormatGenerationOptions, cachedHtml?: HtmlGenerationResult): Promise<{
normal?: string;
highlight?: string;
}>;
export { generateHtmlFormats as _generateHtmlFormats, generatePdfFormats as _generatePdfFormats, generateDocxFormats as _generateDocxFormats, };
//# sourceMappingURL=format-generator.d.ts.map