6

Here is my 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}

Here's the result I see: enter image description here

Note that there's extra space after the "X" in the second case. This appears to be caused by the \label command. Of course, I'd like it to not be there, but I'm not sure where to begin with diagnosing the problem.

4

You have to delay the typesetting until possibly \label has appeared. Assuming these exercises aren't inside lists, the simplest way is using \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}

enter image description here

With {\setbox0=\lastbox} we remove the indentation box; since \label doesn't start a paragraph, the space after it is ignored.

Possibly simpler: use a theorem-like environment.

\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}
4

This is the case because \label was created in such a way that it doesn't introduce a second white space after it and doesn't change the spacefactor (a TeX internal variable which specifies how much the current space might be stretched to get alignment, it is set dependent on the last character prior to that space). This is done by \@bsphack and \@esphack. Unfortunately this ends the scope of \ignorespaces as there was a non-space token, and the space after \label{} is in fact inserted because there was no space prior to \label (else there would be an \ignorespaces inserted by \@esphack).

The following checks whether exercise is followed by a \label and if so eats the space after \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}

enter image description here

  • Wow. That's a surprise. One more weird LaTeXism, I guess. – Derek Aug 5 '18 at 20:53
  • 2
    @Derek not so much. Considering the most use cases this is what \label and the like (so all those \@bsphack \@esphack macros) should most reasonably do. You don't want it to eat all the space around it, just not introduce a second space. – Skillmon Aug 5 '18 at 20:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.