代码之家  ›  专栏  ›  技术社区  ›  Shai UI

如何在Sublime中获得webgl/glsl内联脚本标记的语法高亮显示

  •  0
  • Shai UI  · 技术社区  · 6 年前

    即使我安装了所有相关的 Shader Syntax packages

    有人碰到过这个吗?

    uncolored syntax for glsl in sublime

    0 回复  |  直到 6 年前
        1
  •  8
  •   OdatNurd    6 年前

    实际上,在Sublime中,语法定义通常是指基于外部条件的特定类型的文件:文件的扩展名、文件的第一行(例如bash shebang)或专门重写自动检测的用户。

    一种语法允许另一种语法临时“控制”语法高亮显示是可能的,但这需要由基本语法定义的作者有意识地执行。系统需要知道什么时候应该输入一个新的语法,什么时候应该回到上一个语法,以及(最重要的)在这两者之间实际使用什么语法。

    例如,Sublime附带了一个适用于 .js 但它附带的HTML语法还包括一个规则,该规则允许 <script> 通过将控制权交给该语法,并在 </script> 标签出现。

    所以在你的情况下,你想做的在技术上是可能的,但可以说,它不能“开箱即用”;您需要一个HTML语法,它知道如何专门处理这种类型的脚本标记。包控件上可能已经存在这样的语法。这也是一个修改,你可以让自己,如果你这么想。这个答案的其余部分将告诉您如何做到这一点(底部还有一个指向已修改文件的链接)。


    基本的想法是我们要创造一个 override 与Sublime一起提供的HTML语法文件。顾名思义,这意味着我们正在创建的文件将始终被用来代替Sublime Transparency附带的文件。但是请注意,即使基础文件得到更新,更改后的文件仍将被使用(并且不会得到直接警告)。它的一个特点 OverrideAudit 软件包(免责声明:我是作者)告诉你什么时候会发生这种情况,这样你就可以确保你不会错过基础文件中的新特性或错误修复。

    这些说明还假设您使用的是最新稳定的Sublime版本,目前是3176。新的构建通常会带来新的语法,因此,如果您现在运行的是旧版本(如果您来自神秘的未来,则运行新版本),则基本指令保持不变,但文件的内容可能不同。正如我们将看到的,我们的更改是基于复制现有的功能。

    1打开HTML语法进行编辑

    如果尚未安装,请安装 PackageResourceViewer 打包,然后使用命令 PackageResourceViewer: Open Resource 从命令选项板(请确保您不会意外地选择 extract 选择第一个 HTML 包,然后 HTML.sublime-syntax 文件。打开文件进行编辑;保存文件时,将自动为您创建覆盖。

    在幕后,这是创建一个名为 HTML格式 Packages Preferences > Browse Packages... 并在其中存储资源文件的副本。删除该文件将恢复原始语法。

    View Package File 内置命令打开 HTML/HTML.sublime-syntax

    2告诉语法如何识别着色器标记

    在打开的语法文件的顶部附近是一组 variables ,在语法中是一种提供命名正则表达式的方法,以使以下步骤更易于阅读。变量列表中有一个名为 javascript_mime_type 定义如下:

      javascript_mime_type: |-
        (?ix)(?:
          # https://mimesniff.spec.whatwg.org/#javascript-mime-type
          (?:application|text)/(?:x-)?(?:java|ecma)script
          | text/javascript1\.[0-5]
          | text/jscript
          | text/livescript
        )
    

    在下面,我们将创建自己的变量,该变量包含正则表达式以匹配 type 脚本标记的属性。例如:

      shader_mime_type: |-
        (?ix)(?:
          x-shader/x-fragment
        )
    

    这可能需要扩展,也可能不需要扩展(我不熟悉WebGL如何使用这个标记)。如果可能的内容有多个变体,则可以像上面的JavaScript示例那样进行扩展,以包含额外内容。

    三。包括嵌入GLSL语法的上下文

    在文件的下面(在build3176中,在进行上述更改之后,大约在第315行左右)是一个名为 script-javascript 它包含了解如何突出显示基于javascript的 <脚本>

      script-javascript:
        - meta_content_scope: meta.tag.script.begin.html
        - include: script-common
        - match: '>'
          scope: punctuation.definition.tag.end.html
          set:
            - include: script-close-tag
            - match: (?=\S)
              embed: scope:source.js
              embed_scope: source.js.embedded.html
              escape: (?i)(?=(?:-->\s*)?</script)
    

    前几行包括语法逻辑,用于突出显示 <脚本> 跟随 类型 属性。内容 set embed 这是一个结束语 </脚本> 嵌入 并返回到常规HTML。

    在这里,我们将创建我们自己的部分来悬挂 glsl

      script-glsl:
        - meta_content_scope: meta.tag.script.begin.html
        - include: script-common
        - match: '>'
          scope: punctuation.definition.tag.end.html
          set:
            - include: script-close-tag
            - match: (?=\S)
              embed: scope:source.glsl
              embed_scope: source.glsl.embedded.html
              escape: (?i)(?=(?:-->\s*)?</script)
    

    正如我们所看到的,这与上面的内容几乎相同,但是使用了不同的范围(下面将详细介绍)。

    script 我们的新规则

    script-type-decider . 在这个上下文中有五条匹配规则,所以为了简洁起见,我们只在这里显示第一条。

      script-type-decider:
        - match: (?i)(?={{javascript_mime_type}}(?!{{unquoted_attribute_value}})|'{{javascript_mime_type}}'|"{{javascript_mime_type}}")
          set:
            - script-javascript
            - tag-generic-attribute-meta
            - tag-generic-attribute-value
    

    <脚本> 类型

    就在这下面 match (规则的顺序很重要)我们将添加我们自己的规则 比赛 要模拟这个,请使用我们自己的变量和规则集:

        - match: (?i)(?={{shader_mime_type}}(?!{{unquoted_attribute_value}})|'{{shader_mime_type}}'|"{{shader_mime_type}}")
          set:
            - script-glsl
            - tag-generic-attribute-meta
            - tag-generic-attribute-value
    

    5激活更改

    save 使其处于活动状态的文件。一旦您这样做,Sublime将立即重新编译更改后的语法文件并将其付诸实施。崇高的控制台( View > Show Console )会说 generating syntax summary

    Sample of the syntax in action

    中提供了包含所述更改的完整版本的文件 this gist 用于比较目的,用于生成上述图像。要点与基础文件(修订版1)和修改版(修订版2)一起列出,因此很容易准确地看到对该文件所做的更改。


    期末笔记

    值得一提的是,所讨论的包实际上提供了三种不同的语法( Cg , HLSL GLSL GLSL公司 语法嵌入,我猜这就是你想要的。

    按照上面相同的说明,您可以交换所使用的语法或为其他语法添加规则(假设您知道 类型 我们应该去公园 < 标记以区分它们)。如果有另一种语法提供主观上“更好”的突出显示体验,同样的规则也适用。

    这个难题的重要部分是 scope source.glsl ,这是直接在您使用的包中此文件类型的语法定义中定义的内容。

    该包中的其他作用域是 source.cg source.hlsl . 确定适当范围的最简单方法是创建一个新文件,使用适当的 Set Syntax: Tools > Developer > Show Scope Name 得到一个弹出窗口来告诉你。

        2
  •  1
  •   gman    6 年前

    不是直接的回答,而是另一种解决办法。

    import 可以将着色器存储在单独的文件中

    // some-vertex-shader.glsl
    export default `
    void main() {
      gl_Position = vec4(0, 0, 0, 1);
    }
    `;
    

    然后在JavaScript中可以像这样包含它

    import someVertexShaderSource from 'path/to/some-shader-source.glsl';
    ...
    

    然后你可以用 rollup 如果要支持旧浏览器,请将所有文件合并为一个。

    这是什么 three.js 做。

    const shaderSource = /* glsl */`
    void main() {
      gl_Position = vec4(0, 0, 0, 1);
    }
    
        3
  •  0
  •   Shai UI    6 年前

    与我的懒惰相比,答案有点太复杂了:

    更改:

    <script type="x-shader/x-fragment">
      // glsl code here not syntax highlighting
    </script>
    

    <script>
      // glsl code here now with syntax highlighting
    </script>
    

    但所有其他脚本标记都会运行。语法高亮显示适用于glsl。Sublime认为它是javascript,但似乎在颜色方面做得很好。我主要需要的颜色只是为了调试和测试,所以我可以用这种方式生活,只是添加 type='x-shader/x-fragment' 当你开始生产的时候。