Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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

share|improve this question

3 Answers 3

up vote 10 down vote accepted

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).

share|improve this answer

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).

share|improve this answer
1  
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

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.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.