解析作者数据的包

解析作者数据的包

是否有一个通用的解决方案来解析文档作者数据(姓名、地址、电子邮件等)?我设想的是

\documentclass{whatever}

\addauthor[email = ..., address = ..., other = ..., name = Alice]
\addauthor[email = ..., address = Bob's address, other = ..., name = Bob]

% Now I retrieve it however I want to create a title page

\getauthor{1}{name}  % gives Alice
\getauthor{2}{address} % gives Bob's address

自己编写程序有点超出我的能力,但看起来很有用。目前,我正在使用许多不同的文档类,每个类都有自己独特的解析作者数据的方式。

答案1

我提出了两种基于 的解决方案datatool。第一种需要外部database1.csv文件(在下面的 mwe 中,它由环境生成)。第二种解决方案通过以下命令直接在 .tex 文件中filecontents创建数据库(名为):database2

\DTLnewdb{database2}

\newcommand{\addauthor}[5]{
  \DTLnewrow{database2}%
  \DTLnewdbentry{database2}{num}{#1}
  \DTLnewdbentry{database2}{email}{#2}
  \DTLnewdbentry{database2}{address}{#3}
  \DTLnewdbentry{database2}{other}{#4}
  \DTLnewdbentry{database2}{name}{#5}
}

\addauthor{1}{email1}{Alice's address}{other1}{Alice}
\addauthor{2}{email2}{Bob's address}{other2}{Bob}
\addauthor{3}{email3}{Markus's address}{other3}{Markus}

该命令\getauhor从第一个参数给出的行中提取第二个参数给出的值:

\newcommand{\getauthor}[2]{%
  \DTLforeach*[\DTLiseq{\num}{#1}]
  {database1}%database label
  {\num=num,\email=email,\address=address,\other=other,\name=name}% assignment
  {\csname#2\endcsname}
}

这是一个最小的工作示例:

\documentclass{book}
\usepackage{datatool}
%--------------------------------------------------
% First method
%--------------------------------------------------
\begin{filecontents}[overwrite]{database1.csv}
    num,email,address,other,name
    1,email1,Address 1,Other 1, Isaak Bacharach
    2,email2,Address 2,Other 2, Reinhold Baer
    3,email3,Address 3,Other 3, Christian Bär
    4,email4,Address 4,Other 4, Wolf Barth
\end{filecontents}

\DTLloaddb{database1}{database.csv}
\newcommand{\getauthor}[2]{%
    \DTLforeach*[\DTLiseq{\num}{#1}]
    {database1}%database label
    {\num=num,\email=email,\address=address,\other=other,\name=name}% assignment
    {\textbf{\csname#2\endcsname}}
}
%--------------------------------------------------
%Second method
%--------------------------------------------------
\DTLnewdb{database2}
\newcommand{\addauthor}[5]{
\DTLnewrow{database2}%
\DTLnewdbentry{database2}{num}{#1}
\DTLnewdbentry{database2}{email}{#2}
\DTLnewdbentry{database2}{address}{#3}
\DTLnewdbentry{database2}{other}{#4}
\DTLnewdbentry{database2}{name}{#5}
}
\addauthor{1}{email1}{Alice's address}{other1}{Alice}
\addauthor{2}{email2}{Bob's address}{other2}{Bob}
\addauthor{3}{email3}{Markus's address}{other3}{Markus}

\newcommand{\GetAuthor}[2]{%
    \DTLforeach*[\DTLiseq{\num}{#1}]
    {database2}%database label
    {\num=num,\email=email,\address=address,\other=other,\name=name}% assignment
    {\textbf{\csname#2\endcsname}}
}

\begin{document}

\section{First method (\texttt{database1.csv})}

The name of the forth entry is \getauthor{4}{name}\\    
The address of the second entry is \getauthor{2}{address}

\section{Second method (\texttt{database2})}

The name of the first entry is \GetAuthor{1}{name}\\    
The address of the second entry is \GetAuthor{2}{address}
    
\end{document}

答案2

例如,可以使用 expl3 的属性列表来实现这一点——我稍微改变了语法,需要一些作者 ID,而不是暗示一个递增的数字(当然也可以实现):

\documentclass{article}

\ExplSyntaxOn
\tl_new:N \l__innisfree_author_tl

\cs_new_protected:Npn \innisfree_add_author:nn #1#2
  {
    \prop_if_exist:cF {l__innisfree_author_#1_prop}
      { \prop_new:c {l__innisfree_author_#1_prop} }
    \tl_set:Nn \l__innisfree_author_tl {#1}
    \keyval_parse:NNn
      \__innisfree_value_missing:n
      \__innisfree_set_property:nn
      {#2}
  }

\cs_set_protected:Npn \__innisfree_value_missing:n #1
  { \prop_put:cnn {l__innisfree_author_ \l__innisfree_author_tl _prop} {#1} {??} }

\cs_set_protected:Npn \__innisfree_set_property:nn #1#2
  { \prop_put:cnn {l__innisfree_author_ \l__innisfree_author_tl _prop} {#1} {#2} }
  
\cs_new:Npn \innisfree_get_author:nn #1#2
  { \prop_item:cn {l__innisfree_author_#1_prop} {#2} }

\NewDocumentCommand \addauthor {mm}
  { \innisfree_add_author:nn {#1} {#2} }

\NewDocumentCommand \getauthor {mm}
  { \innisfree_get_author:nn {#1} {#2} }
\ExplSyntaxOff

\addauthor{a}{email = ..., address = ..., other = ..., name = Alice}
\addauthor{b}{email = ..., address = Bob's address, other = ..., name = Bob}

\begin{document}

\getauthor{a}{name} \par
\getauthor{b}{address}

\end{document}

在此处输入图片描述


只是为了好玩,让我们滥用它acro作为替代“解决方案”。虽然这不是一个完全严肃的建议,但实际上它可以相当安全地使用:

\documentclass{article}

\usepackage{acro}
\DeclareAcroProperty{name}
\DeclareAcroProperty{email}
\DeclareAcroProperty{address}
\DeclareAcroProperty{other}

\newcommand\addauthor[2]{%
  \DeclareAcronym{#1}{
    short = #1 , long = #1 , #2 ,
    tag = authors % a filter to separate them from ``real'' acronyms – not
                  % really necessary
  }%
}

\newcommand*\getauthor[2]{\acrofield{#1}{#2}}

\addauthor{a}{email = ..., address = ..., other = ..., name = Alice}
\addauthor{b}{email = ..., address = Bob's address, other = ..., name = Bob}

\begin{document}

\getauthor{a}{name} \par
\getauthor{b}{address}

\end{document}

相关内容