包含通过 \def 定义的 \newtoks 的 pgfmath 表达式

包含通过 \def 定义的 \newtoks 的 pgfmath 表达式

这肯定是另一个与扩展相关的问题,因为我不知道为什么会出现以下情况

\def\MaxValueOfTok{8}%
\newtoks{\SomeTokDefinedViaDef}
\SomeTokDefinedViaDef={\MaxValueOfTok}

\pgfmathsetmacro{\Difference}{10-\the\SomeTokDefinedViaDef}%

失败

包 PGF 数学错误:未知运算符8' or8@'(在‘10-8’中)。

如果可能的话,我更希望采用只需要改变\pgfmathsetmacro计算,而不需要对令牌定义方式进行任何更改的解决方案。或者,调整\def设置方式也可以。

取消注释 MWE 中的最后两行将重现该问题。

代码:

\documentclass{article}
\usepackage{tikz}% Easy way to get pgfmath

\def\MaxValueOfTok{8}%

\newtoks{\SomeTokDefinedDirectly}
\newtoks{\SomeTokDefinedViaDef}

\SomeTokDefinedDirectly={7}
\SomeTokDefinedViaDef={\MaxValueOfTok}

\begin{document}
\pgfmathsetmacro{\Difference}{10-5}%
Differerence is \Difference (numerical).

\pgfmathsetmacro{\Difference}{10-\MaxValueOfTok}%
Differerence is \Difference (using def).

\pgfmathsetmacro{\Difference}{10-\the\SomeTokDefinedDirectly}%
Differerence is \Difference (using SomeTokDefinedDirectly).

%\pgfmathsetmacro{\Difference}{10-\the\SomeTokDefinedViaDef}%
%Differerence is \Difference (using SomeTokDefinedViaDef).
\end{document}

答案1

您可以事先进行完整的扩展:

\documentclass{article}
\usepackage{pgf}% Easy way to get pgfmath

\def\epgfmathsetmacro#1#2{\begingroup
  \edef\x{\endgroup\noexpand\pgfmathsetmacro\noexpand#1{#2}}\x}

\def\MaxValueOfTok{8}%

\newtoks\SomeTokDefinedDirectly
\newtoks\SomeTokDefinedViaDef

\SomeTokDefinedDirectly={7}
\SomeTokDefinedViaDef={\MaxValueOfTok}

\begin{document}
\epgfmathsetmacro{\Difference}{10-5}%
Differerence is \Difference (numerical).

\epgfmathsetmacro{\Difference}{10-\MaxValueOfTok}%
Differerence is \Difference (using def).

\epgfmathsetmacro{\Difference}{10-\the\SomeTokDefinedDirectly}%
Differerence is \Difference (using SomeTokDefinedDirectly).

\epgfmathsetmacro{\Difference}{10-\the\SomeTokDefinedViaDef}%
Differerence is \Difference (using SomeTokDefinedViaDef).
\end{document}

答案2

您必须使用 手动扩展它10\expandafter-\the\SomeTokDefinedViaDef

\documentclass{article}
\usepackage{tikz}% Easy way to get pgfmath

\def\MaxValueOfTok{8}%

\newtoks{\SomeTokDefinedDirectly}
\newtoks{\SomeTokDefinedViaDef}

\SomeTokDefinedDirectly={7}
\SomeTokDefinedViaDef={\MaxValueOfTok}

\begin{document}
\pgfmathsetmacro{\Difference}{10-5}%
Differerence is \Difference (numerical).

\pgfmathsetmacro{\Difference}{10-\MaxValueOfTok}%
Differerence is \Difference (using def).

\pgfmathsetmacro{\Difference}{10-\the\SomeTokDefinedDirectly}%
Differerence is \Difference (using SomeTokDefinedDirectly).

\pgfmathsetmacro{\Difference}{10\expandafter-\the\SomeTokDefinedViaDef}%
Differerence is \Difference (using SomeTokDefinedViaDef).
\end{document}

答案3

pgfmath另一个选项是从包l3fp中替换l3kernel。 中的解析器l3fp负责扩展所有内容;它还会解压\toks和其他寄存器的内容。无需\the

\documentclass{article}

%% Load expl3 for l3fp, and xparse for \NewDocumentCommand.
\usepackage{expl3, xparse}
\ExplSyntaxOn
\NewDocumentCommand {\explfpsetmacro} { m m }
  { \tl_set:Nx #1 { \fp_to_tl:n {#2} } }
\ExplSyntaxOff
%%

\def\MaxValueOfTok{8}%

\newtoks{\SomeTokDefinedDirectly}
\newtoks{\SomeTokDefinedViaDef}

\SomeTokDefinedDirectly={7}
\SomeTokDefinedViaDef={\MaxValueOfTok}

\begin{document}
\explfpsetmacro{\Difference}{10-5}%
Differerence is \Difference (numerical).

\explfpsetmacro{\Difference}{10-\MaxValueOfTok}%
Differerence is \Difference (using def).

\explfpsetmacro{\Difference}{10-\SomeTokDefinedDirectly}%
Differerence is \Difference (using SomeTokDefinedDirectly).

\explfpsetmacro{\Difference}{10-\SomeTokDefinedViaDef}%
Differerence is \Difference (using SomeTokDefinedViaDef).
\end{document}

需要注意以下几点:

  • 目前,pgfmath提供比更多的功能l3fp
  • 计算l3fp很多更精确(16 位浮点数,相对于 TeX 的维度范围);
  • 速度相当;

  • 一些函数很可能永远不会在表达式中使用l3fp,即盒子测量(\widthof...)和随机数。

相关内容