mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
somewhat safer macro replacements
This commit is contained in:
@ -23,45 +23,45 @@ export class SlashCommandClosure {
|
|||||||
return '[Closure]';
|
return '[Closure]';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {string} text
|
||||||
|
* @param {SlashCommandScope} scope
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
substituteParams(text, scope = null) {
|
substituteParams(text, scope = null) {
|
||||||
text = substituteParams(text);
|
|
||||||
let isList = false;
|
let isList = false;
|
||||||
let listValues = [];
|
let listValues = [];
|
||||||
scope = scope ?? this.scope;
|
scope = scope ?? this.scope;
|
||||||
const re = /({{pipe}})|(?:{{var::([^\s]+?)(?:::((?!}}).+))?}})/;
|
const macros = scope.macroList.map(it=>escapeRegex(it.key)).join('|');
|
||||||
while (re.test(text)) {
|
const re = new RegExp(`({{pipe}})|(?:{{var::([^\\s]+?)(?:::((?!}}).+))?}})|(?:{{(${macros})}})`);
|
||||||
const match = re.exec(text);
|
let done = '';
|
||||||
const before = text.slice(0, match.index);
|
let remaining = text;
|
||||||
const after = text.slice(match.index + match[0].length);
|
while (re.test(remaining)) {
|
||||||
const replacer = match[1] ? scope.pipe : scope.getVariable(match[2], match[3]);
|
const match = re.exec(remaining);
|
||||||
|
const before = substituteParams(remaining.slice(0, match.index));
|
||||||
|
const after = remaining.slice(match.index + match[0].length);
|
||||||
|
const replacer = match[1] ? scope.pipe : match[2] ? scope.getVariable(match[2], match[3]) : scope.macroList.find(it=>it.key == match[4])?.value;
|
||||||
if (replacer instanceof SlashCommandClosure) {
|
if (replacer instanceof SlashCommandClosure) {
|
||||||
isList = true;
|
isList = true;
|
||||||
if (match.index > 0) {
|
if (match.index > 0) {
|
||||||
listValues.push(before);
|
listValues.push(before);
|
||||||
}
|
}
|
||||||
listValues.push(replacer);
|
listValues.push(replacer);
|
||||||
if (match.index + match[0].length + 1 < text.length) {
|
if (match.index + match[0].length + 1 < remaining.length) {
|
||||||
const rest = this.substituteParams(after, scope);
|
const rest = this.substituteParams(after, scope);
|
||||||
listValues.push(...(Array.isArray(rest) ? rest : [rest]));
|
listValues.push(...(Array.isArray(rest) ? rest : [rest]));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
text = `${before}${replacer}${after}`;
|
done = `${before}${replacer}`;
|
||||||
|
remaining = after;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (const { key, value } of scope.macroList) {
|
if (!isList) {
|
||||||
if (isList) {
|
text = `${done}${substituteParams(remaining)}`;
|
||||||
listValues.map((lv,idx)=>{
|
|
||||||
if (lv instanceof SlashCommandClosure) {
|
|
||||||
// do nothing
|
|
||||||
} else {
|
|
||||||
listValues[idx] = lv.replace(new RegExp(`{{${escapeRegex(key)}}}`), value);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
text = text.replace(new RegExp(`{{${escapeRegex(key)}}}`), value);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isList) {
|
if (isList) {
|
||||||
if (listValues.length > 1) return listValues;
|
if (listValues.length > 1) return listValues;
|
||||||
return listValues[0];
|
return listValues[0];
|
||||||
|
Reference in New Issue
Block a user