8

It appears that I have a case where \ifx\\#2\\ is false, even though #2 is empty.

Here is the relevant excerpt from the log file, with \tracingcommands and \tracingmacros turned on:

\lastpageref ->\lastpagereftxt 

\lastpagereftxt #1->\pagesLTS@@pageref #1*\END 
#1<-pagesLTS.arabic

\pagesLTS@@pageref #1*#2\END ->\ifx \\#2\\\pagesLTS@@@pageref {#1}\else \expand
after \pagesLTS@@@pagerefstar \fi 
#1<-pagesLTS.arabic
#2<-
{restricted horizontal mode: \ifx}
{false}

As a result, \pagaesLTS@@@pagerefstar is called, and mayhem results. Not least because this happens in the output routine, while typesetting a complicated page header, and the next token happens to be \cr. But that is all beside the point, which is that this can't happen! And yet it does.

My question: How to debug something like this? Assuming it is not a bug in the TeX engine itself, there must be some natural explanation for it. I have verified (using \show) that \ifx really means \ifx at this point, and I assure you that there is no \unless lurking in the code either. And as far as I know, that exhausts the range of possible explanations. Can you come up with more possibilities I can look for?

Edit: I managed to chop the problem files down to size. Here is my input file:

\errorcontextlines=99
\documentclass{blargh}
\begin{document}
(Dummy text to ensure we get a page.)
\end{document}

And my class file, chopped down from over 300 lines to the bare essentials for this problem, and named blarhg.cls:

\NeedsTeXFormat{LaTeX2e}
\LoadClass{report}
\RequirePackage[pagecontinue=false]{pageslts}

\AtBeginDocument{\thispagestyle{Eks}}

\def\PageText#1#2{Page #1 of #2}
\newtoks\firstpageupperright
\firstpageupperright{\PageText{\thepage}{\lastpageref{pagesLTS.arabic}}}

% Taken from pageslts.sty, so I could add \showtokens
\def\pagesLTS@@pageref#1*#2\END{%
  \ifx\\#2\\% no star
    \pagesLTS@@@pageref{#1}%
  \else% star
    \showtokens{"#2"}%
    \expandafter\pagesLTS@@@pagerefstar%
  \fi%
}

\def\ps@Eks{\let\@mkboth\@gobbletwo
     \def\@oddhead{\hfill \vtop to 0pt{\let\\\cr
                            \halign{\strut\hfil####\cr
                                    \relax\tracingall
                                    \the\firstpageupperright\cr
                                    \llap{}\cr}\vss}}
     \def\@oddfoot{}\let\@evenfoot\@oddfoot
     \let\@evenhead\@oddhead}
14
  • 3
    Could you give us a fuller example? Also, could you try \showtokens{"#2"} to see if there is a space or similar as part of #2.
    – Joseph Wright
    Oct 10 '13 at 8:10
  • space would be my guess (there is not one in the log as shown but it may have been trimmed while formatting) Oct 10 '13 at 8:28
  • 1
    Is this in a tabular or other alignment construct? I guess it is since you mention \cr probably the \ifx is expanding durong the pre-scan looking for \omit and the first \\ expands then, and then the second \\ isn't seen until after the cell template is inserted Oct 10 '13 at 8:33
  • @JosephWright I am working on chopping it down to a postable size. \showtokens shows that #2 is indeed empty. Oct 10 '13 at 8:50
  • @DavidCarlisle It is, but inserting \relax in front to stop that didn't help. Besides, wouldn't the expansion of the double backslash [how do I type that so it shows correctly in a comment?] show up in the log? Oct 10 '13 at 8:55
10

Update, in your MWE at the end of the class file change

\let\\\cr

to

\def\\{\cr}

If \\ is \cr then \ifx\\\\ is interesting :-)


The following plain TeX shows \ifx\\\\ expanding to false

{\tracingall
\def\\{\hfill\break}
\def\tablecr{{\global\let\\\relax}}
\halign{%
\expandafter
#\cr
\noexpand\ifx\\\\ A \else B \fi
C\cr
}
}

\bye

{\ifx: (level 1) entered on line 7}
{false}
{\else: \ifx (level 1) entered on line 7}
{the letter B}
3
  • Thanks, that did it. I get the mechanism in your plain TeX example, but I still don't quite understand what happened in my case. It must be related to the exact details of how and when TeX looks for \cr tokens inside a \halign? I had thought it would be too deeply buried in nested macros to make trouble, but I was wrong, evidently. Oct 10 '13 at 10:00
  • It sees the \\ and ends the cell and tests something inside the cell template. If it is \def then it tests the \\ token as intended Oct 10 '13 at 10:28
  • When I have more time to burn, I need to go back to the TeXbook and understand better how the body of \halign is parsed. (It's the details of when and why it “sees the \\” that bother me; I understand that this is what happens.) But thanks again. Oct 10 '13 at 10:44

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.