Help with Multiplex Mode

I’d like to create a simple multiplex mode that combines the HTML and Twig modes for .html.twig files and I’m very new at this.

I have an example that works:

define (function (require, exports, module) {
    var CodeMirror = brackets.getModule("thirdparty/CodeMirror2/lib/codemirror");
    var LanguageManager = brackets.getModule("language/LanguageManager");
    
    CodeMirror.defineMode("markdown_plus", function (config) {
        return CodeMirror.multiplexingMode(
            CodeMirror.getMode(config, "gfm"), {
                open: /^---$/, close: /^---$/,
                mode: CodeMirror.getMode(config, "yaml"),
                // parseDelimiters: true
        });
    });
    
    LanguageManager.defineLanguage("markdown_plus", {
        name: "Markdown Plus",
        mode: "markdown_plus"
    });
});

I’d like my multiplex mode to be only a little more complex, in that it will need more than one open/close pairs. To get started I wrote this, which does not seem to work:

define (function (require, exports, module) {
	var CodeMirror = brackets.getModule ("thirdparty/CodeMirror2/lib/codemirror");
	var LanguageManager = brackets.getModule ("language/LanguageManager");

	CodeMirror.defineMode ("twig_html", function (config) {
		return CodeMirror.multiplexingMode (
			CodeMirror.getMode (config, "htmlmixed"), {
				open: /{%/, close: /%}/,
				mode: CodeMirror.getMode (config, "twig"),
				// parseDelimiters: true
			}
		);
	});

	LanguageManager.defineLanguage ("twig_html", {
		name: "Twig-HTML",
		mode: "twig_html"
	});
});

What did I do wrong with that?

And, to follow, how do I go about adding more open/close pairs? Is that done with longer RegEx in each open: and close:, or is there a way to make multiple sets of open: and close:?

1 Like

You code pretty much works. You did need to turn on parseDelimiters. Here’s what I have:

CodeMirror.defineMode("twig_html", function (config) {
  return CodeMirror.multiplexingMode (
    CodeMirror.getMode(config, "text/html"), {
      open: /\{[%#]/, close: /[%#]\}/,
      mode: CodeMirror.getMode(config, "twig"),
      parseDelimiters: true
    });
});

And yes, you can extend the regexps to parse other delimiters (though it’s not 100% correct – this’ll also match {% ... #}). You could also add multiple sub-modes with different delimiters.

1 Like

Thanks!

Is it “better” to use an extended RegEx to match multiple open/close cases, or sequential sub-modes? Are there speed or memory concerns?

It should not significantly matter for performance – it’ll allocate another mode object, but those aren’t big.

Any idea on how to make twig syntax highlighted inside html attributes?

Example:

<img class="forum-avatar"
     src="http://forum.kozovod.com{{ item.user.avatar_template|replace({'{size}': '30'}) }}" />

Currently, it is not:

You’ll have to also recognize {{ and }} as delimiters, I guess.

1 Like