Online Grammar Rule Explanation Tool

Online Grammar Rule Explanation Tool

Enter a grammar rule or concept to get a detailed explanation.

${data.simpleExplanation.replace(/\n/g, '

')}

`; examplesContent.innerHTML = `
    ${data.examples.map(ex => `
  • ${ex}
  • `).join('')}
`; mistakesContent.innerHTML = `
    ${data.commonMistakes.map(m => `
  • ${m}
  • `).join('')}
`; // Show results and reset tabs resultsContainer.style.display = 'block'; setActiveTab(0); } function showError(message) { errorMessage.textContent = message; errorMessage.style.display = 'block'; resultsContainer.style.display = 'none'; } // --- Tab and Navigation Logic --- function setActiveTab(index) { // Guard clause if (index < 0 || index >= tabButtons.length) return; currentTabIndex = index; tabButtons.forEach((button, i) => { button.classList.toggle('active', i === index); }); tabPanes.forEach((pane, i) => { pane.classList.toggle('hidden', i !== index); }); // Update navigation button states prevBtn.disabled = index === 0; nextBtn.disabled = index === tabButtons.length - 1; } tabButtons.forEach((button, index) => { button.addEventListener('click', () => setActiveTab(index)); }); prevBtn.addEventListener('click', () => { if (currentTabIndex > 0) { setActiveTab(currentTabIndex - 1); } }); nextBtn.addEventListener('click', () => { if (currentTabIndex < tabButtons.length - 1) { setActiveTab(currentTabIndex + 1); } }); // --- PDF Generation Logic --- async function generatePdf() { // 1. Get all content from the UI const rule = ruleTitle.textContent; const explanationHTML = explanationContent.innerHTML; const examplesHTML = examplesContent.innerHTML; const mistakesHTML = mistakesContent.innerHTML; // 2. Format it nicely in the hidden PDF area pdfContentArea.innerHTML = `

${rule}

Simple Explanation

${explanationHTML}

Examples

${examplesHTML}

Common Mistakes

${mistakesHTML} `; // Temporarily show the element to allow html2canvas to render it pdfContentArea.style.display = 'block'; pdfContentArea.style.position = 'absolute'; pdfContentArea.style.left = '-9999px'; // Move it off-screen pdfContentArea.style.width = '800px'; // Set a fixed width for consistent rendering try { // 3. Use html2canvas to create an image of the content const canvas = await html2canvas(pdfContentArea, { scale: 2, // Increase scale for better quality useCORS: true }); const imgData = canvas.toDataURL('image/png'); // 4. Use jsPDF to create the PDF const { jsPDF } = window.jspdf; const pdf = new jsPDF({ orientation: 'portrait', unit: 'px', format: 'a4' }); const pdfWidth = pdf.internal.pageSize.getWidth(); const pdfHeight = pdf.internal.pageSize.getHeight(); const imgWidth = canvas.width; const imgHeight = canvas.height; const ratio = imgWidth / imgHeight; let finalImgWidth = pdfWidth - 40; // with some margin let finalImgHeight = finalImgWidth / ratio; // If the content is too long, split it across pages (simple split) let heightLeft = finalImgHeight; let position = 20; // top margin pdf.addImage(imgData, 'PNG', 20, position, finalImgWidth, finalImgHeight); heightLeft -= pdfHeight; while (heightLeft > 0) { position = position - pdfHeight + 40; // move to next page with margins pdf.addPage(); pdf.addImage(imgData, 'PNG', 20, position, finalImgWidth, finalImgHeight); heightLeft -= pdfHeight; } // 5. Trigger the download const filename = `Grammar-Rule-${rule.split('"')[1] || 'Explanation'}.pdf`.replace(/[^a-z0-9]/gi, '-').toLowerCase(); pdf.save(filename); } catch (error) { console.error("Failed to generate PDF:", error); alert("Sorry, there was an error creating the PDF file."); } finally { // Clean up by hiding the temporary area pdfContentArea.style.display = 'none'; pdfContentArea.innerHTML = ''; } } // --- Event Listeners --- getExplanationBtn.addEventListener('click', () => { const rule = grammarInput.value.trim(); if (rule) { fetchGrammarExplanation(rule); } else { showError("Please enter a grammar rule in the text box."); } }); // Allow pressing Enter to submit grammarInput.addEventListener('keypress', (event) => { if (event.key === 'Enter') { event.preventDefault(); // Prevent form submission if it's inside a form getExplanationBtn.click(); } }); downloadPdfBtn.addEventListener('click', generatePdf); // Pre-populate with a US-relevant example grammarInput.value = "The difference between its and it's"; });
Scroll to Top