Skip to content
On this page

Actions API

Complete reference for Marzipan's zero-dependency formatting actions.

Overview

All markdown formatting actions are bundled with Marzipan. Import them from the main package:

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

Every action accepts an HTMLTextAreaElement and performs the appropriate formatting operation.

Text Formatting

toggleBold(textarea)

Toggle bold formatting on the selected text.

Parameters:

  • textarea (HTMLTextAreaElement) - Target textarea

Markdown Output: **bold text**

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

// Selected: "hello"
// Result: "**hello**"

// Selected: "**hello**"
// Result: "hello" (removes bold)

toggleItalic(textarea)

Toggle italic formatting on the selected text.

Parameters:

  • textarea (HTMLTextAreaElement) - Target textarea

Markdown Output: *italic text*

ts
actions.toggleItalic(textarea);

// Selected: "hello"
// Result: "*hello*"

toggleCode(textarea)

Toggle inline code formatting on the selected text.

Parameters:

  • textarea (HTMLTextAreaElement) - Target textarea

Markdown Output: `code`

ts
actions.toggleCode(textarea);

// Selected: "hello"
// Result: "`hello`"

Headers

insertHeader(textarea, level, toggle?)

Insert or toggle a header at the specified level (1-6).

Parameters:

  • textarea (HTMLTextAreaElement) - Target textarea
  • level (number) - Header level (1-6)
  • toggle (boolean) - Whether to toggle header off if already at that level (default: false)

Markdown Output: # H1, ## H2, etc.

ts
// Insert H2
actions.insertHeader(textarea, 2);

// Toggle H1 (removes header if already H1)
actions.insertHeader(textarea, 1, true);

// On line: "Hello"
// Result: "## Hello" (level 2)

// On line: "## Hello"
// With toggle: true, level: 2
// Result: "Hello" (header removed)

toggleH1(textarea), toggleH2(textarea), toggleH3(textarea)

Convenience methods to toggle specific header levels.

Parameters:

  • textarea (HTMLTextAreaElement) - Target textarea
ts
actions.toggleH1(textarea);  // Toggle # H1
actions.toggleH2(textarea);  // Toggle ## H2
actions.toggleH3(textarea);  // Toggle ### H3

Lists

toggleBulletList(textarea)

Toggle bullet (unordered) list formatting.

Parameters:

  • textarea (HTMLTextAreaElement) - Target textarea

Markdown Output: - item

ts
actions.toggleBulletList(textarea);

// Selected lines:
// hello
// world
//
// Result:
// - hello
// - world

toggleNumberedList(textarea)

Toggle numbered (ordered) list formatting.

Parameters:

  • textarea (HTMLTextAreaElement) - Target textarea

Markdown Output: 1. item

ts
actions.toggleNumberedList(textarea);

// Selected lines:
// hello
// world
//
// Result:
// 1. hello
// 2. world

toggleTaskList(textarea)

Toggle task list (checkbox) formatting.

Parameters:

  • textarea (HTMLTextAreaElement) - Target textarea

Markdown Output: - [ ] task

ts
actions.toggleTaskList(textarea);

// Selected lines:
// Buy milk
// Walk dog
//
// Result:
// - [ ] Buy milk
// - [ ] Walk dog

Blocks

toggleQuote(textarea)

Toggle blockquote formatting.

Parameters:

  • textarea (HTMLTextAreaElement) - Target textarea

Markdown Output: > quote

ts
actions.toggleQuote(textarea);

// Selected lines:
// This is a quote
// Spanning multiple lines
//
// Result:
// > This is a quote
// > Spanning multiple lines

Insert a markdown link.

Parameters:

  • textarea (HTMLTextAreaElement) - Target textarea
  • options (Object) - Link options
    • url (string) - Link URL
    • text (string) - Link text

Markdown Output: [text](url)

ts
// Basic link (prompts for URL)
actions.insertLink(textarea);

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

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

// Smart URL detection:
// Selected: "https://example.com"
// Result: "[](https://example.com)"

// With selected text "click":
// Result: "[click]()"

Utility Functions

getActiveFormats(textarea)

Get an array of currently active formats at the cursor position.

Parameters:

  • textarea (HTMLTextAreaElement) - Target textarea

Returns: string[] - Array of active format names

ts
const formats = actions.getActiveFormats(textarea);

// Cursor in: "**bold *and italic***"
// Returns: ['bold', 'italic']

// Use to update UI state
if (formats.includes('bold')) {
  boldButton.classList.add('active');
}

hasFormat(textarea, format)

Check if a specific format is active at the cursor position.

Parameters:

  • textarea (HTMLTextAreaElement) - Target textarea
  • format (string) - Format name to check

Returns: boolean - Whether the format is active

ts
const isBold = actions.hasFormat(textarea, 'bold');
const isItalic = actions.hasFormat(textarea, 'italic');

// Update button states
boldButton.disabled = !isBold;

expandSelection(textarea)

Expand the current selection to the nearest word or block boundaries.

Parameters:

  • textarea (HTMLTextAreaElement) - Target textarea

Returns: void

ts
// Cursor in middle of "hello"
actions.expandSelection(textarea);
// Now selects entire word "hello"

// Useful before applying formatting
actions.expandSelection(textarea);
actions.toggleBold(textarea);

preserveSelection(textarea, callback)

Execute a callback while preserving the current selection.

Parameters:

  • textarea (HTMLTextAreaElement) - Target textarea
  • callback (Function) - Function to execute

Returns: void

ts
actions.preserveSelection(textarea, () => {
  // Modify content without losing selection
  const value = textarea.value;
  textarea.value = value.toUpperCase();
});

// Selection is restored after callback

Custom Formatting

applyCustomFormat(textarea, format)

Apply a custom formatting rule.

Parameters:

  • textarea (HTMLTextAreaElement) - Target textarea
  • format (FormatStyleOptions) - Custom format definition
    • prefix (string) - Text before selection
    • suffix (string) - Text after selection
    • placeholder (string) - Placeholder if no selection
    • multiline (boolean) - Apply to multiple lines
ts
// Strikethrough
actions.applyCustomFormat(textarea, {
  prefix: '~~',
  suffix: '~~',
  placeholder: 'strikethrough text'
});

// Highlight
actions.applyCustomFormat(textarea, {
  prefix: '==',
  suffix: '==',
  placeholder: 'highlighted'
});

// Custom block
actions.applyCustomFormat(textarea, {
  prefix: '::: warning\n',
  suffix: '\n:::',
  placeholder: 'Warning message',
  multiline: true
});

Debug Mode

setDebugMode(enabled) / getDebugMode()

Enable or disable debug logging for development.

Parameters:

  • enabled (boolean) - Whether to enable debug mode
ts
// Enable debug logging
actions.setDebugMode(true);

// Now all actions log details
actions.toggleBold(textarea);
// Logs:
// - Selection before: {start: 0, end: 5}
// - Operation: add bold
// - Selection after: {start: 2, end: 7}

// Check current state
const isDebug = actions.getDebugMode();

// Disable when done
actions.setDebugMode(false);

Undo Integration

setUndoMethod(method) / getUndoMethod()

Configure how actions integrate with undo/redo.

Parameters:

  • method ('native' | 'custom') - Undo method to use
ts
// Use browser's native undo (default)
actions.setUndoMethod('native');

// Use custom undo handling
actions.setUndoMethod('custom');

// Get current method
const method = actions.getUndoMethod();

Complete Example

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

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

// Create custom toolbar
const toolbar = {
  bold: () => actions.toggleBold(textarea),
  italic: () => actions.toggleItalic(textarea),
  code: () => actions.toggleCode(textarea),
  h1: () => actions.toggleH1(textarea),
  h2: () => actions.toggleH2(textarea),
  link: () => actions.insertLink(textarea, {
    url: prompt('Enter URL:')
  }),
  bullet: () => actions.toggleBulletList(textarea),
  numbered: () => actions.toggleNumberedList(textarea),
  quote: () => actions.toggleQuote(textarea),
};

// Handle keyboard shortcuts
textarea.addEventListener('keydown', (e) => {
  if (e.ctrlKey || e.metaKey) {
    switch (e.key) {
      case 'b':
        e.preventDefault();
        toolbar.bold();
        break;
      case 'i':
        e.preventDefault();
        toolbar.italic();
        break;
      case 'k':
        e.preventDefault();
        toolbar.link();
        break;
    }
  }
});

// Update UI based on active formats
textarea.addEventListener('selectionchange', () => {
  const formats = actions.getActiveFormats(textarea);
  
  document.querySelector('.btn-bold')
    .classList.toggle('active', formats.includes('bold'));
  
  document.querySelector('.btn-italic')
    .classList.toggle('active', formats.includes('italic'));
  
  document.querySelector('.btn-code')
    .classList.toggle('active', formats.includes('code'));
});

// Custom formatting
document.querySelector('.btn-strikethrough').addEventListener('click', () => {
  actions.applyCustomFormat(textarea, {
    prefix: '~~',
    suffix: '~~',
    placeholder: 'strikethrough'
  });
});

// Debug mode for development
if (process.env.NODE_ENV === 'development') {
  actions.setDebugMode(true);
}

Format Names Reference

Format names used by getActiveFormats() and hasFormat():

  • 'bold' - Bold text (**text**)
  • 'italic' - Italic text (*text*)
  • 'code' - Inline code (`text`)
  • 'link' - Links ([text](url))
  • 'quote' - Blockquotes (> text)
  • 'h1' - H1 headers (# text)
  • 'h2' - H2 headers (## text)
  • 'h3' - H3 headers (### text)
  • 'h4' - H4 headers (#### text)
  • 'h5' - H5 headers (##### text)
  • 'h6' - H6 headers (###### text)
  • 'bulletList' - Unordered lists (- text)
  • 'numberedList' - Ordered lists (1. text)
  • 'taskList' - Task lists (- [ ] text)

Browser Compatibility

Actions work in all modern browsers:

  • Chrome/Edge 60+
  • Firefox 55+
  • Safari 11+

See Also

Released under the Apache 2.0 License