Skip to content

Plugin Overview

Generative DOM's plugin system is the mechanism through which all markdown syntax is implemented. The core engine is a plugin host -- it provides buffering, tokenization scheduling, rendering, and an object pool, but it does not know anything about markdown itself.

Plugin Registry

Plugins are registered during Generative DOM construction or dynamically via md.register(). The core maintains an ordered list of plugins sorted by priority.

During tokenization, the core iterates through plugins at each buffer position. The first plugin to return a non-null match wins, and its token is added to the AST. This priority-based dispatch is what allows plugins to override each other (for example, the highlight plugin at priority 95 can intercept code blocks before markdown-code at priority 100).

Priority System

RangePurposePlugins
0--99Custom syntax (matched first)events (40), interactive (45), custom-elements (50), highlight (95)
100--199Block-level markdownmarkdown-heading (100), markdown-code (100), markdown-quote (100), markdown-list (100)
200--299Inline markdownmarkdown-inline (200), markdown-link (200)
300+Fallbackmarkdown-base (300)

Lower numbers are tried first. When two plugins share a priority, registration order determines which is tried first.

Standard Plugins

These plugins implement the core markdown syntax:

  • markdown-base (300) -- Paragraphs, line breaks, escaping, horizontal rules. This is the fallback plugin; anything unmatched by other plugins becomes a paragraph.
  • markdown-inline (200) -- Bold, italic, strikethrough, inline code.
  • markdown-heading (100) -- ATX headings h1 through h6.
  • markdown-code (100) -- Fenced code blocks with optional language tags.
  • markdown-quote (100) -- Blockquotes, including nested.
  • markdown-list (100) -- Ordered and unordered lists, including nested.
  • markdown-link (200) -- Links, images, and autolinks.

Stress Test Plugins

These plugins demonstrate that the plugin system handles non-markdown syntax:

  • highlight (95) -- Syntax highlighting for fenced code blocks.
  • custom-elements (50) -- Custom Web Components parsed from the stream.
  • events (40) -- Invisible elements that emit events with no DOM output.
  • interactive (45) -- Interactive elements that preserve state across re-renders.

Plugin Anatomy

Every plugin is a factory function that returns an GenerativeDomPlugin object:

ts
export function myPlugin(options?: MyPluginOptions): GenerativeDomPlugin {
  return {
    name: 'my-plugin',
    priority: 150,

    init(ctx) {
      // One-time setup
    },

    matchBlock(buffer, pos) {
      // Return BlockMatch or null
    },

    render(token, ctx) {
      // Return HTMLElement, Text, or null
    },

    cleanup(element) {
      // Clean up before element is recycled
    },

    destroy() {
      // Release plugin-level resources
    },
  };
}

See Writing Plugins for a complete guide.