禁止组内所有排版

禁止组内所有排版

我有一个纯功能性的宏(例如,仅定义其他宏),并且我希望能够以内联方式调用它,而无需排版任何新的段落或空白。

\documentclass{article}
\begin{document}
\def\test{
  \gdef\a{1}

  \gdef\b{1}
}

Hello {\test} world!
\end{document}

输出1

按照此,我能够删除所有\par由空行生成。

\documentclass{article}
\begin{document}
\def\test{
  \gdef\a{1}

  \gdef\b{1}
}

Hello {\let\par\relax\test} world!
\end{document}

输出2

然而,这会导致调用宏的地方出现一些空格。

有没有一种方法可以更普遍地抑制组内的所有排版?

如果没有,那么有没有办法也可以抑制组内的所有空格?

答案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}

输出1

这似乎是一种解决方法,所以如果有人知道更好的解决方案,请告诉我!

编辑:

我创建了宏\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}

输出2

相关内容