是否可以使用另一个命令创建一个命令,并将代码作为字符串传递?

是否可以使用另一个命令创建一个命令,并将代码作为字符串传递?

我想循环遍历一个列表并打印一些文本。该文本的位置在表格内,在 \makecell 命令内。我可以对我想要的列表中的项目进行硬编码,包括一些用于换行的 \\ 命令。但我不想硬编码,我想使用循环。MWE:

\documentclass[]{article}
\usepackage{makecell}
\usepackage{pgffor}
\newcommand\AuthorList{First MI. Last, First MI. Last, First MI. Last}
\newcommand\PrintAuthorList{\foreach \x in \AuthorList
    {
        \x
    }
}

\begin{document}

\begin{table*}[h]
    \begin{tabular}{|l|l|}
        \hline
        \makecell[tl]{row 1, line 1 \\ row 1, row 2} & stuff\\
        \hline
        row 2, no cells & \makecell{This is where I want to print the author list, one per line:\\ \PrintAuthorList}\\
        \hline
    \end{tabular}
\end{table*}

\begin{table*}[h]
    \begin{tabular}{|l|l|}
        \hline
        \makecell[tl]{row 1, line 1 \\ row 1, row 2} & stuff\\
        \hline
        row 2, no cells & \makecell{This is where I've hard-coded the result I want:\\ First MI. Last\\First MI. Last\\First MI. Last}\\
        \hline
    \end{tabular}
\end{table*}

\end{document}

该代码可以编译,但不会在作者姓名之间换行。如果我将 \\ 添加到 foreach 循环中,它甚至不会编译。

我的想法是,我使用一个命令创建一个带有我想要的斜杠的字符串,并将该字符串作为代码传递到我的 \makecell 环境中。例如:

\newcommand{\MakeAuthorString}{\foreach \x in \AuthorList{\x\textbackslash\textbackslash}}

但是将其传递到 makecell 环境中显然只会将反斜杠打印为文本。我希望以某种方式将字符串作为代码传递...带有实际的反斜杠,直到进入 makecell 环境后才会进行评估。

答案1

这是一行带有xparse和 的代码expl3

\documentclass[]{article}
\usepackage{makecell}
\usepackage{xparse}

\newcommand\AuthorList{First MI. Last, First MI. Last, First MI. Last}

\ExplSyntaxOn
\NewDocumentCommand\PrintAuthorList{}
 {
  \clist_use:Nn \AuthorList { \\ }
 }
\ExplSyntaxOff

\begin{document}

\begin{tabular}{|l|l|}
\hline
\makecell[tl]{row 1, line 1 \\ row 1, row 2} & stuff\\
\hline
row 2, no cells & \makecell{Author List:\\ \PrintAuthorList}\\
\hline
\end{tabular}

\end{document}

在此处输入图片描述

答案2

如果您喜欢\expandafter-orgies,您可以使用\foreach临时宏来累积表行:

\documentclass[]{article}
\usepackage{makecell}
\usepackage{pgffor}
\newcommand\AuthorList{First MI. Last1, First MI. Last2, First MI. Last3}
\newcommand\MyTemp{}%
\newcommand\PrintAuthorList{%
  \gdef\MyTemp{}%
  \foreach \x in \AuthorList
  {%
    \ifx\MyTemp\empty\else
      \expandafter\def\expandafter\MyTemp\expandafter{\MyTemp\\}%
    \fi
    \expandafter\expandafter\expandafter\gdef
    \expandafter\expandafter\expandafter\MyTemp
    \expandafter\expandafter\expandafter{%
    \expandafter\MyTemp
    \x}%
  }%
  %\show\MyTemp
  \expandafter\gdef\expandafter\MyTemp\expandafter{\expandafter}\MyTemp
}%

\begin{document}

\begin{table}[h]
    \begin{tabular}{|l|l|}
        \hline
        \makecell[tl]{row 1, line 1 \\ row 1, row 2} & stuff\\
        \hline
        row 2, no cells & \makecell{This is where I want to print the author list, one per line:\\ \PrintAuthorList}\\
        \hline
    \end{tabular}
\end{table}

\begin{table}[h]
    \begin{tabular}{|l|l|}
        \hline
        \makecell[tl]{row 1, line 1 \\ row 1, row 2} & stuff\\
        \hline
        row 2, no cells & \makecell{This is where I've hard-coded the result I want:\\ First MI. Last1\\First MI. Last2\\First MI. Last3}\\
        \hline
    \end{tabular}
\end{table}

\end{document}

没有和没有临时宏的变体pgffor——中的作者姓名\AuthorList不得包含不平衡的\else/ ,\fi也不得包含含义等于 含义的标记\MyListEndDenoter

\documentclass[]{article}
\usepackage{makecell}

\newcommand\AuthorList{% 
  % Not a comma-list this time but a list of undelimited/brace-nested arguments:
  {First MI. Last1}%
  {First MI. Last2}%
  {First MI. Last3}%
}%

\newcommand\PrintAuthorList{%
  \expandafter\Exchange\expandafter{\AuthorList}{\AccumulateTableRowsLoop{}{}}{\MyListEndDenoter}%
}%
\makeatletter
\newcommand\AccumulateTableRowsLoop[3]{%
  % #1 - Either empty or \\
  % #2 - Accumulated table rows
  % #3 - Element of AuthorList or \MyListEndDenoter
  \ifx\MyListEndDenoter#3\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
  {#2}{\AccumulateTableRowsLoop{\\}{#2#1#3}}%
}%
\makeatother
\newcommand\Exchange[2]{#2#1}%
\newcommand\MyListEndDenoter{ItMustHaveAWeirdAndBizarreDefinitionWhichNoOtherMacroHas}%


\begin{document}

\begin{table}[h]
    \begin{tabular}{|l|l|}
        \hline
        \makecell[tl]{row 1, line 1 \\ row 1, row 2} & stuff\\
        \hline
        row 2, no cells & \makecell{This is where I want to print the author list, one per line:\\ \PrintAuthorList}\\
        \hline
    \end{tabular}
\end{table}

\begin{table}[h]
    \begin{tabular}{|l|l|}
        \hline
        \makecell[tl]{row 1, line 1 \\ row 1, row 2} & stuff\\
        \hline
        row 2, no cells & \makecell{This is where I've hard-coded the result I want:\\ First MI. Last1\\First MI. Last2\\First MI. Last3}\\
        \hline
    \end{tabular}
\end{table}

\end{document}

在此处输入图片描述

相关内容