使用任务包创建练习集的文件 I/O:缺少 \item

使用任务包创建练习集的文件 I/O:缺少 \item

背景:我正在尝试使用一些分布在多个文件中的开放文本中的练习。我重写了输入机制,并使其运行良好。我可以使用multicolsenumerate在两列中垂直打印练习集,但想水平打印它们,因此使用tasks包。问题如下:

问题:当从 更改为 时enumeratetasks我收到missing \item错误。我认为这是因为\par在 I/O 操作中包含 时引入了\tasktasks软件包文档将此列为环境与 不同的一种方式enumerate\par不允许 )。如果是这种情况,那么我找不到它被引入的位置。如果不是,那么我不知道发生了什么。

梅威瑟:

\documentclass{article}
\usepackage{xparse}
\usepackage{tasks}
\usepackage{filecontents}

\begin{filecontents*}{numbers_20.tex}
{$5 - (2+3)$}
{$0$}
\end{filecontents*}

\begin{filecontents*}{numbers_21.tex}
{$5 - (2-3)$}
{$6$}
\end{filecontents*}

\begin{filecontents*}{numbersset.tex}
\exinput{numbers_20.tex}
\exinput{numbers_21.tex}
\end{filecontents*}

\ExplSyntaxOn
\ior_new:N \l__exread_ior % read exercise
\ior_new:N \l__exsetread_ior % read exercise set
\ior_new:N \l__allread_ior % read all

%Relevant code below
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\NewDocumentCommand{\exinput}{m}{
    \ior_open:Nn \l__exread_ior {#1} % open exercise file
    \ior_get:NN \l__exread_ior \l_tmpb_tl % get line
    \task\l_tmpb_tl % add task
    \ior_close:N \l__exread_ior
}

\NewDocumentCommand{\exsetinput}{m}{
    \ior_open:Nn \l__exsetread_ior {#1} % open set file
    \ior_map_inline:Nn \l__exsetread_ior {\seq_put_right:Nn \l_tmpb_seq {##1}} % put exercises in a sequence
    % if following changed to enumerate, and line 31 to item then works as expected.
    \begin{tasks}(2) % start tasks
        % seq items are "exinput" (above) and should print \task\blah
        \seq_use:Nn \l_tmpb_seq {}
    \end{tasks}

    \ior_close:N \l__exsetread_ior 
    \seq_clear:N \l_tmpb_seq
}


\ExplSyntaxOff
\begin{document}

\exsetinput{numbersset}

\end{document}

答案1

问题是tasks环境的工作方式不太像enumerateenumerate是一个“传统”环境,它会逐行执行代码,直到找到其结尾。tasks它更像一个命令,抓取环境的内容,然后执行其操作。

环境抓取其主体,然后在每次出现标记时将其拆分\task。但是,在您的代码中没有这样的标记;只有\seq_use:Nn \l_tmpb_seq {}

为了使其正常工作,tasks您需要先读取所有内容并将其与\task环境主体中的明确标记一起放入,然后启动tasks环境。

我修改了你的代码来做到这一点。它使用临时序列\l__exread_tmp_seq(避免使用\l_tmpa_seq和其他此类变量;它们只用于短期使用,如快速测试)来存储读取的练习。然后它读取文件(numbersset.tex)而不进行任何特殊处理。此文件应包含要读取的文件名,每行一个。

代码在文件的每一行上进行迭代,并在每一行中使用\__exread_input_one:Nn(我将其设为私有函数;您不需要在文件的每一行中使用它,代码会为您完成 :-)。此内部函数还在每个文件的每一行上进行迭代,并将该行附加到序列变量。完成所有这些操作后,序列应包含 中列出的所有文件中的所有行numbersset.tex,每行前面都有一个\task标记。

完成后,函数会在启动环境之前x展开。一旦环境启动,一切都会各就各位,并完成其工作:\seq_use:Nn \l__exread_tmp_seq { }taskstasks

在此处输入图片描述

代码如下:

\documentclass{article}
\usepackage{xparse}
\usepackage{tasks}
\usepackage{filecontents}
\begin{filecontents*}{numbers_20.tex}
{$5 - (2+3)$}
{$0$}
\end{filecontents*}
\begin{filecontents*}{numbers_21.tex}
{$5 - (2-3)$}
{$6$}
\end{filecontents*}
\begin{filecontents*}{numbersset.tex}
numbers_20.tex
numbers_21.tex
\end{filecontents*}
\ExplSyntaxOn
\ior_new:N \l__exread_all_ior
\ior_new:N \l__exread_one_ior
\seq_new:N \l__exread_tmp_seq
\cs_new_protected:Npn \__exread_input_one:Nn #1 #2
  {
    \ior_open:Nn \l__exread_one_ior {#2}
    \ior_map_inline:Nn \l__exread_one_ior
      { \seq_put_right:Nn #1 { \task ##1 } }
    \ior_close:N \l__exread_one_ior
  }
\NewDocumentCommand { \exsetinput } { m }
  {
    \seq_clear:N \l__exread_tmp_seq
    \file_if_exist:nTF {#1}
      {
        \ior_open:Nn \l__exread_all_ior {#1}
        \ior_map_inline:Nn \l__exread_all_ior
          { \__exread_input_one:Nn \l__exread_tmp_seq {##1} }
        \ior_close:N \l__exread_all_ior
      }
      { \msg_error:nnn { exread } { file-not-found } {#1} }
    \use:x
      {
        \exp_not:N \begin{tasks}(2)
          \seq_use:Nn \l__exread_tmp_seq { }
        \exp_not:N \end{tasks}
      }
  }
\msg_new:nnn { exread } { file-not-found }
  { File~`#1'~not~found. }
\ExplSyntaxOff
\begin{document}

\exsetinput{numbersset}

\end{document}

相关内容