Project 3: Markdown Blog Engine
50 min read
Markdown ParsingSynchronized ScrollingIndexedDBFile ExportSyntax HighlightingRegex
📋 Project Brief
Build a real-time Markdown editor with a dual-pane interface that transforms raw Markdown into beautifully rendered, semantic HTML. This project explores string parsing, regex, synchronized scroll behavior, and client-side file management. The editor must feel as responsive as VS Code — every keystroke should instantly reflect in the preview pane.
🎯 Learning Objectives
- Parse and transform Markdown syntax into semantic HTML
- Implement mathematically synchronized scrolling between two panes
- Build a robust auto-save system using IndexedDB for crash recovery
- Generate downloadable files (.md, .html, .pdf) from client-side data
- Integrate syntax highlighting for fenced code blocks
✅ Feature Requirements
Feature 1: Dual-Pane Synchronized Scroll
Acceptance Criteria:
- Left pane: raw Markdown editor (monospace font, line numbers optional)
- Right pane: rendered HTML preview with proper typography
- Scrolling one pane must proportionally scroll the other
- The sync must account for content height differences (Markdown is shorter than rendered HTML)
- A toggle to disable sync-scroll for users who find it distracting
- No scroll jitter or infinite scroll loops between the two panes
Feature 2: Code Syntax Highlighting
Acceptance Criteria:
- Fenced code blocks (```language) must render with syntax-highlighted colors
- Support at least: JavaScript, Python, HTML, CSS, TypeScript, JSON, Bash
- The highlighting theme must match the editor's light/dark mode
- Code blocks must have a "Copy" button that copies the raw code to clipboard
Feature 3: Export Engine
Acceptance Criteria:
- Export as .md: Downloads the raw Markdown text as a file
- Export as .html: Downloads a standalone HTML file with embedded styles
- Export as .pdf: Uses the browser's print-to-PDF or a library to generate a PDF
- All exports must use the
BlobAPI andURL.createObjectURL - The filename should default to the first heading or "untitled"
Feature 4: Auto-Save to IndexedDB
Acceptance Criteria:
- Every 5 seconds of inactivity (debounced), save the current content to IndexedDB
- On page load, check for a saved draft and offer to restore it
- Show a "Last saved: X seconds ago" indicator in the footer
- Support multiple documents (a simple sidebar listing saved drafts)
- Implement a "Delete Draft" action with confirmation
Feature 5: Emoji Shortcuts
Acceptance Criteria:
- Typing
:smile:in the editor converts to 😄 in the preview - Support at least 50 common emoji codes
- As the user types
:, show an autocomplete dropdown with matching emoji - Pressing Enter or Tab inserts the selected emoji into the editor
📊 Performance Benchmarks
| Metric | Target |
|---|---|
| Keystroke-to-preview latency | < 50ms |
| Parsing a 10,000-line document | < 200ms |
| Scroll sync accuracy | Within 5% of expected position |
| IndexedDB save operation | < 100ms |
🏗️ Suggested File Structure
| File / Folder | Purpose |
|---|---|
src/components/Editor/ | The Markdown text input area |
src/components/Preview/ | The rendered HTML output pane |
src/components/Toolbar/ | Formatting buttons (Bold, Italic, Link, etc.) |
src/services/markdownParser.js | Markdown-to-HTML transformation logic |
src/services/storageService.js | IndexedDB CRUD operations |
src/utils/emojiMap.js | Shortcode-to-emoji lookup table |
🧪 Testing Checklist
- Unit test Markdown parsing: headings, bold, italic, links, images, code blocks, tables
- Unit test emoji shortcode replacement
- Integration test: typing in editor updates preview in real-time
- Integration test: exporting a document produces a valid file
- A11y: editor must be usable with keyboard only
🚀 Stretch Goals
- Add a "Focus Mode" that dims everything except the current paragraph
- Implement a word count and reading time estimator
- Add collaborative editing using Y.js or CRDTs
- Support Mermaid diagram rendering inside Markdown