1

I'm creating a package which defines a command that looks something like this:

\newcommand{\mycommand}[2]{
    \input{|"\mypackage@buildcommand{#1}{#2}"}
}

mypackage@buildcommand uses the ifthen package, which defines \equal. However, when I use \mycommand{x}{y} in a LaTeX document that uses my package, I get an undefined control sequence error referring to \equal. When my macro simply returns the result of the buildcommand instead of passing it to input, it works fine and outputs the command to the LaTeX document, but with that \input it just doesn't work.

Edit
Added relevant code that uses ifthen

\ifx\@empty\playtex@encoding
    \ifdefined\inputencodingname
        % Use inputenc encoding if defined
        \def\playtex@encoding{%
            % Treat utf8x as utf8
            \ifthenelse{\equal{\inputencodingname}{utf8x}}%
            {utf8}{\inputencodingname}%
        }
    \else
        \def\playtex@encoding{utf8}
    \fi
\fi

\newcommand{\playtex@buildcommand}[2]{%
    playtex-render \playtex@playerfile{} #1 #2 %
    --encoding=\playtex@encoding{} %
    \ifthenelse{\equal{\playtex@cache}{always}}{--cache}{%
    \ifthenelse{\equal{\playtex@cache}{never}}{--no-cache}{%
    \ifthenelse{\equal{\playtex@cache}{draft}}{%
        \ifdraft{--cache}{--no-cache}%
    }{{\errmessage{cache must be always, never, or draft}}}}}%
}
  • Welcome to TeX.SX! – Bobyandbob Nov 19 '17 at 23:24
  • 1
    A command defined in terms of \ifthenelse is not expandable, so you can't use it in that context. – egreg Nov 19 '17 at 23:28
  • What alternatives do I have to \ifthenelse? I'm using it there to determine the command-line argument to pass to a shell command based on the value of a macro. I'm also using \ifdraft from the ifdraft package, which I think is similar – potato Nov 19 '17 at 23:38
  • Can you please show your definition of \mypackage@buildcommand so a different strategy can be suggested? – egreg Nov 19 '17 at 23:38
  • I added relevant code – potato Nov 19 '17 at 23:42
1

You need to use an expandable test, which \ifthenelse isn't. Also {} should not be used to delimit macro names in that context and \space should be used.

I changed the command into echo just for testing purposes.

\documentclass{article}
\usepackage{pdftexcmds}

\makeatletter
\newcommand{\ifequalstring}[2]{%
  \ifnum\pdf@strcmp{#1}{#2}=\z@
    \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi
}

\newcommand{\mycommand}[2]{%
  \input{|"\playtex@buildcommand{#1}{#2}"}%
}

\ifdefined\inputencodingname
  % Use inputenc encoding if defined
  \edef\playtex@encoding{%
    % Treat utf8x as utf8
    \ifequalstring{\inputencodingname}{utf8x}{utf8}{\inputencodingname}%
  }%
\else
  \def\playtex@encoding{utf8}%
\fi

\newcommand{\playtex@buildcommand}[2]{%
%  playtex-render \playtex@playerfile\space #1 #2 %
  echo \playtex@playerfile\space #1 #2 %
    --encoding=\playtex@encoding\space
    \ifequalstring{\playtex@cache}{always}
      {--cache}
      {%
       \ifequalstring{\playtex@cache}{never}
         {--no-cache}
         {%
          \ifequalstring{\playtex@cache}{draft}
            {\ifdraft{--cache}{--no-cache}}
            {\errmessage{cache must be always, never, or draft}}%
         }%
      }%
}
\makeatother

\begin{document}

\makeatletter % for testing
\def\playtex@playerfile{FILE}
\def\playtex@cache{always}
\makeatother

\texttt{\mycommand{A}{B}}

\end{document}

Output

FILE A B --encoding=utf8 --cache

0

I got it to work by pulling out all the conditionals from the macros and using the conditionals to define different macros. I created a cachearg macro for the --cache argument and in the input I just put all my "static" macros together. I also had to create a \playtex@space macro, set to a space character, because the \macro{} syntax doesn't work in the \input context to stop the macro from gobbling up stuff after it for whatever reason. In @DavidCarlisle's comment, I see he used a \@space macro which seems to do the same thing, but I tried replacing my \playtex@space with \@space and it wasn't defined. Don't know if it is supposed to be by default.

The whole thing is rather ugly and inflexible: for example, if the inputenc encoding was to change, my package would not update automatically like it would with conditionals in the macro. That said, it works. Thanks for all your help.

  • \@space is probably a typo and \space was meant – user4686 Nov 20 '17 at 7:32

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.