diff --git a/HTML.yaml b/HTML.yaml index 4121557..6b73f5c 100644 --- a/HTML.yaml +++ b/HTML.yaml @@ -13,9 +13,34 @@ first_line_match: (?i)<(!DOCTYPE\s*)?html scope: text.html.basic variables: + attribute_char: (?:[^ "'>/=\x00-\x1f\x7f-\x9f]) unquoted_attribute_value: (?:[^\s<>/''"]|/(?!>))+ not_equals_lookahead: (?=\s*[^\s=]) + block_tag_name: |- + (?ix)(?: + address|applet|article|aside|blockquote|center|dd|dir|div|dl|dt|figcaption|figure|footer|frame|frameset|h1|h2|h3|h4|h5|h6|header|iframe|menu|nav|noframes|object|ol|p|pre|section|ul + )\b + + inline_tag_name: |- + (?ix)(?: + abbr|acronym|area|audio|b|base|basefont|bdi|bdo|big|br|canvas|caption|cite|code|del|details|dfn|dialog|em|font|head|html|i|img|ins|isindex|kbd|li|link|map|mark|menu|menuitem|meta|noscript|param|picture|q|rp|rt|rtc|ruby|s|samp|script|small|source|span|strike|strong|style|sub|summary|sup|time|title|track|tt|u|var|video|wbr + )\b + + form_tag_name: |- + (?ix)(?: + button|datalist|input|label|legend|meter|optgroup|option|output|progress|select|template|textarea + )\b + + 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 + ) + contexts: immediately-pop: - match: '' @@ -38,16 +63,18 @@ contexts: - include: tag-generic-attribute - include: string-double-quoted - include: string-single-quoted - - match: ' scope: invalid.illegal.bad-comments-or-CDATA.html - match: ]*/>)' + - match: (<)((?i:style))\b captures: 0: meta.tag.style.begin.html 1: punctuation.definition.tag.begin.html 2: entity.name.tag.style.html - push: - - match: (?i)() - captures: - 0: meta.tag.style.end.html - 1: punctuation.definition.tag.begin.html - 2: entity.name.tag.style.html - 3: punctuation.definition.tag.end.html - pop: true - - match: '(>)\s*' - captures: - 1: meta.tag.style.begin.html punctuation.definition.tag.end.html - embed: scope:source.css - embed_scope: source.css.embedded.html - escape: (?i)(?=)' - pop: true - - include: tag-attributes - - match: '(<)((?i:script))\b(?![^>]*/>)(?![^>]*(?i:type.?=.?text/((?!javascript).*)))' + push: style-css + - match: '(<)((?i:script))\b' captures: 0: meta.tag.script.begin.html 1: punctuation.definition.tag.begin.html 2: entity.name.tag.script.html - push: - - match: (?i)(-->)?\s*() - captures: - 0: meta.tag.script.end.html - 1: comment.block.html punctuation.definition.comment.html - 2: punctuation.definition.tag.begin.html - 3: entity.name.tag.script.html - 4: punctuation.definition.tag.end.html - pop: true - - match: '(>)\s*()?\s*)' - pop: true - - include: tag-attributes + push: script-javascript - match: ( scope: invalid.illegal.incomplete.html - entities-common: - - match: (&)([a-zA-Z0-9]+|#[0-9]+|#x[0-9a-fA-F]+)(;) - scope: constant.character.entity.html + + entities: + - match: (&#[xX])(\h+)(;) + scope: constant.character.entity.hexadecimal.html captures: 1: punctuation.definition.entity.html 3: punctuation.definition.entity.html - attribute-entities: - - include: entities-common - entities: - - include: entities-common - - match: '&' - scope: invalid.illegal.bad-ampersand.html + - match: (&#)([0-9]+)(;) + scope: constant.character.entity.decimal.html + captures: + 1: punctuation.definition.entity.html + 3: punctuation.definition.entity.html + - match: (&)([a-zA-Z0-9]+)(;) + scope: constant.character.entity.named.html + captures: + 1: punctuation.definition.entity.html + 3: punctuation.definition.entity.html + + style-css: + - meta_content_scope: meta.tag.style.begin.html + - include: style-common + - match: '>' + scope: punctuation.definition.tag.end.html + set: + - include: style-close-tag + - match: '' + embed: scope:source.css + embed_scope: source.css.embedded.html + escape: (?i)(?=(?:-->\s*)?' + scope: punctuation.definition.tag.end.html + set: + - include: style-close-tag + + style-close-tag: + - match: (?i)() + scope: meta.tag.style.end.html + captures: + 1: punctuation.definition.tag.begin.html + 2: entity.name.tag.style.html + 3: punctuation.definition.tag.end.html + pop: true + + style-common: + - include: style-type-attribute + - include: tag-attributes + - match: '/>' + scope: punctuation.definition.tag.end.html + pop: true + + style-type-attribute: + - match: (?i)\btype\b + scope: meta.attribute-with-value.html entity.other.attribute-name.html + set: + - meta_content_scope: meta.tag.style.begin.html meta.attribute-with-value.html + - match: = + scope: punctuation.separator.key-value.html + set: + - meta_content_scope: meta.tag.style.begin.html meta.attribute-with-value.html + - include: style-type-decider + - match: (?=\S) + set: style-css + + style-type-decider: + - match: (?i)(?=text/css(?!{{unquoted_attribute_value}})|'text/css'|"text/css") + set: + - style-css + - tag-generic-attribute-meta + - tag-generic-attribute-value + - match: (?i)(?=>|''|"") + set: + - style-css + - tag-generic-attribute-meta + - tag-generic-attribute-value + - match: (?=\S) + set: + - style-other + - tag-generic-attribute-meta + - tag-generic-attribute-value + + 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*)?' + scope: punctuation.definition.tag.end.html + set: + - meta_content_scope: text.html.embedded.html + - include: script-close-tag + - include: main + + script-other: + - meta_content_scope: meta.tag.script.begin.html + - include: script-common + - match: '>' + scope: punctuation.definition.tag.end.html + set: + - include: script-close-tag + + script-close-tag: + - match: \s*()\s*)?() + scope: meta.tag.script.end.html + captures: + 1: comment.block.html punctuation.definition.comment.end.html + 2: punctuation.definition.tag.begin.html + 3: entity.name.tag.script.html + 4: punctuation.definition.tag.end.html + pop: true + + script-common: + - include: script-type-attribute + - include: tag-attributes + - match: '/>' + scope: punctuation.definition.tag.end.html + pop: true + + script-type-attribute: + - match: (?i)\btype\b + scope: meta.attribute-with-value.html entity.other.attribute-name.html + set: + - meta_content_scope: meta.tag.script.begin.html meta.attribute-with-value.html + - match: = + scope: punctuation.separator.key-value.html + set: + - meta_content_scope: meta.tag.script.begin.html meta.attribute-with-value.html + - include: script-type-decider + - match: (?=\S) + set: script-javascript + + 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: (?i)(?=module(?!{{unquoted_attribute_value}})|'module'|"module") + set: + - script-javascript + - tag-generic-attribute-meta + - tag-generic-attribute-value + - match: (?i)(?=>|''|"") + set: + - script-javascript + - tag-generic-attribute-meta + - tag-generic-attribute-value + - match: (?i)(?=text/html(?!{{unquoted_attribute_value}})|'text/html'|"text/html") + set: + - script-html + - tag-generic-attribute-meta + - tag-generic-attribute-value + - match: (?=\S) + set: + - script-other + - tag-generic-attribute-meta + - tag-generic-attribute-value + string-double-quoted: - match: '"' scope: punctuation.definition.string.begin.html @@ -268,14 +417,17 @@ contexts: - include: entities tag-generic-attribute: - - match: '[a-zA-Z0-9:\-_.]+' + - match: (?={{attribute_char}}) scope: entity.other.attribute-name.html push: - tag-generic-attribute-meta - tag-generic-attribute-equals - - - match: '[a-zA-Z0-9:\-_.]+' - scope: entity.other.attribute-name.html + - generic-attribute-name + + generic-attribute-name: + - meta_scope: entity.other.attribute-name.html + - match: (?!{{attribute_char}}) + pop: true tag-generic-attribute-meta: - meta_scope: meta.attribute-with-value.html @@ -296,7 +448,7 @@ contexts: - match: '"' scope: punctuation.definition.string.end.html pop: true - - include: attribute-entities + - include: entities - match: "'" scope: punctuation.definition.string.begin.html set: @@ -304,9 +456,10 @@ contexts: - match: "'" scope: punctuation.definition.string.end.html pop: true - - include: attribute-entities + - include: entities - match: '{{unquoted_attribute_value}}' scope: string.unquoted.html + pop: true - include: else-pop tag-class-attribute: @@ -336,7 +489,7 @@ contexts: - match: '"' scope: punctuation.definition.string.end.html pop: true - - include: attribute-entities + - include: entities - match: "'" scope: punctuation.definition.string.begin.html set: @@ -345,9 +498,10 @@ contexts: - match: "'" scope: punctuation.definition.string.end.html pop: true - - include: attribute-entities + - include: entities - match: '{{unquoted_attribute_value}}' scope: string.unquoted.html meta.class-name.html + pop: true - include: else-pop tag-id-attribute: @@ -377,7 +531,7 @@ contexts: - match: '"' scope: punctuation.definition.string.end.html pop: true - - include: attribute-entities + - include: entities - match: "'" scope: punctuation.definition.string.begin.html set: @@ -386,9 +540,10 @@ contexts: - match: "'" scope: punctuation.definition.string.end.html pop: true - - include: attribute-entities + - include: entities - match: '{{unquoted_attribute_value}}' scope: string.unquoted.html meta.toc-list.id.html + pop: true - include: else-pop tag-style-attribute: @@ -429,7 +584,7 @@ contexts: tag-event-attribute: - match: |- (?x)\bon( - abort|autocomplete|autocompleteerror|blur|cancel|canplay + abort|autocomplete|autocompleteerror|auxclick|blur|cancel|canplay |canplaythrough|change|click|close|contextmenu|cuechange|dblclick|drag |dragend|dragenter|dragexit|dragleave|dragover|dragstart|drop |durationchange|emptied|ended|error|focus|input|invalid|keydown @@ -472,9 +627,13 @@ contexts: 0: string.quoted.single punctuation.definition.string.end.html - include: else-pop + # This is to prevent breaking syntaxes referencing the old context name + tag-stuff: + - include: tag-attributes + tag-attributes: - include: tag-id-attribute - include: tag-class-attribute - include: tag-style-attribute - include: tag-event-attribute - - include: tag-generic-attribute \ No newline at end of file + - include: tag-generic-attribute diff --git a/Vue Component.sublime-syntax b/Vue Component.sublime-syntax index 1459384..7539ace 100644 --- a/Vue Component.sublime-syntax +++ b/Vue Component.sublime-syntax @@ -5,9 +5,34 @@ file_extensions: [vue] first_line_match: (?i)<(!DOCTYPE\s*)?html scope: text.html.vue variables: + attribute_char: (?:[^ "'>/=\x00-\x1f\x7f-\x9f]) unquoted_attribute_value: (?:[^\s<>/''"]|/(?!>))+ not_equals_lookahead: (?=\s*[^\s=]) + block_tag_name: |- + (?ix)(?: + address|applet|article|aside|blockquote|center|dd|dir|div|dl|dt|figcaption|figure|footer|frame|frameset|h1|h2|h3|h4|h5|h6|header|iframe|menu|nav|noframes|object|ol|p|pre|section|ul + )\b + + inline_tag_name: |- + (?ix)(?: + abbr|acronym|area|audio|b|base|basefont|bdi|bdo|big|br|canvas|caption|cite|code|del|details|dfn|dialog|em|font|head|html|i|img|ins|isindex|kbd|li|link|map|mark|menu|menuitem|meta|noscript|param|picture|q|rp|rt|rtc|ruby|s|samp|script|small|source|span|strike|strong|style|sub|summary|sup|time|title|track|tt|u|var|video|wbr + )\b + + form_tag_name: |- + (?ix)(?: + button|datalist|input|label|legend|meter|optgroup|option|output|progress|select|template|textarea + )\b + + 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 + ) + contexts: immediately-pop: - match: '' @@ -18,8 +43,8 @@ contexts: pop: true main: - - include: langs - include: template-tag + - include: mustache-expression - match: (<\?)(xml) captures: @@ -33,16 +58,18 @@ contexts: - include: tag-generic-attribute - include: string-double-quoted - include: string-single-quoted - - match: scope: invalid.illegal.bad-comments-or-CDATA.html - match: ]*/>) + - match: (<)((?i:style))\b captures: 0: meta.tag.style.begin.html 1: punctuation.definition.tag.begin.html 2: entity.name.tag.style.html - push: - - match: (?i)() - captures: - 0: meta.tag.style.end.html - 1: punctuation.definition.tag.begin.html - 2: entity.name.tag.style.html - 3: punctuation.definition.tag.end.html - pop: true - - match: (>)\s* - captures: - 1: meta.tag.style.begin.html punctuation.definition.tag.end.html - embed: scope:source.css - embed_scope: source.css.embedded.html - escape: (?i)(?=) - pop: true - - include: tag-attributes - - match: (<)((?i:script))\b(?![^>]*/>)(?![^>]*(?i:type.?=.?text/((?!javascript).*))) + push: style-css + - match: (<)((?i:script))\b captures: 0: meta.tag.script.begin.html 1: punctuation.definition.tag.begin.html 2: entity.name.tag.script.html - push: - - match: (?i)(-->)?\s*() - captures: - 0: meta.tag.script.end.html - 1: comment.block.html punctuation.definition.comment.html - 2: punctuation.definition.tag.begin.html - 3: entity.name.tag.script.html - 4: punctuation.definition.tag.end.html - pop: true - - match: (>)\s*()?\s*) - pop: true - - include: tag-attributes + push: script-javascript - match: ( scope: invalid.illegal.incomplete.html - entities-common: - - match: (&)([a-zA-Z0-9]+|#[0-9]+|#x[0-9a-fA-F]+)(;) - scope: constant.character.entity.html + + entities: + - match: (&#[xX])(\h+)(;) + scope: constant.character.entity.hexadecimal.html captures: 1: punctuation.definition.entity.html 3: punctuation.definition.entity.html - attribute-entities: - - include: entities-common - entities: - - include: entities-common - - match: '&' - scope: invalid.illegal.bad-ampersand.html + - match: (&#)([0-9]+)(;) + scope: constant.character.entity.decimal.html + captures: + 1: punctuation.definition.entity.html + 3: punctuation.definition.entity.html + - match: (&)([a-zA-Z0-9]+)(;) + scope: constant.character.entity.named.html + captures: + 1: punctuation.definition.entity.html + 3: punctuation.definition.entity.html + + style-css: + - meta_content_scope: meta.tag.style.begin.html + - include: style-common + - match: '>' + scope: punctuation.definition.tag.end.html + set: + - include: style-close-tag + - match: '' + embed: scope:source.css + embed_scope: source.css.embedded.html + escape: (?i)(?=(?:-->\s*)?' + scope: punctuation.definition.tag.end.html + set: + - include: style-close-tag + + style-close-tag: + - match: (?i)() + scope: meta.tag.style.end.html + captures: + 1: punctuation.definition.tag.begin.html + 2: entity.name.tag.style.html + 3: punctuation.definition.tag.end.html + pop: true + + style-common: + - include: style-lang-attribute + + - include: style-type-attribute + - include: tag-attributes + - match: /> + scope: punctuation.definition.tag.end.html + pop: true + + style-type-attribute: + - match: (?i)\btype\b + scope: meta.attribute-with-value.html entity.other.attribute-name.html + set: + - meta_content_scope: meta.tag.style.begin.html meta.attribute-with-value.html + - match: = + scope: punctuation.separator.key-value.html + set: + - meta_content_scope: meta.tag.style.begin.html meta.attribute-with-value.html + - include: style-type-decider + - match: (?=\S) + set: style-css + + style-type-decider: + - match: (?i)(?=text/css(?!{{unquoted_attribute_value}})|'text/css'|"text/css") + set: + - style-css + - tag-generic-attribute-meta + - tag-generic-attribute-value + - match: (?i)(?=>|''|"") + set: + - style-css + - tag-generic-attribute-meta + - tag-generic-attribute-value + - match: (?=\S) + set: + - style-other + - tag-generic-attribute-meta + - tag-generic-attribute-value + + 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*)?' + scope: punctuation.definition.tag.end.html + set: + - meta_content_scope: text.html.embedded.html + - include: script-close-tag + - include: main + + script-other: + - meta_content_scope: meta.tag.script.begin.html + - include: script-common + - match: '>' + scope: punctuation.definition.tag.end.html + set: + - include: script-close-tag + + script-close-tag: + - match: \s*()\s*)?() + scope: meta.tag.script.end.html + captures: + 1: comment.block.html punctuation.definition.comment.end.html + 2: punctuation.definition.tag.begin.html + 3: entity.name.tag.script.html + 4: punctuation.definition.tag.end.html + pop: true + + script-common: + - include: script-lang-attribute + + - include: script-type-attribute + - include: tag-attributes + - match: /> + scope: punctuation.definition.tag.end.html + pop: true + + script-type-attribute: + - match: (?i)\btype\b + scope: meta.attribute-with-value.html entity.other.attribute-name.html + set: + - meta_content_scope: meta.tag.script.begin.html meta.attribute-with-value.html + - match: = + scope: punctuation.separator.key-value.html + set: + - meta_content_scope: meta.tag.script.begin.html meta.attribute-with-value.html + - include: script-type-decider + - match: (?=\S) + set: script-javascript + + 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: (?i)(?=module(?!{{unquoted_attribute_value}})|'module'|"module") + set: + - script-javascript + - tag-generic-attribute-meta + - tag-generic-attribute-value + - match: (?i)(?=>|''|"") + set: + - script-javascript + - tag-generic-attribute-meta + - tag-generic-attribute-value + - match: (?i)(?=text/html(?!{{unquoted_attribute_value}})|'text/html'|"text/html") + set: + - script-html + - tag-generic-attribute-meta + - tag-generic-attribute-value + - match: (?=\S) + set: + - script-other + - tag-generic-attribute-meta + - tag-generic-attribute-value + string-double-quoted: - match: '"' scope: punctuation.definition.string.begin.html @@ -263,14 +416,17 @@ contexts: - include: entities tag-generic-attribute: - - match: '[a-zA-Z0-9:\-_.]+' + - match: (?={{attribute_char}}) scope: entity.other.attribute-name.html push: - tag-generic-attribute-meta - tag-generic-attribute-equals + - generic-attribute-name - - match: '[a-zA-Z0-9:\-_.]+' - scope: entity.other.attribute-name.html + generic-attribute-name: + - meta_scope: entity.other.attribute-name.html + - match: (?!{{attribute_char}}) + pop: true tag-generic-attribute-meta: - meta_scope: meta.attribute-with-value.html @@ -291,7 +447,7 @@ contexts: - match: '"' scope: punctuation.definition.string.end.html pop: true - - include: attribute-entities + - include: entities - match: "'" scope: punctuation.definition.string.begin.html set: @@ -299,9 +455,10 @@ contexts: - match: "'" scope: punctuation.definition.string.end.html pop: true - - include: attribute-entities + - include: entities - match: '{{unquoted_attribute_value}}' scope: string.unquoted.html + pop: true - include: else-pop tag-class-attribute: @@ -331,7 +488,7 @@ contexts: - match: '"' scope: punctuation.definition.string.end.html pop: true - - include: attribute-entities + - include: entities - match: "'" scope: punctuation.definition.string.begin.html set: @@ -340,9 +497,10 @@ contexts: - match: "'" scope: punctuation.definition.string.end.html pop: true - - include: attribute-entities + - include: entities - match: '{{unquoted_attribute_value}}' scope: string.unquoted.html meta.class-name.html + pop: true - include: else-pop tag-id-attribute: @@ -372,7 +530,7 @@ contexts: - match: '"' scope: punctuation.definition.string.end.html pop: true - - include: attribute-entities + - include: entities - match: "'" scope: punctuation.definition.string.begin.html set: @@ -381,9 +539,10 @@ contexts: - match: "'" scope: punctuation.definition.string.end.html pop: true - - include: attribute-entities + - include: entities - match: '{{unquoted_attribute_value}}' scope: string.unquoted.html meta.toc-list.id.html + pop: true - include: else-pop tag-style-attribute: @@ -424,7 +583,7 @@ contexts: tag-event-attribute: - match: |- (?x)\bon( - abort|autocomplete|autocompleteerror|blur|cancel|canplay + abort|autocomplete|autocompleteerror|auxclick|blur|cancel|canplay |canplaythrough|change|click|close|contextmenu|cuechange|dblclick|drag |dragend|dragenter|dragexit|dragleave|dragover|dragstart|drop |durationchange|emptied|ended|error|focus|input|invalid|keydown @@ -467,6 +626,10 @@ contexts: 0: string.quoted.single punctuation.definition.string.end.html - include: else-pop + # This is to prevent breaking syntaxes referencing the old context name + tag-stuff: + - include: tag-attributes + tag-attributes: - include: vue-directive @@ -475,45 +638,21 @@ contexts: - include: tag-style-attribute - include: tag-event-attribute - include: tag-generic-attribute + mustache-expression: + - match: '{{' + scope: punctuation.definition.template.begin.html + embed: scope:source.js + escape: '}}' + escape_captures: + 0: punctuation.definition.template.end.html + template-tag: - - match: (?i)(<)(template)\b + - match: (<)((?i:template))\b captures: 0: meta.tag.template.begin.html 1: punctuation.definition.tag.begin.html 2: entity.name.tag.template.html - push: - - match: (?i)() - captures: - 0: meta.tag.template.end.html - 1: punctuation.definition.tag.begin.html - 2: entity.name.tag.template.html - 3: punctuation.definition.tag.end.html - pop: true - - match: '>' - scope: meta.tag.template.begin.html punctuation.definition.tag.end.html - push: mustache-template - - match: '' - push: - - meta_scope: meta.tag.template.begin.html - - match: (?=>) - pop: true - - include: tag-attributes - - mustache-template: - - match: (?=]*lang=(['"])coffee?) - captures: - 0: meta.tag.script.begin.html - 1: punctuation.definition.tag.begin.html - 2: entity.name.tag.script.html - push: - - match: (?i)() - captures: - 0: meta.tag.script.end.html - 1: punctuation.definition.tag.begin.html - 2: entity.name.tag.script.html - 3: punctuation.definition.tag.end.html - pop: true - - match: (>) - captures: - 1: meta.tag.script.begin.html punctuation.definition.tag.end.html - embed: scope:source.coffee - escape: (?i)(?=) - pop: true - - include: tag-attributes - - match: (?i)(<)((?:script))\b(?=[^>]*lang=(['"])livescript?) - captures: - 0: meta.tag.script.begin.html - 1: punctuation.definition.tag.begin.html - 2: entity.name.tag.script.html - push: - - match: (?i)() - captures: - 0: meta.tag.script.end.html - 1: punctuation.definition.tag.begin.html - 2: entity.name.tag.script.html - 3: punctuation.definition.tag.end.html - pop: true - - match: (>) - captures: - 1: meta.tag.script.begin.html punctuation.definition.tag.end.html - embed: scope:source.livescript - escape: (?i)(?=) - pop: true - - include: tag-attributes - - match: (?i)(<)((?:script))\b(?=[^>]*lang=(['"])ts?) - captures: - 0: meta.tag.script.begin.html - 1: punctuation.definition.tag.begin.html - 2: entity.name.tag.script.html - push: - - match: (?i)() - captures: - 0: meta.tag.script.end.html - 1: punctuation.definition.tag.begin.html - 2: entity.name.tag.script.html - 3: punctuation.definition.tag.end.html - pop: true - - match: (>) - captures: - 1: meta.tag.script.begin.html punctuation.definition.tag.end.html - embed: scope:source.ts - escape: (?i)(?=) - pop: true - - include: tag-attributes - - match: (?i)(<)((?:script))\b(?=[^>]*) - captures: - 0: meta.tag.script.begin.html - 1: punctuation.definition.tag.begin.html - 2: entity.name.tag.script.html - push: - - match: (?i)() - captures: - 0: meta.tag.script.end.html - 1: punctuation.definition.tag.begin.html - 2: entity.name.tag.script.html - 3: punctuation.definition.tag.end.html - pop: true - - match: (>) - captures: - 1: meta.tag.script.begin.html punctuation.definition.tag.end.html - embed: scope:source.js - escape: (?i)(?=) - pop: true - - include: tag-attributes - - match: (?i)(<)((?:style))\b(?=[^>]*lang=(['"])sass?) - captures: - 0: meta.tag.style.begin.html - 1: punctuation.definition.tag.begin.html - 2: entity.name.tag.style.html - push: - - match: (?i)() - captures: - 0: meta.tag.style.end.html - 1: punctuation.definition.tag.begin.html - 2: entity.name.tag.style.html - 3: punctuation.definition.tag.end.html - pop: true - - match: (>) - captures: - 1: meta.tag.style.begin.html punctuation.definition.tag.end.html - embed: scope:source.sass - escape: (?i)(?=) - pop: true - - include: tag-attributes - - match: (?i)(<)((?:style))\b(?=[^>]*lang=(['"])scss?) - captures: - 0: meta.tag.style.begin.html - 1: punctuation.definition.tag.begin.html - 2: entity.name.tag.style.html - push: - - match: (?i)() - captures: - 0: meta.tag.style.end.html - 1: punctuation.definition.tag.begin.html - 2: entity.name.tag.style.html - 3: punctuation.definition.tag.end.html - pop: true - - match: (>) - captures: - 1: meta.tag.style.begin.html punctuation.definition.tag.end.html - embed: scope:source.scss - escape: (?i)(?=) - pop: true - - include: tag-attributes - - match: (?i)(<)((?:style))\b(?=[^>]*lang=(['"])stylus?) - captures: - 0: meta.tag.style.begin.html - 1: punctuation.definition.tag.begin.html - 2: entity.name.tag.style.html - push: - - match: (?i)() - captures: - 0: meta.tag.style.end.html - 1: punctuation.definition.tag.begin.html - 2: entity.name.tag.style.html - 3: punctuation.definition.tag.end.html - pop: true - - match: (>) - captures: - 1: meta.tag.style.begin.html punctuation.definition.tag.end.html - embed: scope:source.stylus - escape: (?i)(?=) - pop: true - - include: tag-attributes - - match: (?i)(<)((?:style))\b(?=[^>]*lang=(['"])postcss?) - captures: - 0: meta.tag.style.begin.html - 1: punctuation.definition.tag.begin.html - 2: entity.name.tag.style.html - push: - - match: (?i)() - captures: - 0: meta.tag.style.end.html - 1: punctuation.definition.tag.begin.html - 2: entity.name.tag.style.html - 3: punctuation.definition.tag.end.html - pop: true - - match: (>) - captures: - 1: meta.tag.style.begin.html punctuation.definition.tag.end.html - embed: scope:source.postcss - escape: (?i)(?=) - pop: true - - include: tag-attributes - - match: (?i)(<)((?:style))\b(?=[^>]*lang=(['"])less?) - captures: - 0: meta.tag.style.begin.html - 1: punctuation.definition.tag.begin.html - 2: entity.name.tag.style.html - push: - - match: (?i)() - captures: - 0: meta.tag.style.end.html - 1: punctuation.definition.tag.begin.html - 2: entity.name.tag.style.html - 3: punctuation.definition.tag.end.html - pop: true - - match: (>) - captures: - 1: meta.tag.style.begin.html punctuation.definition.tag.end.html - embed: scope:source.css.less - escape: (?i)(?=) - pop: true - - include: tag-attributes - - match: (?i)(<)((?:style))\b(?=[^>]*) - captures: - 0: meta.tag.style.begin.html - 1: punctuation.definition.tag.begin.html - 2: entity.name.tag.style.html - push: - - match: (?i)() - captures: - 0: meta.tag.style.end.html - 1: punctuation.definition.tag.begin.html - 2: entity.name.tag.style.html - 3: punctuation.definition.tag.end.html - pop: true - - match: (>) - captures: - 1: meta.tag.style.begin.html punctuation.definition.tag.end.html - embed: scope:source.css - escape: (?i)(?=) - pop: true - - include: tag-attributes - - match: (?i)(<)((?:template))\b(?=[^>]*lang=(['"])jade?) - captures: - 0: meta.tag.template.begin.html - 1: punctuation.definition.tag.begin.html - 2: entity.name.tag.template.html - push: - - match: (?i)() - captures: - 0: meta.tag.template.end.html - 1: punctuation.definition.tag.begin.html - 2: entity.name.tag.template.html - 3: punctuation.definition.tag.end.html - pop: true - - match: (>) - captures: - 1: meta.tag.template.begin.html punctuation.definition.tag.end.html - embed: scope:text.jade - escape: (?i)(?=) - pop: true - - include: tag-attributes - - match: (?i)(<)((?:template))\b(?=[^>]*lang=(['"])pug?) - captures: - 0: meta.tag.template.begin.html - 1: punctuation.definition.tag.begin.html - 2: entity.name.tag.template.html - push: - - match: (?i)() - captures: - 0: meta.tag.template.end.html - 1: punctuation.definition.tag.begin.html - 2: entity.name.tag.template.html - 3: punctuation.definition.tag.end.html - pop: true - - match: (>) - captures: - 1: meta.tag.template.begin.html punctuation.definition.tag.end.html - embed: scope:text.pug - escape: (?i)(?=) - pop: true - - include: tag-attributes - - match: (?i)(<)((?:template))\b(?=[^>]*lang=(['"])slm?) + style-lang-attribute: + - match: (?i)\blang\b + scope: meta.attribute-with-value.html entity.other.attribute-name.html + set: + - meta_content_scope: meta.tag.style.begin.html meta.attribute-with-value.html + - match: = + scope: punctuation.separator.key-value.html + set: + - meta_content_scope: meta.tag.style.begin.html meta.attribute-with-value.html + - include: style-lang-decider + - match: (?=\S) + set: style-css + + style-lang-decider: + - match: (?i)(?=sass(?!{{unquoted_attribute_value}})|\'sass\'|"sass") + set: + - - meta_content_scope: meta.tag.style.begin.html + - include: style-common + - match: '>' + scope: punctuation.definition.tag.end.html + set: + - include: style-close-tag + - embed_scope: source.sass.embedded.html + match: '' + embed: scope:source.sass + escape: (?i)(?=(?:-->\s*)?' + scope: punctuation.definition.tag.end.html + set: + - include: style-close-tag + - embed_scope: source.scss.embedded.html + match: '' + embed: scope:source.scss + escape: (?i)(?=(?:-->\s*)?' + scope: punctuation.definition.tag.end.html + set: + - include: style-close-tag + - embed_scope: source.stylus.embedded.html + match: '' + embed: scope:source.stylus + escape: (?i)(?=(?:-->\s*)?' + scope: punctuation.definition.tag.end.html + set: + - include: style-close-tag + - embed_scope: source.postcss.embedded.html + match: '' + embed: scope:source.postcss + escape: (?i)(?=(?:-->\s*)?' + scope: punctuation.definition.tag.end.html + set: + - include: style-close-tag + - embed_scope: source.css.less.embedded.html + match: '' + embed: scope:source.css.less + escape: (?i)(?=(?:-->\s*)?' + scope: punctuation.definition.tag.end.html + set: + - include: script-close-tag + - embed_scope: source.coffee.embedded.html + match: '' + embed: scope:source.coffee + escape: (?i)(?=(?:-->\s*)?' + scope: punctuation.definition.tag.end.html + set: + - include: script-close-tag + - embed_scope: source.livescript.embedded.html + match: '' + embed: scope:source.livescript + escape: (?i)(?=(?:-->\s*)?' + scope: punctuation.definition.tag.end.html + set: + - include: script-close-tag + - embed_scope: source.ts.embedded.html + match: '' + embed: scope:source.ts + escape: (?i)(?=(?:-->\s*)? + scope: punctuation.definition.tag.end.html + pop: true + + template-close-tag: + - match: (?i)() + scope: meta.tag.template.end.html captures: - 0: meta.tag.template.begin.html 1: punctuation.definition.tag.begin.html 2: entity.name.tag.template.html - push: - - match: (?i)() - captures: - 0: meta.tag.template.end.html - 1: punctuation.definition.tag.begin.html - 2: entity.name.tag.template.html - 3: punctuation.definition.tag.end.html - pop: true - - match: (>) - captures: - 1: meta.tag.template.begin.html punctuation.definition.tag.end.html - embed: scope:text.slm - escape: (?i)(?=' + scope: punctuation.definition.tag.end.html + set: + - include: template-close-tag - match: '' - push: - - meta_scope: meta.tag.template.begin.html - - match: (?=>) - pop: true - - include: tag-attributes + push: main + template-lang-attribute: + - match: (?i)\blang\b + scope: meta.attribute-with-value.html entity.other.attribute-name.html + set: + - meta_content_scope: meta.tag.template.begin.html meta.attribute-with-value.html + - match: = + scope: punctuation.separator.key-value.html + set: + - meta_content_scope: meta.tag.template.begin.html meta.attribute-with-value.html + - include: template-lang-decider + - match: (?=\S) + set: template-mustache + + template-lang-decider: + - match: (?i)(?=jade(?!{{unquoted_attribute_value}})|\'jade\'|"jade") + set: + - - meta_content_scope: meta.tag.template.begin.html + - include: template-common + - match: '>' + scope: punctuation.definition.tag.end.html + set: + - include: template-close-tag + - embed_scope: text.jade.embedded.html + match: '' + embed: scope:text.jade + escape: (?i)(?=(?:-->\s*)?' + scope: punctuation.definition.tag.end.html + set: + - include: template-close-tag + - embed_scope: text.pug.embedded.html + match: '' + embed: scope:text.pug + escape: (?i)(?=(?:-->\s*)?' + scope: punctuation.definition.tag.end.html + set: + - include: template-close-tag + - embed_scope: text.slm.embedded.html + match: '' + embed: scope:text.slm + escape: (?i)(?=(?:-->\s*)?) - captures: - 0: meta.tag.template.end.html - 1: punctuation.definition.tag.begin.html - 2: entity.name.tag.template.html - 3: punctuation.definition.tag.end.html - pop: true - - match: '>' - scope: meta.tag.template.begin.html punctuation.definition.tag.end.html - push: mustache-template - - match: '' - push: - - meta_scope: meta.tag.template.begin.html - - match: '(?=>)' - pop: true - - include: tag-attributes - - mustache-template: - - match: (?=]*lang=(['"])coffee?) - captures: - 0: meta.tag.script.begin.html - 1: punctuation.definition.tag.begin.html - 2: entity.name.tag.script.html - push: - - match: (?i)() - captures: - 0: meta.tag.script.end.html - 1: punctuation.definition.tag.begin.html - 2: entity.name.tag.script.html - 3: punctuation.definition.tag.end.html - pop: true - - match: '(>)' - captures: - 1: meta.tag.script.begin.html punctuation.definition.tag.end.html - embed: scope:source.coffee - escape: (?i)(?=)' - pop: true - - include: tag-attributes - - match: (?i)(<)((?:script))\b(?=[^>]*lang=(['"])livescript?) - captures: - 0: meta.tag.script.begin.html - 1: punctuation.definition.tag.begin.html - 2: entity.name.tag.script.html - push: - - match: (?i)() - captures: - 0: meta.tag.script.end.html - 1: punctuation.definition.tag.begin.html - 2: entity.name.tag.script.html - 3: punctuation.definition.tag.end.html - pop: true - - match: '(>)' - captures: - 1: meta.tag.script.begin.html punctuation.definition.tag.end.html - embed: scope:source.livescript - escape: (?i)(?=)' - pop: true - - include: tag-attributes - - match: (?i)(<)((?:script))\b(?=[^>]*lang=(['"])ts?) - captures: - 0: meta.tag.script.begin.html - 1: punctuation.definition.tag.begin.html - 2: entity.name.tag.script.html - push: - - match: (?i)() - captures: - 0: meta.tag.script.end.html - 1: punctuation.definition.tag.begin.html - 2: entity.name.tag.script.html - 3: punctuation.definition.tag.end.html - pop: true - - match: '(>)' - captures: - 1: meta.tag.script.begin.html punctuation.definition.tag.end.html - embed: scope:source.ts - escape: (?i)(?=)' - pop: true - - include: tag-attributes - - match: (?i)(<)((?:script))\b(?=[^>]*) - captures: - 0: meta.tag.script.begin.html - 1: punctuation.definition.tag.begin.html - 2: entity.name.tag.script.html - push: - - match: (?i)() - captures: - 0: meta.tag.script.end.html - 1: punctuation.definition.tag.begin.html - 2: entity.name.tag.script.html - 3: punctuation.definition.tag.end.html - pop: true - - match: '(>)' - captures: - 1: meta.tag.script.begin.html punctuation.definition.tag.end.html - embed: scope:source.js - escape: (?i)(?=)' - pop: true - - include: tag-attributes - - match: (?i)(<)((?:style))\b(?=[^>]*lang=(['"])sass?) - captures: - 0: meta.tag.style.begin.html - 1: punctuation.definition.tag.begin.html - 2: entity.name.tag.style.html - push: - - match: (?i)() - captures: - 0: meta.tag.style.end.html - 1: punctuation.definition.tag.begin.html - 2: entity.name.tag.style.html - 3: punctuation.definition.tag.end.html - pop: true - - match: '(>)' - captures: - 1: meta.tag.style.begin.html punctuation.definition.tag.end.html - embed: scope:source.sass - escape: (?i)(?=)' - pop: true - - include: tag-attributes - - match: (?i)(<)((?:style))\b(?=[^>]*lang=(['"])scss?) - captures: - 0: meta.tag.style.begin.html - 1: punctuation.definition.tag.begin.html - 2: entity.name.tag.style.html - push: - - match: (?i)() - captures: - 0: meta.tag.style.end.html - 1: punctuation.definition.tag.begin.html - 2: entity.name.tag.style.html - 3: punctuation.definition.tag.end.html - pop: true - - match: '(>)' - captures: - 1: meta.tag.style.begin.html punctuation.definition.tag.end.html - embed: scope:source.scss - escape: (?i)(?=)' - pop: true - - include: tag-attributes - - match: (?i)(<)((?:style))\b(?=[^>]*lang=(['"])stylus?) - captures: - 0: meta.tag.style.begin.html - 1: punctuation.definition.tag.begin.html - 2: entity.name.tag.style.html - push: - - match: (?i)() - captures: - 0: meta.tag.style.end.html - 1: punctuation.definition.tag.begin.html - 2: entity.name.tag.style.html - 3: punctuation.definition.tag.end.html - pop: true - - match: '(>)' - captures: - 1: meta.tag.style.begin.html punctuation.definition.tag.end.html - embed: scope:source.stylus - escape: (?i)(?=)' - pop: true - - include: tag-attributes - - match: (?i)(<)((?:style))\b(?=[^>]*lang=(['"])postcss?) - captures: - 0: meta.tag.style.begin.html - 1: punctuation.definition.tag.begin.html - 2: entity.name.tag.style.html - push: - - match: (?i)() - captures: - 0: meta.tag.style.end.html - 1: punctuation.definition.tag.begin.html - 2: entity.name.tag.style.html - 3: punctuation.definition.tag.end.html - pop: true - - match: '(>)' - captures: - 1: meta.tag.style.begin.html punctuation.definition.tag.end.html - embed: scope:source.postcss - escape: (?i)(?=)' - pop: true - - include: tag-attributes - - match: (?i)(<)((?:style))\b(?=[^>]*lang=(['"])less?) - captures: - 0: meta.tag.style.begin.html - 1: punctuation.definition.tag.begin.html - 2: entity.name.tag.style.html - push: - - match: (?i)() - captures: - 0: meta.tag.style.end.html - 1: punctuation.definition.tag.begin.html - 2: entity.name.tag.style.html - 3: punctuation.definition.tag.end.html - pop: true - - match: '(>)' - captures: - 1: meta.tag.style.begin.html punctuation.definition.tag.end.html - embed: scope:source.css.less - escape: (?i)(?=)' - pop: true - - include: tag-attributes - - match: (?i)(<)((?:style))\b(?=[^>]*) - captures: - 0: meta.tag.style.begin.html - 1: punctuation.definition.tag.begin.html - 2: entity.name.tag.style.html - push: - - match: (?i)() - captures: - 0: meta.tag.style.end.html - 1: punctuation.definition.tag.begin.html - 2: entity.name.tag.style.html - 3: punctuation.definition.tag.end.html - pop: true - - match: '(>)' - captures: - 1: meta.tag.style.begin.html punctuation.definition.tag.end.html - embed: scope:source.css - escape: (?i)(?=)' - pop: true - - include: tag-attributes - - match: (?i)(<)((?:template))\b(?=[^>]*lang=(['"])jade?) - captures: - 0: meta.tag.template.begin.html - 1: punctuation.definition.tag.begin.html - 2: entity.name.tag.template.html - push: - - match: (?i)() - captures: - 0: meta.tag.template.end.html - 1: punctuation.definition.tag.begin.html - 2: entity.name.tag.template.html - 3: punctuation.definition.tag.end.html - pop: true - - match: '(>)' - captures: - 1: meta.tag.template.begin.html punctuation.definition.tag.end.html - embed: scope:text.jade - escape: (?i)(?=)' - pop: true - - include: tag-attributes - - match: (?i)(<)((?:template))\b(?=[^>]*lang=(['"])pug?) - captures: - 0: meta.tag.template.begin.html - 1: punctuation.definition.tag.begin.html - 2: entity.name.tag.template.html - push: - - match: (?i)() - captures: - 0: meta.tag.template.end.html - 1: punctuation.definition.tag.begin.html - 2: entity.name.tag.template.html - 3: punctuation.definition.tag.end.html - pop: true - - match: '(>)' - captures: - 1: meta.tag.template.begin.html punctuation.definition.tag.end.html - embed: scope:text.pug - escape: (?i)(?=)' - pop: true - - include: tag-attributes - - match: (?i)(<)((?:template))\b(?=[^>]*lang=(['"])slm?) + style-common: !prepend + - include: style-lang-attribute + + style-lang-attribute: + - match: (?i)\blang\b + scope: meta.attribute-with-value.html entity.other.attribute-name.html + set: + - meta_content_scope: meta.tag.style.begin.html meta.attribute-with-value.html + - match: = + scope: punctuation.separator.key-value.html + set: + - meta_content_scope: meta.tag.style.begin.html meta.attribute-with-value.html + - include: style-lang-decider + - match: (?=\S) + set: style-css + + style-lang-decider: + - !style_language [ sass, source.sass ] + - !style_language [ scss, source.scss ] + - !style_language [ stylus, source.stylus ] + - !style_language [ postcss, source.postcss ] + - !style_language [ less, source.css.less ] + - match: (?=\S) + set: + - style-css + - tag-generic-attribute-meta + - tag-generic-attribute-value + + script-common: !prepend + - include: script-lang-attribute + + script-lang-attribute: + - match: (?i)\blang\b + scope: meta.attribute-with-value.html entity.other.attribute-name.html + set: + - meta_content_scope: meta.tag.script.begin.html meta.attribute-with-value.html + - match: = + scope: punctuation.separator.key-value.html + set: + - meta_content_scope: meta.tag.script.begin.html meta.attribute-with-value.html + - include: script-lang-decider + - match: (?=\S) + set: script-javascript + + script-lang-decider: + - !script_language [ coffee, source.coffee ] + - !script_language [ livescript, source.livescript ] + - !script_language [ ts, source.ts ] + - match: (?=\S) + set: + - script-javascript + - tag-generic-attribute-meta + - tag-generic-attribute-value + + template-common: + - include: template-lang-attribute + - include: tag-attributes + - match: '/>' + scope: punctuation.definition.tag.end.html + pop: true + + template-close-tag: + - match: (?i)() + scope: meta.tag.template.end.html captures: - 0: meta.tag.template.begin.html 1: punctuation.definition.tag.begin.html 2: entity.name.tag.template.html - push: - - match: (?i)() - captures: - 0: meta.tag.template.end.html - 1: punctuation.definition.tag.begin.html - 2: entity.name.tag.template.html - 3: punctuation.definition.tag.end.html - pop: true - - match: '(>)' - captures: - 1: meta.tag.template.begin.html punctuation.definition.tag.end.html - embed: scope:text.slm - escape: (?i)(?=)' - pop: true - - include: tag-attributes + 3: punctuation.definition.tag.end.html + pop: true + + template-mustache: + - meta_content_scope: meta.tag.template.begin.html + - include: template-common + - match: '>' + scope: punctuation.definition.tag.end.html + set: + - include: template-close-tag + - match: '' + push: main + + template-lang-attribute: + - match: (?i)\blang\b + scope: meta.attribute-with-value.html entity.other.attribute-name.html + set: + - meta_content_scope: meta.tag.template.begin.html meta.attribute-with-value.html + - match: = + scope: punctuation.separator.key-value.html + set: + - meta_content_scope: meta.tag.template.begin.html meta.attribute-with-value.html + - include: template-lang-decider + - match: (?=\S) + set: template-mustache + template-lang-decider: + - !template_language [ jade, text.jade ] + - !template_language [ pug, text.pug ] + - !template_language [ slm, text.slm ] + - match: (?=\S) + set: + - template-mustache + - tag-generic-attribute-meta + - tag-generic-attribute-value diff --git a/macros.py b/macros.py new file mode 100644 index 0000000..f8a290f --- /dev/null +++ b/macros.py @@ -0,0 +1,37 @@ +from YAMLMacros.lib.syntax import rule as _rule +from YAMLMacros.lib.extend import * + +def script_language(match, embed): + return embed_language_in_tag('script', match, embed) + +def style_language(match, embed): + return embed_language_in_tag('style', match, embed) + +def template_language(match, embed): + return embed_language_in_tag('template', match, embed) + +def embed_language_in_tag(tag, match, embed): + return _rule( + match=r'(?i)(?={0}(?!{{{{unquoted_attribute_value}}}})|\'{0}\'|"{0}")'.format(match), + set=[ + [ + _rule(meta_content_scope='meta.tag.%s.begin.html' % tag), + _rule(include='%s-common' % tag), + _rule( + match='>', + scope='punctuation.definition.tag.end.html', + set=[ + _rule(include='%s-close-tag' % tag), + _rule( + match=r'', + embed=('scope:%s' % embed), + embed_scope=('%s.embedded.html' % embed), + escape=r'(?i)(?=(?:-->\s*)?