Added regex filter option to TTS extension (#4924)

* Add regex filter option to TTS extension

- Added checkbox to enable/disable regex filtering of TTS text
- Added text input for custom regex patterns
- Default pattern removes emojis and non-English text while preserving letters, numbers, spaces, and punctuation
- Regex is applied after asterisk removal and other text processing
- Includes error handling for invalid regex patterns
- Automatically cleans up extra spaces after regex removal

* reverted the accidental change in tts_skip_tags description
clarified the regex description

* Add regex validation warning to TTS settings

* fixed regex field in UI

* reworked the regex warning

* changed the regex event to change (input might not have worked correctly)

* Apply review comments

* Spacing fix

---------

Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
This commit is contained in:
ZhenyaPav
2025-12-31 20:03:04 +02:00
committed by GitHub
parent 0dcd9906bf
commit ef89d0f291
2 changed files with 60 additions and 1 deletions
+49 -1
View File
@@ -1,6 +1,6 @@
import { cancelTtsPlay, eventSource, event_types, getCurrentChatId, isStreamingEnabled, name2, saveSettingsDebounced, substituteParams } from '../../../script.js';
import { ModuleWorkerWrapper, extension_settings, getContext, renderExtensionTemplateAsync } from '../../extensions.js';
import { delay, escapeRegex, getBase64Async, getStringHash, onlyUnique } from '../../utils.js';
import { delay, escapeRegex, getBase64Async, getStringHash, onlyUnique, regexFromString } from '../../utils.js';
import { EdgeTtsProvider } from './edge.js';
import { ElevenLabsTtsProvider } from './elevenlabs.js';
import { SileroTtsProvider } from './silerotts.js';
@@ -640,6 +640,16 @@ async function processTtsQueue() {
: text.replaceAll('*', '').trim(); // remove just the asterisks
}
if (extension_settings.tts.apply_regex && extension_settings.tts.regex_pattern) {
const regex = regexFromString(extension_settings.tts.regex_pattern);
if (regex) {
// Clean up extra spaces that might be left after removal
text = text.replace(regex, '').replace(/\s+/g, ' ').trim();
} else {
console.warn('Invalid regex pattern:', extension_settings.tts.regex_pattern);
}
}
if (extension_settings.tts.narrate_quoted_only) {
const partJoiner = (ttsProvider?.separator || ' ... ');
text = joinQuotedBlocks(text, { separator: partJoiner, includeQuotes: true });
@@ -827,6 +837,10 @@ function loadSettings() {
$('#tts_skip_codeblocks').prop('checked', extension_settings.tts.skip_codeblocks);
$('#tts_skip_tags').prop('checked', extension_settings.tts.skip_tags);
$('#tts_multi_voice_enabled').prop('checked', extension_settings.tts.multi_voice_enabled);
$('#tts_apply_regex').prop('checked', extension_settings.tts.apply_regex);
$('#tts_regex_pattern').val(extension_settings.tts.regex_pattern);
$('#tts_regex_block').toggle(extension_settings.tts.apply_regex);
updateRegexPatternWarning();
$('#playback_rate').val(extension_settings.tts.playback_rate);
$('#playback_rate_counter').val(Number(extension_settings.tts.playback_rate).toFixed(2));
$('#playback_rate_block').toggle(extension_settings.tts.currentProvider !== 'System');
@@ -842,6 +856,8 @@ const defaultSettings = {
narrate_user: false,
playback_rate: 1,
multi_voice_enabled: false,
apply_regex: false,
regex_pattern: '',
};
function setTtsStatus(status, success) {
@@ -942,6 +958,36 @@ function onMultiVoiceClick() {
initVoiceMap();
}
function onApplyRegexChange() {
extension_settings.tts.apply_regex = !!$('#tts_apply_regex').prop('checked');
saveSettingsDebounced();
$('#tts_regex_block').toggle(extension_settings.tts.apply_regex);
updateRegexPatternWarning();
}
function onRegexPatternChange() {
extension_settings.tts.regex_pattern = $('#tts_regex_pattern').val().toString();
saveSettingsDebounced();
updateRegexPatternWarning();
}
function updateRegexPatternWarning() {
const warning = $('#tts_regex_warning');
if (!extension_settings.tts.apply_regex) {
warning.hide();
return;
}
const pattern = extension_settings.tts.regex_pattern;
if (!pattern) {
warning.hide();
return;
}
const regex = regexFromString(pattern);
warning.toggle(!regex);
}
//##############//
// TTS Provider //
//##############//
@@ -1451,6 +1497,8 @@ jQuery(async function () {
$('#tts_narrate_by_paragraphs').on('click', onNarrateByParagraphsClick);
$('#tts_narrate_user').on('click', onNarrateUserClick);
$('#tts_multi_voice_enabled').on('click', onMultiVoiceClick);
$('#tts_apply_regex').on('change', onApplyRegexChange);
$('#tts_regex_pattern').on('input', onRegexPatternChange);
$('#playback_rate').on('input', function () {
const value = $(this).val();