Sublime Text 自定义语法高亮

3

我正在开发一个自定义语法高亮功能,并从HTML语法中复制了一些片段,因为这部分非常相似。我现在卡在了尝试弄清如何对标签内的文本进行高亮的问题上。以下是我的定义:

- match: "(</?)([a-zA-Z0-9:]+)"
  captures:
    1: punctuation.definition.tag.begin.html
    2: entity.name.tag.other.html
  push:
    - meta_scope: meta.tag.other.html
    - match: '>'
      scope: punctuation.definition.tag.end.html
      pop: true
    - match: '.'
      scope: string.quoted.single.html

示例文本:

<file bash>
Some bash code block
Some bash code block
</file>

我的代码可以突出显示括号<>filebash关键字,但我无法弄清如何添加颜色来突出显示内部块。最终我希望将其作为块注释或类似的东西,以便它能够突出显示。有什么建议吗?
我需要一个解决方案,避免为没有闭合标签的标签添加注释突出显示。例如,在我正在处理的标记中,有某些标记不使用关闭标记,例如<tag without close>,它没有</tag>。是否有任何方法在正则表达式中添加排除条件,只在有开放和关闭标记时起作用,而当只有开放标记时不起作用?
<tag without close>
This should not be a comment.

<file bash>
This should be a comment.
</file>

This also should not be a comment.

只有一小部分标签会像上面的<tag>一样使用,主要用于元数据。

1个回答

2
一种方法,基于对<style><script>标签内部管理的松散理解,是使用一个具有pop方法的with_prototype
- match: '(?:^\s+)?(<)([a-zA-Z0-9:]+)\b(?![^>]*/>)'
  captures:
    1: punctuation.definition.tag.begin.html
    2: entity.name.tag.other.html
  push:
    - match: '(</)(\2)(>)'
      captures:
        1: punctuation.definition.tag.begin.html
        2: entity.name.tag.other.html
        3: punctuation.definition.tag.end.html
      pop: true
    - match: '>'
      scope: punctuation.definition.tag.end.html
      push:
        - match: '.'
          scope: comment.block.html
      with_prototype:
        - match: (?=</\2)
          pop: true
        - include: main
    - match: '.'
      scope: string.quoted.single.html

请注意,这里的 ([a-zA-Z0-9:]+) 匹配任何有效的标签名称,就像您在问题中一样,而 \2 用于稍后匹配该组,在立即解除耦合的 match 条件和 with_prototype 条件中都使用。with_protoype 定义了应用于当前上下文中的所有内容的模式,因此我们在达到 </file> 时使用它来确保我们弹出类似注释的高亮显示,而不是将其视为注释的一部分。
with_prototype 中,- include: main 语句确保您的类似注释的内容中的任何标签都像外部的 <file> 标签一样运行。例如,下面的 <hello> 的行为与 <file> 相同。
<file bash>
Some bash code block
<hello stuff>
Some bash code block
</hello>
Some bash code block
</file>

如果您有没有匹配结束标记的标签,可以通过在堆栈中更高的位置定义这些标签的特定行为来覆盖此行为,例如:
- match: '(?:^\s+)?(<)(hello)\b(?![^>]*/>)'
  captures:
    1: punctuation.definition.tag.begin.html
    2: entity.name.tag.other.html
  push:
    - match: '>'
      scope: punctuation.definition.tag.end.html
      pop: true
    - match: '.'
      scope: string.quoted.single.html

如果这段代码出现在 match: '(?:^\s+)?(<)([a-zA-Z0-9:]+)\b(?![^>]*/>)' 之前,任何 <hello> 标签都不会触发类似注释的高亮。

这段文字不是 comment.block.html。

一些 bash 代码块 一些 bash 代码块 一些 bash 代码块


哇,这太棒了,比我想要的要先进得多!还感谢您的解释,这有助于学习。这段代码在99%的情况下都很好用,除非没有闭合标签。 - user1781482
在什么情况下,您希望将一个块突出显示为注释,而没有结束标记?@user1781482 - Robin James Kerrison
我猜想的想法是将开标签和闭标签之间的任何内容视为块。 如果只有开标签,而没有闭标签,则不会有任何块。 - user1781482
也许这应该分成两个独立的部分,以避免过于复杂化。因此,一种情况是突出显示<标签中的某些文本>,另一种情况是<标签开头>块引用文本</标签结尾> - user1781482
让我们在聊天中继续这个讨论 - Robin James Kerrison
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接