legal-markdown-js 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +168 -0
- package/dist/browser.d.ts +87 -0
- package/dist/browser.d.ts.map +1 -0
- package/dist/browser.js +157 -0
- package/dist/browser.js.map +1 -0
- package/dist/cli/index.d.ts +34 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +221 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/service.d.ts +128 -0
- package/dist/cli/service.d.ts.map +1 -0
- package/dist/cli/service.js +284 -0
- package/dist/cli/service.js.map +1 -0
- package/dist/constants/index.d.ts +229 -0
- package/dist/constants/index.d.ts.map +1 -0
- package/dist/constants/index.js +232 -0
- package/dist/constants/index.js.map +1 -0
- package/dist/core/exporters/metadata-exporter.d.ts +104 -0
- package/dist/core/exporters/metadata-exporter.d.ts.map +1 -0
- package/dist/core/exporters/metadata-exporter.js +201 -0
- package/dist/core/exporters/metadata-exporter.js.map +1 -0
- package/dist/core/index.d.ts +40 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +56 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/parsers/yaml-parser.d.ts +149 -0
- package/dist/core/parsers/yaml-parser.d.ts.map +1 -0
- package/dist/core/parsers/yaml-parser.js +321 -0
- package/dist/core/parsers/yaml-parser.js.map +1 -0
- package/dist/core/processors/clause-processor.d.ts +74 -0
- package/dist/core/processors/clause-processor.d.ts.map +1 -0
- package/dist/core/processors/clause-processor.js +213 -0
- package/dist/core/processors/clause-processor.js.map +1 -0
- package/dist/core/processors/date-processor.d.ts +90 -0
- package/dist/core/processors/date-processor.d.ts.map +1 -0
- package/dist/core/processors/date-processor.js +336 -0
- package/dist/core/processors/date-processor.js.map +1 -0
- package/dist/core/processors/header-processor.d.ts +104 -0
- package/dist/core/processors/header-processor.d.ts.map +1 -0
- package/dist/core/processors/header-processor.js +585 -0
- package/dist/core/processors/header-processor.js.map +1 -0
- package/dist/core/processors/import-processor.d.ts +116 -0
- package/dist/core/processors/import-processor.d.ts.map +1 -0
- package/dist/core/processors/import-processor.js +236 -0
- package/dist/core/processors/import-processor.js.map +1 -0
- package/dist/core/processors/mixin-processor.d.ts +93 -0
- package/dist/core/processors/mixin-processor.d.ts.map +1 -0
- package/dist/core/processors/mixin-processor.js +378 -0
- package/dist/core/processors/mixin-processor.js.map +1 -0
- package/dist/core/processors/reference-processor.d.ts +115 -0
- package/dist/core/processors/reference-processor.d.ts.map +1 -0
- package/dist/core/processors/reference-processor.js +273 -0
- package/dist/core/processors/reference-processor.js.map +1 -0
- package/dist/errors/index.d.ts +234 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/index.js +267 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/extensions/batch-processor.d.ts +197 -0
- package/dist/extensions/batch-processor.d.ts.map +1 -0
- package/dist/extensions/batch-processor.js +392 -0
- package/dist/extensions/batch-processor.js.map +1 -0
- package/dist/extensions/formatters/index.d.ts +99 -0
- package/dist/extensions/formatters/index.d.ts.map +1 -0
- package/dist/extensions/formatters/index.js +128 -0
- package/dist/extensions/formatters/index.js.map +1 -0
- package/dist/extensions/index.d.ts +53 -0
- package/dist/extensions/index.d.ts.map +1 -0
- package/dist/extensions/index.js +71 -0
- package/dist/extensions/index.js.map +1 -0
- package/dist/extensions/latex-parser.d.ts +111 -0
- package/dist/extensions/latex-parser.d.ts.map +1 -0
- package/dist/extensions/latex-parser.js +563 -0
- package/dist/extensions/latex-parser.js.map +1 -0
- package/dist/extensions/rst-parser.d.ts +112 -0
- package/dist/extensions/rst-parser.d.ts.map +1 -0
- package/dist/extensions/rst-parser.js +268 -0
- package/dist/extensions/rst-parser.js.map +1 -0
- package/dist/extensions/template-loops.d.ts +61 -0
- package/dist/extensions/template-loops.d.ts.map +1 -0
- package/dist/extensions/template-loops.js +418 -0
- package/dist/extensions/template-loops.js.map +1 -0
- package/dist/extensions/utilities/index.d.ts +114 -0
- package/dist/extensions/utilities/index.d.ts.map +1 -0
- package/dist/extensions/utilities/index.js +137 -0
- package/dist/extensions/utilities/index.js.map +1 -0
- package/dist/extensions/validators/index.d.ts +65 -0
- package/dist/extensions/validators/index.d.ts.map +1 -0
- package/dist/extensions/validators/index.js +88 -0
- package/dist/extensions/validators/index.js.map +1 -0
- package/dist/generators/html-generator.d.ts +184 -0
- package/dist/generators/html-generator.d.ts.map +1 -0
- package/dist/generators/html-generator.js +361 -0
- package/dist/generators/html-generator.js.map +1 -0
- package/dist/generators/pdf-generator.d.ts +165 -0
- package/dist/generators/pdf-generator.d.ts.map +1 -0
- package/dist/generators/pdf-generator.js +275 -0
- package/dist/generators/pdf-generator.js.map +1 -0
- package/dist/helpers/date-helpers.d.ts +216 -0
- package/dist/helpers/date-helpers.d.ts.map +1 -0
- package/dist/helpers/date-helpers.js +402 -0
- package/dist/helpers/date-helpers.js.map +1 -0
- package/dist/helpers/index.d.ts +87 -0
- package/dist/helpers/index.d.ts.map +1 -0
- package/dist/helpers/index.js +149 -0
- package/dist/helpers/index.js.map +1 -0
- package/dist/helpers/number-helpers.d.ts +269 -0
- package/dist/helpers/number-helpers.d.ts.map +1 -0
- package/dist/helpers/number-helpers.js +406 -0
- package/dist/helpers/number-helpers.js.map +1 -0
- package/dist/helpers/string-helpers.d.ts +391 -0
- package/dist/helpers/string-helpers.d.ts.map +1 -0
- package/dist/helpers/string-helpers.js +549 -0
- package/dist/helpers/string-helpers.js.map +1 -0
- package/dist/index.d.ts +229 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +384 -0
- package/dist/index.js.map +1 -0
- package/dist/legal-markdown.umd.min.js +2 -0
- package/dist/legal-markdown.umd.min.js.LICENSE.txt +14 -0
- package/dist/legal-markdown.umd.min.js.map +1 -0
- package/dist/lib/index.d.ts +150 -0
- package/dist/lib/index.d.ts.map +1 -0
- package/dist/lib/index.js +265 -0
- package/dist/lib/index.js.map +1 -0
- package/dist/parsers/content-detector.d.ts +131 -0
- package/dist/parsers/content-detector.d.ts.map +1 -0
- package/dist/parsers/content-detector.js +220 -0
- package/dist/parsers/content-detector.js.map +1 -0
- package/dist/parsers/fallback-parsers.d.ts +14 -0
- package/dist/parsers/fallback-parsers.d.ts.map +1 -0
- package/dist/parsers/fallback-parsers.js +188 -0
- package/dist/parsers/fallback-parsers.js.map +1 -0
- package/dist/parsers/implementations/pandoc-native.d.ts +13 -0
- package/dist/parsers/implementations/pandoc-native.d.ts.map +1 -0
- package/dist/parsers/implementations/pandoc-native.js +63 -0
- package/dist/parsers/implementations/pandoc-native.js.map +1 -0
- package/dist/parsers/implementations/pandoc-wasm.d.ts +14 -0
- package/dist/parsers/implementations/pandoc-wasm.d.ts.map +1 -0
- package/dist/parsers/implementations/pandoc-wasm.js +64 -0
- package/dist/parsers/implementations/pandoc-wasm.js.map +1 -0
- package/dist/parsers/pandoc-factory.d.ts +97 -0
- package/dist/parsers/pandoc-factory.d.ts.map +1 -0
- package/dist/parsers/pandoc-factory.js +146 -0
- package/dist/parsers/pandoc-factory.js.map +1 -0
- package/dist/parsers/pandoc-loader.d.ts +24 -0
- package/dist/parsers/pandoc-loader.d.ts.map +1 -0
- package/dist/parsers/pandoc-loader.js +124 -0
- package/dist/parsers/pandoc-loader.js.map +1 -0
- package/dist/parsers/pandoc-parser.d.ts +27 -0
- package/dist/parsers/pandoc-parser.d.ts.map +1 -0
- package/dist/parsers/pandoc-parser.js +3 -0
- package/dist/parsers/pandoc-parser.js.map +1 -0
- package/dist/styles/default.css +125 -0
- package/dist/styles/headers.css +146 -0
- package/dist/styles/highlight.css +171 -0
- package/dist/tracking/field-tracker.d.ts +206 -0
- package/dist/tracking/field-tracker.d.ts.map +1 -0
- package/dist/tracking/field-tracker.js +247 -0
- package/dist/tracking/field-tracker.js.map +1 -0
- package/dist/types.d.ts +186 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +33 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/logger.d.ts +107 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +122 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/web/bundle-standalone.js +28 -0
- package/dist/web/bundle.js +17 -0
- package/dist/web/index.html +1465 -0
- package/dist/web/legal-markdown.umd.min.js +2 -0
- package/dist/web/standalone.html +390 -0
- package/dist/web/styles.css +874 -0
- package/package.json +118 -0
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @fileoverview PDF Generation Module for Legal Markdown Documents
|
|
4
|
+
*
|
|
5
|
+
* This module provides functionality to convert processed Legal Markdown content
|
|
6
|
+
* into professional PDF documents using Puppeteer for HTML-to-PDF conversion.
|
|
7
|
+
* It builds upon the HTML generator to create print-ready documents with
|
|
8
|
+
* customizable formatting, page layouts, and styling options.
|
|
9
|
+
*
|
|
10
|
+
* Features:
|
|
11
|
+
* - HTML-to-PDF conversion using Puppeteer
|
|
12
|
+
* - Multiple page formats (A4, Letter, Legal)
|
|
13
|
+
* - Customizable margins and page orientation
|
|
14
|
+
* - Header and footer template support
|
|
15
|
+
* - Field highlighting for document review
|
|
16
|
+
* - Temporary file management and cleanup
|
|
17
|
+
* - Error handling and logging
|
|
18
|
+
* - Dual PDF generation (normal and highlighted versions)
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```typescript
|
|
22
|
+
* import { pdfGenerator } from './pdf-generator';
|
|
23
|
+
*
|
|
24
|
+
* const pdf = await pdfGenerator.generatePdf(markdownContent, './output.pdf', {
|
|
25
|
+
* format: 'A4',
|
|
26
|
+
* landscape: false,
|
|
27
|
+
* includeHighlighting: true,
|
|
28
|
+
* margin: { top: '2cm', bottom: '2cm' }
|
|
29
|
+
* });
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
33
|
+
if (k2 === undefined) k2 = k;
|
|
34
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
35
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
36
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
37
|
+
}
|
|
38
|
+
Object.defineProperty(o, k2, desc);
|
|
39
|
+
}) : (function(o, m, k, k2) {
|
|
40
|
+
if (k2 === undefined) k2 = k;
|
|
41
|
+
o[k2] = m[k];
|
|
42
|
+
}));
|
|
43
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
44
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
45
|
+
}) : function(o, v) {
|
|
46
|
+
o["default"] = v;
|
|
47
|
+
});
|
|
48
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
49
|
+
var ownKeys = function(o) {
|
|
50
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
51
|
+
var ar = [];
|
|
52
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
53
|
+
return ar;
|
|
54
|
+
};
|
|
55
|
+
return ownKeys(o);
|
|
56
|
+
};
|
|
57
|
+
return function (mod) {
|
|
58
|
+
if (mod && mod.__esModule) return mod;
|
|
59
|
+
var result = {};
|
|
60
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
61
|
+
__setModuleDefault(result, mod);
|
|
62
|
+
return result;
|
|
63
|
+
};
|
|
64
|
+
})();
|
|
65
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
66
|
+
exports.pdfGenerator = exports.PdfGenerator = void 0;
|
|
67
|
+
const puppeteer = __importStar(require("puppeteer"));
|
|
68
|
+
const fs = __importStar(require("fs/promises"));
|
|
69
|
+
const path = __importStar(require("path"));
|
|
70
|
+
const logger_1 = require("../utils/logger");
|
|
71
|
+
const html_generator_1 = require("./html-generator");
|
|
72
|
+
/**
|
|
73
|
+
* PDF Generator for Legal Markdown Documents
|
|
74
|
+
*
|
|
75
|
+
* Converts processed Legal Markdown content into PDF documents using Puppeteer
|
|
76
|
+
* for HTML-to-PDF conversion. Provides comprehensive formatting options and
|
|
77
|
+
* supports both normal and highlighted document versions.
|
|
78
|
+
*
|
|
79
|
+
* @class PdfGenerator
|
|
80
|
+
* @example
|
|
81
|
+
* ```typescript
|
|
82
|
+
* const generator = new PdfGenerator();
|
|
83
|
+
* const pdf = await generator.generatePdf(content, './output.pdf', {
|
|
84
|
+
* format: 'A4',
|
|
85
|
+
* includeHighlighting: true
|
|
86
|
+
* });
|
|
87
|
+
* ```
|
|
88
|
+
*/
|
|
89
|
+
class PdfGenerator {
|
|
90
|
+
/**
|
|
91
|
+
* Creates a new PDF generator instance
|
|
92
|
+
*
|
|
93
|
+
* @constructor
|
|
94
|
+
*/
|
|
95
|
+
constructor() {
|
|
96
|
+
this.puppeteerOptions = {
|
|
97
|
+
headless: true,
|
|
98
|
+
args: [
|
|
99
|
+
'--no-sandbox',
|
|
100
|
+
'--disable-setuid-sandbox',
|
|
101
|
+
'--disable-dev-shm-usage',
|
|
102
|
+
'--disable-accelerated-2d-canvas',
|
|
103
|
+
'--no-first-run',
|
|
104
|
+
'--no-zygote',
|
|
105
|
+
'--single-process',
|
|
106
|
+
'--disable-gpu',
|
|
107
|
+
],
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Generates a PDF document from Legal Markdown content
|
|
112
|
+
*
|
|
113
|
+
* This method orchestrates the complete PDF generation process:
|
|
114
|
+
* 1. Converts markdown to HTML using the HTML generator
|
|
115
|
+
* 2. Creates a temporary HTML file for Puppeteer
|
|
116
|
+
* 3. Launches a headless Chrome browser
|
|
117
|
+
* 4. Loads the HTML and generates PDF with specified options
|
|
118
|
+
* 5. Cleans up temporary files and browser resources
|
|
119
|
+
*
|
|
120
|
+
* @async
|
|
121
|
+
* @param {string} markdownContent - The processed Legal Markdown content
|
|
122
|
+
* @param {string} outputPath - Path where the PDF will be saved
|
|
123
|
+
* @param {PdfGeneratorOptions} [options={}] - Configuration options for PDF generation
|
|
124
|
+
* @returns {Promise<Buffer>} A promise that resolves to the PDF buffer
|
|
125
|
+
* @throws {Error} When PDF generation fails due to browser, file system, or processing errors
|
|
126
|
+
* @example
|
|
127
|
+
* ```typescript
|
|
128
|
+
* const pdf = await generator.generatePdf(
|
|
129
|
+
* markdownContent,
|
|
130
|
+
* './contract.pdf',
|
|
131
|
+
* {
|
|
132
|
+
* format: 'A4',
|
|
133
|
+
* landscape: false,
|
|
134
|
+
* includeHighlighting: true,
|
|
135
|
+
* margin: { top: '2cm', bottom: '2cm' }
|
|
136
|
+
* }
|
|
137
|
+
* );
|
|
138
|
+
* ```
|
|
139
|
+
*/
|
|
140
|
+
async generatePdf(markdownContent, outputPath, options = {}) {
|
|
141
|
+
let browser = null;
|
|
142
|
+
let tempHtmlPath = null;
|
|
143
|
+
try {
|
|
144
|
+
logger_1.logger.debug('Starting PDF generation', {
|
|
145
|
+
outputPath,
|
|
146
|
+
options,
|
|
147
|
+
});
|
|
148
|
+
// Generate HTML content first
|
|
149
|
+
const htmlContent = await html_generator_1.htmlGenerator.generateHtml(markdownContent, options);
|
|
150
|
+
// Create temporary HTML file
|
|
151
|
+
const tempDir = path.join(process.cwd(), '.temp');
|
|
152
|
+
await fs.mkdir(tempDir, { recursive: true });
|
|
153
|
+
tempHtmlPath = path.join(tempDir, `temp-${Date.now()}.html`);
|
|
154
|
+
await fs.writeFile(tempHtmlPath, htmlContent, 'utf-8');
|
|
155
|
+
// Launch browser
|
|
156
|
+
logger_1.logger.debug('Launching Puppeteer browser');
|
|
157
|
+
browser = await puppeteer.launch(this.puppeteerOptions);
|
|
158
|
+
const page = await browser.newPage();
|
|
159
|
+
// Load the HTML file
|
|
160
|
+
const fileUrl = `file://${path.resolve(tempHtmlPath)}`;
|
|
161
|
+
await page.goto(fileUrl, {
|
|
162
|
+
waitUntil: ['load', 'networkidle0'],
|
|
163
|
+
timeout: 30000,
|
|
164
|
+
});
|
|
165
|
+
// Configure PDF options
|
|
166
|
+
const pdfOptions = {
|
|
167
|
+
path: outputPath,
|
|
168
|
+
format: options.format || 'A4',
|
|
169
|
+
landscape: options.landscape || false,
|
|
170
|
+
printBackground: options.printBackground !== false,
|
|
171
|
+
displayHeaderFooter: options.displayHeaderFooter || false,
|
|
172
|
+
preferCSSPageSize: options.preferCSSPageSize || false,
|
|
173
|
+
margin: options.margin || {
|
|
174
|
+
top: '1cm',
|
|
175
|
+
right: '1cm',
|
|
176
|
+
bottom: '1cm',
|
|
177
|
+
left: '1cm',
|
|
178
|
+
},
|
|
179
|
+
};
|
|
180
|
+
// Add header and footer if provided
|
|
181
|
+
if (options.headerTemplate) {
|
|
182
|
+
pdfOptions.headerTemplate = options.headerTemplate;
|
|
183
|
+
}
|
|
184
|
+
if (options.footerTemplate) {
|
|
185
|
+
pdfOptions.footerTemplate = options.footerTemplate;
|
|
186
|
+
}
|
|
187
|
+
// Generate PDF
|
|
188
|
+
logger_1.logger.debug('Generating PDF with options', { pdfOptions });
|
|
189
|
+
const pdfBuffer = await page.pdf(pdfOptions);
|
|
190
|
+
// Ensure output directory exists
|
|
191
|
+
const outputDir = path.dirname(outputPath);
|
|
192
|
+
await fs.mkdir(outputDir, { recursive: true });
|
|
193
|
+
// Write PDF file
|
|
194
|
+
await fs.writeFile(outputPath, pdfBuffer);
|
|
195
|
+
logger_1.logger.info('PDF generated successfully', {
|
|
196
|
+
outputPath,
|
|
197
|
+
size: pdfBuffer.length,
|
|
198
|
+
});
|
|
199
|
+
return Buffer.from(pdfBuffer);
|
|
200
|
+
}
|
|
201
|
+
catch (error) {
|
|
202
|
+
logger_1.logger.error('Error generating PDF', { error });
|
|
203
|
+
throw new Error(`Failed to generate PDF: ${error instanceof Error ? error.message : String(error)}`);
|
|
204
|
+
}
|
|
205
|
+
finally {
|
|
206
|
+
// Cleanup
|
|
207
|
+
if (browser) {
|
|
208
|
+
await browser.close();
|
|
209
|
+
}
|
|
210
|
+
if (tempHtmlPath) {
|
|
211
|
+
try {
|
|
212
|
+
await fs.unlink(tempHtmlPath);
|
|
213
|
+
}
|
|
214
|
+
catch (error) {
|
|
215
|
+
logger_1.logger.warn('Failed to delete temporary HTML file', { error });
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Generate two PDF versions: one normal and one with highlighting
|
|
222
|
+
*
|
|
223
|
+
* This method creates two PDF versions of the same document:
|
|
224
|
+
* 1. A normal version without field highlighting
|
|
225
|
+
* 2. A highlighted version with field annotations
|
|
226
|
+
*
|
|
227
|
+
* This is useful for document review processes where both clean and
|
|
228
|
+
* annotated versions are needed for different purposes.
|
|
229
|
+
*
|
|
230
|
+
* @async
|
|
231
|
+
* @param {string} markdownContent - The processed Legal Markdown content
|
|
232
|
+
* @param {string} outputPath - Base path for PDF files (will be modified for each version)
|
|
233
|
+
* @param {PdfGeneratorOptions} [options={}] - Configuration options for PDF generation
|
|
234
|
+
* @returns {Promise<Object>} A promise that resolves to both PDF buffers
|
|
235
|
+
* @returns {Buffer} returns.normal - The normal PDF without highlighting
|
|
236
|
+
* @returns {Buffer} returns.highlighted - The highlighted PDF with field annotations
|
|
237
|
+
* @throws {Error} When PDF generation fails for either version
|
|
238
|
+
* @example
|
|
239
|
+
* ```typescript
|
|
240
|
+
* const { normal, highlighted } = await generator.generatePdfVersions(
|
|
241
|
+
* markdownContent,
|
|
242
|
+
* './contract.pdf',
|
|
243
|
+
* { format: 'A4' }
|
|
244
|
+
* );
|
|
245
|
+
* // Creates: contract.normal.pdf and contract.highlighted.pdf
|
|
246
|
+
* ```
|
|
247
|
+
*/
|
|
248
|
+
async generatePdfVersions(markdownContent, outputPath, options = {}) {
|
|
249
|
+
// Generate normal PDF
|
|
250
|
+
const normalPath = outputPath.replace('.pdf', '.normal.pdf');
|
|
251
|
+
const normalOptions = { ...options, includeHighlighting: false };
|
|
252
|
+
const normalPdf = await this.generatePdf(markdownContent, normalPath, normalOptions);
|
|
253
|
+
// Generate highlighted PDF
|
|
254
|
+
const highlightedPath = outputPath.replace('.pdf', '.highlighted.pdf');
|
|
255
|
+
const highlightedOptions = { ...options, includeHighlighting: true };
|
|
256
|
+
const highlightedPdf = await this.generatePdf(markdownContent, highlightedPath, highlightedOptions);
|
|
257
|
+
return {
|
|
258
|
+
normal: normalPdf,
|
|
259
|
+
highlighted: highlightedPdf,
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
exports.PdfGenerator = PdfGenerator;
|
|
264
|
+
/**
|
|
265
|
+
* Singleton instance of PdfGenerator for convenient importing
|
|
266
|
+
*
|
|
267
|
+
* @constant {PdfGenerator} pdfGenerator
|
|
268
|
+
* @example
|
|
269
|
+
* ```typescript
|
|
270
|
+
* import { pdfGenerator } from './pdf-generator';
|
|
271
|
+
* const pdf = await pdfGenerator.generatePdf(content, './output.pdf');
|
|
272
|
+
* ```
|
|
273
|
+
*/
|
|
274
|
+
exports.pdfGenerator = new PdfGenerator();
|
|
275
|
+
//# sourceMappingURL=pdf-generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pdf-generator.js","sourceRoot":"","sources":["../../src/generators/pdf-generator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Date Manipulation and Formatting Helpers
|
|
3
|
+
*
|
|
4
|
+
* This module provides comprehensive date manipulation and formatting utilities
|
|
5
|
+
* specifically designed for legal documents. It includes functions for date
|
|
6
|
+
* arithmetic, parsing, and formatting with legal-specific date formats.
|
|
7
|
+
*
|
|
8
|
+
* Features:
|
|
9
|
+
* - Date arithmetic (add years, months, days)
|
|
10
|
+
* - Flexible date formatting with multiple format options
|
|
11
|
+
* - Legal-specific date formats (formal, ordinal, etc.)
|
|
12
|
+
* - Date parsing with format detection
|
|
13
|
+
* - Comprehensive error handling for invalid dates
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* import { formatDate, addYears, DateFormats } from './date-helpers';
|
|
18
|
+
*
|
|
19
|
+
* // Format a date for legal documents
|
|
20
|
+
* const legalDate = formatDate(new Date(), DateFormats.LEGAL);
|
|
21
|
+
* // Result: "16th day of July, 2025"
|
|
22
|
+
*
|
|
23
|
+
* // Add years to a contract date
|
|
24
|
+
* const expiryDate = addYears('2025-01-01', 5);
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
/**
|
|
28
|
+
* Adds a specified number of years to a date
|
|
29
|
+
*
|
|
30
|
+
* This function handles both Date objects and ISO date strings, making it
|
|
31
|
+
* useful for contract calculations and legal document date processing.
|
|
32
|
+
*
|
|
33
|
+
* @param {Date | string} date - The base date as a Date object or ISO string
|
|
34
|
+
* @param {number} years - The number of years to add (can be negative)
|
|
35
|
+
* @returns {Date} A new Date object with the years added
|
|
36
|
+
* @throws {Error} If the input date is invalid
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```typescript
|
|
40
|
+
* // Add 5 years to a contract start date
|
|
41
|
+
* const startDate = new Date('2025-01-01');
|
|
42
|
+
* const endDate = addYears(startDate, 5);
|
|
43
|
+
* // Result: Date object for 2030-01-01
|
|
44
|
+
*
|
|
45
|
+
* // Using with string input
|
|
46
|
+
* const futureDate = addYears('2025-07-16', 2);
|
|
47
|
+
* // Result: Date object for 2027-07-16
|
|
48
|
+
*
|
|
49
|
+
* // Subtract years (negative input)
|
|
50
|
+
* const pastDate = addYears(new Date(), -3);
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
export declare function addYears(date: Date | string, years: number): Date;
|
|
54
|
+
/**
|
|
55
|
+
* Adds a specified number of days to a date
|
|
56
|
+
*
|
|
57
|
+
* Useful for calculating deadlines, notice periods, and other time-sensitive
|
|
58
|
+
* legal requirements in contracts and legal documents.
|
|
59
|
+
*
|
|
60
|
+
* @param {Date | string} date - The base date as a Date object or ISO string
|
|
61
|
+
* @param {number} days - The number of days to add (can be negative)
|
|
62
|
+
* @returns {Date} A new Date object with the days added
|
|
63
|
+
* @throws {Error} If the input date is invalid
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* ```typescript
|
|
67
|
+
* // Add 30 days for a notice period
|
|
68
|
+
* const noticeDate = addDays(new Date(), 30);
|
|
69
|
+
*
|
|
70
|
+
* // Calculate deadline from string date
|
|
71
|
+
* const deadline = addDays('2025-07-16', 14);
|
|
72
|
+
* // Result: Date object for 2025-07-30
|
|
73
|
+
*
|
|
74
|
+
* // Go back in time (negative days)
|
|
75
|
+
* const pastDate = addDays(new Date(), -7);
|
|
76
|
+
* ```
|
|
77
|
+
*/
|
|
78
|
+
export declare function addDays(date: Date | string, days: number): Date;
|
|
79
|
+
/**
|
|
80
|
+
* Adds a specified number of months to a date
|
|
81
|
+
*
|
|
82
|
+
* Handles month boundaries intelligently, useful for calculating quarterly
|
|
83
|
+
* reports, monthly payments, and other periodic legal obligations.
|
|
84
|
+
*
|
|
85
|
+
* @param {Date | string} date - The base date as a Date object or ISO string
|
|
86
|
+
* @param {number} months - The number of months to add (can be negative)
|
|
87
|
+
* @returns {Date} A new Date object with the months added
|
|
88
|
+
* @throws {Error} If the input date is invalid
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* ```typescript
|
|
92
|
+
* // Add 6 months for a review period
|
|
93
|
+
* const reviewDate = addMonths(new Date('2025-01-31'), 6);
|
|
94
|
+
* // Result: Date object for 2025-07-31
|
|
95
|
+
*
|
|
96
|
+
* // Calculate quarterly dates
|
|
97
|
+
* const quarterlyDate = addMonths('2025-01-01', 3);
|
|
98
|
+
* // Result: Date object for 2025-04-01
|
|
99
|
+
*
|
|
100
|
+
* // Previous months (negative input)
|
|
101
|
+
* const previousQuarter = addMonths(new Date(), -3);
|
|
102
|
+
* ```
|
|
103
|
+
*/
|
|
104
|
+
export declare function addMonths(date: Date | string, months: number): Date;
|
|
105
|
+
/**
|
|
106
|
+
* Formats a date using customizable format strings
|
|
107
|
+
*
|
|
108
|
+
* Provides flexible date formatting with support for multiple format tokens.
|
|
109
|
+
* Particularly useful for legal documents that require specific date formats
|
|
110
|
+
* for different jurisdictions and document types.
|
|
111
|
+
*
|
|
112
|
+
* @param {Date | string} date - The date to format as a Date object or ISO string
|
|
113
|
+
* @param {string} format - The format string (default: 'YYYY-MM-DD')
|
|
114
|
+
* @returns {string} The formatted date string
|
|
115
|
+
* @throws {Error} If the input date is invalid
|
|
116
|
+
*
|
|
117
|
+
* Format tokens:
|
|
118
|
+
* - YYYY: 4-digit year (2025)
|
|
119
|
+
* - YY: 2-digit year (25)
|
|
120
|
+
* - MMMM: Full month name (January)
|
|
121
|
+
* - MMM: Abbreviated month name (Jan)
|
|
122
|
+
* - MM: 2-digit month (01)
|
|
123
|
+
* - M: Month number (1)
|
|
124
|
+
* - DD: 2-digit day (01)
|
|
125
|
+
* - D: Day number (1)
|
|
126
|
+
* - Do: Ordinal day (1st, 2nd, 3rd)
|
|
127
|
+
* - dddd: Full day name (Monday)
|
|
128
|
+
* - ddd: Abbreviated day name (Mon)
|
|
129
|
+
*
|
|
130
|
+
* @example
|
|
131
|
+
* ```typescript
|
|
132
|
+
* const date = new Date('2025-07-16');
|
|
133
|
+
*
|
|
134
|
+
* // Standard formats
|
|
135
|
+
* formatDate(date, 'YYYY-MM-DD'); // "2025-07-16"
|
|
136
|
+
* formatDate(date, 'MM/DD/YYYY'); // "07/16/2025"
|
|
137
|
+
* formatDate(date, 'DD/MM/YYYY'); // "16/07/2025"
|
|
138
|
+
*
|
|
139
|
+
* // Legal document formats
|
|
140
|
+
* formatDate(date, DateFormats.LEGAL); // "16th day of July, 2025"
|
|
141
|
+
* formatDate(date, DateFormats.FORMAL); // "Wednesday, July 16th, 2025"
|
|
142
|
+
*
|
|
143
|
+
* // Custom format
|
|
144
|
+
* formatDate(date, 'MMMM Do, YYYY'); // "July 16th, 2025"
|
|
145
|
+
* ```
|
|
146
|
+
*/
|
|
147
|
+
export declare function formatDate(date: Date | string, format?: string): string;
|
|
148
|
+
/**
|
|
149
|
+
* Predefined date format constants for common legal document formats
|
|
150
|
+
*
|
|
151
|
+
* This object provides commonly used date formats in legal documents,
|
|
152
|
+
* making it easy to maintain consistency across different document types.
|
|
153
|
+
*
|
|
154
|
+
* @constant {Object} DateFormats
|
|
155
|
+
* @example
|
|
156
|
+
* ```typescript
|
|
157
|
+
* import { formatDate, DateFormats } from './date-helpers';
|
|
158
|
+
*
|
|
159
|
+
* const date = new Date('2025-07-16');
|
|
160
|
+
*
|
|
161
|
+
* // Use predefined formats
|
|
162
|
+
* formatDate(date, DateFormats.LEGAL); // "16th day of July, 2025"
|
|
163
|
+
* formatDate(date, DateFormats.FORMAL); // "Wednesday, July 16th, 2025"
|
|
164
|
+
* formatDate(date, DateFormats.US); // "07/16/2025"
|
|
165
|
+
* formatDate(date, DateFormats.EU); // "16/07/2025"
|
|
166
|
+
* ```
|
|
167
|
+
*/
|
|
168
|
+
export declare const DateFormats: {
|
|
169
|
+
readonly ISO: "YYYY-MM-DD";
|
|
170
|
+
readonly US: "MM/DD/YYYY";
|
|
171
|
+
readonly EU: "DD/MM/YYYY";
|
|
172
|
+
readonly UK: "DD/MM/YYYY";
|
|
173
|
+
readonly FULL: "MMMM Do, YYYY";
|
|
174
|
+
readonly FULL_US: "MMMM D, YYYY";
|
|
175
|
+
readonly SHORT: "MMM D, YYYY";
|
|
176
|
+
readonly LEGAL: "Do day of MMMM, YYYY";
|
|
177
|
+
readonly FORMAL: "dddd, MMMM Do, YYYY";
|
|
178
|
+
};
|
|
179
|
+
/**
|
|
180
|
+
* Parses date strings in various formats and returns a Date object
|
|
181
|
+
*
|
|
182
|
+
* Attempts to parse date strings in multiple common formats with intelligent
|
|
183
|
+
* format detection. Useful for processing user input or parsing dates from
|
|
184
|
+
* various document formats.
|
|
185
|
+
*
|
|
186
|
+
* @param {string} dateStr - The date string to parse
|
|
187
|
+
* @returns {Date | null} The parsed Date object, or null if parsing fails
|
|
188
|
+
*
|
|
189
|
+
* Supported formats:
|
|
190
|
+
* - ISO format: YYYY-MM-DD
|
|
191
|
+
* - US format: MM/DD/YYYY
|
|
192
|
+
* - European format: DD/MM/YYYY
|
|
193
|
+
* - Alternative separators: MM-DD-YYYY, DD-MM-YYYY
|
|
194
|
+
* - Natural language formats (via Date constructor)
|
|
195
|
+
*
|
|
196
|
+
* @example
|
|
197
|
+
* ```typescript
|
|
198
|
+
* // ISO format
|
|
199
|
+
* const date1 = parseDate('2025-07-16');
|
|
200
|
+
* // Result: Date object for July 16, 2025
|
|
201
|
+
*
|
|
202
|
+
* // US format (MM/DD/YYYY)
|
|
203
|
+
* const date2 = parseDate('07/16/2025');
|
|
204
|
+
* // Result: Date object for July 16, 2025
|
|
205
|
+
*
|
|
206
|
+
* // European format (DD/MM/YYYY)
|
|
207
|
+
* const date3 = parseDate('16/07/2025');
|
|
208
|
+
* // Result: Date object for July 16, 2025
|
|
209
|
+
*
|
|
210
|
+
* // Invalid date
|
|
211
|
+
* const invalid = parseDate('not a date');
|
|
212
|
+
* // Result: null
|
|
213
|
+
* ```
|
|
214
|
+
*/
|
|
215
|
+
export declare function parseDate(dateStr: string): Date | null;
|
|
216
|
+
//# sourceMappingURL=date-helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"date-helpers.d.ts","sourceRoot":"","sources":["../../src/helpers/date-helpers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAYjE;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAY/D;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAYnE;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,EAAE,MAAM,GAAE,MAAqB,GAAG,MAAM,CA+GrF;AA2BD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,WAAW;;;;;;;;;;CAUd,CAAC;AAEX;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAgCtD"}
|