2

I defined the following command:

\NewDocumentCommand \displayls {s m}{%
  \IfBooleanTF{#1}{\textls*[250]{#2}}{\textls[250]{#2}}%
}

I would like to refactor the definition to remove the duplication.

I can make a trivial version:

\NewDocumentCommand \displayls {s m}{%
  \csname textls\endcsname[250]{#2}%
}

If I then try to process the star argument, I get into trouble. I tried:

\NewDocumentCommand \displayls {s m}{%
  \csname textls\IfBooleanTF{#1}{*}{}\endcsname[250]{#2}%
}

But this does not work for the *-form; it produces:

enter image description here

Here is the test document:

\documentclass{article}

\usepackage{microtype,xparse}
\NewDocumentCommand \displayls {s m}{%
  % (One of the definitions above)
}

\begin{document}
\displayls{foo}
\displayls*{foo}
\end{document}

I tried adding \expandafter before \csname, but that didn't make any difference.

  • 1
    Why do you want to do this exactly? It seems like far more trouble than it is worth and you end up with far less clear code as a result. – cfr Sep 20 '17 at 22:41
  • \NewDocumentCommand{\displayls}{sm}{\IfBooleanTF{#1}{\textls*}{\textls}[250]{#2}} – egreg Sep 20 '17 at 22:45
  • @egreg, thanks, but can't I remove the duplication of \textls? @cfr: I want to remove the duplication. I agree it looks like it won't be that clear in LaTeX, but the general principle of "pass on the star from the outer command to the inner command" is at least a clear idea! – Reuben Thomas Sep 20 '17 at 22:51
  • \textls* is not a csname with name textls* it is \textls followed by *, – David Carlisle Sep 20 '17 at 22:55
  • Related: Defining starred versions of commands (* macro) – Werner Sep 21 '17 at 0:23
3

Just duplicate \textls; or use \exp_last_unbraced:Nf (but I wouldn't bother to).

\documentclass{article}

\usepackage{microtype,xparse}

\NewDocumentCommand{\displayls}{s m}{%
  \IfBooleanTF{#1}{\textls*}{\textls}[250]{#2}%
}

\ExplSyntaxOn
\NewDocumentCommand\displaylsvar{s m}
 {
  \exp_last_unbraced:Nf \textls \IfBooleanT{#1}{*} [250] {#2}
 }
\ExplSyntaxOff

\begin{document}

\displayls{foo}
\displayls*{foo}

\displaylsvar{foo}
\displaylsvar*{foo}

\end{document}

enter image description here

Just for information about your attempt. If you call \textls* it's two tokens, namely \textls and *; to the contrary, \csname textls*\endcsname constructs a single token (undefined, so treated like \relax).

Also, here's the definition of \textls by microtype:

\DeclareRobustCommand\textls{%
  \@ifstar{\let\MT@ls@adjust@\MT@ls@adjust@empty\MT@textls}%
          {\let\MT@ls@adjust@\MT@ls@adjust@relax\MT@textls}%
}

I see no much point in avoiding the duplication in the suggested simple version.

  • Thanks very much for the "principled" answer as well as what is probably the best on in this case (to duplicate the command, and not involve l3). – Reuben Thomas Sep 20 '17 at 22:56
  • Doubly thanks, as I had another rather more complicated case where the star flag was referred to several times (rather than simply being passed through) where it was definitely worth \ExplSyntaxOn. – Reuben Thomas Sep 20 '17 at 23:10

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.