编写 \unpar 宏

编写 \unpar 宏

我想写一个\unpar宏来删除最后一个\par。例如,TeX 代码

 This is a \par \unpar paragraph

应该相当于

 This is a paragraph

(请注意,等效并不意味着它必须完全生成最后一个标记列表:我的意思是它应该具有与我使用最后一个标记列表获得的输出相同的输出。)

解决方案可能是\par按以下方式重新定义:

\let\oldpar\par
\def\unpar{}
\long\def\par#1{\ifx#1\unpar\else\oldpar#1\fi}

\bye但如果前面有 ,则此方法不起作用\par(我不知道为什么)。此外, 的重新定义\par可能会破坏某些宏包。所以,我想知道:有没有一种方法可以定义\unpar而不修改\par

\Unpar那么如果宏不仅删除一个\par,而且删除其前面的所有s ,那又怎么样呢\par

答案1

这不可能。

TeX 看到\par

此时,当前水平列表被拆分为水平框的垂直列表,必要时应用连字符,丢弃可丢弃的粘连并添加左右粘连。然后调用输出例程,该例程可能输出一页或多页,可能取出存储的插入和脚注,并将它们添加到页面中,然后以垂直模式将控制权返回到输入流。

\unpar要取消这一切将会非常困难。

答案2

您可以尝试这样的操作:

\def\par{\futurelet\next\dopar}
\def\dopar{\let\doparA=\endgraf
           \ifx\next\par \let\doparA\relax \fi
           \ifx\next\unpar \let\doparA\relax \fi
           \doparA}
\def\unpar{\donothing{unpar}} % any special macro with empty output
\def\donothing#1{}


This is paragraph.

Note more empty lines here:



\unpar
The paragraph is not finished.

\bye

当然,你必须重新定义\par。没有其他的可能性(这是 David Carlisle 解释的)。

你的错误是:你试图通过#1(宏参数)而不是 来扫描下一个标记,\futurelet后者更加可靠。\outer定义的宏(如\bye)无法加载到#1,但可以使用 进行测试\futurelet。如果下一个标记是,{那么#1扫描的工作量比你需要做的要多得多。但\futurelet保持{不变。

相关内容