@mdc-syntax/math
v1.0.0
Published
Math formula support for MDC Syntax using KaTeX
Readme
@mdc-syntax/math
Math formula support for mdc-syntax using KaTeX.
Features
- ✅ Inline math with
$...$syntax (tokenized at parse time) - ✅ Display math with
$$...$$syntax (tokenized at parse time) - ✅ Math code blocks with
```mathlanguage - ✅ HTML output via KaTeX
- ✅ Full LaTeX math syntax support
- ✅ Vue and React components
- ✅ TypeScript support
- ✅ Automatic tokenization during parsing for optimal performance
Installation
npm install @mdc-syntax/math mdc-syntax katex
# or
pnpm add @mdc-syntax/math mdc-syntax katex
# or
yarn add @mdc-syntax/math mdc-syntax katexNote: KaTeX is a peer dependency. Make sure to install it and include its CSS.
Usage
Vue
<script setup>
import { MDC } from 'mdc-syntax/vue'
import mathPlugin from '@mdc-syntax/math'
import { Math } from '@mdc-syntax/math/vue'
const markdown = `
# Math Examples
Inline math: $E = mc^2$
Display math:
$$
\\int_0^\\infty e^{-x^2} dx = \\frac{\\sqrt{\\pi}}{2}
$$
`
const components = {
math: Math
}
</script>
<template>
<Suspense>
<MDC :markdown="markdown" :components="components" :options="{ plugins: [mathPlugin] }" />
</Suspense>
</template>Important:
- The
mathPluginmust be passed to parse and tokenize$...$and$$...$$expressions - Include KaTeX CSS:
import 'katex/dist/katex.min.css'in your app - MDC component requires
<Suspense>wrapper (it's async)
React
import { MDC } from 'mdc-syntax/react'
import mathPlugin from '@mdc-syntax/math'
import { Math } from '@mdc-syntax/math/react'
const components = {
math: Math
}
function App() {
const markdown = `
# Math Examples
Inline math: $E = mc^2$
Display math:
$$
\\int_0^\\infty e^{-x^2} dx = \\frac{\\sqrt{\\pi}}{2}
$$
`
return <MDC markdown={markdown} components={components} options={{ plugins: [mathPlugin] }} />
}Important:
- The
mathPluginmust be passed to parse and tokenize$...$and$$...$$expressions - Include KaTeX CSS import
Core Parsing API
import { parse } from 'mdc-syntax'
import mathPlugin from '@mdc-syntax/math'
const result = parse('Inline $x^2$ and display $$E = mc^2$$', {
plugins: [mathPlugin]
})
// The AST will contain math nodes with LaTeX content
console.log(result.body)How It Works
The plugin uses a two-stage approach:
Parse Time (markdown-it plugin):
- Custom inline rules detect
$...$and$$...$$syntax - LaTeX expressions are tokenized and stored in the AST
- No rendering happens at this stage
- Custom inline rules detect
Render Time (Vue/React components):
- The
Mathcomponent receives LaTeX content via props - KaTeX renders the LaTeX to HTML on demand
- Component determines display mode based on CSS class
- The
This architecture provides optimal performance by separating parsing from rendering.
Syntax Support
The package supports full LaTeX math syntax via KaTeX:
Inline vs Display Math
Inline math: $E = mc^2$ appears in the text flow
Display math (on its own line):
$$
\int_0^\infty e^{-x^2} dx = \frac{\sqrt{\pi}}{2}
$$
Inline display (same line): Text $$E = mc^2$$ more textBasic Operations
$x + y - z$
$a \times b \div c$
$x^2 + y^2 = z^2$
$x_1, x_2, \ldots, x_n$Fractions and Roots
$\frac{a}{b}$
$\sqrt{x}$
$\sqrt[3]{x}$Greek Letters
$\alpha, \beta, \gamma, \Delta, \Sigma$Integrals and Sums
$$
\int_0^\infty e^{-x^2} dx = \frac{\sqrt{\pi}}{2}
$$
$$
\sum_{i=1}^{n} i = \frac{n(n+1)}{2}
$$Matrices
$$
\begin{pmatrix}
a & b \\
c & d
\end{pmatrix}
$$Limits
$$
\lim_{x \to \infty} f(x)
$$Code Blocks
You can also use code blocks for larger expressions:
```math
x = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a}
```Edge Cases
Dollar Signs in Text
The plugin intelligently avoids matching dollar signs that aren't math:
Prices like $100 or $200 won't be parsed as mathThe parser requires:
- At least one character between
$delimiters - Content that doesn't start with a digit
- Proper closing delimiter
Math in Headings, Lists, Blockquotes
Math works everywhere:
# Formula $E = mc^2$
- Item with $x^2$
- Another with $y^2$
> Quote with $\alpha + \beta$Code Blocks and Inline Code
Math is not parsed inside code:
Inline code: `$x^2$` stays as-is
Code block $x^2$ also stays as-is
Configuration
Math Component Props
Both Vue and React Math components accept:
content(string, required): The LaTeX expressionclass(string, optional): CSS classes (determines inline vs display mode)
The component automatically renders in display mode when the class contains "block", otherwise inline mode.
Troubleshooting
Math not rendering
- Plugin not included: Make sure to pass
plugins: [mathPlugin]to the parse/MDC component - KaTeX CSS not loaded: Import
'katex/dist/katex.min.css'in your app - Component not registered: Register the
Mathcomponent in the components map
Math appearing as plain text
If you see $x^2$ in the output:
- The plugin might not be loaded
- Check that the plugin is in the
pluginsarray
Invalid LaTeX errors
KaTeX will show an error message for invalid LaTeX. Check your syntax:
- Escape backslashes in JavaScript strings:
\\fracnot\frac - Use double backslashes in template strings
Performance
The plugin is designed for performance:
- Parse-time tokenization: Math is identified during markdown parsing
- Lazy rendering: KaTeX only renders when components mount
- No regex scanning at render time: All pattern matching happens once during parse
- Minimal overhead: LaTeX stored as plain text in AST until render
Development
# Install dependencies
pnpm install
# Build
pnpm build
# Test
pnpm test
# Run tests in watch mode
pnpm test -- --watchLicense
MIT
