Math Rendering in XenT

This post serves as both a demonstration and design documentation for mathematical rendering capabilities in the XenT theme, covering engine selection, configuration patterns, and future roadmap.

Math Engine Strategy

XenT supports multiple math rendering engines with a pragmatic approach:

  • Primary Support: KaTeX and MathJax for LaTeX syntax
  • Global Selection: One engine per site (not per-post) for simplicity
  • Future Ready: Designed to accommodate Typst when ecosystem matures

Configuration Pattern

// Complete defaults pattern - in config.content.math:
math: {
  enable: true,           // Enable math rendering globally
  engine: 'katex',        // 'katex' | 'mathjax'
  katex: {                // KaTeX-specific options
    strict: 'warn',
    trust: false,
    throwOnError: false,
    delimiters: undefined,
    macros: {
      '\\RR': '\\mathbb{R}',
      '\\NN': '\\mathbb{N}',
    }
  },
  mathjax: {              // MathJax-specific options
    tex: {
      tags: 'none',
      inlineMath: [['$', '$']],
      displayMath: [['$$', '$$']],
      processRefs: true,
      macros: {
        'RR': '{\\mathbb{R}}',
        'NN': '{\\mathbb{N}}',
      }
    }
  }
}

Engine Comparison

EngineProsConsBest For
KaTeXFast, lightweight, good LaTeX supportLimited advanced featuresMost blogs, fast rendering
MathJaxComplete LaTeX compatibility, extensibleLarger bundle, slowerAcademic content, complex math
TypstModern syntax, integrated designImmature ecosystem, SSR requiredFuture consideration

Engine-Specific Syntax Differences

Local Macro Definitions:

  • KaTeX: Use \gdef\macroname#1{definition} (native command)
  • MathJax: Use \newcommand{\macroname}[1]{definition} (standard LaTeX)

Global Macro Configuration:

// KaTeX format (include backslashes) - in config.content.math:
math: {
  katex: {
    macros: {
      "\\RR": "\\mathbb{R}",
      "\\norm": "\\left\\|#1\\right\\|"
    }
  }
}

// MathJax format (no backslashes, functions use arrays) - in config.content.math:
math: {
  mathjax: {
    tex: {
      macros: {
        "RR": "{\\mathbb{R}}",
        "norm": ["{\\left\\|#1\\right\\|}", 1]
      }
    }
  }
}
\gdef\vec#1{\mathbf{#1}}
\gdef\dd{\,\mathrm{d}}
\gdef\dv#1#2{\frac{\mathrm{d}#1}{\mathrm{d}#2}}
\gdef\pdv#1#2{\frac{\partial#1}{\partial#2}}

LaTeX Macro System

Custom macros enhance mathematical notation readability. Can be defined globally in config or locally with \newcommand/\gdef.

Global macros (configured in user.ts):

  • Number sets: \RR, \NN, \ZZ, \QQ, \CC for \RR, \NN, \ZZ, \QQ, \CC
  • Functions: \norm{x} for \norm{x}, \abs{x} for \abs{x}

Local macros (defined in this post):

  • Vector notation: \vec{v} for \vec{v}, \norm{v} for \norm{v}
  • Absolute value: \abs{x} for \abs{x}
  • Calculus: \dd for \dd, \dv{f}{x} for \dv{f}{x}, \pdv{f}{x} for \pdv{f}{x}

Examples using macros:

The derivative of a function f: \R \to \R:

\dv{f}{x} = \lim_{h \to 0} \frac{f(x + h) - f(x)}{h}

Vector norm properties for \vec{u}, \vec{v} \in \R^n:

\norm{\vec{u} + \vec{v}} \leq \norm{\vec{u}} + \norm{\vec{v}}

Partial derivative of a multivariable function:

\pdv{f}{x_i} = \lim_{h \to 0} \frac{f(x_1, \ldots, x_i + h, \ldots, x_n) - f(x_1, \ldots, x_n)}{h}

Inline Mathematics

Mathematical expressions can be written inline with dollar signs: E = mc^2, or the quadratic formula: x = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a}.

The Pythagorean theorem states that a^2 + b^2 = c^2 for right triangles.

Display Mathematics

Basic Equations

The fundamental theorem of calculus can be expressed as:

\int_a^b f'(x) \, dx = f(b) - f(a)

Euler’s identity, often called the most beautiful equation in mathematics:

e^{i\pi} + 1 = 0

Matrices and Linear Algebra

A 2×2 matrix multiplication:

\begin{pmatrix} a & b \\ c & d \end{pmatrix} \begin{pmatrix} x \\ y \end{pmatrix} = \begin{pmatrix} ax + by \\ cx + dy \end{pmatrix}

The determinant of a 3×3 matrix:

\det(A) = \begin{vmatrix} a & b & c \\ d & e & f \\ g & h & i \end{vmatrix} = a(ei - fh) - b(di - fg) + c(dh - eg)

Calculus and Analysis

The definition of a derivative:

f'(x) = \lim_{h \to 0} \frac{f(x + h) - f(x)}{h}

Integration by parts:

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

Statistics and Probability

The normal distribution probability density function:

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

Bayes’ theorem:

P(A|B) = \frac{P(B|A) \cdot P(A)}{P(B)}

Complex Mathematical Expressions

The Fourier transform:

\mathcal{F}[f(t)](\omega) = \int_{-\infty}^{\infty} f(t) e^{-i\omega t} \, dt

Maxwell’s equations in differential form:

\begin{align}
\nabla \cdot \mathbf{E} &= \frac{\rho}{\varepsilon_0} \\
\nabla \cdot \mathbf{B} &= 0 \\
\nabla \times \mathbf{E} &= -\frac{\partial \mathbf{B}}{\partial t} \\
\nabla \times \mathbf{B} &= \mu_0 \mathbf{J} + \mu_0 \varepsilon_0 \frac{\partial \mathbf{E}}{\partial t}
\end{align}

Greek Letters and Special Symbols

Greek letters: \alpha, \beta, \gamma, \Delta, \Theta, \Lambda, \Pi, \Sigma, \Phi, \Psi, \Omega

Mathematical operators: \sum, \prod, \int, \oint, \nabla, \partial, \infty

Relations and logic: \leq, \geq, \neq, \approx, \equiv, \implies, \iff, \forall, \exists

Set Theory

Set operations:

A \cup B = \{x : x \in A \text{ or } x \in B\}
A \cap B = \{x : x \in A \text{ and } x \in B\}
A \setminus B = \{x : x \in A \text{ and } x \notin B\}

Number Theory

Fermat’s Last Theorem (for n > 2):

x^n + y^n \neq z^n

The prime counting function approximation:

\pi(x) \sim \frac{x}{\ln(x)}

Static Site Generation (SSG) Benefits

XenT renders all math expressions at build time, providing significant advantages over client-side rendering:

Performance Benefits

  • Zero client-side JavaScript: Math is pre-rendered HTML/CSS, no browser processing needed
  • Instant loading: No flash of unstyled content or render delays
  • Better Core Web Vitals: Improved LCP, FCP, and CLS scores
  • CDN optimization: Static HTML caches globally

SEO and Accessibility

  • Search engine friendly: Math content is indexable HTML text
  • Screen reader compatible: Proper semantic markup for assistive technology
  • Progressive enhancement: Works even with JavaScript disabled
  • Print optimized: Math renders correctly in PDF exports

Developer Experience

  • Build-time validation: Math syntax errors caught during development
  • Consistent rendering: Same output across all environments
  • Cache friendly: Math only re-renders when content changes
  • Bundle optimization: Only load math assets when actually used

Result: Math expressions become static HTML before reaching the browser.

Implementation Notes

Design Philosophy: Complete Defaults Pattern

Configuration Architecture:

  • Complete defaults: All options have explicit default values in defaults.ts
  • Progressive disclosure: Users only specify what they want to change
  • Type safety: Full TypeScript interfaces with no optional fallbacks
  • Clean internals: No ?. or || fallback operators in build logic

Example Usage:

// User only needs to specify what they want to change
{
  content: {
    math: {
      enable: true,           // Everything else uses defaults
      engine: "mathjax",      // Switch engines easily
      mathjax: {
        tex: {
          macros: {
            "Q": "{\\mathbb{Q}}"  // Only override specific macros
          }
        }
      }
    }
  }
}

This DeepPartial<XenTConfig> pattern provides excellent developer experience while maintaining clean, predictable internal code.

Per-Post Engine Selection

Decision: Not Implemented

  • Significant technical complexity for marginal benefit
  • Astro limitations with per-post plugin variations
  • Bundle size and performance implications
  • Global engine selection serves most use cases

Migration Strategy

Current State: Existing LaTeX content works with KaTeX/MathJax Future Path: Monitor Typst ecosystem maturity Transition: Simple global engine switch when ready

Performance Characteristics

  • KaTeX: SSG rendering, CDN CSS (~47KB), fast page loads
  • MathJax: SSG rendering, comprehensive LaTeX support
  • SSG Benefits: Math rendered at build time, no client-side JavaScript needed
  • Configuration: Located in config.content.math with complete defaults

Conclusion

This design balances complete defaults architecture with user simplicity. The DeepPartial<XenTConfig> pattern allows users to specify only what they want to change while maintaining fully typed, predictable internal behavior. SSG math rendering provides excellent performance with zero client-side JavaScript overhead. Mathematical rendering remains crisp, professional, and maintainable.