我还没有找到将参数传递给环境的方法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}
如果有人想到了改进此工作流程的方法,请发表评论。