From 01b629bd493a474fd76875d89e208185a59ed6c1 Mon Sep 17 00:00:00 2001 From: Cohee <18619528+Cohee1207@users.noreply.github.com> Date: Tue, 21 Nov 2023 02:54:04 +0200 Subject: [PATCH] New syntax for sendas command --- public/scripts/slash-commands.js | 58 ++++++++++++++++++++------------ public/style.css | 2 +- 2 files changed, 37 insertions(+), 23 deletions(-) diff --git a/public/scripts/slash-commands.js b/public/scripts/slash-commands.js index 31cf55209..2a5066036 100644 --- a/public/scripts/slash-commands.js +++ b/public/scripts/slash-commands.js @@ -77,21 +77,22 @@ class SlashCommandParser { let unnamedArg; if (args.length > 0) { - const argsArray = args.split(' '); - for (let arg of argsArray) { - const equalsIndex = arg.indexOf('='); - if (equalsIndex !== -1) { - const key = arg.substring(0, equalsIndex); - const value = arg.substring(equalsIndex + 1); - // Replace "wrapping quotes" used for escaping spaces - argObj[key] = value.replace(/(^")|("$)/g, ''); - } - else { - break; - } + // Match named arguments + const namedArgPattern = /(\w+)=("(?:\\.|[^"\\])*"|\S+)/g; + let match; + while ((match = namedArgPattern.exec(args)) !== null) { + const key = match[1]; + const value = match[2]; + // Remove the quotes around the value, if any + argObj[key] = value.replace(/(^")|("$)/g, ''); } - unnamedArg = argsArray.slice(Object.keys(argObj).length).join(' '); + // Match unnamed argument + const unnamedArgPattern = /(?:\w+=(?:"(?:\\.|[^"\\])*"|\S+)\s*)*(.*)/s; + match = unnamedArgPattern.exec(args); + if (match !== null) { + unnamedArg = match[1].trim(); + } // Excluded commands format in their own function if (!excludedFromRegex.includes(command)) { @@ -132,7 +133,7 @@ parser.addCommand('name', setNameCallback, ['persona'], '(filename) – sets a background according to filename, partial names allowed', false, true); -parser.addCommand('sendas', sendMessageAs, [], ` – sends message as a specific character. Uses character avatar if it exists in the characters list. Example that will send "Hello, guys!" from "Chloe":
/sendas Chloe
Hello, guys!
`, true, true); +parser.addCommand('sendas', sendMessageAs, [], ` – sends message as a specific character. Uses character avatar if it exists in the characters list. Example that will send "Hello, guys!" from "Chloe": /sendas name="Chloe" Hello, guys!`, true, true); parser.addCommand('sys', sendNarratorMessage, ['nar'], '(text) – sends message as a system narrator', false, true); parser.addCommand('sysname', setNarratorName, [], '(name) – sets a name for future system narrator messages in this chat (display only). Default: System. Leave empty to reset.', true, true); parser.addCommand('comment', sendCommentMessage, [], '(text) – adds a note/comment message not part of the chat', false, true); @@ -499,19 +500,32 @@ async function setNarratorName(_, text) { await saveChatConditional(); } -export async function sendMessageAs(_, text) { +export async function sendMessageAs(namedArgs, text) { if (!text) { return; } - const parts = text.split('\n'); - if (parts.length <= 1) { - toastr.warning('Both character name and message are required. Separate them with a new line.'); - return; - } + let name; + let mesText; - const name = parts.shift().trim(); - let mesText = parts.join('\n').trim(); + if (namedArgs.name) { + name = namedArgs.name.trim(); + mesText = text.trim(); + + if (!name && !text) { + toastr.warning('You must specify a name and text to send as'); + return; + } + } else { + const parts = text.split('\n'); + if (parts.length <= 1) { + toastr.warning('Both character name and message are required. Separate them with a new line.'); + return; + } + + name = parts.shift().trim(); + mesText = parts.join('\n').trim(); + } // Requires a regex check after the slash command is pushed to output mesText = getRegexedString(mesText, regex_placement.SLASH_COMMAND, { characterOverride: name }); diff --git a/public/style.css b/public/style.css index b46c1f8cb..2637870c6 100644 --- a/public/style.css +++ b/public/style.css @@ -218,7 +218,7 @@ table.responsiveTable { color: var(--white50a); } -.mes[is_system="true"] .mes_text br { +.mes[is_system="true"][ch_name="SillyTavern System"] .mes_text br { display: none; }