@speajus/markdown-to-pdf 1.0.8 → 1.0.10

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,8 @@
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. [README.pdf](./README.pdf)
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) | [Live Demo](https://speajus.github.io/markdown-to-pdf/)
4
+
5
+ [![Live Demo](./docs/image.png)](https://speajus.github.io/markdown-to-pdf/)
4
6
 
5
7
  ## Features
6
8
 
@@ -83,6 +85,9 @@ interface PdfOptions {
83
85
  theme?: ThemeConfig; // Typography, colors, and component styles
84
86
  pageLayout?: PageLayout; // Page size and margins
85
87
  basePath?: string; // Base directory for resolving relative image paths
88
+ syntaxHighlight?: boolean; // Enable syntax highlighting (default: true)
89
+ lineNumbers?: boolean; // Show line numbers in code blocks (default: false)
90
+ languages?: string[]; // Prism.js languages to load (default: all)
86
91
  }
87
92
  ```
88
93
 
package/README.pdf CHANGED
Binary file
package/dist/cli.js CHANGED
@@ -20,7 +20,7 @@ async function readMdWritePdf(inputPath, outputPath, extraOptions) {
20
20
  if (!fs_1.default.existsSync(dir))
21
21
  fs_1.default.mkdirSync(dir, { recursive: true });
22
22
  fs_1.default.writeFileSync(path_1.default.resolve(outputPath), buffer);
23
- console.log(`Done. PDF written to ${path_1.default.resolve(outputPath)}`);
23
+ console.log(`PDF written to ${path_1.default.resolve(outputPath)}`);
24
24
  }
25
25
  async function main() {
26
26
  const args = process.argv.slice(2);
package/dist/renderer.js CHANGED
@@ -22,6 +22,7 @@ async function renderMarkdownToPdf(markdown, options) {
22
22
  if (syntaxHighlight) {
23
23
  (0, highlight_prism_js_1.loadHighlightLanguages)(options?.languages);
24
24
  }
25
+ const lineNumbers = options?.lineNumbers ?? false;
25
26
  const emojiFontOpt = options?.emojiFont ?? true;
26
27
  // Use provided image renderer or create default Node.js renderer
27
28
  const imageRenderer = options?.renderImage ?? defaults_js_1.DEFAULTS.renderImage(basePath);
@@ -360,6 +361,11 @@ async function renderMarkdownToPdf(markdown, options) {
360
361
  resetBodyFont();
361
362
  }
362
363
  function renderLink(tok, continued) {
364
+ // If the link wraps an image, render a clickable image instead of text
365
+ const imgChild = tok.tokens?.find((t) => t.type === 'image');
366
+ if (imgChild) {
367
+ return renderImage(imgChild, tok.href);
368
+ }
363
369
  if (headingCtx) {
364
370
  doc.font(headingCtx.font).fontSize(headingCtx.fontSize).fillColor(theme.linkColor);
365
371
  }
@@ -402,7 +408,7 @@ async function renderMarkdownToPdf(markdown, options) {
402
408
  break;
403
409
  }
404
410
  case 'link': {
405
- renderLink(tok, cont);
411
+ await renderLink(tok, cont);
406
412
  break;
407
413
  }
408
414
  case 'image': {
@@ -434,7 +440,7 @@ async function renderMarkdownToPdf(markdown, options) {
434
440
  }
435
441
  }
436
442
  }
437
- async function renderImage(tok) {
443
+ async function renderImage(tok, linkUrl) {
438
444
  try {
439
445
  // Use the pluggable image renderer
440
446
  const imgBuffer = await imageRenderer(tok.href);
@@ -451,7 +457,13 @@ async function renderMarkdownToPdf(markdown, options) {
451
457
  displayWidth = img.width * (displayHeight / img.height);
452
458
  }
453
459
  ensureSpace(displayHeight + 10);
460
+ const imgX = doc.x;
461
+ const imgY = doc.y;
454
462
  doc.image(imgBuffer, { width: displayWidth, height: displayHeight });
463
+ // If the image is wrapped in a link, overlay a clickable annotation
464
+ if (linkUrl) {
465
+ doc.link(imgX, imgY, displayWidth, displayHeight, linkUrl);
466
+ }
455
467
  doc.moveDown(0.5);
456
468
  }
457
469
  catch {
@@ -607,7 +619,7 @@ async function renderMarkdownToPdf(markdown, options) {
607
619
  fontSize: cs.fontSize,
608
620
  lineHeight: 1.5,
609
621
  padding: cs.padding,
610
- lineNumbers: true,
622
+ lineNumbers,
611
623
  drawBackground: true,
612
624
  theme: theme.syntaxHighlight,
613
625
  });
package/dist/types.d.ts CHANGED
@@ -98,6 +98,15 @@ export interface PdfOptions {
98
98
  * Has no effect when `syntaxHighlight` is `false`.
99
99
  */
100
100
  languages?: string[];
101
+ /**
102
+ * Show line numbers in fenced code blocks.
103
+ *
104
+ * Only applies when `syntaxHighlight` is enabled and the code block
105
+ * specifies a language.
106
+ *
107
+ * @default false
108
+ */
109
+ lineNumbers?: boolean;
101
110
  /**
102
111
  * Emoji font configuration.
103
112
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@speajus/markdown-to-pdf",
3
- "version": "1.0.8",
3
+ "version": "1.0.10",
4
4
  "description": "A new project created with Intent by Augment.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -25,12 +25,13 @@
25
25
  }
26
26
  },
27
27
  "files": [
28
- "dist"
28
+ "dist",
29
+ "README.md"
29
30
  ],
30
31
  "scripts": {
31
32
  "build": "tsc && mkdir -p dist/fonts && cp src/fonts/* dist/fonts/",
32
33
  "generate": "tsx samples/generate.ts",
33
- "test": "tsx --test test/*.test.ts && tsx samples/generate.ts"
34
+ "test": "tsx --test test/*.test.ts && tsx samples/generate.ts && tsx ./src/cli.ts README.md README.pdf"
34
35
  },
35
36
  "keywords": [
36
37
  "markdown",