@@ -67,30 +67,49 @@ class LatexFileBuilder {
6767 }
6868
6969 saveImage ( content ) {
70- const img_path = `images/${ content . id } .jpeg`
71- this . zip . addFile ( img_path , content . buffer ) ;
72- return img_path
70+ if ( ! content || ! content . id ) {
71+ throw new Error ( 'Invalid image content: missing id' ) ;
72+ }
73+ if ( ! content . buffer || content . buffer . length === 0 ) {
74+ throw new Error ( `Invalid image content: missing or empty buffer for image ${ content . id } ` ) ;
75+ }
76+ const img_path = `images/${ content . id } .jpeg` ;
77+ // Ensure images directory exists in zip (AdmZip handles this automatically)
78+ this . zip . addFile ( img_path , Buffer . from ( content . buffer ) ) ;
79+ return img_path ;
7380 }
7481 convertContent ( content ) {
7582 if ( epubIsText ( content ) ) {
7683 return LatexFileBuilder . markdownToLatex ( content ) ;
7784 }
78- const img_path = this . saveImage ( content ) ;
79- const captions = _ . map ( content . descriptions , ( d ) => {
80- const new_desc = LatexFileBuilder . markdownToLatex ( d ) ;
81- return `\\caption*{${ new_desc } }`
82- } ) . join ( "\n" ) ;
83-
84- const new_alt = LatexFileBuilder . escapeSpecialChars ( content . alt ) ;
85- return [
86- `\\begin{figure}` ,
87- `\\centering` ,
88- this . videoLinks && content . link && content . link !== "" ? `\\href{${ content . link } }{` : "" ,
89- `\\includegraphics[alt={${ new_alt } }, width=.8\\textwidth]{${ img_path } }` ,
90- this . videoLinks && content . link && content . link !== "" ? `}` : "" ,
91- captions ,
92- `\\end{figure}`
93- ] . join ( "\n" )
85+
86+ // Validate image content before processing
87+ if ( ! content || ! content . buffer || content . buffer . length === 0 ) {
88+ console . warn ( 'Skipping image with missing or empty buffer:' , content ) ;
89+ return `% Image skipped: missing or invalid buffer` ;
90+ }
91+
92+ try {
93+ const img_path = this . saveImage ( content ) ;
94+ const captions = _ . map ( content . descriptions || [ ] , ( d ) => {
95+ const new_desc = LatexFileBuilder . markdownToLatex ( d ) ;
96+ return `\\caption*{${ new_desc } }`
97+ } ) . join ( "\n" ) ;
98+
99+ const new_alt = LatexFileBuilder . escapeSpecialChars ( content . alt || '' ) ;
100+ return [
101+ `\\begin{figure}` ,
102+ `\\centering` ,
103+ this . videoLinks && content . link && content . link !== "" ? `\\href{${ content . link } }{` : "" ,
104+ `\\includegraphics[alt={${ new_alt } }, width=.8\\textwidth]{${ img_path } }` ,
105+ this . videoLinks && content . link && content . link !== "" ? `}` : "" ,
106+ captions ,
107+ `\\end{figure}`
108+ ] . join ( "\n" ) ;
109+ } catch ( error ) {
110+ console . error ( 'Error converting image to LaTeX:' , error , content ) ;
111+ return `% Image conversion error: ${ error . message } ` ;
112+ }
94113 }
95114
96115 convertChapter ( idx , chapter ) {
@@ -132,10 +151,12 @@ class LatexFileBuilder {
132151 const glossary = this . data . chapterGlossary ? "" : this . convertGlossary ( this . glossary )
133152 return [
134153 "\\documentclass{article}" ,
154+ "\\usepackage[utf8]{inputenc}" ,
155+ "\\usepackage[T1]{fontenc}" ,
135156 "\\usepackage{caption}" ,
136157 "\\usepackage{graphicx}" ,
137158 "\\usepackage{hyperref}" ,
138- "\\usepackage[T1]{fontenc }" ,
159+ "\\usepackage{textcomp }" ,
139160 "\\begin{document}" ,
140161 titlepage ,
141162 TOC ,
@@ -227,6 +248,9 @@ class LatexFileBuilder {
227248 }
228249
229250 static escapeSpecialChars ( str ) {
251+ if ( ! str ) return str ;
252+
253+ // First escape ASCII special characters
230254 str = str . replace ( / \\ / g, '\\textbackslash ' ) ;
231255 str = str . replace ( / \$ / g, '\\$' ) ;
232256 str = str . replace ( / \{ / g, '\\{' ) ;
@@ -237,6 +261,17 @@ class LatexFileBuilder {
237261 str = str . replace ( / _ / g, '\\_' ) ;
238262 str = str . replace ( / % / g, '\\%' ) ;
239263 str = str . replace ( / ~ / g, '\\~' ) ;
264+
265+ // Handle Unicode characters - convert to LaTeX commands or use proper encoding
266+ // For characters outside ASCII range, we'll use the textcomp package approach
267+ // or convert to LaTeX Unicode commands
268+ str = str . replace ( / [ \u0080 - \uFFFF ] / g, ( char ) => {
269+ // Common Unicode characters that have LaTeX equivalents
270+ // For others, we'll use the character directly with utf8 encoding
271+ // The utf8 inputenc package should handle most Unicode
272+ return char ;
273+ } ) ;
274+
240275 return str
241276 }
242277 static removeVerbatimEscape ( str ) {
0 commit comments