md-to-pdf-engine 1.0.0
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/LICENSE +21 -0
- package/README.md +91 -0
- package/dist/cli.d.mts +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +671 -0
- package/dist/cli.js.map +1 -0
- package/dist/cli.mjs +648 -0
- package/dist/cli.mjs.map +1 -0
- package/dist/index.d.mts +104 -0
- package/dist/index.d.ts +104 -0
- package/dist/index.js +590 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +541 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +46 -0
package/dist/cli.mjs.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts","../src/pdf-engine.ts","../src/pdf-styles.ts","../src/templates/corporativa-clasica.ts","../src/templates/moderna-minimalista.ts","../src/templates/tecnica-documentacion.ts","../src/templates/moderna-azul.ts","../src/templates/profesional-moderna.ts","../src/templates/index.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * CLI for generating PDF from a Markdown file.\n *\n * Usage:\n * md-to-pdf <file.md> [options]\n *\n * Options:\n * --template <id> Template: corporativa-clasica | moderna-minimalista | tecnica-documentacion | moderna-azul | profesional-moderna\n * --output <path> Output PDF path (default: same name with .pdf)\n * --size <size> Page size: A4 | Letter | Legal (default: A4)\n * --orientation <o> Orientation: portrait | landscape (default: portrait)\n * --cover Include cover page\n * --no-page-numbers Disable page numbers\n * --list-templates List available templates\n */\n\nimport { resolve, dirname, basename, extname, join } from \"path\";\nimport { readFileSync, writeFileSync, existsSync } from \"fs\";\nimport { generatePDFFromMarkdown } from \"./pdf-engine\";\nimport { getTemplateById, DEFAULT_TEMPLATE, getAllTemplates } from \"./templates\";\nimport type { PDFOptions } from \"./types\";\n\nfunction printUsage(): void {\n console.log(`\nmd-to-pdf — Professional PDF generation from Markdown\n\nUsage:\n md-to-pdf <file.md> [options]\n\nOptions:\n --template <id> Template to use (default: corporativa-clasica)\n --output <path> Output PDF path\n --size <size> A4 | Letter | Legal (default: A4)\n --orientation <o> portrait | landscape (default: portrait)\n --cover Include cover page\n --no-page-numbers Disable page numbers\n --list-templates List available templates\n\nTemplates:\n${getAllTemplates()\n .map((t) => ` - ${t.id} (${t.name})`)\n .join(\"\\n\")}\n`);\n}\n\nfunction parseArgs(args: string[]): {\n inputFile: string;\n templateId: string;\n outputFile: string;\n pageSize: \"A4\" | \"Letter\" | \"Legal\";\n orientation: \"portrait\" | \"landscape\";\n includeCover: boolean;\n includePageNumbers: boolean;\n} {\n if (args.length === 0 || args.includes(\"--help\") || args.includes(\"-h\")) {\n printUsage();\n process.exit(0);\n }\n\n if (args.includes(\"--list-templates\")) {\n console.log(\"Available templates:\");\n for (const t of getAllTemplates()) {\n console.log(` ${t.id} - ${t.name}`);\n }\n process.exit(0);\n }\n\n const inputFile = args[0];\n let templateId = \"corporativa-clasica\";\n let outputFile = \"\";\n let pageSize: \"A4\" | \"Letter\" | \"Legal\" = \"A4\";\n let orientation: \"portrait\" | \"landscape\" = \"portrait\";\n let includeCover = false;\n let includePageNumbers = true;\n\n for (let i = 1; i < args.length; i++) {\n switch (args[i]) {\n case \"--template\":\n templateId = args[++i];\n break;\n case \"--output\":\n outputFile = args[++i];\n break;\n case \"--size\":\n pageSize = args[++i] as \"A4\" | \"Letter\" | \"Legal\";\n break;\n case \"--orientation\":\n orientation = args[++i] as \"portrait\" | \"landscape\";\n break;\n case \"--cover\":\n includeCover = true;\n break;\n case \"--no-page-numbers\":\n includePageNumbers = false;\n break;\n }\n }\n\n if (!outputFile) {\n const dir = dirname(inputFile);\n const name = basename(inputFile, extname(inputFile));\n outputFile = join(dir, `${name}.pdf`);\n }\n\n return {\n inputFile: resolve(inputFile),\n templateId,\n outputFile: resolve(outputFile),\n pageSize,\n orientation,\n includeCover,\n includePageNumbers,\n };\n}\n\nasync function main(): Promise<void> {\n const args = process.argv.slice(2);\n const config = parseArgs(args);\n\n if (!existsSync(config.inputFile)) {\n console.error(`Error: file not found: ${config.inputFile}`);\n process.exit(1);\n }\n\n const template = getTemplateById(config.templateId) ?? DEFAULT_TEMPLATE;\n if (config.templateId && !getTemplateById(config.templateId)) {\n console.warn(\n `Warning: template \"${config.templateId}\" not found, using \"${template.id}\"`,\n );\n }\n\n const markdown = readFileSync(config.inputFile, \"utf-8\");\n\n const pdfOptions: PDFOptions = {\n pageSize: config.pageSize,\n orientation: config.orientation,\n margins: template.margins,\n includeCoverPage: config.includeCover,\n includePageNumbers: config.includePageNumbers,\n pageNumberFormat: \"Página X de Y\",\n };\n\n console.log(`Generating PDF...`);\n console.log(` Input: ${config.inputFile}`);\n console.log(` Template: ${template.name} (${template.id})`);\n console.log(` Size: ${config.pageSize} ${config.orientation}`);\n console.log(` Cover page: ${config.includeCover ? \"Yes\" : \"No\"}`);\n console.log(` Page numbers: ${config.includePageNumbers ? \"Yes\" : \"No\"}`);\n\n const pdfBuffer = await generatePDFFromMarkdown(markdown, template, pdfOptions);\n\n writeFileSync(config.outputFile, pdfBuffer);\n\n const sizeMB = (pdfBuffer.length / 1024 / 1024).toFixed(2);\n console.log(`\\nPDF generated: ${config.outputFile} (${sizeMB} MB)`);\n}\n\nmain().catch((err) => {\n console.error(\"Error generating PDF:\", err);\n process.exit(1);\n});\n","import { Marked } from \"marked\";\nimport hljs from \"highlight.js\";\nimport puppeteer from \"puppeteer\";\nimport { generatePDFStyles, generateHeaderHTML, generateFooterHTML } from \"./pdf-styles\";\nimport type { TemplateConfig, PDFOptions } from \"./types\";\n\nconst PAGE_SIZE_MAP: Record<string, { width: string; height: string }> = {\n A4: { width: \"210mm\", height: \"297mm\" },\n Letter: { width: \"8.5in\", height: \"11in\" },\n Legal: { width: \"8.5in\", height: \"14in\" },\n};\n\nfunction getHighlightCSS(): string {\n return `\n .hljs { background: #f5f5f5; color: #24292e; }\n .hljs-comment, .hljs-quote { color: #6a737d; font-style: italic; }\n .hljs-keyword, .hljs-selector-tag, .hljs-addition { color: #d73a49; }\n .hljs-string, .hljs-meta .hljs-string, .hljs-regexp { color: #032f62; }\n .hljs-number, .hljs-literal, .hljs-variable, .hljs-template-variable, .hljs-tag .hljs-attr { color: #005cc5; }\n .hljs-type, .hljs-title, .hljs-section, .hljs-name, .hljs-selector-id, .hljs-selector-class { color: #6f42c1; }\n .hljs-attribute, .hljs-symbol, .hljs-bullet, .hljs-built_in, .hljs-link { color: #e36209; }\n .hljs-subst { color: #24292e; }\n .hljs-deletion { color: #b31d28; background-color: #ffeef0; }\n .hljs-emphasis { font-style: italic; }\n .hljs-strong { font-weight: bold; }\n `;\n}\n\nfunction createConfiguredMarked(): Marked {\n const marked = new Marked();\n\n const renderer = {\n code({ text, lang }: { text: string; lang?: string }): string {\n const language = lang && hljs.getLanguage(lang) ? lang : undefined;\n let highlighted: string;\n\n if (language) {\n highlighted = hljs.highlight(text, { language }).value;\n } else {\n highlighted = hljs.highlightAuto(text).value;\n }\n\n const langClass = language ? ` language-${language}` : \"\";\n const langLabel = language\n ? `<div class=\"code-lang-label\">${language}</div>`\n : \"\";\n return `<div class=\"code-block-wrapper\">${langLabel}<pre><code class=\"hljs${langClass}\">${highlighted}</code></pre></div>\\n`;\n },\n };\n\n marked.setOptions({ gfm: true, breaks: false });\n marked.use({ renderer });\n\n return marked;\n}\n\nfunction wrapCoverPage(htmlContent: string): string {\n const h1Regex = /(<h1[\\s>])/i;\n const match = h1Regex.exec(htmlContent);\n\n if (!match || match.index === undefined) {\n return htmlContent;\n }\n\n const h1Index = match.index;\n const h1CloseIndex = htmlContent.indexOf(\"</h1>\", h1Index);\n if (h1CloseIndex === -1) {\n return htmlContent;\n }\n\n const coverEnd = h1CloseIndex + \"</h1>\".length;\n const coverContent = htmlContent.slice(0, coverEnd);\n const restContent = htmlContent.slice(coverEnd);\n\n return `<div class=\"cover-page\">${coverContent}</div>${restContent}`;\n}\n\n/**\n * Converts Markdown to full HTML with styles applied, ready for rendering.\n */\nexport function markdownToHTML(\n markdown: string,\n template: TemplateConfig,\n options?: { includeCoverPage?: boolean },\n): string {\n const marked = createConfiguredMarked();\n let htmlContent = marked.parse(markdown) as string;\n const css = generatePDFStyles(template);\n const highlightCSS = getHighlightCSS();\n const headerHTML = generateHeaderHTML(template);\n\n if (options?.includeCoverPage) {\n htmlContent = wrapCoverPage(htmlContent);\n }\n\n return `<!DOCTYPE html>\n<html lang=\"es\">\n<head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <style>${css}</style>\n <style>${highlightCSS}</style>\n</head>\n<body>\n ${headerHTML}\n <main>${htmlContent}</main>\n</body>\n</html>`;\n}\n\nfunction buildFooterTextScript(format: string): string {\n switch (format) {\n case \"X/Y\":\n return `textEl.textContent = adjustedPage + '/' + adjustedTotal;`;\n case \"X\":\n return `textEl.textContent = String(adjustedPage);`;\n case \"Page X of Y\":\n return `textEl.textContent = 'Page ' + adjustedPage + ' of ' + adjustedTotal;`;\n case \"Página X de Y\":\n default:\n return `textEl.textContent = 'Página ' + adjustedPage + ' de ' + adjustedTotal;`;\n }\n}\n\nfunction buildFooterTemplate(\n options: PDFOptions,\n margins: { top: number; bottom: number; left: number; right: number },\n): string {\n const baseFooter = generateFooterHTML(options.pageNumberFormat);\n\n if (options.includeCoverPage) {\n return `<div style=\"width: 100%; padding: 0 ${margins.left}mm 0 ${margins.right}mm;\">\n <div id=\"footer-content\" style=\"font-size: 9pt; color: #666; text-align: center; width: 100%; padding-top: 5px; border-top: 1px solid #e0e0e0;\">\n <span id=\"footer-text\"></span>\n </div>\n <script>\n try {\n var pageNum = parseInt(document.querySelector('.pageNumber')?.textContent || '0', 10);\n var totalPages = parseInt(document.querySelector('.totalPages')?.textContent || '0', 10);\n var footerEl = document.getElementById('footer-content');\n var textEl = document.getElementById('footer-text');\n if (pageNum <= 1) {\n footerEl.style.display = 'none';\n } else {\n var adjustedPage = pageNum - 1;\n var adjustedTotal = totalPages - 1;\n ${buildFooterTextScript(options.pageNumberFormat)}\n }\n } catch(e) {}\n </script>\n <span class=\"pageNumber\" style=\"display:none;\"></span>\n <span class=\"totalPages\" style=\"display:none;\"></span>\n </div>`;\n }\n\n return `<div style=\"width: 100%; padding: 0 ${margins.left}mm 0 ${margins.right}mm;\">\n ${baseFooter}\n </div>`;\n}\n\n/**\n * Main PDF rendering engine.\n * Converts Markdown to PDF using Puppeteer with full visual hierarchy.\n */\nexport async function generatePDFFromMarkdown(\n markdown: string,\n template: TemplateConfig,\n options: PDFOptions,\n): Promise<Buffer> {\n let browser: Awaited<ReturnType<typeof puppeteer.launch>> | null = null;\n\n try {\n const fullHTML = markdownToHTML(markdown, template, {\n includeCoverPage: options.includeCoverPage,\n });\n\n const margins = options.margins ?? template.margins;\n\n browser = await puppeteer.launch({\n headless: true,\n args: [\"--no-sandbox\", \"--disable-setuid-sandbox\"],\n });\n\n const page = await browser.newPage();\n await page.setContent(fullHTML, { waitUntil: \"networkidle0\" });\n\n const pageSize = PAGE_SIZE_MAP[options.pageSize] ?? PAGE_SIZE_MAP[\"A4\"];\n const isLandscape = options.orientation === \"landscape\";\n\n const logoJustify = template.logoPosition === \"right\"\n ? \"flex-end\"\n : template.logoPosition === \"center\"\n ? \"center\"\n : \"flex-start\";\n const logoMaxHeight = Math.min(template.logoMaxSize, 50);\n\n let headerTemplate: string;\n if (!template.logoUrl) {\n headerTemplate = '<div style=\"font-size: 1px;\"></div>';\n } else if (template.logoDisplay === \"first-page\") {\n headerTemplate = `<div style=\"width: 100%; padding: 0 ${margins.left}mm 0 ${margins.right}mm;\">\n <div id=\"header-logo\" style=\"display: flex; justify-content: ${logoJustify}; padding: 5px 0;\">\n <img src=\"${template.logoUrl}\" style=\"max-height: ${logoMaxHeight}px;\" />\n </div>\n <span class=\"pageNumber\" style=\"display:none;\"></span>\n <script>\n try {\n var pageNum = parseInt(document.querySelector('.pageNumber').textContent || '0', 10);\n if (pageNum > 1) {\n document.getElementById('header-logo').style.display = 'none';\n }\n } catch(e) {}\n </script>\n </div>`;\n } else {\n headerTemplate = `<div style=\"width: 100%; padding: 0 ${margins.left}mm 0 ${margins.right}mm;\">\n <div style=\"display: flex; justify-content: ${logoJustify}; padding: 5px 0;\">\n <img src=\"${template.logoUrl}\" style=\"max-height: ${logoMaxHeight}px;\" />\n </div>\n </div>`;\n }\n\n const footerTemplate = options.includePageNumbers\n ? buildFooterTemplate(options, margins)\n : '<div style=\"font-size: 1px;\"></div>';\n\n const pdfBuffer = await page.pdf({\n width: pageSize.width,\n height: pageSize.height,\n landscape: isLandscape,\n printBackground: true,\n displayHeaderFooter: options.includePageNumbers || !!template.logoUrl,\n headerTemplate,\n footerTemplate,\n margin: {\n top: `${margins.top}mm`,\n bottom: `${margins.bottom}mm`,\n left: `${margins.left}mm`,\n right: `${margins.right}mm`,\n },\n });\n\n await browser.close();\n browser = null;\n\n return Buffer.from(pdfBuffer);\n } finally {\n if (browser) {\n try {\n await browser.close();\n } catch {\n // Ignore close error\n }\n }\n }\n}\n","import type { TemplateConfig } from \"./types\";\n\n/**\n * Generates the complete CSS for the HTML document rendered as PDF.\n * Styles are based on the template configuration (colors, fonts, margins).\n */\nexport function generatePDFStyles(template: TemplateConfig): string {\n const { colors, fonts } = template;\n\n return `\n /* Reset and base */\n *, *::before, *::after {\n box-sizing: border-box;\n margin: 0;\n padding: 0;\n }\n\n body {\n font-family: ${fonts.body}, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n font-size: 12pt;\n line-height: 1.6;\n color: ${colors.text};\n background-color: ${colors.background};\n }\n\n /* Headings */\n h1, h2, h3, h4, h5, h6 {\n font-family: ${fonts.heading}, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n line-height: 1.3;\n margin-top: 1.5em;\n margin-bottom: 0.5em;\n page-break-after: avoid;\n break-after: avoid;\n orphans: 2;\n widows: 2;\n }\n\n h1 {\n font-size: 28pt;\n color: ${colors.primary};\n border-bottom: 2px solid ${colors.primary};\n padding-bottom: 0.3em;\n margin-top: 0;\n }\n\n h2 {\n font-size: 22pt;\n color: ${colors.primary};\n border-bottom: 1px solid ${colors.secondary};\n padding-bottom: 0.2em;\n }\n\n h3 { font-size: 18pt; color: ${colors.secondary}; }\n h4 { font-size: 15pt; color: ${colors.secondary}; }\n h5 { font-size: 13pt; color: ${colors.secondary}; }\n h6 { font-size: 12pt; color: ${colors.secondary}; font-style: italic; }\n\n /* Paragraphs and text */\n p {\n margin-bottom: 0.8em;\n orphans: 2;\n widows: 2;\n break-inside: avoid;\n }\n\n a { color: ${colors.accent}; text-decoration: underline; }\n strong { font-weight: 700; }\n em { font-style: italic; }\n\n /* Lists */\n ul, ol { margin-bottom: 1em; padding-left: 2em; }\n ul ul, ol ol, ul ol, ol ul { margin-bottom: 0; margin-top: 0.3em; }\n li { margin-bottom: 0.3em; page-break-inside: avoid; break-inside: avoid; }\n ul > li { list-style-type: disc; }\n ul > li > ul > li { list-style-type: circle; }\n ul > li > ul > li > ul > li { list-style-type: square; }\n li::marker { color: ${colors.accent}; }\n\n /* Tables */\n table { width: 100%; border-collapse: collapse; margin-bottom: 1.5em; page-break-inside: auto; }\n thead { background-color: ${colors.primary}; color: ${colors.background}; }\n th { font-weight: 700; text-align: left; padding: 10px 12px; border: 1px solid ${colors.secondary}; }\n td { padding: 8px 12px; border: 1px solid ${colors.secondary}; }\n tbody tr:nth-child(even) { background-color: rgba(0, 0, 0, 0.03); }\n tr { page-break-inside: avoid; }\n\n /* Code blocks */\n .code-block-wrapper { position: relative; margin-bottom: 1em; page-break-inside: avoid; }\n .code-lang-label {\n position: absolute; top: 0; right: 0;\n background-color: ${colors.secondary}20; color: ${colors.secondary};\n font-family: 'SFMono-Regular', 'Consolas', 'Liberation Mono', 'Menlo', monospace;\n font-size: 8pt; padding: 2px 8px; border-radius: 0 6px 0 4px;\n text-transform: uppercase; letter-spacing: 0.03em; z-index: 1;\n }\n pre {\n background-color: ${colors.secondary}1a; border: 1px solid ${colors.secondary}40;\n border-radius: 6px; padding: 1em; margin-bottom: 0;\n overflow-x: visible; white-space: pre-wrap; word-wrap: break-word;\n overflow-wrap: break-word; font-size: 10pt; page-break-inside: avoid;\n }\n pre code { background: none; border: none; padding: 0; font-size: inherit; white-space: pre-wrap; word-wrap: break-word; overflow-wrap: break-word; }\n code {\n font-family: 'SFMono-Regular', 'Consolas', 'Liberation Mono', 'Menlo', monospace;\n background-color: #f0f0f0; border-radius: 3px; padding: 0.15em 0.3em; font-size: 0.9em;\n }\n\n /* Blockquotes */\n blockquote { border-left: 4px solid ${colors.primary}; background-color: rgba(0, 0, 0, 0.02); padding: 0.8em 1.2em; margin: 0 0 1em 0; color: ${colors.text}; }\n blockquote p { margin-bottom: 0.4em; }\n blockquote p:last-child { margin-bottom: 0; }\n\n /* Horizontal rule */\n hr { border: none; border-top: 2px solid ${colors.secondary}; margin: 2em 0; }\n\n /* Images */\n img { max-width: 100%; height: auto; }\n\n /* Pagination */\n .page-break { page-break-after: always; }\n .cover-page { page-break-after: always; break-after: page; }\n * { orphans: 2; widows: 2; }\n\n @media print {\n h1, h2, h3, h4, h5, h6 { page-break-after: avoid; break-after: avoid; orphans: 2; widows: 2; }\n p { page-break-inside: avoid; break-inside: avoid; }\n li { page-break-inside: avoid; break-inside: avoid; }\n pre, blockquote, figure { page-break-inside: avoid; break-inside: avoid; }\n table { page-break-inside: auto; }\n tr { page-break-inside: avoid; break-inside: avoid; }\n thead { display: table-header-group; }\n img { page-break-inside: avoid; break-inside: avoid; }\n }\n `;\n}\n\n/**\n * Generates the HTML header with logo for the document.\n */\nexport function generateHeaderHTML(template: TemplateConfig): string {\n if (!template.logoUrl) {\n return \"\";\n }\n\n const alignMap: Record<string, string> = {\n left: \"flex-start\",\n center: \"center\",\n right: \"flex-end\",\n };\n\n const justify = alignMap[template.logoPosition] ?? \"flex-start\";\n\n return `\n <div style=\"display: flex; justify-content: ${justify}; align-items: center; padding: 0 0 10px 0; border-bottom: 1px solid #e0e0e0; margin-bottom: 10px;\">\n <img src=\"${template.logoUrl}\" style=\"max-height: ${template.logoMaxSize}px; max-width: 200px;\" alt=\"Logo\" />\n </div>\n `;\n}\n\n/**\n * Generates the footer HTML with page number.\n */\nexport function generateFooterHTML(pageNumberFormat: string): string {\n let content: string;\n\n switch (pageNumberFormat) {\n case \"X/Y\":\n content = '<span class=\"pageNumber\"></span>/<span class=\"totalPages\"></span>';\n break;\n case \"X\":\n content = '<span class=\"pageNumber\"></span>';\n break;\n case \"Page X of Y\":\n content = 'Page <span class=\"pageNumber\"></span> of <span class=\"totalPages\"></span>';\n break;\n case \"Página X de Y\":\n default:\n content = 'Página <span class=\"pageNumber\"></span> de <span class=\"totalPages\"></span>';\n break;\n }\n\n return `\n <div style=\"font-size: 9pt; color: #666; text-align: center; width: 100%; padding-top: 5px; border-top: 1px solid #e0e0e0;\">\n ${content}\n </div>\n `;\n}\n","import type { TemplateConfig } from \"../types\";\n\nexport const corporativaClasica: TemplateConfig = {\n id: \"corporativa-clasica\",\n name: \"Corporativa Clasica\",\n logoUrl: \"\",\n logoPosition: \"center\",\n logoDisplay: \"all-pages\",\n logoMaxSize: 100,\n colors: {\n primary: \"#1B3A5C\",\n secondary: \"#C4A035\",\n accent: \"#2E5C8A\",\n background: \"#FFFFFF\",\n text: \"#333333\",\n },\n fonts: {\n heading: \"Georgia, serif\",\n body: \"Garamond, serif\",\n },\n margins: {\n top: 25,\n bottom: 25,\n left: 20,\n right: 20,\n },\n};\n","import type { TemplateConfig } from \"../types\";\n\nexport const modernaMinimalista: TemplateConfig = {\n id: \"moderna-minimalista\",\n name: \"Moderna Minimalista\",\n logoUrl: \"\",\n logoPosition: \"left\",\n logoDisplay: \"all-pages\",\n logoMaxSize: 80,\n colors: {\n primary: \"#2D2D2D\",\n secondary: \"#6B7280\",\n accent: \"#06B6D4\",\n background: \"#FAFAFA\",\n text: \"#1A1A1A\",\n },\n fonts: {\n heading: \"Inter, sans-serif\",\n body: \"system-ui, sans-serif\",\n },\n margins: {\n top: 30,\n bottom: 30,\n left: 25,\n right: 25,\n },\n};\n","import type { TemplateConfig } from \"../types\";\n\nexport const tecnicaDocumentacion: TemplateConfig = {\n id: \"tecnica-documentacion\",\n name: \"Tecnica/Documentacion\",\n logoUrl: \"\",\n logoPosition: \"left\",\n logoDisplay: \"all-pages\",\n logoMaxSize: 80,\n colors: {\n primary: \"#374151\",\n secondary: \"#6B7280\",\n accent: \"#10B981\",\n background: \"#FFFFFF\",\n text: \"#1F2937\",\n },\n fonts: {\n heading: \"Fira Code, monospace\",\n body: \"system-ui, sans-serif\",\n },\n margins: {\n top: 20,\n bottom: 20,\n left: 20,\n right: 20,\n },\n};\n","import type { TemplateConfig } from \"../types\";\n\nexport const modernaAzul: TemplateConfig = {\n id: \"moderna-azul\",\n name: \"Moderna Azul\",\n logoUrl: \"\",\n logoPosition: \"left\",\n logoDisplay: \"first-page\",\n logoMaxSize: 80,\n colors: {\n primary: \"#0080ff\",\n secondary: \"#0f2033\",\n accent: \"#00d4ff\",\n background: \"#ffffff\",\n text: \"#1a1a2e\",\n },\n fonts: {\n heading: \"Inter, sans-serif\",\n body: \"Inter, sans-serif\",\n },\n margins: {\n top: 25,\n bottom: 25,\n left: 20,\n right: 20,\n },\n};\n","import type { TemplateConfig } from \"../types\";\n\nexport const profesionalModerna: TemplateConfig = {\n id: \"profesional-moderna\",\n name: \"Profesional Moderna\",\n logoUrl: \"\",\n logoPosition: \"left\",\n logoDisplay: \"first-page\",\n logoMaxSize: 80,\n colors: {\n primary: \"#1E293B\",\n secondary: \"#475569\",\n accent: \"#7C3AED\",\n background: \"#FFFFFF\",\n text: \"#334155\",\n },\n fonts: {\n heading: \"Helvetica Neue, Helvetica, Arial, sans-serif\",\n body: \"Helvetica Neue, Helvetica, Arial, sans-serif\",\n },\n margins: {\n top: 25,\n bottom: 25,\n left: 25,\n right: 25,\n },\n};\n","import type { TemplateConfig } from \"../types\";\nimport { corporativaClasica } from \"./corporativa-clasica\";\nimport { modernaMinimalista } from \"./moderna-minimalista\";\nimport { tecnicaDocumentacion } from \"./tecnica-documentacion\";\nimport { modernaAzul } from \"./moderna-azul\";\nimport { profesionalModerna } from \"./profesional-moderna\";\n\nexport { corporativaClasica } from \"./corporativa-clasica\";\nexport { modernaMinimalista } from \"./moderna-minimalista\";\nexport { tecnicaDocumentacion } from \"./tecnica-documentacion\";\nexport { modernaAzul } from \"./moderna-azul\";\nexport { profesionalModerna } from \"./profesional-moderna\";\n\nexport const DEFAULT_TEMPLATE: TemplateConfig = corporativaClasica;\n\nconst templatesMap: Record<string, TemplateConfig> = {\n [corporativaClasica.id]: corporativaClasica,\n [modernaMinimalista.id]: modernaMinimalista,\n [tecnicaDocumentacion.id]: tecnicaDocumentacion,\n [modernaAzul.id]: modernaAzul,\n [profesionalModerna.id]: profesionalModerna,\n};\n\nexport function getTemplateById(id: string): TemplateConfig | undefined {\n return templatesMap[id];\n}\n\nexport function getAllTemplates(): TemplateConfig[] {\n return [\n corporativaClasica,\n modernaMinimalista,\n tecnicaDocumentacion,\n modernaAzul,\n profesionalModerna,\n ];\n}\n"],"mappings":"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","names":[]}
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/** Template configuration for PDF generation */
|
|
2
|
+
interface TemplateConfig {
|
|
3
|
+
/** Template display name */
|
|
4
|
+
name: string;
|
|
5
|
+
/** Unique template identifier */
|
|
6
|
+
id: string;
|
|
7
|
+
/** URL or base64 of the company logo */
|
|
8
|
+
logoUrl: string;
|
|
9
|
+
/** Logo position in header */
|
|
10
|
+
logoPosition: "left" | "center" | "right";
|
|
11
|
+
/** Show logo on first page only or all pages */
|
|
12
|
+
logoDisplay: "first-page" | "all-pages";
|
|
13
|
+
/** Maximum logo size in pixels */
|
|
14
|
+
logoMaxSize: number;
|
|
15
|
+
/** Template colors */
|
|
16
|
+
colors: {
|
|
17
|
+
/** Primary color (h1-h2 headings, main borders) */
|
|
18
|
+
primary: string;
|
|
19
|
+
/** Secondary color (h3-h6 headings, table borders) */
|
|
20
|
+
secondary: string;
|
|
21
|
+
/** Accent color (links, bullets) */
|
|
22
|
+
accent: string;
|
|
23
|
+
/** Background color */
|
|
24
|
+
background: string;
|
|
25
|
+
/** Text color */
|
|
26
|
+
text: string;
|
|
27
|
+
};
|
|
28
|
+
/** Fonts */
|
|
29
|
+
fonts: {
|
|
30
|
+
/** Heading font family */
|
|
31
|
+
heading: string;
|
|
32
|
+
/** Body text font family */
|
|
33
|
+
body: string;
|
|
34
|
+
};
|
|
35
|
+
/** Page margins in mm */
|
|
36
|
+
margins: {
|
|
37
|
+
top: number;
|
|
38
|
+
bottom: number;
|
|
39
|
+
left: number;
|
|
40
|
+
right: number;
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
/** PDF generation options */
|
|
44
|
+
interface PDFOptions {
|
|
45
|
+
/** Page size */
|
|
46
|
+
pageSize: "A4" | "Letter" | "Legal";
|
|
47
|
+
/** Page orientation */
|
|
48
|
+
orientation: "portrait" | "landscape";
|
|
49
|
+
/** Custom margins in mm */
|
|
50
|
+
margins: {
|
|
51
|
+
top: number;
|
|
52
|
+
bottom: number;
|
|
53
|
+
left: number;
|
|
54
|
+
right: number;
|
|
55
|
+
};
|
|
56
|
+
/** Include cover page */
|
|
57
|
+
includeCoverPage: boolean;
|
|
58
|
+
/** Include page numbers */
|
|
59
|
+
includePageNumbers: boolean;
|
|
60
|
+
/** Page number format */
|
|
61
|
+
pageNumberFormat: "Página X de Y" | "Page X of Y" | "X/Y" | "X";
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Converts Markdown to full HTML with styles applied, ready for rendering.
|
|
66
|
+
*/
|
|
67
|
+
declare function markdownToHTML(markdown: string, template: TemplateConfig, options?: {
|
|
68
|
+
includeCoverPage?: boolean;
|
|
69
|
+
}): string;
|
|
70
|
+
/**
|
|
71
|
+
* Main PDF rendering engine.
|
|
72
|
+
* Converts Markdown to PDF using Puppeteer with full visual hierarchy.
|
|
73
|
+
*/
|
|
74
|
+
declare function generatePDFFromMarkdown(markdown: string, template: TemplateConfig, options: PDFOptions): Promise<Buffer>;
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Generates the complete CSS for the HTML document rendered as PDF.
|
|
78
|
+
* Styles are based on the template configuration (colors, fonts, margins).
|
|
79
|
+
*/
|
|
80
|
+
declare function generatePDFStyles(template: TemplateConfig): string;
|
|
81
|
+
/**
|
|
82
|
+
* Generates the HTML header with logo for the document.
|
|
83
|
+
*/
|
|
84
|
+
declare function generateHeaderHTML(template: TemplateConfig): string;
|
|
85
|
+
/**
|
|
86
|
+
* Generates the footer HTML with page number.
|
|
87
|
+
*/
|
|
88
|
+
declare function generateFooterHTML(pageNumberFormat: string): string;
|
|
89
|
+
|
|
90
|
+
declare const corporativaClasica: TemplateConfig;
|
|
91
|
+
|
|
92
|
+
declare const modernaMinimalista: TemplateConfig;
|
|
93
|
+
|
|
94
|
+
declare const tecnicaDocumentacion: TemplateConfig;
|
|
95
|
+
|
|
96
|
+
declare const modernaAzul: TemplateConfig;
|
|
97
|
+
|
|
98
|
+
declare const profesionalModerna: TemplateConfig;
|
|
99
|
+
|
|
100
|
+
declare const DEFAULT_TEMPLATE: TemplateConfig;
|
|
101
|
+
declare function getTemplateById(id: string): TemplateConfig | undefined;
|
|
102
|
+
declare function getAllTemplates(): TemplateConfig[];
|
|
103
|
+
|
|
104
|
+
export { DEFAULT_TEMPLATE, type PDFOptions, type TemplateConfig, corporativaClasica, generateFooterHTML, generateHeaderHTML, generatePDFFromMarkdown, generatePDFStyles, getAllTemplates, getTemplateById, markdownToHTML, modernaAzul, modernaMinimalista, profesionalModerna, tecnicaDocumentacion };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/** Template configuration for PDF generation */
|
|
2
|
+
interface TemplateConfig {
|
|
3
|
+
/** Template display name */
|
|
4
|
+
name: string;
|
|
5
|
+
/** Unique template identifier */
|
|
6
|
+
id: string;
|
|
7
|
+
/** URL or base64 of the company logo */
|
|
8
|
+
logoUrl: string;
|
|
9
|
+
/** Logo position in header */
|
|
10
|
+
logoPosition: "left" | "center" | "right";
|
|
11
|
+
/** Show logo on first page only or all pages */
|
|
12
|
+
logoDisplay: "first-page" | "all-pages";
|
|
13
|
+
/** Maximum logo size in pixels */
|
|
14
|
+
logoMaxSize: number;
|
|
15
|
+
/** Template colors */
|
|
16
|
+
colors: {
|
|
17
|
+
/** Primary color (h1-h2 headings, main borders) */
|
|
18
|
+
primary: string;
|
|
19
|
+
/** Secondary color (h3-h6 headings, table borders) */
|
|
20
|
+
secondary: string;
|
|
21
|
+
/** Accent color (links, bullets) */
|
|
22
|
+
accent: string;
|
|
23
|
+
/** Background color */
|
|
24
|
+
background: string;
|
|
25
|
+
/** Text color */
|
|
26
|
+
text: string;
|
|
27
|
+
};
|
|
28
|
+
/** Fonts */
|
|
29
|
+
fonts: {
|
|
30
|
+
/** Heading font family */
|
|
31
|
+
heading: string;
|
|
32
|
+
/** Body text font family */
|
|
33
|
+
body: string;
|
|
34
|
+
};
|
|
35
|
+
/** Page margins in mm */
|
|
36
|
+
margins: {
|
|
37
|
+
top: number;
|
|
38
|
+
bottom: number;
|
|
39
|
+
left: number;
|
|
40
|
+
right: number;
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
/** PDF generation options */
|
|
44
|
+
interface PDFOptions {
|
|
45
|
+
/** Page size */
|
|
46
|
+
pageSize: "A4" | "Letter" | "Legal";
|
|
47
|
+
/** Page orientation */
|
|
48
|
+
orientation: "portrait" | "landscape";
|
|
49
|
+
/** Custom margins in mm */
|
|
50
|
+
margins: {
|
|
51
|
+
top: number;
|
|
52
|
+
bottom: number;
|
|
53
|
+
left: number;
|
|
54
|
+
right: number;
|
|
55
|
+
};
|
|
56
|
+
/** Include cover page */
|
|
57
|
+
includeCoverPage: boolean;
|
|
58
|
+
/** Include page numbers */
|
|
59
|
+
includePageNumbers: boolean;
|
|
60
|
+
/** Page number format */
|
|
61
|
+
pageNumberFormat: "Página X de Y" | "Page X of Y" | "X/Y" | "X";
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Converts Markdown to full HTML with styles applied, ready for rendering.
|
|
66
|
+
*/
|
|
67
|
+
declare function markdownToHTML(markdown: string, template: TemplateConfig, options?: {
|
|
68
|
+
includeCoverPage?: boolean;
|
|
69
|
+
}): string;
|
|
70
|
+
/**
|
|
71
|
+
* Main PDF rendering engine.
|
|
72
|
+
* Converts Markdown to PDF using Puppeteer with full visual hierarchy.
|
|
73
|
+
*/
|
|
74
|
+
declare function generatePDFFromMarkdown(markdown: string, template: TemplateConfig, options: PDFOptions): Promise<Buffer>;
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Generates the complete CSS for the HTML document rendered as PDF.
|
|
78
|
+
* Styles are based on the template configuration (colors, fonts, margins).
|
|
79
|
+
*/
|
|
80
|
+
declare function generatePDFStyles(template: TemplateConfig): string;
|
|
81
|
+
/**
|
|
82
|
+
* Generates the HTML header with logo for the document.
|
|
83
|
+
*/
|
|
84
|
+
declare function generateHeaderHTML(template: TemplateConfig): string;
|
|
85
|
+
/**
|
|
86
|
+
* Generates the footer HTML with page number.
|
|
87
|
+
*/
|
|
88
|
+
declare function generateFooterHTML(pageNumberFormat: string): string;
|
|
89
|
+
|
|
90
|
+
declare const corporativaClasica: TemplateConfig;
|
|
91
|
+
|
|
92
|
+
declare const modernaMinimalista: TemplateConfig;
|
|
93
|
+
|
|
94
|
+
declare const tecnicaDocumentacion: TemplateConfig;
|
|
95
|
+
|
|
96
|
+
declare const modernaAzul: TemplateConfig;
|
|
97
|
+
|
|
98
|
+
declare const profesionalModerna: TemplateConfig;
|
|
99
|
+
|
|
100
|
+
declare const DEFAULT_TEMPLATE: TemplateConfig;
|
|
101
|
+
declare function getTemplateById(id: string): TemplateConfig | undefined;
|
|
102
|
+
declare function getAllTemplates(): TemplateConfig[];
|
|
103
|
+
|
|
104
|
+
export { DEFAULT_TEMPLATE, type PDFOptions, type TemplateConfig, corporativaClasica, generateFooterHTML, generateHeaderHTML, generatePDFFromMarkdown, generatePDFStyles, getAllTemplates, getTemplateById, markdownToHTML, modernaAzul, modernaMinimalista, profesionalModerna, tecnicaDocumentacion };
|