Whitepaper Editing Tool
Structure and create professional whitepapers with ease.
Content Sections
Your complete whitepaper will be previewed here.
${s.content || 'N/A'}
`; }); } html += `Conclusion
${data.conclusion || 'N/A'}
`; if (data.cta) html += `Call to Action
${data.cta}
`; document.getElementById('generated-whitepaper-content').innerHTML = html; }; const downloadPdf = async () => { const { jsPDF } = window.jspdf; const doc = new jsPDF({ orientation: 'portrait', unit: 'mm', format: 'a4' }); const data = getWhitepaperData(); const pageW = doc.internal.pageSize.getWidth(); const pageH = doc.internal.pageSize.getHeight(); const margin = 20; let y = 0; let pageNum = 1; const toc = []; const primaryColor = '#1e293b'; // Slate-800 const textColor = '#334155'; // Slate-700 const addHeaderFooter = (isTocPage = false) => { if (pageNum > 1) { doc.setFontSize(9).setTextColor('#64748b'); const headerText = isTocPage ? 'Table of Contents' : data.title; doc.text(headerText, margin, margin / 2); doc.text(`Page ${pageNum}`, pageW - margin, pageH - (margin / 2), { align: 'right' }); if (data.company) { doc.text(data.company, margin, pageH - (margin / 2)); } } }; // --- Title Page --- doc.setFontSize(28).setFont(undefined, 'bold').setTextColor(primaryColor).text(doc.splitTextToSize(data.title, pageW - margin * 2), pageW / 2, pageH / 2 - 20, { align: 'center' }); doc.setFontSize(14).setFont(undefined, 'normal').setTextColor(textColor).text(data.author || '', pageW / 2, pageH / 2 + 10, { align: 'center' }); doc.setFontSize(14).setFont(undefined, 'bold').setTextColor(textColor).text(data.company || '', pageW / 2, pageH / 2 + 20, { align: 'center' }); const date = new Date('2025-09-15T00:00:00').toLocaleDateString('en-US', { year: 'numeric', month: 'long' }); doc.setFontSize(12).text(date, pageW / 2, pageH / 2 + 30, { align: 'center' }); // --- Content Rendering Pass --- const addSectionToPdf = (title, content, isSub = false) => { if (y > pageH - margin * 2) { doc.addPage(); pageNum++; addHeaderFooter(); y = margin + 10; } toc.push({ title, page: pageNum }); doc.setFontSize(isSub ? 14 : 18).setFont(undefined, 'bold').setTextColor(primaryColor).text(title, margin, y); y += isSub ? 8 : 10; const lines = doc.setFontSize(11).setFont(undefined, 'normal').setTextColor(textColor).splitTextToSize(content || 'Not provided.', pageW - margin * 2); lines.forEach(line => { if (y > pageH - margin) { doc.addPage(); pageNum++; addHeaderFooter(); y = margin + 10; } doc.text(line, margin, y); y += 6; }); y += 8; }; doc.addPage(); pageNum++; addHeaderFooter(); y = margin + 10; addSectionToPdf('1. Introduction', ''); addSectionToPdf('Abstract', data.abstract, true); addSectionToPdf('Problem Statement', data.problem, true); addSectionToPdf('2. Main Body', ''); data.sections.forEach(s => addSectionToPdf(s.title, s.content, true)); addSectionToPdf('3. Conclusion', data.conclusion); if(data.cta) addSectionToPdf('Call to Action', data.cta, true); // --- Table of Contents Page --- doc.insertPage(2); doc.setPage(2); pageNum = 2; addHeaderFooter(true); y = margin + 20; doc.setFontSize(20).setFont(undefined, 'bold').setTextColor(primaryColor).text('Table of Contents', margin, y); y += 15; toc.forEach(item => { doc.setFontSize(12).setFont(undefined, 'normal').setTextColor(textColor); const dots = '.'.repeat(Math.max(0, 70 - item.title.length)); doc.text(`${item.title} ${dots} ${item.page}`, margin, y); y += 8; }); doc.save(`${data.title.replace(/\s+/g, '-')}-Whitepaper.pdf`); }; downloadPdfBtn.addEventListener('click', downloadPdf); // Initialize addSection(); updateTabUI(0); lucide.createIcons(); });