add threshold attribute to WHILE tag

This commit is contained in:
2026-08-19 14:12:26 +02:00
parent 15422cca1f
commit 300864a15e
7 changed files with 61 additions and 25 deletions
+4 -3
View File
@@ -16,7 +16,7 @@ Syntax highlighting and language support for **EFTL (ElixForms Template Language
- `[EFTL]...[/EFTL]` - Main EFTL block
- `[VAR name="..." type="..."]...[/VAR]` - Variable declarations
- `[IF]...[/IF]` - Conditionals
- `[WHILE]...[/WHILE]` - Loops
- `[WHILE threshold="..."]...[/WHILE]` - Loops with an optional string threshold
### Expressions
@@ -40,7 +40,7 @@ Syntax highlighting and language support for **EFTL (ElixForms Template Language
### Control Structures
- `[IF]`, `[CONDITION]`, `[THEN]`, `[ELSE]`, `[ELSE IF]`
- `[WHILE]`, `[DO]`
- `[WHILE]`, `[WHILE threshold="..."]`, `[DO]`
### Comments
@@ -106,7 +106,7 @@ If you want to debug the extension or the language server:
## Snippets
| Prefix | Description |
| ----------- | ---------------------- |
| ---------------- | ------------------------- |
| `eftl` | EFTL block with header |
| `var` | Variable declaration |
| `vartag` | Variable from TAG |
@@ -114,6 +114,7 @@ If you want to debug the extension or the language server:
| `if` | IF statement |
| `ifelse` | IF-ELSE statement |
| `while` | WHILE loop |
| `whilethreshold` | WHILE loop with threshold |
| `split` | Split function |
| `trim` | Trim function |
| `valueof` | VALUE_OF function |
+1 -1
View File
@@ -8,7 +8,7 @@
[VAR name="CONTRAENTI" type="iterable"][SPLIT regex="\n"][TRIM][TAG]SCHEMAID,296,COL0004,IUQOID, , [/TAG][/TRIM][/SPLIT][/VAR]
[VAR name="CONTRAENTI_NUM" type="number"][SIZE_OF varname="CONTRAENTI" /][/VAR]
[WHILE]
[WHILE threshold="99"]
[CONDITION][% IDX < CONTRAENTI_NUM %][/CONDITION]
[DO]
[VAR name="CONTRAENTE" type="string"][VALUE_OF varname="CONTRAENTI" index="IDX" /][/VAR]
+1 -1
View File
@@ -6,7 +6,7 @@
["[EFTL]", "[/EFTL]"],
["[VAR", "[/VAR]"],
["[IF]", "[/IF]"],
["[WHILE]", "[/WHILE]"],
["[WHILE", "[/WHILE]"],
["[FORMAT", "[/FORMAT]"],
["[CONDITION]", "[/CONDITION]"],
["[THEN]", "[/THEN]"],
+12
View File
@@ -79,6 +79,18 @@
],
"description": "Create a WHILE loop"
},
"While Loop with Threshold": {
"prefix": "whilethreshold",
"body": [
"[WHILE threshold=\"${1:99}\"]",
" [CONDITION][% ${2:condition} %][/CONDITION]",
" [DO]",
" $0",
" [/DO]",
"[/WHILE]"
],
"description": "Create a WHILE loop with a threshold"
},
"Split": {
"prefix": "split",
"body": [
+3
View File
@@ -128,6 +128,9 @@ export class EftlParser {
break;
case TokenType.WHILE_OPEN:
if (!/^\[WHILE(?:\s+threshold\s*=\s*"[^"]*")?\s*\]$/.test(token.value)) {
this.addError(token, 'WHILE accepts only the optional string attribute threshold="..."');
}
this.pushBlock(token);
this.advance();
break;
+6 -1
View File
@@ -21,7 +21,7 @@ export enum TokenType {
ELSE_CLOSE = 'ELSE_CLOSE', // [/ELSE]
ELSE_IF_OPEN = 'ELSE_IF_OPEN', // [ELSE IF]
ELSE_IF_CLOSE = 'ELSE_IF_CLOSE', // [/ELSE IF]
WHILE_OPEN = 'WHILE_OPEN', // [WHILE]
WHILE_OPEN = 'WHILE_OPEN', // [WHILE ...]
WHILE_CLOSE = 'WHILE_CLOSE', // [/WHILE]
DO_OPEN = 'DO_OPEN', // [DO]
DO_CLOSE = 'DO_CLOSE', // [/DO]
@@ -192,6 +192,11 @@ export class EftlTokenizer {
this.addToken(TokenType.WHILE_OPEN, '[WHILE]', startLine, startColumn);
return;
}
if (this.source.startsWith('[WHILE', this.pos) && /\s/.test(this.source[this.pos + '[WHILE'.length] || '')) {
this.match('[WHILE');
this.scanTagWithAttributes(TokenType.WHILE_OPEN, 'WHILE', startLine, startColumn);
return;
}
if (this.match('[/WHILE]')) {
this.addToken(TokenType.WHILE_CLOSE, '[/WHILE]', startLine, startColumn);
return;
+16 -1
View File
@@ -236,9 +236,24 @@
"name": "keyword.control.conditional.eftl",
"match": "\\[(IF|ELSE IF|ELSE|/IF|CONDITION|/CONDITION|THEN|/THEN|/ELSE IF|/ELSE)\\]"
},
{
"name": "meta.control.loop.eftl",
"begin": "(\\[)(WHILE)\\b",
"end": "(\\])",
"beginCaptures": {
"1": { "name": "keyword.control.loop.eftl" },
"2": { "name": "keyword.control.loop.eftl" }
},
"endCaptures": {
"1": { "name": "keyword.control.loop.eftl" }
},
"patterns": [
{ "include": "#attributes" }
]
},
{
"name": "keyword.control.loop.eftl",
"match": "\\[(WHILE|/WHILE|DO|/DO)\\]"
"match": "\\[(/WHILE|DO|/DO)\\]"
}
]
},