1

In some longer redefinition of existing code I am using a construct like

\documentclass{book}
\usepackage{xparse}


\makeatletter
\NewDocumentCommand{\mymacro}{smO{}m}{
    \def\blabla{#1}%
    % several lines later in another macro I use
    \IfBooleanTF{\blabla}{}{}
}

\makeatother

\begin{document}
    \mymacro*{}{}
\end{document}

which works fine with texlive 2018 (xparse 2018-10-17) and lualatex. However, when trying with texlive 2019 (xparse 2019-03-05), I get the following error

! Undefined control sequence.
<argument> \LaTeX3 error:
                Invalid use \IfBooleanTF {\blabla }
l.15     \mymacro*{}{}

What would be the correct way of doing something like this with the new xparse version?


Here is my complete macro definition where the case above occurs: Basically, I am trying to remove the caption from subcaptions including the vertical space. To achieve this, I modified parts of the subcaption package. This works for TL2018 as mentioned above and yields the following output:

enter image description here

Please note that I was particularly looking for a minimal invasive solution with respect to the other code I have. To this end, I thought that just adding a * to the \subcaptionbox is very convenient.

\documentclass{book}

\usepackage{xparse,graphicx,subcaption,mwe,float}

\ExplSyntaxOn
\DeclareExpandableDocumentCommand{\IfNoValueOrEmptyTF}{mmm}
{
    \IfNoValueTF{#1}{#2}
    {
        \tl_if_empty:nTF {#1} {#2} {#3}
    }
}
\ExplSyntaxOff
% This code makes \subcaptionbox*{}{\includegraphics...} print no label and remove the vertical space

\makeatletter
\let\oldsubcaptionbox\subcaptionbox
\RenewDocumentCommand{\subcaptionbox}{smO{}m}{
    \def\subcaptionbox@skip@subcpation{#1}%
    \IfBooleanTF{#1}{%
        \IfNoValueOrEmptyTF{#3}{%
            \oldsubcaptionbox*{#2}{#4}%
        }{%
            \oldsubcaptionbox*{#2}[#3]{#4}%
        }%
    }{%
        \IfNoValueOrEmptyTF{#3}{%
            \oldsubcaptionbox{#2}{#4}%
        }{%
            \oldsubcaptionbox{#2}[#3]{#4}%
        }%
    }{%
    }%
}

\long\def\caption@iiibox#1#2#3#4[#5]#6{%
    \begingroup
    #1*% set \caption@position
    \caption@iftop{%
        \endgroup
        \parbox[t]{#4}{%
            #1\relax
            \caption@setposition t%
            \vbox{\caption#2{#3}}%
            \captionbox@hrule
            \csname caption@hj@#5\endcsname
            #6}%
    }{%
        \endgroup
        \parbox[b]{#4}{%
            #1\relax
            \caption@setposition b%
            \csname caption@hj@#5\endcsname
            #6%
            \captionbox@hrule%
            \IfBooleanTF{\subcaptionbox@skip@subcpation}{%
                \IfNoValueOrEmptyTF{#3}{}{%
                    \vtop{\caption#2{#3}}%
                }%
            }{%
                \vtop{\caption#2{#3}}%
            }%
        }%
}}
\makeatother

\begin{document}
    \begin{figure}[H]
        \subcaptionbox{}{\includegraphics[width=0.5\linewidth]{example-image-a}}%
        \subcaptionbox{}{\includegraphics[width=0.5\linewidth]{example-image-b}}%
    \end{figure}
    Blabla
    \begin{figure}[H]
        \subcaptionbox*{}{\includegraphics[width=0.5\linewidth]{example-image-a}}%
        \subcaptionbox*{}{\includegraphics[width=0.5\linewidth]{example-image-b}}
    \end{figure}
    BlaBla
\end{document}
  • Why were you saving the argument in a macro in the first place? – Joseph Wright Mar 28 at 23:08
  • @JosephWright I later redefine another macro where I use \blabla. I did not know another way of doing something like this. – bonanza Mar 28 at 23:09
  • @JosephWright, I added my full macro as requested by Kurt. I thought it was a fundamental thing within xparse that changed... Should I now change the title of the question as it may now look like I am more interesting in achieving the objective of removing the subcaption/vertical space? – bonanza Mar 29 at 8:43
  • 1
    The usage of \IfNoValueOrEmptyTF doesn't make sense. If you use O{} there is no possibility for the -NoValue- flag, because it defaults to be empty. Also using \expandafter\IfBooleanTF\expandafter{\subcaptionbox@skip@subcpation} should work (untested). – Skillmon Mar 29 at 10:30
  • 1
    @bonanza using o as argument specifier and then \IfNoValueTF{#3}{\oldsubcaptionbox{#2}{#4}}{\oldsubcaptionbox{#2}[#3]{#4}} in the code should work, too. – Skillmon Mar 29 at 11:07
3

You're making your life difficult. If there is * and the argument is empty, just issue the last argument, possibly inside a box of the specified width.

\documentclass{book}

\usepackage{xparse,graphicx,subcaption}

\let\oldsubcaptionbox\subcaptionbox

\ExplSyntaxOn
\NewExpandableDocumentCommand{\IfEmptyTF}{mmm}
 {
  \tl_if_empty:nTF { #1 } { #2 } { #3 }
 }
\ExplSyntaxOff

\RenewDocumentCommand{\subcaptionbox}{smom}{%
  \IfBooleanTF{#1}
    {%
     \IfEmptyTF{#2}
      {#4}
      {\IfNoValueTF{#3}{\oldsubcaptionbox*{#2}{#4}}{\oldsubcaptionbox*{#2}[#3]{#4}}}%
    }
    {%
     \IfNoValueTF{#3}{\oldsubcaptionbox{#2}{#4}}{\oldsubcaptionbox{#2}[#3]{#4}}%
    }%
}

\begin{document}

\begin{figure}[htp!]

\subcaptionbox{zzz}{\includegraphics[width=0.5\linewidth]{example-image-a}}%
\subcaptionbox{zzz}{\includegraphics[width=0.5\linewidth]{example-image-b}}

\end{figure}

Blabla

\begin{figure}[htp!]

\subcaptionbox*{zzz}{\includegraphics[width=0.5\linewidth]{example-image-a}}%
\subcaptionbox*{zzz}{\includegraphics[width=0.5\linewidth]{example-image-b}}

\end{figure}

Blabla

\begin{figure}[htp!]

\subcaptionbox*{}{\includegraphics[width=0.5\linewidth]{example-image-a}}%
\subcaptionbox*{}{\includegraphics[width=0.5\linewidth]{example-image-b}}

\end{figure}

BlaBla

\end{document}

enter image description here

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.