diff --git a/custom_components/universal_notifier/utils.py b/custom_components/universal_notifier/utils.py index 6fffe1a..1bff5a6 100644 --- a/custom_components/universal_notifier/utils.py +++ b/custom_components/universal_notifier/utils.py @@ -94,10 +94,23 @@ def get_current_slot_info(slots_conf: dict, now_time, current_vol = vol_val return current_slot, current_vol +# Tag SSML supportati dai motori TTS (Alexa, Google): vanno preservati. +SSML_TAGS = { + "speak", "voice", "prosody", "break", "say-as", "emphasis", + "lang", "phoneme", +} +_TAG_PATTERN = re.compile(r'<\s*/?\s*([a-zA-Z][\w:-]*)[^>]*>') + +def _strip_non_ssml_tags(text: str) -> str: + """Rimuove i tag HTML mantenendo i tag SSML noti.""" + return _TAG_PATTERN.sub( + lambda m: m.group(0) if m.group(1).lower() in SSML_TAGS else '', text + ) + def clean_text_for_tts(text: str) -> str: """Rimuove caratteri speciali per la sintesi vocale.""" if not text: return "" - text = re.sub(r'<[^>]+>', '', text) # Via HTML tags + text = _strip_non_ssml_tags(text) # Via HTML tags, tiene SSML text = re.sub(r'[*_`\[\]]', '', text) # Via markdown text = re.sub(r'http\S+', '', text) # Via URL # Via emoji/icon (preserva lettere accentate latin-1) diff --git a/tests/test_utils.py b/tests/test_utils.py index 888dbc6..d0a070b 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -201,6 +201,21 @@ def test_none_text(self): def test_collapses_whitespace(self): assert clean_text_for_tts("hello world") == "hello world" + def test_preserves_ssml_voice_tag(self): + assert clean_text_for_tts( + "Il sistema è operativo!" + ) == "Il sistema è operativo!" + + @pytest.mark.parametrize("tag", ["prosody rate='slow'", "break time='500ms'", + "say-as interpret-as='date'", "emphasis"]) + def test_preserves_other_ssml_tags(self, tag): + assert f"<{tag}>" in clean_text_for_tts(f"<{tag}>ciao") + + def test_strips_html_around_ssml(self): + assert clean_text_for_tts( + "ciao" + ) == "ciao" + # ============================================================================ # sanitize_text_visual