问题

问题

如何在 ie 上添加“1000 sep” \sage{2^333}

在此处输入图片描述

\documentclass{report}
\usepackage{sagetex}
\usepackage{siunitx}
\sisetup{group-separator = \text{\,}}

\begin{document}
Works:  \num{9000123}

\begin{sageblock}
x=2^333
\end{sageblock}

Works: \sage{x}

Works not: %\num{\sage{x}}
\end{document}

答案1

问题

\sage和宏\sagestr同时执行多项操作,其中一些操作不“可扩展”(实际上,它\ST@sage执行大部分工作)。这与 的问题完全相同\ref,后者直接由 调用\ST@sage。幸运的是,在这种情况下,有办法设计一个可扩展的接口;这就是 和 等包refcount所做zref的。这个想法很简单:

  1. 在仅扩展上下文中,你可以使用“可扩展”命令1来检索与引用关联的标记,我们将其称为福巴此处。此命令可能会根据测试结果扩展为各种标记序列,但无法打印错误消息或执行分配(LuaTeX 除外,这些操作无法在仅扩展的上下文中完成)。如果福巴您要求的引用已定义,命令扩展为与此引用关联的标记(就您而言,这将是 Sage 计算的结果)。

  2. 在你可以做更多事情的地方,而不仅仅是扩展标记,你使用第二个命令来告诉 LaTeX 你已经使用了引用福巴。然后,如果 LaTeX 发现该引用福巴未定义(因为例如在我们的例子中 Sage 尚未运行),它会记住并在运行结束时警告您某些引用未定义,您需要重新运行某些内容(此处为 Sage)。

在我们的例子中,在这两个命令之前还需要第三个命令:将您选择的宏(我们称之为\macro)与 Sage 表达式关联起来,以便将表达式写入.sagetex.sage文件以供 Sage 稍后处理。然后您可以使用诸如\estGet{\macro}恢复以可扩展的方式Sage 计算的表达式的值。这里\estGet是来自包的宏expsagetex,我为这个答案编写了它,可以很容易地获得所需的结果。

解决方案expsagetex

expsagetex有可用的 LaTeX 包吗这里。它是顶层,sagetex允许以可扩展的方式从 Sage 检索结果。我将在下面解释如何使用它,但您可能希望从快速开始节选自论文目录(源代码这里)。这是一个包含教程、许多示例和解释的文件。

使用expsagetex,您的问题可以按如下方式解决。两个示例文件都可以使用以下命令进行编译:

pdflatex document.tex
sage document.sagetex.sage
pdflatex document.tex

(或者,您也可以使用lualatexxelatex)。

不带自动换行

\documentclass{article}
\usepackage{expsagetex}
\usepackage{siunitx}
\sisetup{group-separator = \,}

\setlength{\parindent}{0pt}

\begin{document}

With \verb|\estRecordFormatted|:\smallskip

\estRecordFormatted{\myIntRef}{2**233}%
\num{\estGet[-1]{\myIntRef}}%
\estRefUsed{\myIntRef}

\medskip
With \verb|\estRecordStr|:\smallskip

\estRecordFormatted{\myIntRefII}{str(2**233)}%
\num{\estGet[-1]{\myIntRefII}}%
\estRefUsed{\myIntRefII}

\end{document}

不带自动换行

如果你想重用x由以下方式定义的 Python 变量:

\begin{sageblock}
x = 2**333
\end{sageblock}

当然,您也可以通过替换来实现这一点,例如,将其替换\estRecordFormatted{\myIntRef}{2**233}\estRecordFormatted{\myIntRef}{x}。这是因为在重要的上下文中,和2**333都是x计算同一对象的 Python 表达式:您要打印的整数。

具有自动换行功能

如果您希望数字自动换行,可以不使用siunitx并从中获得的数字,然后对其进行后处理,expsagetex以便在适当的位置插入水平粘连。以下是使用 实现此目的的方法expl3

\documentclass{article}
\usepackage{expsagetex}
\usepackage{xparse}

\ExplSyntaxOn

\regex_const:Nn \c_cis_regex { ( \cB\{ \c[LO]. \cE\} ){3} }
\tl_new:N \l_cis_tmpa_tl

\cs_generate_variant:Nn \tl_reverse_items:n { V }
\prg_generate_conditional_variant:Nnn \tl_if_eq:nn { Vx } { TF }

% #1: separator
% #2: “number”
\cs_new_protected:Npn \cis_seperate_thousands:nn #1#2
  {
    \tl_set:Nx \l_cis_tmpa_tl { \tl_reverse_items:n {#2} }
    \tl_set:Nn \l_tmpa_tl {#1}
    \regex_replace_all:NnN \c_cis_regex
      { \0 \cB\{ \u{\l_tmpa_tl} \cE\} } \l_cis_tmpa_tl
    \tl_set:Nx \l_cis_tmpa_tl { \tl_reverse_items:V \l_cis_tmpa_tl }

    \tl_if_eq:VxTF \c_space_tl { \tl_head:N \l_cis_tmpa_tl }
      { \tl_tail:N \l_cis_tmpa_tl }
      { \tl_use:N \l_cis_tmpa_tl }
  }

\cs_generate_variant:Nn \cis_seperate_thousands:nn { nx }

% The default separator (\,) is unbreakable.
\NewDocumentCommand \separateThousands { O{\,} m }
  { \cis_seperate_thousands:nx {#1} {#2} }

\NewDocumentCommand \thinbreakablespace { }
  { \hspace{.16667em plus 0.01em} }

\ExplSyntaxOff

\setlength{\parindent}{0pt}

\begin{document}

With \verb|\estRecordFormatted|:\smallskip

\estRecordFormatted{\myIntRef}{2**233}%
\separateThousands[\thinbreakablespace]{\estGet[-1]{\myIntRef}}%
\estRefUsed{\myIntRef}

\medskip
With \verb|\estRecordStr|:\smallskip

\estRecordFormatted{\myIntRefII}{str(2**233)}%
\separateThousands[\thinbreakablespace]{\estGet[-1]{\myIntRefII}}%
\estRefUsed{\myIntRefII}

\end{document}

具有自动换行功能

在这里,您也可以x按照与上面解释的完全相同的方式使用变量作为输入。

使用expsagetex

以下是如何使用的说明expsagetex,以补充当前可用的文档(论文目录LaTeX 源)。

  • 函数\est*Record*\est[GA]RecordStr\est[GA]RecordFormatted\est[GA]RecordFloat)都是本答案第一部分中描述的“第三种”命令。调用\estRecordStr{\macro}{sage expression}记录文件sage expression中的内容.sagetex.sage并将结果输出与 关联\macro。此后,\macro将扩展为整数,但您不需要知道这一点。您需要它来恢复 Sage 计算的值,方法是将其传递给\estGet。您还应该将其传递给\estRefUsed(见下文)。

  • 这些\est*Record*函数在本地分配,除了名称中\macro带有 的函数,它们是全局分配的。G

  • 名称中\est*Record*带有Abefore 的函数(A 代表“关联数组”)接受两个参数,而不是单个参数。例如,相当于其中是通过扩展一次获得的控制序列标记。Record\macro\estARecordStr{base}{\whatever-\you-\want}{sage expression}\estRecordStr{\res}{sage expression}\res\csname base@\whatever-\you-\want\endcsname

  • \estRecordFormatted{\macro}{sage expression}与 类似\estRecordStr{\macro}{sage expression},不同之处在于它存储latex(sage expression)而不是仅仅存储sage expression在文件中。如果 Sage 中的评估结果包含指数、括号等内容,.sagetex.sage这可能会在从中获得的 LaTeX 代码中引入数学模式命令。sagetexstr(sage expression)

  • \estRecordFloat{\macro}{sage expression}{format}用于以特定格式记录浮点数。例如,如果格式.10f,这将格式化浮点数,就像您"%.10f" % (sage expression,)在 Python 中发出的那样,即:结果将格式化为 10 位小数,并且不会使用指数表示法。如果您需要更多的灵活性,请使用\estRecordStr(如果您需要 Python 代码的百分号,则可以使用或的常量\percent提供的宏)。sagetexexpl3\c_percent_str

  • \estGet是以可扩展方式检索结果的命令。更准确地说,\estGet[fallback]{\macro}最终扩展为与 相关联的结果\macro\est*Record*结果包装在 中\exp_not:n,又名\unexpanded)。第一个参数倒退是可选的,当 对应的引用\macro尚未定义时使用(可能意味着您需要在 .sagetex.sage 文件上运行 Sage)。当您在默认的 ,即,会导致错误的\estGet地方调用时(例如,在的命令的强制参数中),此参数特别有用。??siunitx\num

  • \estRefUsed{\macro}是您应该做的,以表明您的代码使用与 相关联的结果\macro。如果引用尚未定义,这将生成相应的警告,否则它根本不会执行任何操作。您应该\estGet[fallback]{\macro}在文档中的某个地方使用它。由于\estRefUsed不可扩展,您通常会在附近调用\estGet和,但不会完全在同一个位置。例如:\estRefUsed

    \estRecordFormatted{\mymacro}{2**5}  % record the expression 2**5
    \edef\myresult{\estGet[0]{\mymacro}} % store result in \myresult
    \estRefUsed{\mymacro}                % warn if it's not in the .sout file yet
    \show\myresult                       % show result on terminal
    

    在此示例中,在 内使用\estRecordFormatted或是不正确的。\estRefUsed\edef

在这些宏中,只有\estGet是可扩展的(以及它的expl3姊妹\est_get:nnn)。但这是最重要的一个,您可以在\edef\write\fpeval\num和许多其他地方使用它。例如,如果它从 Sage 检索到的内容是合适的类型,您可以\estGet在计算中间\fpeval、计数器或长度(dimen 或 skip)寄存器分配等中使用。您甚至可以使用它来计算许多点的坐标,以便用 Ti 绘制图Z,pgfplots或任何其他基于 TeX 的绘图框架。所有这些内容的示例都在论文目录; 看看它的LaTeX 源。 可能性是无止境!


脚注

  1. 在这个答案中,我们说一个命令是“可扩展的”,如果它在 中使用时能正确地完成它的工作\edef,即:它可以扩展到它被设计为的任何扩展,而不会产生任何不必要的副作用。这个属性通常被称为“完全可扩展”,但这个术语并不是真正固定的。至少 Heiko Oberdiek 使用的术语“可扩展”与我在他的一些软件包手册中使用的相同(如果我没记错的话),因此我觉得这样做相对安全。:-)

答案2

这有点笨重,但对我来说很有用:

\documentclass{report}
\usepackage{sagetex}
\usepackage{siunitx}
\sisetup{group-separator = \text{\,}}
\begin{document}

\begin{sageblock}
x=2^333
\end{sageblock}

\begin{sagesilent}
start="\\num{"
end="}"
\end{sagesilent}

Works: \sage{x}

Works, too: \sagestr{start+latex(x)+end}

\end{document}

相关内容