请问大佬,为什么在\AtEndDocument
后的代码,运行后不能成功显示
\documentclass{ctexart}
\usepackage{xcolor,tasks,xeCJKfntef}
\ExplSyntaxOn
\seq_new:N \l_fillin_count_seq
\NewDocumentCommand{\fillin}{+m}
{
\textcolor{red}{\CJKunderline{#1}}
\seq_gput_right:Nn \l_fillin_count_seq {#1}
}
\AtEndDocument{
\newcommand{\printanswers}{
\newpage
\section*{填空题答案}
\begin{tasks}(4)
\seq_map_inline:Nn \l_fillin_count_seq {
\task ##1
}
\end{tasks}
}
\printanswers
}
\ExplSyntaxOff
\begin{document}
这是1 \fillin{这是1}
这是2 \fillin{这是2}
这是3 \fillin{这是3}
这是4 \fillin{这是4}
这是5 \fillin{这是5}
\end{document}
还是展开问题,tasks 环境内部以 \task
这个 token
作为分隔符, \task
本身并没有被定义, 所以当 tasks 环境读取的时候遇到
\seq_map_inline:Nn \l_fillin_count_seq
{
\task ##1
}
时, 它没有找到 \task
(注意这里的 \task
在 group 内部), 于是就会抛出警告, 且没有解析到 item
.
解决办法是先展开
\seq_map_inline:Nn \l_fillin_count_seq
{
\task ##1
}
为
\task xxx
\task xxx
\task xxxx
...
\documentclass{ctexart}
\usepackage{xcolor,tasks,xeCJKfntef}
\ExplSyntaxOn
\seq_new:N \l_fillin_count_seq
\NewDocumentCommand{\fillin}{+m}
{
\textcolor{red}{\CJKunderline{#1}}
\seq_gput_right:Nn \l_fillin_count_seq {#1}
}
\AtEndDocument{
\newcommand{\printanswers}{
\newpage
\section*{填空题答案}
\seq_map_inline:Nn \l_fillin_count_seq
{
\tl_put_right:Nn \l_tmpa_tl { \task ##1 }
}
\use:e
{
\exp_not:n { \begin{tasks}(4) }
\exp_not:V \l_tmpa_tl
\exp_not:n { \end{tasks} }
}
}
\printanswers
}
\ExplSyntaxOff
\begin{document}
这是1 \fillin{这是1}
这是2 \fillin{这是2}
这是3 \fillin{这是3}
这是4 \fillin{这是4}
这是5 \fillin{这是5}
\end{document}
1,2
: 其实 tasks 的列表解析机制类似于这里拿到的
\l_tmpa_seq
里面装的就是一个一个的item
.注意
得到的是
只有两项(也可以说是两个
item
). 这里也是解释了为什么你代码虽然处于
tasks
的环境中,且有\task
这个 token, 但它没有被作为分隔符参与分割, 因为它在group
内(指 花括号 内). 所以在未展开之前, 它没有找到\task
, 所以得到的_xxx_seq
为空, 这就是我所说的 没有解析到item.3
:exp_not:<xxx>
系列函数用于 阻止展开 的,上面代码的目的是先展开
\l_tmpa_tl
而后展开 tasks 环境, 所以用了\use:e
且在内部用了exp_not:n { xxx }
来阻止\begin{tasks}, \end{tasks}
被e
型展开.这里需要先将
\l_tmpa_tl
展开一次, 注意是一次,而不是递归展开至无法展开. 这是因为\l_tmpa_tl
中保存的是形如的内容, 前面其实提到了
\task
只作为分隔符,是未定义的. 如果不使用\exp_not:V
的话,那么它将会被递归展开而引发报错,即使\task
是已经定义的,也会被继续展开,这不是我们的目的.所以这里的
\exp_not:V
的作用就是 阻止后面一个 token 被 e 型展开的同时对其做 V 型展开.明白了,谢谢大佬