I am trying to align some fairly long equations the way I would usually do with LaTeX
in groff
. The general form I am aiming for:
A = B + C
= D * E
+ F * G
= H + I = J
In LaTeX
I would do this as follows:
\documentclass[fleqn]{article}
\usepackage{amsmath}
\begin{document}
\begin{alignat*}{3}
A
& = B + C \\
& =
\begin{aligned}[t]
& D * E \\
& + F * G
\end{aligned} \\
& = H + I
&& = J
\end{alignat*}
\end{document}
In eqn
, equation alignment is accomplished with the mark and lineup commands. Quoting Kernighan and Cherry from Typesetting Mathematics 2nd Ed (found here) on how these work:
The word mark may appear once at any place in an equation. It remembers the horizontal position where it appeared. Successive equations can contain one occurence of the word lineup. The place where lineup appears is made to line up with the place marked by the previous mark if at all possible.
Upon reading this I was under the impression that the system does not prohibit both aligning with the previous mark with lineup as well as setting a new mark within the same line of an equation, e.g. I would expect the following:
.PP
.EQ I
A mark =
B + C
.EN
.EQ I
lineup = mark
D * E
.EN
.EQ I
lineup + F * G
.EN
to produce something like this:
A = B + C
= D * E
+ F * G
That is not the case, however. eqn
aligns the plus sign with the equals:
A = B + C
= D * E
+ F * G
and produces a warning:
eqn:test.ms:10: multiple marks and lineups
I compile my .ms
files with a small script:
eqn $1 -Tpdf | groff -ms -Tpdf > ${1/%.ms/.pdf}
I would like to know if there is some macro that would let me store multiple horizontal offsets (or how to define one). Some clarification as to how exactly mark and lineup macros work would also help.
Here's a possible solution for having a second mark
on the same line as lineup
. It uses the base troff sequence \k
to mark the current horizontal position into a register myposn
. There is then an eqn macro mylineup
which calls the eqn special
command to run a troff define MyLineup
which "returns" a character that has a horizontal movement of myposn
units. Before the call eqn sets up some registers with the word following the call, and expects them to be updated to whatever output is desired at that point. We do not use this dummy word, which can be anything, but must not be omitted. For example,
.de MyLineup
. ds 0s "\h'\\n[myposn]u'
. nr 0w \\n[myposn]u
. nr 0h 0
. nr 0d 0
. nr 0skern 0
. nr 0skew 0
..
.EQ I
define mymark '\k[myposn]'
define mylineup 'special MyLineup'
A mark = B + C
.EN
.EQ I
lineup = mymark D * E
.EN
.EQ I
mylineup dummy + F * G
.EN
The lines from .de
to ..
are the MyLineup
definition. The two define
lines should be in the first equation. Thereafter, mymark
and mylineup dummy
can be used in place of mark
and lineup
. The original mark and lineup are unchanged. If necessary, the real mark
can be used again in the line with mylineup
, and so on.
To generalise this to having many marks is complicated. The first problem is that mymark
is just an eqn define and cannot take a number parameter. It cannot use the special
command because it needs to be inline. A trivial solution is just to create a lot of definitions at the start:
define mymark1 '\k[myposn1]'
define mymark2 '\k[myposn2]'
The second problem is that when eqn calls MyLineup
it does not pass the following argument ("dummy" which we intend to change to "1") as a parameter of the call, but in the variable 0s
; also the string is embedded in formatting code and is actually (in my test anyway) \f[R]\,1\/\fP
. So we need to substring the number out of this, with .substring 0s 7 -6
. The modified macro and test is:
.\" gets passed 0s = \f[R]\,1\/\fP !!! not just 1
.de MyLineup
. substring 0s 7 -6
. ds 0s \\h'\\n[myposn\\*[0s]]u'
. nr 0w \\n[myposn\\*[0s]]u
. nr 0h 0
. nr 0d 0
. nr 0skern 0
. nr 0skew 0
..
.EQ I
define mymark1 '\k[myposn1]'
define mymark2 '\k[myposn2]'
define mylineup 'special MyLineup'
A mark = B + C
.EN
.EQ I
lineup = mymark1 D * mymark2 E
.EN
.EQ I
mylineup 1 + F * G
.EN
.EQ I
mylineup 2 + X
.EN
.EQ I
lineup = H + I
.EN