Documentation menu

Formula block

Math and science notation — fractions, exponents, subscripts, Greek letters, and chemical formulas via \ce{...} — rendered server-side as an image with real alt text, since no email client typesets actual math.

How it works

The block takes a small LaTeX-like notation string (for example, \frac{-b \pm \sqrt{b^2-4ac}}{2a}) and renders it server-side to a PNG through GET /api/formula. That's a signed endpoint built on the same from-scratch raster/PNG-encoding primitives the analytics chart blocks already use: there's no client-side math library involved, ever, and no npm dependency behind the renderer.

A formula's content is fixed once authored, unlike the countdown GIF, which must be regenerated per view to stay live. So the whole render request (notation, display mode, color) signs into the URL itself, and the endpoint needs no Firestore read — the response carries a long-lived immutable cache header.

The notation syntax covers fractions, exponents (^), subscripts (_), square roots, Greek letters, named functions (\sin, \lim, \log, and others), set/logic symbols (\forall, \in, \cup, \neg, and others), and common operators. \left(/\right( are recognized but rendered at normal size rather than auto-scaled to their contents, since this is a small bitmap renderer, not a full TeX engine. \text{...} drops back to plain words mid-formula for labeling a term.

Chemical formulas get their own \ce{...} macro: a small mhchem-like subset. Element counts auto-subscript (H2O renders with a subscript 2), trailing ionic charges auto-superscript (H3O+, SO4^2-), and -> renders as a reaction arrow. That means \ce{2H2 + O2 -> 2H2O} doesn't need you to hand-write ^/_ for every atom count and charge.

Syntax the parser doesn't recognize — full LaTeX documents, packages, matrices, tables — never breaks the send. It degrades to rendering the raw notation string as plain literal text instead. That guarantee is enforced at two layers: the parser itself degrades unknown macros to literal text, and the renderer's outermost call never throws even on a layout edge case.

The image is laid out at a scale appropriate to its display mode: larger for Block, smaller for Inline. It steps down automatically if it would exceed the email-safe size budget. Most formulas fit on the first try; only an unusually long expression needs a smaller scale, and a pathological one clamps to the minimum scale rather than looping forever.

The rendered <img> carries explicit width/height attributes sized from that layout pass, so Outlook and other clients don't jump-reflow while the image loads. Critically, it also carries an alt attribute set to the raw notation string itself. A formula is never trapped inside a picture with no text equivalent for a client that blocks images or a screen reader that can't parse a bitmap.

Configurable fields:

  • Notation (LaTeX-like) — the formula text, capped at 300 characters (an over-length value is silently truncated before rendering, never breaks the send).
  • Display mode — Inline (small, sits within a line of text) or Block (larger, its own line).
  • Alignment — Left, Center, or Right (Block mode only, in effect).
  • Color — the notation's stroke color; an invalid or empty value falls back to the renderer's own near-black default rather than reaching the signed endpoint with a value it would reject.
  • Background color, padding, border and border radius on the card.

An empty notation renders nothing at all rather than an empty image — the block simply doesn't emit if there's no text to typeset.

Supported syntax

Every example below is a real, live signed image from the actual /api/formula endpoint, not a mockup, so what you see here is exactly what a recipient's inbox renders. Anything not on this list (full LaTeX documents, packages, matrices, tables, accents like \bar/\hat, ellipses like \dots) isn't recognized. It renders literally as its own typed-out text instead of breaking the send, so it's usually obvious in a preview that a macro isn't supported.

Fractions

\frac{a+b}{c-d}
\frac{a+b}{c-d}

Exponents and subscripts

a_n = a_1 + (n-1)d
a_n = a_1 + (n-1)d

Square roots, nested with a fraction

\sigma = \sqrt{\frac{1}{n}\sum (x_i - \mu)^2}
\sigma = \sqrt{\frac{1}{n}\sum (x_i - \mu)^2}

The quadratic formula — fractions, ±, and a square root together

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

Greek letters

\Delta = b^2 - 4ac
\Delta = b^2 - 4ac

Named functions and limits (upright, not italicized)

\lim_{x \to 0} \frac{\sin x}{x} = 1
\lim_{x \to 0} \frac{\sin x}{x} = 1

Set and logic symbols

\forall x \in S,\ x^2 \geq 0
\forall x \in S,\ x^2 \geq 0

\left(/\right) delimiters — recognized, but not auto-scaled to their contents

y = \left(x+1\right)^2
y = \left(x+1\right)^2

\text{...} for a label mid-formula

d = 5\text{ mi}
d = 5\text{ mi}

Chemical formulas via \ce{...} — auto-subscripted atom counts, a reaction arrow

\ce{2H2 + O2 -> 2H2O}
\ce{2H2 + O2 -> 2H2O}

\ce{...} — auto-superscripted ionic charges

\ce{SO4^2-}
\ce{SO4^2-}

Examples

Subject

This week in study group: the quadratic formula

A chemistry-class recap email typesets a balanced reaction inline in a sentence: "Photosynthesis: \ce{6CO2 + 6H2O -> C6H12O6 + 6O2}" right next to explanatory text. See Education for how Formula fits alongside Assignment, Quiz, and Flashcard deck in a classroom digest. A physics problem set drops the quadratic formula in Block mode as its own line, sized larger and centered, ahead of a worked example. A stats newsletter uses a short inline formula like \mu = \frac{\sum x_i}{n} mid-sentence without breaking the surrounding paragraph's flow. Note that's \mu, not \bar{x}: accent macros like \bar/\hat aren't in the supported syntax list above, so a plain Greek letter is the safe stand-in for a mean where one is needed.

What the static fallback looks like

<div style="margin:8px 0;text-align:left">
  <img src="https://mailinapp.com/api/formula?d=eyJub3RhdGlvbiI6...&s=abc123..."
       width="184" height="52" alt="E = mc^2"
       style="display:inline-block;max-width:100%;height:auto;vertical-align:middle" />
</div>

There's only one render tier — a signed <img> whose alt text always carries the exact notation string, so the formula still communicates even where the image itself doesn't load.