# How to choose singular or plural form from presence of \and in argument

I need a new command \director (similar to author) to write project's director names. But I would like to write the word Director or Directors (if more than one) in front of the names. The easiest way is to use two commands \director and \directors but is it possible to use one command who detects the word \and into the argument and selects plural form.

An example:

\director{John} produces

Director: John

\director{John and Paul} produces

Directors: John, Paul

-

Here's a solution in the "old style":

\documentclass[a4paper]{article}

\def\director{\begingroup\def\and{and }\dodirector}
\def\dodirector#1{%
\def\theargument{#1}\dodirectori#1\and\dodirector\endgroup}
\def\dodirectori#1\and#2\dodirector{%
\if\relax\detokenize{#2}\relax % no \and
Director: #1%
\else
Directors: \theargument
\fi}

\begin{document}

\director{John}

\director{John \and Paul}

\end{document}


If only and is preferred, then a shorter code suffices

\def\director#1{\def\next{#1}\dodirector#1 and \dodirector}
\def\dodirector#1 and #2\dodirector{%
\if\relax\detokenize{#2}\relax % no \and
Director: \next
\else
Directors: \next
\fi}


The input would be

\director{John}

\director{John and Paul}


A "new style" solution (with expl3)

\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\director}{ m }
{
\ignasi_print_director:n { #1 }
}
\cs_new_protected:Npn \ignasi_print_director:n #1
{
\seq_set_split:Nnn \l_ignasi_director_seq { \and } { #1 }
\seq_pop_left:NN \l_ignasi_director_seq \l_ignasi_temp_tl
\seq_if_empty:NTF \l_ignasi_director_seq
{ Director: ~ \tl_use:N \l_ignasi_temp_tl }
{
Directors: ~ \tl_use:N \l_ignasi_temp_tl
\ignasi_andify:
}
}
\cs_new_protected:Npn \ignasi_andify:
{
\seq_pop_right:NN \l_ignasi_director_seq \l_ignasi_temp_tl
\seq_map_inline:Nn \l_ignasi_director_seq {, ~ ##1}
% \seq_if_empty:NF \l_ignasi_director_seq {,} % uncomment for ", and" style
\c_space_token and ~ \tl_use:N \l_ignasi_temp_tl
}
\seq_new:N \l_ignasi_director_seq
\tl_new:N \l_ignasi_temp_tl
\ExplSyntaxOff
\begin{document}
\director{John}

\director{John \and Paul}

\director{John \and Paul \and George}

\director{John \and Paul \and George \and Ringo}
\end{document}


This will output

Director: John
Directors: John and Paul
Directors: John, Paul and George
Directors: John, Paul, George and Ringo

Uncommenting the line in the last definition will add a comma before "and" in case of three or more directors (American style).

-

You can use \IfSubStr from the xstring package as follows:

\documentclass{article}
\usepackage{xstring}%
\newcommand*{\director}[1]{\IfSubStr{#1}{ and }{Directors}{Director}: #1}%

\begin{document}
\director{John and Paul}

\director{John Rands}% Test having "and" as part of the name
\end{document}


I added a space around and to not use the plural for the case where and is part of a name, as in the second example.

-

A completely different solution: Why not change the input to accept a comma-separated list of directors, check the size of the list and then use director or directors accordingly. For example:

\setup<....>
[directors={John, Paul}]


or

\setdirectors[John, Paul]


EDIT Here is an example implementation in ConTeXt

\setuplabeltext[director={Director: }, directors={Directors: }]

\def\doshowdirectors  #1{#1\let\showdirectors\redoshowdirectors}
\def\redoshowdirectors#1{ and #1}

\startsetups print:directors
\getcommacommandsize[\getvariable{document}{director}]
\doifelse{\commalistsize}{1}
{\labeltext{director}}
{\labeltext{directors}}

\let\showdirectors\doshowdirectors
\processcommacommand[\getvariable{document}{director}]\showdirectors

\stopsetups

\setvariables
[document]
[set={\setups{print:directors}}]

\starttext

\setvariables
[document]
[director={John, Paul}]

\setvariables
[document]
[director={John}]

\stoptext


The advantage of a comma list processing is that it is much easier to change the behaviour depending on the number of directors (e.g., if you want a comma after the name if there are more than two directors).

-
This is rather incomplete. –  egreg Sep 19 '11 at 17:57
@egreg: Rest is just a matter of simple comma list processing. I am adding a ConTeXt version of it. –  Aditya Sep 19 '11 at 19:15
Not everybody is acquainted with comma list processing in ConTeXt. :) –  egreg Sep 19 '11 at 19:21
@egreg: I used ConTeXt just because I am more familiar with it. The implementation using expl3 code will be similar. –  Aditya Sep 19 '11 at 20:09