92
92
93
93
94
94
def getLanguageToUse (mathMl : str = "" ) -> str :
95
- """Get the language specified in a math tag if the language pref is Auto, else the language preference."""
95
+ """Get the language specified in a math tag if the language pref is Auto, else the language preference.
96
+
97
+ :param mathMl: The MathML string to examine for language. Defaults to an empty string.
98
+ :returns: The language string to use.
99
+ """
96
100
mathCATLanguageSetting : str = "Auto"
97
101
try :
98
102
# ignore regional differences if the MathCAT language setting doesn't have it.
@@ -117,8 +121,13 @@ def getLanguageToUse(mathMl: str = "") -> str:
117
121
118
122
119
123
def convertSSMLTextForNVDA (text : str ) -> list [str | SpeechCommand ]:
120
- """Change the SSML in the text into NVDA's command structure.
121
- The environment is examined to determine whether a language switch is needed"""
124
+ """
125
+ Change the SSML in the text into NVDA's command structure.
126
+ The environment is examined to determine whether a language switch is needed.
127
+
128
+ :param text: The SSML text to convert.
129
+ :returns: A list of strings and SpeechCommand objects.
130
+ """
122
131
# MathCAT's default rate is 180 wpm.
123
132
# Assume that 0% is 80 wpm and 100% is 450 wpm and scale accordingly.
124
133
# log.info(f"\nSpeech str: '{text}'")
@@ -212,6 +221,8 @@ def convertSSMLTextForNVDA(text: str) -> list[str | SpeechCommand]:
212
221
213
222
214
223
class MathCATInteraction (mathPres .MathInteractionNVDAObject ):
224
+ """An NVDA object used to interact with MathML."""
225
+
215
226
# Put MathML or other formats on the clipboard.
216
227
# MathML is put on the clipboard using the two formats below (defined by MathML spec)
217
228
# We use both formats because some apps may only use one or the other
@@ -225,16 +236,22 @@ class MathCATInteraction(mathPres.MathInteractionNVDAObject):
225
236
226
237
def __init__ (
227
238
self ,
228
- provider : mathPres .MathPresentationProvider = None ,
239
+ provider : mathPres .MathPresentationProvider | None = None ,
229
240
mathMl : str | None = None ,
230
241
):
242
+ """Initialize the MathCATInteraction object.
243
+
244
+ :param provider: Optional presentation provider.
245
+ :param mathMl: Optional initial MathML string.
246
+ """
231
247
super (MathCATInteraction , self ).__init__ (provider = provider , mathMl = mathMl )
232
248
if mathMl is None :
233
249
self .initMathML = "<math></math>"
234
250
else :
235
251
self .initMathML = mathMl
236
252
237
253
def reportFocus (self ) -> None :
254
+ """Calls MathCAT's ZoomIn command and speaks the resulting text."""
238
255
super (MathCATInteraction , self ).reportFocus ()
239
256
# try to get around espeak bug where voice slows down
240
257
if _synthesizerRate and getSynth ().name == "espeak" :
@@ -256,6 +273,7 @@ def getBrailleRegions(
256
273
self ,
257
274
review : bool = False ,
258
275
) -> Generator [braille .Region , None , None ]:
276
+ """Yields braille.Region objects for this MathCATInteraction object."""
259
277
# log.info("***MathCAT start getBrailleRegions")
260
278
yield braille .NVDAObjectRegion (self , appendText = " " )
261
279
region : braille .Region = braille .Region ()
@@ -276,7 +294,12 @@ def getScript(
276
294
self ,
277
295
gesture : KeyboardInputGesture ,
278
296
) -> Callable [KeyboardInputGesture , None ] | None :
279
- # Pass most keys to MathCAT. Pretty ugly.
297
+ """
298
+ Returns the script function bound to the given gesture.
299
+
300
+ :param gesture: A KeyboardInputGesture sent to this object.
301
+ :returns: The script bound to that gesture.
302
+ """
280
303
if (
281
304
isinstance (gesture , KeyboardInputGesture )
282
305
and "NVDA" not in gesture .modifierNames
@@ -309,6 +332,10 @@ def getScript(
309
332
return super ().getScript (gesture )
310
333
311
334
def script_navigate (self , gesture : KeyboardInputGesture ) -> None :
335
+ """Performs the specified navigation command.
336
+
337
+ :param gesture: They keyboard command which specified the navigation command to perform.
338
+ """
312
339
try :
313
340
# try to get around espeak bug where voice slows down
314
341
if _synthesizerRate and getSynth ().name == "espeak" :
@@ -365,6 +392,10 @@ def script_navigate(self, gesture: KeyboardInputGesture) -> None:
365
392
gesture = "kb:control+c" ,
366
393
)
367
394
def script_rawdataToClip (self , gesture : KeyboardInputGesture ) -> None :
395
+ """Copies the raw data to the clipboard, either as MathML, ASCII math, or LaTeX, depending on user preferences.
396
+
397
+ :param gesture: The gesture which activated this script.
398
+ """
368
399
try :
369
400
copyAs : str = "mathml" # value used even if "CopyAs" pref is invalid
370
401
textToCopy : str = ""
@@ -416,7 +447,7 @@ def script_rawdataToClip(self, gesture: KeyboardInputGesture) -> None:
416
447
_hasDataAttr : re .Pattern = re .compile (" data-[^=]+='[^']*'" )
417
448
418
449
def _wrapMathMLForClipBoard (self , text : str ) -> str :
419
- # cleanup the MathML a little
450
+ """Cleanup the MathML a little."""
420
451
text = re .sub (self ._hasAddedId , "" , text )
421
452
mathMLWithNS : str = re .sub (self ._hasDataAttr , "" , text )
422
453
if not re .match (self ._mathTagHasNameSpace , mathMLWithNS ):
@@ -434,9 +465,10 @@ def _copyToClipAsMathML(
434
465
notify : bool | None = False ,
435
466
) -> bool :
436
467
"""Copies the given text to the windows clipboard.
437
- @returns: True if it succeeds, False otherwise.
438
- @param text: the text which will be copied to the clipboard
439
- @param notify: whether to emit a confirmation message
468
+
469
+ :param text: the text which will be copied to the clipboard.
470
+ :param notify: whether to emit a confirmation message.
471
+ :returns: True if it succeeds, False otherwise.
440
472
"""
441
473
# copied from api.py and modified to use CF_MathML_Presentation
442
474
if not isinstance (text , str ) or len (text ) == 0 :
@@ -463,6 +495,12 @@ def _copyToClipAsMathML(
463
495
return False
464
496
465
497
def _setClipboardData (self , format : int , data : str ) -> None :
498
+ """Sets the clipboard data to the given data with the specified format.
499
+
500
+ :param format: The format for the clipboard data.
501
+ This is an integer format code returned by windll.user32.RegisterClipboardFormatW.
502
+ :param data: The data to set on the clipboard.
503
+ """
466
504
# Need to support MathML Presentation, so this copied from winUser.py and the first two lines are commented out
467
505
# For now only unicode is a supported format
468
506
# if format!=CF_UNICODETEXT:
@@ -485,6 +523,7 @@ def _setClipboardData(self, format: int, data: str) -> None:
485
523
486
524
class MathCAT (mathPres .MathPresentationProvider ):
487
525
def __init__ (self ):
526
+ """Initializes MathCAT, loading the rules specified in the rules directory."""
488
527
# super(MathCAT, self).__init__(*args, **kwargs)
489
528
490
529
try :
@@ -502,6 +541,11 @@ def getSpeechForMathMl(
502
541
self ,
503
542
mathml : str ,
504
543
) -> list [str | SpeechCommand ]:
544
+ """Outputs a MathML string as speech.
545
+
546
+ :param mathml: A MathML string.
547
+ :returns: A list of speech commands and strings representing the given MathML.
548
+ """
505
549
global _synthesizerRate
506
550
synth : SynthDriver = getSynth ()
507
551
synthConfig = config .conf ["speech" ][synth .name ]
@@ -557,13 +601,22 @@ def getSpeechForMathMl(
557
601
getSynth ()._set_rate (_synthesizerRate )
558
602
559
603
def _addSounds (self ) -> bool :
604
+ """Queries the user preferences to determine whether or not sounds should be added.
605
+
606
+ :returns: True if MathCAT's `SpeechSound` preference is set, and False otherwise.
607
+ """
560
608
try :
561
609
return libmathcat .GetPreference ("SpeechSound" ) != "None"
562
610
except Exception as e :
563
611
log .exception (f"MathCAT: An exception occurred in _add_sounds: { e } " )
564
612
return False
565
613
566
614
def getBrailleForMathMl (self , mathml : str ) -> str :
615
+ """Gets the braille representation of a given MathML string by calling MathCAT's GetBraille function.
616
+
617
+ :param mathml: A MathML string.
618
+ :returns: A braille string representing the input MathML.
619
+ """
567
620
# log.info("***MathCAT getBrailleForMathMl")
568
621
try :
569
622
libmathcat .SetMathML (mathml )
@@ -582,6 +635,10 @@ def getBrailleForMathMl(self, mathml: str) -> str:
582
635
return ""
583
636
584
637
def interactWithMathMl (self , mathml : str ) -> None :
638
+ """Interact with a MathML string, creating a MathCATInteraction object.
639
+
640
+ :param mathml: The MathML representing the math to interact with.
641
+ """
585
642
MathCATInteraction (provider = self , mathMl = mathml ).setFocus ()
586
643
MathCATInteraction (provider = self , mathMl = mathml ).script_navigate (None )
587
644
@@ -590,6 +647,7 @@ def interactWithMathMl(self, mathml: str) -> None:
590
647
591
648
592
649
def _monkeyPatchESpeak () -> None :
650
+ """Patches an eSpeak bug where the voice slows down."""
593
651
global CACHED_SYNTH
594
652
currentSynth : SynthDriver = getSynth ()
595
653
if currentSynth .name != "espeak" or CACHED_SYNTH == currentSynth :
0 commit comments