mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
add parser flag REPLACE_GETVAR
Replaces all {{getvar::}} and {{getglobalvar::}} macros with {{var::}}. Inserts a series of command executors before the command with the macros that: - save {{pipe}} to a var - call /getvar or /getglobalvar to get the variable used in the macro - call /let to save the retrieved variable - return the saved {{pipe}} value This helps to avoid double-substitutions when the var values contain text that could be interpreted as macros.
This commit is contained in:
@ -1,4 +1,4 @@
|
|||||||
import { isTrueBoolean } from '../utils.js';
|
import { isTrueBoolean, uuidv4 } from '../utils.js';
|
||||||
import { SlashCommand } from './SlashCommand.js';
|
import { SlashCommand } from './SlashCommand.js';
|
||||||
import { OPTION_TYPE, SlashCommandAutoCompleteOption } from './SlashCommandAutoCompleteOption.js';
|
import { OPTION_TYPE, SlashCommandAutoCompleteOption } from './SlashCommandAutoCompleteOption.js';
|
||||||
import { SlashCommandClosure } from './SlashCommandClosure.js';
|
import { SlashCommandClosure } from './SlashCommandClosure.js';
|
||||||
@ -12,6 +12,7 @@ import { SlashCommandScope } from './SlashCommandScope.js';
|
|||||||
/**@enum {Number}*/
|
/**@enum {Number}*/
|
||||||
export const PARSER_FLAG = {
|
export const PARSER_FLAG = {
|
||||||
'STRICT_ESCAPING': 1,
|
'STRICT_ESCAPING': 1,
|
||||||
|
'REPLACE_GETVAR': 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
export class SlashCommandParser {
|
export class SlashCommandParser {
|
||||||
@ -24,6 +25,7 @@ export class SlashCommandParser {
|
|||||||
/**@type {string}*/ keptText;
|
/**@type {string}*/ keptText;
|
||||||
/**@type {number}*/ index;
|
/**@type {number}*/ index;
|
||||||
/**@type {SlashCommandScope}*/ scope;
|
/**@type {SlashCommandScope}*/ scope;
|
||||||
|
/**@type {SlashCommandClosure}*/ closure;
|
||||||
|
|
||||||
/**@type {Object.<PARSER_FLAG,boolean>}*/ flags = {};
|
/**@type {Object.<PARSER_FLAG,boolean>}*/ flags = {};
|
||||||
|
|
||||||
@ -346,6 +348,39 @@ export class SlashCommandParser {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
replaceGetvar(value) {
|
||||||
|
return value.replace(/{{(get(?:global)?var)::([^}]+)}}/gi, (_, cmd, name) => {
|
||||||
|
name = name.trim();
|
||||||
|
// store pipe
|
||||||
|
const pipeName = `_PARSER_${uuidv4()}`;
|
||||||
|
const storePipe = new SlashCommandExecutor(null);
|
||||||
|
storePipe.command = this.commands['let'];
|
||||||
|
storePipe.name = 'let';
|
||||||
|
storePipe.value = `${pipeName} {{pipe}}`;
|
||||||
|
this.closure.executorList.push(storePipe);
|
||||||
|
// getvar / getglobalvar
|
||||||
|
const getvar = new SlashCommandExecutor(null);
|
||||||
|
getvar.command = this.commands[cmd];
|
||||||
|
getvar.name = 'cmd';
|
||||||
|
getvar.value = name;
|
||||||
|
this.closure.executorList.push(getvar);
|
||||||
|
// set to temp scoped var
|
||||||
|
const varName = `_PARSER_${uuidv4()}`;
|
||||||
|
const setvar = new SlashCommandExecutor(null);
|
||||||
|
setvar.command = this.commands['let'];
|
||||||
|
setvar.name = 'let';
|
||||||
|
setvar.value = `${varName} {{pipe}}`;
|
||||||
|
this.closure.executorList.push(setvar);
|
||||||
|
// return pipe
|
||||||
|
const returnPipe = new SlashCommandExecutor(null);
|
||||||
|
returnPipe.command = this.commands['return'];
|
||||||
|
returnPipe.name = 'return';
|
||||||
|
returnPipe.value = `{{var::${pipeName}}}`;
|
||||||
|
this.closure.executorList.push(returnPipe);
|
||||||
|
return `{{var::${varName}}}`;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
parse(text, verifyCommandNames = true, flags = null) {
|
parse(text, verifyCommandNames = true, flags = null) {
|
||||||
this.verifyCommandNames = verifyCommandNames;
|
this.verifyCommandNames = verifyCommandNames;
|
||||||
@ -380,6 +415,7 @@ export class SlashCommandParser {
|
|||||||
this.take(2); // discard opening {:
|
this.take(2); // discard opening {:
|
||||||
let closure = new SlashCommandClosure(this.scope);
|
let closure = new SlashCommandClosure(this.scope);
|
||||||
this.scope = closure.scope;
|
this.scope = closure.scope;
|
||||||
|
this.closure = closure;
|
||||||
this.discardWhitespace();
|
this.discardWhitespace();
|
||||||
while (this.testNamedArgument()) {
|
while (this.testNamedArgument()) {
|
||||||
const arg = this.parseNamedArgument();
|
const arg = this.parseNamedArgument();
|
||||||
@ -595,7 +631,11 @@ export class SlashCommandParser {
|
|||||||
if (listValues.length == 1) return listValues[0];
|
if (listValues.length == 1) return listValues[0];
|
||||||
return listValues;
|
return listValues;
|
||||||
}
|
}
|
||||||
return value.trim();
|
value = value.trim();
|
||||||
|
if (this.flags[PARSER_FLAG.REPLACE_GETVAR]) {
|
||||||
|
value = this.replaceGetvar(value);
|
||||||
|
}
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
testQuotedValue() {
|
testQuotedValue() {
|
||||||
@ -614,6 +654,9 @@ export class SlashCommandParser {
|
|||||||
let value = '';
|
let value = '';
|
||||||
while (!this.testQuotedValueEnd()) value += this.take(); // take all chars until closing quote
|
while (!this.testQuotedValueEnd()) value += this.take(); // take all chars until closing quote
|
||||||
this.take(); // discard closing quote
|
this.take(); // discard closing quote
|
||||||
|
if (this.flags[PARSER_FLAG.REPLACE_GETVAR]) {
|
||||||
|
value = this.replaceGetvar(value);
|
||||||
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -628,6 +671,9 @@ export class SlashCommandParser {
|
|||||||
let value = this.take(); // take the already tested opening bracket
|
let value = this.take(); // take the already tested opening bracket
|
||||||
while (!this.testListValueEnd()) value += this.take(); // take all chars until closing bracket
|
while (!this.testListValueEnd()) value += this.take(); // take all chars until closing bracket
|
||||||
value += this.take(); // take closing bracket
|
value += this.take(); // take closing bracket
|
||||||
|
if (this.flags[PARSER_FLAG.REPLACE_GETVAR]) {
|
||||||
|
value = this.replaceGetvar(value);
|
||||||
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -641,6 +687,9 @@ export class SlashCommandParser {
|
|||||||
parseValue() {
|
parseValue() {
|
||||||
let value = this.jumpedEscapeSequence ? this.take() : ''; // take the first, already tested, char if it is an escaped one
|
let value = this.jumpedEscapeSequence ? this.take() : ''; // take the first, already tested, char if it is an escaped one
|
||||||
while (!this.testValueEnd()) value += this.take(); // take all chars until value end
|
while (!this.testValueEnd()) value += this.take(); // take all chars until value end
|
||||||
|
if (this.flags[PARSER_FLAG.REPLACE_GETVAR]) {
|
||||||
|
value = this.replaceGetvar(value);
|
||||||
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user