Skip to content

Commit 44ef7b4

Browse files
Merge 257f680 into 91a7c39
2 parents 91a7c39 + 257f680 commit 44ef7b4

4 files changed

Lines changed: 73 additions & 6 deletions

File tree

source/NVDAObjects/UIA/wordDocument.py

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
from comtypes import COMError
77
from collections import defaultdict
8+
import mathPres
89
from scriptHandler import isScriptWaiting
910
import textInfos
1011
import eventHandler
@@ -24,6 +25,7 @@
2425
WordDocument as WordDocumentBase,
2526
WordDocumentTextInfo as LegacyWordDocumentTextInfo
2627
)
28+
from NVDAObjects import NVDAObject
2729
from scriptHandler import script
2830

2931

@@ -124,6 +126,12 @@ def label(self):
124126

125127
class WordDocumentTextInfo(UIATextInfo):
126128

129+
def getMathMl(self, field):
130+
mathml = field.get('mathml')
131+
if not mathml:
132+
raise LookupError("No MathML")
133+
return mathml
134+
127135
def _ensureRangeVisibility(self):
128136
try:
129137
inView = self.pointAtStart in self.obj.location
@@ -186,6 +194,8 @@ def _getControlFieldForUIAObject(self, obj, isEmbedded=False, startOfNode=False,
186194
elif obj.UIAElement.cachedControlType==UIAHandler.UIA_GroupControlTypeId and obj.name:
187195
field['role']=controlTypes.Role.EMBEDDEDOBJECT
188196
field['alwaysReportName']=True
197+
elif obj.role == controlTypes.Role.MATH:
198+
field['mathml'] = obj.mathMl
189199
elif obj.UIAElement.cachedControlType==UIAHandler.UIA_CustomControlTypeId and obj.name:
190200
# Include foot note and endnote identifiers
191201
field['content']=obj.name
@@ -281,6 +291,32 @@ def getTextWithFields(self,formatConfig=None):
281291
if len(fields)==0:
282292
# Nothing to do... was probably a collapsed range.
283293
return fields
294+
295+
# MS Word tries to produce speakable math content within equations.
296+
# However, using mathPlayer with the exposed mathml property on the equation is much nicer.
297+
# But, we therefore need to remove the inner math content if reading by line
298+
if not formatConfig or not formatConfig.get('extraDetail'):
299+
# We really only want to remove content if we can guarantee that mathPlayer is available.
300+
mathPres.ensureInit()
301+
if mathPres.speechProvider or mathPres.brailleProvider:
302+
curLevel = 0
303+
mathLevel = None
304+
mathStartIndex = None
305+
mathEndIndex = None
306+
for index in range(len(fields)):
307+
field = fields[index]
308+
if isinstance(field, textInfos.FieldCommand) and field.command == "controlStart":
309+
curLevel += 1
310+
if mathLevel is None and field.field.get('mathml'):
311+
mathLevel = curLevel
312+
mathStartIndex = index
313+
elif isinstance(field, textInfos.FieldCommand) and field.command == "controlEnd":
314+
if curLevel == mathLevel:
315+
mathEndIndex = index
316+
curLevel -= 1
317+
if mathEndIndex is not None:
318+
del fields[mathStartIndex+1:mathEndIndex]
319+
284320
# Sometimes embedded objects and graphics In MS Word can cause a controlStart then a controlEnd with no actual formatChange / text in the middle.
285321
# SpeakTextInfo always expects that the first lot of controlStarts will always contain some text.
286322
# Therefore ensure that the first lot of controlStarts does contain some text by inserting a blank formatChange and empty string in this case.
@@ -362,16 +398,22 @@ def getTextWithFields(self,formatConfig=None):
362398

363399
class WordBrowseModeDocument(UIABrowseModeDocument):
364400

365-
def shouldSetFocusToObj(self,obj):
401+
def _shouldSetFocusToObj(self, obj: NVDAObject) -> bool:
366402
# Ignore strange editable text fields surrounding most inner fields (links, table cells etc)
367403
if obj.role==controlTypes.Role.EDITABLETEXT and obj.UIAElement.cachedAutomationID.startswith('UIA_AutomationId_Word_Content'):
368404
return False
405+
elif obj.role == controlTypes.Role.MATH:
406+
# Don't set focus to math equations otherwise they cannot be interacted with mathPlayer.
407+
return False
369408
return super(WordBrowseModeDocument,self).shouldSetFocusToObj(obj)
370409

371410
def shouldPassThrough(self,obj,reason=None):
372411
# Ignore strange editable text fields surrounding most inner fields (links, table cells etc)
373412
if obj.role==controlTypes.Role.EDITABLETEXT and obj.UIAElement.cachedAutomationID.startswith('UIA_AutomationId_Word_Content'):
374413
return False
414+
elif obj.role == controlTypes.Role.MATH:
415+
# Don't activate focus mode for math equations otherwise they cannot be interacted with mathPlayer.
416+
return False
375417
return super(WordBrowseModeDocument,self).shouldPassThrough(obj,reason=reason)
376418

377419
def script_tab(self,gesture):
@@ -397,7 +439,15 @@ def _iterNodesByType(self,nodeType,direction="next",pos=None):
397439
class WordDocumentNode(UIA):
398440
TextInfo=WordDocumentTextInfo
399441

442+
def _get_mathMl(self):
443+
try:
444+
return self._getUIACacheablePropertyValue(self._UIACustomProps.word_mathml.id)
445+
except COMError:
446+
pass
447+
400448
def _get_role(self):
449+
if self.mathMl:
450+
return controlTypes.Role.MATH
401451
role=super(WordDocumentNode,self).role
402452
# Footnote / endnote elements currently have a role of unknown. Force them to editableText so that theyr text is presented correctly
403453
if role==controlTypes.Role.UNKNOWN:

source/_UIACustomProps.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,3 +88,11 @@ def __init__(self):
8888
programmaticName="ItemCount",
8989
uiaType=UIAutomationType.INT,
9090
)
91+
92+
# A property for fetching raw MathML from an equation node in Microsoft Word.
93+
# Available in MS Word build 14326 and higher.
94+
self.word_mathml = CustomPropertyInfo(
95+
guid=GUID("{FA170AB3-3229-4E7C-827F-DD05EE0481D9}"),
96+
programmaticName="Word.MathML",
97+
uiaType=UIAutomationType.STRING,
98+
)

user_docs/en/changes.t2t

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ Affected users will need to download this update manually.
2929
- Error notifications can be enabled (advanced settings) when using any version of NVDA. (#12672)
3030
- In Windows 10 and later, NVDA will announce the suggestion count when entering search terms in apps such as Settings and Microsoft Store. (#7330, #12758, #12790)
3131
- Table navigation is now supported in grid controls created using the Out-GridView cmdlet in PowerShell. (#12928)
32+
- In Microsoft Word accessed via UI Automation, NVDA will now make use of mathPlayer to read and navigate Office math equations. (#12946)
33+
- For this to work, you must be running Microsoft Word 365/2016 build 14326 or later.
34+
- MathType equations must also be manually converted to Office Math by selecting each and choosing Equation options -> Convert to Office Math in the context menu.
35+
-
3236
-
3337

3438

user_docs/en/userGuide.t2t

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -614,14 +614,19 @@ MathPlayer is available as a free download from: https://www.dessci.com/en/produ
614614

615615
NVDA supports the following types of mathematical content:
616616
- MathML in Mozilla Firefox, Microsoft Internet Explorer and Google Chrome.
617-
- Design Science MathType in Microsoft Word and PowerPoint.
618-
MathType needs to be installed in order for this to work.
617+
- Microsoft Word 365 Modern Math Equations via UI automation:
618+
NVDA is able to read and interact with math equations in Microsoft Word 365/2016 build 14326 and higher.
619+
Note however that any previously created MathType equations must be first converted to Office Math by selecting each and choosing Equation Options -> Convert to Office Math in the context menu. Ensure your version of MathType is the latest version before doing this.
620+
Microsoft Word also now provides linea symbol-based navigation through the equations itself, and supports inputting math using several syntaxes, including LateX. For further details, please see [Linear format equations using UnicodeMath and LaTeX in Word https://support.microsoft.com/en-us/office/linear-format-equations-using-unicodemath-and-latex-in-word-2e00618d-b1fd-49d8-8cb4-8d17f25754f8]
621+
- Microsoft Powerpoint, and older versions of Microsoft Word:
622+
NVDA can read and navigate MathType equations in both Microsoft Powerpoint and Microsoft word.
623+
MathType needs to be installed in order for this to work.
619624
The trial version is sufficient.
620625
It can be downloaded from https://www.dessci.com/en/products/mathtype/
621-
- MathML in Adobe Reader.
626+
- Adobe Reader
622627
Note that this is not an official standard yet, so there is currently no publicly available software that can produce this content.
623-
- Math in Kindle for PC for books with accessible math.
624-
-
628+
- Kindle Reader for PC:
629+
NVDA can read and navigate Math in Kindle for PC for books with accessible math.
625630

626631
When reading a document, NVDA will speak any supported mathematical content where it occurs.
627632
If you are using a braille display, it will also be displayed in braille.

0 commit comments

Comments
 (0)