Styles collide on mixed language parsing

Hi all,
I’m having an issue with mixed language parsing. For context, I have a general templating grammar that looks like this -

@top TemplateString { (Expression | StringContent)* }

@local tokens {
    ExpressionStart[closedBy=ExpressionEnd]{ "{{" }
    @else StringContent

@precedence {

@skip {} {
    Expression {
        ExpressionStart (JavaScriptText* | "") ExpressionEnd

@local tokens {
  ExpressionEnd[openedBy=ExpressionStart] { "}}" }
  @else JavaScriptText

Using this grammar, I wanted to make a parser that parses external markdown and javascript within the expressions.
So I modified my parser as so -

const mixedMarkdownParser = templateStringParser.configure({
  wrap: parseMixed((node) => {
    if (node.type.isTop) {
      return {
        parser: markdownLanguage.language.parser,
        overlay: (node) => {
          return === 'StringContent'
    } else if ( === 'JavaScriptText') {
      return { parser: javascriptLanguage.parser }
    } else {
      return null

Where the markdown and javascript parsers are the default codemirror parsers.
However, when I plug this language support into the editor along with some syntax highlighting

syntaxHighlighting(HighlightStyle.define(markdownHighlightStyles(), { scope: markdownLanguage })),

In the end result, the markdown syntax highlighting is applied to all of the code, ignoring the scoping.

A workaround I’ve found is adding syntax highlighting for the javascript that sets all to initial, but here, the braces still adopt the markdown styles, even though I don’t believe they should have any styling?

syntaxHighlighting(HighlightStyle.define([], { scope: javascriptLanguage, all: 'initial' }))

How would I get it to the ideal case where both the braces and brackets have no styling?

This is specific to headers, right? The highlighting for those uses /... syntax, which causes it to apply to all text within the node. That currently also gets applied across tree boundaries. I can see how that would be surprising. This patch changes that.

Hey Marjin,
Thank you for the fast response!
However, I don’t think this patch fixes my issue.
For example, with this text
Everything is underlined, while I believe with your fix only the “# " before and " a” after should be underlined.
While debugging the code, I noticed the overlay ranges are calculated as expected as well, with the ranges being [0, 2] and [6, 8]
Looking at the span classes too, the grouping doesn’t seem right to me
I tried debugging a bit and I think this is unintentional and has to do with startSpan being called at the wrong time, but I don’t fully understand the file yet and would love your input.

Oh, that was a bug. This patch should fix it.

Thank you so much! This fixed it!