Mathematics

Built-in support for rendering mathematical expressions using LaTeX syntax powered by KaTeX.

Install the optional math extension to add Comark math parsing and KaTeX rendering:

pnpm add @stream-markdown/math
<script setup lang="ts">
import { math } from '@stream-markdown/math'
import { Markdown } from 'vue-stream-markdown'
import 'katex/dist/katex.min.css'

const extensions = {
  math: math({
    config: { throwOnError: false },
  }),
}
</script>

<template>
  <Markdown :content="content" :extensions="extensions" />
</template>

Without math(), the base parser does not register Comark's math plugin and no KaTeX dependency or type is required.

Syntax

vue-stream-markdown uses double dollar signs ($$) to delimit mathematical expressions by default. Single dollar signs ($) are disabled by default to avoid conflicts with currency symbols.

You can enable single dollar sign completion by setting singleDollarTextMath: true in completion:

<script setup lang="ts">
import { Markdown } from 'vue-stream-markdown'

const completion = {
  singleDollarTextMath: true,
}
</script>

<template>
  <Markdown :content="content" :completion="completion" />
</template>

When enabled, you can use both $math$ (inline) and $$math$$ (inline or block).

Inline Math

Wrap inline mathematical expressions with $$:

The quadratic formula is $$x = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a}$$ for solving equations.

Block Math

For display-style equations, place $$ delimiters on separate lines:

$$
E = mc^2
$$

This renders the equation centered and larger:

Common Mathematical Expressions

Fractions

$$\frac{numerator}{denominator}$$

Square Roots

$$\sqrt{x}$$ or $$\sqrt[n]{x}$$

Exponents and Subscripts

$$x^2$$ or $$x_i$$ or $$x_i^2$$

Greek Letters

$$\alpha, \beta, \gamma, \delta, \theta, \pi, \sigma, \omega$$
$$\Gamma, \Delta, \Theta, \Pi, \Sigma, \Omega$$

Summations

$$\sum_{i=1}^{n} i = \frac{n(n+1)}{2}$$

Integrals

$$\int_{a}^{b} f(x) \, dx$$

Limits

$$\lim_{x \to \infty} \frac{1}{x} = 0$$

Matrices

$$
\begin{bmatrix}
a & b \\
c & d
\end{bmatrix}
$$

Advanced Examples

The Quadratic Formula

$$
x = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a}
$$

Euler's Identity

$$
e^{i\pi} + 1 = 0
$$

Normal Distribution

$$
f(x) = \frac{1}{\sigma\sqrt{2\pi}} e^{-\frac{1}{2}\left(\frac{x-\mu}{\sigma}\right)^2}
$$

Taylor Series

$$
e^x = \sum_{n=0}^{\infty} \frac{x^n}{n!} = 1 + x + \frac{x^2}{2!} + \frac{x^3}{3!} + \cdots
$$

Integration by Parts

$$
\int u \, dv = uv - \int v \, du
$$

Special Operators and Symbols

Comparison Operators

$$\leq$$ $$\geq$$ $$\neq$$ $$\approx$$ $$\equiv$$

Set Notation

$$\in$$ $$\notin$$ $$\subset$$ $$\subseteq$$ $$\cup$$ $$\cap$$ $$\emptyset$$

Logic Symbols

$$\land$$ $$\lor$$ $$\neg$$ $$\implies$$ $$\iff$$ $$\forall$$ $$\exists$$

Calculus Notation

$$\frac{dy}{dx}$$ $$\frac{\partial f}{\partial x}$$ $$\nabla$$ $$\infty$$

Streaming Considerations

Incomplete Equations

vue-stream-markdown's unterminated block parser handles incomplete equations gracefully:

$$
E = mc^2

During streaming, the parser detects the incomplete block-level equation and adds the closing $$ delimiter, ensuring proper rendering even before the equation is complete.

Inline vs Block Detection

The parser distinguishes between inline and block math:

  • Inline: $$E = mc^2$$ (same line)
  • Block: Separate lines with newlines
This is inline $$E = mc^2$$ math.

$$
E = mc^2
$$

This is block math.

Accessibility

Mathematical expressions rendered by KaTeX include:

  • MathML - Machine-readable math representation
  • Title Attributes - LaTeX source in tooltips
  • Semantic HTML - Proper structure for screen readers
  • Scalable Typography - Math scales with text size settings

Performance

KaTeX is chosen for its performance characteristics:

  • Fast Rendering - 2-3x faster than MathJax
  • No JavaScript Runtime - Pure CSS styling (after initial render)
  • Small Bundle - Minimal impact on page load

Common Issues

Escaping Backslashes

In JavaScript/TypeScript strings, backslashes need to be escaped:

// ❌ Wrong
const markdown = '$\frac{1}{2}$'

// ✅ Correct
const markdown = '$$\\frac{1}{2}$$'

// ✅ Or use template literals
const markdown = `$$\frac{1}{2}$$`

Currency vs Math

By default, vue-stream-markdown uses $$ for math to avoid conflicts with currency:

This item costs $5 and that one costs $10. (These are currency symbols)

This equation $$x = 5$$ is mathematical notation. (This is math)

Spacing in Equations

Use \, for thin space, \: for medium space, \; for thick space:

$$\int f(x) \, dx$$

Resources