(v_1: (T, T), v_2: (T, T)) -> T { ... }
```
Rendered: $$ s(v_1, v_2) = 1 - \frac{(v_1 \cdot v_2)^2}{|v_1|^2 |v_2|^2} $$
---
### โ๏ธ Solution Comparison
| Approach | Pros | Cons |
|----------|------|------|
| **Unicode Math** ๐ | Zero setup, works everywhere | Limited to simple symbols |
| **KaTeX** ๐ | Fast, full LaTeX, CDN-hosted | Requires JS header injection |
| **MathJax** ๐ข | Full LaTeX support | Slower rendering, heavier |
| **Image-based** ๐ผ๏ธ | No JS needed | Unscalable, unsearchable |
.pull-left[
**Our choice: KaTeX** โ
- Blazing fast (server-side render to HTML)
- Auto-render scans for `$$` / `$`
- Works offline with vendored bundle
- Used by `nalgebra`, `ndarray`, etc.
]
.pull-right[
**What KaTeX gives you:**
$$ \int_{-\infty}^{\infty} e^{-x^2} dx = \sqrt{\pi} $$
$$ \sum_{k=0}^{n} \binom{n}{k} x^{n-k} y^k $$
$$ \det\begin{bmatrix} a & b \\ c & d \end{bmatrix} = ad - bc $$
]
---
### โ๏ธ One-time Setup per Project
**Three files** per repository:
```text
๐ rust-project/
โโโ ๐ .cargo/config.toml # โ New: rustdoc flags
โโโ ๐ src/doc-header.html # โ New: KaTeX header
โโโ ๐ Cargo.toml # โ Updated: docs.rs metadata
```
--
**`.cargo/config.toml`** โ Injects KaTeX into local `cargo doc`:
```toml
[target.'cfg(all())']
rustdocflags = ["--html-in-header", "src/doc-header.html"]
```
--
**`Cargo.toml`** โ Same for docs.rs deployment:
```toml
[package.metadata.docs.rs]
rustdoc-args = ["--html-in-header", "src/doc-header.html"]
```
---
### ๐ The KaTeX Header File
**`src/doc-header.html`** โ Auto-render configuration:
```html
```
--
**Writing in doc comments:**
| Delimiter | Usage | Example |
|-----------|-------|---------|
| `$$ ... $$` | Display math (block) | `$$ x^2 + y^2 $$` |
| `$ ... $` | Inline math | `$E = mc^2$` |
---
class: nord-light, middle, center
## ๐๏ธ Project Walkthroughs
---
### ๐ rat-trig-rs โ Rational Trigonometry
**Project**: Rational Trigonometry library (Norman Wildberger)
**Key formulas added:**
| Function | KaTeX Formula |
|----------|---------------|
| `quadrance` | $$ Q(p_1, p_2) = (x_2 - x_1)^2 + (y_2 - y_1)^2 $$ |
| `spread` | $$ s(v_1, v_2) = 1 - \frac{(v_1 \cdot v_2)^2}{\|v_1\|^2 \|v_2\|^2} $$ |
| `cross` | $$ \text{cross}(v_1, v_2) = x_1 y_2 - y_1 x_2 $$ |
| `archimedes` | $$ \text{quadrea}(q_1, q_2, q_3) = 4 q_1 q_2 - (q_1 + q_2 - q_3)^2 $$ |
| `cosine_law` | $$ s = 1 - \frac{(q_2 + q_3 - q_1)^2}{4 q_2 q_3} $$ |
| `cross3d` | $$ v_1 \times v_2 = (y_1 z_2 - z_1 y_2,\; z_1 x_2 - x_1 z_2,\; x_1 y_2 - y_1 x_2) $$ |
**Files updated**: `trigonom.rs`, `geometry.rs`, `validation.rs`, `const_trigonom.rs`
---
### ๐ฏ ellalgo-rs โ Ellipsoid Method
**Project**: Convex optimization via the Ellipsoid Method
**Ellipsoid update** (core algorithm):
$$ \begin{aligned}
\tilde{g} &= M\,g \\\\
\omega &= g^T \tilde{g} \\\\
\tau^2 &= \kappa\,\omega \\\\
x_c &\leftarrow x_c - \frac{\rho}{\omega}\,\tilde{g} \\\\
M &\leftarrow M - \frac{\sigma}{\omega}\,\tilde{g}\,\tilde{g}^T \\\\
\kappa &\leftarrow \delta\,\kappa
\end{aligned} $$
**LDL^T factorization update** (stable variant):
$$ w = L^{-1}g,\quad z = D^{-1}w,\quad \omega = w^T z,\quad q = L^{-T}z $$
---
### ๐ฏ ellalgo-rs โ Cut Formulas
**Deep cut** (biased cut):
$$ \eta = \tau + n \beta,\quad \rho = \frac{\eta}{n+1},\quad \sigma = \frac{2\eta}{(n+1)(\tau+\beta)},\quad \delta = \frac{n^2}{n^2-1} \cdot \frac{\tau^2 - \beta^2}{\tau^2} $$
**Parallel bias cut:**
$$ \eta = \tau^2 + n\,\beta_0\beta_1,\quad \bar\beta = \frac{\beta_0+\beta_1}{2} $$
$$ h = \tfrac12(\tau^2 + \beta_0\beta_1) + n\bar\beta^2,\quad k = h + \sqrt{h^2 - (n+1)\eta\bar\beta^2} $$
$$ \sigma = \frac{\eta}{k},\quad \rho = \bar\beta\,\sigma $$
**Conjugate Gradient:**
$$ \alpha_k = \frac{r_k^T r_k}{p_k^T A p_k},\quad x_{k+1} = x_k + \alpha_k p_k,\quad r_{k+1} = r_k - \alpha_k A p_k $$
---
### ๐ lds-rs โ Low-Discrepancy Sequences
**Project**: Quasi-Monte Carlo sequence generators
**van der Corput** (fundamental operation):
$$ n = \sum_{k=0}^{m} d_k b^k \quad\longrightarrow\quad \phi_b(n) = \sum_{k=0}^{m} \frac{d_k}{b^{k+1}} $$
--
**Geometric mappings:**
| Generator | Formula |
|-----------|---------|
| **Circle** | $$ \theta = 2\pi v,\quad (\cos\theta,\; \sin\theta) $$ |
| **Disk** | $$ \theta = 2\pi v_\theta,\quad r = \sqrt{v_r},\quad (r\cos\theta,\; r\sin\theta) $$ |
| **Sphere** | $$ \phi = 2v-1,\quad (\sqrt{1-\phi^2}\cos\theta,\; \sqrt{1-\phi^2}\sin\theta,\; \phi) $$ |
| **3-Sphere** | $$ (\cos\eta\cdot e^{i\psi},\; \sin\eta\cdot e^{i(\phi+\psi)}) $$ (Hopf fibration) |
---
### ๐ lds-rs โ N-Sphere Generation
**3-Sphere via covariance mapping:**
$$ \theta = \frac{\pi}{2} v,\quad \chi = F_2^{-1}(\theta),\quad (\sin\chi \cdot \mathbf{s},\; \cos\chi) $$
**N-Sphere via recursion:**
$$ \theta = v \in [0,1],\quad \chi = T_n^{-1}(\theta),\quad (\sin\chi \cdot \mathbf{s}_{n-2},\; \cos\chi) $$
**Precomputed tables** for the marginal CDF inversion:
$$ T_1(\theta) = -\cos\theta,\qquad T_n(\theta) = \int_{0}^{\theta} \sin^{n-1} t\; dt $$
---
### ๐ซ ginger-rs โ Polynomial Root-Finding
**Project**: Parallel Bairstow + Aberth root-finding
**Horner's method** (polynomial evaluation):
$$ P(x) = a_0 x^n + a_1 x^{n-1} + \cdots + a_n,\quad b_k = b_{k-1} \cdot x + a_k $$
--
**Aberth correction:**
$$ z_i' = z_i - \frac{P(z_i)}{P'(z_i)},\qquad P'(z_i) = P_1(z_i) - \sum_{j\neq i} \frac{P(z_i)}{z_i - z_j} $$
--
**Synthetic division** by a quadratic factor:
$$ b_0 = a_0,\quad b_1 = a_1 + r b_0,\quad b_k = a_k + r b_{k-1} + q b_{k-2} $$
$$ A = b_{n-1},\; B = b_n + q b_{n-1} $$
---
### ๐ซ ginger-rs โ Bairstow Details
**Initial guess**:
$$ c = -\frac{a_1}{n a_0},\qquad R = \sqrt[n]{|P(c)|},\qquad (r_k, q_k) = (2(c + R\cos\theta_k),\; -(c^2 + R^2 + 2cR\cos\theta_k)) $$
**Delta correction** (2ร2 system):
$$ \begin{bmatrix} rp + s & p \\ qp & s \end{bmatrix}
\begin{bmatrix} \Delta r \\ \Delta q \end{bmatrix}
= \begin{bmatrix} A \\ B \end{bmatrix} $$
**Adjoint matrix**:
$$ \text{adj}\!\begin{bmatrix} r & q \\ p & s \end{bmatrix}
= \begin{bmatrix} s & -p \\ -pq & pr+s \end{bmatrix} $$
**Quadratic formula:**
$$ x = \frac{r \pm \sqrt{r^2 + 4q}}{2} $$
---
### ๐ฏ projgeom-rs โ Projective Geometry
**Project**: Projective, elliptic, hyperbolic, Euclidean geometry
**Core formulas:**
| Operation | Formula |
|-----------|---------|
| **Cross ratio** | $$ (A,B;C,D) = \frac{AC \cdot BD}{BC \cdot AD} $$ |
| **Harmonic division** | $$ (A,B;C,D) = -1 $$ |
| **Conic** | $$ x^T Q x = 0 $$ |
| **Dot product (3D)** | $$ \mathbf{v}_a \cdot \mathbf{v}_b = x_a x_b + y_a y_b + z_a z_b $$ |
| **Cross product (2D)** | $$ \mathbf{v}_a \times \mathbf{v}_b = x_1 y_2 - x_2 y_1 $$ |
| **Orientation** | $$ \text{sgn}\bigl((x_2-x_1)(y_3-y_1) - (y_2-y_1)(x_3-x_1)\bigr) $$ |
| **Lines parallel** | $$ a_1 b_2 - a_2 b_1 = 0 $$ |
| **Lines perpendicular** | $$ a_1 a_2 + b_1 b_2 = 0 $$ |
---
### ๐ง Pitfall 1: Bracket Escaping
Rustdoc interprets `[foo]` as **intra-doc links**:
```rust
/// $$ v \in [0,1] $$ โ WRONG: rustdoc sees [0,1] as a link!
```
Produces warning:
```
warning: unresolved link to `0,1`
```
--
**Fix**: Escape brackets with backslash:
```rust
/// $$ v \in \[0,1\] $$ โ CORRECT: markdown passes literal [0,1]
```
Similarly for `\sqrt[n]{x}`:
```rust
/// $$ R = \sqrt\[n\]{|P(c)|} $$ โ CORRECT
/// $$ R = \sqrt[n]{|P(c)|} $$ โ WRONG: [n] parsed as link
```
---
### ๐ง Pitfall 2: Line Break Escaping
KaTeX's `aligned` environment needs `\\` for line breaks:
```rust
/// WRONG โ markdown eats one backslash:
/// $$ \begin{aligned}
/// x &= y \\ โ becomes \ in HTML, KaTeX sees only \
/// z &= w
/// \end{aligned} $$
```
--
**Fix**: Use quadruple backslash `\\\\`:
```rust
/// CORRECT โ produces \\ in HTML:
/// $$
/// \begin{aligned}
/// x &= y \\\\ โ markdown: \\\\ โ \\ โ KaTeX sees \\
/// z &= w
/// \end{aligned}
/// $$
```
Rendered:
$$ \begin{aligned}
x &= y \\\\
z &= w
\end{aligned} $$
---
### ๐ Python vs Rust: Equation Patterns
Both projects used the same mathematical content โ only syntax differs:
.pull-left[
**Python (Sphinx + MathJax)** ๐
```python
r"""The spread:
.. math::
s = 1 - \frac{(v_1 \cdot v_2)^2}
{|v_1|^2 |v_2|^2}
where :math:`v_1, v_2` are vectors.
"""
```
]
.pull-right[
**Rust (rustdoc + KaTeX)** ๐ฆ
```rust
/// The spread:
///
/// $$ s = 1 - \frac{(v_1 \cdot v_2)^2}{|v_1|^2 |v_2|^2} $$
///
/// where $v_1, v_2$ are vectors.
pub fn spread(...)
```
]
--
**KaTeX advantages for Rust:**
- โ
Native `$` / `$$` syntax โ no RST baggage
- โ
Works with `cargo doc` output
- โ
Same delimiter style for both projects
---
### ๐๏ธ Full Architecture
.mermaid[
graph TD
subgraph "Per-Project Setup"
A[".cargo/config.toml"] -->|"rustdocflags"| B["cargo doc"]
C["Cargo.toml"] -->|"docs.rs metadata"| D["docs.rs build"]
E["src/doc-header.html"] -->|"injected into <head>"| B
E -->|"injected into <head>"| D
end
subgraph "KaTeX Pipeline"
F["Doc comments\nwith $$...$$"] -->|"cargo doc"| G["HTML with\n$$...$$ preserved"]
G -->|"DOMContentLoaded"| H["KaTeX auto-render\nscans for $$ / $"]
H -->|"renderMathInElement"| I["Beautiful math!\nSVG/HTML output"]
end
subgraph "5 Projects"
J["rat-trig-rs"]
K["ellalgo-rs"]
L["lds-rs"]
M["ginger-rs"]
N["projgeom-rs"]
end
B --> G
D --> G
I --> J
I --> K
I --> L
I --> M
I --> N
]
---
### ๐ Results: By the Numbers
| Metric | Count |
|--------|-------|
| **Projects updated** | 5 |
| **Source files modified** | 28 |
| **KaTeX formulas added** | 110+ |
| **Warnings introduced** | 0 ๐ |
| **Projects with Python reference** | 4 (ellalgo, lds, ginger, projgeom) |
--
**Coverage by domain:**
| Domain | Project | Key Formulas |
|--------|---------|--------------|
| ๐ข Rational Trigonometry | `rat-trig-rs` | Quadrance, spread, cross |
| ๐ฏ Convex Optimization | `ellalgo-rs` | Cut parameters, CG |
| ๐ข Low-Discrepancy | `lds-rs` | van der Corput, sphere maps |
| ๐งฎ Polynomial Roots | `ginger-rs` | Aberth, Bairstow, Horner |
| ๐ Projective Geometry | `projgeom-rs` | Cross ratio, conics |
---
### ๐ก Key Takeaways
.pull-left[
**For Library Authors:**
1. **KaTeX is the gold standard** for math in Rust docs
- Fast, CDN-hosted, auto-render
- Used by top Rust math crates
2. **Three-file setup** is minimal:
- `.cargo/config.toml` + `doc-header.html` + `Cargo.toml` metadata
3. **Reference Python projects** when available:
- Python has `.. math::` โ Rust has `$$...$$`
- Same mathematical content, different syntax
]
.pull-right[
**Watch out for:**
4. **Bracket escaping** โ `\[0,1\]` not `[0,1]` inside math
5. **Line breaks** โ `\\\\` not `\\` in `aligned`
6. **`\sqrt[n]{x}`** โ `\sqrt\[n\]{x}` to avoid link parsing
**Format to follow:**
```rust
/// Description text.
///
/// $$ formula $$
///
/// More description.
```
]
---
class: nord-light, middle, center
## โ Questions?
---
count: false
class: nord-dark, middle, center
# ๐ Thank You
### Happy Documenting!
**Slides**: [`luk036.github.io/idea/doc-eqn-remark`](https://luk036.github.io/idea/doc-eqn-remark.html)
**Repositories**:
- [`github.com/luk036/rat-trig-rs`](https://github.com/luk036/rat-trig-rs)
- [`github.com/luk036/ellalgo-rs`](https://github.com/luk036/ellalgo-rs)
- [`github.com/luk036/lds-rs`](https://github.com/luk036/lds-rs)
- [`github.com/luk036/ginger-rs`](https://github.com/luk036/ginger-rs)
- [`github.com/luk036/projgeom-rs`](https://github.com/luk036/projgeom-rs)
@luk036 ๐จโ๐ป ยท 2026 ๐