@@ -17,12 +17,62 @@ async function generatePDF(markdownFile, outputPDF) {
1717 // Convert to HTML
1818 const html = marked . parse ( markdown ) ;
1919
20- // Create full HTML document with styling
20+ // Get the directory of the markdown file for resolving relative paths
21+ const markdownDir = path . dirname ( path . resolve ( markdownFile ) ) ;
22+
23+ // Convert images to base64 and embed directly
24+ let processedHtml = html ;
25+ const imageRegex = / s r c = " f i g u r e s \/ ( [ ^ " ] + ) " / g;
26+ let match ;
27+ let imageCount = 0 ;
28+
29+ while ( ( match = imageRegex . exec ( html ) ) !== null ) {
30+ const imageName = match [ 1 ] ;
31+ const imagePath = path . join ( markdownDir , 'figures' , imageName ) ;
32+
33+ try {
34+ if ( fs . existsSync ( imagePath ) ) {
35+ const imageData = fs . readFileSync ( imagePath ) ;
36+ const base64Image = imageData . toString ( 'base64' ) ;
37+ const ext = path . extname ( imageName ) . substring ( 1 ) ;
38+ const mimeType = ext === 'png' ? 'image/png' : 'image/jpeg' ;
39+ const dataUrl = `data:${ mimeType } ;base64,${ base64Image } ` ;
40+
41+ processedHtml = processedHtml . replace (
42+ `src="figures/${ imageName } "` ,
43+ `src="${ dataUrl } "`
44+ ) ;
45+ imageCount ++ ;
46+ console . log ( ` ✓ Embedded image: ${ imageName } ` ) ;
47+ } else {
48+ console . warn ( ` ⚠ Image not found: ${ imagePath } ` ) ;
49+ }
50+ } catch ( err ) {
51+ console . warn ( ` ⚠ Failed to load image ${ imageName } : ${ err . message } ` ) ;
52+ }
53+ }
54+
55+ console . log ( ` ✓ Total images embedded: ${ imageCount } ` ) ;
56+
57+ // Create full HTML document with styling and MathJax
2158 const fullHTML = `
2259<!DOCTYPE html>
2360<html>
2461<head>
2562 <meta charset="UTF-8">
63+ <script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>
64+ <script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
65+ <script>
66+ MathJax = {
67+ tex: {
68+ inlineMath: [['$', '$'], ['\\\\(', '\\\\)']],
69+ displayMath: [['$$', '$$'], ['\\\\[', '\\\\]']]
70+ },
71+ svg: {
72+ fontCache: 'global'
73+ }
74+ };
75+ </script>
2676 <style>
2777 body {
2878 font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;
@@ -91,6 +141,19 @@ async function generatePDF(markdownFile, outputPDF) {
91141 img {
92142 max-width: 100%;
93143 height: auto;
144+ display: block;
145+ margin: 1em auto;
146+ }
147+ figure {
148+ text-align: center;
149+ margin: 1.5em 0;
150+ page-break-inside: avoid;
151+ }
152+ figcaption, em {
153+ font-style: italic;
154+ color: #666;
155+ font-size: 0.9em;
156+ margin-top: 0.5em;
94157 }
95158 @media print {
96159 body {
@@ -106,7 +169,7 @@ async function generatePDF(markdownFile, outputPDF) {
106169 </style>
107170</head>
108171<body>
109- ${ html }
172+ ${ processedHtml }
110173</body>
111174</html>
112175 ` ;
@@ -122,7 +185,23 @@ ${html}
122185
123186 // Set content
124187 console . log ( ' Rendering HTML...' ) ;
125- await page . setContent ( fullHTML , { waitUntil : 'networkidle0' } ) ;
188+ await page . setContent ( fullHTML , {
189+ waitUntil : [ 'load' , 'domcontentloaded' , 'networkidle0' ]
190+ } ) ;
191+
192+ // Wait for images to load
193+ await page . evaluate ( ( ) => {
194+ return Promise . all (
195+ Array . from ( document . images )
196+ . filter ( img => ! img . complete )
197+ . map ( img => new Promise ( resolve => {
198+ img . onload = img . onerror = resolve ;
199+ } ) )
200+ ) ;
201+ } ) ;
202+
203+ // Wait for MathJax to render
204+ await new Promise ( resolve => setTimeout ( resolve , 3000 ) ) ;
126205
127206 // Generate PDF
128207 console . log ( ' Generating PDF...' ) ;
0 commit comments