Skip to content

Commit

Permalink
Ensure that when character normalization results in a character with …
Browse files Browse the repository at this point in the history
…symbol definition, the symbol replacement is spoken (#16950)

Fixup for #16622

Summary of the issue:
When unicode normalization of a character (e.g. ·) resulted into a character that had a symbol definition (e.g. ·, middle dot), the symbol definition wasn't applied to the normalization. This resulted in NVDA speaking nothing or only the word normalized.

Description of user facing changes
NVDA will now properly speak the · character (Greek Ano Teleia) as middle dot when normalizing. This also applies to other characters where normalization results in a character that's part of the symbol dictionary.

Description of development approach
When normalizing a character, ensure it is thrown through characterProcessing.processSpeechSymbol.
  • Loading branch information
LeonarddeR authored Aug 5, 2024
1 parent e89ccb3 commit 62a560c
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 1 deletion.
4 changes: 3 additions & 1 deletion source/speech/speech.py
Original file line number Diff line number Diff line change
Expand Up @@ -467,7 +467,9 @@ def _getSpellingSpeechWithoutCharMode(
speakCharAs = symbol
elif not isNormalized and unicodeNormalization:
if (normalized := unicodeNormalize(speakCharAs)) != speakCharAs:
speakCharAs = " ".join(normalized)
speakCharAs = " ".join(
characterProcessing.processSpeechSymbol(locale, normChar) for normChar in normalized
)
isNormalized = True
if config.conf['speech']['autoLanguageSwitching']:
yield LangChangeCommand(locale)
Expand Down
53 changes: 53 additions & 0 deletions tests/unit/test_speech.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import unittest

import config
from characterProcessing import processSpeechSymbol
from speech import (
_getSpellingCharAddCapNotification,
_getSpellingSpeechAddCharMode,
Expand Down Expand Up @@ -475,6 +476,58 @@ def test_decomposed_normalizeOnReport(self):
)
self.assertEqual(repr(list(output)), expected)

def test_normalizedInSymbolDict_normalizeOff(self):
expected = repr([
'·',
EndUtteranceCommand(),
])
output = _getSpellingSpeechWithoutCharMode(
text='·',
locale="en",
useCharacterDescriptions=False,
sayCapForCapitals=False,
capPitchChange=0,
beepForCapitals=False,
unicodeNormalization=False,
reportNormalizedForCharacterNavigation=False,
)
self.assertEqual(repr(list(output)), expected)

def test_normalizedInSymbolDict_normalizeOnDontReport(self):
expected = repr([
processSpeechSymbol("en", "·"),
EndUtteranceCommand(),
])
output = _getSpellingSpeechWithoutCharMode(
text='·',
locale="en",
useCharacterDescriptions=False,
sayCapForCapitals=False,
capPitchChange=0,
beepForCapitals=False,
unicodeNormalization=True,
reportNormalizedForCharacterNavigation=False,
)
self.assertEqual(repr(list(output)), expected)

def test_normalizedInSymbolDict_normalizeOnReport(self):
expected = repr([
processSpeechSymbol("en", "·"),
' normalized',
EndUtteranceCommand(),
])
output = _getSpellingSpeechWithoutCharMode(
text='·',
locale="en",
useCharacterDescriptions=False,
sayCapForCapitals=False,
capPitchChange=0,
beepForCapitals=False,
unicodeNormalization=True,
reportNormalizedForCharacterNavigation=True,
)
self.assertEqual(repr(list(output)), expected)


class SpeechExtensionPoints(unittest.TestCase):

Expand Down

0 comments on commit 62a560c

Please sign in to comment.