Skip to content

Commit 67ad1ff

Browse files
authored
Add an option to use Word's native math speech in Word documents (#19700)
Closes #19670 Summary of the issue: A bug in Microsoft Word is causing math objects to be spoken inconsistently, sometimes using MathCAT and at other times using Word's native math speech. Description of user facing changes: An option is added to the math settings panel to use native math speech while in Word. When checked, MathCAT is disabled while in Word and re-enabled when another application gains focus. Description of developer facing changes: N/A Description of development approach: Handlers were added in winword.py for the gainFocus, loseFocus, and terminate events that disable and re-enable MathCAT. Two new functions were added to mathPres/__init__.py: disable and enable, which save and restore the three global provider objects.
1 parent 5e20004 commit 67ad1ff

5 files changed

Lines changed: 41 additions & 0 deletions

File tree

source/appModules/winword.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,11 @@
99
"""
1010

1111
import appModuleHandler
12+
import config
1213
from scriptHandler import script
1314
import ui
1415
from logHandler import log
16+
import mathPres
1517
from NVDAObjects.IAccessible.winword import WordDocument as IAccessibleWordDocument
1618
from NVDAObjects.UIA.wordDocument import WordDocument as UIAWordDocument
1719
from NVDAObjects.window.winword import (
@@ -57,6 +59,17 @@ def chooseNVDAObjectOverlayClasses(self, obj, clsList):
5759
if UIAWordDocument in clsList or IAccessibleWordDocument in clsList:
5860
clsList.insert(0, WinwordWordDocument)
5961

62+
def event_appModule_gainFocus(self):
63+
if config.conf["math"]["other"]["useWordNativeMath"]:
64+
mathPres.terminate()
65+
66+
def event_appModule_loseFocus(self):
67+
mathPres.initialize()
68+
69+
def terminate(self):
70+
mathPres.initialize()
71+
super().terminate()
72+
6073

6174
class WinwordWordDocument(WordDocument):
6275
def _get_description(self) -> str:

source/config/configSpec.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -525,6 +525,8 @@
525525
blockSeparators = string(default=", \u00a0\u202f")
526526
# Auto, '.', ',', Custom
527527
decimalSeparator = string(default="Auto")
528+
# Use native math speech instead of MathCAT in Word and Outlook
529+
useWordNativeMath = boolean(default=false)
528530
529531
[screenCurtain]
530532
enabled = boolean(default=false)

source/gui/settingsDialogs.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2891,6 +2891,14 @@ def makeSettings(self, settingsSizer: wx.BoxSizer) -> None:
28912891
else:
28922892
self.navSpeechList.SetSelection(0)
28932893

2894+
# Translators: label for checkbox to use native math speech instead of MathCAT in Word and Outlook
2895+
useWordNativeMathText = pgettext("math", "Use native math speech in Word and Outlook")
2896+
self.useWordNativeMathCheckBox = speechGroup.addItem(
2897+
wx.CheckBox(speechGroupBox, label=useWordNativeMathText),
2898+
)
2899+
self.bindHelpEvent("MathUseWordNative", self.useWordNativeMathCheckBox)
2900+
self.useWordNativeMathCheckBox.SetValue(config.conf["math"]["other"]["useWordNativeMath"])
2901+
28942902
# Translators: Text for the navigation group.
28952903
navGroupText = pgettext("math", "Navigation")
28962904
navGroupSizer = wx.StaticBoxSizer(wx.VERTICAL, self, label=navGroupText)
@@ -3080,6 +3088,7 @@ def onSave(self):
30803088
)
30813089
selectedBrailleIndex = self.brailleMathCodeList.GetSelection()
30823090
mathConf["braille"]["brailleCode"] = self._brailleCodeIds[selectedBrailleIndex]
3091+
mathConf["other"]["useWordNativeMath"] = self.useWordNativeMathCheckBox.GetValue()
30833092
mcPrefs = MathCATUserPreferences.fromNVDAConfig()
30843093
mcPrefs.apply()
30853094

source/mathPres/__init__.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,14 @@ def registerProvider(
7979
interactionProvider = provider
8080

8181

82+
def terminate() -> None:
83+
"""Terminate the mathPres module."""
84+
global speechProvider, brailleProvider, interactionProvider
85+
speechProvider = None
86+
brailleProvider = None
87+
interactionProvider = None
88+
89+
8290
def initialize() -> None:
8391
# Register builtin providers if a plugin hasn't registered others.
8492
if not speechProvider or not brailleProvider or not interactionProvider:

user_docs/en/userGuide.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3329,6 +3329,15 @@ Whether to speak the expression after moving to it or give an overview.
33293329
| Options | Speak, Describe overview |
33303330
| Default | Speak |
33313331

3332+
###### Use native math speech in Word and Outlook {#MathUseWordNative}
3333+
3334+
When enabled, NVDA uses Microsoft Word's built-in math presentation (speech, braille, and interaction) instead of MathCAT when reading and interacting with equations in Word documents.
3335+
3336+
| . {.hideHeaderRow} | . |
3337+
|---|---|
3338+
| Options | Checked, Unchecked |
3339+
| Default | Unchecked |
3340+
33323341
##### Navigation Options {#MathNavigation}
33333342

33343343
###### Default navigation mode {#MathNavMode}

0 commit comments

Comments
 (0)