Apply the input rules (markdown) but also keep the tokens

I’m building a markdown editor and I want to make something similar to StackEdit, where you have a split screen with a text editor at the left and the markdown preview at the right. What I want is to build the part of the left, where you basically write some markdown, it is applied to the same text and also you can see the tokens.

As an example, here’s an image:

image

You see the # or the ** in a grey color, but it is applied to the text and the token is still there. I hope I’m clear! Thanks!

You could fake them with :before style rules and such. But if you want to allow people to edit those characters directly, you might be better off building on top of something like CodeMirror

Thanks @marijn! What about codemirror would make this easier to implement?

It’s a text editor that you can set up to keep a Markdown parse tree of your code on the side, so it’ll make a textual editing approach easier to implement than a rich text editor will. But either way this is not going to be an easy thing to build.

1 Like

Thanks @marijn! I handled to add some of the tokens customizing some input rules, for instance:

export function headingsInputRule (regexp: any, nodeType: any, getAttrs: any) {
  return new InputRule(regexp, (state, match, start, end) => {
    const $start = state.doc.resolve(start);
    const attrs = getAttrs instanceof Function ? getAttrs(match) : getAttrs;
    if (!$start.node(-1).canReplaceWith($start.index(-1), $start.indexAfter(-1), nodeType)) {
      return null;
    }
    return state.tr
      .delete(start, end)
      .setBlockType(start, start, nodeType, attrs)
      .insertText(`${'#'.repeat(attrs?.level || 1)} `, start);
  });
}

But the are input rules not working when, for instance, I write **some text**, which is supposed to make the text bold. This seems to be related to (please correct me) wrappingInputRule vs textblockTypeInputRule or maybe nodes vs marks. Can you give me a small guidance on this, or where to see to be able to make an input rule for this: **some text**?

Thanks so much in advance, I really appreciate your answers!