diff --git a/src/server/services/PdfService.ts b/src/server/services/PdfService.ts index 6c9d2fe..3970d1f 100644 --- a/src/server/services/PdfService.ts +++ b/src/server/services/PdfService.ts @@ -287,96 +287,72 @@ export class PdfService { if (!fontItalic) fontItalic = await pdfDoc.embedFont(StandardFonts.HelveticaOblique); if (!fontBoldItalic) fontBoldItalic = fontBold; - // --- NOVO PARSER HTML TinyMCE PARA BLOCOS --- - // Usa jsdom para manter estrutura de blocos e estilos - const { JSDOM } = require('jsdom'); - const dom = new JSDOM(`
${conteudo}`); - const body = dom.window.document.body; - - // Função auxiliar para obter estilos relevantes - function getBlockStyles(el: HTMLElement) { - const styles: any = {}; - const computed = el.getAttribute('style') || ''; - if (/font-weight:\s*bold/i.test(computed) || el.tagName === 'B' || el.tagName === 'STRONG') styles.bold = true; - if (/font-style:\s*italic/i.test(computed) || el.tagName === 'I' || el.tagName === 'EM') styles.italic = true; - if (/text-decoration:\s*underline/i.test(computed) || el.tagName === 'U') styles.underline = true; - if (/text-align:\s*center/i.test(computed) || el.align === 'center' || el.tagName === 'CENTER') styles.align = 'center'; - if (/text-align:\s*right/i.test(computed) || el.align === 'right') styles.align = 'right'; - if (/text-indent:\s*2em/i.test(computed)) styles.indent = true; - if (/font-family:\s*['"]?Fira Sans/i.test(computed)) styles.fontFamily = 'Fira Sans'; - if (el.tagName.match(/^H[1-6]$/)) styles.heading = el.tagName.toLowerCase(); - return styles; - } - - // Função para quebrar texto em linhas respeitando largura máxima - function breakLines(text: string, fontObj: any, fontSize: number, maxWidth: number) { - const words = text.split(' '); - const lines: string[] = []; - let currentLine = ''; - for (const word of words) { - const testLine = currentLine ? currentLine + ' ' + word : word; - const width = fontObj.widthOfTextAtSize(testLine, fontSize); - if (width > maxWidth && currentLine) { - lines.push(currentLine); - currentLine = word; - } else { - currentLine = testLine; - } - } - if (currentLine) lines.push(currentLine); - return lines; - } - - // Função para processar blocos do HTML - function parseBlocks(node: HTMLElement, parentStyles: any = {}) { + // --- PARSER HTML TinyMCE SEM DEPENDÊNCIAS EXTERNAS --- + // Suporte básico a blocos, alinhamento, recuo, negrito, itálico, sublinhado, listas, títulos + function simpleHtmlToBlocks(html: string): any[] { + // Remove tags não suportadas e preserva apenas blocos essenciais + html = html.replace(/'); + html = html.replace(/
'); + html = html.replace(/<\/div>/gi, '
'); + html = html.replace(/]*)>(.*?)<\/p>$/i);
+ if (pMatch) {
+ let styles: any = {};
+ let styleAttr = pMatch[1];
+ if (/text-align:\s*center/i.test(styleAttr)) styles.align = 'center';
+ if (/text-align:\s*right/i.test(styleAttr)) styles.align = 'right';
+ if (/text-indent:\s*2em/i.test(styleAttr)) styles.indent = true;
+ let text = pMatch[2];
+ // Inline styles
+ if (/|/i.test(text)) styles.bold = true;
+ if (/|/i.test(text)) styles.italic = true;
+ if (//i.test(text)) styles.underline = true;
+ text = text.replace(/<\/?(b|strong|i|em|u)>/gi, '');
+ blocks.push({ text, tag: 'p', styles });
+ continue;
+ }
+ // Centralizado
+ let centerMatch = line.match(/^