Book Manuscript Editor
Get automated feedback on pacing, word choice, and common writing issues.
Editorial Report
0Readability
0Filler Words
0Adverbs
0Word Count
Annotated Manuscript
Hover over highlighted words for editorial suggestions.
Please enter some text to analyze.
'; return; } let fillerCount = 0; let adverbCount = 0; // 1. Analyze filler words for (const word in fillerWords) { const regex = new RegExp(`\\b${word}\\b`, 'gi'); const matches = text.match(regex); if (matches) { fillerCount += matches.length; text = text.replace(regex, `${word}`); } } // 2. Analyze adverbs (-ly words) const adverbRegex = /\b(\w+ly)\b/gi; const adverbMatches = text.match(adverbRegex); if (adverbMatches) { adverbCount = adverbMatches.length; text = text.replace(adverbRegex, (match) => `${match}`); } // 3. Analyze dialogue tags const dialogueRegex = /(["'])said\b/gi; text = text.replace(dialogueRegex, (match) => `${match}`); analysisOutput.innerHTML = text; // 4. Calculate metrics const words = textInput.value.trim().split(/\s+/); const wordCount = words.length; const sentences = textInput.value.match(/[^.?!]+[.?!]+(\s|$)/g) || []; const sentenceCount = sentences.length || 1; // Simple syllable counter (heuristic) const countSyllables = (word) => { word = word.toLowerCase(); if(word.length <= 3) return 1; word = word.replace(/(?:[^laeiouy]es|ed|[^laeiouy]e)$/, ''); word = word.replace(/^y/, ''); const matches = word.match(/[aeiouy]{1,2}/g); return matches ? matches.length : 0; }; const totalSyllables = words.map(countSyllables).reduce((a, b) => a + b, 0); // Flesch-Kincaid Readability Score const readability = 206.835 - 1.015 * (wordCount / sentenceCount) - 84.6 * (totalSyllables / wordCount); // Update UI readabilityScoreEl.textContent = Math.max(0, Math.round(readability)); fillerWordsCountEl.textContent = fillerCount; adverbsCountEl.textContent = adverbCount; wordCountEl.textContent = wordCount; outputSection.classList.remove('hidden'); }; const downloadPdf = () => { const { jsPDF } = window.jspdf; const doc = new jsPDF({ orientation: 'p', unit: 'mm', format: 'a4' }); const reportTitle = "Manuscript Editorial Report"; const genDate = new Date().toLocaleDateString('en-US'); const pageWidth = doc.internal.pageSize.getWidth(); const margin = 15; let yPos = 0; // --- PDF Template --- doc.setFillColor(22, 101, 52); // green-800 doc.rect(0, 0, pageWidth, 28, 'F'); doc.setFont('helvetica', 'bold'); doc.setFontSize(16); doc.setTextColor(255, 255, 255); doc.text(reportTitle, margin, 18); yPos = 40; // Summary Section doc.setFont('helvetica', 'bold'); doc.setFontSize(12); doc.setTextColor(30, 41, 59); doc.text("Editorial Summary", margin, yPos); yPos += 8; doc.autoTable({ startY: yPos, head: [['Metric', 'Result', 'Notes']], body: [ ['Readability Score', readabilityScoreEl.textContent, 'Score out of 100. Higher is easier to read.'], ['Filler Words Found', fillerWordsCountEl.textContent, 'Words that often weaken writing.'], ['Adverbs (-ly) Found', adverbsCountEl.textContent, 'Consider replacing with stronger verbs.'], ['Total Word Count', wordCountEl.textContent, ''], ], theme: 'grid', headStyles: { fillColor: [21, 128, 61] }, // green-700 margin: { left: margin, right: margin } }); yPos = doc.autoTable.previous.finalY + 15; // Annotated Manuscript doc.setFont('helvetica', 'bold'); doc.setFontSize(12); doc.setTextColor(30, 41, 59); doc.text("Annotated Manuscript", margin, yPos); yPos += 8; html2canvas(analysisOutput, { scale: 2, useCORS: true }).then(canvas => { const imgData = canvas.toDataURL('image/png'); const imgProps = doc.getImageProperties(imgData); const pdfWidth = pageWidth - (margin * 2); const pdfHeight = (imgProps.height * pdfWidth) / imgProps.width; if (yPos + pdfHeight > 280) { doc.addPage(); yPos = 20; } doc.addImage(imgData, 'PNG', margin, yPos, pdfWidth, pdfHeight); // Footer const pageCount = doc.internal.getNumberOfPages(); for(let i = 1; i <= pageCount; i++) { doc.setPage(i); const footerY = doc.internal.pageSize.getHeight() - 15; doc.setLineWidth(0.2); doc.setDrawColor(134, 239, 172); // green-300 doc.line(margin, footerY, pageWidth - margin, footerY); doc.setFontSize(8); doc.setTextColor(100, 116, 139); doc.text(`Report Generated on: ${genDate}`, margin, footerY + 8); doc.text(`Page ${i} of ${pageCount}`, pageWidth - margin, footerY + 8, { align: 'right' }); } doc.save(`Manuscript_Editorial_Report.pdf`); }).catch(err => { console.error("Error generating PDF:", err); alert("Could not generate PDF. See console for details."); }); }; // --- Event Listeners --- analyzeBtn.addEventListener('click', analyzeManuscript); downloadPdfBtn.addEventListener('click', downloadPdf); });