J'ai voulu tent� une utilisation de Lua avec TikZ. J'ai donc copi�
(entre autres) le fichier pgflibraryfixedpointarithmetic.code.tex
propos� dans la version CVS de TikZ pour en faire ma propre version :
pgflibraryluaarithmetic.code.tex. Puis j'ai modifi� les macros pour
remplacer les appels � FP par des appels � Lua.
Exemple de macro avant conversion :
% add
%
\def\pgfmathfpadd#1#2{%
\pgfmathfpparse{#2}\let\pgfmath@result=\pgfmathresult%
\pgfmathfpparse{#1}%
\pgfmathfpadd@{\pgfmathresult}{\pgfmath@result}%
}
\def\pgfmathfpadd@#1#2{%
\begingroup%
\FPadd\pgfmathresult{#1}{#2}%
\pgfmath@smuggleone\pgfmathresult%
\endgroup%
}
Une fois modifi�e, elle devient :
% add
%
\def\pgfmathluacalcadd
\def\pgfmathluacalcadd#1#2{%
\pgfmathluacalcparse{#2}\let\pgfmath@result=\pgfmathresult%
\pgfmathluacalcparse{#1}%
\pgfmathluacalcadd@{\pgfmathresult}{\pgfmath@result}%
}
\def\pgfmathluacalcadd@#1#2{%
\begingroup%
\edef\luacalc@temp{\directlua{tex.print(#1 + #2)}}%
\global\let\pgfmathresult=\luacalc@temp%
\endgroup%
}
J'ai modifi� toutes les macros en utilisant ce principe.
Plusieurs remarques :
- Le nom des macros originales contient 'fp' alors que celui de mes
macros modifi�es utilise 'luacalc'.
- Le parseur d'expressions reste �crit en TeX (dans PGF) d'o� les
appels � \pgfmathluacalcparse pour pr�parer chaque op�rande avant
d'appeler la v�ritable macro de calcul.
- Les calculs sont plus pr�cis qu'avec la version PGF d'origine mais
ne semblent pas plus rapides.
Par contre, j'ai encore parfois un probl�me d'expansion de macros. Il
arrive parfois que l'un des op�randes ne soit pas "�valu�" jusqu'au
bout avant d'�tre transmis � Lua.
Question : comme je suis nul en TeX pur, quelqu'un pourrait-il me
donner une astuce pour que, dans la macro ci-dessus
(\pgfmathluacalcadd@), les arguments #1 et #2 soient *totalement*
"expand�s" (�a se dit ?) avant d'�tre transmis � Lua ?
--
Paul Gaborit - <http://perso.mines-albi.fr/~gaborit/>
On peut en y allant comme un bourrin avec les \expandafter. Le principe
est de 1-développer les 2 arguments avant qu'ils arrivent à
\pgfmathluacalcadd. Le 1-développement devrait suffire. Si ce n'est pas
le cas, il va falloir les développer totalement avec un \edef, mais
c'est une autre méthode.
Bref, pour 1-développer les 2 arguments, il suffit de remplacer la ligne
\pgfmathluacalcadd@{\pgfmathresult}{\pgfmath@result}%
Par ceci :
\expandafter\expandafter\expandafter
\pgfmathluacalcadd@
\expandafter\expandafter\expandafter
{\expandafter\pgfmathresult\expandafter}\expandafter
{\pgfmath@result}%
Pas testé par contre, mais bien que pas très élégant, ça devrait
fonctionner ;)
Sinon, pour développer *totalement* les 2 arguments, il vaut mieux
utiliser cette méthode.
Remplacer la ligne :
\pgfmathluacalcadd@{\pgfmathresult}{\pgfmath@result}%
par :
\begingroup
\edef\luacalc@temp{\noexpand\pgfmathluacalcadd@
{\pgfmathresult}{\pgfmath@result}}%
\expandafter\endgroup
\luacalc@temp
Christian
> On peut en y allant comme un bourrin avec les \expandafter. Le principe
> est de 1-d�velopper les 2 arguments avant qu'ils arrivent �
> \pgfmathluacalcadd. Le 1-d�veloppement devrait suffire. Si ce n'est pas
> le cas, il va falloir les d�velopper totalement avec un \edef, mais
> c'est une autre m�thode.
Ok.
> Bref, pour 1-d�velopper les 2 arguments, il suffit de remplacer la ligne
> \pgfmathluacalcadd@{\pgfmathresult}{\pgfmath@result}%
>
> Par ceci :
> \expandafter\expandafter\expandafter
> \pgfmathluacalcadd@
> \expandafter\expandafter\expandafter
> {\expandafter\pgfmathresult\expandafter}\expandafter
> {\pgfmath@result}%
>
> Pas test� par contre, mais bien que pas tr�s �l�gant, �a devrait
> fonctionner ;)
>
> Sinon, pour d�velopper *totalement* les 2 arguments, il vaut mieux
> utiliser cette m�thode.
> Remplacer la ligne :
> \pgfmathluacalcadd@{\pgfmathresult}{\pgfmath@result}%
>
> par :
> \begingroup
> \edef\luacalc@temp{\noexpand\pgfmathluacalcadd@
> {\pgfmathresult}{\pgfmath@result}}%
> \expandafter\endgroup
> \luacalc@temp
Sauf que l�, on modifie la macro \pgfmathluacalcadd et non
\pgfmathluacalcadd@. Or, la plupart du temps on ne passe pas par
\pgfmathluacalcadd (le parseur a d�j� fait son boulot).
Ok, fallait le dire !
Dans ce cas, s'il faut modifier \pgfmathluacalcadd@, on peut développer
au maximum les 2 arguments qui lui arrivent. Il suffit de remplacer la
ligne :
\edef\luacalc@temp{\directlua{tex.print(#1 + #2)}}%
par :
\edef\luacalc@temp{\noexpand\directlua{tex.print(#1 + #2)}}%
\edef\luacalc@temp{\luacalc@temp}%
Pas testé, évidemment...
Christian
> Le 28/12/2009 12:00, Paul Gaborit a �crit :
>> Sauf que l�, on modifie la macro \pgfmathluacalcadd et non
>> \pgfmathluacalcadd@. Or, la plupart du temps on ne passe pas par
>> \pgfmathluacalcadd (le parseur a d�j� fait son boulot).
>>
>
> Ok, fallait le dire !
Je pense l'avoir �crit dans mon premier message... ;-)
> Dans ce cas, s'il faut modifier \pgfmathluacalcadd@, on peut d�velopper
> au maximum les 2 arguments qui lui arrivent. Il suffit de remplacer la
> ligne :
> \edef\luacalc@temp{\directlua{tex.print(#1 + #2)}}%
>
> par :
> \edef\luacalc@temp{\noexpand\directlua{tex.print(#1 + #2)}}%
> \edef\luacalc@temp{\luacalc@temp}%
>
> Pas test�, �videmment...
En fait �a ne change rien au probl�me...
J'ai trouv� un ECM purement lua qui permet d'illustrer mon probl�me :
%%%%%%%%%%%%%%%%%%%%%%%%
\documentclass{article}
\begin{document}
\newcommand\myadd[2]{%
\typeout{myadd #1 #2}%
\directlua{tex.print(#1 + #2)}%
}
\myadd{34}{45}
\myadd{2}{\myadd{7}{1.23}}
\end{document}
%%%%%%%%%%%%%%%%%%%%%%%%
Comment d�finir correctement \myadd pour que le second appel
fonctionne comme pr�vu ?
Je ne connais pas du tout lualatex, d'ailleurs, c'est la première fois
que je compile quelque chose avec ce moteur !
Bon, j'ai tenté le diable, voici mon ECM, inspiré du tien :
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\documentclass{article}
\begin{document}
\newcommand\myadd[2]{\directlua{tex.print(#1 + #2)}}
\def\truc{45}
\def\machin{134}
\myadd{\truc}{\myadd{\machin}{200}}
\end{document}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Et bien, la compilation se passe bien, j'obtiens un fichier pdf sur
lequel est écrit 379, qui est bien la somme de 45, 134 et 200.
Où est le problème, y a t-il quelque chose que j'ai pas saisi ???
Christian
Si je prends ton code et que je commente la ligne \typeout, il n'y a pas
de probl�me. Pourquoi tiens-tu � faire une \typeout ?
>
> Si je prends ton code et que je commente la ligne \typeout, il n'y a
> pas de probl�me. Pourquoi tiens-tu � faire une \typeout ?
Ah oui... En quoi cela pose-t-il probl�me ? Il y a quelque chose que
je ne saisis pas. En fait, le code que j'ai montr� fonctionne la
plupart du temps (et il n'y a pas de \typeout) mais �choue parfois
exactement avec le m�me message d'erreur que lorsqu'il y a appel �
\typeout. Je crois qu'il faut que je lise le TeXLivre pour comprendre
mon souci... Je ne comprens pas pouquoi le code avec FP fonctionne
toujours alors que celui avec Lua plante parfois (selon ses
arguments).
> � (at) Mon, 28 Dec 2009 14:24:54 +0100,
> Jacques M <jacques@flute> �crivait (wrote):
>
>> Si je prends ton code et que je commente la ligne \typeout, il n'y a
>> pas de probl�me. Pourquoi tiens-tu � faire une \typeout ?
>
> Ah oui... En quoi cela pose-t-il probl�me ?
\typeout n'est pas purement d�veloppable.
Il faut savoir que l'argument de \directlua, avant d'�tre pass� �
l'interpr�teur Lua, subit le m�me traitement que s'il �tait dans un
\write : il est totalement d�velopp�, puis les �ventuelles s�quences de
contr�le restantes sont converties en caract�res avec la r�gle
habituelle (ajout du caract�re donn� par \escapechar au d�but, d'un
�ventuel espace � la fin). On peut imaginer que l'argument sera �crit
dans un fichier par \write et que le fichier sera lu par Lua.
Du coup, \myadd{2}{\myadd{7}{1.23}} va � un moment donner
\directlua{tex.print(2 + \myadd{7}{1.23})}
En ��pr�parant�� la cha�ne � donner � Lua, et en imaginant qu'on utilisait
\write16 au lieu de \typeout pour simplifier, on a
tex.print(2 + \typeout{myadd 7 1.23}\directlua{tex.print(7 + 1.23)}
puis
tex.print(2 + \write 16{myadd 7 1.23}8.23}
et c'est finalement cette chaine (en supposant \escapechar=91 comme d'habitude)
qui sera pass�e � Lua, car il n'y a pas moyen de developper \write. Je pense
que je n'ai pas besoin de poursuivre...
Pour d�boguer sans tomber sur ce probl�me, le mieux est sans doute de le faire
en Lua, par exemple
\directlua{io.write(myadd #1 #2)}
ou m�me
\directlua{io.write(myadd \unexpanded{#1 #2})}
> Il y a quelque chose que
> je ne saisis pas. En fait, le code que j'ai montr� fonctionne la
> plupart du temps (et il n'y a pas de \typeout) mais �choue parfois
> exactement avec le m�me message d'erreur que lorsqu'il y a appel �
> \typeout.
Peut-�tre un probl�me similaire alors...
> Je crois qu'il faut que je lise le TeXLivre pour comprendre
> mon souci...
Je crois en effet cas que LuaTeX ne rendra jamais inutile la lecture du Livre.
--
Manuel P�gouri�-Gonnard Institut de math�matiques de Jussieu
http://weblog.elzevir.fr/ http://people.math.jussieu.fr/~mpg/