mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
WI regex key syntax highlighting
This commit is contained in:
@ -1502,9 +1502,9 @@ export function select2ModifyOptions(element, items, { select = false, changeEve
|
|||||||
* Can be used on a single global array, querying data from the server or anything similar.
|
* Can be used on a single global array, querying data from the server or anything similar.
|
||||||
*
|
*
|
||||||
* @param {function():Select2Option[]} dataProvider - The provider/function to retrieve the data - can be as simple as "() => myData" for arrays
|
* @param {function():Select2Option[]} dataProvider - The provider/function to retrieve the data - can be as simple as "() => myData" for arrays
|
||||||
* @return {object} The ajax object with the transport function to use on the select2 ajax property
|
* @return {{transport: function}} The ajax object with the transport function to use on the select2 ajax property
|
||||||
*/
|
*/
|
||||||
export function getDynamicSelect2DataViaAjax(dataProvider) {
|
export function dynamicSelect2DataViaAjax(dataProvider) {
|
||||||
function dynamicSelect2DataTransport(params, success, failure) {
|
function dynamicSelect2DataTransport(params, success, failure) {
|
||||||
var items = dataProvider();
|
var items = dataProvider();
|
||||||
// fitering if params.data.q available
|
// fitering if params.data.q available
|
||||||
@ -1524,3 +1524,44 @@ export function getDynamicSelect2DataViaAjax(dataProvider) {
|
|||||||
};
|
};
|
||||||
return ajax;
|
return ajax;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies syntax highlighting to a given regex string by generating HTML with classes
|
||||||
|
*
|
||||||
|
* @param {string} regexStr - The javascript compatible regex string
|
||||||
|
* @returns {string} The html representation of the highlighted regex
|
||||||
|
*/
|
||||||
|
export function highlightRegex(regexStr) {
|
||||||
|
// Function to escape HTML special characters for safety
|
||||||
|
const escapeHtml = (str) => str.replace(/[&<>"']/g, match => ({
|
||||||
|
'&': '&', '<': '<', '>': '>', '"': '"', "'": '''
|
||||||
|
})[match]);
|
||||||
|
|
||||||
|
// Replace special characters with their HTML-escaped forms
|
||||||
|
regexStr = escapeHtml(regexStr);
|
||||||
|
|
||||||
|
// Patterns that we want to highlight only if they are not escaped
|
||||||
|
const patterns = {
|
||||||
|
brackets: /(?<!\\)\[.*?\]/g, // Non-escaped squary brackets
|
||||||
|
quantifiers: /(?<!\\)[*+?{}]/g, // Non-escaped quantifiers
|
||||||
|
operators: /(?<!\\)[|.^$()]/g, // Non-escaped operators like | and ()
|
||||||
|
specialChars: /\\./g,
|
||||||
|
flags: /(?<=\/)([gimsuy]*)$/g, // Match trailing flags
|
||||||
|
delimiters: /^\/|(?<![\\<])\//g, // Match leading or trailing delimiters
|
||||||
|
};
|
||||||
|
|
||||||
|
// Function to replace each pattern with a highlighted HTML span
|
||||||
|
const wrapPattern = (pattern, className) => {
|
||||||
|
regexStr = regexStr.replace(pattern, match => `<span class="${className}">${match}</span>`);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Apply highlighting patterns
|
||||||
|
wrapPattern(patterns.brackets, 'regex-brackets');
|
||||||
|
wrapPattern(patterns.quantifiers, 'regex-quantifier');
|
||||||
|
wrapPattern(patterns.operators, 'regex-operator');
|
||||||
|
wrapPattern(patterns.specialChars, 'regex-special');
|
||||||
|
wrapPattern(patterns.flags, 'regex-flags');
|
||||||
|
wrapPattern(patterns.delimiters, 'regex-delimiter');
|
||||||
|
|
||||||
|
return `<span class="regex-highlight">${regexStr}</span>`;
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
import { saveSettings, callPopup, substituteParams, getRequestHeaders, chat_metadata, this_chid, characters, saveCharacterDebounced, menu_type, eventSource, event_types, getExtensionPromptByName, saveMetadata, getCurrentChatId, extension_prompt_roles } from '../script.js';
|
import { saveSettings, callPopup, substituteParams, getRequestHeaders, chat_metadata, this_chid, characters, saveCharacterDebounced, menu_type, eventSource, event_types, getExtensionPromptByName, saveMetadata, getCurrentChatId, extension_prompt_roles } from '../script.js';
|
||||||
import { download, debounce, initScrollHeight, resetScrollHeight, parseJsonFile, extractDataFromPng, getFileBuffer, getCharaFilename, getSortableDelay, escapeRegex, PAGINATION_TEMPLATE, navigation_option, waitUntilCondition, isTrueBoolean, setValueByPath, flashHighlight, select2ModifyOptions, getStringHash, getSelect2OptionId, getDynamicSelect2DataViaAjax } from './utils.js';
|
import { download, debounce, initScrollHeight, resetScrollHeight, parseJsonFile, extractDataFromPng, getFileBuffer, getCharaFilename, getSortableDelay, escapeRegex, PAGINATION_TEMPLATE, navigation_option, waitUntilCondition, isTrueBoolean, setValueByPath, flashHighlight, select2ModifyOptions, getStringHash, getSelect2OptionId, dynamicSelect2DataViaAjax, highlightRegex } from './utils.js';
|
||||||
import { extension_settings, getContext } from './extensions.js';
|
import { extension_settings, getContext } from './extensions.js';
|
||||||
import { NOTE_MODULE_NAME, metadata_keys, shouldWIAddPrompt } from './authors-note.js';
|
import { NOTE_MODULE_NAME, metadata_keys, shouldWIAddPrompt } from './authors-note.js';
|
||||||
import { registerSlashCommand } from './slash-commands.js';
|
import { registerSlashCommand } from './slash-commands.js';
|
||||||
@ -1332,6 +1332,7 @@ function getWorldEntry(name, data, entry) {
|
|||||||
const content = $('<span>').addClass('item').text(item.text);
|
const content = $('<span>').addClass('item').text(item.text);
|
||||||
const isRegex = isValidRegex(item.text);
|
const isRegex = isValidRegex(item.text);
|
||||||
if (isRegex) {
|
if (isRegex) {
|
||||||
|
content.html(highlightRegex(item.text));
|
||||||
content.addClass('regex_item').prepend($('<span>').addClass('regex_icon').text("•*").attr('title', 'Regex'));
|
content.addClass('regex_item').prepend($('<span>').addClass('regex_icon').text("•*").attr('title', 'Regex'));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1348,7 +1349,7 @@ function getWorldEntry(name, data, entry) {
|
|||||||
|
|
||||||
if (!isMobile()) {
|
if (!isMobile()) {
|
||||||
input.select2({
|
input.select2({
|
||||||
ajax: getDynamicSelect2DataViaAjax(() => worldEntryKeyOptionsCache),
|
ajax: dynamicSelect2DataViaAjax(() => worldEntryKeyOptionsCache),
|
||||||
tags: true,
|
tags: true,
|
||||||
tokenSeparators: [','],
|
tokenSeparators: [','],
|
||||||
tokenizer: customTokenizer,
|
tokenizer: customTokenizer,
|
||||||
|
@ -4035,4 +4035,13 @@ body:not(.movingUI) .drawer-content.maximized {
|
|||||||
height: 100vh;
|
height: 100vh;
|
||||||
z-index: 9999;
|
z-index: 9999;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* CSS styles using a consistent pastel color palette */
|
||||||
|
.regex-brackets { color: #FFB347; } /* Pastel Orange */
|
||||||
|
.regex-special { color: #B0E0E6; } /* Powder Blue */
|
||||||
|
.regex-quantifier { color: #DDA0DD; } /* Plum */
|
||||||
|
.regex-operator { color: #FFB6C1; } /* Light Pink */
|
||||||
|
.regex-flags { color: #98FB98; } /* Pale Green */
|
||||||
|
.regex-delimiter { font-weight: bold; color: #FF6961; } /* Pastel Red */
|
||||||
|
.regex-highlight { color: #FAF8F6; } /* Pastel White */
|
Reference in New Issue
Block a user