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}
8
  • 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}? Feb 7 at 17:40
  • @likethevegetable I always use lua yes. And the semicolon syntax is a great idea Feb 7 at 17:43
  • 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}} ? Feb 8 at 12:15
  • 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 8 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.) Feb 8 at 13:19

8 Answers 8

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

5
  • I admit I am quite amazed at the concision of the code. Just, there is no "and" at the end. Feb 8 at 15:35
  • @VincentKrebs Updated with this change.
    – Gaussler
    Feb 8 at 16:13
  • This is crazy what you achieve with this g type. Thank you very much... Feb 8 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 8 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. Feb 8 at 17:00
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}
9
  • Note that babel and polyglossia are defining the macro \addto as well, but a bit differently, maybe a different name would be better to avoid collisions.
    – Udi Fogiel
    Feb 7 at 19:25
  • Thanks ! I will try this. Note that I don't want math mode. Feb 7 at 19:31
  • @VincentKrebs, the macro \textsubscript that you used in your mwe also use math mode...
    – Udi Fogiel
    Feb 7 at 19:40
  • 2
    I am using \addto from my OPmac / OpTeX.
    – wipet
    Feb 7 at 19:45
  • 2
    @VincentKrebs OK, I added the feature about optional arguments 2 and 3.
    – wipet
    Feb 8 at 4:46
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

11
  • 1
    @VincentKrebs Please see my ADDENDUM. Feb 7 at 20:59
  • 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? Feb 7 at 21:49
  • 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. Feb 7 at 23:04
  • 1
    @VincentKrebs I have provided a secondary answer that functionally mimics wipet's approach of checking the input stream for an opening brace. Feb 7 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. Feb 7 at 23:34
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.

6
  • 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! Feb 7 at 22:47
  • Note that likethevegetable's idea to use semicolons is very good too. Feb 7 at 23:14
  • @VincentKrebs This starts being an XYZUVW problem. Look at the “further answer”.
    – egreg
    Feb 7 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. Feb 7 at 23:21
  • 1
    @VincentKrebs Pretty straightforward, see edit
    – egreg
    Feb 7 at 23:31
5

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}
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

1
  • Yes indeed, \relax can come in handy. But since it is to be used inside text, most of the time it won't be necessary. Feb 7 at 23:10
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

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

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.