2

I have an \outercmd, which uses an \innercmd multiple times with various macros calls e.g.

\newcommand{\outercmd}{
\innercmd{\fooOne{}}
\innercmd{\fooTwo{}}
\innercmd{\fooThree{}}
}

I'd like to be able to adjust the behaviour of \outercmd (without changing its definition) by (a) specifying a subset of {\fooOne{}, \fooTwo{}, \fooThree{}} which I want it to use and by overriding \innercmd{}.

\documentclass{article}

\newcommand{\fooOne}{contentsOne}
\newcommand{\fooTwo}{contentsTwo}
\newcommand{\fooThree}{contentsThree}

\newcommand{\innercmd}[1]{#1}

\newcommand{\outercmd}{
\innercmd{\fooOne{}}
\innercmd{\fooTwo{}}
\innercmd{\fooThree{}}
}

\usepackage{expl3}
\ExplSyntaxOn%
% argument #2 calls \innercmd{\cmdX{}} with different \cmdX{}, and we want it
% to only have an effect if \cmdX{} is in the list #1.
\NewDocumentCommand{\onlyUse}{mm}
{
  \group_begin:%
  \seq_clear:N \l_tmpa_seq
  \clist_map_inline:nn {#1}
  {
    \seq_gput_right:Nn \l_tmpa_seq {\tl_to_str:n {##1}}
  }%
  \typeout{Sequence, one per line}%
  \seq_map_inline:Nn \l_tmpa_seq {%
    \typeout{Elem: {##1}}%
  }%
  \NewCommandCopy{\originnercmd}{\innercmd}%
  \renewcommand{\innercmd}[1]{%
    \tl_set:Nn \l_tmpa_str {\tl_to_str:n {##1}}%
    \typeout{Inner is being called with {\l_tmpa_str} }%
    \seq_if_in:NnT \l_tmpa_seq {\l_tmpa_str}
      {%
        \typeout{Found it!}
        \originnercmd{\cs:w \l_tmpa_str \cs_end:}%
      }%
  }
  #2
  \group_end:%
}
\ExplSyntaxOff%

\begin{document}

Some output to test

Outer by itself:
\outercmd%

Only use first and third:
\onlyUse{ \fooOne{}, \fooThree{} }{  \outercmd{} }%

Only use second:
\onlyUse{ \fooTwo{} }{  \outercmd{} }

\end{document}

I get this output as debug info here:

LaTeX2e <2021-11-15> patch level 1
L3 programming layer <2022-01-21>
(/usr/share/texlive/texmf-dist/tex/latex/base/article.cls
Document Class: article 2021/10/04 v1.4n Standard LaTeX document class
(/usr/share/texlive/texmf-dist/tex/latex/base/size10.clo))
(/usr/share/texlive/texmf-dist/tex/latex/l3kernel/expl3.sty
(/usr/share/texlive/texmf-dist/tex/latex/l3backend/l3backend-pdftex.def))
(_build/mwe.aux)
Sequence,oneperline
Elem:{\fooOne {}}
Elem:{\fooThree {}}
Innerisbeingcalledwith{\fooOne {}}
Innerisbeingcalledwith{\fooTwo {}}
Innerisbeingcalledwith{\fooThree {}}
Sequence,oneperline
Elem:{\fooTwo {}}
Innerisbeingcalledwith{\fooOne {}}
Innerisbeingcalledwith{\fooTwo {}}
Innerisbeingcalledwith{\fooThree {}}

So the string comparison is failing, but I don't understand why or how to fix it. Line 1: Some output to test. Line 2: Outer by itself:
contentsOne contentsTwo contentsThree. Line 3: Only use first and third:. Line 4: Only use second:.

1 Answer 1

1

I noticed that the types were incorrect, \tl_set:Nn \l_tmpa_str {\tl_to_str:n {##1}}% (e.g. setting a token list to a string) by doing \seq_show:N (which printed the sequence, but aborted execution, weird).

Regardless, the final solution turns out to be simple enough.

\usepackage{expl3}
\ExplSyntaxOn%
% argument #2 calls \innercmd{\cmdX{}} with different \cmdX{}, and we want it
% to only have an effect if \cmdX{} is in the list #1.
\NewDocumentCommand{\onlyUse}{mm}
{
  \group_begin:%
  \seq_clear:N \l_tmpa_seq
  \clist_map_inline:nn {#1}
  {
    \seq_gput_right:Nn \l_tmpa_seq {##1}
  }%

  %\typeout{Sequence}%
  % Uncommenting shows the sequence, but also stops execution?
  %\seq_show:N \l_tmpa_seq {}%

  \NewCommandCopy{\originnercmd}{\innercmd}%
  \renewcommand{\innercmd}[1]{%

    \seq_if_in:NnT \l_tmpa_seq {##1}
      {%
        \typeout{Found!}
        \originnercmd{##1}%
      }%
  }
  #2
  \group_end:%
}
\ExplSyntaxOff%
1
  • 1
    welcome! \show (and *_show:N etc.) don't abort execution. however, if you use a gui editor, it may compile in a mode which aborts compilation anytime the run tries to interact with you at the console. if you compile on the command line instead, it will rather pause compilation to show you whatever. you can then choose whether to continue compilation or do something else. Commented Apr 12 at 14:04

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.