Skip to content

Commit 0170b7b

Browse files
committed
Langauge switching wasn't switching the voice.
Now it does. Fixes #81.
1 parent 7fcfc67 commit 0170b7b

File tree

1 file changed

+32
-27
lines changed

1 file changed

+32
-27
lines changed

addon/globalPlugins/MathCAT/MathCAT.py

Lines changed: 32 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@
8282
RE_MATH_LANG = re.compile(r"""<math .*(xml:)?lang=["']([^'"]+)["'].*>""")
8383

8484

85-
def getLanguageToUse(mathMl: str) -> str:
85+
def getLanguageToUse(mathMl: str = "") -> str:
8686
"""Get the language specified in a math tag if the language pref is Auto, else the language preference."""
8787
mathCATLanguageSetting = "Auto"
8888
try:
@@ -98,22 +98,30 @@ def getLanguageToUse(mathMl: str) -> str:
9898
languageMatch = RE_MATH_LANG.search(mathMl)
9999
language = (languageMatch.group(2) if languageMatch else getCurrentLanguage()) # seems to be current voice's language
100100
language = language.lower().replace("_", "-")
101+
if language == "cmn":
102+
language = "zh-cmn"
103+
elif language == "yue":
104+
language = "zh-yue"
101105
return language
102106

103107

104-
def ConvertSSMLTextForNVDA(text: str, language: str = "") -> list:
108+
def ConvertSSMLTextForNVDA(text: str) -> list:
109+
"""Change the SSML in the text into NVDA's command structure.
110+
The environment is examined to determine whether a language switch is needed"""
105111
# MathCAT's default rate is 180 wpm.
106112
# Assume that 0% is 80 wpm and 100% is 450 wpm and scale accordingly.
107113
# log.info(f"\nSpeech str: '{text}'")
108-
if language == "": # shouldn't happen
109-
language = "en" # fallback to what was being used
110-
mathCATLanguageSetting = (
111-
"en" # fallback in case libmathcat.GetPreference fails for unknown reasons
112-
)
114+
115+
# find MathCAT's language setting and store it away (could be "Auto")
116+
# if MathCAT's setting doesn't match NVDA's language setting, change the language that is used
117+
mathCATLanguageSetting = "en" # set in case GetPreference fails
113118
try:
114119
mathCATLanguageSetting = libmathcat.GetPreference("Language")
115120
except Exception as e:
116121
log.error(e)
122+
language = getLanguageToUse()
123+
nvdaLanguage = getCurrentLanguage().replace("_", "-")
124+
log.info(f"\nConvertSSMLTextForNVDA: mathCATLanguageSetting={mathCATLanguageSetting}, Language to use={language}, NVDA={nvdaLanguage}")
117125

118126
synth = getSynth()
119127
_monkeyPatchESpeak()
@@ -135,13 +143,14 @@ def ConvertSSMLTextForNVDA(text: str, language: str = "") -> list:
135143
use_character = (CharacterModeCommand in supported_commands and synth.name != "oneCore")
136144
out = []
137145
if mathCATLanguageSetting != language:
146+
# log.info(f"Setting language to {language}")
138147
try:
139-
# log.info(f"Setting language to {language}")
140148
libmathcat.SetPreference("Language", language)
141-
out.append(LangChangeCommand(language))
142149
except Exception as e:
143150
log.error(e)
144-
language = mathCATLanguageSetting # didn't do the 'append'
151+
language = mathCATLanguageSetting # didn't set the language
152+
if language != nvdaLanguage:
153+
out.append(LangChangeCommand(language))
145154

146155
resetProsody = []
147156
for m in RE_MATHML_SPEECH.finditer(text):
@@ -180,12 +189,15 @@ def ConvertSSMLTextForNVDA(text: str, language: str = "") -> list:
180189
out.extend((" ", m.group(0), " "))
181190
# there is a bug in MS Word that concats the math and the next character outside of math, so we add a space
182191
out.append(" ")
192+
183193
if mathCATLanguageSetting != language:
194+
# restore the old value (probably "Auto")
184195
try:
185196
libmathcat.SetPreference("Language", mathCATLanguageSetting)
186-
out.append(LangChangeCommand(None))
187197
except Exception as e:
188198
log.error(e)
199+
if language != nvdaLanguage:
200+
out.append(LangChangeCommand(None))
189201
# log.info(f"Speech commands: '{out}'")
190202
return out
191203

@@ -204,17 +216,15 @@ class MathCATInteraction(mathPres.MathInteractionNVDAObject):
204216
def __init__(self, provider=None, mathMl: Optional[str] = None):
205217
super(MathCATInteraction, self).__init__(provider=provider, mathMl=mathMl)
206218
if mathMl is None:
207-
self._language = "en"
208219
self.init_mathml = "<math></math>"
209220
else:
210-
self._language = getLanguageToUse(mathMl)
211221
self.init_mathml = mathMl
212222

213223
def reportFocus(self):
214224
super(MathCATInteraction, self).reportFocus()
215225
try:
216226
text = libmathcat.DoNavigateCommand("ZoomIn")
217-
speech.speak(ConvertSSMLTextForNVDA(text, self._language))
227+
speech.speak(ConvertSSMLTextForNVDA(text))
218228
except Exception as e:
219229
log.error(e)
220230
# Translators: this message directs users to look in the log file
@@ -282,7 +292,7 @@ def script_navigate(self, gesture: KeyboardInputGesture):
282292
False,
283293
)
284294
# log.info(f"Navigate speech for {gesture.vkCode}/(s={'shift' in modNames}, c={'control' in modNames}): '{text}'")
285-
speech.speak(ConvertSSMLTextForNVDA(text, self._language))
295+
speech.speak(ConvertSSMLTextForNVDA(text))
286296

287297
# update the braille to reflect the nav position (might be excess code, but it works)
288298
nav_node = libmathcat.GetNavigationMathMLId()
@@ -416,25 +426,20 @@ def __init__(self):
416426
try:
417427
# IMPORTANT -- SetRulesDir must be the first call to libmathcat besides GetVersion()
418428
rules_dir = path.join(path.dirname(path.abspath(__file__)), "Rules")
419-
log.info(f"MathCAT {libmathcat.GetVersion()} installed. Using rules dir: {rules_dir}")
429+
# log.info(f"MathCAT {libmathcat.GetVersion()} installed. Using rules dir: {rules_dir}")
420430
libmathcat.SetRulesDir(rules_dir)
421431
libmathcat.SetPreference("TTS", "SSML")
422432
except Exception as e:
423433
log.error(e)
424434
# Translators: this message directs users to look in the log file
425435
speech.speakMessage(_("MathCAT initialization failed: see NVDA error log for details"))
426-
self._language = ""
427436

428437
def getSpeechForMathMl(self, mathml: str):
429438
try:
430-
self._language = getLanguageToUse(mathml)
439+
# need to set Language before the MathML for DecimalSeparator canonicalization
440+
language = getLanguageToUse(mathml)
431441
# MathCAT should probably be extended to accept "extlang" tagging, but it uses lang-region tagging at the moment
432-
if self._language == "cmn":
433-
self._language = "zh-cmn"
434-
elif self._language == "yue":
435-
self._language = "zh-yue"
436-
# needs to be set before the MathML for DecimalSeparator canonicalization
437-
libmathcat.SetPreference("Language", self._language)
442+
libmathcat.SetPreference("Language", language)
438443
libmathcat.SetMathML(mathml)
439444
except Exception as e:
440445
log.error(e)
@@ -455,17 +460,17 @@ def getSpeechForMathMl(self, mathml: str):
455460
"CapitalLetters_UseWord",
456461
"true" if synthConfig["sayCapForCapitals"] else "false",
457462
)
458-
# log.info(f"Speech text ({self._language}): {libmathcat.GetSpokenText()}")
463+
# log.info(f"Speech text: {libmathcat.GetSpokenText()}")
459464
if PitchCommand in supported_commands:
460465
libmathcat.SetPreference("CapitalLetters_Pitch", str(synthConfig["capPitchChange"]))
461466
if self._add_sounds():
462467
return (
463468
[BeepCommand(800, 25)]
464-
+ ConvertSSMLTextForNVDA(libmathcat.GetSpokenText(), self._language)
469+
+ ConvertSSMLTextForNVDA(libmathcat.GetSpokenText())
465470
+ [BeepCommand(600, 15)]
466471
)
467472
else:
468-
return ConvertSSMLTextForNVDA(libmathcat.GetSpokenText(), self._language)
473+
return ConvertSSMLTextForNVDA(libmathcat.GetSpokenText())
469474

470475
except Exception as e:
471476
log.error(e)

0 commit comments

Comments
 (0)