Engineering Research Document Generator

Engineering Research Document Generator

Construct a formal technical document for your research and findings.

${tab.prompt}

`; if (tab.id === 'title') { contentHtml += ``; contentHtml += ``; contentHtml += ``; } else { contentHtml += ``; } contentHtml += `
`; tabContentContainer.innerHTML += `
${contentHtml}
`; }); updateNavButtons(); } window.showTab = (index) => { if (index >= tabsData.length) { showFinalReview(); return; } currentTab = index; pdfDownloadSection.classList.add('hidden'); document.querySelectorAll('[role="tab"]').forEach((button, i) => { button.className = button.className.replace('tab-active', 'tab-inactive'); button.setAttribute('aria-selected', 'false'); if (i === currentTab) { button.className = button.className.replace('tab-inactive', 'tab-active'); button.setAttribute('aria-selected', 'true'); } }); document.querySelectorAll('[role="tabpanel"]').forEach((panel, i) => { panel.classList.toggle('hidden', i !== currentTab); }); updateNavButtons(); }; function updateNavButtons() { if (!prevBtn || !nextBtn) return; prevBtn.disabled = currentTab === 0; nextBtn.textContent = currentTab === tabsData.length - 1 ? 'Finish & Review' : 'Next'; } function showFinalReview() { currentTab = tabsData.length; document.querySelectorAll('[role="tabpanel"]').forEach(p => p.classList.add('hidden')); prevBtn.disabled = false; nextBtn.classList.add('hidden'); let fullDocHtml = ''; const docTitle = document.getElementById('input-title')?.value || 'Untitled Document'; fullDocHtml += `

${docTitle}

`; tabsData.forEach(tab => { const textarea = document.getElementById(`textarea-${tab.id}`); if (textarea && textarea.value.trim() !== '') { fullDocHtml += `

${tab.title}

`; fullDocHtml += `

${textarea.value.trim().replace(/\n/g, '
')}

`; } }); docPreviewForPdf.innerHTML = fullDocHtml || '

Document is empty. Please fill out the sections.

'; pdfDownloadSection.classList.remove('hidden'); } function handleNavigation(direction) { const newTab = currentTab + direction; if (newTab >= 0 && newTab <= tabsData.length) { newTab === tabsData.length ? showFinalReview() : (nextBtn.classList.remove('hidden'), window.showTab(newTab)); } } window.handleAIAction = async (button, tabId) => { const textarea = document.getElementById(`textarea-${tabId}`); const aiOutputContainer = document.getElementById(`ai-output-${tabId}`); if (!textarea || !aiOutputContainer) return; const text = textarea.value.trim(); if (text.length < 30) { alert("Please provide at least 30 characters for a meaningful refinement."); return; } const buttonText = button.querySelector('.button-text'); const spinner = button.querySelector('.spinner'); button.disabled = true; buttonText.textContent = 'Analyzing...'; spinner.classList.remove('hidden'); try { const systemPrompt = `You are a senior engineering peer reviewer. Refine the following excerpt from a technical research document. Your goal is to improve technical clarity, precision, objectivity, and conciseness. Ensure the language is formal and appropriate for an engineering audience. Correct any grammatical errors or awkward phrasing, but preserve the core technical meaning. Respond only with the refined text.`; const refinedText = await callGeminiAPI(text, systemPrompt); aiOutputContainer.innerHTML = `

AI Suggestion:

${refinedText.replace(/\n/g, '
')}

`; setTimeout(() => aiOutputContainer.querySelector('.ai-suggestion-enter')?.classList.add('ai-suggestion-enter-active'), 10); } catch (error) { aiOutputContainer.innerHTML = `

Error: ${error.message}

`; } finally { button.disabled = false; buttonText.textContent = 'Refine for Technical Clarity'; spinner.classList.add('hidden'); } }; async function callGeminiAPI(text, systemPrompt) { const apiKey = ""; const apiUrl = `https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash-preview-05-20:generateContent?key=${apiKey}`; const payload = { contents: [{ parts: [{ text: text }] }], systemInstruction: { parts: [{ text: systemPrompt }] }, }; const response = await fetch(apiUrl, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload) }); if (!response.ok) throw new Error((await response.json()).error?.message || `API Error`); const result = await response.json(); const candidate = result.candidates?.[0]; if (candidate?.content?.parts?.[0]?.text) return candidate.content.parts[0].text; throw new Error("Invalid response from AI model."); } window.downloadPDF = function() { const { jsPDF } = window.jspdf; const doc = new jsPDF({ orientation: 'p', unit: 'mm', format: 'a4' }); const docTitle = document.getElementById('input-title')?.value.trim() || 'Untitled Engineering Document'; const authors = document.getElementById('input-authors')?.value.trim() || 'No author specified'; const abstract = document.getElementById(`textarea-title`)?.value.trim() || 'No abstract provided.'; const leftMargin = 20, topMargin = 25, contentWidth = doc.internal.pageSize.getWidth() - leftMargin * 2; const pageHeight = doc.internal.pageSize.getHeight(), bottomMargin = 20; const lineHeight = 7, headingFontSize = 14, bodyFontSize = 11, font = 'Helvetica'; let cursorY = 0; // --- Title Page --- doc.setFont(font, 'bold'); doc.setFontSize(18); const titleLines = doc.splitTextToSize(docTitle, contentWidth); cursorY = pageHeight / 4; doc.text(titleLines, doc.internal.pageSize.getWidth() / 2, cursorY, { align: 'center' }); cursorY += titleLines.length * 10; doc.setFont(font, 'normal'); doc.setFontSize(12); const authorLines = doc.splitTextToSize(authors, contentWidth); doc.text(authorLines, doc.internal.pageSize.getWidth() / 2, cursorY + 5, { align: 'center' }); cursorY += authorLines.length * 8; const date = new Date().toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' }); doc.text(date, doc.internal.pageSize.getWidth() / 2, cursorY + 5, { align: 'center' }); doc.setLineWidth(0.5); doc.line(leftMargin, cursorY + 15, leftMargin + contentWidth, cursorY + 15); cursorY += 25; doc.setFont(font, 'bold'); doc.setFontSize(headingFontSize); doc.text('Abstract', leftMargin, cursorY); cursorY += lineHeight; doc.setFont(font, 'normal'); doc.setFontSize(bodyFontSize); const abstractLines = doc.splitTextToSize(abstract, contentWidth); doc.text(abstractLines, leftMargin, cursorY); doc.addPage(); cursorY = topMargin; // --- Main Content --- const addHeader = (title) => { doc.setFontSize(9); doc.setFont(font, 'normal'); const truncatedTitle = title.substring(0, 60) + (title.length > 60 ? '...' : ''); doc.text(truncatedTitle, leftMargin, topMargin - 12); }; const addFooter = (pageNum) => { doc.setFontSize(10); doc.text(String(pageNum), doc.internal.pageSize.getWidth() - leftMargin, pageHeight - 10); }; const checkPageBreak = () => { if (cursorY + (lineHeight * 2) > pageHeight - bottomMargin) { addFooter(doc.internal.getNumberOfPages()); doc.addPage(); cursorY = topMargin; addHeader(docTitle); } }; addHeader(docTitle); tabsData.slice(1).forEach((tab, index) => { // Skip title/abstract tab const textarea = document.getElementById(`textarea-${tab.id}`); if (!textarea || textarea.value.trim() === '') return; checkPageBreak(); cursorY += lineHeight * 2; checkPageBreak(); doc.setFont(font, 'bold'); doc.setFontSize(headingFontSize); const sectionTitle = `${index + 1}. ${tab.title}`; doc.text(sectionTitle, leftMargin, cursorY); cursorY += lineHeight + 2; doc.setFont(font, 'normal'); doc.setFontSize(bodyFontSize); const bodyTextLines = doc.splitTextToSize(textarea.value.trim(), contentWidth); bodyTextLines.forEach(line => { checkPageBreak(); doc.text(line, leftMargin, cursorY); cursorY += lineHeight; }); }); addFooter(doc.internal.getNumberOfPages()); doc.save(docTitle.replace(/[^a-z0-9]/gi, '_').toLowerCase() + '.pdf'); } if (prevBtn && nextBtn && downloadPdfBtn) { prevBtn.addEventListener('click', () => handleNavigation(-1)); nextBtn.addEventListener('click', () => handleNavigation(1)); downloadPdfBtn.addEventListener('click', window.downloadPDF); } initializeUI(); });
Scroll to Top