2

我正在尝试以我通常使用LaTeXin的方式对齐一些相当长的方程groff。我的目标是一般形式:

A = B + C
  = D * E
    + F * G
  = H + I   = J

LaTeX我会这样做如下:

\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}

eqn中,方程对齐是通过marklineup命令完成的。引用Typesetting Mathematics 2nd Ed(在此处找到)中的 Kernighan 和 Cherry 关于这些如何工作的内容:

文字标记可以在方程式中的任何位置出现一次。它会记住它出现的水平位置。连续的方程可以包含一个单词lineup的出现。如果可能的话,排列出现的位置与前一个标记标记的位置对齐。

在阅读本文时,我的印象是系统不会禁止使用阵容与先前的标记对齐以及在等式的同一行内设置新标记,例如,我期望以下内容:

.PP
.EQ I
A mark =
B + C
.EN
.EQ I
lineup = mark
D * E
.EN
.EQ I
lineup + F * G
.EN

产生这样的东西:

A = B + C
  = D * E
    + F * G

然而,事实并非如此。eqn将加号与等号对齐:

A = B + C
  = D * E
  + F * G

并产生警告:

eqn:test.ms:10: multiple marks and lineups

.ms我用一个小脚本编译我的文件:

eqn $1 -Tpdf | groff -ms -Tpdf > ${1/%.ms/.pdf}

我想知道是否有一些宏可以让我存储多个水平偏移(或如何定义一个)。关于标记阵容宏的工作原理的一些说明也会有所帮助。

4

3 回答 3

2

eqn不允许设置新标记非常令人失望。这是一个糟糕的解决方法,可能会有一些用处。它包括重复第一个等式,但将关键字mark放在新位置,并将输出转移到无处,因此它不会出现。.di是开始和结束转移的基础 troff。

.EQ I
A mark = B + C
.EN
.EQ I
lineup = D * E
.EN
.di mydump
.EQ I
A = mark B + C
.EN
.di
.EQ I
lineup + F * G
.EN

请注意,您还可以使用 eqn 命令,例如fwd 99向右移动 99/100 em,其中em大约是字符“m”的宽度。

于 2021-06-05T13:07:31.347 回答
1

我可能被.EQ你的例子中有几个电话误导了。我假设在调用和方程式之间会有文本。但是,如果打算有一个单一的多线方程,则可以使用matrix(或者也可以lpile)来完成。例如,

.nr PS 20p
.nr VS 24p
.PP
.EQ
matrix { 
 lcol { A }
 lcol { = above = above ~ above = }
 lcol { B + C above D * E above + F * G above H + I }
 lcol { ~ above ~ above ~ above = J }
}
.EN

方程

于 2021-06-05T16:24:05.907 回答
1

这是一个可能的解决方案,可以让第二个marklineup. 它使用基本 troff 序列\k将当前水平位置标记到寄存器myposn中。然后有一个 eqn 宏mylineup ,它调用 eqnspecial命令来运行一个 troff 定义MyLineup,它“返回”一个具有myposn单位水平移动的字符。在调用之前,eqn 使用调用之后的单词设置一些寄存器,并期望它们被更新为此时所需的任何输出。我们不使用这个虚拟词,它可以是任何东西,但不能省略。例如,

.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

.deto的行..MyLineup定义。两条define线应该在第一个等式中。此后,mymarkmylineup dummy可以用来代替markand lineup。原有的标记和阵容不变。如有必要,mark可以在符合的情况下再次使用实数mylineup,依此类推。


将其概括为具有许多标记是复杂的。第一个问题是这mymark只是一个 eqn 定义,不能带数字参数。它不能使用该special命令,因为它需要是内联的。一个简单的解决方案是在开始时创建很多定义:

define mymark1 '\k[myposn1]'
define mymark2 '\k[myposn2]'

第二个问题是,当 eqn 调用时MyLineup,它没有传递以下参数(“dummy”,我们打算将其更改为“1”)作为调用的参数,而是在变量中0s;该字符串也嵌入在格式化代码中,实际上是(无论如何在我的测试中)\f[R]\,1\/\fP。所以我们需要用.substring 0s 7 -6. 修改后的宏和测试是:

.\"   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
于 2021-06-05T15:56:49.370 回答