Is there a better solution for this with markdown?

I’m sorry if there is a solution to this already build for CodeMirror, but I could not find one after searching for days. As such, I tried to implement my own fix but my JavaScript experience is non-existent and while this works without CodeMirror, something in CodeMirror stops it from working. I used for this some code I found online.

I want to use editor.md (Pandado on Github) for Markdown which seems to be build using Codemirror 5.0. The problem is my users rarely understand markdown and my server parser uses grubers implementation, which I cannot change on the server side. I only want to change the user front side.

The issue is that people don’t double-space each line as they don’t know markdown as more advanced users. Which means text is then posted joined and is very hard to read. They think its a bug but that is how markdown works. I imagined the best solution is to create a JS code that will automatically insert them after each new line, so after researching and testing I came up with this solution that seems to do the trick.

In my text area HTML I added an event such as:

<textarea onkeyup="DoubleSpace()" rows="10"></textarea>

That is triggered with the following code:

    const DoubleSpace = () => {

        if (event.keyCode == 13) {

            const { target } = event;
            const { selectionStart, value } = target;
            const bulletWithSpace = `\u002a\u002a`; // value to insert u0020 = space, u002a = * for testing

            //console.log('debug');
            target.value = [...value]
                .map((c, i) => i === selectionStart - 1
                    ? `${bulletWithSpace}\n` // changed to the back for last line
                    : c
                )
                .join('');

            target.selectionStart = selectionStart+bulletWithSpace.length;
            target.selectionEnd = selectionStart+bulletWithSpace.length;
        }

    }

This works. You get the symbols inserted in a new line when someone hits enter, which I would then use to properly set the markdown for new lines by inserting 2 spaces after someone hits the enter key.

The problem is that once I try to use this in Codemirror with editor.md, it will trigger the event but does not actually insert the character. Except on Firefox, if I type and hit enter really fast it sometimes works. This means something in Codemirror is blocking it, and I don’t know where else to look. The irony is that the preview does spaces line correctly, but by using a break line as HTML.

Since Codemirror seems to replace the original text area, at least with editor.md, I added the following to codemirror.js after:
field.setAttribute("spellcheck", "false");

field.setAttribute("onkeyup", "DoubleSpace ()");

That properly adds the same trigger to the form. I added the JS file on a separate file to avoid mixing the code with codemirror.

If I then uncheck the console debug message on the code. I can see it properly triggered. Every time I hit enter, it works in the browser console. But the code is not inserting anything in the editor. Normal text area works, with codemirror it does not, but the code is properly triggered. It is something related to inserting the actual symbol into the editor.

I have no idea how to fix this and maybe (probably) there is someway easier to do this directly in codemirror which works even better. I’m really frustrated since I can use this on a normal textarea box but not once I load codemirror. Someone with JS experience or Codemirror can probably spot the issue right away. I know this is not probably the best way to do it, and I have not even tested if it would work on mobile, but I can’t seem to fix the double space any other way and I can’t implement another markdown flavor an as parser either on the back end.

Is there a better way to achieve this?

I don’t have experience with editor.md, but you probably need to do it from the CM editor instance.
See Key maps section in the CM manual, there’s an example for the Tab key.

Probably something like this (not tested; this will disable the smart indent from the default newlineAndIndent):

editor.setOption("extraKeys", {
  Enter: function(cm) {
    var spaces = Array(cm.getOption("indentUnit") + 1).join(" \n");
    cm.replaceSelection(spaces);
  }
});

indentLine or indentAuto also could be handy.

There’s also the continuelist addon, which do something similar (if it works with editor.md).

Thank you Geist-00 :beers:

I think this is pointing me in the right direction. Thanks to your link and example, I actually found the editor is actually using similar functions for keyboard shortcuts to create headlines and similar.

You are right, I should probably use those functions which are build already instead of an external trigger. I tested your code, and it seems to work somehow, it does trigger on enter but does not enter a new line, either way, I appreciate your reply, as now at least I know what to look for and where to start. Using the key functions in Codemirror seems obviously the most logic approach to use.

NOTE: I already got this working by copying an existing example and just modified. It was so much easier than using my own code and now it works nicely. Thank you again!