\def で定義された \newtoks を含む pgfmath 式

\def で定義された \newtoks を含む pgfmath 式

これは、拡張に関連する問題の1つであるに違いありません。

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

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

失敗する

パッケージ PGF 数学エラー: 不明な演算子8' or8@' ('10-8' 内)。

可能であれば、\pgfmathsetmacro計算の変更のみを必要とし、トークンの定義方法を変更する必要がないソリューションが望ましいです。あるいは、\defの設定方法を調整することでも同様に機能します。

MWE の最後の 2 行のコメントを解除すると、問題が再現されます。

コード:

\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

もう 1 つのオプションは、バンドルからpgfmathを に置き換えることです。 のパーサーは、すべてを展開する処理を行います。また、 およびその他のレジスタの内容を展開します。 は必要ありません。l3fpl3kernell3fp\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多くのより正確(TeX の次元の範囲に対して 16 桁の浮動小数点)
  • 速度は同等です。

  • いくつかの関数l3fp、つまりボックス測定 ( \widthof...) と乱数は、式内で使用するようには実装されない可能性がほとんどです。

関連情報