Skip to content

blueberrycongee/codemirror-live-markdown

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

95 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

codemirror-live-markdown

npm version npm downloads CI License: MIT

Obsidian-style Live Preview for CodeMirror 6 โ€” A modular plugin collection that hides Markdown syntax when you're not editing it.

English | ็ฎ€ไฝ“ไธญๆ–‡

Live Demo ยท Documentation ยท Roadmap


Why This Library?

Most Markdown editors force you to choose: either see raw syntax or rendered output. Live Preview gives you both โ€” syntax fades in only when your cursor enters, letting you edit naturally while seeing formatted results.

Key differentiators:

  • Modular โ€” Import only what you need (math? tables? code blocks?)
  • Zero lock-in โ€” Works with any CodeMirror 6 setup
  • Lightweight โ€” No heavy dependencies forced on you

Features

Feature Description Since
โœจ Live Preview Hide markers when not editing v0.1.0
๐Ÿ“ Inline Formatting Bold, italic, strikethrough, inline code v0.1.0
๐Ÿ“‘ Block Elements Headers, lists, blockquotes v0.1.0
๐Ÿงฎ Math KaTeX rendering (inline & block) v0.2.0
๐Ÿ“Š Tables GFM table rendering v0.3.0
๐Ÿ’ป Code Blocks Syntax highlighting via lowlight v0.4.0
๐Ÿ–ผ๏ธ Images Image preview with loading states v0.5.0
๐Ÿ”— Links Clickable link rendering v0.5.0
๐Ÿงฉ Editable Tables (Advanced) Optional table editor with inline cells + source toggle v0.5.1

Installation

npm install codemirror-live-markdown

Peer dependencies:

npm install @codemirror/state @codemirror/view @codemirror/lang-markdown @codemirror/language @lezer/markdown

Optional dependencies (install only what you need):

npm install katex      # For math formulas
npm install lowlight   # For code syntax highlighting

Quick Start

import { EditorState } from '@codemirror/state';
import { EditorView } from '@codemirror/view';
import { markdown } from '@codemirror/lang-markdown';
import {
  livePreviewPlugin,
  markdownStylePlugin,
  editorTheme,
  mouseSelectingField,
  collapseOnSelectionFacet,
  setMouseSelecting,
} from 'codemirror-live-markdown';

const view = new EditorView({
  state: EditorState.create({
    doc: '# Hello World\n\nThis is **bold** and *italic* text.',
    extensions: [
      markdown(),
      collapseOnSelectionFacet.of(true),
      mouseSelectingField,
      livePreviewPlugin,
      markdownStylePlugin,
      editorTheme,
    ],
  }),
  parent: document.getElementById('editor')!,
});

// Required: Track mouse selection state
view.contentDOM.addEventListener('mousedown', () => {
  view.dispatch({ effects: setMouseSelecting.of(true) });
});
document.addEventListener('mouseup', () => {
  requestAnimationFrame(() => {
    view.dispatch({ effects: setMouseSelecting.of(false) });
  });
});

Documentation

Adding Optional Features

Each feature is a separate plugin. Import and add only what you need:

import { Table } from '@lezer/markdown';
import {
  mathPlugin,
  blockMathField,
  tableField,
  tableEditorPlugin,
  codeBlockField,
  codeBlockEditorPlugin,
  imageField,
  linkPlugin,
} from 'codemirror-live-markdown';

const extensions = [
  markdown({ extensions: [Table] }), // Enable GFM tables in parser
  // ... core extensions from Quick Start
  
  // Optional features:
  mathPlugin,                        // Inline math: `$E=mc^2$`
  blockMathField,                    // Block math: ```math
  tableField,                        // GFM tables
  tableEditorPlugin(),               // Editable tables with source toggle
  codeBlockField({ copyButton: true }), // Code blocks with syntax highlighting
  codeBlockEditorPlugin({ copyButton: true }), // Code blocks with MD/Code toggle
  imageField(),                      // Image preview
  linkPlugin(),                      // Link rendering
];

Code Block Options

codeBlockField({
  lineNumbers: false,      // Show line numbers
  copyButton: true,        // Show copy button
  defaultLanguage: 'text', // Fallback language
  interaction: 'auto',     // 'auto' | 'toggle'
})
  • interaction: 'auto' (default): enter source mode when cursor enters code block.
  • interaction: 'toggle': keep rendered mode by default and switch with MD / Code buttons.

Code Block Editor Plugin

codeBlockEditorPlugin({
  copyButton: true,
  lineNumbers: false,
  defaultLanguage: 'text',
})

codeBlockEditorPlugin() is a non-breaking convenience API for codeBlockField({ interaction: 'toggle' }).

Registering Additional Languages

import { registerLanguage, initHighlighter } from 'codemirror-live-markdown';
import rust from 'highlight.js/lib/languages/rust';

// Initialize highlighter (required before first use)
await initHighlighter();

// Register additional languages
registerLanguage('rust', rust);

Theming

Customize with CSS variables:

:root {
  --md-heading: #1a1a1a;
  --md-bold: #1a1a1a;
  --md-italic: #1a1a1a;
  --md-link: #2563eb;
  --md-code-bg: #f5f5f5;
}

API Reference

Core Extensions

Export Description
livePreviewPlugin Main live preview behavior
markdownStylePlugin Styling for headers, bold, italic, etc.
editorTheme Default theme with animations
mouseSelectingField Tracks drag selection state
collapseOnSelectionFacet Enable/disable live preview

Feature Extensions

Export Description Requires
mathPlugin Inline math rendering katex
blockMathField Block math rendering katex
tableField Table rendering @lezer/markdown Table
tableEditorPlugin() Editable table rendering @lezer/markdown Table
codeBlockField(options?) Code block highlighting lowlight
codeBlockEditorPlugin(options?) Code block editable preview with MD/Code toggle lowlight
setCodeBlockSourceMode Toggle code block source mode via effect โ€”
imageField(options?) Image preview โ€”
linkPlugin(options?) Link rendering โ€”

Utilities

Export Description
shouldShowSource(state, from, to) Check if range should show source
renderMath(source, displayMode) Render LaTeX to HTML
highlightCode(code, lang?) Highlight code string
initHighlighter() Initialize syntax highlighter
isHighlighterAvailable() Check if highlighter is ready

Development

git clone https://github.com/blueberrycongee/codemirror-live-markdown.git
cd codemirror-live-markdown
npm install
npm run dev      # Watch mode
npm test         # Run tests
npm run build    # Production build

Run the demo:

cd demo
npm install
npm run dev

Contributing

Contributions are welcome! Please read our contributing guidelines before submitting a PR.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

License

MIT ยฉ blueberrycongee

Acknowledgments

About

Resources

License

Contributing

Stars

Watchers

Forks

Packages

 
 
 

Contributors