6

How do I pass an in(de)finite number of arguments?

I would like a command of the type:

\coollist{a}{b}{c}{d}{e}{f}... {y}{z}.

More specifically, I need a command \lexinfinite that would allow me to pass an indefinite number of items of the type {a,b,c}, corresponding to lexemes in a list, inside text (a being the italicized word, b the subscripted grammatical category, and c the translation):

\lexinfinite{a,b,c}{a',b',c'}{...}

MWE

\documentclass{article}

\usepackage{xspace}

\newcommand{\tslt}[1]{\unskip\xspace`#1'}

\NewDocumentCommand{\lexAUX}{mmm}{\textit{#1}\IfNoValueF{#2}{\textup{\textsubscript{\textsc{#2}}}}\IfNoValueF{#3}{\tslt{#3}}}

\NewDocumentCommand{\lex}{>{\SplitArgument{2}{,}}m}{\lexAUX#1}

\newcommand{\lexduo}[2]{\lex{#1}\space and\space\lex{#2}} \newcommand{\lextrio}[3]{\lex{#1},\space\lex{#2}\space and\space\lex{#3}}

\begin{document}

\lex{tree,n,arbre}, \lex{apple,n,pomme} and \lex{stuff,n,thing}

\lexduo{tree,n,arbre}{apple,n,pomme}

\lextrio{tree,n,arbre}{apple,n,pomme}{stuff,n,thing}

\end{document}

  • 3
    Are you interested in using LuaLaTeX for this? Could do a simple regex split. As for an "infinite" number of {}, not so sure. Do you like this syntax? {A,b;c,d;1,2}? – likethevegetable Feb 07 '23 at 17:40
  • @likethevegetable I always use lua yes. And the semicolon syntax is a great idea – Vincent Krebs Feb 07 '23 at 17:43
  • Pretty much duplicate of macros - Commands that may take a variable number of arguments - TeX - LaTeX Stack Exchange (guess I'll leave it as is because this one solves OP's specific question) – user202729 Feb 08 '23 at 02:10
  • 1
    What about a command where the list with an arbitrary amount of arguments is nested between curly braces so that internally it can be handled as a single argument - \coolitlist{{a}{b}{c}{d}{e}{f}{g}{h}{i}{j}{k}{l}{m}{n}{o}{p}{q}{r}{s}{t}{u}{v}{w}{x}{y}{z}} ? – Ulrich Diez Feb 08 '23 at 12:15
  • @Ulrich Hi Ulrich! This was the idea behind a few proposals but I wanted to avoid double braces. I usually have 2 or 3 lexemes, but I didn't want to create \lexquadro and son on ;) – Vincent Krebs Feb 08 '23 at 12:26
  • 1
    I think tis would be a lot easier to understand if you provided the actual context in which you plan to use this. Is it a text or math mode command? What should it be able to accomplish? – Gaussler Feb 08 '23 at 13:17
  • 1
    @VincentKrebs I asked because from a nitpicker's point of view double-braces would be more in line with LaTeX-syntax. Besides this with double-braces one can have TeX iterate on the argument until it is blank which implies that one does not need a method for "looking ahead at the next token". Looking ahead at the next token is a crucial thing in LaTeX because there are no 100%-reliable ways of doing that. (You can use \let/\futurelet but that actually does not take into account the "shape" of tokens. If you use macros for looking ahead, brace-stripping and tokenization might cause problems.) – Ulrich Diez Feb 08 '23 at 13:19
  • I see. This is really for 2 to 5-6 arguments -- I didn't want to write \lexquatro, \lexquinto, \lexsexto and so on (and I say this, I'm a Latin teacher you know ;) ) Again we can add \relax whevener needed. – Vincent Krebs Feb 08 '23 at 15:38

8 Answers8

8

You can define your macros using TeX primitives and elementary macros:

\documentclass{article}

\newcount\lexcount \def\lexi#1,#2,#3,#4^{{\it #1}\if^#2^\else\uppercase{$_{\rm #2}$}\if^#3^\else~`#3'\fi\fi} \def\lexinf {\lexcount=0 \def\lexinfS{}\futurelet\next\lexinfA} \def\lexinfA {\ifx\next\bgroup \expandafter\lexinfB \else \expandafter\lexinfS \fi} \def\lexinfB #1{\advance\lexcount by1 \addto\lexinfS{\lexinfC{#1}}\futurelet\next\lexinfA} \def\lexinfC#1{\lexi #1,,,^\advance\lexcount by-1 \ifcase\lexcount \or \ and \else , \fi} \long\def\addto#1#2{\expandafter\def\expandafter#1\expandafter{#1#2}}

\begin{document}

\lexinf{tree,n,arbre}

\lexinf{tree,n,arbre}{apple,n,pomme}

\lexinf{tree,n,arbre}{apple,n,pomme}{stuff,n,thing}

\lexinf{tree,n,arbre}{apple,n,pomme}{stuff,n,thing}{last,x,uff}

\end{document}

wipet
  • 74,238
6

Do you mean something like this? Or do you need somehow to incorporate the ellipsis (...) into the input/output?

\documentclass{article}
\usepackage{listofitems}
\newcommand\coolitlist[1]{%
  \readlist*\mylist{#1}%
  \foreachitem\z\in\mylist[]{%
    $\z$%
    \ifnum\zcnt<\listlen\mylist[]\relax, \fi
    \ifnum\zcnt=\numexpr\listlen\mylist[]-1\relax and \fi
  }%
}
\begin{document}
\coolitlist{a, b, c}

\coolitlist{a,b,c,d,e,f} \end{document}

enter image description here

ADDENDUM

Perhaps this addition of \lexlist addresses the OP's comment for a list of \lex commands.

\documentclass{article}
\usepackage{listofitems,xspace}
\newcommand\coolitlist[1]{%
  \readlist*\mylist{#1}%
  \foreachitem\z\in\mylist[]{%
    $\z$%
    \ifnum\zcnt<\listlen\mylist[]\relax, \fi
    \ifnum\zcnt=\numexpr\listlen\mylist[]-1\relax and \fi
  }%
}
\newcommand\lexlist[1]{%
  \readlist*\mylist{#1}%
  \foreachitem\z\in\mylist[]{%
    \expandafter\lex\expandafter{\z}%
    \ifnum\zcnt<\listlen\mylist[]\relax, \fi
    \ifnum\zcnt=\numexpr\listlen\mylist[]-1\relax and \fi
  }%
}
\NewDocumentCommand{\lexAUX}{mmm}{\textit{#1}\IfNoValueF{#2}{\textup{\textsubscript{\textsc{#2}}}}\IfNoValueF{#3}{\tslt{#3}}}

\NewDocumentCommand{\lex}{>{\SplitArgument{2}{,}}m}{\lexAUX#1}

\newcommand{\tslt}[1]{\unskip\xspace`#1'}

\begin{document} \coolitlist{a, b, c}

\coolitlist{a,b,c,d,e,f}

\lex{house,n,maison}

\lexlist{{house,n,maison},{arbre,n,tree},{stuff,n,thing}} \end{document}

enter image description here

SECONDARY ANSWER

Per OP's request, this will have \lexlist absorb as many groups as are presented, so that groups need not be grouped, as in prior answer:

\documentclass{article}
\usepackage{listofitems,xspace}
\newtoks\lextoks
\ignoreemptyitems
\newcommand\coolitlist[1]{%
  \readlist*\mylist{#1}%
  \foreachitem\z\in\mylist[]{%
    $\z$%
    \ifnum\zcnt<\listlen\mylist[]\relax, \fi
    \ifnum\zcnt=\numexpr\listlen\mylist[]-1\relax and \fi
  }%
}
\newcommand\lexlist{\lextoks{}\lexlistA}
\newcommand\lexlistA{\futurelet\nexttok\lexlistB}
\newcommand\lexlistB{\ifx\nexttok\bgroup\expandafter\lexlistC
  \else\expandafter\lexlistD\expandafter{\the\lextoks}\fi}
\newcommand\lexlistC[1]{\lextoks\expandafter{\the\lextoks{#1},}%
  \lexlistA}
\newcommand\lexlistD[1]{%
  \readlist*\mylist{#1}%
  \foreachitem\z\in\mylist[]{%
    \expandafter\lex\expandafter{\z}%
    \ifnum\zcnt<\listlen\mylist[]\relax, \fi
    \ifnum\zcnt=\numexpr\listlen\mylist[]-1\relax and \fi
  }%
}
\NewDocumentCommand{\lexAUX}{mmm}{\textit{#1}\IfNoValueF{#2}{\textup{\textsubscript{\textsc{#2}}}}\IfNoValueF{#3}{\tslt{#3}}}

\NewDocumentCommand{\lex}{>{\SplitArgument{2}{,}}m}{\lexAUX#1}

\newcommand{\tslt}[1]{\unskip\xspace`#1'}

\begin{document} \coolitlist{a, b, c}

\coolitlist{a,b,c,d,e,f}

\lex{house,n,maison}

\lexlist{house,n,maison}{arbre,n,tree}{stuff,n,thing} or else plain text \end{document}

enter image description here

  • No this is perfect, the ellipsis was only for the question ;) However some commands I use already have comma-delimited arguments : \lex{house,n,maison} and I would like to pass a list of several "lex", so I also need the brace-delimited variant : \lex{house,n,maison}{arbre,n,tree}{stuff,n,thing}.... and so on; is it possible? – Vincent Krebs Feb 07 '23 at 16:21
  • 1
    @VincentKrebs Please see my ADDENDUM. – Steven B. Segletes Feb 07 '23 at 20:59
  • I got it yes, but there is the doubled brace. – Vincent Krebs Feb 07 '23 at 21:11
  • 1
    @VincentKrebs, true, but \lexlist needs a way to know when to stop digesting arguments, and the double brace is it. How else would you propose a way to terminate the lex list? – Steven B. Segletes Feb 07 '23 at 21:49
  • wipet's answer does it (do not ask me how, you are much better equipped than me to understand ;) ) – Vincent Krebs Feb 07 '23 at 21:54
  • 1
    @VincentKrebs After absorbing a group, wipet looks to see if the next character is a \bgroup (i.e., a left brace). If so, he continues the absorption. – Steven B. Segletes Feb 07 '23 at 23:04
  • Thank you. It is a nice method don't you think so ? I can always pass \relax whenever a problem should arise. – Vincent Krebs Feb 07 '23 at 23:06
  • 1
    @VincentKrebs I have provided a secondary answer that functionally mimics wipet's approach of checking the input stream for an opening brace. – Steven B. Segletes Feb 07 '23 at 23:30
  • 1
    @VincentKrebs The new \lexlistD is my original \lexlist macro, whereas the new \lexlist and the A,B,C variants perform the \bgroup test and build the token list of included groups, which finally gets passed to \lexlistD. – Steven B. Segletes Feb 07 '23 at 23:34
  • This is very nice of you, I really appreciate it, thanks a lot. – Vincent Krebs Feb 07 '23 at 23:37
  • 1
    @VincentKrebs What do you mean remove the last comma? On the input or the output? If you mean in the output, then \newcommand\lexlistD[1]{% \readlist*\mylist{#1}% \foreachitem\z\in\mylist[]{% \expandafter\lex\expandafter{\z}% \ifnum\zcnt<\numexpr\listlen\mylist[]-1\relax, \fi \ifnum\zcnt=\numexpr\listlen\mylist[]-1\relax\ and \fi }% } – Steven B. Segletes Feb 08 '23 at 00:32
6

Further answer

The comments under “New answer” apply the same.

\documentclass{article}

\NewDocumentCommand{\lexeme}{>{\SplitArgument{2}{,}}m}{% \dolexeme#1% } \NewDocumentCommand{\dolexeme}{mmm}{% \textit{#1}% \IfValueT{#2}{\textsubscript{#2}}% \IfValueT{#3}{ (#3)}% }

\ExplSyntaxOn

\NewDocumentCommand{\lex}{m} { \krebs_lex_listoflexemes:n { #1 } }

\seq_new:N \l__krebs_lex_in_seq \seq_new:N \l__krebs_lex_out_seq

\cs_new_protected:Nn \krebs_lex_listoflexemes:n { \seq_set_split:Nnn \l__krebs_lex_in_seq { ; } { #1 } \seq_set_map:NNn \l__krebs_lex_out_seq \l__krebs_lex_in_seq { \lexeme{##1} } \seq_use:Nnnn \l__krebs_lex_out_seq { ~and~ } { ,~ } { ~and~ } }

\ExplSyntaxOff

\begin{document}

\lex{ tree,n,arbre; apple,n,pomme; stuff,n,chose; invasion,n,invasion; ascension,n,ascension; last,a,dernier; x; y,q }

\end{document}

enter image description here

New answer

This seems like an XYZ-problem: I want to do X with the Y method, but I present Z.

First and foremost: you gain nothing with an indefinite number of arguments, because the syntax is obscure and error prone.

Judging from your edited question, you want to loop over a set of comma separated lists, doing something (unspecified) to these lists.

My proposal is to have a clearer syntax that helps in confining the data and avoids “going on forever”.

\documentclass{article}

\ExplSyntaxOn

\NewDocumentCommand{\lex}{m} { \tl_map_function:nN { #1 } \krebs_cool_whatever:n }

\cs_new_protected:Nn \krebs_cool_whatever:n { !!\clist_use:nnnn { #1 } { ~and~ } { ,~ } { ~and~ }!! \par }

\ExplSyntaxOff

\begin{document}

\lex{ {tree,n,arbre} {apple,n,pomme} {stuff,n,chose} {invasion,n,invasion} {ascension,n,ascension} {last,a,dernier} }

\end{document}

enter image description here

Waiting for a further edit to fill in what you mean to do with the lists.

Original answer

Reading minds is not easy…

Based on your comment I defined a dummy \lex command that takes a comma separated list, just to show that it works with no problem.

The idea is to exploit \seq_use:Nnnn, where the n arguments specify, respectively, the separator between only two items, the separator between several items and the separator between the last two items (if more than two).

The input is transformed into a sequence, another one is built by wrapping the items with \textit and the result is passed to \seq_use:Nnnn.

\documentclass{article}

\ExplSyntaxOn

\NewDocumentCommand{\lex}{m} { \clist_map_inline:nn { #1 } { \fbox{##1} } }

\NewDocumentCommand{\coolitlist}{m} { \krebs_cool_itlist:n { #1 } }

\seq_new:N \l__krebs_cool_itlist_in_seq \seq_new:N \l__krebs_cool_itlist_out_seq

\cs_new_protected:Nn \krebs_cool_itlist:n { \seq_set_from_clist:Nn \l__krebs_cool_itlist_in_seq { #1 } \seq_set_map:NNn \l__krebs_cool_itlist_out_seq \l__krebs_cool_itlist_in_seq { \textit { ##1 } } \seq_use:Nnnn \l__krebs_cool_itlist_out_seq { ~and~ } { ,~ } { ~and~ } }

\ExplSyntaxOff

\begin{document}

\coolitlist{a}

\coolitlist{a,b}

\coolitlist{a,b,c}

\coolitlist{a,b,\lex{c,cc,ccc},d}

\end{document}

enter image description here

No counter, no arithmetic.

egreg
  • 1,121,712
  • It's a list of lexemes. I just want to use it inside text, like : "Here are three words I'm interested in : x, y and z; and each time you get the word italicized, and, optionally, the category in subscript, and, optionally, a space followed by a 'translation'. wipet's answer is the closest to what I want, except it does not handle the optionality of subarguments 2 and 3. Thank you! – Vincent Krebs Feb 07 '23 at 22:47
  • Note that likethevegetable's idea to use semicolons is very good too. – Vincent Krebs Feb 07 '23 at 23:14
  • @VincentKrebs This starts being an XYZUVW problem. Look at the “further answer”. – egreg Feb 07 '23 at 23:18
  • Thanks. I don't really understand your remarks since the updated MWE is pretty clear. Now I still prefer to avoid the double braces if possible. – Vincent Krebs Feb 07 '23 at 23:21
  • 1
    @VincentKrebs Pretty straightforward, see edit – egreg Feb 07 '23 at 23:31
  • @VincentKrebs I edited it to match the (hopefully) final version of the question. – egreg Feb 07 '23 at 23:37
5

I don’t understand the purpose of it, but is this what you want?

\documentclass{article}

\usepackage{xspace,xparse}

\newcommand{\tslt}[1]{\unskip\xspace`#1'}

\NewDocumentCommand{\lexAUX}{mmm}{\textit{#1}\IfNoValueF{#2}{\textup{\textsubscript{\textsc{#2}}}}\IfNoValueF{#3}{\tslt{#3}}}

\NewDocumentCommand{\lexTRIPLE}{>{\SplitArgument{2}{,}}m}{\lexAUX#1}

\DeclareDocumentCommand\lexEXTRA{g}{% \IfValueT{#1}{% ,\space\lexTRIPLE{#1}\lexEXTRA }% }

\DeclareDocumentCommand\lex{m}{% \lexTRIPLE{#1}% \lexEXTRA }

\begin{document}

\lex{tree,n,arbre}, \lex{apple,n,pomme} and \lex{stuff,n,thing}

\lex{tree,n,arbre}{apple,n,pomme}

\lex{tree,n,arbre}{apple,n,pomme}{stuff,n,thing}

\end{document}

enter image description here


A slightly less concise version which adds “and”:

\documentclass{article}

\usepackage{xspace,xparse}

\newcommand{\tslt}[1]{\unskip\xspace`#1'}

\NewDocumentCommand{\lexAUX}{mmm}{\textit{#1}\IfNoValueF{#2}{\textup{\textsubscript{\textsc{#2}}}}\IfNoValueF{#3}{\tslt{#3}}}

\NewDocumentCommand{\lexTRIPLE}{>{\SplitArgument{2}{,}}m}{\lexAUX#1}

\DeclareDocumentCommand\lexEXTRA{mg}{% \IfValueTF{#2}{% ,\space\lexTRIPLE{#1}\lexEXTRA{#2}% }{% \space and\space\lexTRIPLE{#1}% }% }

\DeclareDocumentCommand\lex{mg}{% \lexTRIPLE{#1}% \IfValueT{#2}{% \lexEXTRA{#2}% }% }

\begin{document}

\lex{tree,n,arbre}, \lex{apple,n,pomme} and \lex{stuff,n,thing}

\lex{tree,n,arbre}{apple,n,pomme}

\lex{tree,n,arbre}{apple,n,pomme}{stuff,n,thing}

\end{document}

enter image description here

Gaussler
  • 12,801
  • I admit I am quite amazed at the concision of the code. Just, there is no "and" at the end. – Vincent Krebs Feb 08 '23 at 15:35
  • @VincentKrebs Updated with this change. – Gaussler Feb 08 '23 at 16:13
  • This is crazy what you achieve with this g type. Thank you very much... – Vincent Krebs Feb 08 '23 at 16:32
  • 1
    Don’t say that too loud in here. The LaTeX gurus frown upon the use of optional arguments in braces (which is what g-type arguments are). But your question cannot really be answered without it. – Gaussler Feb 08 '23 at 16:35
  • Well, I can say loud that this argument type handles recursivity with a simplicity that, to the best of my knowledge, no other methodology can achieve. The rest is dogma. – Vincent Krebs Feb 08 '23 at 17:00
4

You can use the pgffor package (which is loaded by tikz) to take advantage of the ... syntax.

enter image description here

\documentclass{article}

\usepackage{pgffor, ifthen}

\newcommand{\coolitlist}[1]{\foreach\W[count=\n]in{#1}{\xdef\nnn{\n}}% \foreach\W[count=\n, evaluate=\n as \m using int(\n+1)]in{#1} {\ifthenelse{\n=\nnn}{ and \W}{\ifthenelse{\m=\nnn}{\W}{\W,\ }}}}

\begin{document}

I like \coolitlist{a,b,...,g}.

I like \coolitlist{10,9,...,2}.

I like \coolitlist{{blue},{green},{yellow}}.

\end{document}

Sandy G
  • 42,558
4

If I understand correctly, this is what you want

\documentclass{article}

\ExplSyntaxOn

\seq_new:N \l__krebs_cool_itlist_a_seq \seq_new:N \l__krebs_cool_itlist_b_seq

\NewDocumentCommand \coolitlist { m } {% \seq_set_from_clist:Nn \l__krebs_cool_itlist_a_seq { #1 } \krebs_cool_itlist: }

\cs_new:Nn \krebs_cool_itlist_concat:n { \seq_set_from_clist:Nn \l__krebs_cool_itlist_b_seq { #1 } \seq_concat:NNN \l__krebs_cool_itlist_a_seq \l__krebs_cool_itlist_a_seq \l__krebs_cool_itlist_b_seq \krebs_cool_itlist:

}

\cs_new_protected:Nn \krebs_cool_itlist: { \peek_meaning:NTF \c_group_begin_token { \krebs_cool_itlist_concat:n } { \seq_set_map:NNn \l__krebs_cool_itlist_b_seq \l__krebs_cool_itlist_a_seq { \textit { ##1 } } \seq_use:Nnnn \l__krebs_cool_itlist_b_seq { ~and~ } { ,~ } { ~and~ } } }

\ExplSyntaxOff \begin{document}

\coolitlist{a,b,c,d,e,f,g,h,i,j}

\coolitlist{a,b,c,d,e,f,g,h,i,j}{k,l,m,n,o,p}

\coolitlist{a,b,c,d,e,f,g,h,i,j}{k,l,m,n,o,p}{q,r,s,t,u,v}

\coolitlist{a,b,c,d,e,f,g,h,i,j}{k,l,m,n,o,p}{q,r,s,t,u,v}{w,x,y,z} 

Resault with \verb|\bgroup|

\coolitlist{a,b,c,d,e,f,g,h,i,j}\bgroup k,l,m,n,o,p\egroup

\end{document}

enter image description here

It is based on egreg's answer. The way it works is that the function will peek after the first argument to see if it is an open group character (beware that an implicit one is also valid, but e.g \bgroup would probably give unwanted results. Also spaces are not skipped), if so, it will concatenate the content of the next argument to the first argument and peek ahead again, if not it will do the same as \krebs_cool_itlist:n from egreg's answer.

Maybe it will be wise to append \relax after a call of \coolitlist, e.g. \coolitlist{a,b}{c}\relax

Udi Fogiel
  • 3,824
1

This is in the spirit of Gaussler's answer which makes use of xparse's (deprecated) g-type-argument, but it does not require at least one brace-nested lexem-triple to be present.

\documentclass{article}

\usepackage{xspace,xparse}

\newcommand{\tslt}[1]{\unskip\xspace`#1'}

\NewDocumentCommand{\lexAUX}{mmm}{\textit{#1}\IfNoValueF{#2}{\textup{\textsubscript{\textsc{#2}}}}\IfNoValueF{#3}{\tslt{#3}}}

\NewDocumentCommand{\lexTRIPLE}{>{\SplitArgument{2}{,}}m}{\lexAUX#1}

\makeatletter \DeclareDocumentCommand\lexloop{mmg}{% \IfValueTF{#3}{@firstoftwo#1\lexloop{#2\lexTRIPLE{#3}}{{, }{ and }}}% {@secondoftwo#1}% }% \makeatother \DeclareDocumentCommand\lex{}{\lexloop{{}{}}{{}{}}}%

\begin{document}

\lex{tree,n,arbre}, \lex{apple,n,pomme} and \lex{stuff,n,thing}

\lex{tree,n,arbre}{apple,n,pomme}

\lex{tree,n,arbre}{apple,n,pomme}{stuff,n,thing}

\lex{tree,n,arbre}

noth\lex ing

\end{document}

enter image description here

Ulrich Diez
  • 28,770
0

I am very grateful to you everyone for your many interesting proposals.

I write down all the coding possibilities; I am learning a lot thanks to you.

Here is a MWE illustrating the solutions that I retain.

\documentclass{article}
\usepackage{listofitems,xspace,fontspec}
\usepackage[lmargin=2.5cm,rmargin=2.5cm,bmargin=2.5cm,tmargin=3.5cm]{geometry}
\setmainfont{Times New Roman}

%%%%%%% Common Code %%%%%%% \NewDocumentCommand{\oldlexAUX}{mmm}{\textit{#1}\IfNoValueF{#2}{\textup{\textsubscript{\textsc{#2}}}}\IfNoValueF{#3}{\tslt{#3}}} \NewDocumentCommand{\oldlex}{>{\SplitArgument{2}{,}}m}{\oldlexAUX#1} \newcommand{\tslt}[1]{\unskip\xspace`#1'} %%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%% Gaussler's g-type Method %%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\DeclareDocumentCommand\lexEXTRA{mg}{% \IfValueTF{#2}{% ,\space\oldlex{#1}\lexEXTRA{#2}% }{% \space and\space\oldlex{#1}% }% }

\DeclareDocumentCommand\gausslex{mg}{% \oldlex{#1}% \IfValueT{#2}{% \lexEXTRA{#2}% }% }

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%% Wipet/Steven Method %%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\newtoks\lextoks \ignoreemptyitems

\newcommand{\lexeme}{\expandafter\oldlex\expandafter{\z}}

\newcommand\lex{\lextoks{}\lexA} \newcommand\lexA{\futurelet\nexttok\lexB} \newcommand\lexB{\ifx\nexttok\bgroup\expandafter\lexC \else\expandafter\lexD\expandafter{\the\lextoks}\fi} \newcommand\lexC[1]{\lextoks\expandafter{\the\lextoks{#1},}% \lexA}

\newcommand\lexD[1]{% \readlist*\mylist{#1}% \foreachitem\z\in\mylist[]{% \ifnum\zcnt=1\lexeme \else \ifnum\zcnt<\listlen\mylist[]\unskip,\space\lexeme \else\space and \lexeme \fi \fi }% }

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%% Enrico's Semi-Colon Variant of \lex %%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\NewDocumentCommand{\dolex}{>{\SplitArgument{2}{,}}m}{% \coolexAUX#1% } \NewDocumentCommand{\coolexAUX}{mmm}{% \textit{#1}% \IfValueT{#2}{\textup{\textsubscript{\textsc{#2}}}}% \IfValueT{#3}{\tslt{#3}}% }

\ExplSyntaxOn

\NewDocumentCommand{\coolex}{m} { \krebs_lex_listoflexemes:n { #1 } }

\seq_new:N \l__krebs_lex_in_seq \seq_new:N \l__krebs_lex_out_seq

\cs_new_protected:Nn \krebs_lex_listoflexemes:n { \seq_set_split:Nnn \l__krebs_lex_in_seq { ; } { #1 } \seq_set_map:NNn \l__krebs_lex_out_seq \l__krebs_lex_in_seq { \dolex{##1} } \seq_use:Nnnn \l__krebs_lex_out_seq { ~and~ } { ,~ } { ~and~ } }

\ExplSyntaxOff

\begin{document}

I would like to mention several words, namely \gausslex{invasion,n,invasion}{great,a,génial}{avec,p,with}{eat,v}{word-with-no-category}! \textrightarrow{} This is \textit{Gaussler}'s very economic method for infinite brace-delimited arguments.

\vspace{2ex}

I would like to mention several words, namely \lex{invasion,n,invasion}{great,a,génial}{avec,p,with}{eat,v}{word-with-no-category}! \textrightarrow{} This is \textit{wipet} and \textit{Steven}'s solution, using \TeX{} primitives and delimiting arguments with \textbf{braces}.

\vspace{2ex}

I would like to mention several words, namely \coolex{invasion,n,invasion;great,a,génial;avec,p,with;eat,v;word-with-no-category}! \textrightarrow{} This is \textit{egreg}'s solution, using \textit{Expl3} syntax and delimiting arguments with \textbf{semicolons}.

\end{document}

enter image description here