为什么 \xspace 在预期插入后面的空格时却不总是插入?

为什么 \xspace 在预期插入后面的空格时却不总是插入?

在 MWE 中,\xspace在 的第一个测试中正确地插入了一个空格\foo,但是在第二个测试中,当它后面跟着一个短划线时,却没有插入空格。

有办法解决这个问题吗?

\documentclass{article}
\usepackage{xspace}
\newcommand{\foo}{FOO\xspace}

\begin{document}
\foo BAR

\foo -- why no space here?

\end{document}

输出:

在此处输入图片描述

答案1

连字符-位于xspace的例外列表1中,其中未添加空格。您可以使用以下命令将其删除\xspaceremoveexception{-}

\documentclass{article}
\usepackage{xspace}
\newcommand{\foo}{FOO\xspace}

\begin{document}
\foo BAR

\foo -- why no space here?

\xspaceremoveexception{-}
\foo -- why no space here?

\end{document}

在此处输入图片描述


正如 David 在评论中所说,xspace未检测到空间据它\foo--bar所知\foo --bar确切地相同,因为在\xspace执行其操作时,TeX 已经标记了宏和下一个字符,并且忽略了其间的任何空格。

xspace向前看,看看下一个字符前面是否应该有一个空格,并且关于-如果需要,则插入该空格。

使用上面的解决方案,我们改变了\xspace的异常列表,因此它将总是,从现在开始,在 之前添加一个空格-,即使您不想这样做。

还不满意吗?

如果你想破解\xspace的规则,你可以从手册中给出的例子开始:

\documentclass{article}
\usepackage{xspace}
\newcommand{\foo}{FOO\xspace}

\begin{document}
\foo BAR

\foo -- why no space here?

\xspaceremoveexception{-}
\foo -- why no space here?

\xspaceremoveexception{-}% repeated, for the sake of copy-pasting
\makeatletter
\renewcommand*\@xspace@hook{%
  \ifx\@let@token-%
    \expandafter\@xspace@dash@i
  \fi
}
\def\@xspace@dash@i-{\futurelet\@let@token\@xspace@dash@ii}
\def\@xspace@dash@ii{%
  \ifx\@let@token-%
  \else
    \unskip
  \fi
  -%
}
\makeatother

\foo - why no space here?

\foo -- why no space here?

\end{document}

在此处输入图片描述

David 在那里演示了如何使用来\@xspace@hook检查下一个字符为--,如果不是,则删除插入的空格\xspace。这可以扩展以检查更多字符2,但这值得吗?

我的看法:xspace我在写学士论文的时候用了几个月。它可以帮助你记住打字,\foo{}或者\foo\在你习惯忘记打字的时候帮助你。但随着时间的推移,你需要不同的东西(就像你在这里做的那样),而且它会比它应该花费更多的时间。这是我的观点(显然也是 David 的观点 :P)。


1默认情况下,例外列表包含:

,.'/?;:!~-)\ \/\bgroup\egroup\@sptoken\space\@xobeysp\footnote\footnotemark
%        ↑ Here it is :)

2显然我没有更好的事情可做 :)

以下\@xspace@hook检查:

  1. 如果后面跟着\foo一个-。如果是,则删除插入的空格\xspace并返回;
  2. 如果后面跟着的\foo--。如果是,它会向前查找空格。如果找到空格,则\xspace保留 插入的空格,否则将其删除。即:

    \foo-bar  % prints FOO-bar
    \foo-- bar% prints FOO -- bar
    \foo--bar % prints FOO--bar
    

(请注意,无论哪种方式,由于 TeX 的解析规则,后面的空格都\foo无关紧要)。

在此处输入图片描述

\documentclass{article}
\usepackage{xspace}
\newcommand{\foo}{FOO\xspace}

\begin{document}
\pagenumbering{gobble}
\foo BAR

\foo -- why no space here?

\xspaceremoveexception{-}
\foo -- why no space here?

\xspaceremoveexception{-}
\makeatletter
\renewcommand*\@xspace@hook{%
  \begingroup
  \ifx\@let@token-%
    \obeyspaces
    \expandafter\@xspace@dash@i
  \fi
}
\def\@xspace@dash@i-{\futurelet\@let@token\@xspace@dash@ii}
\def\@xspace@dash@ii{%
  \ifx\@let@token-%
    \expandafter\@xspace@dash@sp@i
  \else
    \unskip
    -%
    \endgroup
  \fi
}
\def\@xspace@dash@sp@i-{\futurelet\@let@token\@xspace@dash@sp@ii}
\def\@xspace@dash@sp@ii{%
  \ifx\@let@token\space%
  \else
    \unskip
  \fi
  --%
  \endgroup
}
\makeatother

\foo - why no space here?

\foo -- why no space here?

\foo--why no space here?

\end{document}

相关内容