Taken from this post, I have the following code to define a macro that takes an arbitrary number of arguments and concatenates them with an interleaving symbol (\simeq_{k}) in math mode:
\makeatletter
\def\kleene{%
%
\futurelet\@let@token\@kleene
}
\def\@kleene{%
\ifx\@let@token\bgroup
\expandafter\@@kleene
\else
\expandafter%
\fi
}
\def\@@kleene#1{%
#1%
\futurelet\@let@token\@@@kleene
}
\def\@@@kleene{%
\ifx\@let@token\bgroup
\simeq_{k}
\expandafter\@@kleene
\else
\expandafter%
\fi
}
\makeatother
Just as a remark, I use latex with Ott and the arguments of \kleene might be of the form [[some_ott_syntax]]. Unfortunately, the double delimiters [[]] are reserved for including Ott code in my latex code. So, most of the times, the arguments of \kleene contain those delimiters and I cannot avoid this.
The macro is based on checking whether the next character is a {. This forces me to provide each argument of \kleene right next to the previous, without any white space, like I show below. Note that the arguments might be of the form [[arg]] (surrounded with [[]] because they are Ott code).
\kleene{arg1}{arg2}{arg3}{arg4}
However, sometimes I want to pass a long list of arguments and every argument is perhaps quite long itself. For readability of the tex code it would be useful to be able to write the following and mean the above.
\kleene{[[some_long_ott_code1]]}
{[[some_long_ott_code2]]}
{[[some_long_ott_code3]]}
{[[some_long_ott_code4]]}.
Currently this is impossible because the next character after the first argument is a newline "character", so the next arguments are not parsed as arguments of \kleene but as just some latex (math) code.
How can I possibly modify the \kleene macro so that when it checks for the next argument, it doesn't take into account the white space (newline, spaces and tabs)?
Such a formulation will perhaps need a special character (for example, it could be a full-stop) to indicate that the list of arguments is over.


\@ifnextcharis a wrapper around futurelet that skips spaces – David Carlisle Jun 06 '19 at 11:12[]not{}no standard latex command has a variable number of{}arguments – David Carlisle Jun 06 '19 at 11:13{}instead of[]for the optional arguments might introduce problems? I use{}for uniformity of the syntax of\kleene. But suppose I want to define the command as you say. What extra changes should I make? – frabala Jun 06 '19 at 11:15{..]..}– David Carlisle Jun 06 '19 at 11:19\kleeneis of the form[[some_ott_code]]. It works fine. Is this what you mean? If not, please provide me a full answer, as I'm not sure what changes I need to make to the macro. – frabala Jun 06 '19 at 11:22\kleene{a}{b}{c}and then, out of the blue, it turns out they're in the form\kleene[[a]][[b]][[c]]. What will happen with the next update? – egreg Jun 06 '19 at 11:29{}and[]. I have updated my question accordingly. – frabala Jun 06 '19 at 11:34[[...]]? Is that automatically generated? Do you want to keep the double brackets or remove them? – egreg Jun 06 '19 at 11:52\kleene{arg1}{arg2}{arg3}{arg4}{\large This should not be treated as a kleene argument but how can kleene know this?}? Would you mind nesting everything that shall be processed by\kleeneinto one additional brace group:\kleene{{arg1}{arg2}{arg3}{arg4}}? That way one could easily implement taking the argument of\kleenefor a list of undelimited arguments and have LaTeX iterate on that expandably... – Ulrich Diez Jun 06 '19 at 20:08{and}). "Iterating expandably" means that everything works only by means of macro expansion, no temporary assignments/"definitions" by means of\letor\futureletor the like needed. This might save some memory. This makes getting the result of\kleeneinto the replacement text of another macro definition more easy. I just wrote a full anwer... – Ulrich Diez Jun 06 '19 at 21:57