给定一个 TeX 段落,有没有办法在 TeX 会自动插入换行符的地方插入标记(类似于 \everypar?)
为了提供一些背景信息,我正在编写一个用于排版编程语言语法的 LaTeX 包。给定类似这样的内容
\begin{format}
Types \alpha ::= \tau | \tau \to \tau | \mu \alpha. \tau | ...
\end{format}
它应该转换为 tabularx,其中包含“类型”、“\alpha”、“::=”和定义主体(规范 X)的列。X 列的定义是,其上下文在数学模式下排版,并且 | 被重新定义为 \mid。但是,如果行太长,它应该换行,并且 | 应该出现在 ::= 出现的位置。例如,
Types \alpha ::= \tau | \tau \to \tau
| \mu \alpha. \tau
我的暂定策略是在每个 TeX 换行符前插入适当的“\ \multicolumn{...}”标记序列,这样我就可以在 ::= 所在的位置插入 |。
有任何想法吗?
(PS,我认为现有的 LaTeX BNF 包无法做到这一点 —— 我所见过的包都需要一个明确的命令来断行并将 | 放在 ::= 所在的位置。)
答案1
我的建议是让它变得参差不齐,然后告诉 TeX | 是换行的好地方,方法是调整 的值\penalty
。根据你如何说服 TeX | 应该被替换为\mid
,你可以这样做
\documentclass{article}
\mathcode`|="8000
\begingroup
\catcode`|\active
\gdef|{\penalty2000\mid\nobreak}
\endgroup
\begin{document}
\begin{flushleft}
$AAAAAAAAAA|BBBBBBBBBBB|CCCCCCCCCCCCCCCCC|DDDDDDDDDDDDD
|EEEEEEEEEEEEEEE|FFFFFFFFFFFFFFFFFF|GGGGGGGGGGGGGG|HHHHHHHHHHHHH$
\end{flushleft}
\end{document}
这是一个更完整的例子。
\documentclass{article}
\usepackage{colonequals}
\usepackage{tabularx}
\usepackage{calc}
\makeatletter
\begingroup
\catcode`|\active
\gdef\setupformatpipe{%
\mathcode`\|="8000
\catcode`\|\active
\def|{\penalty-1\makebox[\widthof{$\m@th{}\coloncolonequals{}$}]{$\m@th\mid$}\nobreak}%
}
\endgroup
\newenvironment{format}
{\setupformatpipe
\tabularx{\linewidth}{lr@{}>{\raggedright\arraybackslash}X}}
{\endtabularx}
\def\formatrow#1 #2::=#3\\{%
#1&$\m@th#2$&$\m@th{}\coloncolonequals#3$\\
}
\makeatother
\begin{document}
\begin{format}
\formatrow Types \alpha ::= \tau | \tau \to \tau | \mu \alpha. \tau |
AAAAAAAAAAAAA | BBBBBBBBBBBB | CCCCCCCCCCC | DDDDDDDDDDDDD
| EEEEEEEEEEEEEEEEE | FFFFFFFFFFFFFFF\\
\formatrow {} \beta ::= GGGGGGGGGGGG | HHHHHHHHHHHHHH |
IIIIIIIIIIIIIII | JJJJJJJJJJJJ | KKKKKKKKKKK | LLLLLLL\\
\end{format}
\end{document}
但它确实需要使用该\formatrow
宏。
答案2
我会放置 ::= 以便它实际上(部分)位于第三列:
\documentclass{book}
\usepackage{array}
\begin{document}
\begin{tabular}{ll>{\makebox[0pt]{::=}\quad}p{2cm}}
Types &$\alpha$ & $\tau | \tau \to \tau \allowbreak
| \mu \alpha. \tau$
\end{tabular}
\end{document}