Static highlighting using CM v6

I want to highlight some pieces of code for a documentation of a new poor-supported language, it is alif. I coded a custom simple mode with @codemirror/legacy-modes/mode/simple-mode, everything is fine till now. Now I want to statically highlight alif code, I thought about using highlight.js, but it would be much easier to create a centralized place of writing highlighting modes. Using CM as a static highlighter will make development faster, if I edit alif simple modes and everything is updated.

Here is a related article, but v5 not CM v6 (next).

To implement a runmode-like functionality with CM6, use the @codemirror/highlight package like so

import {highlightTree, defaultHighlightStyle} from "@codemirror/highlight"
export function runmode(textContent: string, language: Language, callback: (text: string, style: string, from: number, to: number) => void, options?: Record<string, any>) {
  const tree = language.parseString(textContent);
  let pos = 0;
  highlightTree(tree, defaultHighlightStyle.match, (from, to, classes) => {
    from > pos && callback(textContent.slice(pos, from), null, pos, from);
    callback(textContent.slice(from, to), classes, from, to);
    pos = to;
  });
  pos != tree.length && callback(textContent.slice(pos, tree.length), null, pos, tree.length);
}

The reason why we need to keep a position state is because unstyled tokens are not emitted.

Note that in my experience, although dynamically loading languages is easier in CM6 because its given as es modules, I’ve found the overall bundle size required to replicate the runmode functionality larger because @codemirror/highlight depends on @codemirror/view and @codemirror/state but 1. that may be tree-shaking misconfiguration 2. if you’re highlighting in server, bundle size might not be a problem.

2 Likes

parseString is no longer available since @codemirror/language@0.19.
How can I do it in the latest version? Thanks!

Call language.parser.parse(string) instead. I forgot to mention this in the release notes—added it.

1 Like