0
# Accessibility Features
1
2
MathJax provides comprehensive accessibility support including speech generation, semantic enrichment, interactive exploration, and assistive technology integration to make mathematical content accessible to users with disabilities.
3
4
## Capabilities
5
6
### Speech Generation
7
8
Generate spoken descriptions of mathematical expressions for screen readers and voice output.
9
10
```javascript { .api }
11
interface AccessibilityOptions {
12
/** Background color for highlighting */
13
backgroundColor?: string;
14
/** Background opacity (0-1) */
15
backgroundOpacity?: number;
16
/** Foreground color for highlighting */
17
foregroundColor?: string;
18
/** Foreground opacity (0-1) */
19
foregroundOpacity?: number;
20
/** Highlight color scheme */
21
highlight?: 'None' | 'Hover' | 'Flame' | 'Blue' | 'Green' | 'Magenta' | 'Red';
22
/** Enable subtitles display */
23
subtitles?: boolean;
24
/** Enable speech output */
25
speech?: boolean;
26
}
27
```
28
29
**Usage Examples:**
30
31
```javascript
32
// Enable accessibility features
33
MathJax.config.options = {
34
enableAssistiveMml: true,
35
enableExplorer: true,
36
a11y: {
37
backgroundColor: 'Blue',
38
backgroundOpacity: 0.2,
39
foregroundColor: 'Yellow',
40
foregroundOpacity: 1,
41
highlight: 'Flame',
42
subtitles: true,
43
speech: true
44
}
45
};
46
47
// Load accessibility components
48
MathJax.config.loader.load.push(
49
'a11y/semantic-enrich',
50
'a11y/speech',
51
'a11y/explorer',
52
'a11y/assistive-mml'
53
);
54
```
55
56
### Semantic Enrichment
57
58
Enhance mathematical expressions with semantic information for better accessibility.
59
60
```javascript { .api }
61
// Semantic enrichment is automatically applied when accessibility is enabled
62
// No direct API calls needed - works transparently with input processors
63
```
64
65
**Configuration Examples:**
66
67
```javascript
68
// Configure semantic enrichment
69
MathJax.config.options = {
70
enableAssistiveMml: true, // Enable assistive MathML generation
71
sre: {
72
domain: 'mathspeak', // Speech domain
73
style: 'default', // Speech style
74
locale: 'en', // Language locale
75
modality: 'speech' // Output modality
76
}
77
};
78
79
// Advanced semantic options
80
MathJax.config.sre = {
81
json: '/path/to/mathmaps', // Path to semantic rules
82
xpath: '/path/to/xpath', // XPath evaluator
83
domain: 'clearspeak', // Alternative speech domain
84
style: 'brief' // Brief speech style
85
};
86
```
87
88
### Interactive Explorer
89
90
Provide interactive navigation and exploration of mathematical expressions.
91
92
```javascript { .api }
93
// Explorer is activated automatically when enabled
94
// Users can navigate using keyboard shortcuts:
95
// - Arrow keys: Navigate expression tree
96
// - Enter: Speak current sub-expression
97
// - Escape: Exit exploration mode
98
```
99
100
**Configuration Examples:**
101
102
```javascript
103
// Enable interactive explorer
104
MathJax.config.options = {
105
enableExplorer: true,
106
a11y: {
107
keyMagnifier: true, // Magnify focused elements
108
speechTags: true, // Include speech tags
109
braille: false // Braille output (experimental)
110
}
111
};
112
113
// Explorer keyboard shortcuts
114
const explorerKeys = {
115
'ArrowRight': 'next sibling',
116
'ArrowLeft': 'previous sibling',
117
'ArrowDown': 'first child',
118
'ArrowUp': 'parent',
119
'Enter': 'speak current',
120
'Escape': 'exit explorer'
121
};
122
```
123
124
### Assistive MathML
125
126
Generate enhanced MathML with accessibility attributes for assistive technologies.
127
128
```javascript { .api }
129
// Assistive MathML is generated automatically when enabled
130
// Adds aria-label, role, and other accessibility attributes
131
```
132
133
**Examples:**
134
135
```javascript
136
// Enable assistive MathML
137
MathJax.config.options = {
138
enableAssistiveMml: true
139
};
140
141
// Result includes accessibility attributes:
142
// <math aria-label="x squared plus y squared equals z squared" role="img">
143
// <mrow>
144
// <msup aria-label="x squared">
145
// <mi>x</mi>
146
// <mn>2</mn>
147
// </msup>
148
// <mo>+</mo>
149
// <msup aria-label="y squared">
150
// <mi>y</mi>
151
// <mn>2</mn>
152
// </msup>
153
// <mo>=</mo>
154
// <msup aria-label="z squared">
155
// <mi>z</mi>
156
// <mn>2</mn>
157
// </msup>
158
// </mrow>
159
// </math>
160
```
161
162
## Accessibility Components
163
164
### Speech Recognition Engine (SRE)
165
166
The Speech Rule Engine provides the core functionality for semantic analysis and speech generation.
167
168
```javascript
169
// SRE is loaded automatically with accessibility features
170
MathJax.config.loader.load.push('a11y/sre');
171
172
// SRE provides multiple speech domains:
173
// - mathspeak: MathSpeak standard
174
// - clearspeak: ClearSpeak standard
175
// - chromevox: ChromeVox style
176
// - emacspeak: Emacspeak style
177
```
178
179
### Complexity Analysis
180
181
Analyze mathematical complexity to optimize speech output.
182
183
```javascript
184
// Load complexity analyzer
185
MathJax.config.loader.load.push('a11y/complexity');
186
187
// Complexity affects speech verbosity
188
MathJax.config.sre = {
189
domain: 'clearspeak',
190
style: 'auto' // Automatically adjust based on complexity
191
};
192
```
193
194
### Visual Highlighting
195
196
Provide visual feedback during navigation and exploration.
197
198
```javascript
199
// Configure visual highlighting
200
MathJax.config.options = {
201
a11y: {
202
backgroundColor: 'Blue',
203
backgroundOpacity: 0.3,
204
foregroundColor: 'White',
205
foregroundOpacity: 1,
206
highlight: 'Hover' // Highlight on mouse hover
207
}
208
};
209
210
// Available highlight modes:
211
// - 'None': No highlighting
212
// - 'Hover': Highlight on hover
213
// - 'Flame': Red highlighting
214
// - 'Blue': Blue highlighting
215
// - 'Green': Green highlighting
216
// - 'Magenta': Magenta highlighting
217
// - 'Red': Red highlighting
218
```
219
220
## Configuration Options
221
222
### Global Accessibility Configuration
223
224
```javascript { .api }
225
interface GlobalAccessibilityOptions {
226
/** Enable assistive MathML generation */
227
enableAssistiveMml?: boolean;
228
/** Enable interactive explorer */
229
enableExplorer?: boolean;
230
/** Accessibility-specific options */
231
a11y?: AccessibilityDisplayOptions;
232
/** Speech Rule Engine options */
233
sre?: SREOptions;
234
}
235
```
236
237
### Display Options
238
239
```javascript { .api }
240
interface AccessibilityDisplayOptions {
241
/** Background highlight color */
242
backgroundColor?: string;
243
/** Background opacity (0-1) */
244
backgroundOpacity?: number;
245
/** Foreground highlight color */
246
foregroundColor?: string;
247
/** Foreground opacity (0-1) */
248
foregroundOpacity?: number;
249
/** Highlight color scheme */
250
highlight?: 'None' | 'Hover' | 'Flame' | 'Blue' | 'Green' | 'Magenta' | 'Red';
251
/** Show subtitles */
252
subtitles?: boolean;
253
/** Enable speech output */
254
speech?: boolean;
255
/** Magnify focused elements */
256
keyMagnifier?: boolean;
257
/** Include speech tags in output */
258
speechTags?: boolean;
259
/** Enable braille output (experimental) */
260
braille?: boolean;
261
}
262
```
263
264
### Speech Rule Engine Options
265
266
```javascript { .api }
267
interface SREOptions {
268
/** Speech domain */
269
domain?: 'mathspeak' | 'clearspeak' | 'chromevox' | 'emacspeak';
270
/** Speech style */
271
style?: 'default' | 'brief' | 'sbrief' | 'auto';
272
/** Language locale */
273
locale?: string;
274
/** Output modality */
275
modality?: 'speech' | 'braille' | 'prefix' | 'summary';
276
/** Path to semantic rules */
277
json?: string;
278
/** XPath evaluator path */
279
xpath?: string;
280
}
281
```
282
283
## Complete Configuration Example
284
285
```javascript
286
// Comprehensive accessibility setup
287
window.MathJax = {
288
// Load accessibility components
289
loader: {
290
load: [
291
'input/tex', 'output/chtml',
292
'a11y/semantic-enrich',
293
'a11y/speech',
294
'a11y/explorer',
295
'a11y/complexity',
296
'a11y/assistive-mml'
297
]
298
},
299
300
// Enable accessibility features
301
options: {
302
enableAssistiveMml: true,
303
enableExplorer: true,
304
305
// Visual highlighting
306
a11y: {
307
backgroundColor: 'Blue',
308
backgroundOpacity: 0.2,
309
foregroundColor: 'Yellow',
310
foregroundOpacity: 1,
311
highlight: 'Hover',
312
subtitles: true,
313
speech: true,
314
keyMagnifier: true,
315
speechTags: true
316
},
317
318
// Speech configuration
319
sre: {
320
domain: 'clearspeak',
321
style: 'default',
322
locale: 'en',
323
modality: 'speech'
324
}
325
},
326
327
// TeX input with accessibility-friendly packages
328
tex: {
329
packages: ['base', 'ams', 'color'],
330
macros: {
331
// Define accessible macros
332
accessible: ['\\text{#1}', 1]
333
}
334
},
335
336
// CommonHTML output with accessibility
337
chtml: {
338
fontURL: 'https://cdn.jsdelivr.net/npm/mathjax@4/fonts/woff-v2',
339
adaptiveCSS: true
340
}
341
};
342
```
343
344
## Speech Domains and Styles
345
346
### MathSpeak Domain
347
348
Standard mathematical speech rules from Design Science.
349
350
```javascript
351
MathJax.config.sre = {
352
domain: 'mathspeak',
353
style: 'default' // or 'brief', 'sbrief'
354
};
355
356
// Examples:
357
// "x^2" → "x squared"
358
// "\\frac{a}{b}" → "fraction a over b"
359
// "\\sum_{i=1}^n" → "sum from i equals 1 to n"
360
```
361
362
### ClearSpeak Domain
363
364
Mathematical speech rules optimized for clarity.
365
366
```javascript
367
MathJax.config.sre = {
368
domain: 'clearspeak',
369
style: 'default' // or 'brief'
370
};
371
372
// Examples:
373
// "x^2" → "x squared"
374
// "\\frac{a}{b}" → "the fraction with numerator a and denominator b"
375
// "\\sqrt{x}" → "the square root of x"
376
```
377
378
### ChromeVox Domain
379
380
Speech rules optimized for the ChromeVox screen reader.
381
382
```javascript
383
MathJax.config.sre = {
384
domain: 'chromevox',
385
style: 'default'
386
};
387
```
388
389
## Interactive Navigation
390
391
### Keyboard Shortcuts
392
393
Users can navigate mathematical expressions using keyboard shortcuts:
394
395
| Key | Action |
396
|-----|--------|
397
| `→` | Move to next sibling |
398
| `←` | Move to previous sibling |
399
| `↓` | Move to first child |
400
| `↑` | Move to parent |
401
| `Enter` | Speak current element |
402
| `Escape` | Exit exploration mode |
403
| `Space` | Toggle subtitles |
404
405
### Navigation Example
406
407
```javascript
408
// Enable explorer and handle events
409
MathJax.config.options = {
410
enableExplorer: true,
411
a11y: {
412
subtitles: true,
413
speech: true
414
}
415
};
416
417
// Listen for navigation events (if needed for custom handling)
418
document.addEventListener('click', (event) => {
419
const mathElement = event.target.closest('.mjx-chtml, .mjx-svg');
420
if (mathElement) {
421
// Math element clicked - explorer will activate automatically
422
console.log('Math explorer activated');
423
}
424
});
425
```
426
427
## Screen Reader Integration
428
429
### NVDA Integration
430
431
```javascript
432
// Optimize for NVDA screen reader
433
MathJax.config.options = {
434
enableAssistiveMml: true,
435
sre: {
436
domain: 'mathspeak',
437
style: 'default',
438
locale: 'en'
439
}
440
};
441
```
442
443
### JAWS Integration
444
445
```javascript
446
// Optimize for JAWS screen reader
447
MathJax.config.options = {
448
enableAssistiveMml: true,
449
sre: {
450
domain: 'clearspeak',
451
style: 'brief',
452
locale: 'en'
453
}
454
};
455
```
456
457
### VoiceOver Integration
458
459
```javascript
460
// Optimize for VoiceOver (macOS/iOS)
461
MathJax.config.options = {
462
enableAssistiveMml: true,
463
sre: {
464
domain: 'mathspeak',
465
style: 'sbrief', // Super brief for VoiceOver
466
locale: 'en'
467
}
468
};
469
```
470
471
## Advanced Accessibility Features
472
473
### Custom Speech Rules
474
475
```javascript
476
// Add custom speech rules (requires SRE knowledge)
477
MathJax.config.sre = {
478
domain: 'clearspeak',
479
style: 'default',
480
// Custom rules can be added through SRE configuration
481
customRules: {
482
'custom-notation': 'custom speech pattern'
483
}
484
};
485
```
486
487
### Multilingual Support
488
489
```javascript
490
// Configure for different languages
491
MathJax.config.sre = {
492
domain: 'mathspeak',
493
style: 'default',
494
locale: 'es', // Spanish
495
// Available locales: en, es, fr, de, it, etc.
496
};
497
498
// Language-specific speech patterns
499
const languageConfigs = {
500
en: { domain: 'clearspeak', style: 'default' },
501
es: { domain: 'mathspeak', style: 'default' },
502
fr: { domain: 'mathspeak', style: 'brief' },
503
de: { domain: 'mathspeak', style: 'default' }
504
};
505
506
// Apply language configuration
507
const userLang = navigator.language.substring(0, 2);
508
MathJax.config.sre = languageConfigs[userLang] || languageConfigs.en;
509
```
510
511
### Braille Output
512
513
```javascript
514
// Enable experimental braille support
515
MathJax.config.options = {
516
a11y: {
517
braille: true
518
},
519
sre: {
520
modality: 'braille',
521
domain: 'mathspeak'
522
}
523
};
524
```
525
526
## Testing Accessibility
527
528
### Accessibility Validation
529
530
```javascript
531
// Test accessibility features
532
function testAccessibility() {
533
// Check if assistive MathML is generated
534
const mathElements = document.querySelectorAll('[role="img"]');
535
console.log(`Found ${mathElements.length} accessible math elements`);
536
537
// Check aria-labels
538
mathElements.forEach((element, index) => {
539
const label = element.getAttribute('aria-label');
540
console.log(`Element ${index}: ${label || 'No aria-label'}`);
541
});
542
543
// Test speech generation
544
if (window.SRE) {
545
const testExpr = 'x^2 + y^2 = z^2';
546
const speech = window.SRE.toSpeech(testExpr);
547
console.log(`Speech output: ${speech}`);
548
}
549
}
550
551
// Run accessibility tests
552
MathJax.whenReady(testAccessibility);
553
```
554
555
### Screen Reader Testing
556
557
```javascript
558
// Simulate screen reader interaction
559
function simulateScreenReader() {
560
const mathElements = document.querySelectorAll('.mjx-chtml, .mjx-svg');
561
562
mathElements.forEach(element => {
563
// Check for proper ARIA attributes
564
const role = element.getAttribute('role');
565
const label = element.getAttribute('aria-label');
566
const describedBy = element.getAttribute('aria-describedby');
567
568
console.log('Accessibility attributes:', {
569
role,
570
label,
571
describedBy
572
});
573
574
// Test focus management
575
element.tabIndex = 0;
576
element.addEventListener('focus', () => {
577
console.log('Math element focused:', label);
578
});
579
});
580
}
581
582
// Apply screen reader simulation
583
MathJax.typesetPromise().then(simulateScreenReader);
584
```
585
586
## Performance Considerations
587
588
### Selective Accessibility
589
590
```javascript
591
// Enable accessibility only when needed
592
const hasScreenReader = window.navigator.userAgent.includes('NVDA') ||
593
window.navigator.userAgent.includes('JAWS') ||
594
window.speechSynthesis;
595
596
if (hasScreenReader) {
597
MathJax.config.options.enableAssistiveMml = true;
598
MathJax.config.options.enableExplorer = true;
599
MathJax.config.loader.load.push('a11y/semantic-enrich', 'a11y/speech');
600
}
601
```
602
603
### Lazy Loading Accessibility
604
605
```javascript
606
// Load accessibility features on demand
607
function enableAccessibility() {
608
return MathJax.loader.load('a11y/semantic-enrich', 'a11y/speech', 'a11y/explorer')
609
.then(() => {
610
MathJax.config.options.enableAssistiveMml = true;
611
MathJax.config.options.enableExplorer = true;
612
613
// Re-process existing math
614
return MathJax.typesetPromise();
615
});
616
}
617
618
// Enable on user request or detection
619
document.getElementById('enable-accessibility').addEventListener('click', enableAccessibility);
620
```