![自动列出文档中的作者](https://linux22.com/image/458448/%E8%87%AA%E5%8A%A8%E5%88%97%E5%87%BA%E6%96%87%E6%A1%A3%E4%B8%AD%E7%9A%84%E4%BD%9C%E8%80%85.png)
我有一个命令\by{ }
可以让我列出这样的文章的作者:
\by{
{author 1}{tagline} \\
{author 2}{tagline} \\
{author 3}{tagline} \\
<etc.>
}
我想将、、等存储author 1
在author 2
某种author 3
列表中,并像这样打印该列表:
author 1 \\
author 2 \\
author 3 \\
<etc.>
我还希望能够手动添加名称(即未使用的名称\by
)。例如,名称Jane
。
重要的是,每个名字只出现一次在列表中。如果author 1
写了两篇文章,他们的名字仍然应该只在印刷的作者列表中出现一次。
我还有一个环境\mytextbox
显示此列表的环境。但是,我不想修改此环境以自动打印作者,因为我仍然希望能够在这个环境中手动输入作者作为“故障保护”,以防由于某种原因自动列表出现错误(例如,由于将来导入了新的包或另一段新代码)。我选择将此环境包含在 MWE 中,以确保解决方案与其兼容。
梅威瑟:
\RequirePackage{fix-cm}
\documentclass[fontsize=13pt,paper=a4,openany,parskip=half,DIV=calc]{scrbook}
\usepackage[T1]{fontenc}
\usepackage{DejaVuSans} % Sans-serif
\usepackage{lipsum}
% mytextbox environment:
\RequirePackage{eso-pic}
\newcommand{\overlaytextbox}[3]{% \placetextbox{<horizontal pos>}{<vertical pos>}{<stuff>}
\AddToShipoutPictureFG*{%
\put(\LenToUnit{#1\paperwidth},%
\LenToUnit{#2\paperheight}){\vtop{{\null}\parbox{0.3\textwidth}{#3}}}
}%
}%
\newcommand{\mytextbox}[2][black]{%
\overlaytextbox{0.05}{0.94}{% 0.65 og 0.94 for plassering til høyre
\color{#1}
\subsubsection*{Authors}%
%\vspace{3mm}%
\linespread{1.6}\selectfont
{\itshape
#2
}%
}%
}%
% \by command:
\def\by#1{\vspace{1mm}{\centering\fontsize{7}{10}\sffamily Written by \\}\vspace{5pt}\setbox1=\box0 \setbox1=\box3 \byA\\#1\end}
\def\byA#1{\ifx\end#1\expandafter\byC
\else
\expandafter\byB
\fi
}
\def\byB#1#2{%
\ifvoid3
\setbox1=\hbox{\makebox{\vtop{\halign{\hfil##\hfil\cr{\fontsize{9}{11}\sffamily\MakeUppercase{#1}}\vspace{-5pt}\cr{\fontsize{7}{10}\sffamily#2}\cr}}}}%
\ifvoid0\setbox0=\box1
\else
\setbox2=\hbox{\unhcopy0 \ \hspace{2mm}{\fontsize{7}{10}\sffamily and} \hspace{2mm} \unhcopy1 \ \hspace{2mm} {\fontsize{7}{10}\sffamily et al.}}
\ifdim\wd2>\hsize
\setbox3=\hbox{ \unhbox0 \ \hspace{2mm}{\fontsize{7}{10}\sffamily et al.}\hspace{2mm}}
\else
\setbox0=\hbox{\unhbox0 \ \hspace{2mm}{\fontsize{7}{10}\sffamily and}\hspace{2mm} \unhbox1}
\fi
\fi
\fi
\byA
}
\def\byC{\ifvoid3 \setbox3=\box0 \fi \hbox to\hsize{\hss\box3\hss}\bigskip}
\begin{document}
\hfill
\begin{minipage}[t]{0.6\textwidth}
\begin{center}
\lipsum[1-2]
\end{center}
\end{minipage}
\mytextbox[red]{
% some command to list authors here:
% for exaple \authorlist
Someone \\
Firstname Lastname \\
Myname is Bond \\
Paul \\
Jane \\
}
\clearpage
{\centering \sffamily\textbf{First Article}\\}
\by{
{Someone}{Tagline}
}
\lipsum[1]
{\centering \sffamily\textbf{Second Article}\\}
\by{
{Firstname Lastname}{Hey ho matey yo ho} \\
{Someone}{New tagline}\\
{Myname is Bond}{Secret Service} \\
{Paul}{Physicist}
}
\lipsum[1]
{\centering \sffamily\textbf{Third Article}\\}
\by{
{Paul}{Still a physicist}
}
\lipsum[1]
{\centering \sffamily\textbf{Poem}\\}
\begin{center}
foo \\
baz \\
baa foo!
\end{center}
Thank you Jane for creating this poem!
\end{document}
我该怎么做?在哪里可以找到有关如何在 LaTeX 中制作此类列表的更多信息?我想我必须使用某种 if 语句来检查作者是否已在列表中?
我目前能想到的唯一解决方案是使用expl3
token 列表和\str_case:nnF{ author }{ {<compare to list element>}{} }{ <add to list> }
。但是,我认为将 和纯 TeX 结合起来可能不是一个好主意expl3
。另外,我并不完全确定如何实现这种方法。
答案1
您可以添加\addauthor{#1}
到宏中\byB
(在此宏的顶部):
\def\byB#1#2{%
\addauthor{#1}%
\ifvoid3
...
您可以定义宏\addauthor
:
\def\authorlist{}
\def\addauthor#1{\immediate\write\csname @mainaux\endcsname{\string\xauthor{#1}}}
\def\xauthor#1{%
\unless \ifcsname xa:#1\endcsname
\expandafter\gdef\csname xa:#1\endcsname{}
\expandafter\gdef\expandafter\authorlist\expandafter{\authorlist #1\\}
\fi
}
最后,你可以\authorlist
在红框中使用,因为这个列表包括
author1\\author2\\author3\\...
在第二次运行 TeX 之后。我们使用该.aux
文件是因为您想\authorlist
在作者被读取之前知道\by
。
如果您想将 Jane 添加到列表中,您可以在红框中手动执行此操作,也可以\addauthor{Jane}
在“感谢”文本中的“foo baz baa foo”诗歌后面写入。