如何在 pgffor 循环中使用 sagesilent(或 verbatim)环境?

如何在 pgffor 循环中使用 sagesilent(或 verbatim)环境?

我想使用 创建不同版本的试卷和相应的示例解决方案sagetex。我需要为更复杂的计算分配变量,因此我依赖于环境sagesilent。但是,此环境似乎是一种类型verbatim环境,并且似乎与包提供的\foreach循环不兼容pgffor。后者是生成考试的不同版本所必需的。

错误消息如下所示:

错误:段落在 \verbatim@ 完成之前结束。

有没有办法让这两个包一起工作?理想情况下,解决方案可以选择允许在环境中扩展宏sagesilent就像在这个答案中一样

下面给出了一个 MWE 示例(没有宏扩展)。

\documentclass{minimal}
\usepackage{pgffor}
\usepackage{sagetex}
\begin{document}
\foreach \x/\y in {3/4,5/6,7/8} {

  The product of $\x$ and $\y$ is $\sage{\x*\y}$. % this works

  % but not this: (the assignment z= cannot be done in \sage{})
  \begin{sagesilent}
    z=2*9
  \end{sagesilent}

}
\end{document}

答案1

一种方法(易于理解并且仅使用公共 API,但很不方便)是使用exec()

\documentclass{minimal}
\usepackage{pgffor}
\usepackage{sagetex}
\begin{document}
\begin{sagesilent}
def execreturnempty(s):
    exec(s, globals())
    return ""
\end{sagesilent}

\foreach \x/\y in {3/4,5/6,7/8} {

  The product of $\x$ and $\y$ is $\sage{\x*\y}$. % this works

  a\sagestr{execreturnempty('z=2*9')}b
}

\sage{z}  % double check the code is executed correctly
\end{document}

其工作原理显而易见。

另一种方法是定义这样的\sageexec命令,但这种实现依赖于命令在sagetex包内部的实现方式。(编写代码,学习 TeX 编程,然后阅读sagetex包的源代码并调整定义sageblock

\documentclass{minimal}
\usepackage{pgffor}
\usepackage{sagetex}
\begin{document}

% ======== begin magic ========
\makeatletter
\newcommand{\sageexec}[1]{%
\ST@wsf{%
_st_.current_tex_line = \the\inputlineno^^J%
_st_.blockbegin()^^Jtry: #1^^J%
except:^^J %intentional space
_st_.goboom(\the\inputlineno)^^J_st_.blockend()}}
\makeatother
% ======== end magic ========

\foreach \x/\y in {3/4,5/6,7/8} {

  The product of $\x$ and $\y$ is $\sage{\x*\y}$. % this works

  \sageexec{z=2*9}
}

\sage{z}  % double check the code is executed correctly
\end{document}

相关内容