0

Consider the following MWE, reproducing the problem from this question:

\documentclass{article}

\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}

\usepackage{kotex}
\usepackage{amsmath}

\newtheorem{Cvičení}{Cvičení}

\begin{document}

\tracingmacros2\tracingcommands2

\begin{align*}
    a = b
\end{align*}

\end{document}

The problem here is the use of special characters as an environment name in \newtheorem. While this was quickly identified, I found the emerging warning and error somewhat obscure:

! Missing \endcsname inserted.
<to be read again> 
                   \protect 
l.16 \end{align*}

The control sequence marked <to be read again> should
not appear between \csname and \endcsname.

and

! TeX capacity exceeded, sorry [input stack size=5000].
\@spaces ->\space 
                  \space \space \space 
l.16 \end{align*}

If you really absolutely need more capacity,
you can ask a wizard to enlarge me.

These errors appear without the use of \begin{Cvičení}, but only when kotex is loaded.


I investigated using the \tracing commands in the MWE above and found the relevant part of the log file to be lines 5038 ff:

\@elt #1->\global \csname c@#1\endcsname \the \csname c@#1\endcsname 
#1<-CviÄení
{\csname}

Ä#1->\ifcsname u8:\string Ä\string #1\endcsname \csname u8:\string Ä\string #1\
expandafter \endcsname \else \expandafter \unihangul@two@octets \expandafter Ä\
expandafter #1\fi 
#1<-
{\ifcsname}
{\string}
{\string}
{true}
{\csname}
{\string}
{\string}
{\expandafter}
{\else}

\u8:Ä ->\IeC {\v c}

\IeC ->\ifx \protect \@typeset@protect \expandafter \@firstofone \else \noexpan
d \IeC \fi 
{\ifx}
{true}
{\expandafter}
{\else}

\@firstofone #1->#1
#1<-\v c

\v ->\T1-cmd \v \T1\v 

\T1-cmd #1->\ifx \protect \@typeset@protect \@inmathwarn #1\else \noexpand #1\e
xpandafter \@gobble \fi 
#1<-\v 
{\ifx}
{true}

\@inmathwarn #1->\ifmmode \@latex@warning {Command \protect #1 invalid in math 
mode}\fi 
#1<-\v 
{\ifmmode}
{true}

\@latex@warning #1->\GenericWarning {\space \space \space \@spaces \@spaces \@s
paces }{LaTeX Warning: #1}
#1<-Command \protect \v  invalid in math mode

\GenericWarning ->\csname m@gobble\iffirstchoice@ \else 4\fi \endcsname \protec
t \GenericWarning  
{\csname}
{\iftrue}
{true}
{\else}

\m@gobble ->

! Missing \endcsname inserted.
<to be read again> 
                   \protect 
l.16 \end{align*}

The control sequence marked <to be read again> should
not appear between \csname and \endcsname.


\GenericWarning  #1#2->\begingroup \def \MessageBreak {
#1}\set@display@protect \immediate \write \@unused {
#2\on@line .
}\endgroup 
#1<-\space \space \space \@spaces \@spaces \@spaces 
#2<-LaTeX Warning: Command \protect \v  invalid in math mode

\space -> 

\space -> 

\space -> 

\@spaces ->\space \space \space \space 

\space -> 

\space -> 

\space -> 

\space -> 

\@spaces ->\space \space \space \space 

\space -> 

\space -> 

\space -> 

\space -> 

\@spaces ->\space \space \space \space 

\space -> 

\space -> 

\space -> 

\space -> 

\set@display@protect ->\let \protect \string 
{\string}

\v ->\T1-cmd \v \T1\v 

What I gathered from this is the following:

  1. The align* environment causes many counters to be globally updated using \@elt, including \c@Cvičení (which appears as \c@CviÄení­ in the log file).

  2. Ä is an active character (this seems to be the part that kotex is responsible for) and eventually results in a \v being expanded.

  3. Since \v cannot be used in math mode, LaTeX tries to warn me about that.

  4. Then something goes wrong. \csname m@gobble\iffirstchoice@ \else 4\fi \endcsname \protect \GenericWarning results in \m@gobble being expanded to nothing (despite its name not gobbling anything), but then TeX seems to still want to read a \csname and complains about \protect (leading to the warning we see).

    • This happens only this one time, despite this same line of code being expanded over and over again in the coming loop.
  5. LaTeX now proceeds expanding \GenericWarning and finally tries to write "Command \v invalid in math mode" to the log file by essentially saying \let\protect\string and then writing Command \protect \v invalid in math mode to the log file. According to the log file ({string}) this should have worked, but subsequently \v is expanded anyway.

  6. This causes an infinite loop that goes on until TeX's memory capacity is exceeded, leading to the final error.


So, my questions are

  • Why does the issue in 4. only appear this one time and not at subsequent expansions of the same line of code?

  • Why does basically executing \let\protect\string \protect\v not have the desired effect in 5.?

2

First question: Why does the issue in 4. only appear this one time and not at subsequent expansions of the same line of code?

The warning said "Missing \endcsname inserted. ... The control sequence marked should not appear between \csname and \endcsname." So the problem is that LaTeX was still waiting for \endcsname, because the first \endcsname in \@elt is never reached but \relax (disguised under the name \protect here) is not allowed in a csname. This is no longer a problem awterwards because like the message says TeX actually inserts a \endcsname before showing you the error, so at a later point we are no longer in a csname, so \relax (or \protect) is valid.

Second question: Why does basically executing \let\protect\string \protect\v not have the desired effect in 5.?

For this you have to look further up in the log file: About 10 lines before expanding the first \@elt, there is a line {\xdef}. So we are in a \xdef definition (of \@gtempa). Inside the expanded value of \xdef (or \edef) unexpandable commands like \let are allowed, but kept as is without evaluation.

So in this context \let\protect\string\protect\v will not evaluate the \let or \protect, but will try to expand for expandable commands \string and \v which causes the endless recursion.

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.