如何在 FOR 循环中调用 \newcommand - 自动文档准备

如何在 FOR 循环中调用 \newcommand - 自动文档准备

我正在编写一份技术报告,需要简化它以摆脱荒谬的手动复制粘贴工作。

我的想法:

  • 我的模拟结果可以以相同的方式呈现(相同的变量、图片和表格)

我已经尝试过的:

  • 我熟悉 \newcommand 关于名称中数字的限制 - 罗马数字对我来说没问题
\documentclass{article}
\usepackage{tikz}

\begin{document}

   % Variables definition

        % Simulation results example 
        \newcommand{\NameCI}{Acceleration}
        \newcommand{\ResultCI}{OK}
        \newcommand{\CommentCI}{My description 1}

        % Simulation results example 
        \newcommand{\NameCII}{Deceleration}
        \newcommand{\ResultCII}{NOT OK}
        \newcommand{\commentCII}{My description 2}

    % FOR loop - results presentation 
    % (this should prepare a dedicated page for each simulation 
    % and use my already defined variables)
        
    \foreach \x in {I, II}
    {
        Simulation name: \NameC\x  
        Simulation result: \ResultC\x
        % code for pictures and tables which uses more variables like these above
    }
        
\end{document}

问题:

  • 如何遍历我的变量以便准备一次页面模板并填充所有定义的变量(一些类似的应用程序将是来自 MS Office 的串行通信)

答案1

附录以实现更广泛的实施。

我认为listofitems对此很有用。

\documentclass{article}
\usepackage{listofitems}
\newcommand\newcommands[2]{%
  \readlist*\cmdtxt{#2}%
  \foreachitem\z\in\cmdtxt[]{%
    \expandafter\gdef\csname#1\romannumeral\zcnt\expandafter\endcsname
    \expandafter{\z}%
  }%
}
\begin{document}
\newcommands{CaseName}{Acceleration, Deceleration, Right turn, Left Turn}
\CaseNameiii{} and \CaseNameiv, followed by \CaseNameii{} and
\CaseNamei.
\end{document}

在此处输入图片描述

如果您坚持使用大写罗马数字,则可以使用以下变体:

\documentclass{article}
\usepackage{listofitems}
\newcounter{cmdctr}
\newcommand\newcommands[2]{%
  \readlist*\cmdtxt{#2}%
  \foreachitem\z\in\cmdtxt[]{%
    \setcounter{cmdctr}{\zcnt}%
    \expandafter\gdef\csname#1\Roman{cmdctr}\expandafter\endcsname
    \expandafter{\z}%
  }%
}
\begin{document}
\newcommands{CaseName}{Acceleration, Deceleration, Right turn, Left Turn}
\CaseNameIII{} and \CaseNameIV, followed by \CaseNameII{} and
\CaseNameI.
\end{document}

附录

也许这更符合 OP 的愿望:

\documentclass{article}
\usepackage{listofitems}
\newcommand\newcommands[2]{%
  \readlist*\cmdtxt{#2}%
  \foreachitem\z\in\cmdtxt[]{%
    \expandafter\gdef\csname#1\romannumeral\zcnt\expandafter\endcsname
    \expandafter{\z}%
  }%
}
\newcommand\usecmd[1]{\csname#1\romannumeral\z\endcsname}
\newcommand\fillstencil[2]{%
  \readlist*\numcnt{#1}%
  \foreachitem\z\in\numcnt[]{%
    #2
  }%
}
\begin{document}
\newcommands{CaseName}{Acceleration, Deceleration, Right turn, Left Turn}
\newcommands{Result}{OK, OK, Not OK, Maybe OK}

\fillstencil{1,2,4}{%
\subsection{Subject: \usecmd{CaseName}!}

The result was \usecmd{Result}

The end
}

\end{document}

在此处输入图片描述

答案2

您可能对 Nicola Talbot 博士的数据工具-用于维护数据库和迭代数据库记录元素的包。

如何使用以下方法处理问题的示例数据工具-package 位于这个答案的末尾。

是因为它可能。

\csname..\endcsname可能是你的朋友:

\documentclass{article}
\usepackage{tikz}

\begin{document}

   % Variables definition

        % Simulation results example 
        \newcommand{\NameCI}{Acceleration}
        \newcommand{\ResultCI}{OK}
        \newcommand{\CommentCI}{My description 1}

        % Simulation results example 
        \newcommand{\NameCII}{Deceleration}
        \newcommand{\ResultCII}{NOT OK}
        \newcommand{\CommentCII}{My description 2}

    % FOR loop - results presentation 
    % (this should prepare a dedicated paragraph for each simulation 
    %  and use the already defined variables)
        
    \foreach \x in {I, II}
    {%
        \par\noindent
        \textbf{Simulation name:} \csname NameC\x\endcsname\\
        \textbf{Simulation description:} \csname CommentC\x\endcsname\\
        \textbf{Simulation result:} \csname ResultC\x\endcsname\\
        \textbf{Control-sequence-names:} 
           \texttt{\expandafter\string\csname NameC\x\endcsname}/%
           \texttt{\expandafter\string\csname CommentC\x\endcsname}/%
           \texttt{\expandafter\string\csname ResultC\x\endcsname}%
        % code for pictures and tables which uses more variables like these above
        \bigskip
    }
        
\end{document}

在此处输入图片描述

我有时会使用一个宏\NameToCs来处理由左花括号()分隔的参数{和嵌套在括号中的参数。

\NameToCs工作原理如下:

\NameToCs⟨stuff not in curly braces⟩{NameOfCs}
⟨stuff not in curly braces⟩\NameOfCs

括号中嵌套的参数用于表示要通过..⟨control sequence token⟩构造的的名称。在宏定义的 中,您可以使用-notation来表示宏,其最后一个参数将由 分隔,该分隔符(与其他参数分隔符不同)将保留在原处/重新插入:\csname\endcsname⟨parameter text⟩#{{

\makeatletter
\newcommand\exchange[2]{#2#1}%
\@ifdefinable\NameToCs{\long\def\NameToCs#1#{\romannumeral0\innerNameToCs{#1}}}%
\newcommand\innerNameToCs[2]{\expandafter\exchange\expandafter{\csname#2\endcsname}{ #1}}%
\makeatother

此类宏有多种用途:

1) \NameToCs{foo}\foo
2) \NameToCs\string{foo}\string\foo
3) \NameToCs\meaning{foo}\meaning\foo
4) \NameToCs\global\long\def{foo}...\global\long\foo...
5) \NameToCs\newcommand*{foo}...\newcommand*\foo...
6) \NameToCs\NameToCs\global\let{foo}={bar}\NameToCs\global\let\foo={bar}\global\let\foo=\bar

基本上\NameToCs只是一个包装器,用于将\csname..\endcsname结果应用并附加到⟨control sequence token⟩某些标记序列以供进一步处理,例如定义或只是调用。

您可以使用\csname..\endcsame/\NameToCs创建⟨control sequence token⟩名称包含空格和/或阿拉伯数字的。 \csname..\endcsame/\NameToCs将扩展可扩展标记(例如),同时收集要创建的的名称。由/创建的可以以任何方式使用。例如,用于定义或调用相关控制序列。 如果由/创建的在创建时未定义,则底层 会导致 TeX 让其含义等于-primitive 中的含义\the⟨counter⟩⟨control sequence token⟩⟨control sequence token⟩\csname..\endcsame\NameToCs
⟨control sequence token⟩\csname..\endcsame\NameToCs\csname..\endcsame\relax当前的范围/组,但不在父范围/上级范围之内(即使 -parameter\globaldefs具有正值)。(这不会干扰\newcommandas以与未定义的控制序列相同的方式处理\newcommand相等的控制序列。)\relax

\documentclass{article}

\makeatletter
\newcommand\exchange[2]{#2#1}%
\@ifdefinable\NameToCs{\long\def\NameToCs#1#{\romannumeral0\innerNameToCs{#1}}}%
\newcommand\innerNameToCs[2]{\expandafter\exchange\expandafter{\csname#2\endcsname}{ #1}}%

\newcommand\simulationlist{}
\newcommand\appendtosimulationlist{%
      \ifnum\value{simulation}>1 \expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
      {\expandafter\exchange\expandafter{\expandafter{\expandafter,\number\value{simulation}}}}%
      {\expandafter\exchange\expandafter{\expandafter{\number\value{simulation}}}}%
      {\g@addto@macro{\simulationlist}}%
}%
\makeatother

\newcounter{simulation}
\setcounter{simulation}{0}
\renewcommand\thesimulation{\arabic{simulation}}

\usepackage{tikz}

\begin{document}

   % Variables definition

        % Simulation results example     
        \stepcounter{simulation}
        % Now the simulation-counter's value is 1.
        \appendtosimulationlist
        % Now "1" is appended to the definition of \simulationlist.
        \NameToCs\newcommand{Name\number\value{simulation}}{Acceleration}
        \NameToCs\newcommand{Result\number\value{simulation}}{OK}
        \NameToCs\newcommand{Description\number\value{simulation}}{My description 1}

        % Simulation results example 
        \stepcounter{simulation}
        % Now the simulation-counter's value is 2.
        \appendtosimulationlist
        % Now ",2" is appended to the definition of \simulationlist.
        \NameToCs\newcommand{Name\number\value{simulation}}{Deceleration}
        \NameToCs\newcommand{Result\number\value{simulation}}{NOT OK}
        \NameToCs\newcommand{Description\number\value{simulation}}{My description 2}

    % loop - results presentation 
    % (this should prepare a dedicated paragraph for each simulation 
    %  and use the already defined variables)


    \noindent A \verb|\foreach|-loop:\bigskip

    \foreach \x in \simulationlist
    {%
        \par\noindent
        \textbf{Simulation name:} \NameToCs{Name\x}\\
        \textbf{Simulation description:} \NameToCs{Description\x}\\
        \textbf{Simulation result:} \NameToCs{Result\x}\\
        \textbf{Control-sequence-names:} 
           \texttt{\NameToCs\string{Name\x}}/%
           \texttt{\NameToCs\string{Description\x}}/%
           \texttt{\NameToCs\string{Result\x}}%
        % code for pictures and tables which uses more variables like these above
        \bigskip
    }
    
    \noindent A \verb|\loop..\ifnum..\repeat|-loop:\bigskip
    
    \newcount\loopcount
    \loopcount=0
    \loop
    \ifnum\loopcount<2 %
       \advance\loopcount by 1
       \par\noindent
       \textbf{Simulation name:} \NameToCs{Name\the\loopcount}\\
       \textbf{Simulation description:} \NameToCs{Description\the\loopcount}\\
       \textbf{Simulation result:} \NameToCs{Result\the\loopcount}\\
       \textbf{Control-sequence-names:} 
          \texttt{\NameToCs\string{Name\the\loopcount}}/%
          \texttt{\NameToCs\string{Description\the\loopcount}}/%
          \texttt{\NameToCs\string{Result\the\loopcount}}%
       % code for pictures and tables which uses more variables like these above
       \bigskip
    \repeat
    
\end{document}

在此处输入图片描述

这里有一种方法,使用数据工具包用于维护数据库和迭代该数据库的命令:

\documentclass{article}

\usepackage{datatool}

\newcounter{AmountOfSimulations}
\DTLnewdb{simulations}

\begin{document}

% Simulation results example     
\DTLnewrow{simulations}%
\stepcounter{AmountOfSimulations}%
\DTLnewdbentry{simulations}{Name}{Acceleration}%
\DTLnewdbentry{simulations}{Result}{OK}%
\dtlexpandnewvalue
\DTLnewdbentry{simulations}{Description}{My description \number\value{AmountOfSimulations}}%
\dtlnoexpandnewvalue

% Simulation results example     
\DTLnewrow{simulations}%
\stepcounter{AmountOfSimulations}%
\DTLnewdbentry{simulations}{Name}{Deceleration}%
\DTLnewdbentry{simulations}{Result}{NOT OK}%
\dtlexpandnewvalue
\DTLnewdbentry{simulations}{Description}{My description \number\value{AmountOfSimulations}}%
\dtlnoexpandnewvalue

% FOR loop - results presentation 
% (this should prepare a dedicated paragraph for each simulation)

\DTLforeach{simulations}{\NameField=Name, \ResultField=Result, \DescriptionField=Description}{%
    \par\noindent
    \textbf{Simulation name:} \NameField\\
    \textbf{Simulation description:} \DescriptionField\\
    \textbf{Simulation result:} \ResultField
    % code for pictures and tables which uses more variables like these above
    \bigskip
}
    
\end{document}

在此处输入图片描述

以下是一种方法,使用 .csv 文件(逗号分隔值文件)来维护数据库和数据工具包用于加载该数据库和迭代该数据库的命令:

\documentclass{article}

\begin{filecontents*}{CSVDataBaseOfMyInterestingSimulations.csv}
Name,Result,Description
"Acceleration","OK","My Description 1"
"Deceleration","NOT OK","My Description 2"
\end{filecontents*}

\usepackage{datatool}

\DTLloaddb{simulations}{CSVDataBaseOfMyInterestingSimulations.csv}

\begin{document}

% FOR loop - results presentation 
% (this should prepare a dedicated paragraph for each simulation)

\DTLforeach{simulations}{\NameField=Name, \ResultField=Result, \DescriptionField=Description}{%
    \par\noindent
    \textbf{Simulation name:} \NameField\\
    \textbf{Simulation description:} \DescriptionField\\
    \textbf{Simulation result:} \ResultField
    % code for pictures and tables which uses more variables like these above
    \bigskip
}
    
\end{document}

在此处输入图片描述

相关内容