highlightjs / highlight.js

JavaScript syntax highlighter with language auto-detection and zero dependencies.
https://highlightjs.org/
BSD 3-Clause "New" or "Revised" License
23.3k stars 3.52k forks source link

Multi-Class / multi-matching breaks wrapping matcher #3101

Closed NullVoxPopuli closed 3 years ago

NullVoxPopuli commented 3 years ago

Describe the issue I'm trying to highlight an HTML-like language, with this:

const TAG_NAME_RE = regex.concat(/[A-Z_]/, regex.optional(/[A-Z0-9:_.-]*:/), /[A-Z0-9_.-]*/);

  return {
    name: 'Ember.JS, Glimmer',
    aliases: [
      'hbs',
      'html.hbs',
      'html.handlebars',
      'htmlbars'
    ],
    case_insensitive: true,
    contains: [
      hljs.COMMENT(/\{\{!--/, /--\}\}/),
      hljs.COMMENT(/\{\{!/, /\}\}/),
      hljs.COMMENT(/<!--/, /-->/),
      // open tag
      {
        className: 'tag',
        begin: regex.concat(
          /<:?/,
          regex.lookahead(regex.concat(
            TAG_NAME_RE,
            regex.either(/\/>/, />/, /\s/)
          ))
        ),
        end: /\/?>/,
        contains: [
    className: {
      1: 'attribute',
      2: 'operator'
    },
    match: [
      /[A-Za-z0-9-_]+/,
      /=/
    ]
        ]
      },
    ]
  };

Which language seems to have the issue? I'm writing it :)

Are you using highlight or highlightAuto?

Whatever the developer.html uses ...

Sample Code to Reproduce

<AngleBraketComponent
  @mustache={{@bla}}
  @number=123
  {{modifier @arg (sub-exp 1 "<- num" (concat "string" "another"))}}
  data-test-id="test"
  class="my-class" as |test|>

The developer.html shows: image

Expected behavior The tag wraps all the way around until the >

Additional context if you clear the contains array, the tag is correctly outlining the entire tag.

joshgoebel commented 3 years ago

Note to self: This is a bug in #3081. startsMode accounts for the new multi-class stuff, but endsMode doesn't so it's closing an extra tag that it should not.

joshgoebel commented 3 years ago

Fixed in the PR.