如何根据参数中的 \and 选择单数或复数形式

如何根据参数中的 \and 选择单数或复数形式

我需要一个新命令\director(类似于author)来写入项目的导演姓名。但我想在姓名前面写上 Director 或 Directors(如果不止一个)这个词。最简单的方法是使用两个命令\director,但是否可以使用一个命令来检测参数中的\directors单词并选择复数形式。\and

一个例子:

\director{John}生产

导演: 约翰

\director{John and Paul}生产

导演:约翰、保罗

答案1

这是一个“旧式”的解决方案:

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

如果只是and首选,那么较短的代码就足够了

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

输入将是

\director{John}

\director{John and Paul}

一种“新风格”的解决方案(带有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}

这将输出

导演:约翰
导演:约翰和保罗
导演:约翰、保罗和乔治
导演:约翰、保罗、乔治和林戈

取消注释最后定义中的行将在有三位或更多导演的情况下在“and”之前添加一个逗号(美式风格)。

答案2

您可以按如下方式使用\IfSubStrxstring包:

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

我在周围添加了一个空格,以便在作为名称一部分的and情况下不使用复数,如第二个示例所示。and

答案3

一个完全不同的解决方案:为什么不将输入更改为接受以逗号分隔的导演列表,检查列表的大小,然后相应地使用导演。例如:

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

或者

\setdirectors[John, Paul]

编辑以下是 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                                                                                           

逗号列表处理的优点是可以根据董事人数更轻松地更改行为(例如,如果有两名以上的董事,则希望在姓名后面加上逗号)。

相关内容