我需要一个新命令\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
您可以按如下方式使用\IfSubStr
该xstring
包:
\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
逗号列表处理的优点是可以根据董事人数更轻松地更改行为(例如,如果有两名以上的董事,则希望在姓名后面加上逗号)。