3

This is similar to a previous question (Spaces around Boolean argument to \IfValueT gives -NoValue-) but the answer to that one involved a math mode character and its catcode, whereas in this question there is no such issue.

Consider this MWE:

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn \NewDocumentCommand{\testing}{ o } {% \IfValueTF{ #1 } {#1} {false} }% \ExplSyntaxOff

\begin{document} \testing \end{document}

Without the \ExplSyntaxOn...\ExplSyntaxOff and without any spaces around #1 in \IfValueTF{#1} I get the expected result (false). However, if I put spaces around the argument \IfValueTF{ #1 } I get -NoValue-, unless I also turn on \ExplSyntaxOn...\ExplSyntaxOff. This can't be a mathmode issue or catcode issue like before, at least if it is I don't understand it. Also, if I make the argument to \testing mandatory rather than optional, this doesn't happen, but I still don't get false when I expect to. What is going on in this situation? I know \NewDocumentCommand doesn't require xparse but should I included it anyway and put all my definitions inside \ExplSyntaxOn...\ExplSyntaxOff?

  • 4
    well outside \ExplSyntaxOn spaces matters. \NewDocumentCommand requires xparse, but if you use the new latex-dev format, xparse is already included. – Ulrike Fischer Aug 13 '20 at 18:09
  • 4
    ExplSyntaxOn changes the catcode of space so it's ignored, but you are not using any expl3 code here so it is probably more correct to not use ExplSyntaxOn and not put spurious spaces around #1 so it works. – David Carlisle Aug 13 '20 at 19:29
  • @UlrikeFischer Thank you for telling me about the latex-dev format. I had seen that before but didn't know what it was. – LaTeXereXeTaL Aug 13 '20 at 19:31
  • @DavidCarlisle I wasn't aware space's catcode changes in `\ExplSyntaxOn' so that explains it. – LaTeXereXeTaL Aug 13 '20 at 19:33
  • 5
    @LaTeXereXeTaL changing catcodes is all it does (more or less) – David Carlisle Aug 13 '20 at 19:34
  • 2
  • @campa I have, and it presents a problem. Should document commands be consistently defined inside or outside ExplSyntaxOn...ExplSyntaxOff in preparation for the final LaTeX3 format? It make a big difference in certain cases and I see no consistency in practice. I'm thoroughly confused over what to do about it. – LaTeXereXeTaL Aug 14 '20 at 15:54
  • IMO it's the same as with \makeatletter: you use it if you need kernel macros. As long as you use only user-level commands no expl syntax is necessary. But again IMO, and I'm a lousy programmer. – campa Aug 14 '20 at 16:30
  • If someone will make an answer I'll accept it. – LaTeXereXeTaL Dec 19 '20 at 16:43

2 Answers2

5

Because { #1 } and {#1} are different, unless the spaces get ignored during the tokenization phase.

With the standard category codes, { #1 } is six tokens

{1 <space>10 #6 112 <space>10 }2

In particular, the spaces would be in the replacement text of the macro and the test \IfValueTF{ #1 } will always return true, because, in case the optional argument is missing, the passed argument is <space>-NoValue-<space>, which is different from -NoValue-

On the other hand, after \ExplSyntaxOn the category code of the space is set to 9 and such a character is discarded during the tokenization phase, unless it follows a character of category code 0 (the backslash), so in the expl3 programming environment, the input { #1 } is just four tokens

{1 #6 112 }2

In particular, after \ExplSyntaxOn, one can use “backslash-space” and get the usual token (that is a space in output). The problem of “backslash-space” at the end of a line is solved by setting \endlinechar=32 (the space): TeX removes any trailing space from a line before starting tokenization, but in this case the space is reinserted as the endline character.

egreg
  • 1,121,712
0

As David Carlisle points out, the issue is one of catcodes and how they are affected by \ExplSyntaxOn and \ExplSyntaxOff.