我使用包制作了以下 MCQ 列表tasks
。
问题是我需要一个命令来测量每个\task
问题的所有 s 的内容并确定它们之间的最大宽度。如果它大于某个宽度(~200pt),它应该更改\task
为\task*
遍历当前问题中的选项以在底部给出输出。
\documentclass{article}
\usepackage[papersize={600pt,800pt},top=50pt,left=50pt,right=50pt,bottom=50pt]{geometry}
\usepackage{tikz}
\usepackage{calc}
\usepackage{enumitem}
\usepackage{tasks}
\makeatletter
\renewcommand\normalsize{\@setfontsize\normalsize{13.5pt}{17pt}}
\normalsize
\makeatother
\definecolor{ChoiceGray}{RGB}{204,204,204}
\newcommand*\Choice[1]{%
\begin{tikzpicture}[baseline=-5pt]
\node [gray,minimum width=22pt,minimum height=22pt,draw=ChoiceGray,rounded corners] {\large #1};
\end{tikzpicture}}
\newcounter{ChoiceLabel}
\newcommand*\ChoiceLabel{%
\refstepcounter{ChoiceLabel}%
\hskip1em\llap{\Choice{\Alph{ChoiceLabel}}}}%
\newcommand*{\MCQ}[1]{\setcounter{ChoiceLabel}{0}\begin{tasks}[after-item-skip=3mm,label=\ChoiceLabel](2)
#1
\end{tasks}}
\begin{document}
\begin{enumerate}[label=\arabic*.,leftmargin=1cm]
\item{Question text here.
\MCQ{
\task Some choice
\task Another choice
\task A choice with larger width that will break on two lines
\task The last one
}
}
\end{enumerate}
\end{document}
\documentclass{article}
\usepackage[papersize={600pt,800pt},top=50pt,left=50pt,right=50pt,bottom=50pt]{geometry}
\usepackage{tikz}
\usepackage{calc}
\usepackage{enumitem}
\usepackage{tasks}
\makeatletter
\renewcommand\normalsize{\@setfontsize\normalsize{13.5pt}{17pt}}
\normalsize
\makeatother
\definecolor{ChoiceGray}{RGB}{204,204,204}
\newcommand*\Choice[1]{%
\begin{tikzpicture}[baseline=-5pt]
\node [gray,minimum width=22pt,minimum height=22pt,draw=ChoiceGray,rounded corners] {\large #1};
\end{tikzpicture}}
\newcounter{ChoiceLabel}
\newcommand*\ChoiceLabel{%
\refstepcounter{ChoiceLabel}%
\hskip1em\llap{\Choice{\Alph{ChoiceLabel}}}}%
\newcommand*{\MCQ}[1]{\setcounter{ChoiceLabel}{0}\begin{tasks}[after-item-skip=3mm,label=\ChoiceLabel](2)
#1
\end{tasks}}
\begin{document}
\begin{enumerate}[label=\arabic*.,leftmargin=1cm]
\item{Question text here.
\MCQ{
\task* Some choice
\task* Another choice
\task* A choice with larger width that will break on two lines
\task* The last one
}
}
\end{enumerate}
\end{document}
是否可以?
答案1
这里我使用作为分隔符的listofitems
参数进行初始解析。它循环遍历解析结果并测量最长的一个。如果最长的一个超过了阈值(这里是 200pt),它会构建一个标记列表来替换原始参数中存在的任何内容。\MCQ
\task
\tasklist
\task*
\task
OP 的原始语法得以保留。
\documentclass{article}
\usepackage[papersize={600pt,800pt},top=50pt,left=50pt,right=50pt,bottom=50pt]{geometry}
\usepackage{tikz}
\usepackage{calc}
\usepackage{enumitem}
\usepackage{tasks}
\makeatletter
\renewcommand\normalsize{\@setfontsize\normalsize{13.5pt}{17pt}}
\normalsize
\makeatother
\definecolor{ChoiceGray}{RGB}{204,204,204}
\newcommand*\Choice[1]{%
\begin{tikzpicture}[baseline=-5pt]
\node [gray,minimum width=22pt,minimum height=22pt,draw=ChoiceGray,rounded corners] {\large #1};
\end{tikzpicture}}
\newcounter{ChoiceLabel}
\newcommand*\ChoiceLabel{%
\refstepcounter{ChoiceLabel}%
\hskip1em\llap{\Choice{\Alph{ChoiceLabel}}}}%
\newtoks\tasktoks
\usepackage{listofitems}
\newcommand*{\MCQ}[1]{%
\setsepchar{\task}%
\ignoreemptyitems%
\readlist*\tasklist{#1}%
\def\longtask{0pt}%
\foreachitem\taskitem\in\tasklist{% MEASURE THE LONGEST TASK
\setbox0=\hbox{\taskitem}%
\ifdim\wd0>\longtask\relax\edef\longtask{\the\wd0}\fi%
}%
\setcounter{ChoiceLabel}{0}%
\ifdim\longtask>200pt\relax% FOR LONG TASKS, EMPLOY \task*
\foreachitem\taskitem\in\tasklist{%
\tasktoks\expandafter{\the\tasktoks\task*}%
\tasktoks\expandafter\expandafter\expandafter{%
\expandafter\the\expandafter\tasktoks\taskitem}%
}%
\else%
\tasktoks{#1}%
\fi%
\def\tmp{ \begin{tasks}[after-item-skip=3mm,label=\ChoiceLabel](2)}%
\expandafter\tmp\the\tasktoks%
\end{tasks}%
}
\begin{document}
\begin{enumerate}[label=\arabic*.,leftmargin=1cm]
\item{Question text here.
\MCQ{
\task Some choice
\task Another choice
\task Third choice
\task The last one
}
}
\end{enumerate}
\begin{enumerate}[label=\arabic*.,leftmargin=1cm]
\item{Question text here.
\MCQ{
\task Some choice
\task Another choice
\task A choice with larger width that will break on two lines
\task The last one
}
}
\end{enumerate}
\end{document}
答案2
如果您可以接受(稍微)修改的任务列表输入,例如:
\MCQ{Some choice\\
Another choice\\
A choice with a larger width that will break on two lines\\
The last one
}
下面是一个可行的解决方案。它使用包中的解析和迭代listofitems
以及包中的一些函数etoolbox
。关键思想是首先迭代以找到最大宽度,然后迭代构建环境主体tasks
。由于对tasks
内容的处理非常特殊(我为此使用了来自克莱门斯对于问题任务环境与 pgffors foreach)。如果您使用更标准的环境,则所有内容都可以用四五行来编码。
\documentclass{article}
\usepackage[papersize={600pt,800pt},top=50pt,left=50pt,right=50pt,bottom=50pt]{geometry}
\usepackage{tikz}
\usepackage{calc}
\usepackage{enumitem}
\usepackage{tasks}
\usepackage{listofitems}
\usepackage{etoolbox}
\makeatletter
\renewcommand\normalsize{\@setfontsize\normalsize{13.5pt}{17pt}}
\normalsize
\makeatother
\definecolor{ChoiceGray}{RGB}{204,204,204}
\newcommand*\Choice[1]{%
\begin{tikzpicture}[baseline=-5pt]
\node [gray,minimum width=22pt,minimum height=22pt,draw=ChoiceGray,rounded corners] {\large #1};
\end{tikzpicture}}
\newcounter{ChoiceLabel}
\newcommand*\ChoiceLabel{%
\refstepcounter{ChoiceLabel}%
\hskip1em\llap{\Choice{\Alph{ChoiceLabel}}}%
}
%------------------------
\newcommand\switchtwo[2]{#2#1}
\newcommand\expandsecond[2]{\expandafter\switchtwo\expandafter{#1}{#2}}
\newlength{\tsklenmax}
\newcommand{\setTaskLenMax}[1]{\setlength{\tsklenmax}{#1}}
\newcommand{\maxdim}[2]{\ifdimgreater{#1}{#2}{#1}{#2}}
\newcommand*{\MCQ}[1]{
% initize
\ifdef{\taskslist}{\renewcommand*\taskslist{}}{\newcommand*\taskslist{}}
\ifdef{\thetasks}{\let\thetasks\undefined}{}
\newlength{\tsklen}\newlength{\tsklentempmax}
\setlength{\tsklentempmax}{\tsklenmax}
% read tasks
\setsepchar{\\} \ignoreemptyitems
\greadlist*\thetasks{#1}
% find maximal width
\foreachitem\atask\in\thetasks{
\settowidth{\tsklen}{\atask}
\setlength{\tsklentempmax}{\maxdim{\tsklen}{\tsklentempmax}}
}
% choose task version
\ifdimgreater{\tsklentempmax}{\tsklenmax}{\def\usestar{\noexpand\task*}}{\def\usestar{\noexpand\task}}
% populate task list
\foreachitem\atask\in\thetasks{
\begingroup
\edef\x{\endgroup
\expandafter\noexpand\csname g@addto@macro\endcsname
\noexpand\taskslist{\usestar \atask}%
}\x
}
% display tasks
\setcounter{ChoiceLabel}{0}%
\expandsecond\taskslist
{\begin{tasks}[after-item-skip=3mm,label=\ChoiceLabel](2)}
\end{tasks}
}
\begin{document}
\setTaskLenMax{250pt}
\begin{enumerate}
\item question 1
\MCQ{Some choice\\
Another choice\\
A choice with a larger width that will break on two lines\\
The last one
}
\item Question 2
\MCQ{Some choice\\
Another choice\\
With reduced larger width \\
The last one
}
\end{enumerate}
\end{document}
新的MCQ
命令及其辅助功能/长度在前言的末尾定义。
显然,当您已经加载tikz
以创建花式标签时,您可以用 替换列表处理和迭代pgf
。