Fontlex ·
All demos ·
Download
Fontlex Relaxed Math
The box below is a plain text box holding math the way people type it in plain text:
(a+b)/(c+d), x^2, sqrt(x). The font typesets it as you type: fractions,
roots, superscripts and subscripts, laid out by the text engine that lays out the letters. Ordinary text stays
ordinary, so and/or, w/o, dates and paths are left alone. The characters stay exactly
as typed. No script on this page lays anything out.
- Try
(a+b)/(c+d), x^2, or sqrt(x).
- Copying preserves exactly what you typed.
- Spaces inside formulas and mixed Greek/Latin text have limitations; see below.
What it typesets
- Fractions:
1/2, x/2, 2a/3, (a+b)/(c+d),
f(x)/2, 1/(1+1/x). Parentheses around a whole part go; with a script after them they
stay: (a+b)^2/c.
- Scripts:
x^2, x^(n+1), x^-1, x_1, H_2O,
and both at once, stacked: x_i^2.
- Roots:
sqrt(x^2+1).
- Symbols:
<= >= != -> =>
+- become ≤ ≥ ≠ → ⇒ ±. Greek letters and other symbols can be typed as themselves.
That is all: this isn't LaTeX or a general math engine. For a little LaTeX, see
Fontlex Math, a subset as well.
What stays text
- A fraction's parts are numbers (
12, 3.5), a number and a letter
(2a), one letter, a group in parentheses, a call like f(x) or sin(x), or
a root, each with its scripts. Longer words make no fraction: and/or, km/h,
page/2.
- Two lone letters make a fraction only in an expression (
a+b/c, x = a/b), so
w/o, n/a and I/O stay as they are.
- Slashes in a row (
a/b/c, 10/23/2026, //) make none, nor does any
slash in a run of characters where one touches a longer word (tr/a-z/A-Z/).
- No script touches another underscore, and a number has no subscript:
file_1_2,
1_000 stay text.
Limits and ambiguous notation
- Nesting. Constructs go inside constructs 3 deep, with at most 2 fractions
inside one another, and at most 24 characters in a construct that isn't inside another. Past that, a
construct stays as its characters.
- Spaces. A space inside a construct leaves it as its characters: write
(a+b)/2, not
(a + b)/2. Spaces between formulas are fine.
- Greek and Latin. Chrome and Firefox shape runs of Greek and Latin letters apart, and a construct
can't span two runs, so there
e^(iπ) stays as its characters. Safari lays it out.
- Ambiguous notation. A part is a whole word, so
2/3x is 2 over 3x, and
x^2y is x² followed by y. A number over a number is always a fraction, so 7/8 bit
and a date like 6/14 are typeset too. On its own, a/b stays text, as
w/o does.
- Lines and the caret. Each line is read on its own. A construct that isn't complete yet stays as
its characters until it is. Inside a fraction the caret stays at the fraction's start: its glyphs are drawn
where they belong, but take no room of their own.
- Where it's checked. HarfBuzz (the shaper in Chrome and Firefox) and Core Text (Safari, macOS)
against a model of the notation. By screenshot, Chrome and Safari's WebKit on macOS, and Chromium and Firefox
on Linux and Windows. Native Windows apps, which shape with DirectWrite, aren't checked.
How it works
122 passes read each line the way the rules above say, and rewrite it as the LaTeX that lays out the
same: (a+b)/(c+d) as \frac{a+b}{c+d}, with the parentheses as its braces and a
\frac and braces that the line doesn't have inserted as glyphs that draw nothing. Then Fontlex
Math's own passes lay it out. The font has 55,176 glyphs and 2,044 substitution and 301 positioning lookups.
Results
Each line is shaped with the font, what it draws is read back from the glyphs (characters by name and
size, rules from their outlines), and compared with a separate Python model of the notation
(relaxed.py), to the font unit.
| Lines | Count | HarfBuzz |
| Edge cases (incomplete and broken input, and prose) | 50 | 100.0% |
| Random formulas and words, some mistyped | 2,000 | 100.0% |
This page checks a sample each time it is built. The full check, 20,000 random lines and the
edge cases in HarfBuzz and Core Text, matches the model on every line: see
math/README.md.
Base font: JetBrains Mono (SIL Open Font License).