ai-pdf-builder 0.3.1 → 0.4.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.
Potentially problematic release.
This version of ai-pdf-builder might be problematic. Click here for more details.
- package/dist/chunk-C63SSMWG.mjs +594 -0
- package/dist/cli.js +2 -2
- package/dist/cli.mjs +1 -1
- package/dist/index.js +2 -2
- package/dist/index.mjs +1 -1
- package/package.json +1 -1
- package/templates/agreement.latex +140 -100
- package/templates/memo.latex +75 -91
- package/templates/termsheet.latex +141 -147
- package/templates/whitepaper.latex +235 -0
|
@@ -0,0 +1,594 @@
|
|
|
1
|
+
// src/generator.ts
|
|
2
|
+
import { spawn } from "child_process";
|
|
3
|
+
import * as fs3 from "fs";
|
|
4
|
+
import * as path3 from "path";
|
|
5
|
+
|
|
6
|
+
// src/templates.ts
|
|
7
|
+
import * as fs from "fs";
|
|
8
|
+
import * as path from "path";
|
|
9
|
+
var TEMPLATES_DIR = path.join(__dirname, "..", "templates");
|
|
10
|
+
var BUILT_IN_TEMPLATES = {
|
|
11
|
+
default: {
|
|
12
|
+
name: "default",
|
|
13
|
+
path: path.join(TEMPLATES_DIR, "default.latex"),
|
|
14
|
+
description: "Clean, professional default template with modern styling",
|
|
15
|
+
supportedDocTypes: ["memo", "whitepaper", "report", "proposal", "generic"]
|
|
16
|
+
},
|
|
17
|
+
memo: {
|
|
18
|
+
name: "memo",
|
|
19
|
+
path: path.join(TEMPLATES_DIR, "memo.latex"),
|
|
20
|
+
description: "Business memo template with executive summary styling",
|
|
21
|
+
supportedDocTypes: ["memo", "report", "proposal"]
|
|
22
|
+
},
|
|
23
|
+
agreement: {
|
|
24
|
+
name: "agreement",
|
|
25
|
+
path: path.join(TEMPLATES_DIR, "agreement.latex"),
|
|
26
|
+
description: "Legal agreement template with formal structure",
|
|
27
|
+
supportedDocTypes: ["agreement", "generic"]
|
|
28
|
+
},
|
|
29
|
+
termsheet: {
|
|
30
|
+
name: "termsheet",
|
|
31
|
+
path: path.join(TEMPLATES_DIR, "termsheet.latex"),
|
|
32
|
+
description: "Term sheet template for investment documents",
|
|
33
|
+
supportedDocTypes: ["termsheet", "agreement"]
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
var customTemplates = /* @__PURE__ */ new Map();
|
|
37
|
+
var templateCache = /* @__PURE__ */ new Map();
|
|
38
|
+
function getTemplate(name) {
|
|
39
|
+
if (templateCache.has(name)) {
|
|
40
|
+
return templateCache.get(name) || null;
|
|
41
|
+
}
|
|
42
|
+
if (customTemplates.has(name)) {
|
|
43
|
+
const config = customTemplates.get(name);
|
|
44
|
+
return loadTemplateFile(config.path, name);
|
|
45
|
+
}
|
|
46
|
+
if (BUILT_IN_TEMPLATES[name]) {
|
|
47
|
+
return loadTemplateFile(BUILT_IN_TEMPLATES[name].path, name);
|
|
48
|
+
}
|
|
49
|
+
if (fs.existsSync(name)) {
|
|
50
|
+
return loadTemplateFile(name, name);
|
|
51
|
+
}
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
function getTemplatePath(name) {
|
|
55
|
+
if (customTemplates.has(name)) {
|
|
56
|
+
return customTemplates.get(name).path;
|
|
57
|
+
}
|
|
58
|
+
if (BUILT_IN_TEMPLATES[name]) {
|
|
59
|
+
return BUILT_IN_TEMPLATES[name].path;
|
|
60
|
+
}
|
|
61
|
+
if (fs.existsSync(name)) {
|
|
62
|
+
return name;
|
|
63
|
+
}
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
function loadTemplateFile(filePath, cacheKey) {
|
|
67
|
+
try {
|
|
68
|
+
if (!fs.existsSync(filePath)) {
|
|
69
|
+
console.warn(`Template file not found: ${filePath}`);
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
const content = fs.readFileSync(filePath, "utf-8");
|
|
73
|
+
templateCache.set(cacheKey, content);
|
|
74
|
+
return content;
|
|
75
|
+
} catch (error) {
|
|
76
|
+
console.error(`Error loading template ${filePath}:`, error);
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
function listTemplates() {
|
|
81
|
+
const builtIn = Object.values(BUILT_IN_TEMPLATES);
|
|
82
|
+
const custom = Array.from(customTemplates.values());
|
|
83
|
+
return [...builtIn, ...custom];
|
|
84
|
+
}
|
|
85
|
+
function getTemplateConfig(name) {
|
|
86
|
+
if (customTemplates.has(name)) {
|
|
87
|
+
return customTemplates.get(name) || null;
|
|
88
|
+
}
|
|
89
|
+
if (BUILT_IN_TEMPLATES[name]) {
|
|
90
|
+
return BUILT_IN_TEMPLATES[name];
|
|
91
|
+
}
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
function registerTemplate(config) {
|
|
95
|
+
if (!fs.existsSync(config.path)) {
|
|
96
|
+
throw new Error(`Template file not found: ${config.path}`);
|
|
97
|
+
}
|
|
98
|
+
const absolutePath = path.resolve(config.path);
|
|
99
|
+
customTemplates.set(config.name, {
|
|
100
|
+
...config,
|
|
101
|
+
path: absolutePath
|
|
102
|
+
});
|
|
103
|
+
templateCache.delete(config.name);
|
|
104
|
+
}
|
|
105
|
+
function unregisterTemplate(name) {
|
|
106
|
+
if (customTemplates.has(name)) {
|
|
107
|
+
customTemplates.delete(name);
|
|
108
|
+
templateCache.delete(name);
|
|
109
|
+
return true;
|
|
110
|
+
}
|
|
111
|
+
return false;
|
|
112
|
+
}
|
|
113
|
+
function hasTemplate(name) {
|
|
114
|
+
return customTemplates.has(name) || BUILT_IN_TEMPLATES.hasOwnProperty(name) || fs.existsSync(name);
|
|
115
|
+
}
|
|
116
|
+
function getTemplatesForDocType(docType) {
|
|
117
|
+
const all = listTemplates();
|
|
118
|
+
return all.filter((t) => t.supportedDocTypes.includes(docType));
|
|
119
|
+
}
|
|
120
|
+
function clearTemplateCache() {
|
|
121
|
+
templateCache.clear();
|
|
122
|
+
}
|
|
123
|
+
function getTemplatesDirectory() {
|
|
124
|
+
return TEMPLATES_DIR;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// src/utils.ts
|
|
128
|
+
import { execSync } from "child_process";
|
|
129
|
+
import * as fs2 from "fs";
|
|
130
|
+
import * as path2 from "path";
|
|
131
|
+
import * as os from "os";
|
|
132
|
+
function checkPandoc() {
|
|
133
|
+
try {
|
|
134
|
+
const version = execSync("pandoc --version", { encoding: "utf-8" });
|
|
135
|
+
const versionMatch = version.match(/pandoc\s+([\d.]+)/);
|
|
136
|
+
const pathResult = execSync("which pandoc", { encoding: "utf-8" }).trim();
|
|
137
|
+
return {
|
|
138
|
+
available: true,
|
|
139
|
+
version: versionMatch ? versionMatch[1] : "unknown",
|
|
140
|
+
path: pathResult
|
|
141
|
+
};
|
|
142
|
+
} catch (error) {
|
|
143
|
+
return {
|
|
144
|
+
available: false,
|
|
145
|
+
error: "Pandoc not found. Install with: brew install pandoc (macOS) or apt-get install pandoc (Linux)"
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
function checkLaTeX() {
|
|
150
|
+
try {
|
|
151
|
+
const version = execSync("pdflatex --version", { encoding: "utf-8" });
|
|
152
|
+
const versionMatch = version.match(/pdfTeX\s+([\d.-]+)/);
|
|
153
|
+
const pathResult = execSync("which pdflatex", { encoding: "utf-8" }).trim();
|
|
154
|
+
return {
|
|
155
|
+
available: true,
|
|
156
|
+
engine: "pdflatex",
|
|
157
|
+
version: versionMatch ? versionMatch[1] : "unknown",
|
|
158
|
+
path: pathResult
|
|
159
|
+
};
|
|
160
|
+
} catch (error) {
|
|
161
|
+
return {
|
|
162
|
+
available: false,
|
|
163
|
+
error: "pdflatex not found. Install BasicTeX (brew install --cask basictex) or TeX Live"
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
function checkSystem() {
|
|
168
|
+
const pandoc = checkPandoc();
|
|
169
|
+
const latex = checkLaTeX();
|
|
170
|
+
const ready = pandoc.available && latex.available;
|
|
171
|
+
let message = "";
|
|
172
|
+
if (ready) {
|
|
173
|
+
message = `Ready: Pandoc ${pandoc.version}, pdfTeX ${latex.version}`;
|
|
174
|
+
} else {
|
|
175
|
+
const missing = [];
|
|
176
|
+
if (!pandoc.available) missing.push("Pandoc");
|
|
177
|
+
if (!latex.available) missing.push("LaTeX/pdflatex");
|
|
178
|
+
message = `Missing dependencies: ${missing.join(", ")}`;
|
|
179
|
+
}
|
|
180
|
+
return { pandoc, latex, ready, message };
|
|
181
|
+
}
|
|
182
|
+
function createTempDir(prefix = "pdf-builder") {
|
|
183
|
+
const tempDir = path2.join(os.tmpdir(), `${prefix}-${Date.now()}`);
|
|
184
|
+
fs2.mkdirSync(tempDir, { recursive: true });
|
|
185
|
+
return tempDir;
|
|
186
|
+
}
|
|
187
|
+
function cleanupTempDir(dirPath) {
|
|
188
|
+
try {
|
|
189
|
+
if (fs2.existsSync(dirPath)) {
|
|
190
|
+
fs2.rmSync(dirPath, { recursive: true, force: true });
|
|
191
|
+
}
|
|
192
|
+
} catch (error) {
|
|
193
|
+
console.warn(`Warning: Could not clean up temp directory: ${dirPath}`);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
function generateYAMLFrontMatter(metadata) {
|
|
197
|
+
const lines = ["---"];
|
|
198
|
+
for (const [key, value] of Object.entries(metadata)) {
|
|
199
|
+
if (value !== void 0 && value !== "") {
|
|
200
|
+
const escapedValue = String(value).replace(/"/g, '\\"');
|
|
201
|
+
lines.push(`${key}: "${escapedValue}"`);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
lines.push("---");
|
|
205
|
+
return lines.join("\n");
|
|
206
|
+
}
|
|
207
|
+
function sanitizeContent(content) {
|
|
208
|
+
const dangerousCommands = [
|
|
209
|
+
"\\input",
|
|
210
|
+
"\\include",
|
|
211
|
+
"\\write18",
|
|
212
|
+
"\\immediate",
|
|
213
|
+
"\\openin",
|
|
214
|
+
"\\openout",
|
|
215
|
+
"\\read",
|
|
216
|
+
"\\write",
|
|
217
|
+
"\\newwrite",
|
|
218
|
+
"\\closeout",
|
|
219
|
+
"\\closein"
|
|
220
|
+
];
|
|
221
|
+
let sanitized = content;
|
|
222
|
+
for (const cmd of dangerousCommands) {
|
|
223
|
+
const regex = new RegExp(cmd.replace("\\", "\\\\") + "[^\\s{]*({[^}]*})?", "gi");
|
|
224
|
+
sanitized = sanitized.replace(regex, "");
|
|
225
|
+
}
|
|
226
|
+
return sanitized;
|
|
227
|
+
}
|
|
228
|
+
function parseColor(color) {
|
|
229
|
+
if (/^\d+,\s*\d+,\s*\d+$/.test(color)) {
|
|
230
|
+
return color.replace(/\s/g, "");
|
|
231
|
+
}
|
|
232
|
+
const rgbMatch = color.match(/RGB\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/i);
|
|
233
|
+
if (rgbMatch) {
|
|
234
|
+
return `${rgbMatch[1]},${rgbMatch[2]},${rgbMatch[3]}`;
|
|
235
|
+
}
|
|
236
|
+
const hexMatch = color.match(/^#?([A-Fa-f0-9]{2})([A-Fa-f0-9]{2})([A-Fa-f0-9]{2})$/);
|
|
237
|
+
if (hexMatch) {
|
|
238
|
+
const r = parseInt(hexMatch[1], 16);
|
|
239
|
+
const g = parseInt(hexMatch[2], 16);
|
|
240
|
+
const b = parseInt(hexMatch[3], 16);
|
|
241
|
+
return `${r},${g},${b}`;
|
|
242
|
+
}
|
|
243
|
+
return "59,130,246";
|
|
244
|
+
}
|
|
245
|
+
function formatFileSize(bytes) {
|
|
246
|
+
if (bytes < 1024) return `${bytes} B`;
|
|
247
|
+
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
|
|
248
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// src/generator.ts
|
|
252
|
+
var DEFAULT_OPTIONS = {
|
|
253
|
+
toc: true,
|
|
254
|
+
tocDepth: 2,
|
|
255
|
+
numberSections: true,
|
|
256
|
+
fontSize: 11,
|
|
257
|
+
margin: "1in",
|
|
258
|
+
paperSize: "letter",
|
|
259
|
+
timeout: 6e4
|
|
260
|
+
};
|
|
261
|
+
async function generatePDF(options) {
|
|
262
|
+
const startTime = Date.now();
|
|
263
|
+
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
264
|
+
const sysCheck = checkSystem();
|
|
265
|
+
if (!sysCheck.ready) {
|
|
266
|
+
return {
|
|
267
|
+
success: false,
|
|
268
|
+
error: `System requirements not met: ${sysCheck.message}`
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
if (!opts.content || opts.content.trim().length === 0) {
|
|
272
|
+
return {
|
|
273
|
+
success: false,
|
|
274
|
+
error: "Content is required"
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
let tempDir = null;
|
|
278
|
+
try {
|
|
279
|
+
tempDir = opts.workDir || createTempDir("pdf-builder");
|
|
280
|
+
const sanitizedContent = sanitizeContent(opts.content);
|
|
281
|
+
const fullMarkdown = buildMarkdownDocument(sanitizedContent, opts);
|
|
282
|
+
const inputPath = path3.join(tempDir, "input.md");
|
|
283
|
+
fs3.writeFileSync(inputPath, fullMarkdown, "utf-8");
|
|
284
|
+
const templatePath = await prepareTemplate(tempDir, opts);
|
|
285
|
+
const outputPath = opts.outputPath || path3.join(tempDir, "output.pdf");
|
|
286
|
+
const pandocOpts = {
|
|
287
|
+
inputPath,
|
|
288
|
+
outputPath,
|
|
289
|
+
templatePath,
|
|
290
|
+
toc: opts.toc ?? true,
|
|
291
|
+
tocDepth: opts.tocDepth ?? 2,
|
|
292
|
+
numberSections: opts.numberSections ?? true,
|
|
293
|
+
fontSize: opts.fontSize ?? 11,
|
|
294
|
+
margin: opts.margin ?? "1in",
|
|
295
|
+
paperSize: opts.paperSize ?? "letter",
|
|
296
|
+
timeout: opts.timeout ?? 6e4
|
|
297
|
+
};
|
|
298
|
+
await executePandoc(pandocOpts);
|
|
299
|
+
if (!fs3.existsSync(outputPath)) {
|
|
300
|
+
return {
|
|
301
|
+
success: false,
|
|
302
|
+
error: "PDF generation failed - output file not created"
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
const buffer = fs3.readFileSync(outputPath);
|
|
306
|
+
const stats = fs3.statSync(outputPath);
|
|
307
|
+
const generationTime = Date.now() - startTime;
|
|
308
|
+
const result = {
|
|
309
|
+
success: true,
|
|
310
|
+
buffer: opts.outputPath ? void 0 : buffer,
|
|
311
|
+
path: opts.outputPath || void 0,
|
|
312
|
+
fileSize: stats.size,
|
|
313
|
+
generationTime
|
|
314
|
+
};
|
|
315
|
+
result.pageCount = estimatePageCount(buffer);
|
|
316
|
+
return result;
|
|
317
|
+
} catch (error) {
|
|
318
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
319
|
+
return {
|
|
320
|
+
success: false,
|
|
321
|
+
error: `PDF generation failed: ${errorMessage}`,
|
|
322
|
+
generationTime: Date.now() - startTime
|
|
323
|
+
};
|
|
324
|
+
} finally {
|
|
325
|
+
if (tempDir && !opts.workDir && !opts.outputPath) {
|
|
326
|
+
} else if (tempDir && !opts.workDir) {
|
|
327
|
+
cleanupTempDir(tempDir);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
function buildMarkdownDocument(content, opts) {
|
|
332
|
+
const parts = [];
|
|
333
|
+
if (opts.metadata) {
|
|
334
|
+
const frontMatter = generateYAMLFrontMatter({
|
|
335
|
+
...opts.metadata,
|
|
336
|
+
geometry: `margin=${opts.margin || "1in"}`,
|
|
337
|
+
fontsize: `${opts.fontSize || 11}pt`,
|
|
338
|
+
papersize: opts.paperSize || "letter"
|
|
339
|
+
});
|
|
340
|
+
parts.push(frontMatter);
|
|
341
|
+
parts.push("");
|
|
342
|
+
}
|
|
343
|
+
parts.push(content);
|
|
344
|
+
return parts.join("\n");
|
|
345
|
+
}
|
|
346
|
+
async function prepareTemplate(tempDir, opts) {
|
|
347
|
+
const templateName = opts.template || "default";
|
|
348
|
+
let templateContent = getTemplate(templateName);
|
|
349
|
+
if (!templateContent) {
|
|
350
|
+
const templatePath = getTemplatePath(templateName);
|
|
351
|
+
if (templatePath && fs3.existsSync(templatePath)) {
|
|
352
|
+
templateContent = fs3.readFileSync(templatePath, "utf-8");
|
|
353
|
+
} else {
|
|
354
|
+
templateContent = getTemplate("default");
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
if (!templateContent) {
|
|
358
|
+
throw new Error(`Template not found: ${templateName}`);
|
|
359
|
+
}
|
|
360
|
+
if (opts.customColors) {
|
|
361
|
+
templateContent = applyColorCustomizations(templateContent, opts.customColors);
|
|
362
|
+
}
|
|
363
|
+
const customTemplatePath = path3.join(tempDir, "template.latex");
|
|
364
|
+
fs3.writeFileSync(customTemplatePath, templateContent, "utf-8");
|
|
365
|
+
return customTemplatePath;
|
|
366
|
+
}
|
|
367
|
+
function applyColorCustomizations(template, colors) {
|
|
368
|
+
let result = template;
|
|
369
|
+
if (colors.primary) {
|
|
370
|
+
const rgb = parseColor(colors.primary);
|
|
371
|
+
result = result.replace(
|
|
372
|
+
/\\definecolor{(?:zeroBlue|primaryColor)}{RGB}{[^}]+}/g,
|
|
373
|
+
`\\definecolor{primaryColor}{RGB}{${rgb}}`
|
|
374
|
+
);
|
|
375
|
+
}
|
|
376
|
+
if (colors.secondary) {
|
|
377
|
+
const rgb = parseColor(colors.secondary);
|
|
378
|
+
result = result.replace(
|
|
379
|
+
/\\definecolor{(?:zeroGray|secondaryColor)}{RGB}{[^}]+}/g,
|
|
380
|
+
`\\definecolor{secondaryColor}{RGB}{${rgb}}`
|
|
381
|
+
);
|
|
382
|
+
}
|
|
383
|
+
if (colors.accent) {
|
|
384
|
+
const rgb = parseColor(colors.accent);
|
|
385
|
+
result = result.replace(
|
|
386
|
+
/\\definecolor{(?:zeroDark|accentColor)}{RGB}{[^}]+}/g,
|
|
387
|
+
`\\definecolor{accentColor}{RGB}{${rgb}}`
|
|
388
|
+
);
|
|
389
|
+
}
|
|
390
|
+
return result;
|
|
391
|
+
}
|
|
392
|
+
function executePandoc(opts) {
|
|
393
|
+
return new Promise((resolve2, reject) => {
|
|
394
|
+
const args = [
|
|
395
|
+
opts.inputPath,
|
|
396
|
+
"-o",
|
|
397
|
+
opts.outputPath,
|
|
398
|
+
"--pdf-engine=pdflatex",
|
|
399
|
+
`-V`,
|
|
400
|
+
`geometry:margin=${opts.margin}`,
|
|
401
|
+
`-V`,
|
|
402
|
+
`fontsize=${opts.fontSize}pt`,
|
|
403
|
+
`-V`,
|
|
404
|
+
`papersize=${opts.paperSize}`,
|
|
405
|
+
`-V`,
|
|
406
|
+
`documentclass=article`,
|
|
407
|
+
`-V`,
|
|
408
|
+
`colorlinks=true`,
|
|
409
|
+
`-V`,
|
|
410
|
+
`linkcolor=blue`,
|
|
411
|
+
`-V`,
|
|
412
|
+
`urlcolor=blue`
|
|
413
|
+
];
|
|
414
|
+
if (opts.templatePath) {
|
|
415
|
+
args.push(`--template=${opts.templatePath}`);
|
|
416
|
+
}
|
|
417
|
+
if (opts.toc) {
|
|
418
|
+
args.push("--toc");
|
|
419
|
+
args.push(`--toc-depth=${opts.tocDepth}`);
|
|
420
|
+
}
|
|
421
|
+
if (opts.numberSections) {
|
|
422
|
+
args.push("--number-sections");
|
|
423
|
+
}
|
|
424
|
+
const pandoc = spawn("pandoc", args, {
|
|
425
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
426
|
+
});
|
|
427
|
+
let stderr = "";
|
|
428
|
+
pandoc.stderr.on("data", (data) => {
|
|
429
|
+
stderr += data.toString();
|
|
430
|
+
});
|
|
431
|
+
const timeout = setTimeout(() => {
|
|
432
|
+
pandoc.kill("SIGKILL");
|
|
433
|
+
reject(new Error(`Pandoc timed out after ${opts.timeout}ms`));
|
|
434
|
+
}, opts.timeout);
|
|
435
|
+
pandoc.on("close", (code) => {
|
|
436
|
+
clearTimeout(timeout);
|
|
437
|
+
if (code === 0) {
|
|
438
|
+
resolve2();
|
|
439
|
+
} else {
|
|
440
|
+
reject(new Error(`Pandoc failed with code ${code}: ${stderr}`));
|
|
441
|
+
}
|
|
442
|
+
});
|
|
443
|
+
pandoc.on("error", (error) => {
|
|
444
|
+
clearTimeout(timeout);
|
|
445
|
+
reject(new Error(`Failed to execute Pandoc: ${error.message}`));
|
|
446
|
+
});
|
|
447
|
+
});
|
|
448
|
+
}
|
|
449
|
+
function estimatePageCount(buffer) {
|
|
450
|
+
const content = buffer.toString("binary");
|
|
451
|
+
const matches = content.match(/\/Type\s*\/Page[^s]/g);
|
|
452
|
+
return matches ? matches.length : 1;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
// src/presets.ts
|
|
456
|
+
async function generateMemo(content, metadata, options) {
|
|
457
|
+
return generatePDF({
|
|
458
|
+
content,
|
|
459
|
+
metadata,
|
|
460
|
+
template: "memo",
|
|
461
|
+
toc: false,
|
|
462
|
+
numberSections: true,
|
|
463
|
+
fontSize: 11,
|
|
464
|
+
margin: "1in",
|
|
465
|
+
...options
|
|
466
|
+
});
|
|
467
|
+
}
|
|
468
|
+
async function generateAgreement(content, metadata, options) {
|
|
469
|
+
return generatePDF({
|
|
470
|
+
content,
|
|
471
|
+
metadata,
|
|
472
|
+
template: "agreement",
|
|
473
|
+
toc: false,
|
|
474
|
+
numberSections: true,
|
|
475
|
+
fontSize: 10,
|
|
476
|
+
margin: "1in",
|
|
477
|
+
...options
|
|
478
|
+
});
|
|
479
|
+
}
|
|
480
|
+
async function generateTermsheet(content, metadata, options) {
|
|
481
|
+
return generatePDF({
|
|
482
|
+
content,
|
|
483
|
+
metadata,
|
|
484
|
+
template: "termsheet",
|
|
485
|
+
toc: false,
|
|
486
|
+
numberSections: true,
|
|
487
|
+
fontSize: 10,
|
|
488
|
+
margin: "1in",
|
|
489
|
+
...options
|
|
490
|
+
});
|
|
491
|
+
}
|
|
492
|
+
async function generateWhitepaper(content, metadata, options) {
|
|
493
|
+
return generatePDF({
|
|
494
|
+
content,
|
|
495
|
+
metadata,
|
|
496
|
+
template: "whitepaper",
|
|
497
|
+
toc: true,
|
|
498
|
+
tocDepth: 2,
|
|
499
|
+
numberSections: true,
|
|
500
|
+
fontSize: 11,
|
|
501
|
+
margin: "1.2in",
|
|
502
|
+
...options
|
|
503
|
+
});
|
|
504
|
+
}
|
|
505
|
+
async function generateReport(content, metadata, options) {
|
|
506
|
+
return generatePDF({
|
|
507
|
+
content,
|
|
508
|
+
metadata,
|
|
509
|
+
template: "default",
|
|
510
|
+
toc: true,
|
|
511
|
+
tocDepth: 2,
|
|
512
|
+
numberSections: true,
|
|
513
|
+
fontSize: 11,
|
|
514
|
+
margin: "1in",
|
|
515
|
+
...options
|
|
516
|
+
});
|
|
517
|
+
}
|
|
518
|
+
async function generateProposal(content, metadata, options) {
|
|
519
|
+
return generatePDF({
|
|
520
|
+
content,
|
|
521
|
+
metadata,
|
|
522
|
+
template: "default",
|
|
523
|
+
toc: false,
|
|
524
|
+
numberSections: true,
|
|
525
|
+
fontSize: 11,
|
|
526
|
+
margin: "1in",
|
|
527
|
+
...options
|
|
528
|
+
});
|
|
529
|
+
}
|
|
530
|
+
async function generateCapitalIntroAgreement(content, metadata, options) {
|
|
531
|
+
return generatePDF({
|
|
532
|
+
content,
|
|
533
|
+
metadata,
|
|
534
|
+
template: "agreement",
|
|
535
|
+
toc: false,
|
|
536
|
+
numberSections: true,
|
|
537
|
+
fontSize: 10,
|
|
538
|
+
margin: "1in",
|
|
539
|
+
...options
|
|
540
|
+
});
|
|
541
|
+
}
|
|
542
|
+
async function generateSAFE(content, metadata, options) {
|
|
543
|
+
return generatePDF({
|
|
544
|
+
content,
|
|
545
|
+
metadata,
|
|
546
|
+
template: "agreement",
|
|
547
|
+
toc: false,
|
|
548
|
+
numberSections: true,
|
|
549
|
+
fontSize: 10,
|
|
550
|
+
margin: "1in",
|
|
551
|
+
...options
|
|
552
|
+
});
|
|
553
|
+
}
|
|
554
|
+
async function generateNDA(content, metadata, options) {
|
|
555
|
+
return generatePDF({
|
|
556
|
+
content,
|
|
557
|
+
metadata,
|
|
558
|
+
template: "agreement",
|
|
559
|
+
toc: false,
|
|
560
|
+
numberSections: true,
|
|
561
|
+
fontSize: 10,
|
|
562
|
+
margin: "1in",
|
|
563
|
+
...options
|
|
564
|
+
});
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
export {
|
|
568
|
+
getTemplate,
|
|
569
|
+
getTemplatePath,
|
|
570
|
+
listTemplates,
|
|
571
|
+
getTemplateConfig,
|
|
572
|
+
registerTemplate,
|
|
573
|
+
unregisterTemplate,
|
|
574
|
+
hasTemplate,
|
|
575
|
+
getTemplatesForDocType,
|
|
576
|
+
clearTemplateCache,
|
|
577
|
+
getTemplatesDirectory,
|
|
578
|
+
checkPandoc,
|
|
579
|
+
checkLaTeX,
|
|
580
|
+
checkSystem,
|
|
581
|
+
sanitizeContent,
|
|
582
|
+
parseColor,
|
|
583
|
+
formatFileSize,
|
|
584
|
+
generatePDF,
|
|
585
|
+
generateMemo,
|
|
586
|
+
generateAgreement,
|
|
587
|
+
generateTermsheet,
|
|
588
|
+
generateWhitepaper,
|
|
589
|
+
generateReport,
|
|
590
|
+
generateProposal,
|
|
591
|
+
generateCapitalIntroAgreement,
|
|
592
|
+
generateSAFE,
|
|
593
|
+
generateNDA
|
|
594
|
+
};
|
package/dist/cli.js
CHANGED
|
@@ -476,12 +476,12 @@ async function generateWhitepaper(content, metadata, options) {
|
|
|
476
476
|
return generatePDF({
|
|
477
477
|
content,
|
|
478
478
|
metadata,
|
|
479
|
-
template: "
|
|
479
|
+
template: "whitepaper",
|
|
480
480
|
toc: true,
|
|
481
481
|
tocDepth: 2,
|
|
482
482
|
numberSections: true,
|
|
483
483
|
fontSize: 11,
|
|
484
|
-
margin: "
|
|
484
|
+
margin: "1.2in",
|
|
485
485
|
...options
|
|
486
486
|
});
|
|
487
487
|
}
|
package/dist/cli.mjs
CHANGED
package/dist/index.js
CHANGED
|
@@ -554,12 +554,12 @@ async function generateWhitepaper(content, metadata, options) {
|
|
|
554
554
|
return generatePDF({
|
|
555
555
|
content,
|
|
556
556
|
metadata,
|
|
557
|
-
template: "
|
|
557
|
+
template: "whitepaper",
|
|
558
558
|
toc: true,
|
|
559
559
|
tocDepth: 2,
|
|
560
560
|
numberSections: true,
|
|
561
561
|
fontSize: 11,
|
|
562
|
-
margin: "
|
|
562
|
+
margin: "1.2in",
|
|
563
563
|
...options
|
|
564
564
|
});
|
|
565
565
|
}
|
package/dist/index.mjs
CHANGED