% Copyright 2019 by Christophe Jorssen and Mark Wibrow % Copyright 2019 by Christian Feuersänger % % This file may be distributed and/or modified % % 1. under the LaTeX Project Public License and/or % 2. under the GNU Public License. % % See the file doc/generic/pgf/licenses/LICENSE for more details. % % $Id$ % % % This is a library for a LUA math parser and LUA math operations. % Advantage compared to its TeX pendant: it is FASTER and has HIGHER % ACCURACY. % Disadvantage: any function declared by means of % \pgfmathdeclarefunction is NOT automatically transported to the LUA % side (at the time of this writing). % LUA functions need to be defined by means of LUA code % % function pgfluamathfunctions.myoperation(a,b) % return a*2*b % end % % this will automatically set up 'myoperation' for use in % \pgfluamathparse{myoperation(4,2)} % % The library has TWO use-cases which are more or less distinct: one % is to use LUA for all math function, but not for math expression % parsing -- this was still under control of the TeX math parser. % This approach works like the 'fpu' library. % % The second approach is to use LUA to parse all math expressions - % but if someone calls \pgfmathadd@{1}{2}, it would use the TeX % command. This approach is relatively lightweight because it does not % need to substitute all \pgfmath* macros. % % One can mix both modes. % ******************************************************************* % Some luatex stuff. Should be put elsewhere (e.g. in % pgfutil-luatex-engine). \edef\pgfliblua@oldcatcodedoublequote{\the\catcode`\"}% \catcode`\"=12 % We assume luatex version > 0.39: % - \directlua will work % - \directlua is the only luatex primitive that we can assume % accessible without being prefixed by the format via % tex.enableprimitives. % Ideas taken from the ifluatex package (Heiko Oberdiek) \let\pgfutil@ifluatex\iffalse \begingroup\expandafter\expandafter\expandafter\endgroup \expandafter\ifx\csname directlua\endcsname\relax \else \expandafter\let\csname pgfutil@ifluatex\expandafter\endcsname \csname iftrue\endcsname \fi \pgfutil@ifluatex \let\pgfutil@directlua\directlua \pgfutil@directlua{% tex.enableprimitives('pgfutil@',{'luaescapestring'})}% \else \def\pgfutil@directlua#1{}% \def\pgfutil@luaescapestring#1{}% \fi \pgfutil@directlua{% pgfluamathfunctions = require("pgf.luamath.functions") pgfluamathparser = require("pgf.luamath.parser")}% % Patch some configuration macros such that the modifications are % available in LUA as well: \pgfkeys{ /pgf/trig format/deg/.add code={}{\directlua{pgfluamathfunctions.setTrigFormat("deg")}\aftergroup\pgfmath@settrigformat}, /pgf/trig format/rad/.add code={}{\directlua{pgfluamathfunctions.setTrigFormat("rad")}\aftergroup\pgfmath@settrigformat}, }% % ... and reactivate the key: \pgfmathiftrigonometricusesdeg{% \pgfkeys{/pgf/trig format/deg}% }{% \pgfkeys{/pgf/trig format/rad}% }% % re-activates the current trig format. This is important after a TeX % group has been closed. \def\pgfmath@settrigformat{% \pgfmathiftrigonometricusesdeg{% \directlua{pgfluamathfunctions.setTrigFormat("deg")}% }{% \directlua{pgfluamathfunctions.setTrigFormat("rad")}% }% }% \let\pgfmathsetseed@pgfbasic = \pgfmathsetseed \def\pgfmathsetseed#1{% \pgfmathsetseed@pgfbasic{#1}% \directlua{pgfluamathfunctions.setRandomSeed(pgfluamathfunctions.tonumber("\pgfmathresult"))}% }% % Patch 'declare function' such that it communicates the function % directly to LUA. \let\pgfmathnotifynewdeclarefunction@orig=\pgfmathnotifynewdeclarefunction \def\pgfmathnotifynewdeclarefunction#1#2#3{% \pgfmathnotifynewdeclarefunction@orig{#1}{#2}{#3}% % % we have to check if '#3' contains control sequences. % this is highly tricky as it may contain '#1'... \begingroup \toks0={#3}% \xdef\pgf@marshal@glob{\the\toks0 }% \endgroup \pgfutil@command@to@string\pgf@marshal@glob\pgf@marshal \expandafter\pgfutilifcontainsmacro\expandafter{\pgf@marshal}{% \def\pgf@temp{1}% }{% \def\pgf@temp{0}% }% \if1\pgf@temp % let lua produce an error when evaluating this function -- we cannot possibly expand the macro to its current state: \directlua{pgfluamathparser.pushLocalExpressionFunction(% "\pgfutil@luaescapestring{#1}",% #2,% "functionMustBeEvaluatedInTeX")}% \else \directlua{pgfluamathparser.pushLocalExpressionFunction(% "\pgfutil@luaescapestring{#1}",% #2,% "\pgfutil@luaescapestring{#3}")}% \fi % % ensure that the local function is removed at the end of the % scope. To this end, we maintain a stack on the LUA side. \aftergroup\pgfluamathparse@pop@local@function }% \def\pgfluamathparse@pop@local@function{% \directlua{pgfluamathparser.popLocalExpressionFunction()}% }% % End of luatex stuff % ******************************************************************* % Loading part: based on fpu library % if LUA failed to evaluate the expression, it will be evaluated in % TeX as fallback. This boolean defines if the error message shall be % shown or suppressed. The default is to suppress it and show any % resulting TeX errors. % % If LUA fails \pgfmathresult will be empty. % % This is actually only for debugging; it will be set implicitly when % activating/deactivating TeX fallback. \newif\ifpgfluamathshowerrormessage % Defines what happens if LUA failed to evaluate the expression: if % this is true, the TeX parser will be invoked as fallback. % % This happens % - for \chardef'ed boxes for which LUA lacks evaluation capabilities % - if the expression includes some function which is unavailable in % LUA (defined only in TeX) % - some special cases which simply haven't been added to the LUA % parser (yet). % At the time of this writing, this includes % -- arrays created via '{}' and indexed with '[]' % -- strings with "" % -- 'scalar' function % -- hex/octal/binary input \newif\ifpgfluamathenableTeXfallback \newif\ifpgfluamathcomputationactive \newif\ifpgfluamathparseractive \def\pgfluamath@makecomputationactive{% \ifpgfluamathcomputationactive \else \pgfluamath@checkuninstallcmd% \pgfluamath@install% \pgfluamathcomputationactivetrue \fi}% \def\pgfluamath@makecomputationinactive{% \ifpgfluamathcomputationactive \pgfluamath@uninstall% \pgfluamathcomputationactivefalse \fi}% \let\pgfluamath@pgfmathparse\pgfmathparse \def\pgfluamath@makeparseractive{% \ifpgfluamathparseractive \else \let\pgfluamath@pgfmathparse\pgfmathparse \let\pgfmathparse\pgfluamathparse \let\pgfmath@iftrue=\pgfmathluamath@iftrue \pgfluamathparseractivetrue \fi}% \let\pgfmath@iftrue@basic=\pgfmath@iftrue \def\pgfluamath@makeparserinactive{% \ifpgfluamathparseractive \let\pgfmathparse\pgfluamath@pgfmathparse \let\pgfmath@iftrue=\pgfmath@iftrue@basic \pgfluamathparseractivefalse \fi}% \pgfqkeys{/pgf}{% % Enable lua-side computation of \pgfmathresult % (will be deactivated after the current TeX group) luamath/.is choice, luamath/only computation/.code={% \pgfutil@ifluatex \pgfluamath@makecomputationactive \pgfluamath@makeparserinactive \else \pgfmath@error{Sorry, you need the luaTeX engine to use the luamath library}{}% \fi}, luamath/parser and computation/.code={% \pgfutil@ifluatex \pgfluamath@makecomputationactive \pgfluamath@makeparseractive \else \pgfmath@error{Sorry, you need the luaTeX engine to use the luamath library}{}% \fi}, luamath/off/.code={% \pgfluamath@makecomputationinactive \pgfluamath@makeparserinactive}, luamath/.default=only computation, % % activates ONLY the parser. This is fast and does not replace the % \pgfmath* functions. % @see |parser and computation| which also allows to write % \pgfmathadd{1}{2} to call LUA luamath/parser/.code={% \pgfutil@ifluatex \pgfluamath@makeparseractive \else \pgfmath@error{Sorry, you need the luaTeX engine to use the luamath library}{}% \fi }, luamath/output format/.is choice, luamath/output format/fixed/.code= {\def\pgfluamath@outputformat@choice{0}}, % returns results for use in the FPU luamath/output format/float/.code= {\def\pgfluamath@outputformat@choice{1}}, luamath/output format/fixed, % this is merely useful for debugging purposes, I guess. luamath/show error message/.is if=pgfluamathshowerrormessage, luamath/enable TeX fallback/.is choice, luamath/enable TeX fallback/true/.code={\pgfluamathenableTeXfallbacktrue\pgfluamathshowerrormessagefalse}, luamath/enable TeX fallback/false/.code={\pgfluamathenableTeXfallbackfalse\pgfluamathshowerrormessagetrue}, luamath/enable TeX fallback/.default=true, luamath/enable TeX fallback=true, }% \def\pgfluamath@uninstall@appendcmd#1{% \expandafter\gdef\expandafter\pgfluamath@uninstall\expandafter{% \pgfluamath@uninstall #1}}% % If the uninstall command is already assembled, it will skip the % uninstall assemblation. \def\pgfluamath@checkuninstallcmd{% \pgfutil@ifundefined{pgfluamath@uninstall}{% \global\let\pgfluamath@uninstall=\pgfutil@empty }{% % We already HAVE an uninstall command (prepared globally). % So: don't waste time assembling one! \def\pgfluamath@uninstall@appendcmd##1{}% \def\pgfluamath@prepareuninstallcmd##1{}% }% }% % This assembles an uninstall command globally ON FIRST USAGE. % See \pgfmathfloat@plots@checkuninstallcmd \def\pgfluamath@prepareuninstallcmd#1{% \expandafter\global\expandafter\let \csname pgfluamath@backup@\string#1\endcsname=#1% \expandafter\gdef\expandafter\pgfluamath@uninstall\expandafter{% \pgfluamath@uninstall \expandafter\let\expandafter#1\csname pgfluamath@backup@\string#1\endcsname}% }% \def\pgfluamath@install@function#1=#2{% \pgfluamath@prepareuninstallcmd{#1}% \let#1=#2% }% \def\pgfluamath@install{% \pgfluamath@install@function\pgfmathadd@=\pgfluamathadd@% \pgfluamath@install@function\pgfmathsubtract@=\pgfluamathsubtract@% \pgfluamath@install@function\pgfmathneg@=\pgfluamathneg@% \pgfluamath@install@function\pgfmathmultiply@=\pgfluamathmultiply@% \pgfluamath@install@function\pgfmath@iftrue=\pgfmathluamath@iftrue% \pgfluamath@install@function\pgfmathdivide@=\pgfluamathdivide@% % \pgfluamath@install@function\pgfmathdiv@=\pgfluamathdiv@% \pgfluamath@install@function\pgfmathfactorial@=\pgfluamathfactorial@% \pgfluamath@install@function\pgfmathsqrt@=\pgfluamathsqrt@% % \pgfluamath@install@function\pgfmathpow@=\pgfluamathpow@% \pgfluamath@install@function\pgfmathe@=\pgfluamathe@% \pgfluamath@install@function\pgfmathexp@=\pgfluamathexp@% \pgfluamath@install@function\pgfmathln@=\pgfluamathln@% \pgfluamath@install@function\pgfmathlogten@=\pgfluamathlogten@% % \pgfluamath@install@function\pgfmathlogtwo@=\pgfluamathlogtwo@% \pgfluamath@install@function\pgfmathabs@=\pgfluamathabs@% \pgfluamath@install@function\pgfmathmod@=\pgfluamathmod@% \pgfluamath@install@function\pgfmathMod@=\pgfluamathMod@% \pgfluamath@install@function\pgfmathround@=\pgfluamathround@% \pgfluamath@install@function\pgfmathfloor@=\pgfluamathfloor@% \pgfluamath@install@function\pgfmathceil@=\pgfluamathceil@% % \pgfluamath@install@function\pgfmathint@=\pgfluamathint@% % \pgfluamath@install@function\pgfmathfrac@=\pgfluamathfrac@% % \pgfluamath@install@function\pgfmathreal@=\pgfluamathreal@% \pgfluamath@install@function\pgfmathgcd@=\pgfluamathgcd@% \pgfluamath@install@function\pgfmathisprime@=\pgfluamathisprime@% \pgfluamath@install@function\pgfmathpi@=\pgfluamathpi@% \pgfluamath@install@function\pgfmathrad@=\pgfluamathrad@% \pgfluamath@install@function\pgfmathdeg@=\pgfluamathdeg@% \pgfluamath@install@function\pgfmathsin@=\pgfluamathsin@% \pgfluamath@install@function\pgfmathcos@=\pgfluamathcos@% \pgfluamath@install@function\pgfmathtan@=\pgfluamathtan@% \pgfluamath@install@function\pgfmathsec@=\pgfluamathsec@% \pgfluamath@install@function\pgfmathcosec@=\pgfluamathcosec@% \pgfluamath@install@function\pgfmathcot@=\pgfluamathcot@% \pgfluamath@install@function\pgfmathasin@=\pgfluamathasin@% \pgfluamath@install@function\pgfmathacos@=\pgfluamathacos@% \pgfluamath@install@function\pgfmathatan@=\pgfluamathatan@% \pgfluamath@install@function\pgfmathatantwo@=\pgfluamathatantwo@% \pgfluamath@install@function\pgfmathmax@=\pgfluamathmax@% \pgfluamath@install@function\pgfmathmin@=\pgfluamathmin@% % \pgfluamath@install@function\pgfmath@pi=\pgfluamathpi@% % \pgfluamath@install@function\pgfmathpi=\pgfluamathpi@% % \pgfluamath@install@function\pgfmathe@=\pgfluamathe@% % \pgfluamath@install@function\pgfmathe=\pgfluamathe@% % \pgfluamath@install@function\pgfmathlessthan@=\pgfluamathlessthan@% % \pgfluamath@install@function\pgfmathless@=\pgfluamathlessthan@% % \pgfluamath@install@function\pgfmathgreaterthan@=\pgfluamathgreaterthan@% % \pgfluamath@install@function\pgfmathgreater@=\pgfluamathgreaterthan@% % \pgfluamath@install@function\pgfmathpow@=\pgfluamathpow@ \pgfluamath@install@function\pgfmathrand@=\pgfluamathrand@ \pgfluamath@install@function\pgfmathrand=\pgfluamathrand@ \pgfluamath@install@function\pgfmathrnd@=\pgfluamathrnd@ \pgfluamath@install@function\pgfmathrnd=\pgfluamathrnd@ % \pgfluamath@install@function\pgfmathtrue@=\pgfluamathtrue@ % \pgfluamath@install@function\pgfmathfalse@=\pgfluamathfalse@ % \pgfluamath@install@function\pgfmathnot@=\pgfluamathnot@ % \pgfluamath@install@function\pgfmathhex@=\pgfluamathhex@ % \pgfluamath@install@function\pgfmathHex@=\pgfluamathHex@ % \pgfluamath@install@function\pgfmathoct@=\pgfluamathoct@ % \pgfluamath@install@function\pgfmathbin@=\pgfluamathbin@ % \pgfluamath@install@function\pgfmathand@=\pgfluamathand@ % \pgfluamath@install@function\pgfmathor@=\pgfluamathor@ % \pgfluamath@install@function\pgfmathfactorial@=\pgfluamathfactorial@ % \pgfluamath@install@function\pgfmathveclen@=\pgfluamathveclen@ % \pgfluamath@install@function\pgfmathcosh@=\pgfluamathcosh@ % \pgfluamath@install@function\pgfmathsinh@=\pgfluamathsinh@ % \pgfluamath@install@function\pgfmathtanh@=\pgfluamathtanh@ % \pgfluamath@install@function@unimplemented{ceil}% % \pgfluamath@install@function@unimplemented{frac}% % \pgfluamath@install@function@unimplemented{log2}% % \pgfluamath@install@function@unimplemented{log10}% % \pgfluamath@install@function@unimplemented{equalto}% % \pgfluamath@install@function@unimplemented{random}% % \pgfluamath@install@function@unimplemented{setseed}% % \pgfluamath@install@function@unimplemented{Mod}% % \pgfluamath@install@function@unimplemented{real}% % \pgfluamath@install@function@unimplemented{notequal}% \pgfluamath@install@function\pgfmathreciprocal=\pgfluamathreciprocal% \pgfluamath@install@function\pgfpointnormalised=\pgfluamathpointnormalised }% \def\pgfluamathgetresult#1{% \edef\pgfmathresult{\pgfutil@directlua{tex.print(-1,#1)}}}% \def\pgfmathluamath@iftrue{% \if 0\pgfluamath@outputformat@choice \let\pgfmathluamath@@iftrue@v=\pgfluamathone \else \let\pgfmathluamath@@iftrue@v=\pgfluamathfloatone \fi \pgfmathluamath@iftrue@ }% \def\pgfluamathone{1.0}% \def\pgfluamathfloatone{1Y1.0e+00]}% \def\pgfmathluamath@iftrue@#1#2{% \ifx\pgfmathresult\pgfmathluamath@@iftrue@v \def\pgfmath@next{#1}% \else \def\pgfmath@next{#2}% \fi \pgfmath@next }% \def\pgfluamathpi@{% \pgfluamathgetresult{pgfluamathfunctions.pi()}}% \def\pgfluamathe@{% \pgfluamathgetresult{pgfluamathfunctions.e()}}% \def\pgfluamathadd@#1#2{% \pgfluamathgetresult{pgfluamathfunctions.add(#1,#2)}}% \def\pgfluamathsubtract@#1#2{% \pgfluamathgetresult{pgfluamathfunctions.subtract(#1,#2)}}% \def\pgfluamathneg@#1{% \pgfluamathgetresult{pgfluamathfunctions.neg(#1)}}% \def\pgfluamathmultiply@#1#2{% \pgfluamathgetresult{pgfluamathfunctions.multiply(#1,#2)}}% \def\pgfluamathdivide@#1#2{% \pgfluamathgetresult{pgfluamathfunctions.divide(#1,#2)}}% \def\pgfluamathabs@#1{% \pgfluamathgetresult{pgfluamathfunctions.abs(#1)}}% \def\pgfluamathround@#1{% \pgfluamathgetresult{pgfluamathfunctions.round(#1)}}% \def\pgfluamathfloor@#1{% \pgfluamathgetresult{pgfluamathfunctions.floor(#1)}}% \def\pgfluamathceil@#1{% \pgfluamathgetresult{pgfluamathfunctions.ceil(#1)}}% \def\pgfluamathgcd@#1#2{% \pgfluamathgetresult{pgfluamathfunctions.gcd(#1,#2)}}% \def\pgfluamathisprime@#1{% \pgfluamathgetresult{pgfluamathfunctions.isprime(#1)}}% \def\pgfluamathmax@#1{% \pgfluamathgetresult{% math.max(pgfluamathfunctions.split_braces_to_explist("#1"))}}% \def\pgfluamathmin@#1{% \pgfluamathgetresult{% math.min(pgfluamathfunctions.split_braces_to_explist("#1"))}}% \def\pgfluamathsin@#1{% \pgfluamathgetresult{pgfluamathfunctions.Sin(#1)}}% \def\pgfluamathcos@#1{% \pgfluamathgetresult{pgfluamathfunctions.Cos(#1)}}% \def\pgfluamathtan@#1{% \pgfluamathgetresult{pgfluamathfunctions.Tan(#1)}}% \def\pgfluamathmod@#1#2{% \pgfluamathgetresult{pgfluamathfunctions.mod(#1,#2)}}% \def\pgfluamathMod@#1#2{% \pgfluamathgetresult{pgfluamathfunctions.Mod(#1,#2)}}% \def\pgfluamathrad@#1{% \pgfluamathgetresult{pgfluamathfunctions.rad(#1)}}% \def\pgfluamathdeg@#1{% \pgfluamathgetresult{pgfluamathfunctions.deg(#1)}}% \def\pgfluamathatan@#1{% \pgfluamathgetresult{pgfluamathfunctions.aTan(#1)}}% \def\pgfluamathatantwo@#1#2{% \pgfluamathgetresult{pgfluamathfunctions.aTan2(#1,#2)}}% \def\pgfluamathasin@#1{% \pgfluamathgetresult{pgfluamathfunctions.aSin(#1)}}% \def\pgfluamathacos@#1{% \pgfluamathgetresult{pgfluamathfunctions.aCos(#1)}}% \def\pgfluamathcot@#1{% \pgfluamathgetresult{1/pgfluamathfunctions.Tan(#1)}}% \def\pgfluamathsec@#1{% \pgfluamathgetresult{1/pgfluamathfunctions.Cos(#1)}}% \def\pgfluamathcosec@#1{% \pgfluamathgetresult{1/pgfluamathfunctions.Sin(#1)}}% \def\pgfluamathexp@#1{% \pgfluamathgetresult{pgfluamathfunctions.exp(#1)}}% \def\pgfluamathln@#1{% \pgfluamathgetresult{pgfluamathfunctions.log(#1)}}% \def\pgfluamathlogten@#1{% \pgfluamathgetresult{pgfluamathfunctions.log10(#1)}}% \def\pgfluamathsqrt@#1{% \pgfluamathgetresult{pgfluamathfunctions.sqrt(#1)}}% \def\pgfluamathrnd@{% \pgfluamathgetresult{pgfluamathfunctions.rnd()}}% \def\pgfluamathrand@{% \pgfluamathgetresult{pgfluamathfunctions.rand(-1,1)}}% \def\pgfluamathfactorial@#1{% \pgfluamathgetresult{pgfluamathfunctions.factorial(#1)}}% \def\pgfluamathreciprocal#1{% \pgfluamathgetresult{1/#1}}% % \pgfluamath@install@function\pgfmath@pi=\pgfluamathpi@% % \pgfluamath@install@function\pgfmathpi=\pgfluamathpi@% % \pgfluamath@install@function\pgfmathe@=\pgfluamathe@% % \pgfluamath@install@function\pgfmathe=\pgfluamathe@% % \pgfluamath@install@function\pgfmathlessthan@=\pgfluamathlessthan@% % \pgfluamath@install@function\pgfmathless@=\pgfluamathlessthan@% % \pgfluamath@install@function\pgfmathgreaterthan@=\pgfluamathgreaterthan@% % \pgfluamath@install@function\pgfmathgreater@=\pgfluamathgreaterthan@% % \pgfluamath@install@function\pgfmathpow@=\pgfluamathpow@ % \pgfluamath@install@function\pgfmathrand@=\pgfluamathrand@ % \pgfluamath@install@function\pgfmathrand=\pgfluamathrand@ % \pgfluamath@install@function\pgfmathrnd@=\pgfluamathrnd@ % \pgfluamath@install@function\pgfmathrnd=\pgfluamathrnd@ % \pgfluamath@install@function\pgfmathtrue@=\pgfluamathtrue@ % \pgfluamath@install@function\pgfmathfalse@=\pgfluamathfalse@ % \pgfluamath@install@function\pgfmathnot@=\pgfluamathnot@ % \pgfluamath@install@function\pgfmathhex@=\pgfluamathhex@ % \pgfluamath@install@function\pgfmathHex@=\pgfluamathHex@ % \pgfluamath@install@function\pgfmathoct@=\pgfluamathoct@ % \pgfluamath@install@function\pgfmathbin@=\pgfluamathbin@ % \pgfluamath@install@function\pgfmathand@=\pgfluamathand@ % \pgfluamath@install@function\pgfmathor@=\pgfluamathor@ % \pgfluamath@install@function\pgfmathfactorial@=\pgfluamathfactorial@ % \pgfluamath@install@function\pgfmathveclen@=\pgfluamathveclen@ % \pgfluamath@install@function\pgfmathcosh@=\pgfluamathcosh@ % \pgfluamath@install@function\pgfmathsinh@=\pgfluamathsinh@ % \pgfluamath@install@function\pgfmathtanh@=\pgfluamathtanh@ \def\pgfluamathpointnormalised#1{% \pgf@process{#1}% \pgfutil@directlua{% pgfluamathfunctions.pointnormalised(% \pgf@sys@tonumber{\pgf@x},\pgf@sys@tonumber{\pgf@y})}% \ignorespaces}% % Parser \newif\ifpgfluamathunitsdeclared % true if and only if LUA failed to evaluate the expression and the % expression was evaluated by means of the TeX parser as fallback. % % This happens % - for \chardef'ed boxes for which LUA lacks evaluation capabilities % - if the expression includes some function which is unavailable in % LUA (defined only in TeX) % - some special cases which simply haven't been added to the LUA % parser (yet). % At the time of this writing, this includes % -- arrays created via '{}' and indexed with '[]' % -- strings with "" % -- 'scalar' function % -- hex/octal/binary input \newif\ifpgfluamathusedTeXfallback % Parses the math expression and defines \pgfmathresult and % \ifpgfmathunitsdeclared to contain the result. % % If \ifpgfluamathparseractive then the result is also assigned to % \pgfmathresult. Furthermore, if the expression cannot be evaluated (because LUA does not support % it), it will be evaluated by mean of TeX as fallback. % % @see \ifpgfluamathusedTeXfallback % @see \ifpgfluamathshowerrormessage \def\pgfluamathparse#1{% \pgfluamathusedTeXfallbackfalse \pgfutil@directlua{pgfluamathparser.texCallParser( "\pgfutil@luaescapestring{#1}", \pgfluamath@outputformat@choice, \ifpgfluamathshowerrormessage true\else false\fi)% }% \ifx\pgfmathresult\pgfutil@empty \ifpgfluamathenableTeXfallback \pgfluamathusedTeXfallbacktrue \pgfluamath@pgfmathparse{#1}% \fi \fi }% \catcode`\"=\pgfliblua@oldcatcodedoublequote \endinput