我需要在 LaTeX 中创建一个列表n人数及其各自的性别:
\adduser[M]{Pedro Jose}
\adduser[M]{John Scar}
\adduser[F]{Leila Brew}
...
\adduser[F]{Larissa Yik}
当我使用 LaTeX 编译它时,我希望它产生类似这样的内容:
Pedro Jose is Male
John Scar is Male
Leila Brew is Female
...
Larissa Yik is Female
我尝试使用以 分隔的变量的原始 LaTeX 重复函数;
,但它不起作用。有什么想法吗?
@更新
史蒂文解答了这个问题。
\documentclass{minimal}
\usepackage[utf8]{inputenc}
\makeatletter
\newcommand*\userlist{}
\newcommand*\adduser[2][]
{\g@addto@macro\userlist{
#2\ifx M#1 is male\fi\ifx F#1 is female\fi.\\
}}
\makeatother
% User's to add
\adduser[M]{Pedro Jose}
\adduser[M]{John Scar}
\adduser[F]{Leila Brew}
\adduser[F]{Larissa Yik}
\begin{document}
{\noindent\textbf{User list:}}%
\noindent\userlist
\end{document}
答案1
我建议使用数据工具- 打包并维护两个数据库:
- 一个数据库用于添加条目。
该数据库将在 LaTeX 运行结束时保存到外部文本文件中。
在下面的示例中,该数据库称为“usersinterim”。 - 另一个数据库用于迭代条目。
该数据库是在 LaTeX 运行开始时通过加载上次运行期间创建的外部文本文件创建的。
该数据库包含在以前的LaTeX 运行。
在下面的例子中,该数据库被称为“用户”。
这样,您甚至可以在添加用户之前创建所有用户等的列表。
但您至少需要编译该文档两次。
\documentclass{article}
\usepackage{datatool}
\usepackage{atveryend}
\newcommand\DATABASEFILECreateIfNotExistent[1]{%
\DTLifdbexists{#1}{}{%
\IfFileExists{\jobname.#1}{%
\DTLloaddb{#1}{\jobname.#1}%
}{%
\DTLnewdb{#1}%
}%
}%
\DTLifdbexists{#1interim}{}{%
\DTLnewdb{#1interim}%
\AtEndDocument{%
% This will save the interim-database to file with
% the last \shipout. The last \shipout is triggered
% by \end{document}/\enddocument.
\DTLsavedb{#1interim}{\jobname.#1}%
}%
\AfterLastShipout{%
% Check whether the content of the database-token-register
% stemming from the database-file of the previous LaTeX-run
% differs from content of the database-token-register
% stemming from the database-file of the current LaTeX-run.
% If so, something changed and you need to re-run LaTeX.
% Probably this should be omitted with large databases.
\begingroup
\DTLgdeletedb{#1interim}%
\DTLloaddb{#1interim}{\jobname.#1}%
\edef\tempa{\the\csname dtldb@#1\endcsname}%
\edef\tempb{\the\csname dtldb@#1interim\endcsname}%
\ifx\tempa\tempb
\endgroup
\else
\endgroup
\csname @latex@warning@no@line\endcsname{%
Database `#1' may have changed.
Rerun to get listings of entries etc right%
}%
\fi
}%
}%
}%
\newcommand\usercount{0}%
\newcommand\stepusercount{%
\xdef\usercount{\number\numexpr\usercount+1\relax}%
}%
\newcommand\adduser[2][]{%
\stepusercount
\DATABASEFILECreateIfNotExistent{users}%
\DTLnewrow{usersinterim}%
{%
\dtlexpandnewvalue
\DTLnewdbentry{usersinterim}{primary key}{\usercount}%
}%
\DTLnewdbentry{usersinterim}{name}{#2}%
\DTLnewdbentry{usersinterim}{gender}{#1}%
}%
\newcommand\GenderListOfAllUsers{%
\DATABASEFILECreateIfNotExistent{users}%
\DTLforeach{users}{\NameField=name, \GenderField=gender}{%
\par\noindent
\NameField
\expandafter\lowercase\expandafter{\expandafter\ifx\GenderField}m%
\space is male%
\else
\expandafter\lowercase\expandafter{\expandafter\ifx\GenderField}f%
\space is female%
\else
's gender is not identified%
\fi
\fi
.%
}%
}%
\begin{document}
\noindent\textbf{List of all users:}\medskip
\GenderListOfAllUsers
\bigskip
\noindent\textbf{Some text.}
\bigskip
\adduser[M]{Pedro Jose}
\adduser[M]{John Scar}
\adduser[F]{Leila Brew}
\adduser[F]{Larissa Yik}
\adduser[?]{John Doe}
\adduser{Smith, John}
\noindent\textbf{List of all users:}\medskip
\GenderListOfAllUsers
\end{document}