将方程与“groff eqn”中的多个标记和阵容对齐

如何解决将方程与“groff eqn”中的多个标记和阵容对齐

我正在尝试按照我通常在 LaTeX 中使用 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(找到 here)中的 Kernighan 和 Cherry 来说明它们是如何工作的:

mark 这个词可以在等式中的任何地方出现一次。它记住它出现的水平位置。连续方程可以包含一个lineuplineup 出现的地方尽可能与前面mark标记的地方对齐。

在阅读本文时,我的印象是系统不会禁止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}

我想知道是否有一些宏可以让我存储多个水平偏移(或如何定义一个)。对 marklineup 宏究竟是如何工作的进行一些说明也会有所帮助。

解决方法

非常令人失望的是,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

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

,

这是在与 mark 相同的行上有第二个 lineup 的可能解决方案。它使用基本 troff 序列 \k 将当前水平位置标记到寄存器 myposn 中。然后有一个 eqn 宏 mylineup,它调用 eqn special 命令来运行 troff define 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

.de.. 的行是 MyLineup 的定义。两条 define 行应该在第一个等式中。此后,可以使用 mymarkmylineup dummy 代替 marklineup。原始标记和阵容不变。如有必要,可以在带有 mark 的行中再次使用真正的 mylineup,依此类推。


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

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

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

.substring 0s 7 -6
,

我可能被您的示例中的多个 .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

equation

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?