1

In my program below, I defined a function \checklist that takes to optional arguments and one compulsory argument. The function works as expected.

Then, I would like to define another function \othercheck that calls \checklist:

  • e.g., \othercheck[10]{blah} should call \checklist[1][0]{blah}.
  • e.g., \othercheck[11]{blah} should call \checklist[1][1]{blah}.

Why does it return the following error? I understand that it is probably because a string is fed instead of a number but I did not manage to overcome that using some conversion strategies (etoolbox, etc).

! Missing number, treated as zero. \let l.39 ...check[01]{Second square should be checked}

  \documentclass{article}
  \usepackage{etoolbox}
  \usepackage{wasysym} 
  \usepackage{xparse}

  \usepackage{xargs}
  \newcommandx{\checklist}[3][1=0, 2=0]{
   \ifnumcomp{#1}{=}{0}{\Square}{\XBox}%
   \ifnumcomp{#2}{=}{0}{\Square}{\XBox}%
   #3%
   }%

  \usepackage{xstring}
  \newcommandx{\othercheck}[2][1=]{%
   % if no optional argument
   \ifstrempty{#1}{\checklist{#2}}%
   {%
    % if optional argument
    \def\varA{\StrMid{#1}{1}{1}}
    \def\varB{\StrMid{#1}{2}{2}}
    \checklist[\varA][\varB]{#2}
    }%
   }%
  
  \begin{document}
  \checklist{Check this} % OK
  \checklist[1][0]{Check that} % OK
  \othercheck{Default: nothing checked} % OK
  %\othercheck[01]{Second square should be checked} % <---- crashes
  \end{document}
1
  • 3
    Additionally try typing out the arguments for \checklist say using \typeout{\meaning #1} etc. You'll notice that \ifnumcomp is given \StrMid {01}{1}{1} which in it self is not a number and thus cannot be compared using \ifnumcomp. Remember that many of these macros does not expand their input. Perhaps you should start over and explain what exactly the end goal is? Then people can suggest modern solutions.
    – daleif
    Commented Feb 2, 2023 at 13:59

1 Answer 1

1

I'd not use xargs: with ltcmd (formerly xparse) it's much easier.

The error is in \def\varA{...}. See the proper way below.

\documentclass{article}
\usepackage{etoolbox}
\usepackage{wasysym} 
\usepackage{xparse}
\usepackage{xstring}

\NewDocumentCommand{\checklist}{O{0}O{0}m}{%
  \ifnumcomp{#1}{=}{0}{\Square}{\XBox}%
  \ifnumcomp{#2}{=}{0}{\Square}{\XBox}%
  #3%
}

\NewDocumentCommand{\othercheck}{om}{%
 % if no optional argument
 \IfNoValueTF{#1}{\checklist{#2}}%
  {%
   % if optional argument
   \StrMid{#1}{1}{1}[\varA]%
   \StrMid{#1}{2}{2}[\varB]%
   \checklist[\varA][\varB]{#2}
  }%
}

\begin{document}

\checklist{Check this}

\checklist[1][0]{Check that}

\othercheck{Default: nothing checked}

\othercheck[01]{Second square should be checked}

\end{document}

enter image description here

But your \checklist command is too complicated and \othercheck can be made better.

You seem to want to pass a two-bit string to the command and check or uncheck depending on the bit value.

\documentclass{article}
\usepackage{wasysym} 

\ExplSyntaxOn
\NewDocumentCommand{\newcheck}{O{00}m}
 {
  \str_map_function:nN { #1 } \anderstood_check:n
  \ #2
 }

\cs_new:Nn \anderstood_check:n
 {
  \str_case:nn { #1 }
   {
    {0}{\Square}
    {1}{\XBox}
   }
 }

\ExplSyntaxOff

\begin{document}

\newcheck{Default: nothing checked}

\newcheck[01]{Second square should be checked}

\newcheck[10]{First square should be checked}

\newcheck[11]{Both squares should be checked}

\end{document}

enter image description here

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .