如何将参数从 Sagetex 传递给 Sage?

如何将参数从 Sagetex 传递给 Sage?

我还没有找到将参数传递给环境的方法sagesilent,所以我想知道这是否可行。我的最终目的是sagetex与结合probsoln。该包probsoln允许您管理问题数据库,并且这些问题可以采用可选参数。因此,当我调用其中一个问题时,我想将其参数直接传递给sagetex进行计算。

我已经准备了一个MWE与 probsoln 无关的函数。它在 sagetex 中构建了一个多项式,我想要的是改变np=15(sagesilent 内部)的定义np=\np

如果我能做到扩张sagesilent 中的每个 LaTeX 宏,这都可以轻松完成。实际上,我认为这个问题也可以独立于 sage 和 sagetex 来表述,如下所示:如何在处理环境之前将环境内的宏替换为其定义/值?

有任何想法吗?

妇女权利委员会:

\documentclass{article}%
\PassOptionsToPackage{T1}{fontenc}
\usepackage{fontenc}
\usepackage[utf8]{inputenc}

\usepackage{sagetex}
\pagestyle{empty} 

\begin{document}
\def\np{15}

\begin{sagesilent}
np=15 #grado del polinomio p
p1=0
pcoeffs=range(np+1)
x = var('x')
for i in range(np+1):
   pcoeffs[i]= Integer(randint(-8,8))
   p1=p1+pcoeffs[i]*x^i
\end{sagesilent}
\noindent This is a polynom of grade $\np$:

$\sage{p1}$ 

\end{document}

答案1

在 内部扩展宏sagesilent需要更改环境中的 catcode 处理。以下代码将创建一个sagesilentexp在其中扩展宏的环境。

宏的行为与正常情况略有不同。不带参数的宏不会吃掉尾随空格,因为空格现在是文字。如果不带参数的宏后面跟着{},那么{}将在代码中显示为文字{} 我根据以下情况改进了答案这个问题,这样,不带参数的宏后面的括号就会按预期消失。 如果您需要文字反斜杠,则可以使用\textbackslash(这需要重新定义)。我还重新定义了\\文字反斜杠,因为在这种情况下,它的正常 LaTeX 用法是多余的,并且\\比更紧凑\textbackslash。同样,\{\}可用于添加文字括号。

\makeatletter
\newenvironment{sagesilentexp}%
  {\ST@beginsfbl%
    % All changes are in \verbatim@processline
    \def\verbatim@processline{%
      \begingroup
      % Redefine escapes so they write to file in literal fashion
      \edef\{{\@charlb}%
      \edef\}{\@charrb}%
      \edef\\{\@backslashchar}
      \let\textbackslash\@backslashchar
      % Retokenize with new catcodes
      \everyeof{\noexpand}%
      \endlinechar-1\relax
      \let\do\@makeother\dospecials%
      \catcode`\\=0%
      \catcode`\{=1%
      \catcode`\}=2%
      \xdef\verbatim@line@retok{\expandafter\scantokens\expandafter{\the\verbatim@line}}%
      \endgroup
      % Strip out any brace groups, and warn of unexpandable macros
      \let\verbatim@line@retok@final\empty
      \let\verbatim@line@retok@last\verbatim@line@retok
      \expandafter\gobble@retok@braces\verbatim@line@retok\@nil
      \expandafter\check@retok@unexpandable\verbatim@line@retok@final\@nil
      % Write retokenized result
      % Leading space is important since Python is whitespace-sensitive
      \ST@wsf{ \verbatim@line@retok@final}%
    }%
    \verbatim@start}%
  {\ST@endsfbl\@esphack}
\def\gobble@retok@braces#1#2\@nil{%
  \g@addto@macro{\verbatim@line@retok@final}{#1}%
  \if\relax\detokenize{#2}\relax
    \ifx\verbatim@line@retok@last\verbatim@line@retok@final
    \else
      \let\verbatim@line@retok@last\verbatim@line@retok@final
      \let\verbatim@line@retok@final\empty
      \expandafter\gobble@retok@braces\verbatim@line@retok@last\@nil
    \fi
  \else
    \gobble@retok@braces#2\@nil
  \fi}
\def\check@retok@unexpandable#1#2\@nil{%
  \ifcat#1\relax
    \PackageWarning{}{Verbatim text contained unexpandable macro \string#1}%
  \else
    \if\relax\detokenize{#2}\relax
    \else
      \check@retok@unexpandable#2\@nil
    \fi
  \fi}
\makeatother

答案2

我发布了我自己问题的答案,因为我找到了解决这个问题的方法。所以如果有人想做类似的事情,这是我的解决方案。

对生成随机问题的依赖sage非常严重,相比于使用来probsoln管理问题数据库,我发现更容易让它sage同时写出问题文本和解决方案。

工作流程将从创建一个仅包含sagesilent环境的 .tex 文件开始,其中每个问题都定义为 sage 函数,并具有自己的参数。此文件将插入到\input\begin{document}tex 文件中。

sagesilent此后,当您需要使用其中一个时,您只需调用主文档中的函数即可。

诀窍在于这些问题函数返回两个参数,其中一个参数称为问题其中一个叫解决方案\sagestr{problem},它们是 LaTeX 字符串,可以使用或与主文档一起调用\sagestr{solution}

如果有人想到了改进此工作流程的方法,请发表评论。

相关内容