From fe42e198d2ad53698bd53c4dc4331e2220d2dc56 Mon Sep 17 00:00:00 2001 From: newtextdoc1111 Date: Wed, 29 Oct 2025 14:52:31 +0900 Subject: [PATCH] fix: Fix tag normalization to handle multi-tags (#36) --- tests/js/utils.test.js | 33 ++++++++++++++++++++++++--------- web/js/utils.js | 14 +++++++++++--- 2 files changed, 35 insertions(+), 12 deletions(-) diff --git a/tests/js/utils.test.js b/tests/js/utils.test.js index 073e579..38b23a1 100644 --- a/tests/js/utils.test.js +++ b/tests/js/utils.test.js @@ -196,34 +196,49 @@ describe('normalizeTagToInsert', () => { settingValues.replaceUnderscoreWithSpace = false; expect(normalizeTagToInsert('blue_hair(style)')).toBe('blue_hair\\(style\\)'); - - settingValues.replaceUnderscoreWithSpace = originalValue; }); test('should not replace underscores in wildcard syntax regardless of setting', () => { - const originalValue = settingValues.replaceUnderscoreWithSpace; - // Wildcard syntax should preserve underscores regardless of setting settingValues.replaceUnderscoreWithSpace = true; expect(normalizeTagToInsert('__wildcard__')).toBe('__wildcard__'); settingValues.replaceUnderscoreWithSpace = false; expect(normalizeTagToInsert('__wildcard__')).toBe('__wildcard__'); - - settingValues.replaceUnderscoreWithSpace = originalValue; }); test('should not replace underscores in symbol-only tags regardless of setting', () => { - const originalValue = settingValues.replaceUnderscoreWithSpace; - // Symbol-only tags should not be affected by the setting settingValues.replaceUnderscoreWithSpace = true; expect(normalizeTagToInsert('^_^')).toBe('^_^'); settingValues.replaceUnderscoreWithSpace = false; expect(normalizeTagToInsert('^_^')).toBe('^_^'); + }); - settingValues.replaceUnderscoreWithSpace = originalValue; + test('should not escape parentheses when tag contains commas (multi-tags)', () => { + const multiTag = 'masterpiece, best quality, (high quality), ultra-detailed'; + expect(normalizeTagToInsert(multiTag)).toBe('masterpiece, best quality, (high quality), ultra-detailed'); + }); + + test('should not escape parentheses in multi-tag strings with parentheses', () => { + const multiTag = '(worst quality, low quality, normal quality), bad anatomy'; + expect(normalizeTagToInsert(multiTag)).toBe('(worst quality, low quality, normal quality), bad anatomy'); + }); + + test('should handle multi-tags with both underscores and parentheses correctly', () => { + settingValues.replaceUnderscoreWithSpace = true; + const multiTag = 'best_quality, (high_quality:1.2), ultra_detailed'; + expect(normalizeTagToInsert(multiTag)).toBe('best quality, (high quality:1.2), ultra detailed'); + + settingValues.replaceUnderscoreWithSpace = false; + expect(normalizeTagToInsert(multiTag)).toBe('best_quality, (high_quality:1.2), ultra_detailed'); + }); + + test('should still escape parentheses for single tags without commas', () => { + // Single tags (not multi-tags) should still have parentheses escaped + expect(normalizeTagToInsert('blue(hair)')).toBe('blue\\(hair\\)'); + expect(normalizeTagToInsert('(tag)')).toBe('\\(tag\\)'); }); }); diff --git a/web/js/utils.js b/web/js/utils.js index 11c8530..969c973 100644 --- a/web/js/utils.js +++ b/web/js/utils.js @@ -223,23 +223,31 @@ export function normalizeTagToSearch(str) { * Converts underscores to spaces only if the tag contains at least one letter or number, * and is not a wildcard call (e.g., "__wildcard__"). * Keeps underscores for tags that are only symbols (e.g. "^_^") or wildcard calls. - * @param {string} str + * For multi-tags (multiple tags with commas), parentheses are not escaped to preserve prompt weight syntax. + * @param {string} str * @returns {string} */ export function normalizeTagToInsert(str) { if (!str) return str; + // Check if multi-tag string + const isMultiTag = str.includes(','); + + // Check if the string contains at least one letter or number if (isContainsLetterOrNumber(str)) { const isWildcardCall = str.startsWith('__') && str.endsWith('__') && str.length > 4; if (!isWildcardCall && settingValues.replaceUnderscoreWithSpace) { // If doesn't wildcard call and setting is enabled, replace underscores with spaces - return escapeParentheses(str.replace(/_/g, " ")); + const result = str.replace(/_/g, " "); + // Only escape parentheses for single tags, not multi-tags + return isMultiTag ? result : escapeParentheses(result); } } // Otherwise, keep it as is (e.g., ""^_^", "__wildcard__") - return escapeParentheses(str); + // Only escape parentheses for single tags, not multi-tags + return isMultiTag ? str : escapeParentheses(str); } /**