EasyMDE Documentation

repository·master·Indexed 25 days ago

https://github.com/ionaru/easy-markdown-editor

A simple, embeddable JavaScript Markdown editor and drop-in replacement for textareas. Version 2.21.0 features a toolbar, keyboard shortcuts, real-time syntax rendering, auto-saving, and spell checking. Built on CodeMirror, Font Awesome, and Marked, it supports side-by-side preview, fullscreen mode, and customizable toolbar actions.

Tokens
6.3K
Snippets
8
Records
26
Agent score
35%

What's inside EasyMDE

  1. Understand EasyMDE architecture and dependencies

    master

    EasyMDE is a fork of SimpleMDE and relies on the following core technologies:

    • CodeMirror: The backbone used for Markdown syntax parsing and editor functionality.
    • Font Awesome: Used for toolbar icons.
    • Marked: Used to render previews using GitHub Flavored Markdown (GFM).
  2. Load the EasyMDE editor

    master

    After installing or importing the module, you can initialize the editor. By default, calling new EasyMDE() will load the editor onto the first <textarea> element found on the page. To target a specific element, pass the element to the element option in the constructor.

    <!-- Default: loads onto the first textarea -->
    <textarea></textarea>
    <script>
    const easyMDE = new EasyMDE();
    </script>
    
    <!-- Specific: targets a specific textarea via ID -->
    <textarea id="my-text-area"></textarea>
    <script>
    const easyMDE = new EasyMDE({element: document.getElementById('my-text-area')});
    </script>
  3. Configure Keyboard Shortcuts

    master

    EasyMDE includes a set of default keyboard shortcuts. You can override specific shortcuts or unbind them by passing a shortcuts object to the configuration.

    Note: Shortcuts are automatically converted between platforms (e.g., Cmd on macOS becomes Ctrl on Windows/Linux).

    The list of actions you can bind is identical to the list of built-in toolbar button actions (e.g., toggleBold, drawLink, togglePreview).

    const editor = new EasyMDE({
        shortcuts: {
            "toggleOrderedList": "Ctrl-Alt-K", // alter the shortcut for toggleOrderedList
            "toggleCodeBlock": null, // unbind Ctrl-Alt-C
            "drawTable": "Cmd-Alt-T", // bind Cmd-Alt-T to drawTable action, which doesn't come with a default shortcut,
        }
    });
  4. Customize the Toolbar

    master

    You can customize the toolbar using the toolbar option. You can:

    1. Reorder existing buttons: Pass an array of icon names.
    2. Add custom buttons: Pass an object containing name, action (a function), className, title, and optional text or attributes.
    3. Create dropdown menus: Use the children property within a toolbar object to nest buttons.
    4. Add separators: Use the string "|" in the array.

    Note: Actions can be built-in EasyMDE methods (e.g., EasyMDE.toggleBold) or custom functions.

    // Only the order of existing buttons
    const easyMDE = new EasyMDE({
        toolbar: ["bold", "italic", "heading", "|", "quote"]
    });
    
    // All information and/or add your own icons or text
    const easyMDE = new EasyMDE({
        toolbar: [
            {
                name: "bold",
                action: EasyMDE.toggleBold,
                className: "fa fa-bold",
                title: "Bold",
            },
            "italic", // shortcut to pre-made button
            {
                name: "custom",
                action: (editor) => {
                    // Add your own code
                },
                className: "fa fa-star",
                text: "Starred",
                title: "Custom Button",
                attributes: {
                    id: "custom-id",
                    "data-value": "custom value"
                }
            },
            "|"
        ]
    });
    
    // Put some buttons on dropdown menu
    const easyMDE = new EasyMDE({
        toolbar: [{
                    name: "heading",
                    action: EasyMDE.toggleHeadingSmaller,
                    className: "fa fa-header",
                    title: "Headers",
                },
                "|",
                {
                    name: "others",
                    className: "fa fa-blind",
                    title: "others buttons",
                    children: [
                        {
                            name: "image",
                            action: EasyMDE.drawImage,
                            className: "fa fa-picture-o",
                            title: "Image",
                        },
                        {
                            name: "quote",
                            action: EasyMDE.toggleBlockquote,
                            className: "fa fa-percent",
                            title: "Quote",
                        },
                        {
                            name: "link",
                            action: EasyMDE.drawLink,
                            className: "fa fa-link",
                            title: "Link",
                        }
                    ]
                },
            // [, ...]
        },
    ]);
  5. Install EasyMDE

    master

    You can install EasyMDE using npm or via a CDN.

    npm install easymde

    Via UNPKG CDN:

    <link rel="stylesheet" href="https://unpkg.com/easymde/dist/easymde.min.css">
    <script src="https://unpkg.com/easymde/dist/easymde.min.js"></script>

    Via jsDelivr CDN:

    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/easymde/dist/easymde.min.css">
    <script src="https://cdn.jsdelivr.net/npm/easymde/dist/easymde.min.js"></script>
  6. Configure EasyMDE Options

    master

    EasyMDE can be customized using an options object passed to the constructor. Key configuration categories include:

    • Autosave: Enable automatic text saving with autosave: { enabled: true, uniqueId: '...', delay: 1000 }.
    • Editor Appearance: Control minHeight, maxHeight, placeholder, lineNumbers, and theme.
    • Markdown Parsing: Use parsingConfig to adjust how Markdown is parsed during editing (e.g., strikethrough, allowAtxHeaderWithoutSpace) and renderingConfig for the preview mode (e.g., codeSyntaxHighlighting, sanitizerFunction).
    • Image Upload: Enable image uploads via uploadImage: true and configure imageUploadEndpoint, imageMaxSize, and imageAccept.
    • Toolbar & Icons: Customize the toolbar via the toolbar option and hide specific icons using hideIcons or showIcons.
    const editor = new EasyMDE({
        autofocus: true,
        autosave: {
            enabled: true,
            uniqueId: "MyUniqueID",
            delay: 1000,
            submit_delay: 5000,
            timeFormat: {
                locale: 'en-US',
                format: {
                    year: 'numeric',
                    month: 'long',
                    day: '2-digit',
                    hour: '2-digit',
                    minute: '2-digit',
                },
            },
            text: "Autosaved: "
        },
        blockStyles: {
            bold: "__",
            italic: "_",
        },
        unorderedListStyle: "-",
        element: document.getElementById("MyID"),
        forceSync: true,
        hideIcons: ["guide", "heading"],
        indentWithTabs: false,
        initialValue: "Hello world!",
        insertTexts: {
            horizontalRule: ["", "\n\n-----\n\n"],
            image: ["![](http://", ")"],
            link: ["[", "](https://)"],
            table: ["", "\n\n| Column 1 | Column 2 | Column 3 |\n| -------- | -------- | -------- |\n| Text     | Text     | Text     |\n\n"],
        },
        lineWrapping: false,
        minHeight: "500px",
        parsingConfig: {
            allowAtxHeaderWithoutSpace: true,
            strikethrough: false,
            underscoresBreakWords: true,
        },
        placeholder: "Type here...",
    
        previewClass: "my-custom-styling",
        previewClass: ["my-custom-styling", "more-custom-styling"],
    
        previewRender: (plainText) => customMarkdownParser(plainText), // Returns HTML from a custom parser
        previewRender: (plainText, preview) => {
            setTimeout(() => {
                preview.innerHTML = customMarkdownParser(plainText);
            }, 250);
    
            // If you return null, the innerHTML of the preview will not
            // be overwritten. Useful if you control the preview node's content via
            // vdom diffing.
            // return null;
    
            return "Loading...";
        },
        promptURLs: true,
        promptTexts: {
            image: "Custom prompt for URL:",
            link: "Custom prompt for URL:",
        },
        renderingConfig: {
            singleLineBreaks: false,
            codeSyntaxHighlighting: true,
            sanitizerFunction: (renderedHTML) => {
                // Using DOMPurify and only allowing <b> tags
                return DOMPurify.sanitize(renderedHTML, {ALLOWED_TAGS: ['b']})
            },
        },
        shortcuts: {
            drawTable: "Cmd-Alt-T"
        },
        showIcons: ["code", "table"],
        spellChecker: false,
        status: false,
        status: ["autosave", "lines", "words", "cursor"], // Optional usage
        status: ["autosave", "lines", "words", "cursor", {
            className: "keystrokes",
            defaultValue: (el) => {
                el.setAttribute('data-keystrokes', 0);
            },
            onUpdate: (el) => {
                const keystrokes = Number(el.getAttribute('data-keystrokes')) + 1;
                el.innerHTML = `${keystrokes} Keystrokes`;
                el.setAttribute('data-keystrokes', keystrokes);
            },
        }], // Another optional usage, with a custom status bar item that counts keystrokes
        styleSelectedText: false,
        sideBySideFullscreen: false,
        syncSideBySidePreviewScroll: false,
        tabSize: 4,
        toolbar: false,
        toolbarTips: false,
        toolbarButtonClassPrefix: "mde",
    });
  7. Initialize EasyMDE editor

    master

    To use EasyMDE, instantiate the EasyMDE class by passing an options object. You can specify a target element (a <textarea>) to bind the editor to. If no element is provided, it defaults to the first textarea found in the document.

    Key configuration options include:

    • element: The DOM element to use as the editor.
    • initialValue: The initial markdown text to load.
    • toolbar: An array of strings defining the buttons in the toolbar.
    • uploadImage: Boolean to enable/disable image uploading via drag-and-drop or paste.
    • imageUploadFunction: A custom function to handle image uploads.
  8. Handle CodeMirror events in EasyMDE

    master

    EasyMDE is bundled with CodeMirror, allowing you to listen to CodeMirror events via the codemirror property on the EasyMDE instance. You can catch any event supported by CodeMirror (e.g., change).

    const easyMDE = new EasyMDE();
    easyMDE.codemirror.on("change", () => {
        console.log(easyMDE.value());
    });
  9. Use EasyMDE utility methods

    master

    EasyMDE provides several utility methods to check the current state of the editor or manage autosave data:

    • isPreviewActive(): Returns a boolean indicating if preview mode is active.
    • isSideBySideActive(): Returns a boolean indicating if side-by-side mode is active.
    • isFullscreenActive(): Returns a boolean indicating if fullscreen mode is active.
    • clearAutosavedValue(): Clears the currently autosaved value.
    const easyMDE = new EasyMDE();
    easyMDE.isPreviewActive(); // returns boolean
    easyMDE.isSideBySideActive(); // returns boolean
    easyMDE.isFullscreenActive(); // returns boolean
    easyMDE.clearAutosavedValue(); // no returned value
  10. Remove EasyMDE and revert to a text area

    master

    To destroy the EasyMDE instance and revert the element back to its original <textarea> state, call the toTextArea() method.

    Note: Calling toTextArea() clears any associated autosave. The resulting text area will retain the text from the EasyMDE instance. To remove registered event listeners when the editor is no longer needed, call cleanup().

    const easyMDE = new EasyMDE();
    // ...
    easyMDE.toTextArea();
    easyMDE = null;
    
    // To remove event listeners:
    easyMDE.cleanup();
  11. Configure image uploading

    master

    EasyMDE supports asynchronous image uploading. You can enable it by setting uploadImage: true.

    To handle the actual upload to your server, provide a custom function via imageUploadFunction. This function will be called with the FileList from a drag-and-drop, paste, or file browser action.

    Other related options:

    • imageMaxSize: Maximum file size in bytes (default: 2097152).
    • imageAccept: Allowed MIME types (default: 'image/png, image/jpeg, image/gif, image/avif').
    • imagePathAbsolute: Whether the returned image path should be absolute.
    • imageCSRFName: The name of the CSRF token field (e.g., 'csrfmiddlewaretoken').
    • imageCSRFHeader: Boolean indicating if the CSRF token should be sent in a header.