So, recently, I was given the option to create an interesting little tool, which was based off another tool that had been seen online (as is often the way with these things).

We have a (very simple) text area that allows MarkDown, and this has its own little preview window – this was achieved using marked and some pretty simple code.

If you want to create such a tool, it’s quite simple – our package manager of choice is Yarn, mainly because of some esoteric reason I have not been made aware of within our organization, so we start by installing marked:

yarn add marked
yarn add -D @types/marked

We also needed to add the typings, because we’re working in typescript, that’s what Line 2 is for.

It was quite simple from here to create a component1 that held the Markdown code.

import { marked } from "marked";

/**
 * @class MarkdownComponent
 * @description A class to render markdown text in a preview area
 */
export default class MarkdownComponent {
    /**
     * @constructor
     * @param {HTMLInputElement} input - The input element that contains the markdown text
     * @param {HTMLElement} target - The target element where the markdown text will be rendered
     */
    constructor(private input: HTMLInputElement, private target: HTMLElement) {
        this.initMarkdownEditor();
    }

    /**
     * @method renderMarkdown
     * @description Converts a string from MarkDown to HTML
     * @param md The string to convert from MarkDown to HTML
     * @returns The formatted string in HTML
     */
    private renderMarkdown(md) {
        const mdEncoded = $('<span>').text(md).html()
        return marked(mdEncoded);
    }

    /**
     * @method initMarkdownEditor
     * @description Initializes the markdown editor
     */
    private initMarkdownEditor() {
        // Use line breaks within Markdown text
        marked.use({ breaks: true });

        // Get JQuery object references for the input and the target
        const $input = $(this.input);
        const $preview = $(this.target);

        // Pre-render the markdown text if it is already present in the input
        $().on("ready", () => {
            if ($input.val() !== "") {
                const htmlText = this.renderMarkdown($input.val());
                $preview.html(htmlText);
            }
        });

        // When a key is pressed in the input, render the markdown text
        $textArea.on("keyup", () => {
            // Get the markdown text
            const markdownText = $input.val();
            // If it's an empty string
            if (!markdownText || markdownText === "") {
                // Display a message in the preview area
                $preview.html('<p class="text-info">Nothing to preview!</p>');
            } else {
                // Otherwise, render the markdown text
                const htmlText = this.renderMarkdown(markdownText);
                $preview.html(htmlText);
            }
        });
    }
}

I hope the code above is fairly self-explanitory, if not, please, just leave a comment or drop me a line!

And that’s it , until part 2

  1. please note, this is not in the sense of a JSX, React, or other component, I am just using the word here as a name for what the class represents ↩︎

One response to “Make Your Mark(Down) – Part 1”

  1. […] earlier, in Make Your Mark(Down) – Part 1 I tried to introduce you to an editable Markdown control with preview, the next thing we decided we […]

    Like