我正在忙着处理一份文件,需要添加一个附录,其中包含姓名列表和简短的传记(每人约一段)。
如果我能做到这一点,我会更高兴,因为我在相关章节中描述了这个人,将其保存到宏中,然后添加到最后。类似于参考书目。
是否有一个包可以做到这一点或者有办法构建这样的宏?
答案1
我会采取与 Seamus 略有不同的方法。
我们首先定义一个列表来保存所有名称。该列表将用逗号分隔:
\def\alist{}% {George, Martin, Seamus, Yiannis}
然后我们定义辅助宏来将人员添加到列表中。同时我们动态创建一个命令来保存个人简介。例如,键入\Mary
将为该人员排版个人简介。
要打印附录中的 Bios,我们只需输入:
\PrintBios
我们还添加了一些辅助函数来保持列表排序,以便我们可以按字母顺序打印它们。这些是从 listings 包借用的(只是一个 BubbleSort)。
为了循环遍历列表,我们使用@for
LaTeX 内核的。
这是包含所有这些内容的最小版本。Bios 只是lipsum
软件包中的段落。
\documentclass[11pt]{book}
\usepackage{lstdoc,lipsum}
\begin{document}
\makeatletter
\def\alist{}
\let\sort\lst@BubbleSort
\def\addtolist#1#2{
\lst@lAddTo\alist{#2}
}
\long\gdef\addPerson#1#2{\addtolist\alist{#1,}}
\def\AddBio#1#2{%
\long\expandafter\gdef\csname#1\endcsname{\textbf{#1}: #2}
\addPerson{#1}{#2}
\sort\alist
}
\def\PrintBios{%
\@for \i:=\alist\do{%
\csname\i\endcsname}
}
%example
\AddBio{Yiannis}{\lipsum[2]}
\AddBio{Mary}{\lipsum[3]}
\AddBio{Ann}{\lipsum[1]}
% print the biographies
\PrintBios
\makeatother
\end{document}
我不太确定对于数百个 Bios 来说编译速度会有多快,但对于大约 100-200 个 Bios 来说,编译时间是难以察觉的。
答案2
以下是使用newfile
包来实现这一点。显然,它需要一些调整。其中很多内容借鉴自这个问题. 还要感谢马丁·沙雷尔以供评论。
这个想法是将每个作者的简历写入一个文件,然后在最后将其全部读入。
\documentclass{book}
\usepackage{newfile}
\usepackage{lipsum}
\newoutputstream{bios}
\openoutputfile{\jobname.bio}{bios}
\newcommand\styleauthor[1]{{\bfseries \begin{center}#1\end{center}}}
\newcommand\authorbio[2]{%
\addtostream{bios}{%
\unexpanded{%
\styleauthor{#1}%
\par
#2
\vspace{\baselineskip}}
}
}
\begin{document}
\chapter{Foo}
\authorbio{A. Author}{Here is a short bio on Albert Author
\lipsum[2]}
\chapter{Bar}
\authorbio{B. Buthor}{Here is a short bio on Brian Buthor
This allows newlines. Sweet.}
\appendix
\chapter{Author bios}
\closeoutputstream{bios}
\input{\jobname.bio}
\end{document}
答案3
只是为了好玩,这是 Yiannis 的答案在 LaTeX3 中的重新实现。想法完全相同:该\AddBio
命令将作者姓名和简历保存到宏中,并使用参数sort
来命名它们。这sort
也是作者排序的依据。
这利用了 egreg 的解决方案来以 l3 方式对字符串进行排序。(代码在注释中链接了答案)。
\documentclass{article}
\usepackage{xparse,expl3,kantlipsum,l3sort}
\ExplSyntaxOn
\seq_new:N \l_authorlist_seq
% Sort, Author Name, Bio
\NewDocumentCommand{\AddBio}{mm+m}{
\tl_new:c {l_#1_name_tl}
\tl_gset:cn {l_#1_name_tl} {#2}
\tl_new:c {l_#1_bio_tl}
\tl_gset:cn {l_#1_bio_tl} {#3}
\seq_gput_right:Nn \l_authorlist_seq {#1}
}
% From egreg's answer: http://tex.stackexchange.com/a/52967/215
\prg_new_conditional:Npnn \string_compare:nnn #1 #2 #3 {TF}
{
\if_int_compare:w \pdftex_strcmp:D {#1}{#3} #2 \c_zero
\prg_return_true:
\else:
\prg_return_false:
\fi
}
\NewDocumentCommand{\sortauthors}{ }{
\seq_sort:Nn \l_authorlist_seq {
\string_compare:nnnTF {##1} {>} {##2} {\sort_reversed:} {\sort_ordered:}
}
}
\NewDocumentCommand{\PrintBio}{m}{
\textbf{\tl_use:c {l_#1_name_tl}:~} \tl_use:c{l_#1_bio_tl}\par
}
\NewDocumentCommand{\PrintBios}{}{
\sortauthors
\seq_map_inline:Nn \l_authorlist_seq {\PrintBio{##1}}
}
\ExplSyntaxOff
\begin{document}
\AddBio{foo}{Jethro Foo}{\kant[1-2]}
\AddBio{bar}{Horatio Bar}{\kant[2-3]}
\AddBio{kant}{Immanuel Kant}{\kant[5]}
\PrintBios
\end{document}
我确信其中一些命令等不符合 LaTeX3 的宏命名约定,但这是一个概念证明......