@speajus/markdown-to-pdf 1.0.2 → 1.0.3

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/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Basic-Markdown-To-PDF
2
2
 
3
- A lightweight TypeScript library that converts Markdown files into styled PDF documents. Built on [marked](https://github.com/markedjs/marked) for parsing and [PDFKit](https://pdfkit.org/) for PDF generation.
3
+ A lightweight TypeScript library that converts Markdown files into styled PDF documents. Built on [marked](https://github.com/markedjs/marked) for parsing and [PDFKit](https://pdfkit.org/) for PDF generation. [README.pdf](./README.pdf)
4
4
 
5
5
  ## Features
6
6
 
package/README.pdf ADDED
Binary file
Binary file
package/package.json CHANGED
@@ -1,16 +1,26 @@
1
1
  {
2
2
  "name": "@speajus/markdown-to-pdf",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "description": "A new project created with Intent by Augment.",
5
5
  "main": "dist/src/index.js",
6
6
  "types": "dist/src/index.d.ts",
7
+ "exports": {
8
+ "node": {
9
+ "require": "./dist/src/index.js",
10
+ "import": "./dist/src/index.js"
11
+ },
12
+ "browser": {
13
+ "require": "./dist/src/browser.js",
14
+ "import": "./dist/src/browser.js"
15
+ }
16
+ },
7
17
  "files": [
8
18
  "dist/src"
9
19
  ],
10
20
  "scripts": {
11
- "build": "tsc",
12
- "generate": "ts-node samples/generate.ts",
13
- "test": "echo \"Error: no test specified\" && exit 1"
21
+ "build": "tsc && mkdir -p dist/src/fonts && cp src/fonts/* dist/src/fonts/",
22
+ "generate": "tsx samples/generate.ts",
23
+ "test": "tsx samples/generate.ts"
14
24
  },
15
25
  "keywords": [
16
26
  "markdown",
@@ -27,12 +37,21 @@
27
37
  "dependencies": {
28
38
  "@resvg/resvg-js": "^2.6.2",
29
39
  "marked": "^17.0.2",
30
- "pdfkit": "^0.17.2"
40
+ "pdfkit": "^0.17.2",
41
+ "prismjs": "^1.30.0"
31
42
  },
32
43
  "devDependencies": {
33
44
  "@types/node": "^25.2.3",
34
45
  "@types/pdfkit": "^0.17.5",
35
- "ts-node": "^10.9.2",
46
+ "@types/prismjs": "^1.26.6",
47
+ "canvas": "^3.2.1",
48
+ "pdfjs-dist": "^3.11.174",
49
+ "tsx": "^4.21.0",
36
50
  "typescript": "^5.9.3"
51
+ },
52
+ "pnpm": {
53
+ "overrides": {
54
+ "canvas": "^3.2.1"
55
+ }
37
56
  }
38
57
  }
package/dist/src/cli.d.ts DELETED
@@ -1,2 +0,0 @@
1
- #!/usr/bin/env ts-node
2
- export {};
package/dist/src/cli.js DELETED
@@ -1,24 +0,0 @@
1
- #!/usr/bin/env ts-node
2
- "use strict";
3
- var __importDefault = (this && this.__importDefault) || function (mod) {
4
- return (mod && mod.__esModule) ? mod : { "default": mod };
5
- };
6
- Object.defineProperty(exports, "__esModule", { value: true });
7
- const path_1 = __importDefault(require("path"));
8
- const index_js_1 = require("./index.js");
9
- async function main() {
10
- const args = process.argv.slice(2);
11
- if (args.length === 0) {
12
- console.error('Usage: ts-node src/cli.ts <input.md> [output.pdf]');
13
- process.exit(1);
14
- }
15
- const inputPath = args[0];
16
- const outputPath = args[1] ?? inputPath.replace(/\.md$/i, '.pdf');
17
- console.log(`Converting ${inputPath} → ${outputPath}`);
18
- await (0, index_js_1.generatePdf)(inputPath, outputPath);
19
- console.log(`Done. PDF written to ${path_1.default.resolve(outputPath)}`);
20
- }
21
- main().catch((err) => {
22
- console.error('Error:', err);
23
- process.exit(1);
24
- });
@@ -1,5 +0,0 @@
1
- export type { TextStyle, PageLayout, CodeStyle, CodeBlockStyle, BlockquoteStyle, TableStyles, ThemeConfig, PdfOptions, } from './types.js';
2
- export { renderMarkdownToPdf } from './renderer.js';
3
- export { defaultTheme, defaultPageLayout } from './styles.js';
4
- import type { PdfOptions } from './types.js';
5
- export declare function generatePdf(inputPath: string, outputPath: string, options?: PdfOptions): Promise<void>;
package/dist/src/index.js DELETED
@@ -1,26 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.defaultPageLayout = exports.defaultTheme = exports.renderMarkdownToPdf = void 0;
7
- exports.generatePdf = generatePdf;
8
- var renderer_js_1 = require("./renderer.js");
9
- Object.defineProperty(exports, "renderMarkdownToPdf", { enumerable: true, get: function () { return renderer_js_1.renderMarkdownToPdf; } });
10
- var styles_js_1 = require("./styles.js");
11
- Object.defineProperty(exports, "defaultTheme", { enumerable: true, get: function () { return styles_js_1.defaultTheme; } });
12
- Object.defineProperty(exports, "defaultPageLayout", { enumerable: true, get: function () { return styles_js_1.defaultPageLayout; } });
13
- const fs_1 = __importDefault(require("fs"));
14
- const path_1 = __importDefault(require("path"));
15
- const renderer_js_2 = require("./renderer.js");
16
- async function generatePdf(inputPath, outputPath, options) {
17
- const resolvedInput = path_1.default.resolve(inputPath);
18
- const markdown = fs_1.default.readFileSync(resolvedInput, 'utf-8');
19
- const basePath = path_1.default.dirname(resolvedInput);
20
- const mergedOptions = { ...options, basePath: options?.basePath ?? basePath };
21
- const buffer = await (0, renderer_js_2.renderMarkdownToPdf)(markdown, mergedOptions);
22
- const dir = path_1.default.dirname(path_1.default.resolve(outputPath));
23
- if (!fs_1.default.existsSync(dir))
24
- fs_1.default.mkdirSync(dir, { recursive: true });
25
- fs_1.default.writeFileSync(path_1.default.resolve(outputPath), buffer);
26
- }
@@ -1,2 +0,0 @@
1
- import type { PdfOptions } from './types.js';
2
- export declare function renderMarkdownToPdf(markdown: string, options?: PdfOptions): Promise<Buffer>;
@@ -1,423 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.renderMarkdownToPdf = renderMarkdownToPdf;
7
- const styles_js_1 = require("./styles.js");
8
- const pdfkit_1 = __importDefault(require("pdfkit"));
9
- const marked_1 = require("marked");
10
- const resvg_js_1 = require("@resvg/resvg-js");
11
- const stream_1 = require("stream");
12
- const https_1 = __importDefault(require("https"));
13
- const http_1 = __importDefault(require("http"));
14
- const fs_1 = __importDefault(require("fs"));
15
- const path_1 = __importDefault(require("path"));
16
- function isSvg(buf) {
17
- // Check for XML/SVG signature in the first 256 bytes
18
- const head = buf.subarray(0, 256).toString('utf-8').trimStart();
19
- return head.startsWith('<svg') || head.startsWith('<?xml');
20
- }
21
- function convertSvgToPng(svgData) {
22
- const resvg = new resvg_js_1.Resvg(svgData, { font: { loadSystemFonts: true } });
23
- const rendered = resvg.render();
24
- return Buffer.from(rendered.asPng());
25
- }
26
- const FETCH_TIMEOUT_MS = 10000;
27
- const MAX_REDIRECTS = 5;
28
- function fetchImageBuffer(url, redirectCount = 0) {
29
- if (redirectCount > MAX_REDIRECTS) {
30
- return Promise.reject(new Error(`Too many redirects fetching ${url}`));
31
- }
32
- return new Promise((resolve, reject) => {
33
- const get = url.startsWith('https') ? https_1.default.get : http_1.default.get;
34
- const req = get(url, (res) => {
35
- if (res.statusCode && res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
36
- res.resume(); // drain the response so the socket can be reused / freed
37
- fetchImageBuffer(res.headers.location, redirectCount + 1).then(resolve, reject);
38
- return;
39
- }
40
- if (!res.statusCode || res.statusCode < 200 || res.statusCode >= 300) {
41
- res.resume();
42
- reject(new Error(`HTTP ${res.statusCode} fetching ${url}`));
43
- return;
44
- }
45
- const chunks = [];
46
- res.on('data', (chunk) => chunks.push(chunk));
47
- res.on('end', () => resolve(Buffer.concat(chunks)));
48
- res.on('error', reject);
49
- });
50
- req.on('error', reject);
51
- req.setTimeout(FETCH_TIMEOUT_MS, () => {
52
- req.destroy(new Error(`Timeout fetching ${url} after ${FETCH_TIMEOUT_MS}ms`));
53
- });
54
- });
55
- }
56
- async function renderMarkdownToPdf(markdown, options) {
57
- const theme = options?.theme ?? styles_js_1.defaultTheme;
58
- const layout = options?.pageLayout ?? styles_js_1.defaultPageLayout;
59
- const basePath = options?.basePath ?? process.cwd();
60
- const { margins } = layout;
61
- const doc = new pdfkit_1.default({ size: layout.pageSize, margins });
62
- const stream = new stream_1.PassThrough();
63
- const chunks = [];
64
- doc.pipe(stream);
65
- stream.on('data', (chunk) => chunks.push(chunk));
66
- const tokens = marked_1.marked.lexer(markdown);
67
- const contentWidth = doc.page.width - margins.left - margins.right;
68
- function ensureSpace(needed) {
69
- if (doc.y + needed > doc.page.height - margins.bottom) {
70
- doc.addPage();
71
- }
72
- }
73
- function applyBodyFont(bold, italic) {
74
- let font = theme.body.font;
75
- if (bold && italic)
76
- font = 'Helvetica-BoldOblique';
77
- else if (bold)
78
- font = 'Helvetica-Bold';
79
- else if (italic)
80
- font = 'Helvetica-Oblique';
81
- doc.font(font).fontSize(theme.body.fontSize).fillColor(theme.body.color);
82
- }
83
- function resetBodyFont() {
84
- doc.font(theme.body.font).fontSize(theme.body.fontSize).fillColor(theme.body.color);
85
- }
86
- function renderCodespan(text, continued) {
87
- const cs = theme.code.inline;
88
- doc.font(cs.font).fontSize(cs.fontSize);
89
- const textW = doc.widthOfString(text);
90
- const textH = doc.currentLineHeight();
91
- const bgX = doc.x;
92
- const bgY = doc.y;
93
- doc.save();
94
- doc.rect(bgX, bgY, textW + 4, textH + 2).fill(cs.backgroundColor);
95
- doc.restore();
96
- doc.font(cs.font).fontSize(cs.fontSize).fillColor(cs.color);
97
- doc.text(text, bgX + 2, bgY + 1, { continued });
98
- resetBodyFont();
99
- }
100
- function renderLink(tok, continued) {
101
- doc.font(theme.body.font).fontSize(theme.body.fontSize).fillColor(theme.linkColor);
102
- const linkText = tok.text || tok.href;
103
- doc.text(linkText, { continued, underline: true, link: tok.href });
104
- doc.fillColor(theme.body.color);
105
- }
106
- async function renderInlineTokens(inlineTokens, continued, insideBold = false, insideItalic = false) {
107
- for (let i = 0; i < inlineTokens.length; i++) {
108
- const isLast = i === inlineTokens.length - 1;
109
- const cont = continued || !isLast;
110
- const tok = inlineTokens[i];
111
- switch (tok.type) {
112
- case 'text': {
113
- const t = tok;
114
- if (t.tokens && t.tokens.length > 0) {
115
- await renderInlineTokens(t.tokens, cont, insideBold, insideItalic);
116
- }
117
- else {
118
- applyBodyFont(insideBold, insideItalic);
119
- doc.text(t.text, { continued: cont });
120
- }
121
- break;
122
- }
123
- case 'strong': {
124
- const t = tok;
125
- await renderInlineTokens(t.tokens, cont, true, insideItalic);
126
- break;
127
- }
128
- case 'em': {
129
- const t = tok;
130
- await renderInlineTokens(t.tokens, cont, insideBold, true);
131
- break;
132
- }
133
- case 'codespan': {
134
- renderCodespan(tok.text, cont);
135
- break;
136
- }
137
- case 'link': {
138
- renderLink(tok, cont);
139
- break;
140
- }
141
- case 'image': {
142
- await renderImage(tok);
143
- break;
144
- }
145
- case 'del': {
146
- applyBodyFont(insideBold, insideItalic);
147
- doc.text(tok.text, { continued: cont, strike: true });
148
- break;
149
- }
150
- case 'escape': {
151
- applyBodyFont(insideBold, insideItalic);
152
- doc.text(tok.text, { continued: cont });
153
- break;
154
- }
155
- case 'br': {
156
- doc.moveDown(0.5);
157
- break;
158
- }
159
- default: {
160
- const raw = tok.text ?? tok.raw ?? '';
161
- if (raw) {
162
- applyBodyFont(insideBold, insideItalic);
163
- doc.text(raw, { continued: cont });
164
- }
165
- break;
166
- }
167
- }
168
- }
169
- }
170
- async function renderImage(tok) {
171
- try {
172
- let imgBuffer;
173
- if (tok.href.startsWith('http://') || tok.href.startsWith('https://')) {
174
- imgBuffer = await fetchImageBuffer(tok.href);
175
- }
176
- else {
177
- // Local file path — resolve relative to the markdown file's directory
178
- const imgPath = path_1.default.resolve(basePath, tok.href);
179
- imgBuffer = fs_1.default.readFileSync(imgPath);
180
- }
181
- // Convert SVG to PNG since pdfkit doesn't support SVG natively
182
- if (isSvg(imgBuffer)) {
183
- imgBuffer = convertSvgToPng(imgBuffer);
184
- }
185
- // Read the image's intrinsic dimensions via pdfkit
186
- // openImage exists at runtime but is missing from @types/pdfkit
187
- const img = doc.openImage(imgBuffer);
188
- const maxHeight = doc.page.height - margins.top - margins.bottom;
189
- // Scale down to fit content area, but never scale up beyond natural size
190
- let displayWidth = Math.min(img.width, contentWidth);
191
- let displayHeight = img.height * (displayWidth / img.width);
192
- // Also cap height to the printable area
193
- if (displayHeight > maxHeight) {
194
- displayHeight = maxHeight;
195
- displayWidth = img.width * (displayHeight / img.height);
196
- }
197
- ensureSpace(displayHeight + 10);
198
- doc.image(imgBuffer, { width: displayWidth, height: displayHeight });
199
- doc.moveDown(0.5);
200
- }
201
- catch {
202
- ensureSpace(20);
203
- resetBodyFont();
204
- doc.text(`[Image: ${tok.text || 'image'}]`);
205
- doc.moveDown(0.3);
206
- }
207
- }
208
- async function renderList(list, depth) {
209
- const indent = margins.left + depth * 20;
210
- for (let idx = 0; idx < list.items.length; idx++) {
211
- const item = list.items[idx];
212
- ensureSpace(theme.body.fontSize * 2);
213
- resetBodyFont();
214
- const bullet = list.ordered ? `${list.start + idx}.` : '•';
215
- doc.text(bullet, indent, doc.y, { continued: true, width: contentWidth - depth * 20 });
216
- doc.text(' ', { continued: true });
217
- // Render item inline tokens
218
- const itemTokens = item.tokens;
219
- for (const child of itemTokens) {
220
- if (child.type === 'text') {
221
- const t = child;
222
- if (t.tokens && t.tokens.length > 0) {
223
- await renderInlineTokens(t.tokens, false);
224
- }
225
- else {
226
- doc.text(t.text);
227
- }
228
- }
229
- else if (child.type === 'paragraph') {
230
- await renderInlineTokens(child.tokens, false);
231
- }
232
- else if (child.type === 'list') {
233
- await renderList(child, depth + 1);
234
- }
235
- }
236
- doc.moveDown(0.2);
237
- }
238
- }
239
- async function renderTable(table) {
240
- const colCount = table.header.length;
241
- if (colCount === 0)
242
- return;
243
- const cellPad = theme.table.cellPadding;
244
- const colWidth = contentWidth / colCount;
245
- const rowH = theme.body.fontSize + cellPad * 2 + 4;
246
- const textInsetY = (rowH - theme.body.fontSize) / 2;
247
- ensureSpace(rowH * 2);
248
- const startX = margins.left;
249
- let y = doc.y;
250
- // Header row
251
- doc.save();
252
- doc.rect(startX, y, contentWidth, rowH).fill(theme.table.headerBackground);
253
- doc.restore();
254
- doc.font('Helvetica-Bold').fontSize(theme.body.fontSize).fillColor(theme.body.color);
255
- for (let c = 0; c < colCount; c++) {
256
- const cellX = startX + c * colWidth;
257
- doc.text(table.header[c].text, cellX + cellPad, y + textInsetY, {
258
- width: colWidth - cellPad * 2,
259
- height: rowH,
260
- align: table.align[c] || 'left',
261
- });
262
- }
263
- // Header border
264
- doc.save();
265
- doc.strokeColor(theme.table.borderColor).lineWidth(0.5);
266
- doc.rect(startX, y, contentWidth, rowH).stroke();
267
- for (let c = 1; c < colCount; c++) {
268
- const cx = startX + c * colWidth;
269
- doc.moveTo(cx, y).lineTo(cx, y + rowH).stroke();
270
- }
271
- doc.restore();
272
- y += rowH;
273
- // Body rows
274
- resetBodyFont();
275
- for (const row of table.rows) {
276
- ensureSpace(rowH);
277
- for (let c = 0; c < colCount; c++) {
278
- const cellX = startX + c * colWidth;
279
- doc.text(row[c].text, cellX + cellPad, y + textInsetY, {
280
- width: colWidth - cellPad * 2,
281
- height: rowH,
282
- align: table.align[c] || 'left',
283
- });
284
- }
285
- doc.save();
286
- doc.strokeColor(theme.table.borderColor).lineWidth(0.5);
287
- doc.rect(startX, y, contentWidth, rowH).stroke();
288
- for (let c = 1; c < colCount; c++) {
289
- const cx = startX + c * colWidth;
290
- doc.moveTo(cx, y).lineTo(cx, y + rowH).stroke();
291
- }
292
- doc.restore();
293
- y += rowH;
294
- }
295
- doc.x = margins.left;
296
- doc.y = y;
297
- doc.moveDown(0.5);
298
- resetBodyFont();
299
- }
300
- async function renderToken(token) {
301
- switch (token.type) {
302
- case 'heading': {
303
- const t = token;
304
- const key = `h${t.depth}`;
305
- const style = theme.headings[key];
306
- const spaceAbove = style.fontSize * 0.8;
307
- const spaceBelow = style.fontSize * 0.3;
308
- ensureSpace(spaceAbove + style.fontSize + spaceBelow);
309
- doc.moveDown(spaceAbove / doc.currentLineHeight());
310
- doc.font(style.font).fontSize(style.fontSize).fillColor(style.color);
311
- doc.text(t.text);
312
- doc.moveDown(spaceBelow / doc.currentLineHeight());
313
- resetBodyFont();
314
- break;
315
- }
316
- case 'paragraph': {
317
- const t = token;
318
- ensureSpace(theme.body.fontSize * 2);
319
- resetBodyFont();
320
- await renderInlineTokens(t.tokens, false);
321
- doc.moveDown(0.5);
322
- break;
323
- }
324
- case 'code': {
325
- const t = token;
326
- const cs = theme.code.block;
327
- const lines = t.text.split('\n');
328
- const lineH = cs.fontSize * 1.4;
329
- const blockH = lines.length * lineH + cs.padding * 2;
330
- ensureSpace(blockH + 10);
331
- const x = margins.left;
332
- const y = doc.y;
333
- doc.save();
334
- doc.rect(x, y, contentWidth, blockH).fill(cs.backgroundColor);
335
- doc.restore();
336
- doc.font(cs.font).fontSize(cs.fontSize).fillColor(cs.color);
337
- let textY = y + cs.padding;
338
- for (const line of lines) {
339
- doc.text(line, x + cs.padding, textY, { width: contentWidth - cs.padding * 2 });
340
- textY += lineH;
341
- }
342
- doc.x = margins.left;
343
- doc.y = y + blockH;
344
- doc.moveDown(0.5);
345
- resetBodyFont();
346
- break;
347
- }
348
- case 'blockquote': {
349
- const t = token;
350
- const bq = theme.blockquote;
351
- ensureSpace(30);
352
- const bqPadding = 6; // vertical padding above and below text
353
- const startY = doc.y;
354
- doc.y += bqPadding; // add top padding before text
355
- const textX = margins.left + bq.borderWidth + bq.indent;
356
- const textWidth = contentWidth - bq.borderWidth - bq.indent;
357
- for (const child of t.tokens) {
358
- if (child.type === 'paragraph') {
359
- const p = child;
360
- const font = bq.italic ? 'Helvetica-Oblique' : theme.body.font;
361
- doc.font(font).fontSize(theme.body.fontSize).fillColor(theme.body.color);
362
- doc.text('', textX, doc.y, { width: textWidth });
363
- await renderInlineTokens(p.tokens, false, false, bq.italic);
364
- doc.moveDown(0.3);
365
- }
366
- else {
367
- await renderToken(child);
368
- }
369
- }
370
- doc.y += bqPadding; // add bottom padding after text
371
- const endY = doc.y;
372
- doc.save();
373
- doc.rect(margins.left, startY, bq.borderWidth, endY - startY).fill(bq.borderColor);
374
- doc.restore();
375
- doc.x = margins.left;
376
- doc.moveDown(0.3);
377
- resetBodyFont();
378
- break;
379
- }
380
- case 'list': {
381
- await renderList(token, 0);
382
- doc.moveDown(0.3);
383
- break;
384
- }
385
- case 'hr': {
386
- ensureSpace(20);
387
- doc.moveDown(0.5);
388
- const y = doc.y;
389
- doc.save();
390
- doc.strokeColor(theme.horizontalRuleColor).lineWidth(1)
391
- .moveTo(margins.left, y)
392
- .lineTo(margins.left + contentWidth, y)
393
- .stroke();
394
- doc.restore();
395
- doc.y = y;
396
- doc.moveDown(0.5);
397
- resetBodyFont();
398
- break;
399
- }
400
- case 'table': {
401
- await renderTable(token);
402
- break;
403
- }
404
- case 'image': {
405
- await renderImage(token);
406
- break;
407
- }
408
- case 'space':
409
- case 'html':
410
- break;
411
- default:
412
- break;
413
- }
414
- }
415
- // ── Main loop ─────────────────────────────────────────────────────────────
416
- for (const token of tokens) {
417
- await renderToken(token);
418
- }
419
- doc.end();
420
- return new Promise((resolve) => {
421
- stream.on('end', () => resolve(Buffer.concat(chunks)));
422
- });
423
- }
@@ -1,3 +0,0 @@
1
- import type { ThemeConfig, PageLayout } from './types.js';
2
- export declare const defaultTheme: ThemeConfig;
3
- export declare const defaultPageLayout: PageLayout;
@@ -1,56 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.defaultPageLayout = exports.defaultTheme = void 0;
4
- exports.defaultTheme = {
5
- headings: {
6
- h1: { font: 'Helvetica-Bold', fontSize: 28, color: '#1a1a1a', bold: true },
7
- h2: { font: 'Helvetica-Bold', fontSize: 22, color: '#2a2a2a', bold: true },
8
- h3: { font: 'Helvetica-Bold', fontSize: 18, color: '#3a3a3a', bold: true },
9
- h4: { font: 'Helvetica-Bold', fontSize: 16, color: '#4a4a4a', bold: true },
10
- h5: { font: 'Helvetica-Bold', fontSize: 14, color: '#5a5a5a', bold: true },
11
- h6: { font: 'Helvetica-Bold', fontSize: 12, color: '#6a6a6a', bold: true },
12
- },
13
- body: {
14
- font: 'Helvetica',
15
- fontSize: 11,
16
- color: '#333333',
17
- lineGap: 4,
18
- },
19
- code: {
20
- inline: {
21
- font: 'Courier',
22
- fontSize: 10,
23
- color: '#c7254e',
24
- backgroundColor: '#f9f2f4',
25
- },
26
- block: {
27
- font: 'Courier',
28
- fontSize: 9,
29
- color: '#333333',
30
- backgroundColor: '#f5f5f5',
31
- padding: 8,
32
- },
33
- },
34
- blockquote: {
35
- borderColor: '#3498db',
36
- borderWidth: 3,
37
- italic: true,
38
- indent: 20,
39
- },
40
- linkColor: '#2980b9',
41
- horizontalRuleColor: '#cccccc',
42
- table: {
43
- headerBackground: '#f0f0f0',
44
- borderColor: '#cccccc',
45
- cellPadding: 6,
46
- },
47
- };
48
- exports.defaultPageLayout = {
49
- pageSize: 'LETTER',
50
- margins: {
51
- top: 50,
52
- right: 50,
53
- bottom: 50,
54
- left: 50,
55
- },
56
- };
@@ -1,62 +0,0 @@
1
- export interface TextStyle {
2
- font: string;
3
- fontSize: number;
4
- color: string;
5
- lineGap?: number;
6
- bold?: boolean;
7
- italic?: boolean;
8
- }
9
- export interface PageLayout {
10
- pageSize: string;
11
- margins: {
12
- top: number;
13
- right: number;
14
- bottom: number;
15
- left: number;
16
- };
17
- }
18
- export interface CodeStyle {
19
- font: string;
20
- fontSize: number;
21
- color: string;
22
- backgroundColor: string;
23
- }
24
- export interface CodeBlockStyle extends CodeStyle {
25
- padding: number;
26
- }
27
- export interface BlockquoteStyle {
28
- borderColor: string;
29
- borderWidth: number;
30
- italic: boolean;
31
- indent: number;
32
- }
33
- export interface TableStyles {
34
- headerBackground: string;
35
- borderColor: string;
36
- cellPadding: number;
37
- }
38
- export interface ThemeConfig {
39
- headings: {
40
- h1: TextStyle;
41
- h2: TextStyle;
42
- h3: TextStyle;
43
- h4: TextStyle;
44
- h5: TextStyle;
45
- h6: TextStyle;
46
- };
47
- body: TextStyle;
48
- code: {
49
- inline: CodeStyle;
50
- block: CodeBlockStyle;
51
- };
52
- blockquote: BlockquoteStyle;
53
- linkColor: string;
54
- horizontalRuleColor: string;
55
- table: TableStyles;
56
- }
57
- export interface PdfOptions {
58
- theme?: ThemeConfig;
59
- pageLayout?: PageLayout;
60
- /** Base directory for resolving relative image paths */
61
- basePath?: string;
62
- }
package/dist/src/types.js DELETED
@@ -1,2 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });