Groff Arithmetic – How to Perform Calculations

arithmeticgroff

Is it possible to perform arithmetic using groff?
Say I want to calculate what page is the current one, and I currently am on page 2.
I can get the next page's number by using:

.PP
Next page is number \n[.pn]

Which will compile as Next page is number 3.

How can I perform arithmetic to render instead:

.PP
Current page is ((\n[.pn]-1))

into Current page is 2 ?

Best Answer

The current page number is \n% .

To interpolate the result of an arithmetic expression, I think you'll need to put it in a number register first.

Here's a macro (not exhaustively tested) that takes an expression as its argument, assigns the result to a (presumably unused) register named __, then interpolates the contents of the register.

Current page is \n%.
.br
.\" EI - eval and interpolate
.\" $1 is an expression to evaluate
.\" $2 (optional) is a string to append to the interpolated expression,
.\"    without any intervening whitespace
.de EI
.nr __ \\$1
\&\\n(__\\$2
..
.nr x 4
4 times 3 minus 5 is
'EI (\nx*3-5)
\&.
.br
Here there's no space before the period:
'EI (\nx*3-5) .
.br

After running through nroff:

Current page is 1.
4 times 3 minus 5 is 7 .
Here there's no space before the period: 7.

This seems like such a common thing to do that there may be a macro like it already in the standard macro packages, but I don't know.

Related Question