在开始用户定义环境后使用 \label 时出现神秘的水平空格

在开始用户定义环境后使用 \label 时出现神秘的水平空格

这是我的 MWE:

\documentclass{article}
\RequirePackage{expl3}
\RequirePackage{xparse}

\ExplSyntaxOn
\newcounter{exercise}
\NewDocumentEnvironment{exercise}{}
{
  \refstepcounter{exercise}
  \par\noindent
  \theexercise.\hspace{4pt}X
  \ignorespaces
}
{
  \par
  \ignorespacesafterend
}
\ExplSyntaxOff

\begin{document}

\begin{exercise}
  If $H$ is a subgroup of $G$, then something.
\end{exercise}

\begin{exercise}\label{A}
  If $H$ is a subgroup of $G$, then something.
\end{exercise}

\end{document}

这是我看到的结果: 在此处输入图片描述

请注意,在第二种情况下,“X”后面有一个多余的空格。这似乎是由命令引起的\label。当然,我希望它不存在,但我不知道从哪里开始诊断问题。

答案1

您必须延迟排版,直到可能\label出现为止。假设这些练习不在列表中,最简单的方法是使用\everypar

\documentclass{article}
\usepackage{expl3}
\usepackage{xparse}
\usepackage{showframe}

\ExplSyntaxOn
\newcounter{exercise}
\NewDocumentEnvironment{exercise}{}
 {
  \refstepcounter{exercise}
  \par
  \everypar={{\setbox0=\lastbox}\theexercise.\hspace{4pt}\everypar={}}
 }
 {
  \par
  \ignorespacesafterend
 }
\ExplSyntaxOff

\begin{document}

\begin{exercise}
  If $H$ is a subgroup of $G$, then something.
\end{exercise}

\begin{exercise}\label{A}
  If $H$ is a subgroup of $G$, then something.
\end{exercise}

\end{document}

在此处输入图片描述

我们{\setbox0=\lastbox}删除了缩进框;由于\label不开始段落,因此其后的空格将被忽略。

可能更简单:使用类似定理的环境。

\documentclass{article}
\usepackage{amsthm}
\usepackage{showframe}

\newtheoremstyle{exercise}
  {0pt}       % ABOVESPACE
  {0pt}       % BELOWSPACE
  {\upshape}  % BODYFONT
  {0pt}       % INDENT (empty value is the same as 0pt)
  {}          % HEADFONT
  {.}         % HEADPUNCT
  { }         % HEADSPACE
  % CUSTOM-HEAD-SPEC follows
  {\thmnumber{#2}}

\theoremstyle{exercise}
\newtheorem{exercise}{}

\begin{document}

\begin{exercise}
  If $H$ is a subgroup of $G$, then something.
\end{exercise}

\begin{exercise}\label{A}
  If $H$ is a subgroup of $G$, then something.
\end{exercise}

\end{document}

答案2

这是因为\label创建的方式不会引入第二后面有空格,并且不会改变 spacefactor(TeX 内部变量,指定当前空间可以拉伸多少才能对齐,它取决于该空间之前的最后一个字符)。这是通过 和 完成的\@bsphack\@esphack不幸的是,这会结束 的范围,\ignorespaces因为有一个非空格标记,并且后面的空格\label{}实际上是插入的,因为 之前没有空格\label(否则 会\ignorespaces插入一个\@esphack)。

下面检查 后面是否exercise跟着\label,如果是,则占用 后面的空格\label{}

\documentclass{article}
\RequirePackage{expl3}
\RequirePackage{xparse}

\ExplSyntaxOn
\makeatletter
\newcounter{exercise}
\NewDocumentEnvironment{exercise}{}
{
  \refstepcounter{exercise}
  \par\noindent
  \theexercise.\hspace{4pt}X
  \@ifnextchar\label
    {\eatlabel}{\ignorespaces}
}
{
  \par
  \ignorespacesafterend
}
\newcommand\eatlabel{}
\def\eatlabel\label#1{\label{#1}\ignorespaces}
\makeatother
\ExplSyntaxOff

\begin{document}

\begin{exercise}
  If $H$ is a subgroup of $G$, then something.
\end{exercise}

\begin{exercise} \label{A}
  If $H$ is a subgroup of $G$, then something.
\end{exercise}

\end{document}

在此处输入图片描述

相关内容