如何在Sublime中为webgl / glsl内联脚本标签突出显示语法

时间:2019-02-15 00:18:23

标签: html windows glsl sublimetext3 webgl

我正在尝试在html文件的脚本标签中为glsl片段着色器进行语法突出显示/着色。

即使我在Sublime Text中安装了所有相关的Shader Syntax packages,我仍然没有突出显示语法。我相信这些只能解决外部文件或非HTML文件的问题。但是我正在使用内部脚本标签。

有人碰到这个吗?

uncolored syntax for glsl in sublime

3 个答案:

答案 0 :(得分:4)

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

一种语法有可能允许另一种语法暂时“控制”语法突出显示,但是这需要基础语法定义的作者有意识地做出决定。系统需要知道什么时候应该输入新的语法,什么时候应该退回到前一个语法,以及(最重要的是)在两者之间实际使用什么语法。

例如,Sublime附带了自己适用于.js文件的JavaScript语法,但附带的HTML语法还包括允许适当的<script>标签内容的规则通过将控制权交给该语法将其突出显示为JavaScript,并在出现</script>标记时将其取回。

因此,在您的情况下,您想做的事在技术上是可能的,但可以说“开箱即用”是行不通的。您需要一种HTML语法,该语法应专门处理该类型的脚本标记。包控制中可能已经存在这样的语法。如果您愿意,这也是可以进行的修改。该答案的其余部分将告诉您如何执行此操作(底部也有指向已修改文件的链接)。


基本思想是,我们将创建Sublime随附的HTML语法文件的override。顾名思义,这意味着将始终使用我们正在创建的文件代替Sublime随附的文件。但是请注意,即使基础文件得到更新,更改后的文件仍将被使用(并且不会收到直接警告)。 OverrideAudit程序包的功能之一(免责声明:我是作者)是告诉您何时发生这种情况,因此可以确保您不会错过基础文件中的新功能或错误修复。

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

1。打开HTML语法进行编辑

如果尚未安装,请安装PackageResourceViewer软件包,然后从命令面板中使用命令PackageResourceViewer: Open Resource(请确保您不小心选择了{{1} }变体),然后首先选择extract程序包,然后选择HTML文件。这将打开文件以供编辑;保存文件时,将自动为您创建替代。

在幕后,这是在HTML.sublime-syntax文件夹中创建一个名为HTML的文件夹(使用Packages查找该文件夹),并在其中存储资源文件的副本。删除该文件将恢复原始语法。

您可以使用内置的Preferences > Browse Packages...命令打开View Package File资源并将其保存在适当的位置,以手动创建替代。如果这样做,则需要关闭并重新打开该文件,因为它将以只读方式打开。

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

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

javascript_mime_type

在此之后,我们将创建我们自己的变量,该变量包含正则表达式以匹配script标记的 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

这可能需要扩展,也可能不需要扩展(我不熟悉此标签如何用于WebGL)。如果可能的内容存在多种变体,则可以像上面的JavaScript示例中一样扩展它,以包括其他内容。

3。包含嵌入GLSL语法的上下文

在文件中进一步向下(在内部版本3176中,在进行上述更改之后大约在315行左右)是名为 shader_mime_type: |- (?ix)(?: x-shader/x-fragment ) 的上下文,该上下文包含用于了解如何突出显示基于javascript的内容的语法规则script-javascript标签,看起来像这样:

<script>

前几行包含语法逻辑,以突出显示 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) 属性之后的<script>中的其余属性。 type的内容很神奇。他们说,如果标记的主体不为空,则应该通过set突出显示Javascript语法来突出显示内容,而结束的embed标记是逃离</script>并转到回到常规HTML。

在这里,我们将创建自己的部分以挂起embed脚本:

glsl

我们可以看到,这几乎与上面的相同,但是使用了不同的范围(更多内容见下文)。

4。告诉 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) 标签有关我们的新规则

我们奠定了基础,现在将所有内容捆绑在一起。在文件的下方(在3176中,经过上述更改,这大约是第390行),有一组名为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 标签的<script>属性中应用的规则,以查看该特定标签的内容应如何处理。这里专门引用的规则使用上面概述的变量来确定这是一个JavaScript标记,并使用我们刚刚看过的规则嵌入JavaScript语法。

在此type的正下方(规则的顺序很重要),我们将使用我们自己的变量和规则集添加自己的match来模仿这一点:

match

5。启用更改

在完成所有更改后,您要做的只是 - 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 该文件以使它们处于活动状态。一旦这样做,Sublime将立即重新编译已更改的语法文件并将其生效。 Sublime控制台(save)执行此操作时将说出View > Show Console。如果您没有看到任何错误消息,就可以开始:

Sample of the syntax in action

this gist中提供了讨论了更改的完整版本的文件,用于比较目的,并用于生成上述图像。设计要点的基本文件版本为修订版1,修改版本为版本2,因此可以很容易地确切看到对该文件进行了哪些更改。


最后的笔记

值得一提的是,所讨论的软件包实际上提供了三种不同的语法(generating syntax summaryCgHLSL)。上面的语法修改仅处理GLSL语法嵌入,我猜这正是您想要的。

按照与上述相同的说明,您可以交换使用的语法或为其他语法添加规则(假设您知道GLSL标记中应该包含什么type以区分它们)。如果存在另一种可以提供主观“更好”突出显示体验的语法,则同样的规则也将适用。

难题的重要部分是嵌入式语法中使用的<script>。在上面的示例中,我们使用了scope,它是直接在您使用的包中为此文件类型的语法定义中定义的。

该软件包中的其他范围是source.glslsource.cg。确定适当范围的最简单方法是创建一个新文件,在命令面板中使用适当的source.hlsl项设置空缓冲区的语法,然后使用Set Syntax:获得一个弹出窗口,该弹出窗口将告诉你。

答案 1 :(得分:1)

不是直接答案,而是替代解决方案。

使用ES6 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';
...

这样您就可以设置Sublime以突出显示.glsl文件中的代码

如果您想支持较旧的浏览器,则可以使用类似rollup的格式将所有文件合并为一个文件。

three.js就是这样。

同样在VSCode中(抱歉,不是sublimetext),我相信您可以使用一种语言标记模板文字以使其突出显示

const shaderSource = /* glsl */`
void main() {
  gl_Position = vec4(0, 0, 0, 1);
}

答案 2 :(得分:0)

与我的懒惰相比,答案有些复杂:

更改:

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

收件人:

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

然后javascript在glsl的第一行失败,但是我们不需要js进行解析,所以没关系。因此您只会在浏览器中看到该脚本标记的一个错误。

但是所有其他脚本标签都运行。并且语法高亮适用于glsl。 Sublime认为它是javascript,但似乎在颜色方面做得很好。我主要需要用于调试和测试的颜色,因此我可以以这种方式使用它,只需在发布产品时添加type='x-shader/x-fragment'

相关问题