Editor
Type Markdown here. Shortcuts: Ctrl+B for bold, Ctrl+I for italic, Ctrl+L for links
Preview
${htmlContent} `], { type: 'text/html' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = 'exported-markdown.html'; a.click(); URL.revokeObjectURL(url); } } catch (err) { showMessage('Failed to copy HTML: ' + err.message, true); } document.body.removeChild(tempTextarea); }); // Help button helpBtn.addEventListener('click', function() { markdownEditor.value = initialContent; updatePreview(); showMessage('Help content loaded'); }); // Expand editor/preview expandEditorBtn.addEventListener('click', function() { if (previewContainer.classList.contains('collapsed')) { // If preview is already collapsed, reset both editorContainer.classList.remove('expanded'); previewContainer.classList.remove('collapsed'); expandEditorBtn.textContent = '⬅️'; } else { // Expand editor, collapse preview editorContainer.classList.add('expanded'); previewContainer.classList.add('collapsed'); expandEditorBtn.textContent = '➡️'; } }); expandPreviewBtn.addEventListener('click', function() { if (editorContainer.classList.contains('collapsed')) { // If editor is already collapsed, reset both previewContainer.classList.remove('expanded'); editorContainer.classList.remove('collapsed'); expandPreviewBtn.textContent = '➡️'; } else { // Expand preview, collapse editor previewContainer.classList.add('expanded'); editorContainer.classList.add('collapsed'); expandPreviewBtn.textContent = '⬅️'; } }); // Show message function function showMessage(text, isError = false) { messageElement.textContent = text; messageElement.classList.remove('error'); if (isError) { messageElement.classList.add('error'); } messageElement.classList.add('show'); // Hide message after 3 seconds setTimeout(function() { messageElement.classList.remove('show'); }, 3000); } // Auto-save every 30 seconds setInterval(function() { localStorage.setItem('markdown-content', markdownEditor.value); }, 30000); // Handle tab key in editor (insert tab instead of changing focus) markdownEditor.addEventListener('keydown', function(e) { if (e.key === 'Tab') { e.preventDefault(); const start = this.selectionStart; const end = this.selectionEnd; // Insert tab at cursor position or at the beginning of each line in selection if (start === end) { // No selection, just insert tab this.value = this.value.substring(0, start) + ' ' + this.value.substring(end); this.selectionStart = this.selectionEnd = start + 2; } else { // For selections, handle multi-line tab const selectedText = this.value.substring(start, end); const lines = selectedText.split('\n'); if (e.shiftKey) { // Shift+Tab: remove indentation const modifiedLines = lines.map(line => { if (line.startsWith(' ')) { return line.substring(2); } else if (line.startsWith(' ')) { return line.substring(1); } return line; }); const modifiedText = modifiedLines.join('\n'); this.value = this.value.substring(0, start) + modifiedText + this.value.substring(end); this.selectionStart = start; this.selectionEnd = start + modifiedText.length; } else { // Tab: add indentation const modifiedText = lines.map(line => ' ' + line).join('\n'); this.value = this.value.substring(0, start) + modifiedText + this.value.substring(end); this.selectionStart = start; this.selectionEnd = start + modifiedText.length; } } // Update preview updatePreview(); } }); }); Markdown Editor
Editor
Preview
Document saved successfully!
${sanitizedHtml} `; // Create download link const blob = new Blob([fullHtml], { type: 'text/html' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = `${title.toLowerCase().replace(/\s+/g, '-')}.html`; document.body.appendChild(a); a.click(); // Clean up setTimeout(() => { document.body.removeChild(a); URL.revokeObjectURL(url); }, 100); showToast('Document exported as HTML'); } // Handle new document creation function handleNewDocument() { if (isDocChanged) { const confirmNew = confirm('You have unsaved changes. Create a new document anyway?'); if (!confirmNew) return; } // Generate a unique ID const newId = 'doc_' + Date.now(); currentDocId = newId; // Clear editor editor.value = '# New Document\n\nStart writing here...'; renderMarkdown(); // Save the new document saveDocument(newId, 'New Document', editor.value); isDocChanged = false; showToast('New document created'); } // Handle help button click function handleHelp() { cheatsheetModal.style.display = 'block'; } // Handle modal close function handleCloseModal() { cheatsheetModal.style.display = 'none'; } // Also close modal if user clicks outside of it window.addEventListener('click', (e) => { if (e.target === cheatsheetModal) { cheatsheetModal.style.display = 'none'; } }); // Handle insert image button function handleInsertImage() { const imageUrl = prompt('Enter image URL:'); if (imageUrl) { const altText = prompt('Enter alt text (description):', ''); const imageMarkdown = `![${altText}](${imageUrl})`; insertAtCursor(imageMarkdown); } } // Handle insert link button function handleInsertLink() { const linkUrl = prompt('Enter URL:'); if (linkUrl) { const linkText = prompt('Enter link text:', 'Link text'); const linkMarkdown = `[${linkText}](${linkUrl})`; insertAtCursor(linkMarkdown); } } // Insert text at cursor position function insertAtCursor(text) { const cursorPos = editor.selectionStart; const textBefore = editor.value.substring(0, cursorPos); const textAfter = editor.value.substring(editor.selectionEnd); editor.value = textBefore + text + textAfter; editor.selectionStart = cursorPos + text.length; editor.selectionEnd = cursorPos + text.length; editor.focus(); renderMarkdown(); isDocChanged = true; } // Show toast notification function showToast(message) { toastMessage.textContent = message; toast.classList.add('show'); setTimeout(() => { toast.classList.remove('show'); }, 3000); } // Initialize the application init(); });