Podcast Episode Script Generator

Podcast Episode Script Generator

Structure your next hit episode with ease.

${data.hostName}: ${segment.points}

`; }); scriptHTML += `

Outro

[TRANSITION SOUND EFFECT]

${data.hostName}: ${data.outroRecap}

${data.hostName}: ${data.outroCta}

[OUTRO MUSIC FADES IN AND PLAYS TO END]

`; const contentDiv = document.getElementById('generated-script-content'); if (contentDiv) contentDiv.innerHTML = scriptHTML; } tabs.forEach((tab, index) => tab.addEventListener('click', () => updateTabUI(index))); nextBtn.addEventListener('click', () => { if (currentTab < totalTabs - 1) { if (currentTab === totalTabs - 2) generateScript(); updateTabUI(currentTab + 1); } }); prevBtn.addEventListener('click', () => { if (currentTab > 0) updateTabUI(currentTab - 1); }); downloadPdfBtn.addEventListener('click', () => { const { jsPDF } = window.jspdf; const doc = new jsPDF({ orientation: 'portrait', unit: 'mm', format: 'a4' }); const data = getScriptData(); const pageW = doc.internal.pageSize.getWidth(); const pageH = doc.internal.pageSize.getHeight(); const margin = 15; const usableWidth = pageW - margin * 2; const cueWidth = 35; const textWidth = usableWidth - cueWidth - 2; let y = margin; const cyanColor = '#0891b2'; const darkGray = '#334155'; const lightGray = '#64748b'; const checkPageBreak = (height) => { if (y + height > pageH - margin) { doc.addPage(); y = margin; addHeader(); } }; const addHeader = () => { doc.setFontSize(9); doc.setFont(undefined, 'normal'); doc.setTextColor(lightGray); doc.text(`${data.podcastTitle} | Ep. ${data.episodeNumber}: ${data.episodeTitle}`, margin, margin - 5); const pageNumText = `Page ${doc.internal.getNumberOfPages()}`; const textWidth = doc.getStringUnitWidth(pageNumText) * doc.internal.getFontSize() / doc.internal.scaleFactor; doc.text(pageNumText, pageW - margin - textWidth, margin - 5); }; const addScriptLine = (cue, text) => { doc.setFontSize(10); doc.setFont(undefined, 'bold'); doc.setTextColor(cyanColor); const cueLines = doc.splitTextToSize(`[${cue}]`, cueWidth); doc.setFontSize(11); doc.setFont(undefined, 'normal'); doc.setTextColor(darkGray); const textLines = doc.splitTextToSize(text, textWidth); const height = Math.max(cueLines.length, textLines.length) * 5 + 3; checkPageBreak(height); doc.setFont(undefined, 'bold'); doc.setTextColor(cyanColor); doc.text(cueLines, margin, y); doc.setFont(undefined, 'normal'); doc.setTextColor(darkGray); doc.text(textLines, margin + cueWidth + 2, y); y += height; }; const addSectionTitle = (title) => { checkPageBreak(12); doc.setFontSize(12); doc.setFont(undefined, 'bold'); doc.setTextColor(darkGray); doc.text(title, margin, y); y += 5; doc.setDrawColor(cyanColor); doc.setLineWidth(0.2); doc.line(margin, y, pageW-margin, y); y += 8; }; // --- Build PDF --- addHeader(); addSectionTitle('INTRODUCTION'); addScriptLine('MUSIC', 'Intro music fades in and then fades to background.'); addScriptLine(data.hostName.toUpperCase(), data.introHook); addScriptLine(data.hostName.toUpperCase(), data.introDetails); data.segments.forEach((seg, i) => { addSectionTitle(`SEGMENT ${i+1}: ${seg.title.toUpperCase()}`); addScriptLine('SFX', 'Transition sound effect.'); addScriptLine(data.hostName.toUpperCase(), seg.points); }); addSectionTitle('OUTRO'); addScriptLine('SFX', 'Transition sound effect.'); addScriptLine(data.hostName.toUpperCase(), data.outroRecap); addScriptLine(data.hostName.toUpperCase(), data.outroCta); addScriptLine('MUSIC', 'Outro music fades in and plays to end.'); doc.save(`${data.podcastTitle.replace(/\s+/g, '-')}-Ep${data.episodeNumber}-Script.pdf`); }); // Initialize updateTabUI(0); addSegment(); // Start with one segment lucide.createIcons(); });
Scroll to Top