function getBlockIdsAndRanges(codeString, cleanCode) {
let blockIdDict = {};
let blockIdStack = [];
let tagLen = 0;
// match #beg_block_id# and exactly 20 Chars
let matchArray = Array.from(codeString.matchAll(/(#beg_block_id#|#end_block_id#) (\S{20})/g));
for (let match of matchArray) {
let cmd = match[1];
let blockId = match[2];
console.log(cmd + " " + blockId);
let tagActualLen = match[0].length;
if (cmd === '#beg_block_id#') {
blockIdStack.push([blockId, match.index - tagLen]);
tagLen += tagActualLen;
} else if (cmd === '#end_block_id#') {
tagLen += tagActualLen;
if (blockIdStack.length === 0) {
console.error(`Error: Unmatched 'end' for block_id '${blockId}' at index ${match.index}`);
continue;
}
let lastBlock = blockIdStack.pop();
let lastBlockId = lastBlock[0];
let startIndex = lastBlock[1];
if (lastBlockId !== blockId) {
console.error(`Error: Mismatched block_id at index ${match.index}`);
} else {
blockIdDict[blockId] = {
'startIndex': startIndex,
'endIndex': match.index + match[0].length - tagLen,
'code' : cleanCode.substring(startIndex, match.index + match[0].length - tagLen)
};
}
}
}
if (blockIdStack.length !== 0) {
for (let block of blockIdStack) {
console.error(`Error: Not ended block_id '${block[0]}' at index ${block[1]}`);
}
}
return blockIdDict;
}