2

According to Leslie Lamport in his 1985 book "LaTeX user's guide and reference manual" the macros \begin... \end form a group whereby code within the group is not visible from outside it. Any code redefinitions are local to the \begin \end grouping. I have found a problem with this.

% epigraphprob.tex SE 558448

\documentclass{report}
\usepackage{epigraph}
\begin{document}
\epigraph{text}{source}  % first epigraph
%...
%{
\begin  % local redefinitions
  \setlength{\epigraphwidth}{0.7\textwidth} % make it wider
  % other changes
  \epigraph{text2}{source2}  % second epigraph
\end   % forget local redefinitions
%}
%...
\epigraph{text3}{source3}  % third epigraph typeset as per first epigraph
%...
\end{document}

The above MWE fails with the message "! LaTeX Error: Environment u n\relax defined".

If I replace \begin ... \end with { ... } then it works.

Anybody got any idea what causes this mismatch and how to fix it?


The question was not a joke or a troll. On page 27 of his book Lampert says:

The scope of a declaration is ended by an \end command or a right brace. In the input, braces and \begin and \end commands must come in matched pairs. The scope of a declaration is ended by the first \end or } whose matching \begin or { precedes the declaration.

No mention of the commands taking an argument.

I had vague memories of there being simple commands which enclosed a declaration. Mico suggested \begingroup with \endgroup or \bgroup with \egroup. Both of these pairings worked with one requiring less typing than the other. There was no mention of these in Lamport.

I'm getting old and forgetfull but I should have read Lamport more carefully and then looked at other documents but even the LaTeX Companion barely mentions them except in regard to problems and error messages. GOM.

6
  • 7
    Who are you imitating Peter Wilson? Of course \begin and \end take an argument of the environment name. Aug 17 '20 at 19:34
  • 3
    you have \begin{\setlength} matched with \end{\epigraph} so it's not surprising that you get weird low level errors. Aug 17 '20 at 20:03
  • 2
    I think you meant to write \begingroup and \endgroup (or maybe \bgroup and \egroup), not blank \begin and \end.
    – Mico
    Aug 17 '20 at 20:23
  • 1
    @Mico Would you like to make your comment into an answer. It worked for me. Aug 18 '20 at 18:04
  • @PeterWilson - Done :-)
    – Mico
    Aug 18 '20 at 22:37
7

Both \begin and \end are macros that require an argument:

\DeclareRobustCommand\begin[1]{%
  \@ifundefined{#1}%
    {\def\reserved@a{\@latex@error{Environment #1 undefined}\@eha}}%
    {\def\reserved@a{\def\@currenvir{#1}%
     \edef\@currenvline{\on@line}%
     \csname #1\endcsname}}%
  \@ignorefalse
  \begingroup\@endpefalse\reserved@a}

The current definition of \end is a bit more complicated to make it robust:

% latex.ltx, line 5654:
\edef\end
  {\unexpanded{%
     \romannumeral
       \ifx\protect\@typeset@protect
       \expandafter       %1
         \expandafter        %2
       \expandafter       %1
           \expandafter         %3 expands the \csname inside \end<space>
       \expandafter       %1
         \expandafter        %2  expands \end<space>
       \expandafter       %1     expands the \else
           \z@
       \else
         \expandafter\z@\expandafter\protect
       \fi
   }%
   \expandafter\noexpand\csname end \endcsname
  }
\@namedef{end }#1{%
  \csname end#1\endcsname\@checkend{#1}%
  \expandafter\endgroup\if@endpe\@doendpe\fi
  \if@ignore\@ignorefalse\ignorespaces\fi}

The description in the manual doesn't mention the arguments, but as both macros (actually the ones with a trailing space in their name, but it's just implementation detail) require an argument, TeX will look for it using its standard rules.

With your code, the argument of \begin is \setlength and the argument of \end is \epigraph. Just for fun, \@ifundefined{\setlength} returns true, so TeX does

\def\reserved@a{\@latex@error{Environment \setlength undefined}\@eha}

and will expand it after doing \begingroup\@endpefalse. Since the definition of \setlength is

% latex.ltx, line 2365:
\def\setlength#1#2{#1 #2\relax}

you get

Environment u n\relax defined

A weird error message that results from previous errors.

Environments do form a group, because of the \begingroup in the definition of \begin, which is matched by \endgroup in the definition of \end. But if the argument is improper, expect problems.

1
  • Not mentioned in that particular sentence (on page 25) but just an inch of paper above that! Aug 17 '20 at 23:47
7

In case this question is legit. If anyone wants to use the syntax of environments to get local grouping for temporary assignments, without any particular environment defined, then it is a good idea to use name of the setting as the environment name, because commands can be used as environments that way. This is nicer than braces for complicated documents because it shows and forces proper matching ("you are in a maze of curly braces, all alike"). For the sample in the question, the method would use

\begin{setlength}{\epigraphwidth}{0.7\textwidth} % locally make it wider
  % other localized changes
  \epigraph{text2}{source2}  % second epigraph
\end{setlength}   % forget local 

It looks a bit clunky for \setlength, but makes great sense for some settings, like \begin{bfseries}...\end{bfseries}.

Some assignments need to be active at the end of the paragraph to work their best, in which case the "end" component could be defined to end the paragraph before ending the local group, as in

% for font command \Large used as an environment
\def\endLarge{\par}
...
\begin{Large}
This is an important announcement...
\end{Large}
1

(At the OP's request, I've reposted my earlier comment as an answer.)

As the other answers have already noted, LaTeX's \begin and \end directives require an argument -- which, naturally, should be identical in order for them to initiate and terminate a valid LaTeX environment. Every non-trivial LaTeX document contains at least one environment -- the document environment (pun intended).

If the objective is not to execute an entire environment but "merely" to define a group -- in the TeX-specific sense of the word "group" -- one can employ either \begingroup and \endgroup or, in many but not all circumstances, \bgroup and \egroup. (\bgroup and \egroup are defined as { and }, respectively; these are, of course, the characters usually (nearly always?!) set aside to function as TeX's grouping characters.) \begingroup and \bgroup are not synonyms, by the way. This matters, for instance, if one is in math mode. As noted in @egreg's answer, the definitions of \begin and \end contain \begingroup and \endgroup directives, respectively; these directives serves to ensure that the contents of a LaTeX environment form a TeX group.

For more information on the differences between \begingroup/\endgroup and \bgroup/\egroup, please see When should one use \begingroup instead of \bgroup?

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.