mirror of
https://github.com/letscontrolit/ESPEasy.git
synced 2026-07-27 19:57:38 +00:00
Update espeasy.js
simple On-Do-Endon and If-Endif checks
This commit is contained in:
+70
-22
@@ -281,54 +281,80 @@ function initalAutocorrection() {
|
||||
textarea.value = text;
|
||||
}
|
||||
|
||||
function formatLogic(text) {
|
||||
unction formatLogic(text) {
|
||||
const INDENT = ' '; // 2 spaces
|
||||
const lines = text.split('\n').map(line => line.trim()); // remove all existing indentation
|
||||
|
||||
let indentLevel = 0;
|
||||
const result = [];
|
||||
const stack = [];
|
||||
const errors = [];
|
||||
|
||||
let openOnDoLine = null;
|
||||
let ifCount = 0;
|
||||
let endifCount = 0;
|
||||
let ifLines = [];
|
||||
|
||||
// ignoring case
|
||||
function startsWithKeyword(line, keywords) {
|
||||
line = line.toLowerCase();
|
||||
return keywords.some(k => line.startsWith(k));
|
||||
}
|
||||
|
||||
// We define these keywords:
|
||||
const ON_START = 'on'; // Start of main block
|
||||
const ON_END = 'endon'; // End of main block
|
||||
const IF_START = 'if'; // If block start
|
||||
const ELSE = 'else'; // Else block
|
||||
const IF_END = 'endif'; // Endif
|
||||
const ON_START = 'on';
|
||||
const ON_END = 'endon';
|
||||
const IF_START = 'if';
|
||||
const ELSE = 'else';
|
||||
const IF_END = 'endif';
|
||||
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
const line = lines[i];
|
||||
const low = line.toLowerCase();
|
||||
|
||||
// On ... Endon blocks
|
||||
// handle "On ... Do"
|
||||
if (startsWithKeyword(low, [ON_START])) {
|
||||
// main block - no indent for this line
|
||||
const hasDo = low.includes('do');
|
||||
|
||||
if (!hasDo) {
|
||||
errors.push(`Line ${i + 1}: "On" without "Do"`);
|
||||
} else {
|
||||
if (openOnDoLine !== null) {
|
||||
errors.push(`Line ${openOnDoLine + 1}: "On...Do" without closing "Endon"`);
|
||||
}
|
||||
openOnDoLine = i;
|
||||
}
|
||||
|
||||
result.push(line);
|
||||
indentLevel = 1; // indent inside On ... Endon
|
||||
indentLevel = 1;
|
||||
stack.push(ON_START);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Handle "Endon"
|
||||
if (startsWithKeyword(low, [ON_END])) {
|
||||
// ending main block - decrease indent before printing
|
||||
indentLevel = Math.max(indentLevel - 1, 0);
|
||||
result.push(INDENT.repeat(indentLevel) + line);
|
||||
stack.pop();
|
||||
|
||||
if (stack.includes(ON_START)) {
|
||||
// remove everything from the top of the stack until the last ON_START
|
||||
while (stack.length) {
|
||||
const popped = stack.pop();
|
||||
if (popped === ON_START) {
|
||||
openOnDoLine = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
errors.push(`Line ${i + 1}: "Endon" without matching "On...Do"`);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// If inside main block:
|
||||
if (stack.includes(ON_START)) {
|
||||
// Handle If, Else, Endif blocks inside main block
|
||||
|
||||
if (startsWithKeyword(low, [IF_START])) {
|
||||
// If starts: indent current line, push stack, increase indent
|
||||
ifCount++;
|
||||
ifLines.push(i + 1);
|
||||
result.push(INDENT.repeat(indentLevel) + line);
|
||||
stack.push(IF_START);
|
||||
indentLevel++;
|
||||
@@ -336,7 +362,6 @@ function formatLogic(text) {
|
||||
}
|
||||
|
||||
if (startsWithKeyword(low, [ELSE])) {
|
||||
// Else: decrease indent (close previous If block), print Else, increase indent again
|
||||
indentLevel = Math.max(indentLevel - 1, 0);
|
||||
result.push(INDENT.repeat(indentLevel) + line);
|
||||
indentLevel++;
|
||||
@@ -344,25 +369,48 @@ function formatLogic(text) {
|
||||
}
|
||||
|
||||
if (startsWithKeyword(low, [IF_END])) {
|
||||
// Endif: decrease indent, print line, pop stack
|
||||
endifCount++;
|
||||
indentLevel = Math.max(indentLevel - 1, 0);
|
||||
result.push(INDENT.repeat(indentLevel) + line);
|
||||
// pop only if top of stack is If
|
||||
if (stack[stack.length - 1] === IF_START) {
|
||||
|
||||
if (stack.length && stack[stack.length - 1] === IF_START) {
|
||||
stack.pop();
|
||||
ifLines.pop();
|
||||
} else {
|
||||
errors.push(`Line ${i + 1}: "Endif" without matching "If"`);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// Normal line inside main block or If blocks, indent with current level
|
||||
// any normal line inside On block
|
||||
result.push(INDENT.repeat(indentLevel) + line);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Lines outside any On ... Endon block, print as is (or trim)
|
||||
// Outside any block
|
||||
result.push(line);
|
||||
}
|
||||
|
||||
// Final checks
|
||||
if (openOnDoLine !== null) {
|
||||
errors.push(`Line ${openOnDoLine + 1}: "On...Do" without closing "Endon"`);
|
||||
}
|
||||
|
||||
if (ifCount > endifCount) {
|
||||
const diff = ifCount - endifCount;
|
||||
errors.push(`Missing ${diff} Endif(s)`);
|
||||
if (ifLines.length > 0) {
|
||||
errors.push(`Unclosed If block(s) starting at line(s): ${ifLines.join(", ")}`);
|
||||
}
|
||||
} else if (endifCount > ifCount) {
|
||||
errors.push(`Found ${endifCount - ifCount} Endif(s) without matching If(s)`);
|
||||
}
|
||||
|
||||
if (errors.length > 0) {
|
||||
alert("Errors found:\n" + errors.join("\n"));
|
||||
}
|
||||
|
||||
return result.join('\n');
|
||||
}
|
||||
//--------------------------------------------------------------------------------- end of formatting option
|
||||
|
||||
Reference in New Issue
Block a user