Home / Alt manpages / eqn(1)

  • eqn(1)
  • User command
  • linux

Format Equations in roff with GNU eqn

Typing a quadratic formula into a man page or a roff document looks impossible until you meet eqn, which turns plain-text maths into proper notation. You will turn a small roff document containing mathematical notation into terminal, PostScript or MathML output with GNU eqn. The examples use groff 1.23.0 from the Ubuntu groff-base package. Allow about 15 minutes for a first working document. No root privileges are needed.

1. Know which program does what

eqn is a preprocessor. It reads roff, translates the material between .EQ and .EN, and writes roff to standard output. It does not normally produce a finished page by itself.

  • Day to day: let groff invoke it with -e.
  • The installed name: geqn is the compatibility name for the GNU implementation.

Confirm the version before relying on a feature. It also makes a bug report reproducible:

eqn --version
groff --version
dpkg-query -W -f='\${Package} \${Version}\n' groff-base

Checkpoint

On the machine used for these examples, the result begins with GNU eqn (groff) version 1.23.0 and the package is groff-base 1.23.0-3build2. Your output may differ.

2. Write a displayed equation

Put the equation between lines beginning with .EQ and .EN. Spaces and newlines separate tokens. They do not become visible spacing in the result.

.EQ
F = m a
.EN

Save that as newton.roff, then render it for a UTF-8 terminal:

groff -e -Tutf8 newton.roff

You should see an equation containing F = ma. The terminal driver may use escape sequences to underline italic letters, so do not treat the raw output as plain text. The same source can go to a different groff device, as long as that device is installed.

To inspect what the preprocessor itself emits, use:

eqn -Tutf8 newton.roff | sed -n '1,35p'

That output is intermediate roff, not a portable display format. Keep the -T option: without it, eqn warns that it was not given a device. Passing it in the pipeline stops the preprocessor and formatter making different device assumptions.

3. Build a less trivial expression

Tokens such as sup, over and sqrt describe structure, and braces group an expression. Without braces, a superscript applies to the next expression only. That is a frequent source of wrong-looking formulae.

.EQ
x = { - b ~ \[+-] ~ sqrt { b sup 2 - 4 a c } } over { 2 a }
.EN

Render it with the same command:

groff -e -Tutf8 quadratic.roff

The output contains a fraction, a plus-or-minus sign and a square root. Two details are worth knowing:

  • The ~ token requests a full space. Use it when automatic mathematical spacing is not enough.
  • The \[+-] sequence is the groff special character for plus-or-minus, so you do not rely on the input encoding.

4. Add inline equations deliberately

For running text, define delimiters inside an equation block. This example uses two dollar signs and then turns them off, so later dollar signs in the document are ordinary text.

.EQ
delim $$
.EN
The distance is $x sup 2 + y sup 2$.
.EQ
delim off
.EN

Run it as:

groff -e -Tutf8 inline.roff

Delimiters apply to equations not enclosed by .EQ and .EN. A source-level delim xy overrides a command-line delimiter set with eqn -d xy.

Recovery

If an inline equation is accidentally left open, eqn -N prohibits newlines within delimiters and helps eqn recover from a missing closing delimiter.

5. Produce MathML when HTML is the target

Use the MathML device instead of the normal troff device:

eqn -T MathML newton.roff

The output keeps the .EQ and .EN lines, but puts MathML markup for the equation between them. In a larger groff workflow, pass the same device choice consistently through the preprocessors you use.

MathML is not troff with different spelling:

  • Tuning parameters are ignored. Eqn's visual tuning parameters do not affect MathML, because a browser or another MathML engine chooses the final dimensions.
  • Some primitives fail. The special, up, down, fwd and back primitives are unavailable in this mode and produce an error element.

Tip

Stick to ordinary equation structure when the same source must work in both output families.

Common traps

  • Running only eqn. Its output is meant for troff. Pipe it to a matching formatter, or use the simpler groff -e form.
  • Forgetting grouping. Write e sup { a b } when the whole grouped expression belongs above the line. e sup a b means the superscript ends before b.
  • Using an unquoted short name. Names such as pi can collide with troff identifiers. Quote text that should be treated literally, for example "pi".
  • Expecting terminal output to be a clean text file. The terminal driver can emit control sequences for styles. Render to a device suited to the next consumer.
  • Changing eqnrc without a plan. By default eqn searches for that initialisation file in the directories selected by -M, then the site and standard groff macro directories. Use -R to suppress it for a controlled test. This changes formatting defaults, so compare output before adopting it.

Nothing in these examples changes system state, so there is no service to restart and no undo step. If a document renders wrongly, keep the source and compare the intermediate output from eqn -Tutf8 with the final formatter output. That separates equation syntax errors from device or font problems.

Done means

  • Version known. eqn --version reports the implementation you intend to use.
  • Document renders. A file containing .EQ and .EN comes out right through groff -e.
  • Structure correct. Grouped superscripts, fractions and radicals give the intended layout.
  • Delimiters closed. Inline delimiters are switched off again when the document no longer needs them.
  • MathML chosen knowingly. You use it only when its rendering and primitive limits fit the target.