![如何在 pgffor 循环中使用 sagesilent(或 verbatim)环境?](https://linux22.com/image/326097/%E5%A6%82%E4%BD%95%E5%9C%A8%20pgffor%20%E5%BE%AA%E7%8E%AF%E4%B8%AD%E4%BD%BF%E7%94%A8%20sagesilent%EF%BC%88%E6%88%96%20verbatim%EF%BC%89%E7%8E%AF%E5%A2%83%EF%BC%9F.png)
我想使用 创建不同版本的试卷和相应的示例解决方案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}