![将多位作者添加到目录](https://linux22.com/image/344010/%E5%B0%86%E5%A4%9A%E4%BD%8D%E4%BD%9C%E8%80%85%E6%B7%BB%E5%8A%A0%E5%88%B0%E7%9B%AE%E5%BD%95.png)
我正在尝试将作者列表添加到目录中,但不知为何无法成功。我认为,由于列表已写入文件,因此需要保护该列表,但这似乎行不通。
虽然有点长,但是 MWE 如下:
\documentclass[10pt, onecolumn, final]{book}
\usepackage{url}
\usepackage{graphicx}
\usepackage{forloop}
\usepackage{lipsum}
\usepackage{microtype}
\usepackage{suffix}
\usepackage{etoolbox}
%%% Code to add multiple authors to a chapter and to the TOC
\newcounter{chapterauthornum}
\newcounter{authorlstnum}
\newcounter{authorcounter}
%% Create variables to save author and institution information
\newcommand\chapterauthors[2]{%
\stepcounter{chapterauthornum}
\protect\expandafter\def\csname chapterauthorsname\thechapterauthornum\endcsname{\protect{#1}}
\protect\expandafter\def\csname chapterinstsname\thechapterauthornum\endcsname{\protect{#2}}
}
%% Command to print author and institution list below the chapter heading and generate the author list for the TOC
\newcommand\printauthorlist{
%%% Print author list with institutions
\getauthorchapterlist % List bleow chatper heading
%%% Add authors to Table of Contents
\printauthortoclist % Prints list for testing
\makeauthortoclist % Adds list of authors to Table of Contents
\setcounter{chapterauthornum}{0} % Resets everything for next chapter
}
%% Generates the list that goes below the chapter headng
\newcommand\getauthorchapterlist{%
\setcounter{authorlstnum}{\value{chapterauthornum}}
\setcounter{authorcounter}{0}
\loop
\ifnum\value{authorlstnum}>0 %
\stepcounter{authorcounter}
{\parindent0pt\vspace*{-15pt}%
\linespread{1.1}
\raggedleft\large\bfseries\itshape
\csname chapterauthorsname\theauthorcounter\endcsname
\par\nobreak\vspace*{15pt}
}
{\parindent0pt\vspace*{-15pt}%
\linespread{1.1}
\raggedleft\normalfont
\csname chapterinstsname\theauthorcounter\endcsname
\par\nobreak\vspace*{20pt}
}
\addtocounter{authorlstnum}{-1}
\repeat
\par\nobreak\vspace*{10pt}
}
%% Generate the list of authors that will go into the Table of Contents
\newcommand\makeauthortoclist{%
% \protect
\forloop{authorcounter}{1}{\value{authorcounter} < \value{chapterauthornum}}
{\expandafter\csname chapterauthorsname\theauthorcounter\endcsname, \relax}
{and \expandafter\csname chapterauthorsname\thechapterauthornum\endcsname}
}
%% use the list of authors generated and adds them to the Table of Contents
\newcommand{\printauthortoclist}{%
\addtocontents{toc}{%
% \vskip-5mm
\protect\contentsline{chapter}%
% \hskip1.3em\mdseries\itshape\protect\scriptsize
{\hskip1.3em\mdseries\scshape\protect\scriptsize\makeauthortoclist}{}{}}
}
\title{Models and Reality}
\author{John Dobleman}
\begin{document}
\frontmatter
\tableofcontents
\mainmatter
\chapter{A Probabilistic Analysis}
\chapterauthors{Gilna Samuel}{Department of Finance, Rensselaer Polytechnic Institute}
\chapterauthors{Cornelius Longbottom}{Department of Magic and Tchnology, MIT}
\chapterauthors{Nat Granger}{Department of Muggle Integration, Ministry of Magic}
\printauthorlist
\section{Magic and what it means}
\lipsum[1-3]
\end{document}
所以问题是,虽然列表按照我想要的方式生成,但它并没有被添加到目录中;只有最后一位作者被添加了。我知道它正在生成,因为我在正文中添加了下面的列表。
我怀疑这与我使用 csname 的方式有关。如能得到任何帮助,我将不胜感激。
答案1
问题在于,的论证\addtocontents
是一个移动论证(它被移动到了目录中),并且\forloop
论证中使用的是脆弱的(它包含“作业”)。
\forloop
旨在打印文本,而不是在参数中收集文本。您必须以不同的方式执行此操作,要么通过将其收集在用作变量的宏中,要么通过将其收集在令牌寄存器中。
以下是使用宏的解决方案:
\newcommand\authortoclist{}
\newcommand\addto[2]{%
\edef#1{#1#2}}%
%% Generate the list of authors that will go into the Table of Contents
\newcommand\makeauthortoclist{%
\def\authortoclist{}
\forloop{authorcounter}{1}{\value{authorcounter} < \value{chapterauthornum}}
{\addto\authortoclist{\expandafter\csname chapterauthorsname\theauthorcounter\endcsname, }}
\addto\authortoclist{and \expandafter\csname chapterauthorsname\thechapterauthornum\endcsname}
}
%% To print the list of authors, just use \makeauthortoclist \authortoclist
%% use the list of authors generated and adds them to the Table of Contents
\newcommand{\printauthortoclist}{%
\makeauthortoclist
\addtocontents{toc}{%
\vskip-2mm
\protect\contentsline{chapter}%
{\hskip1.3em\mdseries\scshape\protect\scriptsize \authortoclist}{}{}\vskip2mm}
}
答案2
这是另一个使用令牌寄存器而不是宏的解决方案。使用宏的解决方案仍然不够稳健,因为宏\edef
中\addto
存在。如果作者和机构仅包含 ASCII 字符,则它可以工作,但如果有重音字符,则它会失败。要制作一个稳健的解决方案需要做更多工作,但这里是:
\newtoks\authortoclist
\newcommand\action{}
\newcommand\addto[2]{%
\toks0={#2}
\edef\action{\noexpand#1={\the#1\the\toks0}}%
\action}
%% Generate the list of authors that will go into the Table of Contents
\newcommand\makeauthortoclist{%
\authortoclist={}
\forloop{authorcounter}{1}{\value{authorcounter} < \value{chapterauthornum}}
{\expandafter\addto\expandafter\authortoclist\expandafter{\csname chapterauthorsname\theauthorcounter\endcsname, }}
\addto\authortoclist{and }
\expandafter\addto\expandafter\authortoclist\expandafter{\csname chapterauthorsname\thechapterauthornum\endcsname}
}
%% To print the list of authors, just use \makeauthortoclist \the\authortoclist
%% use the list of authors generated and adds them to the Table of Contents
\newcommand{\printauthortoclist}{%
\makeauthortoclist
\addtocontents{toc}{%
\vskip-2mm
\protect\contentsline{chapter}%
{\hskip1.3em\mdseries\scshape\protect\scriptsize \the\authortoclist}{}{}\vskip 2mm}
}