muddle/editors/vscode/syntaxes/spug.tmLanguage.json
2026-10-23 08:53:07 -04:00

200 lines
5.8 KiB
JSON

{
"$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.schema.json",
"name": "SPUG",
"scopeName": "source.spug",
"patterns": [
{ "include": "#frontmatter" },
{ "include": "#comment" },
{ "include": "#javascript-block" },
{ "include": "#doctype" },
{ "include": "#control-line" },
{ "include": "#keyword-line" },
{ "include": "#element" }
],
"repository": {
"comment": {
"patterns": [
{
"name": "comment.block.spug",
"begin": "/\\*",
"end": "\\*/"
},
{
"name": "comment.block.html.spug",
"begin": "<!--",
"end": "-->"
}
]
},
"frontmatter": {
"name": "meta.embedded.block.ts.spug",
"begin": "^---\\s*$",
"beginCaptures": { "0": { "name": "punctuation.definition.frontmatter.begin.spug" } },
"end": "^---\\s*$",
"endCaptures": { "0": { "name": "punctuation.definition.frontmatter.end.spug" } },
"patterns": [{ "include": "source.ts" }]
},
"javascript-block": {
"name": "meta.embedded.block.ts.spug",
"begin": "^\\s*(javascript|typescript)!\\s*$",
"beginCaptures": { "1": { "name": "keyword.control.spug" } },
"end": "^\\s*end\\s*$",
"endCaptures": { "0": { "name": "keyword.control.spug" } },
"patterns": [{ "include": "source.ts" }]
},
"doctype": {
"match": "^\\s*(doctype)\\b\\s*(\\S+)?",
"captures": {
"1": { "name": "keyword.control.spug" },
"2": { "name": "constant.other.doctype.spug" }
}
},
"control-line": {
"name": "meta.spug-control.spug",
"begin": "^\\s*(each|if|unless|else if|else|while|case|when|default)\\b",
"beginCaptures": { "1": { "name": "keyword.control.spug" } },
"end": "$",
"patterns": [
{ "match": "\\bin\\b", "name": "keyword.operator.of.spug" },
{ "include": "#interpolation" },
{ "include": "#expression" }
]
},
"keyword-line": {
"match": "^\\s*(extends|include|block|append|prepend|mixin|slot|yield|island|component|render|props)\\b\\s*([\\w./@-]*)",
"captures": {
"1": { "name": "keyword.control.spug" },
"2": {
"patterns": [
"string.quoted.other.path.spug",
{ "match": "[\\w./@-]+", "name": "variable.other.predefined.spug" }
]
}
}
},
"anchor": {
"match": "@(?!(?:each|if|unless|else|while|case|when|default|props|doctype|javascript|typescript|end)\\b)[A-Za-z_][\\w-]*(?:\\([^(){}]*\\))?",
"name": "entity.other.relation-anchor.spug"
},
"element": {
"name": "meta.element.spug",
"begin": "^\\s*([A-Za-z][A-Za-z0-9:_.-]*)",
"beginCaptures": {
"1": { "name": "entity.name.tag.spug" }
},
"end": "$",
"patterns": [
{ "include": "#class-id" },
{ "include": "#anchor" },
{ "include": "#attributes" },
{ "include": "#output" },
{ "include": "#interpolation" },
{ "include": "#text" }
]
},
"class-id": {
"patterns": [
{
"match": "(\\.)([A-Za-z_][\\w-]*)",
"captures": {
"1": { "name": "punctuation.definition.tag.spug" },
"2": { "name": "entity.other.attribute-name.class.spug" }
}
},
{
"match": "(#)([A-Za-z_][\\w-]*)",
"captures": {
"1": { "name": "punctuation.definition.tag.spug" },
"2": { "name": "entity.other.attribute-name.id.spug" }
}
}
]
},
"attributes": {
"name": "meta.attributes.spug",
"begin": "\\(",
"end": "\\)",
"patterns": [
{ "include": "#anchor" },
{ "include": "#attributes" },
{
"match": "([A-Za-z_][\\w:-]*)\\s*(?==)",
"name": "entity.other.attribute-name.spug"
},
{ "include": "#d-string" },
{ "include": "#expression" }
]
},
"d-string": {
"name": "string.quoted.double.stcss",
"begin": "([dD])(\"|')",
"beginCaptures": {
"1": { "name": "keyword.other.stcss" },
"2": { "name": "punctuation.definition.string.begin.stcss" }
},
"end": "(?<!\\\\)\\2",
"endCaptures": { "0": { "name": "punctuation.definition.string.end.stcss" } },
"patterns": [
{ "include": "#interpolation" },
{ "include": "#expression" }
]
},
"output": {
"contentName": "meta.embedded.expression.ts",
"begin": "(!?=)",
"beginCaptures": { "1": { "name": "punctuation.separator.filters.spug" } },
"end": "$",
"patterns": [{ "include": "#expression" }]
},
"interpolation": {
"name": "meta.interpolation.spug",
"begin": "([#!])\\{",
"beginCaptures": { "0": { "name": "punctuation.definition.interpolation.begin.spug" } },
"end": "\\}",
"endCaptures": { "0": { "name": "punctuation.definition.interpolation.end.spug" } },
"contentName": "meta.embedded.expression.ts",
"patterns": [{ "include": "#curly-nesting" }, { "include": "#expression" }]
},
"curly-nesting": {
"begin": "\\{",
"beginCaptures": { "0": { "name": "punctuation.definition.brace.curly.spug" } },
"end": "\\}",
"endCaptures": { "0": { "name": "punctuation.definition.brace.curly.spug" } },
"patterns": [
{ "include": "#curly-nesting" },
{ "include": "#expression" }
]
},
"text": {
"patterns": [
{
"match": "&amp;|&lt;|&gt;|&quot;|&#\\w+;",
"name": "constant.character.escape.html.spug"
}
]
},
"expression": {
"patterns": [
{ "include": "#interpolation" },
{ "include": "#d-string" },
{
"name": "string.quoted.js",
"begin": "([\"'`])",
"end": "(?<!\\\\)\\1",
"patterns": [{ "include": "#interpolation" }]
},
{
"match": "\\b(?:true|false|null|undefined|this|await|async|new|typeof|instanceof)\\b",
"name": "constant.language.js"
},
{
"match": "\\b(?:if|else|each|while|return|function|const|let|var|import|from|export)\\b",
"name": "keyword.control.ts"
},
{ "match": "\\b\\d+(?:\\.\\d+)?\\b", "name": "constant.numeric.decimal.js" },
{ "match": "[A-Za-z_$][\\w$]*", "name": "variable.other.js" },
{ "match": "&&|\\|\\||[?:,+\\-*/%<>=!]=[?]?|[?:,+\\-*/%<>=!]", "name": "keyword.operator.js" }
]
}
}
}