我正在生成 LaTeX 代码,因此,我面临着在插入的 LaTeX 命令和随后的文本之间保留空格的困难。我现在的做法是按照以下答案的建议去做的类似的问题,即始终{}
在命令后放置一对空括号。
例如,假设有一个定义\newcommand{\arnold}{Arnold Schwarzenegger}
,一个源文本xxx $foo is a xxx
,和$foo
代表\arnold
,我将源文本翻译为xxx \arnold{} is a xxx
。
我知道我可以使用xxx {\arnold} is a xxx
应该更安全的东西(从语法上来说) - 但是这使得在这里插入一个开始组并在那里插入一个结束组变得不可能,这对我来说是必不可少的。
此外,该xspace
软件包不是一个解决方案,因为我无法控制用户想要插入到他们的脚本中的命令,我甚至不会思考关于重新定义/包装现有命令——考虑到 TeX 内部工作的极度复杂性(通常与消化或其结果进行比较),这种方法最好留给拥有无限资源的平行世界去尝试。(更重要的是,Dave Carlisle 本人推荐不是使用xspace
,所以谢谢,但是不用了,谢谢。)
在这种特殊情况下,这可以保留空间(或缺少空间);但是,我担心可能会定义一些奇怪的 (La)TeX 命令,从而导致\foo x
和\foo{} x
(或\bar{argument} x
和\bar{argument}{} x
)产生不同的东西。
如果事实证明这是不可能的,或者碰巧不是这样,我也可以就这样放弃;但是如果有如此重要的命令,我可以使用什么替代设备?
编辑感谢下面一位知名 TeXpert 提供的信息,我现在知道第一个选项不再适用:我希望用户能够将任意 TeX 片段插入到他们的脚本中,只要生成的 TeX 整体有意义,这些选项就应该始终按预期工作。你能定义宏,以便随后的缺失与存在{}
确实会产生影响,因此有人将要已经这样做了;因此,透明地插入{}
可能会导致意外的事情发生。
换句话说,我需要一个替代解决方案 - 最好是一个在数学模式下也可以工作的解决方案,但我可以接受特殊处理数学模式,因为数学模式在 TeX 中一直就像一个完全不同的东西,我可以设置适当的限制和内容检查来处理这种情况。
答案1
如果你知道\foo
不接受参数并且不处于数学模式,那么
\foo{}
足够安全。
您还提到了命令确实有参数的情况
\bar{argument}{}
但是在那里它们{}
不可能做任何有用的事情,因为{argument}
无论如何空格都不会被删除,所以在这种情况下最好不要添加它们。
很容易定义\foo
这确实会影响事情
\def\foo{\@ifnextchar\bgroup{yes}{no}}
例如,会让对方\foo a
说“不”和\foo{} a
“是”。但如果你这样做,你大概是有意这样做的。
数学模式下的空括号组{}
会影响间距、比较${}-1$
,$-1$
因此最好不要{}
在数学模式下添加,但由于数学模式下空格会被忽略,因此命令名称后的空格问题无论如何都不适用。
一个可能更安全的选择是使用
\IeC{\foo}
inputenc
这是用于此目的的命令。
aaaa \IeC{\foo} bbbb
将会正常工作
aaa \IeC{\bar}{argument} aaa
\IeC
或多或少\def\IeC#1{#1}
与一些检查有关\protect
(你也可以使用)
如果你还没有加载inputenc
它是:
\def\IeC{%
\ifx\protect\@typeset@protect
\expandafter\@firstofone
\else
\noexpand\IeC
\fi
}
答案2
因为对这个问题的反应已经平息,而且唯一的候选答案——虽然确实有帮助——并没有显示我准备好或能够采用的解决方案,所以我将在这里回答我自己的问题。
稍微改写一下我原来的帖子,手头的问题是:给定一个 TeX 源字符串XYZ
,其中X
和Z
是你控制的部分,Y
是插入的一段任意(但大概是有效的)TeX 代码,你可以不控制,你怎样才能使得(应该以空格开头)无论以什么结尾,Z
空格都会被保留?Y
Y
通过目前的讨论和网络搜索,我相信一般情况下,没有万无一失的方法可以做到这一点除了解析中间部分Y
并对其工作原理进行逆向工程之外,没有其他方法。不用说,这太难了,太容易出错了,而且 — — 程序员会告诉你 — — 也限制了你使用静态代码分析所能做的事情(当然,有针对特定情况的解决方案和针对宏作者的解决方案)。
Y
我采用的解决方案是不采取任何措施,这意味着处理/边界处空格的责任Z
可以说从 转移到Z
,Y
即,无论谁编写宏以包含在我的 TeX 生成软件中以及无论谁使用它编写文本都有责任注意正确的空格处理,软件不会在这里做任何事情(这毕竟可能是一件好事,因为它遵循最小惊讶原则)。