使用重复命令创建动态列表变量

使用重复命令创建动态列表变量

我需要在 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}

在此处输入图片描述

相关内容