Expressão pgfmath contendo um \newtoks definido através de um \def

Expressão pgfmath contendo um \newtoks definido através de um \def

Este deve ser outro daqueles problemas relacionados à expansão, pois não sei por que o seguinte

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

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

falha com

Erro matemático do pacote PGF: Operador desconhecido 8' or8@' (em '10-8').

Se possível, preferiria uma solução que exigisse apenas a alteração do \pgfmathsetmacrocálculo e não exigisse nenhuma alteração na forma como o token é definido. Como alternativa, ajustar a \defconfiguração também funcionaria.

Remover o comentário das duas últimas linhas do MWE reproduzirá o problema.

Código:

\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}

Responder1

Você pode fazer a expansão completa de antemão:

\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}

Responder2

Você terá que expandi-lo manualmente, usando 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}

Responder3

Outra opção é substituir pgfmathpelo l3fppacote l3kernel. O analisador l3fpcuida de expandir tudo; ele também descompacta o conteúdo de \toksoutros registros. Não há necessidade de \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}

Algumas coisas a serem observadas:

  • no momento, pgfmathoferece mais funções que l3fp;
  • cálculos com l3fpsãomuitomais preciso (pontos flutuantes de 16 dígitos, versus a faixa de dimensões do TeX);
  • a velocidade é comparável;

  • algumas funções provavelmente nunca serão implementadas para uso em l3fpexpressões, nomeadamente medidas de caixa ( \widthof...) e números aleatórios.

informação relacionada