Rosey/markdown-draft-js

Escape Markdown on draftToMarkdown

Opened this issue · 1 comments

There is the setting escapeMarkdownCharacters which apparently only works markdown -> draft, which is not very intuitive for me, because when loading the content i want the stored markdown to be restored to the draft state.

However there's no option to escape markdown when converting draft -> markdown, if I want to escape user inputs. Draft returns blocks with bare text and styling information. Can there be either an option to also escape in this direction, or a callback to modify text while converting and before the style is applied, so I can write the escaping myself

Until fixed, there is my attempt to resolve this. I am still debugging this, but it looks like it is working:

// '\\' must be first
const defaultReplacements = ['\\', '*', '_', '#', '[', ']', '~'];

function escapeMarkdown(block: RawDraftContentBlock, replacements = defaultReplacements) {
    let string = block.text
    replacements.forEach(function (replacement) {
        let idx = 0;
        while ((idx = string.indexOf(replacement, idx)) !== -1) {
            string = insertAt(string, idx, '\\');
            block.inlineStyleRanges.forEach(range => {
                if (idx < range.offset) {
                    range.offset++;
                } else if (idx >= range.offset && idx < range.offset + range.length) {
                    range.length++;
                }
            })
            idx = idx + 2;
        }
        block.text = string;
    }, block)
}


function insertAt (target: string, index:number, string: string) {
    var ind = index < 0 ? target.length + index  :  index;
    return  target.substring(0, ind) + string + target.substr(ind);
}

export function toMarkdown(contentState: ContentState): string {
    const rawObject = convertToRaw(contentState);
    rawObject.blocks.forEach(block => {
        escapeMarkdown(block);
    })
    const value = draftToMarkdown(rawObject);
    return value;
}