24

Perhaps this question has been asked before, but I could not track the correct question down.

I stumbled accidentally over this feature:

Say, I want to make a

\newcommand{\supersophisticatedmacroname}{Hello}

definition and then something like an end-of-environment command

\endsupersophisticatedmacroname

but this fails:

! LaTeX Error: Command \endsupersophisticatedmacroname already
defined.
               Or name \end... illegal, see p.192 of the manual.

I could understand the error message, if I would say \newcommand{\endtable} etc, as those names are defined of course, marking the end of environments. But I am pretty sure, that there is no such command (think of the macro name ;-)) in any sensible class.

Does LaTeX prevent definition of commands beginning with \end...? Why? Just to make the conceptual implementation of environments easier?

Here is a non-MWE

\documentclass{book}

\newcommand{\supersophisticatedmacroname}{Hello}%

\newcommand{\endsupersophisticatedmacroname}{World}% fails
\newcommand{\endandnowforsomethingcompletelydifferent}{World}% fails too.


\begin{document}%
Hello World

\supersophisticatedmacroname


\end{document}

Plain TeX does not complain:

\def\supersophisticatedmacroname{Hello}%
\def\endsupersophisticatedmacroname{World}%



\supersophisticatedmacroname

\bye

Edit

As Manuel states in his comment,

\def\endsupersophisticatedmacroname{...}

will even work in LaTeX.

Edit

There are four (!!) good answers to my question -- I have thought about accepting one and I know, this means, I must 'disappoint' three other, equally highly qualified users here.

  • 1
    I never had a problem with that (\end…), but what I hope is solved in LaTeX3 is the hability to have \quote{…} and \begin{quote} … \end{quote} by default without further tricks, with a different namespace. – Manuel Sep 5 '14 at 15:38
  • @Manuel: I detected this accidentally... I was quite astonished – user31729 Sep 5 '14 at 15:43
  • 1
    There's certainly some code in latex.ltx (\@qend & co.) that certainly indicate that yes, LaTeX does prevent the creation of those macros. By the way, the “plainer” TeX \def\end… doesn't complain in LaTeX either :) – Manuel Sep 5 '14 at 15:45
  • @Manuel: Yes, I detected that \def\end... way already. I should have looked into latex.ltx of course ;-) I will add your comment as further information. – user31729 Sep 5 '14 at 15:47
  • 2
    "Or name \end... illegal, see p.192 of the manual." What did p.192 of the manual say? – Joshua Taylor Sep 6 '14 at 21:59
26

As others have noted, you may not define any commands starting with \end. The reason is that you may use any latex2e command as an environment (some don't like that design, but that's the way it was designed) so you can go

\begin{small}....\end{small}

even though \endsmall is not normally defined.

If you were allowed to go

\newcommand\endsmall{zzzz}

just if \endsmall is not defined, then you would have been allowed to redefine the small environment with no warning.

  • Also as others have noted (tex.stackexchange.com/questions/199692/…), though, perhaps it's better to say "you may not use LaTeX's definition mechanisms to define any commands starting with \end". You certainly can define them by cutting out the LaTeX middleman and using \def directly. – LSpice Sep 6 '14 at 7:17
  • @LSpice as David said this is a deliberate, documented design decision, so it is somewhat beside the point that you can change or overwrite anything in a macro langage like LaTeX. – Frank Mittelbach Sep 10 '14 at 7:21
20

The command \newcommand{<cs>}... does \@ifdefinable{<cs>} for testing if the control sequence is available; the definition is

\long\def\@ifdefinable #1#2{%
      \edef\reserved@a{\expandafter\@gobble\string #1}%
     \@ifundefined\reserved@a
         {\edef\reserved@b{\expandafter\@carcube \reserved@a xxx\@nil}%
          \ifx \reserved@b\@qend \@notdefinable\else
            \ifx \reserved@a\@qrelax \@notdefinable\else
              #2%
            \fi
          \fi}%
         \@notdefinable}

The first bit

 \edef\reserved@a{\expandafter\@gobble\string #1}

produces the macro name without the backslash (at least if \escapechar has its usual value), storing it in \reserved@a; then this is fed to \@ifundefined. If the requested macro passes the test,

\edef\reserved@b{\expandafter\@carcube \reserved@a xxx\@nil

is performed, which stores in \reserved@b the first three characters in the macro name (or fills it with x's to arrive at three anyway). Then \reserved@b is compared to \@qend whose expansion is

% latex.ltx, line 794:
\edef\@qend{\expandafter\@cdr\string\end\@nil}

that is, it contains the stringified (category code 12) version of end. In this case it calls \@notdefinable; the same it does if \reserved@a contains exactly \relax (not to redefine this primitive).

The second argument is the (massaged) definition text, that is so gobbled if the full test is not passed.

You might redefine \@qend to be anything that can't be produced by \string, say \def\@qend{$}, and be able to define commands whose name starts with end. Don't.

20

Short answer: yes, LaTeX2e does reserve these names, at least as far as \newcommand is concerned. The TeX \def primitive has no such restriction and may be used if you really want to define a command starting \end....

LaTeX2e implements environment foo by looking for a macro \foo and possibly one \endfoo. These are created for example by

\newenvironment{foo}{}{}

To prevent issues which could arise from doing

\newcommand\endfoo{}

this is checked for and specifically blocked. Imagine for example you didn't know about the implementation and did exactly the above: you'd have a surprising result for one of the two cases without the check.

The issue here really is of course that LaTeX2e is rather 'permissive' about what counts as an environment. There is no specific namespace for the implementations and you don't have to define \endfoo at all. The 'LaTeX3 vision' is to address this properly: if you look at xparse it does have the idea of a separate namespace built in, but of course at present has to define LaTeX2e-compatible commands.

  • I don't like the word "workaround" in this context. For 2e this is not a workaround but something that breaks the 2e design hand possibly hurts later on, e.g. if \endfoo was defined by the user he/she later mights load a package that defines environment "foo". Of course Leslie's original decision is questionable in todays light, but we have to see it being driven by the limitations of the engine back then (even pool size was an issue). – Frank Mittelbach Sep 10 '14 at 7:26
  • @FrankMittelbach I've altered that sentence. There are cases where \end... is the best name provided you know what you are doing. – Joseph Wright Sep 10 '14 at 8:45
17

In the LaTeX2e kernel latex.ltx, \newcommand{<cs>} checks whether it is possible to define <cs> via a macro called \@ifdefinable. Its definition, from the LaTeX2e kernel documentation/source2e (section 11.3 Command definitions, p 23), has the following description:

\@ifdefinable{NAME}{<YES>}

Executes <YES> if the user is allowed to define \NAME, otherwise it gives an error. The user can define \NAME if \@ifundefined{NAME} is true, NAMErelax and the first three letters of NAME are not end, and if \endNAME is not defined.

  • Was just looking for that :-) – Joseph Wright Sep 5 '14 at 15:49
  • @Werner: I learned something just now ... thanks about source2e information. – user31729 Sep 5 '14 at 15:52

Your Answer

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