任务环境与 pgffor 的 foreach

任务环境与 pgffor 的 foreach

我想\foreach在列表中创建任务(通过包tasks) 放在问题中。MWE:

\documentclass{article}
\usepackage[magyar]{babel}
\usepackage[utf8x]{inputenc}
\usepackage{t1enc}
\usepackage{exsheets}
\usepackage{pgffor}
\usepackage{fp}
\def\pontlist{
2/3/1/4/,
5/1/-4/3/,
2/7/11/10/,
4/-3/5/7/,
-4/4/5/-7/,
-4/-4/4/4/,
3/7/-3/10/,
-1/-2/3/4/,
-1/3/-2/1/
}
\newcommand{\felezopont}[4]{
  \FPeval{\resx}{round( ( (#1)+(#3) )/2,1)}
  \FPeval{\resy}{round( ( (#2)+(#4) )/2,1)}
  \task $A(#1;#2)$, $B(#3;#4)$
  {$(\resx;\resy)$}
}
\begin{document}
\begin{question}
  Határozd meg a következő pontpárok felezőpontját!
  \begin{tasks}
    \foreach \ax/\ay/\bx/\by in \pontlist {
      \felezopont{\ax}{\ay}{\bx}{\by}
    }
  \end{tasks}
\end{question}
\end{document}

没有的话\begin{tasks} ... \end{tasks}也可以正常工作,但是使用tasks环境会导致错误:

! LaTeX Error: Something's wrong--perhaps a missing \item.

See the LaTeX manual or LaTeX Companion for explanation.
Type  H <return>  for immediate help.
 ...

l.33 \end{question}

我使用错了什么?

答案1

您需要确保tasks环境确实可以看到\tasks。它们不能隐藏在宏中(即使它是可扩展的)。顺便说一句:它tasks本身就是一个包 –exsheets只需加载它即可。

这是一个可能的解决方案:

\newcommand*\pontlist{
  2/3/1/4/,
  5/1/-4/3/,
  2/7/11/10/,
  4/-3/5/7/,
  -4/4/5/-7/,
  -4/-4/4/4/,
  3/7/-3/10/,
  -1/-2/3/4/,
  -1/3/-2/1/
}

% remove \task from the definition:
\newcommand{\felezopont}[4]{
  \FPeval{\resx}{round( ( (#1)+(#3) )/2,1)}
  \FPeval{\resy}{round( ( (#2)+(#4) )/2,1)}
  $A(#1;#2)$, $B(#3;#4)$
  {$(\resx;\resy)$}
}

% build list for the tasks environment:
\newcommand*\taskslist{}
\foreach \ax/\ay/\bx/\by in \pontlist {
  \begingroup
  \edef\x{\endgroup
    \expandafter\noexpand\csname g@addto@macro\endcsname
    \noexpand\taskslist{\noexpand\task\noexpand\felezopont{\ax}{\ay}{\bx}{\by}}%
  }\x
}

% needed helper macros so the tasks environment actually sees \task macros:
\newcommand\switchtwo[2]{#2#1}
\newcommand\expandsecond[2]{%
  \expandafter\switchtwo\expandafter{#1}{#2}%
}

进而:

\expandsecond\taskslist
{\begin{tasks}}
\end{tasks}

这种解决方案的缺点是它不能在类似包question的环境中使用exsheets,因为\begin{tasks}它对它来说是隐藏的,而\end{tasks}不是。但解决这个问题的方法很简单:把它完全隐藏在宏中:

\newcommand*\printtaskslist{%
  \expandsecond\taskslist
  {\begin{tasks}}
  \end{tasks}%
}

进而

\begin{question}
  Text
  \printtaskslist
\end{question}

在此处输入图片描述

完整代码:

\documentclass{article}
\usepackage[utf8]{inputenc}

\usepackage{exsheets,tasks}
\usepackage{pgffor}
\usepackage{fp}

\newcommand*\pontlist{
  2/3/1/4/,
  5/1/-4/3/,
  2/7/11/10/,
  4/-3/5/7/,
  -4/4/5/-7/,
  -4/-4/4/4/,
  3/7/-3/10/,
  -1/-2/3/4/,
  -1/3/-2/1/
}

% remove \task from the definition:
\newcommand{\felezopont}[4]{
  \FPeval{\resx}{round( ( (#1)+(#3) )/2,1)}
  \FPeval{\resy}{round( ( (#2)+(#4) )/2,1)}
  $A(#1;#2)$, $B(#3;#4)$
  {$(\resx;\resy)$}
}

% build list for the tasks environment:
\newcommand*\taskslist{}
\foreach \ax/\ay/\bx/\by in \pontlist {
  \begingroup
  \edef\x{\endgroup
    \expandafter\noexpand\csname g@addto@macro\endcsname
    \noexpand\taskslist{\noexpand\task\noexpand\felezopont{\ax}{\ay}{\bx}{\by}}%
  }\x
}

% needed helper macros so the tasks environment actually sees \task macros:
\newcommand\switchtwo[2]{#2#1}
\newcommand\expandsecond[2]{%
  \expandafter\switchtwo\expandafter{#1}{#2}%
}

\newcommand*\printtaskslist{%
  \expandsecond\taskslist
  {\begin{tasks}}
  \end{tasks}%
}

\begin{document}

\begin{question}
  Text
  \printtaskslist
\end{question}

\end{document}

答案2

您需要\task提前准备好清单并交付扩展在环境中。以下是在和tasks的帮助下实现此目的的方法。xparseexpl3

请避免使用过时的软件包t1encutf8x

\documentclass{article}
\usepackage[T1]{fontenc}    % NOT t1enc
\usepackage[utf8]{inputenc} % NOT utf8x
\usepackage[magyar]{babel}

\usepackage{xparse,exsheets}

\ExplSyntaxOn
% function for print the coordinates from the input x1/y1/x2/y2/
\cs_new:Npn \uzsolt_felezopont:w #1/#2/#3/#4/
 {
  $A(#1;#2)$,~$B(#3;#4)$~$(\fp_eval:n { (#1+#3)/2 }; \fp_eval:n { (#2+#4)/2 })$
 }
% macro for making the tasks environment
\cs_new_protected:Nn \uzsolt_pointtask:n
 {
  \begin{tasks}
  #1
  \end{tasks}
 }
% the variant that accepts a token list variable as its argument
\cs_generate_variant:Nn \uzsolt_pointtask:n { V }

% a variable for later usage
\tl_new:N \l_uzsolt_pointtask_tl

% the main macro that accepts an implicit list of points as argument
\NewDocumentCommand{\pointtask}{m}
 {
  \tl_clear:N \l_uzsolt_pointtask_tl
  \clist_map_inline:Nn #1
   {
    \tl_put_right:Nn \l_uzsolt_pointtask_tl { \task \uzsolt_felezopont:w ##1 }
   }
  \uzsolt_pointtask:V \l_uzsolt_pointtask_tl
 }
\ExplSyntaxOff


\newcommand\pontlist{
  2/3/1/4/,
  5/1/-4/3/,
  2/7/11/10/,
  4/-3/5/7/,
  -4/4/5/-7/,
  -4/-4/4/4/,
  3/7/-3/10/,
  -1/-2/3/4/,
  -1/3/-2/1/
}

\begin{document}

\begin{question}
Határozd meg a következő pontpárok felezőpontját!
\pointtask\pontlist
\end{question}

\end{document}

另一方面,如果你\pointtask定义

  \clist_map_inline:nn {#1}

而不是\clist_map_inline:Nn #1,输入可以是

\begin{question}
Határozd meg a következő pontpárok felezőpontját!
\pointtask{
  2/3/1/4/,
  5/1/-4/3/,
  2/7/11/10/,
  4/-3/5/7/,
  -4/4/5/-7/,
  -4/-4/4/4/,
  3/7/-3/10/,
  -1/-2/3/4/,
  -1/3/-2/1/
}
\end{question}

(不需要先前的定义\pontlist)在我看来,这样会更好。

在此处输入图片描述

相关内容