110 lines
3.9 KiB
YAML
110 lines
3.9 KiB
YAML
%YAML 1.2
|
|
---
|
|
# NotesCraft's own Twig grammar. Original work written for this project; not copied
|
|
# from any other grammar. Regexes stay linear: no nested quantifiers, so nothing backtracks far.
|
|
# Strings end at their line unless the language allows multi-line ones.
|
|
name: Twig
|
|
file_extensions: [twig, html.twig]
|
|
scope: text.html.twig
|
|
|
|
contexts:
|
|
main:
|
|
- match: '\{#'
|
|
scope: keyword.operator.template.begin comment.block
|
|
push: comment
|
|
- match: '\{\{-?'
|
|
scope: keyword.operator.template.begin
|
|
push: expr
|
|
- match: '\{%-?'
|
|
scope: keyword.operator.template.begin
|
|
push: stmt
|
|
comment:
|
|
- meta_scope: comment.block
|
|
- match: '#\}'
|
|
scope: keyword.operator.template.end
|
|
pop: true
|
|
expr:
|
|
- match: '-?\}\}'
|
|
scope: keyword.operator.template.end
|
|
pop: true
|
|
- match: '"'
|
|
scope: punctuation.definition.string.begin
|
|
push: expr-dq
|
|
- match: ''''
|
|
scope: punctuation.definition.string.begin
|
|
push: expr-sq
|
|
- match: '(\|)\s*([A-Za-z_]\w*)'
|
|
captures:
|
|
1: keyword.operator
|
|
2: support.function.filter
|
|
- match: '\b(?:if|elif|else|endif|for|endfor|block|endblock|extends|include|import|from|as|macro|endmacro|call|endcall|set|endset|filter|endfilter|with|endwith|raw|endraw|autoescape|endautoescape|do|break|continue|trans|endtrans|ignore|missing|scoped|recursive|elseif|embed|endembed|use|apply|endapply|sandbox|endsandbox|verbatim|endverbatim|flush|deprecated|cache|endcache|yield|super)\b'
|
|
scope: keyword.control
|
|
- match: '\b(?:and|or|not|in|is|starts|ends|matches)\b'
|
|
scope: keyword.operator.word
|
|
- match: '\b(?:true|false|none|null|True|False|None|TRUE|FALSE|NULL)\b'
|
|
scope: constant.language
|
|
- match: '\b(?:0[xX][0-9a-fA-F_]+|0[bB][01_]+|\d[\d_]*(?:\.\d[\d_]*)?(?:[eE][+-]?\d+)?)\b'
|
|
scope: constant.numeric
|
|
- match: '[-+*/%=<>!&|^~?:.,]+'
|
|
scope: keyword.operator
|
|
expr-dq:
|
|
- meta_scope: string.quoted.double
|
|
- match: '\\.'
|
|
scope: constant.character.escape
|
|
- match: '"'
|
|
scope: punctuation.definition.string.end
|
|
pop: true
|
|
- match: '(?=\n)'
|
|
pop: true
|
|
expr-sq:
|
|
- meta_scope: string.quoted.single
|
|
- match: '\\.'
|
|
scope: constant.character.escape
|
|
- match: ''''
|
|
scope: punctuation.definition.string.end
|
|
pop: true
|
|
- match: '(?=\n)'
|
|
pop: true
|
|
stmt:
|
|
- match: '-?%\}'
|
|
scope: keyword.operator.template.end
|
|
pop: true
|
|
- match: '"'
|
|
scope: punctuation.definition.string.begin
|
|
push: stmt-dq
|
|
- match: ''''
|
|
scope: punctuation.definition.string.begin
|
|
push: stmt-sq
|
|
- match: '(\|)\s*([A-Za-z_]\w*)'
|
|
captures:
|
|
1: keyword.operator
|
|
2: support.function.filter
|
|
- match: '\b(?:if|elif|else|endif|for|endfor|block|endblock|extends|include|import|from|as|macro|endmacro|call|endcall|set|endset|filter|endfilter|with|endwith|raw|endraw|autoescape|endautoescape|do|break|continue|trans|endtrans|ignore|missing|scoped|recursive|elseif|embed|endembed|use|apply|endapply|sandbox|endsandbox|verbatim|endverbatim|flush|deprecated|cache|endcache|yield|super)\b'
|
|
scope: keyword.control
|
|
- match: '\b(?:and|or|not|in|is|starts|ends|matches)\b'
|
|
scope: keyword.operator.word
|
|
- match: '\b(?:true|false|none|null|True|False|None|TRUE|FALSE|NULL)\b'
|
|
scope: constant.language
|
|
- match: '\b(?:0[xX][0-9a-fA-F_]+|0[bB][01_]+|\d[\d_]*(?:\.\d[\d_]*)?(?:[eE][+-]?\d+)?)\b'
|
|
scope: constant.numeric
|
|
- match: '[-+*/%=<>!&|^~?:.,]+'
|
|
scope: keyword.operator
|
|
stmt-dq:
|
|
- meta_scope: string.quoted.double
|
|
- match: '\\.'
|
|
scope: constant.character.escape
|
|
- match: '"'
|
|
scope: punctuation.definition.string.end
|
|
pop: true
|
|
- match: '(?=\n)'
|
|
pop: true
|
|
stmt-sq:
|
|
- meta_scope: string.quoted.single
|
|
- match: '\\.'
|
|
scope: constant.character.escape
|
|
- match: ''''
|
|
scope: punctuation.definition.string.end
|
|
pop: true
|
|
- match: '(?=\n)'
|
|
pop: true
|