or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

accessibility.mddocument-rendering.mdextensions.mdindex.mdinitialization.mdinput-processing.mdoutput-formats.md

output-formats.mddocs/

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

```