Skip to content
On this page

API Reference

Comprehensive guide to the Marzipan API, bundled actions, and plugin system.

Overview

Marzipan provides a simple yet powerful API for creating and managing markdown editors. The API is organized into three main parts:

  1. Marzipan Class - Core editor functionality
  2. Actions API - Zero-dependency formatting helpers
  3. Plugin System - Extensible plugin architecture

Quick Reference

Creating an Editor

ts
import { Marzipan } from '@pinkpixel/marzipan';

const [editor] = new Marzipan('#my-editor', {
  placeholder: 'Start typing...',
  toolbar: true,
  theme: 'cave',
  smartLists: true,
});

Using Actions

ts
import { actions } from '@pinkpixel/marzipan';

const textarea = document.querySelector('textarea');
actions.toggleBold(textarea);
actions.toggleItalic(textarea);
actions.insertLink(textarea);

Adding Plugins

ts
import { tablePlugin } from '@pinkpixel/marzipan/plugins/tablePlugin';
import { mermaidPlugin } from '@pinkpixel/marzipan/plugins/mermaidPlugin';

new Marzipan('#editor', {
  plugins: [tablePlugin(), mermaidPlugin()]
});

Core API

Constructor

new Marzipan(target, options)

Creates one or more Marzipan editor instances.

  • target (string | Element | NodeList | Array)
    • string - CSS selector (e.g., '#editor')
    • Element - Single DOM element
    • NodeList - Collection of elements
    • Array - Array of elements
  • options (Object) - Configuration options

Returns: Array<Marzipan> - Always returns an array

ts
// Single editor
const [editor] = new Marzipan('#editor');

// Multiple editors
const editors = new Marzipan('.markdown-editor');

// With options
const [editor] = new Marzipan('#editor', {
  fontSize: '16px',
  toolbar: true,
  showStats: true
});

Instance Methods

Content Management

ts
// Get current content
const content = editor.getValue();

// Set new content
editor.setValue('# Hello World');

// Get rendered HTML
const html = editor.getRenderedHTML();

// Get clean HTML (no Marzipan classes)
const cleanHtml = editor.getCleanHTML();

Display Modes

ts
// Toggle preview mode
editor.showPreviewMode(true);  // Read-only preview
editor.showPreviewMode(false); // Edit mode

// Toggle plain textarea
editor.showPlainTextarea(true);  // Plain textarea
editor.showPlainTextarea(false); // Overlay preview

// Show/hide statistics
editor.showStats(true);

Focus Management

ts
editor.focus(); // Focus the editor
editor.blur();  // Remove focus

Editor State

ts
// Check initialization
if (editor.isInitialized()) {
  console.log('Editor ready!');
}

// Re-initialize with new options
editor.reinit({ fontSize: '18px' });

// Update preview manually
editor.updatePreview();

// Destroy instance
editor.destroy();

Static Methods

Marzipan.init(target, options)

Convenience method, equivalent to new Marzipan().

ts
const editors = Marzipan.init('.markdown-editor', {
  toolbar: true
});

Marzipan.getInstance(element)

Get existing instance from a DOM element.

ts
const element = document.getElementById('my-editor');
const instance = Marzipan.getInstance(element);

Marzipan.setTheme(theme, customColors?)

Set global theme for all instances.

ts
// Built-in theme
Marzipan.setTheme('cave');

// Custom theme
Marzipan.setTheme({
  name: 'ocean',
  colors: {
    bgPrimary: '#1a2332',
    bgSecondary: '#152033',
    text: '#d4e4f7'
  }
});

// Override specific colors
Marzipan.setTheme('solar', { bgPrimary: '#002b36' });

Marzipan.destroyAll()

Destroy all existing instances.

ts
Marzipan.destroyAll();

Actions API

The bundled actions API provides zero-dependency formatting helpers.

Text Formatting

ts
import { actions } from '@pinkpixel/marzipan';

const textarea = document.querySelector('textarea');

actions.toggleBold(textarea);      // **bold**
actions.toggleItalic(textarea);    // *italic*
actions.toggleCode(textarea);      // `code`

Headers

ts
actions.insertHeader(textarea, 1);  // # H1
actions.insertHeader(textarea, 2);  // ## H2
actions.insertHeader(textarea, 3);  // ### H3

// Convenience methods
actions.toggleH1(textarea);
actions.toggleH2(textarea);
actions.toggleH3(textarea);

Lists

ts
actions.toggleBulletList(textarea);    // - bullet
actions.toggleNumberedList(textarea);  // 1. numbered
actions.toggleTaskList(textarea);      // - [ ] task

Blocks

ts
actions.toggleQuote(textarea);  // > quote
ts
// Basic link
actions.insertLink(textarea);

// With URL
actions.insertLink(textarea, { url: 'https://example.com' });

// With text and URL
actions.insertLink(textarea, {
  text: 'Click here',
  url: 'https://example.com'
});

Utilities

ts
// Get active formats
const formats = actions.getActiveFormats(textarea);
// Returns: ['bold', 'italic', ...]

// Check specific format
const isBold = actions.hasFormat(textarea, 'bold');

// Custom formatting
actions.applyCustomFormat(textarea, {
  prefix: '~~',
  suffix: '~~',
  placeholder: 'strikethrough'
});

// Debug mode
actions.setDebugMode(true);

Plugin System

Marzipan's plugin system allows you to extend editor functionality.

Available Plugins

ts
// Tables
import { tablePlugin } from '@pinkpixel/marzipan/plugins/tablePlugin';
import { tableGridPlugin } from '@pinkpixel/marzipan/plugins/tableGridPlugin';
import { tableGeneratorPlugin } from '@pinkpixel/marzipan/plugins/tableGeneratorPlugin';

// Syntax Highlighting
import { tinyHighlight } from '@pinkpixel/marzipan/plugins/tinyHighlight';

// Diagrams
import { mermaidPlugin } from '@pinkpixel/marzipan/plugins/mermaidPlugin';
import { mermaidExternalPlugin } from '@pinkpixel/marzipan/plugins/mermaidExternalPlugin';

// Images
import { imagePickerPlugin } from '@pinkpixel/marzipan/plugins/imagePickerPlugin';
import { imageManagerPlugin } from '@pinkpixel/marzipan/plugins/imageManagerPlugin';

// Theming
import { accentSwatchPlugin } from '@pinkpixel/marzipan/plugins/accentSwatchPlugin';

Using Plugins

ts
new Marzipan('#editor', {
  plugins: [
    tablePlugin(),
    mermaidPlugin({ theme: 'dark' }),
    tinyHighlight(),
    accentSwatchPlugin()
  ]
});

Plugin Configuration

Most plugins accept configuration options:

ts
tablePlugin({
  defaultColumns: 3,
  defaultRows: 2,
  maxColumns: 10
})

mermaidPlugin({
  theme: 'dark',
  darkMode: true
})

imageManagerPlugin({
  uploadUrl: '/api/upload',
  maxSize: 5 * 1024 * 1024  // 5MB
})

TypeScript Support

Marzipan is written in TypeScript and ships with full type definitions.

ts
import { Marzipan, MarzipanOptions, MarzipanInstance } from '@pinkpixel/marzipan';
import { actions, ActionMethod } from '@pinkpixel/marzipan';

// Fully typed options
const options: MarzipanOptions = {
  fontSize: '16px',
  toolbar: true,
  onChange: (value: string, instance: MarzipanInstance) => {
    console.log('Changed:', value);
  }
};

const [editor]: [MarzipanInstance] = new Marzipan('#editor', options);

Events & Callbacks

onChange

ts
new Marzipan('#editor', {
  onChange: (value, instance) => {
    console.log('Content:', value);
    console.log('Instance ID:', instance.instanceId);
  }
});

onKeydown

ts
new Marzipan('#editor', {
  onKeydown: (event, instance) => {
    if (event.ctrlKey && event.key === 's') {
      event.preventDefault();
      saveContent(instance.getValue());
    }
  }
});

Native Events

ts
const [editor] = new Marzipan('#editor');

editor.textarea.addEventListener('input', (e) => {
  console.log('Input event');
});

editor.textarea.addEventListener('focus', () => {
  console.log('Editor focused');
});

editor.textarea.addEventListener('blur', () => {
  console.log('Editor blurred');
});

Detailed References

For more in-depth information, see:

Examples

Complete Editor Setup

ts
import { Marzipan, actions } from '@pinkpixel/marzipan';
import { tablePlugin } from '@pinkpixel/marzipan/plugins/tablePlugin';
import { mermaidPlugin } from '@pinkpixel/marzipan/plugins/mermaidPlugin';

const [editor] = new Marzipan('#editor', {
  // Typography
  fontSize: '15px',
  lineHeight: 1.6,
  padding: '16px',
  
  // Behavior
  autofocus: true,
  autoResize: true,
  minHeight: '300px',
  placeholder: 'Start writing...',
  smartLists: true,
  
  // Features
  toolbar: true,
  showStats: true,
  theme: 'cave',
  
  // Callbacks
  onChange: (value) => {
    localStorage.setItem('draft', value);
  },
  
  onKeydown: (event, instance) => {
    if (event.ctrlKey && event.key === 's') {
      event.preventDefault();
      publishContent(instance.getValue());
    }
  },
  
  // Plugins
  plugins: [
    tablePlugin(),
    mermaidPlugin({ theme: 'dark' })
  ],
  
  // Custom stats
  statsFormatter: ({ words, chars, lines, line, column }) => {
    const readingTime = Math.ceil(words / 200);
    return `📖 ${words} words (🕒 ${readingTime} min) • Line ${line}:${column}`;
  }
});

// Programmatic actions
const boldButton = document.querySelector('#bold');
boldButton?.addEventListener('click', () => {
  actions.toggleBold(editor.textarea);
  editor.focus();
});

Multiple Editors

ts
const editors = new Marzipan('.markdown-editor', {
  toolbar: true,
  onChange: (value, instance) => {
    console.log(`Editor ${instance.instanceId} changed`);
  }
});

// Access individual editors
editors.forEach((editor, index) => {
  console.log(`Editor ${index}:`, editor.getValue());
});

// Sync content between editors
editors[0].onChange = (value) => {
  editors[1].setValue(value);
};

Framework Integration

tsx
// React
import { useEffect, useRef } from 'react';
import { Marzipan } from '@pinkpixel/marzipan';

export function Editor() {
  const ref = useRef<HTMLDivElement>(null);
  
  useEffect(() => {
    if (!ref.current) return;
    const [editor] = new Marzipan(ref.current, {
      toolbar: true,
      onChange: (value) => {
        console.log('Changed:', value);
      }
    });
    return () => editor.destroy();
  }, []);
  
  return <div ref={ref} />;
}

Browser Support

Marzipan supports all modern browsers:

  • ✅ Chrome 60+
  • ✅ Firefox 55+
  • ✅ Safari 11+
  • ✅ Edge 79+

Performance Tips

  1. Debounce onChange for expensive operations
  2. Use plugins selectively - only import what you need
  3. Lazy load large plugins like Mermaid
  4. Set maxHeight for very long documents
  5. Disable features you don't need (toolbar, stats, etc.)

Best Practices

  1. Always clean up - Call destroy() when unmounting
  2. Use TypeScript - Full type definitions included
  3. Handle errors - Wrap in try/catch when appropriate
  4. Test responsively - Mobile behavior differs slightly
  5. Follow conventions - Use the actions API for consistency

Need Help?

Released under the Apache 2.0 License