M Markdown Editor FREE

MarkdownLn 1, Col 1
Preview

Table of Contents

Words: 0 Characters: 0 Lines: 0 Headings: 0 Reading: 0s
`; } function exportHTML(){ const html=generateFullHTML(); document.getElementById('export-code').textContent=html; document.getElementById('export-modal').classList.add('show'); } function closeModal(){document.getElementById('export-modal').classList.remove('show')} function copyExport(){ navigator.clipboard.writeText(generateFullHTML()).then(()=>showToast('HTML copied!')); closeModal(); } function copyHTML(){ navigator.clipboard.writeText(markdownToHtml(editor.value)).then(()=>showToast('HTML copied!')); } function downloadHTML(){ const blob=new Blob([generateFullHTML()],{type:'text/html'}); const a=document.createElement('a'); a.href=URL.createObjectURL(blob); a.download='document.html'; a.click(); URL.revokeObjectURL(a.href); closeModal(); showToast('Downloaded!'); } // === Toast === function showToast(msg){ const t=document.getElementById('toast');t.textContent=msg;t.classList.add('show'); setTimeout(()=>t.classList.remove('show'),2000); } // === Keyboard shortcuts === editor.addEventListener('keydown',e=>{ if((e.ctrlKey||e.metaKey)&&e.key==='b'){e.preventDefault();insertMd('**','**')} if((e.ctrlKey||e.metaKey)&&e.key==='i'){e.preventDefault();insertMd('*','*')} if((e.ctrlKey||e.metaKey)&&e.key==='k'){e.preventDefault();insertMd('[','](url)')} if(e.key==='Tab'){ e.preventDefault(); const s=editor.selectionStart; editor.setRangeText(' ',s,s,'end'); render(); } }); // === Cursor position === editor.addEventListener('click',updateCursor); editor.addEventListener('keyup',updateCursor); function updateCursor(){ const v=editor.value.substring(0,editor.selectionStart); const ln=v.split('\n').length; const col=editor.selectionStart-v.lastIndexOf('\n'); document.getElementById('cursor-pos').textContent=`Ln ${ln}, Col ${col}`; } // === Resizable divider === const divider=document.getElementById('divider'); let isDragging=false; divider.addEventListener('mousedown',()=>{isDragging=true;document.body.style.cursor='col-resize';document.body.style.userSelect='none'}); document.addEventListener('mousemove',e=>{ if(!isDragging)return; const main=document.getElementById('main'); const rect=main.getBoundingClientRect(); const pct=((e.clientX-rect.left)/rect.width)*100; const ep=document.getElementById('editor-pane'); const pp=document.getElementById('preview-pane'); ep.style.flex=`0 0 ${Math.max(20,Math.min(80,pct))}%`; pp.style.flex='1'; }); document.addEventListener('mouseup',()=>{if(isDragging){isDragging=false;document.body.style.cursor='';document.body.style.userSelect=''}}); // === Init === const defaultMd=`# Welcome to Markdown Editor A **free online Markdown editor** with live preview, word count, and HTML export. ## Features - **Live preview** — see changes in real time - **Toolbar** — quick formatting shortcuts - **Keyboard shortcuts** — Ctrl+B (bold), Ctrl+I (italic), Ctrl+K (link) - **Export** — download as HTML file - **Table of Contents** — auto-generated from headings - **Statistics** — word count, characters, reading time - **Dark theme** — easy on the eyes ## Markdown Cheatsheet ### Text Formatting This is **bold**, this is *italic*, and this is ~~strikethrough~~. Inline \`code\` looks like this. ### Code Block \`\`\`javascript function greet(name) { return \`Hello, \${name}!\`; } console.log(greet('World')); \`\`\` ### Lists - Unordered item 1 - Unordered item 2 - Nested item 1. Ordered item 1 2. Ordered item 2 ### Task List - [x] Write Markdown parser - [x] Add live preview - [ ] Conquer the world ### Blockquote > "The best way to predict the future is to invent it." > — Alan Kay ### Table | Feature | Status | |---------|--------| | Live Preview | Done | | Export HTML | Done | | Word Count | Done | | TOC | Done | ### Horizontal Rule --- ### Links & Images Visit [Tool Factory](https://tool-factory-prod.web.app) for more developer tools. --- *Built with Tool Factory — Free Developer Tools* `; // Load saved or default const saved=localStorage.getItem('md-editor-content'); editor.value=saved||defaultMd; render(); editor.addEventListener('input',render);