I made a macro for subtracting two lists which does what was intended.
Then, I found a set-up, here on TeX.SE, with the macro \g@addto@macro
and \@gobble
which is much simpler and gives, in principle, the same output.
When trying to use this second form, some problems did arise.
After some searching, it became clear that the \@gobble
had not been expanded yet, adding an additional element to the list and causing trouble.
What is the best solution for this problem?
I feel that it is preferable to process the resulting \processedlist
so that it can be used in any macro which expects a list.
Then, we get again something similar as in the first macro, a lot of \expandafter
s, although this time they will be used only once and, thus, it should be faster.
\documentclass{article}
\setlength{\parindent}{0pt}
\setlength{\parskip}{1.5ex plus 0.5ex minus 0.2ex}
\begin{document}
\makeatletter
\section*{First macro for subtracting two lists}
\newif\iffirstterm
\newif\ifisinlist
\def\subtractlists#1#2{% original list, remove list
\def\processedlist{}%
\firsttermtrue%
\@for\tempa:=#1\do{%
\isinlistfalse%
\@for\tempb:=#2\do{\ifx\tempa\tempb\isinlisttrue\fi}%
\ifisinlist%
\else%
\iffirstterm%
\expandafter\def\expandafter\processedlist\expandafter{\tempa}%
\firsttermfalse%
\else%
\expandafter\expandafter\expandafter\def%
\expandafter\expandafter\expandafter\processedlist%
\expandafter\expandafter\expandafter{%
\expandafter\processedlist\expandafter,\tempa}%
\fi%
\fi}%
}
%%% some lists for testing:
\def\originallist{Lima,Alpha,Delta,Oscar,Tango,Whisky,Echo,Romeo,Xray}
\def\removelist{Whisky,Oscar,Romeo,Delta}
%The list can be entered as comma separated items or as a macro:
\verb|\originallist|: \originallist\par
\verb|\removelist|: \removelist\par
\verb|\subtractlists{\originallist}{\removelist}|\par
\subtractlists{\originallist}{\removelist}
\verb|\processedlist|: \processedlist\par
%\@for\tempa:=\processedlist\do{(\tempa)}
\section*{Second macro for subtracting two lists}
\def\subtractlist#1#2{% #1:original list,#2:remove list
\def\processedlist{\@gobble}%
\@for\tempa:=#1\do{%
\isinlistfalse%
\@for\tempb:=#2\do{\ifx\tempa\tempb\isinlisttrue\fi}%
\ifisinlist%
\else%
\expandafter\g@addto@macro%
\expandafter\processedlist%
\expandafter{\expandafter,\tempa}%
\fi}%
}
\verb|\originallist|: \originallist\par
\verb|\removelist|: \removelist\par
\verb|\subtractlist{\originallist}{\removelist}|\par
\subtractlist{\originallist}{\removelist}
\verb|\processedlist|: \processedlist\par
\section*{Problems with second approach}
There is some extra matter:
\@for\tempa:=\processedlist\do{(\tempa)}
the first comma has not been gobbled yet:
\verb|\meaning\processedlist|: \meaning\processedlist
\section*{What is the solution?}
This works:
\expandafter\@for\expandafter\tempa%
\expandafter:\expandafter=\processedlist\do{(\tempa)}
but maybe this is safer?:
\expandafter\@for\expandafter\tempa%
\expandafter:\expandafter=%
\expandafter{\processedlist}\do{(\tempa)}
However, the objective is to have \verb|\processedlist| clean of the extra
matter to use it as list in some other macro. Maybe:
\expandafter\expandafter\expandafter\def%
\expandafter\expandafter\expandafter\processedlist%
\expandafter\expandafter\expandafter{\processedlist}
\meaning\processedlist
which is more or less what we had in the first macro.
\end{document}
\bf
to\textbf
was not so complicated. I do not know the new command needed now, but in general they are very far from the natural language. I am very sure that my question can be solved in LaTeX3, but probably, I will not understand how it works.