Political Speech Template Generator
Step 1: Define the Speech Framework
Step 2: Enter Your Core Content
Step 3: Your Generated Speech Template
This is our moment. This is our choice. Let's choose a brighter future, together. Thank you, God bless you, and God bless the United States of America.
`; pdfText += `Closing\n- Deliver a powerful, unifying closing statement.\n- Thank the audience.\n- God bless America.`; speechOutput.innerHTML = speechHtml; lastGeneratedText = pdfText; // Store clean text for PDF } /** * Generates and triggers a download for a PDF of the result. (Spec II.C) */ function pstg_downloadPdf() { if (!lastGeneratedText) { alert("Please generate a speech first by navigating to the final tab."); return; } if (typeof jspdf === 'undefined') { alert('Error: PDF library could not be loaded. Please refresh the page.'); return; } const { jsPDF } = window.jspdf; const doc = new jsPDF(); const audience = pstg_getValue("pstg-audience"); const typeSelect = document.getElementById("pstg-speech-type"); const speechTypeName = typeSelect ? typeSelect.options[typeSelect.selectedIndex].text : "Speech"; // PDF Content & Formatting (Spec II.C.2, II.C.3) doc.setFontSize(18); doc.setTextColor('#003366'); // Consistent color doc.text(`${speechTypeName} Template`, 105, 20, { align: 'center' }); doc.setFontSize(11); doc.setTextColor('#212529'); doc.text(`For Audience: ${audience || 'General'}`, 20, 30); // Use splitTextToSize to handle wrapping for the main content const textLines = doc.splitTextToSize(lastGeneratedText, 170); // 170mm width doc.text(textLines, 20, 45); // Save the PDF (Spec II.C.4) doc.save("Political-Speech-Template.pdf"); } // --- Tab Navigation Logic (Global Scope for onclick) --- window.pstg_openTab = function (evt, tabName) { const container = document.getElementById("pstg-container"); if (!container) return; const tabcontent = container.getElementsByClassName("pstg-tab-content"); for (let i = 0; i < tabcontent.length; i++) { tabcontent[i].style.display = "none"; tabcontent[i].classList.remove("pstg-active"); } const tablinks = container.getElementsByClassName("pstg-tab-link"); for (let i = 0; i < tablinks.length; i++) { tablinks[i].classList.remove("pstg-active"); } const activeTab = document.getElementById(tabName); if (activeTab) { activeTab.style.display = "block"; activeTab.classList.add("pstg-active"); } if (evt && evt.currentTarget) { evt.currentTarget.classList.add("pstg-active"); } // Generate speech when navigating to the final tab (Spec II.B.4) if (tabName === 'pstg-tab-3') { pstg_generateSpeech(); } }; window.pstg_navTab = function (direction) { const container = document.getElementById("pstg-container"); if (!container) return; const tabs = container.querySelectorAll(".pstg-tab-link"); let currentIndex = -1; for (let i = 0; i < tabs.length; i++) { if (tabs[i].classList.contains("pstg-active")) { currentIndex = i; break; } } if (currentIndex === -1) return; let newIndex = currentIndex + direction; if (newIndex >= tabs.length || newIndex < 0) { return; // Don't loop } // Simulate click (this will also trigger generation on tab 3) tabs[newIndex].click(); }; // --- Initializer --- // Attach listener to PDF button const pdfBtn = document.getElementById("pstg-download-pdf"); if(pdfBtn) { pdfBtn.addEventListener("click", pstg_downloadPdf); } else { console.error("Generator: PDF button not found."); } });