使用 xparse 将密钥从 multicols 本地传递到 enumitem

使用 xparse 将密钥从 multicols 本地传递到 enumitem

key=val我在尝试使用本地定义xparse来传递multicols枚举(包)时遇到了一个小问题enumitem。我重新定义了环境enumerate以接受columns=number和创建的命令\keyans[...]\answer{...}并保存工作表练习的多项选择键和答案,一切都很好,只是当在第一级\showanskey[...]{...}{...}[...]激活时,会影响嵌套在其中的所有级别。columnsenumerate

columns=2在第一级使用时它看起来像这样:

当前结果

所有嵌套环境都分为两列。

希望输出是这样的:

预期结果

我尝试将\group_begin:\group_end:放在不同的地方,但只会出现错误。代码改编自定义具有多个可选参数的列表环境和 MWE:

% arara: pdflatex
% arara: clean: { extensions: [ aux, log] }
\documentclass{article}
\usepackage{letltxmacro,enumitem,multicol,xparse}
\usepackage[most]{tcolorbox}
\usepackage[margin=0.6in,noheadfoot,papersize={8.5in,13in}]{geometry} % for mwe
\setlength{\parindent}{0pt}
\pagestyle{empty}

% Set keys for save-ans and save-key in enumitem
\SetEnumitemKey{save-ans}{before={\storecurrentid{#1}\begin{saveanswer}{#1}},after=\end{saveanswer}}%
\SetEnumitemKey{save-key}{before={\storecurrentid{#1}\begin{savekeyans}{#1}},after=\end{savekeyans}}%

% Save a copy enumerate
\LetLtxMacro\oldenum\enumerate
\LetLtxMacro\oldendenum\endenumerate

% Redefine enumerate for multicols
\ExplSyntaxOn
\RenewDocumentEnvironment{enumerate}{ O{} }
 {
  \tl_clear:N \l_keyanswer_enumitem_tl
  \keys_set:nn { keyanswer } { #1 } 
  \int_compare:nT { \l_keyanswer_columns_tl > 1 } 
   { 
   \setlength{\multicolsep}{5.0pt plus 2.0pt minus 1.5pt}
   \begin{multicols}{ \l_keyanswer_columns_tl } 
   }
  \keyanswer_beginenum:V \l_keyanswer_enumitem_tl 
 }
 {
  \oldendenum
  \int_compare:nT { \l_keyanswer_columns_tl > 1 }
   { \end{multicols} }
 }
\cs_new_protected:Npn \keyanswer_beginenum:n #1
 { \oldenum[#1] }

\cs_generate_variant:Nn \keyanswer_beginenum:n {V}

\tl_new:N \l_keyanswer_columns_tl
\tl_new:N \l_keyanswer_enumitem_tl

\keys_define:nn { keyanswer }
 {
  columns .tl_set:N  = \l_keyanswer_columns_tl,
  columns .initial:n = 1,
  unknown .code:n    = \tl_put_right:Nx \l_keyanswer_enumitem_tl 
                        { \l_keys_key_tl \tl_if_empty:nF { #1 } { = \exp_not:n { #1 } } , },
 }

% Implementation to save \answer{...} and \keyans[...] in lists
\prop_new:N \g_keyanswer_admin_prop

\cs_new:Npn \storecurrentid #1{%
  \prop_gput:Nnn \g_keyanswer_admin_prop {current-id} {#1}
 }
\cs_new:Npn \retrievecurrentid {%
  \prop_item:Nn \g_keyanswer_admin_prop {current-id}
 }

% environments for save \answer{...} and \keyans[...]
\NewDocumentEnvironment{saveanswer}{ m }{%
  \setlist[enumerate,2]{leftmargin=16pt,nosep,itemsep=0pt,label=(\alph*),before={\stepdownlevel},after={\stepuplevel}}%
  \setlist[enumerate,3]{leftmargin=20pt,nosep,itemsep=0pt,label=\Roman*.,before={\stepdownlevel},after={\stepuplevel}}%
  \seq_if_exist:cF { l_keyanswer_data_#1_seq }{ \seq_new:c { l_keyanswer_data_#1_seq }}
  }{ \leavevmode }

\NewDocumentEnvironment{savekeyans}{ m }{%
  \setlist[enumerate,1]{left=0pt,labelsep=5pt,itemsep=1pt,label=\arabic*.}%
  \setlist[enumerate,2]{leftmargin=16pt,nosep,label=\Alph*)}%
  \seq_if_exist:cF { l_keyanswer_data_#1_seq }{%
    \seq_new:c { l_keyanswer_data_#1_seq }}}{ \leavevmode }

% commands \answer{...} and \keyans[...]
\NewDocumentCommand{\answer}{ +m }{%
  \seq_gput_right:cn { l_keyanswer_data_ \retrievecurrentid _seq }{\item  #1}
  \par%
 }

\NewDocumentCommand\keyans{ !o }{%
 \IfNoValueTF{#1}{%
  \tl_set:Nn \l_tmpa_tl {\protect\item}%
  \tl_put_right:Nx \l_tmpa_tl {\protect\space \Alph{enumii}}% 
  \seq_gput_right:cV { l_keyanswer_data_ \retrievecurrentid _seq }{ \l_tmpa_tl}%
  \par%
    }{%
  \seq_gput_right:cn { l_keyanswer_data_ \retrievecurrentid _seq }{\item #1}%
  \par%
    }%
 }%

% \stepdownlevel and \stepuplevel for save in nested enumerate
\newcommand{\stepdownlevel}{%
  \seq_gput_right:cn {l_keyanswer_data_ \retrievecurrentid _seq} {\item \begin{enumerate}}
 }
\newcommand{\stepuplevel}{%
  \seq_gput_right:cn {l_keyanswer_data_ \retrievecurrentid _seq} {\end{enumerate}}
 }

% Display \answer{...} and \keyans[...] in list by id
\cs_new:Npn \displayseqcontent #1#2 {%
  \seq_if_empty:cF { l_keyanswer_data_#1_seq } {%
    \seq_log:c { l_keyanswer_data_#1_seq }
    \setlist[enumerate,1]{labelsep=5pt,label=\arabic*.,leftmargin=15pt,labelsep=3pt,font=\footnotesize,nosep,widest=80}%
    \setlist[enumerate,2]{font=\footnotesize,labelsep=5pt,leftmargin=0.6cm,nosep,label=(\alph*)}%
    \setlist[enumerate,3]{font=\footnotesize,labelsep=5pt,leftmargin=0.3cm,nosep,label=\Roman*.}%
    \begin{enumerate}[#2] \small\setlength{\columnsep}{0pt}
      \seq_map_inline:cn { l_keyanswer_data_#1_seq } { ##1 }
    \end{enumerate}
  }
 }
\ExplSyntaxOff

% \showanskey[tcolorbox]{title}{list ref}[columns]
\DeclareTotalTColorBox{\showanskey}{O{} m m O{4}}
 { colback=white,size=small,top=0mm,bottom=1.5mm, left=0mm,width=\columnwidth,title filled,%
  fontupper=\small,fonttitle=\small\sffamily, adjusted title={#2},center title,#1}
 { \displayseqcontent{#3}{columns=#4} }%

\begin{document}

\section{Multiple Choice}

\begin{enumerate}[save-key=mchoice,left=0pt,columns=2]
\item First type of questions
    \begin{enumerate}
        \item value 
        \item value 
        \item value
        \item correct \keyans
        \item value 
    \end{enumerate}
\item Second type of questions
        \begin{enumerate}[leftmargin=2pc,label=\Roman*.]
            \item $2\alpha+2\delta=90^{\circ}$
            \item $\alpha=\delta$ 
            \item $\angle EDF=45^{\circ}$
        \end{enumerate}
\begin{enumerate}[columns=2]% 
        \item I only 
        \item II only \keyans
        \item I and II only
        \item I and III only 
        \item I, II, and III
\end{enumerate}
%\columnbreak % 
\item Third type of questions
        \begin{enumerate}[leftmargin=2pc,label=(\arabic*)]
            \item $2\alpha+2\delta=90^{\circ}$
            \item $\angle EDF=45^{\circ}$
        \end{enumerate}
    \begin{enumerate}
        \item Altenativa A 
        \item Altenativa B 
        \item Altenativa C \keyans
        \item Altenativa D
        \item Altenativa E 
    \end{enumerate}
\item Fourth type of question, a problem with numerical response \keyans[$\sqrt{2}$]

\end{enumerate}

\section{Worksheet}

\begin{enumerate}[save-ans=Worksheet,left=0pt,labelsep=5pt,nosep,label=\arabic*.,columns=2]
\item Factor $x^{2}-2x+1$  \answer{$\left(x-1\right)^{2}$} 
\item Factor $3x+3y+3z$    \answer{$3(x+y+z)$}
\item True False
  \begin{enumerate}
  \item $\alpha > \delta$ \answer{False}
  \item \LaTeX2e\ is cool? \answer{Very True!}
  \end{enumerate} 
\item Related to Linux
  \begin{enumerate}
  \item You use linux? \answer{Yes}
  \item Usually uses the package manager? \answer{Yes}
  \item Rate the following package managers
        \begin{enumerate}
        \item dnf \answer{good}
        \item apt \answer{very good}
        \item yum \answer{obsolete}
        \end{enumerate}
  \end{enumerate} 
\end{enumerate}

\section{Answers}
\showanskey[colback=yellow!30!white]{Multiple Choice Keys}{mchoice}[5]
\showanskey[colback=yellow!30!white]{Solution Worksheet}{Worksheet}[2]

\section{Normal enumerate}
\begin{enumerate}
\item First level
    \begin{enumerate}
        \item Second level 
        \item value 
        \item \begin{enumerate}
                \item Third level
                \item value
               \end{enumerate}
    \end{enumerate}
\end{enumerate}

\end{document}

如果放入所有子层级,columns=1则跳过该问题,但是,不能用 来做到这一点。如果我\showanskey不使用,则直接使用\RenewDocumentEnvironment{enumerate}

\SetEnumitemKey{columns}{before=\begin{multicols}{#1},after=\end{multicols}}%

我收到以下错误:

! LaTeX3 Error: Variable \l_keyanswer_data_mchoice_seq undefined.

我怎样才能解决这个问题?

感激的

答案1

一旦设置了键,值将保持不变。

在设置指定的值之前,您可以通过指定相关键来简单地恢复该值:

\keys_set:nn { keyanswer } { #1 } 

应该成为

\keys_set:nn { keyanswer } { columns=1, #1 } 

相关内容