0
# Output Formats
1
2
MathJax supports two high-quality output formats: CommonHTML (HTML/CSS) and SVG (Scalable Vector Graphics). Both formats provide excellent rendering quality, accessibility support, and extensive customization options.
3
4
## Capabilities
5
6
### CommonHTML Output
7
8
Render mathematics using HTML elements with CSS styling, providing excellent performance and integration with web content.
9
10
```javascript { .api }
11
/**
12
* Get CommonHTML stylesheet
13
* @returns CSS stylesheet element for CommonHTML output
14
*/
15
function chtmlStylesheet(): Element;
16
17
/**
18
* Get metrics for CommonHTML element
19
* @param wrapper - Element wrapper to measure
20
* @param display - Whether element is in display mode
21
* @returns Metrics object with measurements
22
*/
23
function getMetricsFor(wrapper: Element, display: boolean): Metrics;
24
```
25
26
**Usage Examples:**
27
28
```javascript
29
// Convert to CommonHTML
30
const htmlElement = MathJax.tex2chtml('E = mc^2');
31
document.body.appendChild(htmlElement);
32
33
// Get stylesheet for styling
34
const stylesheet = MathJax.chtmlStylesheet();
35
document.head.appendChild(stylesheet);
36
37
// Get metrics for positioning
38
const metrics = MathJax.getMetricsFor(htmlElement, false);
39
console.log('Width:', metrics.em, 'em');
40
```
41
42
### SVG Output
43
44
Render mathematics as scalable vector graphics, providing perfect scaling and print quality.
45
46
```javascript { .api }
47
/**
48
* Get SVG stylesheet
49
* @returns CSS stylesheet element for SVG output
50
*/
51
function svgStylesheet(): Element;
52
53
/**
54
* Get metrics for SVG element
55
* @param wrapper - Element wrapper to measure
56
* @param display - Whether element is in display mode
57
* @returns Metrics object with measurements
58
*/
59
function getMetricsFor(wrapper: Element, display: boolean): Metrics;
60
```
61
62
**Usage Examples:**
63
64
```javascript
65
// Convert to SVG
66
const svgElement = MathJax.tex2svg('\\frac{x^2}{2}');
67
document.body.appendChild(svgElement);
68
69
// Get stylesheet for SVG styling
70
const stylesheet = MathJax.svgStylesheet();
71
document.head.appendChild(stylesheet);
72
73
// Get SVG metrics
74
const metrics = MathJax.getMetricsFor(svgElement, true);
75
console.log('SVG dimensions:', metrics);
76
```
77
78
## Configuration Options
79
80
### CommonHTML Configuration
81
82
```javascript { .api }
83
interface CommonHTMLOptions {
84
/** Scaling factor for output */
85
scale?: number;
86
/** Minimum scaling factor */
87
minScale?: number;
88
/** Match container font height */
89
matchFontHeight?: boolean;
90
/** Inherit font for mtext elements */
91
mtextInheritFont?: boolean;
92
/** Inherit font for merror elements */
93
merrorInheritFont?: boolean;
94
/** Use MathML spacing rules */
95
mathmlSpacing?: boolean;
96
/** Attributes to skip when processing */
97
skipAttributes?: Record<string, boolean>;
98
/** Ex-height factor */
99
exFactor?: number;
100
/** Display alignment */
101
displayAlign?: 'left' | 'center' | 'right';
102
/** Display indentation */
103
displayIndent?: string;
104
/** Font URL for web fonts */
105
fontURL?: string;
106
/** Use adaptive CSS */
107
adaptiveCSS?: boolean;
108
}
109
```
110
111
**Configuration Example:**
112
113
```javascript
114
MathJax.config.chtml = {
115
scale: 1.2,
116
minScale: 0.5,
117
matchFontHeight: true,
118
mtextInheritFont: true,
119
merrorInheritFont: true,
120
mathmlSpacing: true,
121
exFactor: 0.5,
122
displayAlign: 'center',
123
displayIndent: '2em',
124
fontURL: 'https://cdn.jsdelivr.net/npm/mathjax@4/fonts/woff-v2',
125
adaptiveCSS: true,
126
skipAttributes: {
127
'data-semantic-type': true,
128
'data-semantic-role': true
129
}
130
};
131
```
132
133
### SVG Configuration
134
135
```javascript { .api }
136
interface SVGOptions {
137
/** Scaling factor for output */
138
scale?: number;
139
/** Minimum scaling factor */
140
minScale?: number;
141
/** Inherit font for mtext elements */
142
mtextInheritFont?: boolean;
143
/** Inherit font for merror elements */
144
merrorInheritFont?: boolean;
145
/** Use MathML spacing rules */
146
mathmlSpacing?: boolean;
147
/** Attributes to skip when processing */
148
skipAttributes?: Record<string, boolean>;
149
/** Ex-height factor */
150
exFactor?: number;
151
/** Display alignment */
152
displayAlign?: 'left' | 'center' | 'right';
153
/** Display indentation */
154
displayIndent?: string;
155
/** Font caching mode */
156
fontCache?: 'local' | 'global' | 'none';
157
/** Local ID prefix */
158
localID?: string;
159
/** Include internal speech titles */
160
internalSpeechTitles?: boolean;
161
}
162
```
163
164
**Configuration Example:**
165
166
```javascript
167
MathJax.config.svg = {
168
scale: 1.0,
169
minScale: 0.5,
170
mtextInheritFont: false,
171
merrorInheritFont: false,
172
mathmlSpacing: true,
173
exFactor: 0.5,
174
displayAlign: 'center',
175
displayIndent: '0',
176
fontCache: 'local',
177
localID: 'MJX-SVG',
178
internalSpeechTitles: true,
179
skipAttributes: {
180
'data-mml-node': true
181
}
182
};
183
```
184
185
## Font Management
186
187
### CommonHTML Fonts
188
189
CommonHTML output uses web fonts for optimal rendering:
190
191
```javascript
192
// Font configuration
193
MathJax.config.chtml = {
194
fontURL: 'https://cdn.jsdelivr.net/npm/mathjax@4/fonts/woff-v2',
195
adaptiveCSS: true,
196
matchFontHeight: true
197
};
198
199
// Custom font paths
200
MathJax.config.chtml = {
201
fontURL: '/static/mathjax-fonts',
202
fontFormat: 'woff2' // woff, woff2, otf, ttf
203
};
204
205
// Disable web fonts (use system fonts)
206
MathJax.config.chtml = {
207
fontURL: null
208
};
209
```
210
211
### SVG Fonts
212
213
SVG output embeds font information directly:
214
215
```javascript
216
// Font caching options
217
MathJax.config.svg = {
218
fontCache: 'local', // Cache fonts per element
219
// fontCache: 'global', // Global font cache
220
// fontCache: 'none' // No font caching
221
};
222
223
// Font loading
224
MathJax.config.options = {
225
loadAllFontFiles: true // Preload all font files
226
};
227
```
228
229
## Output Customization
230
231
### Styling and Appearance
232
233
```javascript
234
// Custom CSS for CommonHTML
235
const style = document.createElement('style');
236
style.textContent = `
237
.mjx-chtml {
238
font-size: 120%;
239
color: #333;
240
}
241
242
.mjx-chtml .mjx-math {
243
border: 1px solid #ddd;
244
padding: 5px;
245
border-radius: 3px;
246
}
247
248
.mjx-display {
249
text-align: center;
250
margin: 1em 0;
251
}
252
`;
253
document.head.appendChild(style);
254
255
// Custom CSS for SVG
256
const svgStyle = document.createElement('style');
257
svgStyle.textContent = `
258
.mjx-svg {
259
background: #f9f9f9;
260
border-radius: 4px;
261
}
262
263
.mjx-svg svg {
264
filter: drop-shadow(1px 1px 2px rgba(0,0,0,0.1));
265
}
266
`;
267
document.head.appendChild(svgStyle);
268
```
269
270
### Display Options
271
272
```javascript
273
// Configure display alignment
274
MathJax.config.chtml = {
275
displayAlign: 'left',
276
displayIndent: '2em'
277
};
278
279
// Configure scaling
280
MathJax.config.svg = {
281
scale: 1.5,
282
minScale: 0.8
283
};
284
285
// Per-conversion options
286
const options = {
287
display: true,
288
scale: 1.2,
289
em: 16,
290
ex: 8,
291
containerWidth: 1200
292
};
293
294
const result = MathJax.tex2svg('x^2 + y^2 = z^2', options);
295
```
296
297
## Performance Optimization
298
299
### Output Format Selection
300
301
```javascript
302
// Choose format based on use case
303
function selectOptimalFormat(context) {
304
if (context.needsScaling) {
305
return 'svg'; // SVG scales perfectly
306
}
307
308
if (context.needsInteraction) {
309
return 'chtml'; // HTML integrates better with DOM
310
}
311
312
if (context.needsPrint) {
313
return 'svg'; // SVG prints at high quality
314
}
315
316
return 'chtml'; // Default to CommonHTML for web
317
}
318
319
// Dynamic format switching
320
async function renderWithOptimalFormat(math, context) {
321
const format = selectOptimalFormat(context);
322
323
if (format === 'svg') {
324
return MathJax.tex2svg(math);
325
} else {
326
return MathJax.tex2chtml(math);
327
}
328
}
329
```
330
331
### Caching and Reuse
332
333
```javascript
334
// Cache rendered mathematics
335
class MathCache {
336
constructor() {
337
this.cache = new Map();
338
}
339
340
render(expression, format, options = {}) {
341
const key = JSON.stringify({ expression, format, options });
342
343
if (this.cache.has(key)) {
344
return this.cache.get(key).cloneNode(true);
345
}
346
347
let result;
348
if (format === 'svg') {
349
result = MathJax.tex2svg(expression, options);
350
} else {
351
result = MathJax.tex2chtml(expression, options);
352
}
353
354
this.cache.set(key, result.cloneNode(true));
355
return result;
356
}
357
358
clear() {
359
this.cache.clear();
360
}
361
}
362
363
const mathCache = new MathCache();
364
const cached = mathCache.render('E = mc^2', 'svg');
365
```
366
367
## Advanced Features
368
369
### Custom Output Processing
370
371
```javascript
372
// Post-process CommonHTML output
373
function customizeCommonHTML(element) {
374
// Add custom attributes
375
element.setAttribute('data-math-type', 'equation');
376
377
// Add accessibility improvements
378
const mathElements = element.querySelectorAll('.mjx-math');
379
mathElements.forEach(math => {
380
math.setAttribute('role', 'img');
381
math.setAttribute('aria-label', 'Mathematical expression');
382
});
383
384
// Add custom styling
385
element.classList.add('custom-math');
386
387
return element;
388
}
389
390
// Apply custom processing
391
const rawHTML = MathJax.tex2chtml('x^2 + y^2 = z^2');
392
const customHTML = customizeCommonHTML(rawHTML);
393
```
394
395
### SVG Manipulation
396
397
```javascript
398
// Post-process SVG output
399
function customizeSVG(svgElement) {
400
const svg = svgElement.querySelector('svg');
401
402
// Add custom attributes
403
svg.setAttribute('data-math-rendered', 'true');
404
405
// Modify viewBox for custom sizing
406
const viewBox = svg.getAttribute('viewBox');
407
if (viewBox) {
408
const [x, y, width, height] = viewBox.split(' ').map(Number);
409
svg.setAttribute('viewBox', `${x-5} ${y-5} ${width+10} ${height+10}`);
410
}
411
412
// Add background rectangle
413
const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
414
rect.setAttribute('x', '0');
415
rect.setAttribute('y', '0');
416
rect.setAttribute('width', '100%');
417
rect.setAttribute('height', '100%');
418
rect.setAttribute('fill', '#f8f8f8');
419
rect.setAttribute('stroke', '#ddd');
420
svg.insertBefore(rect, svg.firstChild);
421
422
return svgElement;
423
}
424
425
// Apply SVG customization
426
const rawSVG = MathJax.tex2svg('\\int_0^\\infty e^{-x} dx');
427
const customSVG = customizeSVG(rawSVG);
428
```
429
430
### Responsive Mathematics
431
432
```javascript
433
// Make mathematics responsive
434
function makeResponsive(mathElement, maxWidth = 600) {
435
const svg = mathElement.querySelector('svg');
436
if (svg) {
437
// Make SVG responsive
438
svg.style.maxWidth = '100%';
439
svg.style.height = 'auto';
440
441
// Scale down for small screens
442
const actualWidth = parseFloat(svg.getAttribute('width'));
443
if (actualWidth > maxWidth) {
444
const scale = maxWidth / actualWidth;
445
svg.style.transform = `scale(${scale})`;
446
svg.style.transformOrigin = 'left center';
447
}
448
}
449
450
return mathElement;
451
}
452
453
// Apply responsive design
454
const math = MathJax.tex2svg('\\sum_{i=1}^{n} \\frac{1}{i^2} = \\frac{\\pi^2}{6}');
455
const responsive = makeResponsive(math);
456
```
457
458
## Integration Examples
459
460
### Print Styling
461
462
```javascript
463
// Print-optimized CSS
464
const printStyle = document.createElement('style');
465
printStyle.textContent = `
466
@media print {
467
.mjx-chtml {
468
font-size: 12pt;
469
color: black !important;
470
}
471
472
.mjx-svg svg {
473
max-width: 100% !important;
474
height: auto !important;
475
}
476
477
.mjx-display {
478
page-break-inside: avoid;
479
margin: 0.5em 0;
480
}
481
}
482
`;
483
document.head.appendChild(printStyle);
484
```
485
486
### Dark Mode Support
487
488
```javascript
489
// Dark mode mathematics
490
function applyDarkMode(isDark) {
491
const style = document.createElement('style');
492
style.id = 'mathjax-dark-mode';
493
494
if (isDark) {
495
style.textContent = `
496
.mjx-chtml {
497
color: #e0e0e0 !important;
498
}
499
500
.mjx-svg {
501
filter: invert(1) hue-rotate(180deg);
502
}
503
`;
504
} else {
505
style.textContent = '';
506
}
507
508
// Replace existing dark mode styles
509
const existing = document.getElementById('mathjax-dark-mode');
510
if (existing) {
511
existing.remove();
512
}
513
514
document.head.appendChild(style);
515
}
516
517
// Apply dark mode
518
applyDarkMode(true);
519
```
520
521
## Metrics and Measurements
522
523
### Output Metrics
524
525
```javascript { .api }
526
interface Metrics {
527
/** Em size in pixels */
528
em: number;
529
/** Ex height in pixels */
530
ex: number;
531
/** Container width */
532
containerWidth: number;
533
/** Scale factor */
534
scale: number;
535
/** Line width setting */
536
lineWidth?: number;
537
/** Actual scale factor used */
538
scaleFactor?: number;
539
/** Font scaling factor */
540
fontScale?: number;
541
}
542
```
543
544
**Usage Examples:**
545
546
```javascript
547
// Get element metrics
548
const element = MathJax.tex2chtml('x^2 + y^2 = z^2');
549
const metrics = MathJax.getMetricsFor(element, false);
550
551
console.log('Em size:', metrics.em);
552
console.log('Ex height:', metrics.ex);
553
console.log('Scale:', metrics.scale);
554
555
// Use metrics for positioning
556
element.style.marginTop = `${metrics.ex * 0.5}px`;
557
element.style.marginBottom = `${metrics.ex * 0.5}px`;
558
559
// Responsive scaling based on metrics
560
const scaleFactor = Math.min(1.0, 800 / metrics.containerWidth);
561
element.style.transform = `scale(${scaleFactor})`;
562
```
563
564
### Bounding Box Calculations
565
566
```javascript
567
// Get bounding box information
568
function getMathBoundingBox(mathElement) {
569
const svg = mathElement.querySelector('svg');
570
if (svg) {
571
const viewBox = svg.getAttribute('viewBox');
572
if (viewBox) {
573
const [x, y, width, height] = viewBox.split(' ').map(Number);
574
return { x, y, width, height };
575
}
576
}
577
578
// For CommonHTML, use DOM measurements
579
const rect = mathElement.getBoundingClientRect();
580
return {
581
x: 0,
582
y: 0,
583
width: rect.width,
584
height: rect.height
585
};
586
}
587
588
// Position mathematics using bounding box
589
const math = MathJax.tex2svg('\\frac{a}{b}');
590
const bbox = getMathBoundingBox(math);
591
math.style.position = 'absolute';
592
math.style.left = `${100 - bbox.width / 2}px`;
593
math.style.top = `${50 - bbox.height / 2}px`;
594
```