About ${inputs.boilerplate.value.split(' ')[0]}
${p(data.boilerplate)}Contact:
${data.contactName ? `${escapeHTML(data.contactName)}
` : ''} ${data.contactTitle ? `${escapeHTML(data.contactTitle)}
` : ''} ${data.contactEmail ? `${escapeHTML(data.contactEmail)}
` : ''} ${data.contactPhone ? `${escapeHTML(data.contactPhone)}
` : ''} ${data.website ? `${escapeHTML(data.website)}
` : ''}###
`; }; const getTxtContent = () => { const data = getReleaseData(); let content = "FOR IMMEDIATE RELEASE\n\n"; content += `${data.headline.toUpperCase()}\n\n`; if (data.subheadline) { content += `${data.subheadline}\n\n`; } content += `${data.dateline} -- ${data.intro}\n\n`; content += `${data.problem}\n\n`; content += `${data.solution}\n\n`; content += `"${data.quote}"\n- ${data.attribution}\n\n`; content += `About\n${data.boilerplate}\n\n`; content += `Contact:\n`; if (data.contactName) content += `${data.contactName}\n`; if (data.contactTitle) content += `${data.contactTitle}\n`; if (data.contactEmail) content += `${data.contactEmail}\n`; if (data.contactPhone) content += `${data.contactPhone}\n`; if (data.website) content += `${data.website}\n`; content += `\n###\n`; return content; }; const downloadTxt = () => { const txtContent = getTxtContent(); const blob = new Blob([txtContent], { type: 'text/plain;charset=utf-8' }); const a = document.createElement('a'); a.href = URL.createObjectURL(blob); a.download = 'press_release.txt'; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(a.href); }; const downloadPDF = () => { if (typeof window.jspdf === 'undefined' || typeof window.jspdf.jsPDF === 'undefined') { alert('Error: jsPDF library not loaded.'); return; } const { jsPDF } = window.jspdf; const doc = new jsPDF('p', 'mm', 'a4'); const data = getReleaseData(); const margin = 20; const pageWidth = doc.internal.pageSize.getWidth(); const usableWidth = pageWidth - (margin * 2); let yPos = 25; // Start position const addWrappedText = (text, options = {}) => { const { font = 'times', style = 'normal', size = 12, align = 'left', indent = 0, isQuote = false } = options; doc.setFont(font, style); doc.setFontSize(size); let textToSplit = text; let textMargin = margin + indent; let textWidth = usableWidth - indent; if (isQuote) { textMargin += 10; textWidth -= 20; textToSplit = `"${text}"`; } const splitText = doc.splitTextToSize(textToSplit, textWidth); if (yPos + (splitText.length * 7) > 270) { // Check for page break doc.addPage(); yPos = 20; } doc.text(splitText, textMargin, yPos, { align: align }); yPos += (splitText.length * 7); // 7mm per line yPos += 3; // buffer }; // --- Build PDF Document --- doc.setFont('times', 'bold'); doc.setFontSize(12); doc.text("FOR IMMEDIATE RELEASE", pageWidth / 2, yPos, { align: 'center' }); yPos += 10; doc.setFont('times', 'bold'); doc.setFontSize(16); addWrappedText(data.headline.toUpperCase(), { size: 16, style: 'bold', align: 'center' }); yPos += 2; if (data.subheadline) { addWrappedText(data.subheadline, { size: 12, style: 'italic', align: 'center' }); yPos += 2; } doc.setFont('times', 'normal'); doc.setFontSize(12); const datelineIntro = ` ${data.dateline} -- ${data.intro}`; addWrappedText(datelineIntro, { size: 12 }); addWrappedText(data.problem, { size: 12, indent: 5 }); addWrappedText(data.solution, { size: 12, indent: 5 }); addWrappedText(data.quote, { size: 12, style: 'italic', isQuote: true }); addWrappedText(`- ${data.attribution}`, { size: 12, style: 'bold', align: 'right' }); addWrappedText("About", { size: 12, style: 'bold' }); addWrappedText(data.boilerplate, { size: 12, indent: 5 }); addWrappedText("Contact:", { size: 12, style: 'bold' }); let contactInfo = ''; if (data.contactName) contactInfo += `${data.contactName}\n`; if (data.contactTitle) contactInfo += `${data.contactTitle}\n`; if (data.contactEmail) contactInfo += `${data.contactEmail}\n`; if (data.contactPhone) contactInfo += `${data.contactPhone}\n`; if (data.website) contactInfo += `${data.website}\n`; addWrappedText(contactInfo, { size: 12, indent: 5 }); addWrappedText("###", { size: 12, style: 'bold', align: 'center' }); doc.save('press_release.pdf'); }; // --- Event Listeners --- // Tab Buttons tabButtons.forEach((btn, index) => { btn.addEventListener('click', () => showTab(index + 1)); }); // Next/Prev Navigation nextBtn.addEventListener('click', () => showTab(currentTab + 1)); prevBtn.addEventListener('click', () => showTab(currentTab - 1)); // Tab 4 Actions downloadPdfBtn.addEventListener('click', downloadPDF); downloadTxtBtn.addEventListener('click', downloadTxt); // --- Initialization --- showTab(1); // Set initial state });