Skip to content

Latest commit

 

History

History
254 lines (185 loc) · 7.63 KB

File metadata and controls

254 lines (185 loc) · 7.63 KB

Design Documentation

Overview

The Markdown Viewer is designed as a lightweight, zero-dependency, single-file web application that provides a fast and elegant way to view markdown files in the browser. This document outlines the architectural decisions, design patterns, and implementation details.

Core Design Principles

1. Simplicity First

  • Single file architecture: Everything contained in one HTML file
  • No build process: Direct browser execution
  • Zero dependencies: No external libraries or frameworks
  • Minimal footprint: ~400 lines of code total

2. Performance

  • Client-side only: No server requests after initial load
  • Efficient parsing: Single-pass markdown parsing where possible
  • Minimal DOM manipulation: Batch updates and innerHTML for rendering
  • Lazy evaluation: Process only when file is loaded

3. User Experience

  • Instant feedback: Immediate rendering after file selection
  • Multiple input methods: Button click and drag-and-drop
  • Theme persistence: Remember user preferences
  • Responsive design: Works on all screen sizes

Architecture

Component Structure

index.html
├── HTML Structure
│   ├── Toolbar (file input, theme toggle)
│   ├── Drop Zone (drag-and-drop area)
│   └── Content Area (rendered markdown)
├── CSS Styles
│   ├── Base styles
│   ├── Light theme
│   ├── Dark theme
│   └── Markdown-specific styles
└── JavaScript
    ├── MarkdownParser class
    ├── File handling
    ├── Theme management
    └── Event handlers

MarkdownParser Class

The custom markdown parser is the heart of the application:

Design Decisions

  1. Class-based architecture: Encapsulates parsing logic and state
  2. CommonMark compliance: Follows the CommonMark specification
  3. Regex-based parsing: Fast pattern matching for inline elements
  4. Line-by-line processing: Efficient for streaming and large files
  5. Context tracking: Maintains state for multi-line constructs

Parsing Strategy

Parse Flow:
1. Split input into lines
2. For each line:
   a. Check for code blocks (toggle state)
   b. Check for block elements (headers, lists, tables)
   c. Apply inline transformations
   d. Generate HTML output
3. Close any open contexts
4. Return complete HTML

Key Components

  • Inline patterns array: Ordered list of regex patterns for inline elements
  • State management: Tracks code blocks, lists, tables, blockquotes
  • HTML escaping: Prevents XSS attacks via content
  • Nested structure support: Handles complex markdown constructs

Styling Architecture

Dual Theme System

Light Theme (default):
├── Base colors from system fonts
├── High contrast for readability
└── GitHub-inspired markdown styles

Dark Theme:
├── Inverted color scheme
├── Reduced eye strain colors
└── Preserved syntax highlighting contrast

CSS Organization

  1. Reset and base styles: Consistent cross-browser rendering
  2. Component styles: Toolbar, buttons, drop zone
  3. Markdown content styles: Typography, spacing, elements
  4. Dark mode overrides: Complete theme using CSS classes
  5. Responsive rules: Mobile-first approach

File Handling

Input Methods

  1. File Input Element: Traditional file selection

    • Hidden input element
    • Triggered by styled button
    • Accepts .md, .markdown, .txt
  2. Drag and Drop API: Modern file handling

    • Full page drop zone
    • Visual feedback on drag
    • Prevents default browser behavior

Processing Pipeline

File Input → FileReader API → Text Content → Parser → HTML → DOM

Theme Management

  • localStorage API: Persists user preference
  • System preference detection: Respects OS dark mode
  • Instant switching: No page reload required
  • Icon feedback: Visual indicator of current theme

Technical Decisions

Why Single File?

  1. Portability: Easy to share and deploy
  2. Offline capability: Works without internet
  3. Security: No external requests or dependencies
  4. Simplicity: No build tools or package management

Why Custom Parser?

  1. Size constraints: Existing libraries too large
  2. Feature control: Only what we need
  3. Learning opportunity: Understanding markdown internals
  4. Performance tuning: Optimized for our use case

Why No Framework?

  1. Vanilla JS is sufficient: Modern browsers have everything needed
  2. Performance: No framework overhead
  3. Size: Keeps file small and fast
  4. Compatibility: Works everywhere ES6 is supported

Performance Optimizations

Parsing Optimizations

  • Single-pass parsing: Most elements processed in one iteration
  • Regex compilation: Patterns defined once and reused
  • Early returns: Skip unnecessary processing
  • String concatenation: Building HTML as strings before DOM insertion

Rendering Optimizations

  • Batch DOM updates: Single innerHTML assignment
  • CSS containment: Styles scoped to content area
  • Efficient selectors: ID-based element access
  • Event delegation: Single event listener for drag-and-drop

Memory Management

  • No memory leaks: Proper event listener cleanup
  • Efficient string handling: Avoid unnecessary copies
  • Garbage collection friendly: Clear references when done

Security Considerations

XSS Prevention

  • Content escaping: All user content HTML-escaped
  • No eval() usage: No dynamic code execution
  • Safe innerHTML: Only for generated trusted HTML
  • Content Security Policy: Compatible with strict CSP

Input Validation

  • File type checking: Only accept markdown extensions
  • Size limitations: Handled by browser file API
  • Malformed markdown: Parser handles gracefully

Browser Compatibility

Required Features

  • ES6 Support: Classes, arrow functions, template literals
  • FileReader API: For reading local files
  • localStorage: For theme persistence
  • Drag and Drop API: For file dropping
  • CSS Grid/Flexbox: For layout

Fallback Strategies

  • Theme detection: Falls back to light theme
  • File input: Works even without drag-and-drop
  • localStorage: Graceful handling if unavailable

Future Considerations

Potential Enhancements

  1. Extended markdown syntax: GitHub Flavored Markdown
  2. Export functionality: Save as HTML/PDF
  3. Syntax highlighting: For code blocks
  4. Math rendering: LaTeX support
  5. Mermaid diagrams: Diagram rendering

Architecture Evolution

  • Web Components: Encapsulate functionality
  • Service Worker: Offline PWA capabilities
  • WebAssembly: High-performance parsing
  • Streaming parser: Handle very large files

Maintaining Simplicity

Any future enhancements should:

  1. Remain optional
  2. Not break single-file architecture
  3. Maintain zero-dependency goal
  4. Keep core functionality fast

Testing Strategy

Manual Testing

  1. Feature testing: Each markdown element
  2. Edge cases: Empty files, special characters
  3. Browser testing: Cross-browser compatibility
  4. Performance testing: Large file handling
  5. Accessibility testing: Keyboard navigation, screen readers

Test Cases

  • Various markdown documents
  • Edge cases and malformed content
  • Large files (>5MB)
  • Different character encodings
  • Mobile device testing

Conclusion

The Markdown Viewer demonstrates that modern web applications can be simple, fast, and feature-complete without complex build processes or dependencies. The architecture prioritizes user experience while maintaining code simplicity and performance.