Как получить подсветку синтаксиса в Sublime для встроенных тегов webgl / glsl - PullRequest
0 голосов
/ 15 февраля 2019

Я пытаюсь получить подсветку / раскраску синтаксиса для фрагментного шейдера glsl в теге сценария в html-файле.

Даже если я установил все связанные Синтаксические пакеты шейдеров в SublimeТекст я до сих пор не получаю подсветку синтаксиса.Я полагаю, что те только исправляют это для внешних файлов или для файлов не HTML.Но я использую внутренний тег сценария.

Кто-нибудь сталкивался с этим?

uncolored syntax for glsl in sublime

Ответы [ 3 ]

0 голосов
/ 15 февраля 2019

Действительно, вы правы в том, что в Sublime определение синтаксиса обычно относится к определенному типу файла на основе внешних критериев: расширение, которое имеет файл, первая строка файла (например, bash shebang) или пользователь, специально переопределяющийавтоматическое обнаружение.

Один синтаксис может позволить другому временно «взять под контроль» выделение синтаксиса, но это должно быть осознанное решение, реализованное автором определения базового синтаксиса.Система должна знать, когда ей следует ввести новый синтаксис, когда он должен вернуться к предыдущему и (что наиболее важно), какой синтаксис фактически использовать между ними.

Например, Sublime поставляется с JavaScriptсинтаксис, который применяется к .js файлам сам по себе, но синтаксис HTML, который поставляется вместе с ним, также содержит правило, позволяющее выделять содержимое соответствующего тега <script> как JavaScript, передавая управление этому синтаксису и возвращая его обратно.когда появляется включающий тег </script>.

Таким образом, в вашем случае то, что вы хотите сделать, технически возможно, но, так сказать, не работает "из коробки";вам нужен HTML-синтаксис, который знает, как обрабатывать теги этого типа специально.Такой синтаксис может уже существовать в управлении пакетами.Это также модификация, которую вы можете сделать сами, если хотите.В оставшейся части этого ответа вы узнаете, как это сделать (и внизу есть ссылка на измененный файл).


Основная идея заключается в том, что мы собираемся создать override файла синтаксиса HTML, который поставляется с Sublime.Как следует из названия, это означает, что файл, который мы создаем, всегда будет использоваться вместо файла, который поставляется с Sublime прозрачно.Однако обратите внимание, что даже если основной файл будет обновлен, ваш измененный файл все равно будет использоваться (и вы не получите прямого предупреждения).Одна из особенностей пакета OverrideAudit (отказ от ответственности: я автор) - сообщить вам, когда это произойдет, чтобы вы могли быть уверены, что не пропустите новые функции или исправления ошибок в базовом пакете.file.

В этих инструкциях также предполагается, что вы используете последнюю стабильную сборку 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, чтобы включить дополнительные элементы.

3.Включите контекст, который встраивает синтаксис GLSL

Далее в файле (в сборке 3176 это примерно в строке 315 или около того после внесения вышеуказанного изменения) находится контекст с именем script-javascript, который содержит правила синтаксиса для знаниякак выделить содержимое тега <script> на основе 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)

Первые несколько строк содержат логику для синтаксиса, выделяющую остальные атрибуты в <script>, которыеследуйте атрибуту type.Содержание set - это магия здесь;они говорят, что если тело тега не пустое, содержимое должно быть подсвечено с помощью embed с помощью синтаксиса Javascript, и что закрывающий тег </script> - это то, что экранирует 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)

Как мы видим, это почти идентично приведенному выше, но используется другая область (болееоб этом ниже).

4.Сообщите тегу script о наших новых правилах

Мы заложили основу, чтобы теперь все связать.Ниже в файле (в 3176 это примерно строка 390 после вышеуказанных изменений) есть набор правил, озаглавленный 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> type атрибут, чтобы увидеть, что должно происходить с содержимым этого конкретного тега.Специально указанное здесь правило использует переменную, описанную выше, чтобы определить, что это тег JavaScript, и использует правило, на которое мы только что посмотрели, для встраивания синтаксиса JavaScript.

Прямо под этим match (порядок правил имеет значение)мы добавим нашу собственную 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 немедленно перекомпилирует измененный файл синтаксиса и запустит его в действие.Когда это будет сделано, консоль Sublime (View > Show Console) сообщит generating syntax summary.Если вы не видите никаких сообщений об ошибках, вы готовы к работе:

Sample of the syntax in action

Полная версия файла с упомянутыми изменениями:доступно в этой сущности для целей сравнения и использовалось для создания вышеуказанного изображения.Суть изложена в базовом файле в качестве ревизии 1, а модификации - в версии 2, поэтому легко увидеть, какие именно изменения были внесены в файл.


Заключительные замечания

Стоит отметить, что данный пакет на самом деле предоставляет три различных синтаксиса (Cg, HLSL и GLSL).Вышеуказанные модификации синтаксиса обрабатывают только встраивание синтаксиса GLSL, которое, как я догадался, было тем, к чему вы стремились.

Следуя тем же инструкциям, что и выше, вы можете поменять используемый синтаксис или добавить правила и для остальных (при условии, что вы знаете, что type должно идти в теге <script>, чтобы различать их).Те же правила также будут применяться, если есть другой синтаксис, который предоставляет субъективно «лучший» опыт выделения.

Важной частью головоломки является scope, который используется во встроенном синтаксисе.В приведенном выше примере мы использовали source.glsl, что определено непосредственно в определении синтаксиса для этого типа файла в используемом вами пакете.

Другие области в этом пакете: source.cgи source.hlsl.Самый простой способ определить подходящую область - создать новый файл, использовать соответствующий элемент Set Syntax: из командной палитры, чтобы установить синтаксис для пустого буфера, и использовать Tools > Developer > Show Scope Name, чтобы получить всплывающее окно, которое сообщит вам.

0 голосов
/ 20 февраля 2019

Ответы были немного слишком сложными по сравнению с тем, насколько я ленив:

Измените:

<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' при выпуске в производство.

0 голосов
/ 15 февраля 2019

не прямой ответ, а альтернативное решение.

Используя 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 (извините, не сублиметекст) я считаю, что вы можете пометить литералы шаблона с помощьюязык, чтобы выделить его

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