使用逗号分隔列表输入来调用适当的命令

使用逗号分隔列表输入来调用适当的命令

我想这个问题必须在某个地方问,但我已经搜索了一段时间却没有找到,所以如果有答案,请随时引导我到那里。

我有一系列函数,它们基本上都执行相同的操作,但输入数量可变。我想用一个逗号分隔的输入列表调用一个函数,让该函数找到输入的长度,并用适当的输入调用适当的函数。不幸的是,我不太了解逗号分隔列表语法,也找不到好的入门书。我想要的一个例子(伪代码):

\newcommand{\RandQ}[1]{
%Set \length to be the length of the input to \RandQ list
\renewcommand{\length}{length{#1}}
%Now call the appropriate function with the appropriate inputs
ifthenelse{\length = 5}{\RandFiveQ{#1}{#2}{#3}{#4}{#5}}{}
%Where #1, #2, #3, etc are the 1st, 2nd, 3rd, etc entries of the list from the input above
ifthenelse{\length = 4}{\RandFourQ{#1}{#2}{#3}{#4}}{}
ifthenelse{\length = 5}{\RandThreeQ{#1}{#2}{#3}}{}
ifthenelse{\length = 5}{\RandTwoQ{#1}{#2}}{}
}

其中\RandFiveQ,,,是已定义的函数\RandFourQ,分别接受 5、4、3 和 2 个输入。\RandThreeQ\RandTwoQ

示例用法如下 \RandQ{1, 2, 3, 4}

这将返回

\RandFourQ{1}{2}{3}{4}

然后它将被解析为实际命令 \RandFourQ。

根据要求,我将包括 \RandXQ 命令的代码。我要补充的是,这个项目是为了避免必需的 cls 文件中的一些错误代码,以及学习如何在 latex 本身中编码……所以这里可能有一些 Rube-Goldberging……我已经警告过你了 :)

本质上,我已经预先生成了一个计数器 A1-AX 的随机列表(RandFourQ 生成了 A1 到 A4,并随机为它们分配了 1 到 4 的数字……例如 A1 = 3、A2 = 2、A3 = 1、A4 = 4),然后对于每个 RandXQ,第一个输入是答案顺序,然后是答案选项。如果第一个是 3,它会输出第 3 个答案选项,这样我就可以随机化答案顺序(例如,对于多项选择测试)。值得注意的是,有很多更简单的方法可以做到这一点,但不幸的是,所需的 cls 文件会杀死大多数这些选项。

%Syntax: For each "choice" You want to type The following:
%\RandMe{n}{A}{}
%\(n)choices
%\Rand(n)Q{\arabic{A1}}{Answer1}{Answer2}...{Answer n}
%\Rand(n)Q{\arabic{A2}}{Answer1}{Answer2}...{Answer n}
%.
%.
%.
%\Rand(#ofchoices)Q{An}{Answer1}{Answer2}...{Answer n}
%
%Where n is the number of questions choices there are Note that the number of choices "n" in the \Rand(n)Q must be spelled out with the first letter capitalized. Thus for 5 choices you would type "\RandFiveQ". 
%So for example with a question that has 4 choices of "2", "4", "17" and "No Answer" you would type:
%
%\RandMe{4}
%\fourchoices
%{\RandFourQ{\arabic{A1}}{2}{4}{17}{No Answer}}
%{\RandFourQ{\arabic{A2}}{2}{4}{17}{No Answer}}
%{\RandFourQ{\arabic{A3}}{2}{4}{17}{No Answer}}
%{\RandFourQ{\arabic{A4}}{2}{4}{17}{No Answer}}
%
%Currently supported are: \RandFiveQ, \RandFourQ, \RandThreeQ, \RandTwoQ.
%Also required is \usepackage{calc}, \usepackage{lcg}
%
\newcommand{\RandFiveQ}[6]
{
\ifthenelse{#1 = 1}{#2}{}
\ifthenelse{#1 = 2}{#3}{}
\ifthenelse{#1 = 3}{#4}{}
\ifthenelse{#1 = 4}{#5}{}
\ifthenelse{#1 = 5}{#6}{}
}

\newcommand{\RandFourQ}[5]
{
\ifthenelse{#1 = 1}{#2}{}
\ifthenelse{#1 = 2}{#3}{}
\ifthenelse{#1 = 3}{#4}{}
\ifthenelse{#1 = 4}{#5}{}
}

\newcommand{\RandThreeQ}[4]
{
\ifthenelse{#1 = 1}{#2}{}
\ifthenelse{#1 = 2}{#3}{}
\ifthenelse{#1 = 3}{#4}{}
}

\newcommand{\RandTwoQ}[3]
{
\ifthenelse{#1 = 1}{#2}{}
\ifthenelse{#1 = 2}{#3}{}
}

答案1

您可以定义四个辅助宏:

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\RandQ}{m}
 {
  \int_case:nnF { \clist_count:n { #1 } }
   {
    {2}{\RandTwoQL{#1}}
    {3}{\RandThreeQL{#1}}
    {4}{\RandFourQL{#1}}
    {5}{\RandFiveQL{#1}}
   }
   {Wrong~number~of~args~(#1)}
 }
\NewDocumentCommand{\RandTwoQL}{>{\SplitArgument{1}{,}}m}
 {
  \RandTwoQ#1
 }
\NewDocumentCommand{\RandThreeQL}{>{\SplitArgument{2}{,}}m}
 {
  \RandThreeQ#1
 }
\NewDocumentCommand{\RandFourQL}{>{\SplitArgument{3}{,}}m}
 {
  \RandFourQ#1
 }
\NewDocumentCommand{\RandFiveQL}{>{\SplitArgument{4}{,}}m}
 {
  \RandFiveQ#1
 }
\ExplSyntaxOff

\newcommand{\RandTwoQ}[2]{-#1-#2-}
\newcommand{\RandThreeQ}[3]{-#1-#2-#3-}
\newcommand{\RandFourQ}[4]{-#1-#2-#3-#4-}
\newcommand{\RandFiveQ}[5]{-#1-#2-#3-#4-#5-}

\begin{document}

\RandQ{1,2}

\RandQ{1,2,3}

\RandQ{1,2,3,4}

\RandQ{1,2,3,4,5}

\end{document}

主宏计算项目的数量并调用适当的宏,该宏反过来通过将参数拆分为正确数量的括号参数\SplitArgument

我使用了四个宏的虚假定义。如果知道定义,就可以做得更好。

在此处输入图片描述

答案2

这是一个基于 LuaLaTeX 的解决方案。它设置了一个 Lua 函数,该函数 (a) 在处理的早期阶段扫描所有输入行,并且 (b) 有\RandQ{...}选择地用替换所有 实例\Rand<num>Q,其中<num>取决于 参数中逗号分隔的项目数\RandQ

下面的示例提供了 Lua 代码以及\RandFiveQ\RandFourQ等的一些虚拟定义,以创建独立的工作示例

在此处输入图片描述

% !TEX TS-program = lualatex
\documentclass{article}

%% Lua-side code: Define the function "do_RandQ" and assign
%% it to the "process_input_buffer" callback
\usepackage{luacode}
\begin{luacode}
function do_RandQ ( line )
  line = string.gsub ( line , "Q{(.-),(.-),(.-),(.-),(.-)}", "FiveQ{%1}{%2}{%3}{%4}{%5}" )
  line = string.gsub ( line , "Q{(.-),(.-),(.-),(.-)}", "FourQ{%1}{%2}{%3}{%4}" )
  line = string.gsub ( line , "Q{(.-),(.-),(.-)}", "ThreeQ{%1}{%2}{%3}" )
  line = string.gsub ( line , "Q{(.-),(.-)}", "TwoQ{%1}{%2}" )
  return ( line )
end
luatexbase.add_to_callback ( "process_input_buffer" , 
    do_RandQ, "do_RandQ" )
\end{luacode}

%% TeX-side code: Dummy definitions of \Rand<num>Q macros
\def\RandFiveQ#1#2#3#4#5{#1---#2---#3---#4---#5}
\def\RandFourQ#1#2#3#4{#1?#2?#3?#4}
\def\RandThreeQ#1#2#3{#1\dots#2\dots#3}
\def\RandTwoQ#1#2{#1??#2}

\begin{document}    
%% Four instances of "\RandQ", each one with a different number of items
\RandQ{1,2,3,4,5}

\RandQ{a,b,c,d}

\RandQ{A,B,C}

\RandQ{x,y}
\end{document}

相关内容