衡量任务中的列表项并做出相应的更改

衡量任务中的列表项并做出相应的更改

我使用包制作了以下 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

相关内容