在 LaTeX 中,有些命令会处理参数但不产生可见的输出。
例如,命令\label
,或者,如果你使用 color 或 xcolor 包,命令\color
。
当参数的右花括号被标记时,TeX 的读取装置会切换到状态 M(行中间),因此 .tex 源代码中右花括号后面的空格会被标记化为显式空格标记。
如果在源代码中,相应命令前有一个空格(它将成为空格标记),并且该命令参数的结束花括号后也有一个空格,那么您将获得两个显式的空格标记,在水平模式下,如果没有发生换行,则每个空格标记都会导致水平空格。
人们往往不喜欢这样。
因此这些宏具有类似\@bsphack
..的\@esphack
机制:调用宏时,会存储寄存器的值\lastskip
和参数的值。最后,恢复空间因子,如果存储的值表明在调用宏之前已设置空间,则使用 忽略后续空间标记。\spacefactor
\lastskip
\ignorespaces
如果您定义的命令输出可见文本,但在其定义中使用不输出可见文本的命令,则可能会导致意外的输出。
假设我打算编写一个命令,读取一个参数并将其设置为蓝色。
我可以这样写:
\documentclass{article}
\usepackage{xcolor}
\newcommand\blue[1]{{\color{blue}#1}}%
\newcommand\ingroup[1]{{#1}}%
\begin{document}
\Huge
\par\noindent(\ingroup{ Text })
\par\noindent(\blue{ Text })
\par\noindent(\textcolor{blue}{ Text })
\end{document}
但输出结果却有一个微妙之处:
使用该命令时,\ingroup
参数中的前导空格不会被忽略。
使用该命令时,\green
参数中的前导空格将被忽略。 也一样\textcolor
。
确保
- 参数中前导的明确空格标记不会被忽略,并且
- 即使没有前导空格,连字符也会打开吗?
答案1
如果我理解正确,您可以直接使用\relax
来停止\igorespaces
。连字符是可以的,如下所示
\documentclass{article}
\usepackage{xcolor}
\newcommand\blue[1]{{\color{blue}\relax#1}}%
\newcommand\ingroup[1]{{#1}}%
\begin{document}
\Huge
\par\noindent X\dotfill X
\par\noindent(\ingroup{ Text })
\par\noindent(\blue{ Text })
\par\noindent(\blue{ TextTextTextTextTextTextTextText })
\par\noindent(\textcolor{blue}{ Text })
\end{document}
答案2
编辑1:
\ignorespaces
通过宽度为 0pt 的水平跳过停止并启用连字。添加前缀\relax
以确保以下空格标记(如果存在)变为水平粘合。
\documentclass{article}
\usepackage{xcolor}
\newcommand\blue[1]{{\color{blue}\ifhmode\hskip0pt\relax\fi#1}}%
\newcommand\ingroup[1]{{\ifhmode\hskip0pt\relax\fi#1}}%
\newcommand\textandlabel[1]{{\label{#1}\ifhmode\hskip0pt\relax\fi#1}}%
% Let's cheat with the hyphenation of
% Hippopotomonstrosesquippedaliopho–bia :
%\hyphenation{Hip-popo-tomon-stros-esquippedalio-pho-bia}
\hyphenation{Hip-pop-o-to-mon-stros-es-quip-pe-da-li-o-pho-bia}
\begin{document}
\Huge
\par\noindent(\ingroup{ Hippopotomonstrosesquippedaliophobia })
\par\noindent(\ingroup{Hippopotomonstrosesquippedaliophobia})
\par\noindent(\blue{ Hippopotomonstrosesquippedaliophobia })
\par\noindent(\blue{Hippopotomonstrosesquippedaliophobia})
\par\noindent(\textandlabel{ Hippopotomonstrosesquippedaliophobia })
\par\noindent(\textandlabel{Hippopotomonstrosesquippedaliophobia})
\bigskip
\hrule height 1ex
\end{document}