Standard Operating Procedure (SOP) Generator

SOP Generator

Create a professional Standard Operating Procedure document step-by-step.

${document.getElementById('sopPurpose').value.replace(/\n/g, '
') || 'Not specified.'}

2.0 Scope

${document.getElementById('sopScope').value.replace(/\n/g, '
') || 'Not specified.'}

3.0 Responsibilities

${parseTextToHtmlList(document.getElementById('sopResponsibilities').value, 'ul')}

4.0 Materials & Equipment

${parseTextToHtmlList(document.getElementById('sopMaterials').value, 'ul')}

5.0 Procedure

${parseTextToHtmlList(document.getElementById('sopProcedure').value, 'ol')} `; document.getElementById('output-display').innerHTML = outputHTML; document.getElementById('output-title').textContent = sopTitle; formContainer.style.display = 'none'; document.getElementById('tab-container').style.display = 'none'; navButtons.style.display = 'none'; outputSection.classList.remove('hidden'); } function downloadPDF() { const { jsPDF } = window.jspdf; if (!downloadBtn) return; downloadBtn.textContent = 'Generating Document...'; downloadBtn.disabled = true; try { const sopTitle = document.getElementById('sopTitle').value || 'Untitled SOP'; const doc = new jsPDF({ orientation: 'p', unit: 'mm', format: 'a4' }); const margin = 20; const pageWidth = doc.internal.pageSize.getWidth(); const pageHeight = doc.internal.pageSize.getHeight(); const effectiveDate = new Date().toLocaleDateString('en-US'); const docId = `SOP-${Date.now().toString().slice(-6)}`; let yPos = 0; let pageNum = 1; const addHeader = () => { doc.setFont('Helvetica', 'bold'); doc.setFontSize(16); doc.text(sopTitle, pageWidth / 2, margin, { align: 'center' }); doc.setFontSize(9); doc.setFont('Helvetica', 'normal'); doc.text(`Document ID: ${docId}`, margin, margin + 10); doc.text(`Version: 1.0`, margin, margin + 14); doc.text(`Effective Date: ${effectiveDate}`, margin, margin + 18); doc.setDrawColor(150); doc.line(margin, margin + 22, pageWidth - margin, margin + 22); yPos = margin + 30; }; const addFooter = () => { doc.setFont('Helvetica', 'normal'); doc.setFontSize(9); doc.text(`Page ${pageNum}`, pageWidth / 2, pageHeight - 10, { align: 'center' }); }; const checkPageBreak = (heightNeeded) => { if (yPos + heightNeeded > pageHeight - 15) { addFooter(); doc.addPage(); pageNum++; addHeader(); addFooter(); } }; const addSection = (title, content, isOrderedList = false) => { const lines = doc.splitTextToSize(content.replace(/^\d+\.\s*/gm, ''), pageWidth - margin * 2 - (isOrderedList ? 5 : 0)); checkPageBreak(12 + lines.length * 5); doc.setFont('Helvetica', 'bold'); doc.setFontSize(12); doc.text(title, margin, yPos); yPos += 7; doc.setFont('Helvetica', 'normal'); doc.setFontSize(10); if (isOrderedList) { const items = content.split('\n').filter(line => line.trim() !== ''); items.forEach((item, index) => { const itemLines = doc.splitTextToSize(item.trim().replace(/^\d+\.\s*/, ''), pageWidth - margin * 2 - 8); checkPageBreak(itemLines.length * 5 + 2); doc.text(`${index + 1}.`, margin, yPos); doc.text(itemLines, margin + 8, yPos); yPos += itemLines.length * 5 + 2; }); } else if (content.includes('\n')) { // Unordered list const items = content.split('\n').filter(line => line.trim() !== ''); items.forEach(item => { const itemLines = doc.splitTextToSize(item.trim(), pageWidth - margin * 2 - 8); checkPageBreak(itemLines.length * 5 + 2); doc.text(`•`, margin + 3, yPos); doc.text(itemLines, margin + 8, yPos); yPos += itemLines.length * 5 + 2; }); } else { // Paragraph doc.text(lines, margin, yPos); yPos += lines.length * 5 + 5; } }; addHeader(); addSection('1.0 Purpose', document.getElementById('sopPurpose').value || 'Not specified.'); addSection('2.0 Scope', document.getElementById('sopScope').value || 'Not specified.'); addSection('3.0 Responsibilities', document.getElementById('sopResponsibilities').value || 'Not specified.'); addSection('4.0 Materials & Equipment', document.getElementById('sopMaterials').value || 'Not specified.'); addSection('5.0 Procedure', document.getElementById('sopProcedure').value || 'Not specified.', true); addFooter(); doc.save(`SOP_${sopTitle.replace(/\s/g, '_')}.pdf`); } catch (error) { console.error("Error generating PDF:", error); alert("An error occurred while generating the PDF. Please try again."); } finally { downloadBtn.textContent = 'Download as Official SOP (PDF)'; downloadBtn.disabled = false; } } showTab(currentTab); });
Scroll to Top