我有一个纯功能性的宏(例如,仅定义其他宏),并且我希望能够以内联方式调用它,而无需排版任何新的段落或空白。
\documentclass{article}
\begin{document}
\def\test{
\gdef\a{1}
\gdef\b{1}
}
Hello {\test} world!
\end{document}
按照此,我能够删除所有\par
由空行生成。
\documentclass{article}
\begin{document}
\def\test{
\gdef\a{1}
\gdef\b{1}
}
Hello {\let\par\relax\test} world!
\end{document}
然而,这会导致调用宏的地方出现一些空格。
有没有一种方法可以更普遍地抑制组内的所有排版?
如果没有,那么有没有办法也可以抑制组内的所有空格?
答案1
(\a
和\b
已经由 LaTeX 内核定义。最好不要覆盖这些定义。因此在下面的例子中我使用了\A
和\B
。)
你可以
- 切换到
\nullfont
以中和字符标记的排版 - 重新定义
\par
为不执行任何操作:
\documentclass{article}
\makeatletter
\newcommand\bspesphackgroup[1]{\@bsphack{\nullfont\let\par=\empty#1}\@esphack}%
\makeatother
\begin{document}
\def\test{
\gdef\A{1}
\gdef\B{1}
}
Hello World!
Hello \bspesphackgroup{\test} World!
\end{document}
但这总体上不会妨碍打字。
例如,或\kern
或\vskip
或\hskip
或\hrule
将\vrule
被执行并产生可见效果。除此之外,font-switching-commands 内部\test
可能会覆盖\nullfont
:
\documentclass{article}
\makeatletter
\newcommand\bspesphackgroup[1]{\@bsphack{\nullfont\let\par=\empty#1}\@esphack}%
\makeatother
\begin{document}
\def\test{
\gdef\A{1}
\gdef\B{1}
\let\par=\endgraf
\par\vskip 2cm
\leavevmode\vrule width 2cm height 2cm\relax
\normalfont This is disturbing!
}
Hello World!
Hello \bspesphackgroup{\test} World!
\end{document}
答案2
不要在\test
宏中添加空格。
% nullprob.tex SE 561601
\documentclass{article}
\begin{document}
\def\test{%
\gdef\a{1}%
%
\gdef\b{1}%
}
Hello {\test}world!
\end{document}
答案3
(\a
和\b
已经由 LaTeX 内核定义。最好不要覆盖这些定义。因此在下面的例子中我使用了\A
和\B
。)
问题似乎在于⟨定义文本⟩控制\test
字标记\par
和空格标记出现在不该出现的地方。
如果嵌套在 的定义\test
(即 的定义\A
和 的定义\B
)内的定义不包含应产生空格标记或\par
-token 的换行符你可以暂时用类别代码为 14 (注释) 的字符来\endlinechar
表示%
,而不是用类别代码为 5 (行尾) 的返回字符来表示,因此 - 取决于 TeX 读取装置的状态 - 要么根本不产生任何标记,要么产生一个空格标记,要么产生一个控制字标记\par
:
\documentclass{article}
\begingroup
\makeatletter
\endlinechar=`\%\relax
\@firstofone{%
\endgroup
\def\test{
\def\A{1}
\def\B{1}
}
}
\show\test
\begin{document}
Hello world!
\show\A
\show\B
Hello \test world!
\show\A
\show\B
\end{document}
控制台输出显示⟨定义文本⟩在之间/后面没有\test
-token\par
或空格标记⟨定义文本⟩和\A
:\B
> \test=macro:
->\def \A {1}\def \B {1}.
l.15 \show\test
?
(./test.aux)
> \A=undefined.
l.20 \show\A
?
> \B=undefined.
l.21 \show\B
?
> \A=macro:
->1.
l.25 \show\A
?
> \B=macro:
->1.
l.26 \show\B
?
答案4
我能够有效地禁用空格,参考 TeXbook 第 76 页。
我通过设置固定宽度的可忽略空间,并在分组后删除空间来实现此\spacefactor=10000
目的\xspaceskip=0.0001pt
。
\documentclass{article}
\begin{document}
\def\test{
\gdef\a{1}
\gdef\b{1}
}
Hello {\spacefactor=10000\xspaceskip=0.0001pt\let\par\relax\test}world!
\end{document}
这似乎是一种解决方法,所以如果有人知道更好的解决方案,请告诉我!
编辑:
我创建了宏\bnosp
和\enosp
,使我能够真正地嵌入这样的宏,而无需\gdef
。\bnosp
保存的值\spacefactor
,\xspaceskip
并\par
在将它们更改为上述值并调用宏之前,将\enosp
它们重置为原始值。
\documentclass{article}
\begin{document}
\def\test{
\def\a{1}
\def\b{1}
}
\def\bnosp{\edef\xspaceskiporig{\the\xspaceskip}\edef\spacefactororig{\the\spacefactor}\let\parorig\par\spacefactor=10000\xspaceskip=0.00001pt\let\par\relax}
\def\enosp{\spacefactor=\spacefactororig\xspaceskip=\xspaceskiporig\let\par\parorig}
Hello \bnosp \test \enosp world!
\a\ \b
\end{document}