Inline Parse Example

Hello, I’m struggling with extending my markdown parser to work like it did in Code Mirror 5.

I can see examples but I have no idea what these numbers correlate to, they don’t seem to be javascript keycodes. e.g (Yes this specific character is shown in a comment but that doesn’t allow me to know what other characters would be)

Link(cx, next, start) {
   return next == 91 /* '[' */ ? cx.append(new InlineDelimiter(LinkStart, start, start + 1, 1 /* Open */)) : -1;
}

Below is what I had in Code Mirror 5, for context this token is very simple and if possible I’d rather just use regex instead of streams, but am willing to work with whichever.

The corresponding regex would be RegExp(/\?-(.*?)-\?/g)

Code Mirror 5 Example
(TLDR it finds matches between: ?- here -? )

export const FIB_MODE = 'fib';
CodeMirror.defineMode(FIB_MODE, function (config, parserConfig) {
  const fibOverlay = {
    token: function (stream, state) {
      let ch;
      if (stream.match('?-')) {
        while ((ch = stream.next()) != null)
          if (ch == '-' && stream.next() == '?') {
            stream.eat('?');
            return FIB_MODE;
          }
      }

      // Necessary
      while (stream.next() != null && !stream.match('?-', false)) {}
      return null;
    },
  };

  return CodeMirror.overlayMode(
    CodeMirror.getMode(config, parserConfig.backdrop || 'markdown'),
    fibOverlay
  );
});

i.e. Is there an example of extending markdown in CodeMirror 6 and how do I know what those numbers in the inline parser correlate to?

Characters have numbers (see String.charCodeAt and the Unicode standard), and that’s what is being used here. You should be able to define an inline parser to parse this syntax, but it’s going to require some programming and reading of docs.

Thanks for the input, got it.

import { styleTags, Tag, tags } from "@lezer/highlight"

const ClozeDelim = { resolve: "Cloze", mark: "ClozeMark" };
export const clozeTag = Tag.define();
export const Cloze = {
    defineNodes: ["Cloze", "ClozeMark"],
    parseInline: [{
        name: "Cloze",
        parse(cx, next, pos) {
          /* ?- value -? */ /* 63 == unicode '?' | 45 == unicode '-' */
          if ((next == 63  && cx.char(pos + 1) == 45) ) {
            return cx.addDelimiter(ClozeDelim, pos, pos + 2, true, false);
          } else if ((next == 45 && cx.char(pos + 1) == 63) ) {
            return cx.addDelimiter(ClozeDelim, pos, pos + 2, false, true);
          }

          return -1
        }
    }],
    props: [
        styleTags({
            ClozeMark: tags.processingInstruction,
            'Cloze/...': clozeTag
        })
    ]
}

Quick follow up question.

Maybe I’m missing something obvious? How do I get my markdown parser extension to work inside of a language block?

image

The markdown parser doesn’t parse inside code blocks, so these syntax extensions won’t be recognized there.

So inline parser is not a clear substitute for replacing Overlay Mode from CM5. – i.e. It seems like I should of been using a MatchDecorator.

	import { MatchDecorator, ViewPlugin, Decoration } from '@codemirror/view';

	let highlightDeco = Decoration.mark({ class: 'highlight' });
	let decorator = new MatchDecorator({
		regexp: /\?-(.*?)-\?/g,
		decoration: (m) => highlightDeco
	});

	let plugin = ViewPlugin.define(
		(view) => ({
			decorations: decorator.createDeco(view),
			update(u) {
				this.decorations = decorator.updateDeco(u, this.decorations);
			}
		}),
		{
			decorations: (v) => v.decorations
		}
	);

image