diff options
author | Karl Berry <karl@freefriends.org> | 2015-08-08 22:54:29 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2015-08-08 22:54:29 +0000 |
commit | 531d43fafa269c546d587eaca6cd14adcd11914f (patch) | |
tree | 1883933af984c60254e6d9d1bd955a76748cb827 /Master/texmf-dist/tex/generic/pgf/libraries | |
parent | 877e963d44f039783cb9227d90c911866c780961 (diff) |
pgf (8aug15)
git-svn-id: svn://tug.org/texlive/trunk@38079 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/generic/pgf/libraries')
13 files changed, 2165 insertions, 1434 deletions
diff --git a/Master/texmf-dist/tex/generic/pgf/libraries/luamath/pgf/luamath/functions.lua b/Master/texmf-dist/tex/generic/pgf/libraries/luamath/pgf/luamath/functions.lua new file mode 100644 index 00000000000..8fc963d8b9e --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/libraries/luamath/pgf/luamath/functions.lua @@ -0,0 +1,626 @@ +-- Copyright 2011 by Christophe Jorssen +-- +-- 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: functions.lua,v 1.3 2015/05/10 20:34:13 cfeuersaenger Exp $ +-- + +local pgfluamathfunctions = pgfluamathfunctions or {} + +-- Maps function names to their function. +-- +-- Note that this allows to register functions which are not in pgfluamathfunctions. +-- +-- Note that the string keys are not necessarily the same as the function +-- names. In particular, the math expression "not(1,1)" will execute notPGF(1,1) +-- +-- Note that each function which is added to pgfluamathfunctions will _automatically_ be inserted into this map, see __newindex. +-- (I fear it will not be erased directly...) +pgfluamathfunctions.stringToFunctionMap = {} + +local newFunctionAllocatedCallback = function(table,key,value) + local keyName = tostring(key):gsub("PGF","") + if not value then + stringToFunctionMap[keyName] = nil + elseif type(value) == 'function' then + -- remember it, and strip PGF suffix (i.e. remember 'not' instead of 'notPGF') + pgfluamathfunctions.stringToFunctionMap[keyName] = value + end + rawset(table,key,value) +end + +setmetatable(pgfluamathfunctions, { __newindex = newFunctionAllocatedCallback }) + +local mathabs, mathacos, mathasin = math.abs, math.acos, math.asin +local mathatan, mathceil = math.atan, math.ceil +local mathcos, mathdeg = math.cos, math.deg +local mathexp, mathfloor, mathfmod = math.exp, math.floor, math.fmod +local mathlog, mathmax = math.log, math.max +local mathmin, mathpi = math.min, math.pi +local mathrad, mathrandom = math.rad, math.random +local mathrandomseed, mathsin = math.randomseed, math.sin +local mathsqrt = math.sqrt +local mathtan = math.tan + +local trigFormatToRadians = mathrad + +local radiansToTrigFormat = mathdeg + +pgfluamathfunctions.TrigFormat = { 'deg', 'rad' } +pgfluamathfunctions.stringToFunctionMap["TrigFormat"] = nil + +-- choice is one of the valid choices in TrigFormat. +function pgfluamathfunctions.setTrigFormat(choice) + if choice == 'deg' then + trigFormatToRadians = mathrad + radiansToTrigFormat = mathdeg + elseif choice == 'rad' then + local identity = function(x) return x end + trigFormatToRadians = identity + radiansToTrigFormat = identity + else + error("The argument '" .. tostring(choice) .. "' is no valid choice for setTrigFormat.") + end +end +pgfluamathfunctions.stringToFunctionMap["setTrigFormat"] = nil + +pgfluamathfunctions.setRandomSeed = mathrandomseed +pgfluamathfunctions.stringToFunctionMap["setRandomSeed"] = nil + +------------------------------------------- + +function pgfluamathfunctions.add(x,y) + return x+y +end + +function pgfluamathfunctions.subtract(x,y) + return x-y +end + +function pgfluamathfunctions.neg(x) + return -x +end + +function pgfluamathfunctions.multiply(x,y) + return x*y +end + +function pgfluamathfunctions.veclen(x,y) + return mathsqrt(x*x+y*y) +end + +function pgfluamathfunctions.divide(x,y) + return x/y +end + +function pgfluamathfunctions.div(x,y) + return mathfloor(x/y) +end + +function pgfluamathfunctions.pow(x,y) + -- do not use math.pow -- it is deprecated as of LUA 5.3 + return x^y +end + +function pgfluamathfunctions.factorial(x) +-- TODO: x must be an integer + if x == 0 then + return 1 + else + return x * pgfluamathfunctions.factorial(x-1) + end +end + +function pgfluamathfunctions.ifthenelse(x,y,z) + if x~= 0 then + return y + else + return z + end +end + +function pgfluamathfunctions.equal(x,y) + if x == y then + return 1 + else + return 0 + end +end + +function pgfluamathfunctions.greater(x,y) + if x > y then + return 1 + else + return 0 + end +end + +function pgfluamathfunctions.less(x,y) + if x < y then + return 1 + else + return 0 + end +end + +function pgfluamathfunctions.min(x,y) + return mathmin(x,y) +end + +function pgfluamathfunctions.max(x,y) + return mathmax(x,y) +end + +function pgfluamathfunctions.notequal(x,y) + if x ~= y then + return 1 + else + return 0 + end +end + +function pgfluamathfunctions.notless(x,y) + if x >= y then + return 1 + else + return 0 + end +end + +function pgfluamathfunctions.notgreater(x,y) + if x <= y then + return 1 + else + return 0 + end +end + +function pgfluamathfunctions.andPGF(x,y) + if (x ~= 0) and (y ~= 0) then + return 1 + else + return 0 + end +end + +function pgfluamathfunctions.orPGF(x,y) + if (x ~= 0) or (y ~= 0) then + return 1 + else + return 0 + end +end + +function pgfluamathfunctions.notPGF(x) + if x == 0 then + return 1 + else + return 0 + end +end + +function pgfluamathfunctions.pi() + return mathpi +end + +function pgfluamathfunctions.e() + return mathexp(1) +end + +function pgfluamathfunctions.abs(x) + return mathabs(x) +end + +function pgfluamathfunctions.floor(x) + return mathfloor(x) +end + +function pgfluamathfunctions.ceil(x) + return mathceil(x) +end + +function pgfluamathfunctions.exp(x) + return mathexp(x) +end + +function pgfluamathfunctions.ln(x) + return mathlog(x) +end + +local logOf10 = mathlog(10) +function pgfluamathfunctions.log10(x) + return mathlog(x) / logOf10 +end + +local logOf2 = mathlog(2) +function pgfluamathfunctions.log2(x) + return mathlog(x) / logOf2 +end + +function pgfluamathfunctions.sqrt(x) + return mathsqrt(x) +end + +function pgfluamathfunctions.sign(x) + if x < 0 then + return -1.0 + elseif x == 0 then + return 0.0 + else + return 1.0 + end +end +function pgfluamathfunctions.real(x) + -- "ensure that x contains a decimal point" is kind of a no-op here, isn't it!? + return x +end + +function pgfluamathfunctions.rnd() + return mathrandom() +end + +function pgfluamathfunctions.rand() + return -1 + mathrandom() *2 +end + +function pgfluamathfunctions.random(x,y) + if x == nil and y == nil then + return mathrandom() + elseif y == nil then + return mathrandom(x) + else + return mathrandom(x,y) + end +end + +function pgfluamathfunctions.deg(x) + return mathdeg(x) +end + +function pgfluamathfunctions.rad(x) + return mathrad(x) +end + +function pgfluamathfunctions.round(x) + if x<0 then + return -mathfloor(mathabs(x)+0.5) + else + return mathfloor(x + 0.5) + end +end + +function pgfluamathfunctions.gcd(a, b) + if b == 0 then + return a + else + return pgfluamathfunctions.gcd(b, a%b) + end +end + +function pgfluamathfunctions.isprime(a) + local ifisprime = true + if a == 1 then + ifisprime = false + elseif a == 2 then + ifisprime = true +-- if a > 2 then + else + local i, imax = 2, mathceil(mathsqrt(a)) + 1 + while ifisprime and (i < imax) do + if pgfluamathfunctions.gcd(a,i) ~= 1 then + ifisprime = false + end + i = i + 1 + end + end + if ifisprime then + return 1 + else + return 0 + end +end + + +function pgfluamathfunctions.split_braces_to_explist(s) + -- (Thanks to mpg and zappathustra from fctt) + -- Make unpack available whatever lua version is used + -- (unpack in lua 5.1 table.unpack in lua 5.2) + local unpack = table.unpack or unpack + local t = {} + for i in s:gmatch('%b{}') do + table.insert(t, tonumber(i:sub(2, -2))) + end + return unpack(t) +end + +function pgfluamathfunctions.split_braces_to_table(s) + local t = {} + for i in s:gmatch('%b{}') do + table.insert(t, tonumber(i:sub(2, -2))) + end + return t +end + +function pgfluamathfunctions.mathtrue() + return 1.0 +end +pgfluamathfunctions.stringToFunctionMap["true"] = pgfluamathfunctions.mathtrue + +function pgfluamathfunctions.mathfalse() + return 0.0 +end +pgfluamathfunctions.stringToFunctionMap["false"] = pgfluamathfunctions.mathfalse + +function pgfluamathfunctions.frac(a) + -- should be positive, apparently + return mathabs(a - pgfluamathfunctions.int(a)) +end + +function pgfluamathfunctions.int(a) + if a < 0 then + return -mathfloor(mathabs(a)) + else + return mathfloor(a) + end +end + +function pgfluamathfunctions.iseven(a) + if (a % 2) == 0 then + return 1.0 + else + return 0.0 + end +end + +function pgfluamathfunctions.isodd(a) + if (a % 2) == 0 then + return 0.0 + else + return 1.0 + end +end + +function pgfluamathfunctions.mod(x,y) + if x/y < 0 then + return -(mathabs(x)%mathabs(y)) + else + return mathabs(x)%mathabs(y) + end +end + +function pgfluamathfunctions.Mod(x,y) + local tmp = pgfluamathfunctions.mod(x,y) + if tmp < 0 then + tmp = tmp + y + end + return tmp +end + +function pgfluamathfunctions.Sin(x) + return mathsin(trigFormatToRadians(x)) +end +pgfluamathfunctions.sin=pgfluamathfunctions.Sin + + +function pgfluamathfunctions.cosh(x) + -- math.cosh is deprecated as of LUA 5.3 . reimplement it: + return 0.5* (mathexp(x) + mathexp(-x)) +end +function pgfluamathfunctions.sinh(x) + -- math.sinh is deprecated as of LUA 5.3 . reimplement it: + return 0.5* (mathexp(x) - mathexp(-x)) +end + +local sinh = pgfluamathfunctions.sinh +local cosh = pgfluamathfunctions.cosh +function pgfluamathfunctions.tanh(x) + -- math.tanh is deprecated as of LUA 5.3 . reimplement it: + return sinh(x)/cosh(x) +end + +function pgfluamathfunctions.Cos(x) + return mathcos(trigFormatToRadians(x)) +end +pgfluamathfunctions.cos=pgfluamathfunctions.Cos + +function pgfluamathfunctions.Tan(x) + return mathtan(trigFormatToRadians(x)) +end +pgfluamathfunctions.tan=pgfluamathfunctions.Tan + +function pgfluamathfunctions.aSin(x) + return radiansToTrigFormat(mathasin(x)) +end +pgfluamathfunctions.asin=pgfluamathfunctions.aSin + +function pgfluamathfunctions.aCos(x) + return radiansToTrigFormat(mathacos(x)) +end +pgfluamathfunctions.acos=pgfluamathfunctions.aCos + +function pgfluamathfunctions.aTan(x) + return radiansToTrigFormat(mathatan(x)) +end +pgfluamathfunctions.atan=pgfluamathfunctions.aTan + +local mathatan2 +if math.atan2 == nil then + -- math.atan2 has been deprecated since LUA 5.3 + mathatan2 = function (y,x) return mathatan(y,x) end +else + mathatan2 = math.atan2 +end + +function pgfluamathfunctions.aTan2(y,x) + return radiansToTrigFormat(mathatan2(y,x)) +end +pgfluamathfunctions.atan2=pgfluamathfunctions.aTan2 +pgfluamathfunctions.atantwo=pgfluamathfunctions.aTan2 + +function pgfluamathfunctions.cot(x) + return pgfluamathfunctions.cos(x) / pgfluamathfunctions.sin(x) +end +function pgfluamathfunctions.sec(x) + return 1 / pgfluamathfunctions.cos(x) +end +function pgfluamathfunctions.cosec(x) + return 1 / pgfluamathfunctions.sin(x) +end + +function pgfluamathfunctions.pointnormalised (pgfx, pgfy) + local pgfx_normalised, pgfy_normalised + if pgfx == 0. and pgfy == 0. then + -- Orginal pgf macro gives this result + tex.dimen['pgf@x'] = "0pt" + tex.dimen['pgf@y'] = "1pt" + else + pgfx_normalised = pgfx/math.sqrt(pgfx^2 + pgfy^2) + pgfx_normalised = pgfx_normalised - pgfx_normalised%0.00001 + pgfy_normalised = pgfy/math.sqrt(pgfx^2 + pgfy^2) + pgfy_normalised = pgfy_normalised - pgfy_normalised%0.00001 + tex.dimen['pgf@x'] = tostring(pgfx_normalised) .. "pt" + tex.dimen['pgf@y'] = tostring(pgfy_normalised) .. "pt" + end + return nil +end + +local isnan = function(x) + return x ~= x +end + +pgfluamathfunctions.isnan = isnan + +local infty = 1/0 +pgfluamathfunctions.infty = infty + +local nan = math.sqrt(-1) +pgfluamathfunctions.nan = nan + +local stringlen = string.len +local globaltonumber = tonumber +local stringsub=string.sub +local stringformat = string.format +local stringsub = string.sub + +-- like tonumber(x), but it also accepts nan, inf, infty, and the TeX FPU format +function pgfluamathfunctions.tonumber(x) + if type(x) == 'number' then return x end + if not x then return x end + + local len = stringlen(x) + local result = globaltonumber(x) + if not result then + if len >2 and stringsub(x,2,2) == 'Y' and stringsub(x,len,len) == ']' then + -- Ah - some TeX FPU input of the form 1Y1.0e3] . OK. transform it + local flag = stringsub(x,1,1) + if flag == '0' then + -- ah, 0.0 + result = 0.0 + elseif flag == '1' then + result = globaltonumber(stringsub(x,3, len-1)) + elseif flag == '2' then + result = globaltonumber("-" .. stringsub(x,3, len-1)) + elseif flag == '3' then + result = nan + elseif flag == '4' then + result = infty + elseif flag == '5' then + result = -infty + end + else + local lower = x:lower() + if lower == 'nan' then + result = nan + elseif lower == "-nan" then + result = nan + elseif lower == 'inf' or lower == 'infty' then + result = infty + elseif lower == '-inf' or lower == '-infty' then + result = -infty + end + end + end + + return result +end + +local stringlen = string.len +local globaltonumber = tonumber +local stringformat = string.format +local stringsub = string.sub +local stringfind = string.find +local stringbyte = string.byte +local NULL_CHAR = string.byte("0",1) + +local function discardTrailingZeros(x) + local result = x + -- printf is too stupid: I would like to have + -- 1. a fast method + -- 2. a reliable method + -- 3. full precision of x + -- 4. a fixed point representation + -- the 'f' modifier has trailing zeros (stupid!) + -- the 'g' modified can switch to scientific notation (no-go!) + local periodOff = stringfind(result, '.',1,true) + if periodOff ~= nil then + -- strip trailing zeros + local chars = { stringbyte(result,1,#result) }; + local lastNonZero = #chars + for i = #chars, periodOff, -1 do + if chars[i] ~= NULL_CHAR then lastNonZero=i; break; end + end + if lastNonZero ~= #chars then + -- Ah: we had at least one trailing zero. + -- discard all but the last. + lastNonZero = mathmax(periodOff+1,lastNonZero) + end + result = stringsub(result, 1, lastNonZero) + end + return result; +end + +local function discardTrailingZerosFromMantissa(x) + local mantissaStart = stringfind(x, "e") + + local mantissa = stringsub(x,1,mantissaStart-1) + local exponent = stringsub(x,mantissaStart) + + return discardTrailingZeros(mantissa) .. exponent +end + + +-- a helper function which has no catcode issues when communicating with TeX: +function pgfluamathfunctions.tostringfixed(x) + if x == nil then + return "" + end + + return discardTrailingZeros(stringformat("%f", x)) +end + +-- converts an input number to a string which is accepted by the TeX FPU +function pgfluamathfunctions.toTeXstring(x) + local result = "" + if x ~= nil then + if x == infty then result = "4Y0.0e0]" + elseif x == -infty then result = "5Y0.0e0]" + elseif isnan(x) then result = "3Y0.0e0]" + elseif x == 0 then result = "0Y0.0e0]" + else + result = discardTrailingZerosFromMantissa(stringformat("%.10e", x)) + if x > 0 then + result = "1Y" .. result .. "]" + else + result = "2Y" .. stringsub(result,2) .. "]" + end + end + end + return result +end + +return pgfluamathfunctions diff --git a/Master/texmf-dist/tex/generic/pgf/libraries/luamath/pgf/luamath/parser.lua b/Master/texmf-dist/tex/generic/pgf/libraries/luamath/pgf/luamath/parser.lua new file mode 100644 index 00000000000..55066b45aad --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/libraries/luamath/pgf/luamath/parser.lua @@ -0,0 +1,470 @@ +-- Copyright 2011 by Christophe Jorssen and Mark Wibrow +-- Copyright 2014 by Christian Feuersaenger +-- +-- 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: parser.lua,v 1.1 2014/12/27 14:11:49 cfeuersaenger Exp $ +-- +-- usage: +-- +-- pgfluamathparser = require("pgf.luamath.parser") +-- +-- local result = pgfluamathparser.pgfmathparse("1+ 2*4^2") +-- +-- This LUA class has a direct backend in \pgfuselibrary{luamath}, see the documentation of that TeX package. + +local pgfluamathparser = pgfluamathparser or {} + +pgfluamathfunctions = require("pgf.luamath.functions") + +-- lpeg is always present in luatex +local lpeg = require("lpeg") + +local S, P, R = lpeg.S, lpeg.P, lpeg.R +local C, Cc, Ct = lpeg.C, lpeg.Cc, lpeg.Ct +local Cf, Cg, Cs = lpeg.Cf, lpeg.Cg, lpeg.Cs +local V = lpeg.V +local match = lpeg.match + +local space_pattern = S(" \n\r\t")^0 +local tex_unit = + P('pt') + P('mm') + P('cm') + P('in') + + -- while valid units, the font-depending ones need special attention... move them to the TeX side. For now. + -- P('ex') + P('em') + + P('bp') + P('pc') + + P('dd') + P('cc') + P('sp'); + +local one_digit_pattern = R("09") +local positive_integer_pattern = one_digit_pattern^1 +-- FIXME : it might be a better idea to remove '-' from all number_patterns! Instead, rely on the prefix operator 'neg' to implement negative numbers. +-- Is that wise? It is certainly less efficient... +local integer_pattern = S("+-")^-1 * positive_integer_pattern +-- Valid positive decimals are |xxx.xxx|, |.xxx| and |xxx.| +local positive_integer_or_decimal_pattern = positive_integer_pattern * ( P(".") * one_digit_pattern^0)^-1 + + (P(".") * one_digit_pattern^1) +local integer_or_decimal_pattern = S("+-")^-1 * positive_integer_or_decimal_pattern +local fpu_pattern = R"15" * P"Y" * positive_integer_or_decimal_pattern * P"e" * P("-")^-1 * R("09")^1 * P"]" +local unbounded_pattern = P"inf" + P"INF" + P"nan" + P"NaN" + P"Inf" +local number_pattern = C(unbounded_pattern + fpu_pattern + integer_or_decimal_pattern * (S"eE" * integer_pattern + C(tex_unit))^-1) + +local underscore_pattern = P("_") + +local letter_pattern = R("az","AZ") +local alphanum__pattern = letter_pattern + one_digit_pattern + underscore_pattern + +local identifier_pattern = letter_pattern^1 * alphanum__pattern^0 + +local openparen_pattern = P("(") * space_pattern +local closeparen_pattern = P(")") +local opencurlybrace_pattern = P("{") +local closecurlybrace_pattern = P("}") +local openbrace_pattern = P("[") +local closebrace_pattern = P("]") + +-- hm. what about '\\' or '\%' ? +-- accept \pgf@x, \count0, \dimen42, \c@pgf@counta, \wd0, \ht0, \dp 0 +local controlsequence_pattern = P"\\" * C( (R("az","AZ") + P"@")^1) * space_pattern* C( R"09"^0 ) + +-- local string = P('"') * C((1 - P('"'))^0) * P('"') + +local comma_pattern = P(",") * space_pattern + + +---------------- +local TermOp = C(S("+-")) * space_pattern +local RelationalOp = C( P"==" + P"!=" + P"<=" + P">=" + P"<" + P">" ) * space_pattern +local FactorOp = C(S("*/")) * space_pattern + +-- Grammar +local Exp, Term, Factor = V"Exp", V"Term", V"Factor" +local Prefix = V"Prefix" +local Postfix = V"Postfix" + + + +local function eval (v1, op, v2) + if (op == "+") then return v1 + v2 + elseif (op == "-") then return v1 - v2 + elseif (op == "*") then return v1 * v2 + elseif (op == "/") then return v1 / v2 + else + error("This function must not be invoked for operator "..op) + end +end + +local pgfStringToFunctionMap = pgfluamathfunctions.stringToFunctionMap +local function function_eval(name, ... ) + local f = pgfStringToFunctionMap[name] + if not f then + error("Function '" .. name .. "' is undefined (did not find pgfluamathfunctions."..name .." (looked into pgfluamathfunctions.stringToFunctionMap))") + end + -- FIXME: validate signature + return f(...) +end + + +local func = + (C(identifier_pattern) * space_pattern * openparen_pattern * Exp * (comma_pattern * Exp)^0 * closeparen_pattern) / function_eval; + +local functionWithoutArg = identifier_pattern / function_eval + +-- this is what can occur as exponent after '^'. +-- I have the impression that the priorities could be implemented in a better way than this... but it seems to work. +local pow_exponent = + -- allows 2^-4, 2^1e4, 2^2 + -- FIXME : why not 2^1e2 ? + Cg(C(integer_or_decimal_pattern) + -- 2^pi, 2^multiply(2,2) + + Cg(func+functionWithoutArg) + -- 2^(2+2) + + openparen_pattern * Exp * closeparen_pattern ) + +local function prefix_eval(op, x) + if op == "-" then + return pgfluamathfunctions.neg(x) + elseif op == "!" then + return pgfluamathfunctions.notPGF(x) + else + error("This function must not be invoked for operator "..op) + end +end + + +local prefix_operator = C( S"-!" ) +local prefix_operator_pattern = (prefix_operator * space_pattern * Cg(Prefix) ) / prefix_eval + +-- apparently, we need to distinghuish between <expr> ! and <expr> != <expr2>: +local postfix_operator = C( S"r!" - P"!=" ) + C(P"^") * space_pattern * pow_exponent + + +local ternary_eval = pgfluamathfunctions.ifthenelse + +local factorial_eval = pgfluamathfunctions.factorial +local deg = pgfluamathfunctions.deg +local pow_eval = pgfluamathfunctions.pow + +-- @param prefix the argument before the postfix operator. +-- @param op either nil or the postfix operator +-- @param arg either nil or the (mandatory) argument for 'op' +local function postfix_eval(prefix, op, arg) + local result + if op == nil then + result = prefix + elseif op == "r" then + if arg then error("parser setup error: expected nil argument") end + result = deg(prefix) + elseif op == "!" then + if arg then error("parser setup error: expected nil argument") end + result = factorial_eval(prefix) + elseif op == "^" then + if not arg then error("parser setup error: ^ with its argument") end + result = pow_eval(prefix, arg) + else + error("Parser setup error: " .. tostring(op) .. " unexpected in this context") + end + return result +end + +local function relational_eval(v1, op, v2) + local fct + if (op == "==") then fct = pgfluamathfunctions.equal + elseif (op == "!=") then fct = pgfluamathfunctions.notequal + elseif (op == "<") then fct = pgfluamathfunctions.less + elseif (op == ">") then fct = pgfluamathfunctions.greater + elseif (op == ">=") then fct = pgfluamathfunctions.notless + elseif (op == "<=") then fct = pgfluamathfunctions.notgreater + else + error("This function must not be invoked for operator "..op) + end + return fct(v1,v2) +end + +-- @return either the box property or nil +-- @param cs "wd", "ht", or "dp" +-- @param intSuffix some integer +local function get_tex_box(cs, intSuffix) + -- assume get_tex_box is only called when a dimension is required. + local result + pgfluamathparser.units_declared = true + local box =tex.box[tonumber(intSuffix)] + if not box then error("There is no box " .. intSuffix) end + if cs == "wd" then + result = box.width / 65536 + elseif cs == "ht" then + result = box.height / 65536 + elseif cs == "dp" then + result = box.depth / 65536 + else + result = nil + end + return result +end + + +local function controlsequence_eval(cs, intSuffix) + local result + if intSuffix and #intSuffix >0 then + if cs == "count" then + result= pgfluamathparser.get_tex_count(intSuffix) + elseif cs == "dimen" then + result= pgfluamathparser.get_tex_dimen(intSuffix) + else + result = get_tex_box(cs,intSuffix) + if not result then + -- this can happen - we cannot expand \chardef'ed boxes here. + -- this will be done by the TeX part + error('I do not know/support the TeX register "\\' .. cs .. '"') + end + end + else + result = pgfluamathparser.get_tex_register(cs) + end + return result +end + +pgfluamathparser.units_declared = false +function pgfluamathparser.get_tex_register(register) + -- register is a string which could be a count or a dimen. + if pcall(tex.getcount, register) then + return tex.count[register] + elseif pcall(tex.getdimen, register) then + pgfluamathparser.units_declared = true + return tex.dimen[register] / 65536 -- return in points. + else + error('I do not know the TeX register "' .. register .. '"') + return nil + end + +end + +function pgfluamathparser.get_tex_count(count) + -- count is expected to be a number + return tex.count[tonumber(count)] +end + +function pgfluamathparser.get_tex_dimen(dimen) + -- dimen is expected to be a number + pgfluamathparser.units_declared = true + return tex.dimen[tonumber(dimen)] / 65536 +end + +function pgfluamathparser.get_tex_sp(dimension) + -- dimension should be a string + pgfluamathparser.units_declared = true + return tex.sp(dimension) / 65536 +end + + +local initialRule = V"initial" + +local Summand = V"Summand" +local Relational = V"Relational" +local LogicalOr = V"LogicalOr" +local LogicalAnd = V"LogicalAnd" + +local pgftonumber = pgfluamathfunctions.tonumber +local tonumber_withunit = pgfluamathparser.get_tex_sp +local function number_optional_units_eval(x, unit) + if not unit then + return pgftonumber(x) + else + return tonumber_withunit(x) + end +end + +-- @param scale the number. +-- @param controlsequence either nil in which case just the number must be returned or a control sequence +-- @see controlsequence_eval +local function scaled_controlsequence_eval(scale, controlsequence, intSuffix) + if controlsequence==nil then + return scale + else + return scale * controlsequence_eval(controlsequence, intSuffix) + end +end + +-- Grammar +-- +-- for me: +-- - use '/' to evaluate all expressions which contain a _constant_ number of captures. +-- - use Cf to evaluate expressions which contain a _dynamic_ number of captures +-- +-- see unittest_luamathparser.tex for tons of examples +local G = P{ "initialRule", + initialRule = space_pattern* Exp * -1; + -- ternary operator (or chained ternary operators): + -- FIXME : is this chaining a good idea!? + Exp = Cf( Relational * Cg(P"?" * space_pattern * Relational * P":" *space_pattern * Relational )^0, ternary_eval) ; + -- FIXME : do we really allow something like " 1 == 1 != 2" ? I would prefer (1==1) != 2 !? + Relational = Cf(LogicalOr * Cg(RelationalOp * LogicalOr)^0, relational_eval); + LogicalOr = Cf(LogicalAnd * (P"||" * space_pattern * LogicalAnd)^0, pgfluamathfunctions.orPGF); + LogicalAnd = Cf(Summand * (P"&&" * space_pattern * Summand)^0, pgfluamathfunctions.andPGF); + Summand = Cf(Term * Cg(TermOp * Term)^0, eval) ; + Term = Cf(Prefix * Cg(FactorOp * Prefix)^0, eval); + Prefix = prefix_operator_pattern + Postfix; + -- this calls 'postfix_eval' with nil arguments if it is no postfix operation.. but that does not hurt (right?) + Postfix = Factor * (postfix_operator * space_pattern)^-1 / postfix_eval; + Factor = + ( + number_pattern / number_optional_units_eval * + -- this construction will evaluate number_pattern with 'number_optional_units_eval' FIRST. + -- also accept '0.5 \pgf@x' here: + space_pattern *controlsequence_pattern^-1 / scaled_controlsequence_eval + + func + + functionWithoutArg + + openparen_pattern * Exp * closeparen_pattern + + controlsequence_pattern / controlsequence_eval + ) *space_pattern + ; +} + +-- does not reset units_declared. +local function pgfmathparseinternal(str) + local result = match(G,str) + if result == nil then + error("The string '" .. str .. "' is no valid PGF math expression. Please check for syntax errors.") + end + return result +end + + +-- This is the math parser function in this module. +-- +-- @param str a string like "1+1" which is accepted by the PGF math language +-- @return the result of the expression. +-- +-- Throws an error if the string is no valid expression. +function pgfluamathparser.pgfmathparse(str) + pgfluamathparser.units_declared = false + + return pgfmathparseinternal(str) +end + +local pgfmathparse = pgfluamathparser.pgfmathparse +local tostringfixed = pgfluamathfunctions.tostringfixed +local tostringfpu = pgfluamathfunctions.toTeXstring + +local tmpFunctionArgumentPrefix = "tmpVar" +local stackOfLocalFunctions = {} + +-- This is a backend for PGF's 'declare function'. +-- \tikzset{declare function={mu(\x,\i)=\x^\i;}} +-- will boil down to +-- pgfluamathparser.declareExpressionFunction("mu", 2, "#1^#2") +-- +-- The local function will be pushed on a stack of known local functions and is +-- available until popLocalExpressionFunction() is called. TeX will call this using +-- \aftergroup. +-- +-- @param name the name of the new function +-- @param numArgs the number of arguments +-- @param expression an expression containing #1, ... #n where n is numArgs +-- +-- ATTENTION: local functions behave DIFFERENTLY in LUA! +-- In LUA, local variables are not expanded whereas TeX expands them. +-- The difference is +-- +-- declare function={mu1(\x,\i)=\x^\i;} +-- \pgfmathparse{mu1(-5,2)} --> -25 +-- \pgfluamathparse{mu1(-5,2)} --> 25 +-- +-- x = -5 +-- \pgfmathparse{mu1(x,2)} --> 25 +-- \pgfluamathparse{mu1(x,2)} --> 25 +-- +-- In an early prototype, I simulated TeX's expansion to fix the first case (successfully). +-- BUT: that "simulated expansion" broke the second case because LUA will evaluate "x" and hand -5 to the local function. +-- I decided to keep it as is. Perhaps we should fix PGF's expansion approach in TeX (which is ugly anyway) +function pgfluamathparser.pushLocalExpressionFunction(name, numArgs, expression) + -- now we have "tmpVar1^tmpVar2" instead of "#1^#2" + local normalizedExpr = expression:gsub("#", tmpFunctionArgumentPrefix) + local restores = {} + local tmpVars = {} + for i=1,numArgs do + local tmpVar = tmpFunctionArgumentPrefix .. tostring(i) + tmpVars[i] = tmpVar + end + + local newFunction = function(...) + local args = table.pack(...) + + -- define "tmpVar1" ... "tmpVarN" to return args[i]. + -- Of course, we need to restore "tmpVar<i>" after we return! + for i=1,numArgs do + local tmpVar = tmpVars[i] + local value = args[i] + restores[i] = pgfStringToFunctionMap[tmpVar] + pgfStringToFunctionMap[tmpVar] = function () return value end + end + + -- parse our expression. + + -- FIXME : this here is an attempt to mess around with "units_declared". + -- It would be better to call pgfmathparse and introduce some + -- semaphore to check if pgfmathparse is a nested call-- in this case, it should + -- not reset units_declared. But there is no "finally" block and pcall is crap (looses stack trace). + local success,result = pcall(pgfmathparseinternal, normalizedExpr) + + -- remove 'tmpVar1', ... from the function table: + for i=1,numArgs do + local tmpVar = tmpVars[i] + pgfStringToFunctionMap[tmpVar] = restores[i] + end + + if success==false then error(result) end + return result + end + table.insert(stackOfLocalFunctions, name) + pgfStringToFunctionMap[name] = newFunction +end + +function pgfluamathparser.popLocalExpressionFunction() + local name = stackOfLocalFunctions[#stackOfLocalFunctions] + pgfStringToFunctionMap[name] = nil + -- this removes the last element: + table.remove(stackOfLocalFunctions) +end + + +-- A Utility function which simplifies the interaction with the TeX code +-- @param expression the input expression (string) +-- @param outputFormatChoice 0 if the result should be a fixed point number, 1 if it should be in FPU format +-- @param showErrorMessage (boolean) true if any error should be displayed, false if errors should simply result in an invocation of TeX's parser (the default) +-- +-- it defines \pgfmathresult and \ifpgfmathunitsdeclared +function pgfluamathparser.texCallParser(expression, outputFormatChoice, showErrorMessage) + local success, result + if showErrorMessage then + result = pgfmathparse(expression) + success = true + else + success, result = pcall(pgfmathparse, expression) + end + + if success and result then + local result_str + if outputFormatChoice == 0 then + -- luamath/output format=fixed + result_str = tostringfixed(result) + else + -- luamath/output format=fixed + result_str = tostringfpu(result) + end + tex.sprint("\\def\\pgfmathresult{" .. result_str .. "}") + if pgfluamathparser.units_declared then + tex.sprint("\\pgfmathunitsdeclaredtrue") + else + tex.sprint("\\pgfmathunitsdeclaredfalse") + end + else + tex.sprint("\\def\\pgfmathresult{}") + tex.sprint("\\pgfmathunitsdeclaredfalse") + end +end + +return pgfluamathparser diff --git a/Master/texmf-dist/tex/generic/pgf/libraries/luamath/pgflibraryluamath.code.tex b/Master/texmf-dist/tex/generic/pgf/libraries/luamath/pgflibraryluamath.code.tex index b06695a87fa..1d7a5227dd6 100644 --- a/Master/texmf-dist/tex/generic/pgf/libraries/luamath/pgflibraryluamath.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/libraries/luamath/pgflibraryluamath.code.tex @@ -1,4 +1,5 @@ % Copyright 2011 by Christophe Jorssen and Mark Wibrow +% Copyright 2014 by Christian Feuersänger % % This file may be distributed and/or modified % @@ -7,14 +8,43 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. % -% $Id: pgflibraryluamath.code.tex,v 1.11 2012/03/06 16:06:09 cjorssen Exp $ +% $Id: pgflibraryluamath.code.tex,v 1.20 2015/06/05 06:23:21 cfeuersaenger Exp $ % -% !!! Warning: this library does not work with fpu!!! +% +% 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 <general text> will work % - \directlua is the only luatex primitive that we can assume @@ -38,11 +68,92 @@ \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}% + \directlua{pgfluamathparser.pushLocalExpressionFunction(% + "\pgfutil@luaescapestring{#1}",% + #2,% + "\pgfutil@luaescapestring{#3}")}% + % + % 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 "<str>" +% -- 'scalar' function +% -- hex/octal/binary input +\newif\ifpgfluamathenableTeXfallback + \newif\ifpgfluamathcomputationactive \newif\ifpgfluamathparseractive @@ -60,6 +171,7 @@ \pgfluamathcomputationactivefalse \fi} +\let\pgfluamath@pgfmathparse\pgfmathparse \def\pgfluamath@makeparseractive{% \ifpgfluamathparseractive \else @@ -97,7 +209,33 @@ luamath/off/.code={% \pgfluamath@makecomputationinactive \pgfluamath@makeparserinactive}, - luamath/.default=only computation} + 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{% @@ -107,9 +245,6 @@ % uninstall assemblation. \def\pgfluamath@checkuninstallcmd{% \pgfutil@ifundefined{pgfluamath@uninstall}{% - \pgfutil@directlua{% - pgfluamathfunctions = require("pgfluamath.functions") - pgfluamathparser = require("pgfluamath.parser")} \global\let\pgfluamath@uninstall=\pgfutil@empty }{% % We already HAVE an uninstall command (prepared globally). @@ -334,166 +469,45 @@ \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 "<str>" +% -- '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{% - \pgfluamathunitsdeclaredfalse - % The following "two passes" (TeX -> lua -> TeX -> lua -> TeX) is - % required for chadef'ed named boxes. The parser - % adds \number in front of the box name (e.g. \mybox -> - % \number\mybox). Then this is expanded to the chardef'ed number via - % \edef expansion. - \edef\pgfluamath@temp{% - \pgfutil@directlua{% - % Double quotes " are needed here. On the lua side, single quotes - % ' are used. Take care to don't mix them. - pgfluamathparser.parse("\pgfutil@luaescapestring{#1}") - tex.sprint(parsed_expression)}}% - % We can now feed back the evaluator. - \edef\pgfluamathresult{% - \pgfutil@directlua{% - pgfluamathparser.eval('\pgfluamath@temp') - if pgfluamathparser.result == nil then - tex.print('nil') - else - tex.print(pgfluamathparser.result) - end}}% - \csname pgfluamathunitsdeclared\pgfutil@directlua{% - if pgfluamathparser.units_declared == true then - tex.print('true') - else - tex.print('false') - end}\endcsname - \ifpgfluamathparseractive - \let\pgfmathresult\pgfluamathresult - \let\ifpgfmathunitsdeclared=\ifpgfluamathunitsdeclared - \fi} + \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 -% NEW: CJ (06 March 2012) Work in progress -\documentclass{minimal} - -\usepackage{pgfmath} - -\makeatletter -\let\pgfutil@directlua\directlua - -\directlua{dofile('pgfmathparser.lua')} - -\def\pgfluamathdeclarefunction#1#2#3{% - \pgfutil@directlua{% - pgfluamath.declare_new_function('#1',#2,#3)}} - -\pgfluamathdeclarefunction{add}{2}{% - function (a,b) return a + b end} - -\pgfluamathdeclarefunction{substract}{2}{% - function (a,b) return a - (b) end} - -\pgfluamathdeclarefunction{neg}{1}{% - function (a) return -(a) end} - -\pgfluamathdeclarefunction{multiply}{2}{% - function (a,b) return a * b end} - -\pgfluamathdeclarefunction{divide}{2}{% - function (a,b) return a / b end} - -\pgfluamathdeclarefunction{pow}{2}{% - function (a,b) return math.pow(a,b) end} - -\pgfluamathdeclarefunction{deg}{1}{% - function (a) return math.deg(a) end} - -\pgfluamathdeclarefunction{ifthenelse}{3}{% - function (a,b,c) if a == 1 then return b else return c end end} - -\pgfluamathdeclarefunction{equal}{2}{% - function (a,b) if a == b then return 1 else return 0 end end} - -\pgfluamathdeclarefunction{greater}{2}{% - function (a,b) if a > b then return 1 else return 0 end end} - -\pgfluamathdeclarefunction{less}{2}{% - function (a,b) if a < b then return 1 else return 0 end end} - -\pgfluamathdeclarefunction{notequal}{2}{% - function (a,b) if a < b or a > b then return 1 else return 0 end end} - -\pgfluamathdeclarefunction{notless}{2}{% - function (a,b) if a >= b then return 1 else return 0 end end} - -\pgfluamathdeclarefunction{notgreater}{2}{% - function (a,b) if a <= b then return 1 else return 0 end end} - -\pgfluamathdeclarefunction{andPGF}{2}{% - function (a,b) if (a < 0 or a > 0) and (b < 0 or b > 0) then return - 1 else return 0 end end} - -\pgfluamathdeclarefunction{orPGF}{2}{% - function (a,b) if (a < 0 or a > 0) or (b < 0 or b > 0) then return 1 - else return 0 end end} - -\pgfluamathdeclarefunction{modulo}{2}{% - % This is the definition of the lua % modulo operator - % The % operator cannot be used here (catcode issue) - function (a,b) return a - math.floor(a/b)*b end} - -\pgfluamathdeclarefunction{int}{1}{% - function (a) return a - pgfluamath.defined_functions.modulo.code(a,1) end} - -\pgfluamathdeclarefunction{frac}{1}{% - function (a) return pgfluamath.defined_functions.modulo.code(a,1) end} - -\pgfluamathdeclarefunction{factorial}{1}{% - function (a) - a = math.abs(pgfluamath.defined_functions.int.code(a)) - if a == 1 then - return 1 - else - return a * pgfluamath.defined_functions.factorial.code(a-1) - end - end} - -\pgfluamathdeclarefunction{sqrt}{1}{% - function (a) return math.sqrt(a) end} - - - -\def\pgfluamathparseandresult#1{% - \pgfutil@directlua{% - local s = pgfluamath.transform_math_expr('#1',pgfluamath.defined_functions_pattern) - texio.write_nl('pgfluamath: parsed expression "' .. s .. '"') - loadstring('tex.sprint(-1,' .. s .. ')')()}} - -\makeatother -\begin{document} - -$\pgfluamathparseandresult{1+2} = 3$ - -$\pgfluamathparseandresult{2*3} = 6$ - -$\pgfluamathparseandresult{1--1} = 2$ - -$\pgfluamathparseandresult{6/2} = 3$ - -$\pgfluamathparseandresult{2^2} = 4$ - -$\pgfluamathparseandresult{1>2} = 0$ - -$\pgfluamathparseandresult{2>1} = 1$ - -$\pgfluamathparseandresult{1!=1} = 0$ - -$\pgfluamathparseandresult{1?2:3} = 2$ - -$\pgfluamathparseandresult{1.0||0} = 1$ - -$\pgfluamathparseandresult{1&&0} = 0$ - -$\pgfluamathparseandresult{sqrt(2)} = \pgfmathparse{sqrt(2)}\pgfmathresult$ - -%\pgfluamathparseandresult{{1,{2,3-7}[1],4}[1]^2} - -\end{document} -% Local Variables: -% TeX-engine: luatex -% End:
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/libraries/luamath/pgfluamath.functions.lua b/Master/texmf-dist/tex/generic/pgf/libraries/luamath/pgfluamath.functions.lua deleted file mode 100644 index fa3c1872a58..00000000000 --- a/Master/texmf-dist/tex/generic/pgf/libraries/luamath/pgfluamath.functions.lua +++ /dev/null @@ -1,313 +0,0 @@ --- Copyright 2011 by Christophe Jorssen --- --- 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: pgfluamath.functions.lua,v 1.9 2013/07/25 10:39:34 tantau Exp $ --- - -local pgfluamathfunctions = pgfluamathfunctions or {} - -local mathabs, mathacos, mathasin = math.abs, math.acos, math.asin -local mathatan, mathatan2, mathceil = math.atan, math.atan2, math.ceil -local mathcos, mathcosh, mathdeg = math.cos, math.cosh, math.deg -local mathexp, mathfloor, mathfmod = math.exp, math.floor, math.fmod -local mathfrexp, mathhuge, mathldexp = math.frexp, math.huge, math.ldexp -local mathlog, mathlog10, mathmax = math.log, math.log10, math.max -local mathmin, mathmodf, mathpi = math.min, math.modf, math.pi -local mathpow, mathrad, mathrandom = math.pow, math.rad, math.random -local mathrandomseed, mathsin = math.randomseed, math.sin -local mathsinh, mathsqrt, mathtanh = math.sinh, math.sqrt, math.tanh -local mathtan = math.tan - -function pgfluamathfunctions.add(x,y) - return x+y -end - -function pgfluamathfunctions.substract(x,y) - return x-y -end - -function pgfluamathfunctions.neg(x) - return -x -end - -function pgfluamathfunctions.multiply(x,y) - return x*y -end - -function pgfluamathfunctions.divide(x,y) - return x/y -end - -function pgfluamathfunctions.pow(x,y) - return mathpow(x,y) -end - -function pgfluamathfunctions.factorial(x) --- TODO: x must be an integer - if x == 0 then - return 1 - else - return x * factorial(x-1) - end -end - -function pgfluamathfunctions.deg(x) - return mathdeg(x) -end - -function pgfluamathfunctions.ifthenelse(x,y,z) - if x~= 0 then - return y - else - return z - end -end - -function pgfluamathfunctions.equal(x,y) - if x == y then - return 1 - else - return 0 - end -end - -function pgfluamathfunctions.greater(x,y) - if x > y then - return 1 - else - return 0 - end -end - -function pgfluamathfunctions.less(x,y) - if x < y then - return 1 - else - return 0 - end -end - -function pgfluamathfunctions.notequal(x,y) - if x ~= y then - return 1 - else - return 0 - end -end - -function pgfluamathfunctions.notless(x,y) - if x >= y then - return 1 - else - return 0 - end -end - -function pgfluamathfunctions.notgreater(x,y) - if x <= y then - return 1 - else - return 0 - end -end - -function pgfluamathfunctions.andPGF(x,y) - if (x ~= 0) and (y ~= 0) then - return 1 - else - return 0 - end -end - -function pgfluamathfunctions.orPGF(x,y) - if (x ~= 0) or (y ~= 0) then - return 1 - else - return 0 - end -end - -function pgfluamathfunctions.notPGF(x) - if x == 0 then - return 1 - else - return 0 - end -end - -function pgfluamathfunctions.pi() - return mathpi -end - -function pgfluamathfunctions.e() - return mathexp(1) -end - -function pgfluamathfunctions.abs(x) - return mathabs(x) -end - -function pgfluamathfunctions.floor(x) - return mathfloor(x) -end - -function pgfluamathfunctions.ceil(x) - return mathceil(x) -end - -function pgfluamathfunctions.exp(x) - return mathexp(x) -end - -function pgfluamathfunctions.log(x) - return mathlog(x) -end - -function pgfluamathfunctions.log10(x) - return mathlog10(x) -end - -function pgfluamathfunctions.sqrt(x) - return mathsqrt(x) -end - -function pgfluamathfunctions.rnd() - return mathrandom() -end - -function pgfluamathfunctions.rand() - return mathrandom(-1,1) -end - -function pgfluamathfunctions.deg(x) - return mathdeg(x) -end - -function pgfluamathfunctions.rad(x) - return mathrad(x) -end - -function pgfluamathfunctions.round(x) - if x<0 then - return -mathceil(mathabs(x)) - else - return mathceil(x) - end -end - -function pgfluamathfunctions.gcd(a, b) - if b == 0 then - return a - else - return gcd(b, a%b) - end -end - -function pgfluamathfunctions.isprime(a) - local ifisprime = true - if a == 1 then - ifisprime = false - elseif a == 2 then - ifisprime = true --- if a > 2 then - else - local i, imax = 2, mathceil(mathsqrt(a)) + 1 - while ifisprime and (i < imax) do - if gcd(a,i) ~= 1 then - ifisprime = false - end - i = i + 1 - end - end - if ifisprime then - return 1 - else - return 0 - end -end - - -function pgfluamathfunctions.split_braces_to_explist(s) - -- (Thanks to mpg and zappathustra from fctt) - -- Make unpack available whatever lua version is used - -- (unpack in lua 5.1 table.unpack in lua 5.2) - local unpack = table.unpack or unpack - local t = {} - for i in s:gmatch('%b{}') do - table.insert(t, tonumber(i:sub(2, -2))) - end - return unpack(t) -end - -function pgfluamathfunctions.split_braces_to_table(s) - local t = {} - for i in s:gmatch('%b{}') do - table.insert(t, tonumber(i:sub(2, -2))) - end - return t -end - -function pgfluamathfunctions.mod(x,y) - if x/y < 0 then - return -(mathabs(x)%mathabs(y)) - else - return mathabs(x)%mathabs(y) - end -end - -function pgfluamathfunctions.Mod(x,y) - return mathabs(x)%mathabs(y) -end - -function pgfluamathfunctions.Sin(x) - return mathsin(mathrad(x)) -end - -function pgfluamathfunctions.Cos(x) - return mathcos(mathrad(x)) -end - -function pgfluamathfunctions.Tan(x) - return mathtan(mathrad(x)) -end - -function pgfluamathfunctions.aSin(x) - return mathdeg(mathasin(x)) -end - -function pgfluamathfunctions.aCos(x) - return mathdeg(mathacos(x)) -end - -function pgfluamathfunctions.aTan(x) - return mathdeg(mathatan(x)) -end - -function pgfluamathfunctions.aTan2(y,x) - return mathdeg(mathatan2(y,x)) -end - -function pgfluamathfunctions.pointnormalised (pgfx, pgfy) - local pgfx_normalised, pgfy_normalised - if pgfx == 0. and pgfy == 0. then - -- Orginal pgf macro gives this result - tex.dimen['pgf@x'] = "0pt" - tex.dimen['pgf@y'] = "1pt" - else - pgfx_normalised = pgfx/math.sqrt(pgfx^2 + pgfy^2) - pgfx_normalised = pgfx_normalised - pgfx_normalised%0.00001 - pgfy_normalised = pgfy/math.sqrt(pgfx^2 + pgfy^2) - pgfy_normalised = pgfy_normalised - pgfy_normalised%0.00001 - tex.dimen['pgf@x'] = tostring(pgfx_normalised) .. "pt" - tex.dimen['pgf@y'] = tostring(pgfy_normalised) .. "pt" - end - return nil -end - -return pgfluamathfunctions
\ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/pgf/libraries/luamath/pgfluamath.parser.lua b/Master/texmf-dist/tex/generic/pgf/libraries/luamath/pgfluamath.parser.lua deleted file mode 100644 index b059e334358..00000000000 --- a/Master/texmf-dist/tex/generic/pgf/libraries/luamath/pgfluamath.parser.lua +++ /dev/null @@ -1,647 +0,0 @@ --- Copyright 2011 by Christophe Jorssen and Mark Wibrow --- --- 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: pgfluamath.parser.lua,v 1.14 2012/04/29 20:36:29 ludewich Exp $ - -local pgfluamathparser = pgfluamathparser or {} - -require("pgfluamath.functions") - --- lpeg is always present in luatex -local lpeg = require("lpeg") - -local S, P, R = lpeg.S, lpeg.P, lpeg.R -local C, Cc, Ct = lpeg.C, lpeg.Cc, lpeg.Ct -local Cf, Cg, Cs = lpeg.Cf, lpeg.Cg, lpeg.Cs -local V = lpeg.V - -local space_pattern = S(" \n\r\t")^0 - -local exponent_pattern = S("eE") - -local one_digit_pattern = R("09") -local positive_integer_pattern = one_digit_pattern^1 -local integer_pattern = P("-")^-1 * positive_integer_pattern --- Valid positive decimals are |xxx.xxx|, |.xxx| and |xxx.| -local positive_decimal_pattern = (one_digit_pattern^1 * P(".") * - one_digit_pattern^1) + - (P(".") * one_digit_pattern^1) + - (one_digit_pattern^1 * P(".")) -local decimal_pattern = P("-")^-1 * positive_decimal_pattern -local float_pattern = decimal_pattern * exponent_pattern * integer_pattern -local number_pattern = float_pattern + decimal_pattern + integer_pattern - -local at_pattern = P("@") - -local underscore_pattern = P("_") - -local lower_letter_pattern = R("az") -local upper_letter_pattern = R("AZ") -local letter_pattern = lower_letter_pattern + upper_letter_pattern -local alphanum_pattern = letter_pattern + one_digit_pattern -local alphanum__pattern = alphanum_pattern + underscore_pattern -local alpha__pattern = letter_pattern + underscore_pattern - -local openparen_pattern = P("(") -local closeparen_pattern = P(")") -local opencurlybrace_pattern = P("{") -local closecurlybrace_pattern = P("}") -local openbrace_pattern = P("[") -local closebrace_pattern = P("]") - --- local string = P('"') * C((1 - P('"'))^0) * P('"') - -local orop_pattern = P("||") -local andop_pattern = P("&&") - -local neqop_pattern = P("!=") - -local then_pattern = P("?") -local else_pattern = P(":") -local factorial_pattern = P("!") -local not_mark_pattern = P("!") -local radians_pattern = P("r") - -local comma_pattern = P(",") - ---[[ -local grammar = P { - -- "E" stands for expression - "ternary_logical_E", - ternary_logical_E = Cf(V("logical_or_E") * - Cg( then_mark * V("logical_or_E") * else_mark * V("logical_or_E"))^0,evalternary); - logical_or_E = Cf(V("logical_and_E") * Cg(orop * V("logical_and_E"))^0,evalbinary); - logical_and_E = Cf(V("equality_E") * Cg(andop * V("equality_E"))^0,evalbinary); - equality_E = Cf(V("relational_E") * - Cg((eqop * V("relational_E")) + (neqop * V("relational_E")))^0,evalbinary); - relational_E = Cf(V("additive_E") * Cg((lessop * V("additive_E")) + - (greatop * V("additive_E")) + - (lesseqop * V("additive_E")) + - (greateqop * V("additive_E")))^0,evalbinary); - additive_E = Cf(V("multiplicative_E") * Cg((addop * V("multiplicative_E")) + - (subop * V("multiplicative_E")))^0,evalbinary); - multiplicative_E = Cf(V("power_E") * Cg((mulop * V("power_E")) + - divop * V("power_E"))^0,evalbinary); - power_E = Cf(V("postfix_unary_E") * Cg(powop * V("postfix_unary_E"))^0,evalbinary); - postfix_unary_E = Cf(V("prefix_unary_E") * Cg(radians + factorial)^0,evalpostfixunary); - prefix_unary_E = Cf(Cg(not_mark + negop)^0 * V("E"),evalprefixunary), - E = string + float + decimal + integer / tonumber + - (openparen * V("ternary_logical_E") * closeparen) + - (func * param_beg * V("ternary_logical_E") * - (comma * V("ternary_logical_E"))^0 * param_end); -} - -local parser = space_pattern * grammar * -1 ---]] - --- NOTE: \pgfmathparse{pi/3.14} will fail giving pgfluamathfunctions.pi()3.14 --- (the / is missing, probably gobbled by one of the captures of the grammar). - -pgfluamathparser.transform_operands = P({ - 'transform_operands'; - - one_char = lpeg.P(1), - lowercase = lpeg.R('az'), - uppercase = lpeg.R('AZ'), - numeric = lpeg.R('09'), - dot = lpeg.P('.'), - exponent = lpeg.S('eE'), - sign_prefix = lpeg.S('-+'), - begingroup = lpeg.P('('), - endgroup = lpeg.P(')'), - backslash = lpeg.P'\\', - at = lpeg.P'@', - - alphabetic = lpeg.V'lowercase' + lpeg.V'uppercase', - alphanumeric = lpeg.V'alphabetic' + lpeg.V'numeric', - - integer = lpeg.V'numeric'^1, - real = lpeg.V'numeric'^0 * lpeg.V'dot' * lpeg.V'numeric'^1, - scientific = (lpeg.V'real' + lpeg.V'integer') * lpeg.V'exponent' * lpeg.V'sign_prefix'^0 * lpeg.V'integer', - - number = lpeg.V'scientific' + lpeg.V'real' + lpeg.V'integer', - function_name = lpeg.V('alphabetic') * lpeg.V('alphanumeric')^0, - - tex_cs = lpeg.V'backslash' * (lpeg.V'alphanumeric' + lpeg.V'at')^1, - tex_box_dimension_primative = lpeg.V'backslash' * (lpeg.P'wd' + lpeg.P'ht' + lpeg.P'dp'), - tex_register_primative = lpeg.V'backslash' * (lpeg.P'count' + lpeg.P'dimen'), - - tex_primative = lpeg.V'tex_box_dimension_primative' + lpeg.V'tex_register_primative', - tex_macro = -lpeg.V'tex_primative' * lpeg.V'tex_cs', - - tex_unit = - lpeg.P('pt') + lpeg.P('mm') + lpeg.P('cm') + lpeg.P('in') + - lpeg.P('ex') + lpeg.P('em') + lpeg.P('bp') + lpeg.P('pc') + - lpeg.P('dd') + lpeg.P('cc') + lpeg.P('sp'), - - tex_register_named = lpeg.C(lpeg.V'tex_macro'), - tex_register_numbered = lpeg.C(lpeg.V'tex_register_primative') * lpeg.C(lpeg.V'integer'), - tex_register_basic = lpeg.Cs(lpeg.Ct(lpeg.V'tex_register_numbered' + lpeg.V'tex_register_named') / pgfluamathparser.process_tex_register), - - tex_multiplier = lpeg.Cs((lpeg.V'tex_register_basic' + lpeg.C(lpeg.V'number')) / pgfluamathparser.process_muliplier), - - tex_box_width = lpeg.Cs(lpeg.P('\\wd') / 'width'), - tex_box_height = lpeg.Cs(lpeg.P('\\ht') / 'height'), - tex_box_depth = lpeg.Cs(lpeg.P('\\dp') / 'depth'), - tex_box_dimensions = lpeg.V'tex_box_width' + lpeg.V'tex_box_height' + lpeg.V'tex_box_depth', - tex_box_named = lpeg.Cs(lpeg.Ct(lpeg.V'tex_box_dimensions' * lpeg.C(lpeg.V'tex_macro')) / pgfluamathparser.process_tex_box_named), - tex_box_numbered = lpeg.Cs(lpeg.Ct(lpeg.V'tex_box_dimensions' * lpeg.C(lpeg.V'number')) / pgfluamathparser.process_tex_box_numbered), - tex_box_basic = lpeg.V'tex_box_named' + lpeg.V'tex_box_numbered', - - tex_register = lpeg.Cs(lpeg.V'tex_multiplier' * lpeg.V'tex_register_basic') + lpeg.V'tex_register_basic', - tex_box = lpeg.Cs(lpeg.Cs(lpeg.V'tex_multiplier') * lpeg.V'tex_box_basic') + lpeg.V'tex_box_basic', - tex_dimension = lpeg.Cs(lpeg.V'number' * lpeg.V'tex_unit' / pgfluamathparser.process_tex_dimension), - - tex_operand = lpeg.Cs(lpeg.V'tex_dimension' + lpeg.V'tex_box' + lpeg.V'tex_register'), - - function_name = lpeg.V'alphabetic' * (lpeg.V'alphanumeric'^1), - function_operand = lpeg.Cs(lpeg.Ct(lpeg.C(lpeg.V'function_name') * lpeg.C(lpeg.V'one_char') + lpeg.C(lpeg.V'function_name')) / pgfluamathparser.process_function), - - -- order is (always) important! - operands = lpeg.V'tex_operand' + lpeg.V'number' + lpeg.V'function_operand', - - transform_operands = lpeg.Cs((lpeg.V'operands' + 1)^0) - }) - --- Namespaces will be searched in the following order. -pgfluamathparser.function_namespaces = { - 'pgfluamathfunctions', 'math', '_G'} - -pgfluamathparser.units_declared = false - -function pgfluamathparser.get_tex_box(box, dimension) - -- assume get_tex_box is only called when a dimension is required. - pgfluamathparser.units_declared = true - if dimension == 'width' then - return tex.box[box].width / 65536 -- return in points. - elseif dimension == 'height' then - return tex.box[box].height / 65536 - else - return tex.box[box].depth / 65536 - end -end - -function pgfluamathparser.get_tex_register(register) - -- register is a string which could be a count or a dimen. - if pcall(tex.getcount, register) then - return tex.count[register] - elseif pcall(tex.getdimen, register) then - pgfluamathparser.units_declared = true - return tex.dimen[register] / 65536 -- return in points. - else - pgfluamathparser.error = 'I do not know the TeX register "' .. register '"' - return nil - end - -end - -function pgfluamathparser.get_tex_count(count) - -- count is expected to be a number - return tex.count[tonumber(count)] -end - -function pgfluamathparser.get_tex_dimen(dimen) - -- dimen is expected to be a number - pgfluamathparser.units_declared = true - return tex.dimen[tonumber(dimen)] / 65536 -end - -function pgfluamathparser.get_tex_sp(dimension) - -- dimension should be a string - pgfluamathparser.units_declared = true - return tex.sp(dimension) / 65536 -end - - - --- transform named box specification --- e.g., \wd\mybox -> pgfluamathparser.get_tex_box["mybox"].width --- -function pgfluamathparser.process_tex_box_named(box) - return 'pgfluamathparser.get_tex_box(\\number' .. box[2] .. ', "' .. box[1] .. '")' -end - --- transform numbered box specification --- e.g., \wd0 -> pgfluamathparser.get_tex_box["0"].width --- -function pgfluamathparser.process_tex_box_numbered(box) - return 'pgfluamathparser.get_tex_box("' .. box[2] .. '", "' .. box[1] .. '")' -end - --- transform a register --- e.g., \mycount -> pgfluamathparser.get_tex_register["mycount"] --- \dimen12 -> pgfluamathparser.get_tex_dimen[12] --- -function pgfluamathparser.process_tex_register(register) - if register[2] == nil then -- a named register - return 'pgfluamathparser.get_tex_register("' .. register[1]:sub(2, register[1]:len()) .. '")' - else -- a numbered register - return 'pgfluamathparser.get_tex_' .. register[1]:sub(2, register[1]:len()) .. '(' .. register[2] .. ')' - end -end - --- transform a 'multiplier' --- e.g., 0.5 -> 0.5* (when followed by a box/register) --- -function pgfluamathparser.process_muliplier(multiplier) - return multiplier .. '*' -end - --- transform an explicit dimension to points --- e.g., 1cm -> pgfluamathparser.get_tex_sp("1cm") --- -function pgfluamathparser.process_tex_dimension(dimension) - return 'pgfluamathparser.get_tex_sp("' .. dimension .. '")' -end - --- Check the type and 'namespace' of a function F. --- --- If F cannot be found as a Lua function or a Lua number in the --- namespaces in containted in pgfluamathparser.function_namespaces --- then an error results. --- --- if F is a Lua function and isn't followd by () (a requirement of Lua) --- then the parentheses are inserted. --- --- e.g., random -> random() (if random is a function in the _G namespace) --- pi -> math.pi (if pi is a constant that is only in the math namespace) --- -function pgfluamathparser.process_function(function_table) - local function_name = function_table[1] - local char = function_table[2] - if (char == nil) then - char = '' - end - for _, namespace in pairs(pgfluamathparser.function_namespaces) do - local function_type = assert(loadstring('return type(' .. namespace .. '.' .. function_name .. ')'))() - if function_type == 'function' then - if not (char == '(') then - char = '()' - end - return namespace .. '.' .. function_name .. char - elseif function_type == 'number' then - return namespace .. '.' .. function_name .. char - end - end - pgfluamathparser.error = 'I don\'t know the function or constant \'' .. function_name .. '\'' -end - - -pgfluamathparser.remove_spaces = lpeg.Cs((lpeg.S' \n\t' / '' + 1)^0) - - -function pgfluamathparser.evaluate(expression) - assert(loadstring('pgfluamathparser._result=' .. expression))() - pgfluamathparser.result = pgfluamathparser._result -end - -function pgfluamathparser.parse(expression) - pgfluamathparser.write_to_log("Parsing expression:" .. expression) - pgfluamathparser.units_declared = false - - pgfluamathparser.error = nil - pgfluamathparser.result = nil - - -- Remove spaces - expression = pgfluamathparser.remove_spaces:match(expression) - - parsed_expression = - pgfluamathparser.transform_operands:match(expression) - pgfluamathparser.write_to_log("Transformed expression:" - .. parsed_expression) -end - -function pgfluamathparser.eval(expression) - pgfluamathparser.write_to_log("Evaluating expression:" .. expression) - pcall(pgfluamathparser.evaluate, expression) - pgfluamathparser.write_to_log("Result:" .. pgfluamathparser.result) - if pgfluamathparser.result == nil then - pgfluamathparser.error = "Sorry, I could not evaluate '" .. expression .. "'" - return nil - else - return pgfluamathparser.result - end -end - -pgfluamathparser.trace = true - -function pgfluamathparser.write_to_log (s) - if pgfluamathparser.trace then - texio.write_nl(s) - end -end - -return pgfluamathparser - ---[[ NEW: 2012/02/21, CJ, work in progress --- We need 3 parsers (or 2, 2 and 3 could be merged) --- (1) To get the number associated with a (\chardef'ed) box (e.g. --- \ht\mybox -> \ht26) --- This is part of a TeX ->(\directlua == \edef) -> lua -> (lpeg parser 1) --- -> TeX -> (\directlua == \edef) --- (2) To transform math and functions operands --- (3) To transform units, dimen and count register - --- TODO: strings delimited by "..." --- TODO: units. \pgfmathparse{12+1cm}\pgfmathresult and \the\dimexpr 12pt+1cm\relax have the same result. Note: \pgfmathparse{(12+1)cm} won't work in plain pgfmath. --- TODO: Parser 3 - - -pgfluamath = pgfluamath or {} - -pgfluamath.debug = true - -local lpeg = require('lpeg') -local P, R, S, V = lpeg.P, lpeg.R, lpeg.S, lpeg.V -local C, Cc, Cs = lpeg.C, lpeg.Cc, lpeg.Cs -local Cf, Cg, Ct = lpeg.Cf, lpeg.Cg, lpeg.Ct -local match = lpeg.match - -local space = S(' \n\t') - -local lowercase = R('az') -local uppercase = R('AZ') -local alphabetic = lowercase + uppercase - -local digit = R('09') - -local alphanumeric = alphabetic + digit - -local dot = P('.') -local exponent = S('eE') -local sign_prefix = S('+-') - -local integer = digit^1 -local float = (digit^1 * dot * digit^0) + (digit^0 * dot * digit^1) -local scientific = (float + integer) * exponent * sign_prefix^-1 * integer - -local number = scientific + float + integer - -local at = P('@') - -local backslash = P('\\') - -local box_width = P('\\wd') -local box_height = P('\\ht') -local box_depth = P('\\dp') -local box_dimension = box_width + box_height + box_depth - -local tex_cs = backslash * (alphabetic + at)^1 - -local lparen = P('(') -local rparen = P(')') - -local lbrace = P('{') -local rbrace = P('}') - -local lbracket = P('[') -local rbracket = P(']') - -local thenop = P('?') -local elseop = P(':') - -local orop = P('||') -local andop = P('&&') - -local eqop = P('==') -local neqop = P('!=') - -local greaterop = P('>') -local lessop = P('<') -local greatereqop = P('>=') -local lesseqop = P('<=') - -local addop = P('+') -local subop = P('-') - -local mulop = P('*') -local divop = P('/') - -local powop = P('^') - -local radop = P('r') - -local notop = P('!') -local negop = P('-') - -local comma = P(',') - -function pgfluamath.namedbox_to_numberedbox (s) - -- Transforms '{\wd|\ht|\dp}\mybox' to '{\wd|\ht|\dp}\number\mybox' - local function transform (capture) - print('Captured ' .. capture) - return '\\number' .. capture - end - local dimension_of_a_named_box = - box_dimension * space^0 * (tex_cs / transform) - -- P(1) matches exactly one character - -- V(1) is the entry of the grammar with index 1. It defines the initial rule. - -- The manual says: - -- "If that entry is a string, it is assumed to be the name of the initial rule. - -- Otherwise, LPeg assumes that the entry 1 itself is the initial rule." - local grammar = - P({ - [1] = (dimension_of_a_named_box + P(1)) * V(1) + P(true) - }) - return print(match(Cs(grammar),s)) -end ---[[ -namedbox_to_numberedbox('test') -namedbox_to_numberedbox('\\test') -namedbox_to_numberedbox('\\wd\\test') -namedbox_to_numberedbox('\\wd\\test0') -namedbox_to_numberedbox('\\wd\\test01') -namedbox_to_numberedbox('\\wd\\test@t 012') -namedbox_to_numberedbox(' \\wd \\test012') -namedbox_to_numberedbox('\\wd\\test012\\test \\ht\\zozo0') -namedbox_to_numberedbox('\\wd0') ---]] - --- Grammar (from lowest to highest precedence) --- Need to adjust to the precedences in plain pgfmath parser --- IfThenElse Expression -local ITE_E = V('ITE_E') --- logical OR Expression -local OR_E = V('OR_E') --- logical AND Expression -local AND_E = V('AND_E') --- EQuality Expression -local EQ_E = V('EQ_E') --- Relational EQuality Expression -local REQ_E = V('REQ_E') --- ADDitive Expression -local ADD_E = V('ADD_E') --- MULtiplicative Expression -local MUL_E = V('MUL_E') --- POWer Expression -local POW_E = V('POW_E') --- POSTfix Expression -local POST_E = V('POST_E') --- PREfix Expression -local PRE_E = V('PRE_E') --- ARRAY Expression -local ARRAY_E = V('ARRAY_E') --- Expression -local E = V('E') - -function pgfluamath.transform_math_expr (s, f_patt) - if pgfluamath.debug then - texio.write_nl('pgfluamath: parsing expression "' .. s ..'"') - end - -- f_patt extends the grammar dynamically at the time of the call to the - -- parser. - -- The idea is to have a set of predefined acceptable functions (via e.g. - -- \pgfmathdeclarefunction) - if not f_patt then - -- P(false) is a pattern that always fails - -- (neutral element for the + operator on patterns) - f_patt = P(false) - end - local function transform_ITE(a, b, c) - if not b then - return a - else - return string.format('pgfluamath.defined_functions.ifthenelse.code(%s,%s,%s)', a, b, c) - end - end - local function transform_binary(a, b, c) - if not b then - return a - else - return string.format('pgfluamath.defined_functions.%s.code(%s,%s)', b, a, c) - end - end - local function transform_postunary(a, b) - if not b then - return a - else - return string.format('pgfluamath.defined_functions.%s.code(%s)', b, a) - end - end - local function transform_preunary(a, b) - if not b then - return a - else - return string.format('pgfluamath.defined_functions.%s.code(%s)', a, b) - end - end - local function transform_array(a, b) - -- One exception to the mimmic of plain pgfmath. I do not use the equivalent array function to transform the arrays because I don't know how to handle both cases {1,{2,3}[1],4}[1] and {1,{2,3},4}[1][1] with the parser and the array function. - -- So I convert a pgf array to a lua table. One can access one entry of the table like this ({1,2})[1] (note the parenthesis, ie {1,2}[1] won't work). - local s - if not b then - s = '{' - else - s = '({' - end - for i = 1,#a do - -- We change the index to fit with pgfmath plain convention (index starts at 0 while in lua index starts at 1) - s = s .. '[' .. tostring(i-1) .. ']=' .. a[i] - if i < #a then - s = s .. ',' - end - end - if b then - s = s .. '})' - for i = 1,#b do - s = s .. '[' .. b[i] .. ']' - end - else - s = s .. '}' - end - return s - end - local grammar = - lpeg.P({ - 'ITE_E', - ITE_E = (OR_E * (thenop * OR_E * elseop * OR_E)^-1) / transform_ITE, - OR_E = (AND_E * (orop * Cc('orPGF') * AND_E)^-1) / transform_binary, - AND_E = (EQ_E * (andop * Cc('andPGF') * EQ_E)^-1) / transform_binary, - EQ_E = (REQ_E * ((eqop * Cc('equal') + neqop * Cc('notequal')) * REQ_E)^-1) / transform_binary, - REQ_E = (ADD_E * ((lessop * Cc('less') + greaterop * Cc('greater') + lesseqop * Cc('notgreater') + greatereqop * Cc('notless')) * ADD_E)^-1) / transform_binary, - ADD_E = Cf(MUL_E * Cg((addop * Cc('add') + subop * Cc('substract')) * MUL_E)^0,transform_binary), - MUL_E = Cf(POW_E * Cg((mulop * Cc('multiply') + divop * Cc('divide')) * POW_E)^0,transform_binary), - POW_E = Cf(POST_E * Cg(powop * Cc('pow') * POST_E)^0,transform_binary), - POST_E = (PRE_E * (radop * Cc('rad'))^-1) / transform_postunary, - PRE_E = ((notop * Cc('notPGF') + negop * Cc('neg'))^-1 * E) / transform_preunary, - ARRAY_E = (lbrace * Ct(ITE_E * (comma * ITE_E)^0) * rbrace * Ct((lbracket * ITE_E * rbracket)^0)) / transform_array, - E = ((integer + float)^-1 * tex_cs^1) + f_patt + C(number) + (lparen * ITE_E * rparen) + ARRAY_E + lbrace * ITE_E * rbrace - }) - return lpeg.match(Cs(grammar),s) -end - -function pgfluamath.ptransform_math_expr(s, f_patt) - local st = pgfluamath.transform_math_expr(s, f_patt) - if st ~= nil then - return texio.write_nl(st) - end -end - -pgfluamath.defined_functions = {} -pgfluamath.defined_functions_pattern = P(false) - -function pgfluamath.declare_new_function (name, nargs, code) - -- nil is true - -- The function name CANNOT be a lua reserved word (so no 'and' nor 'or') - if pgfluamath.defined_functions[name] then - print('Function ' .. name .. ' is already defined. ' .. - 'I overwrite it!') - end - pgfluamath.defined_functions[name] = {['name'] = name, ['nargs'] = nargs, ['code'] = code} - - -- TODO - -- We need a function to dynamically (depending on the number of arguments) define a patten (in order to avoid the long ifcase-type structure). - local pattern - if nargs == 0 then - pattern = P(name) / function (s) return name .. '()' end - else if nargs == 1 then - pattern = ((P(name) * lparen * Cs(ITE_E) * rparen) / function (s) return 'pgfluamath.defined_functions.' .. name .. '.code(' .. s .. ')' end) - else if nargs == 2 then - pattern = (P(name) * lparen * Cs(ITE_E) * comma * Cs(ITE_E) * rparen / function (s1,s2) return 'pgfluamath.defined_functions.' .. name .. 'code(' .. s1 .. ',' .. s2 .. ')' end) - else if nargs == 3 then - pattern = (P(name) * lparen * Cs(ITE_E) * comma * Cs(ITE_E) * comma * Cs(ITE_E) * rparen / function (s1,s2,s3) return 'pgfluamath.defined_functions.' .. name .. 'code(' .. s1 .. ',' .. s2 .. ',' .. s3 .. ')' end) - end - end - end - end - -- TODO - -- This needs to be regenerated every time a new function is added, in conjunction with a sort of the table (see IMPORTANT below) - pgfluamath.defined_functions_pattern = pgfluamath.defined_functions_pattern + pattern -end - --- IMPORTANT: for 'function' with *0* argument, the longest string, the first --- ie declaring pi before pit won't work. -pgfluamath.declare_new_function('pit',0) -pgfluamath.declare_new_function('pi',0) -pgfluamath.declare_new_function('exp',1) -pgfluamath.declare_new_function('toto',1) -pgfluamath.declare_new_function('gauss',2) - -pgfluamath.ptransform_math_expr('exp(exp(1+1))',pgfluamath.defined_functions_pattern) - -pgfluamath.ptransform_math_expr('1?(2?3:4^5):gauss(6+toto(7),8+9>10?11:12))',pgfluamath.defined_functions_pattern) - -pgfluamath.ptransform_math_expr('!(1!=-2)>3?(4+5*6+7?8||9&&10:11):12^13r||14') -pgfluamath.ptransform_math_expr('-1^2\\test\\toto^3') -pgfluamath.ptransform_math_expr('{1,{2+3,4}[1],5}[2]+6') -pgfluamath.ptransform_math_expr('{1,{2+3,4},5}[1][1]') -pgfluamath.ptransform_math_expr('{1,{2,3},4}[1][1]') -pgfluamath.ptransform_math_expr('{1,{2,3}[1],4}[1]') - ---Loadstring: If it succeeds in converting the string to a *function*, it returns that function; otherwise, it returns nil and an error message. -toto = loadstring('texio.write_nl(' .. pgfluamath.transform_math_expr('{1,{2,3},4}[1][1]') .. ')') -toto() - --- IMPORTANT NOTE!! --- local function add (a,b) will fail within loadstring. Needs to be global. loadstring opens a new chunk that does not know the local variables of other chunks. - ---toto = loadstring('texio.write_nl(' .. pgfluamath.transform_math_expr('{1,{2,3E-1+7}[1],4}[1]') .. ')') ---toto() - -return pgfluamath diff --git a/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryarrows.meta.code.tex b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryarrows.meta.code.tex index 77edfcd8dc6..80b2573a0c4 100644 --- a/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryarrows.meta.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryarrows.meta.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/libraries/pgflibraryarrows.meta.code.tex,v 1.12 2013/12/13 15:11:58 tantau Exp $ +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/libraries/pgflibraryarrows.meta.code.tex,v 1.13 2015/05/13 21:19:11 cfeuersaenger Exp $ @@ -139,13 +139,13 @@ }, setup code = { % Compute front miter length: - \pgfmathdivide@\pgfarrowlength\pgfarrowwidth% + \pgfmathdivide@{\pgf@sys@tonumber\pgfarrowlength}{\pgf@sys@tonumber\pgfarrowwidth}% \let\pgf@temp@quot\pgfmathresult% \pgf@x\pgfmathresult pt% \pgf@x\pgfmathresult\pgf@x% \pgf@x4\pgf@x% \advance\pgf@x by1pt% - \pgfmathsqrt@\pgf@x% + \pgfmathsqrt@{\pgf@sys@tonumber\pgf@x}% \pgf@xc\pgfmathresult\pgfarrowlinewidth% xc is front miter \pgf@xc.5\pgf@xc \pgf@xa\pgf@temp@quot\pgfarrowlinewidth% xa is extra harpoon miter @@ -548,13 +548,13 @@ \advance\pgfutil@tempdimb by-\pgfarrowlinewidth \ifpgfarrowroundjoin% \else% - \pgfmathdivide@\pgfutil@tempdima\pgfutil@tempdimb% + \pgfmathdivide@{\pgf@sys@tonumber\pgfutil@tempdima}{\pgf@sys@tonumber\pgfutil@tempdimb}% \let\pgf@temp@quot\pgfmathresult% \pgf@x\pgfmathresult pt% \pgf@x\pgfmathresult\pgf@x% \pgf@x40.96\pgf@x% \advance\pgf@x by1pt% \pgflinewidth^2 + (6.4 \pgftempdim@a / \pgfutil@tempdimb) \pgflinewidth^2 - \pgfmathsqrt@\pgf@x% + \pgfmathsqrt@{\pgf@sys@tonumber\pgf@x}% \pgf@xc\pgfmathresult\pgfarrowlinewidth% xc is front miter \pgf@xc.5\pgf@xc \fi% @@ -686,13 +686,13 @@ % Front miter: \ifpgfarrowroundjoin% \else% - \pgfmathdivide@\pgfutil@tempdima\pgfutil@tempdimb% + \pgfmathdivide@{\pgf@sys@tonumber\pgfutil@tempdima}{\pgf@sys@tonumber\pgfutil@tempdimb}% \let\pgf@temp@quot\pgfmathresult% \pgf@x\pgfmathresult pt% \pgf@x\pgfmathresult\pgf@x% \pgf@x49.44662\pgf@x% \advance\pgf@x by1pt% \pgfarrowlinewidth^2 + (0.41019/0.0583333 \pgftempdim@a / \pgfutil@tempdimb) \pgfarrowlinewidth^2 - \pgfmathsqrt@\pgf@x% + \pgfmathsqrt@{\pgf@sys@tonumber\pgf@x}% \pgf@xc\pgfmathresult\pgfarrowlinewidth% xc is front miter \pgf@xc.5\pgf@xc \pgf@xa\pgf@temp@quot\pgfarrowlinewidth% xa is extra harpoon miter @@ -826,13 +826,13 @@ \fi \pgfarrowssavethe\pgfarrowlinewidth% % Compute front miter length: - \pgfmathdivide@\pgfarrowlength\pgfarrowwidth% + \pgfmathdivide@{\pgf@sys@tonumber\pgfarrowlength}{\pgf@sys@tonumber\pgfarrowwidth}% \let\pgf@temp@quot\pgfmathresult% \pgf@x\pgfmathresult pt% \pgf@x\pgfmathresult\pgf@x% \pgf@x9\pgf@x% \advance\pgf@x by1pt% - \pgfmathsqrt@\pgf@x% + \pgfmathsqrt@{\pgf@sys@tonumber\pgf@x}% \pgf@xc\pgfmathresult\pgfarrowlinewidth% \pgf@xa\pgf@temp@quot\pgfarrowlinewidth % Inner length (pgfutil@tempdima) is now arrowlength - front miter @@ -862,7 +862,7 @@ \pgf@process{\pgfpointnormalised{\pgfqpoint{.3\pgfarrowlength}{.2333333\pgfarrowwidth}}}% \advance\pgf@y by1pt% \pgf@yc\pgf@y\pgf@xc\pgf@x% - \pgfmathdivide@\pgf@yc\pgf@xc% + \pgfmathdivide@{\pgf@sys@tonumber\pgf@yc}{\pgf@sys@tonumber\pgf@xc}% \pgfutil@tempdimb\pgfmathresult\pgfarrowlinewidth% \pgfutil@tempdimb-.5\pgfutil@tempdimb% \advance\pgfutil@tempdimb by.5\pgfarrowwidth% @@ -922,13 +922,13 @@ \pgfarrowlinewidth\pgf@x \fi % Compute front miter length: - \pgfmathdivide@\pgfarrowlength\pgfarrowwidth% + \pgfmathdivide@{\pgf@sys@tonumber\pgfarrowlength}{\pgf@sys@tonumber\pgfarrowwidth}% \let\pgf@temp@quot\pgfmathresult% \pgf@x\pgfmathresult pt% \pgf@x\pgfmathresult\pgf@x% \pgf@x4\pgf@x% \advance\pgf@x by1pt% - \pgfmathsqrt@\pgf@x% + \pgfmathsqrt@{\pgf@sys@tonumber\pgf@x}% \pgf@xc\pgfmathresult\pgfarrowlinewidth% xc is front miter \pgf@xc.5\pgf@xc \pgf@xa\pgf@temp@quot\pgfarrowlinewidth% xa is extra harpoon miter @@ -940,25 +940,25 @@ \pgf@ya\pgfmathresult pt% \advance\pgf@yb by-\pgf@ya% \pgf@yb.5\pgf@yb% half angle in yb - \pgfmathtan@{\pgf@yb}% + \pgfmathtan@{\pgf@sys@tonumber\pgf@yb}% \pgfmathreciprocal@{\pgfmathresult}% \pgf@yc\pgfmathresult\pgfarrowlinewidth% \pgf@yc.5\pgf@yc% \advance\pgf@ya by\pgf@yb% - \pgfmathsincos@{\pgf@ya}% + \pgfmathsincos@{\pgf@sys@tonumber\pgf@ya}% \pgf@ya\pgfmathresulty\pgf@yc% ya is the back miter \pgf@yb\pgfmathresultx\pgf@yc% yb is the top miter \ifdim\pgfarrowinset=0pt% \pgf@ya.5\pgfarrowlinewidth% easy: back miter is half linewidth \fi % Compute inset miter length: - \pgfmathdivide@\pgfarrowinset\pgfarrowwidth% + \pgfmathdivide@{\pgf@sys@tonumber\pgfarrowinset}{\pgf@sys@tonumber\pgfarrowwidth}% \let\pgf@temp@quot\pgfmathresult% \pgf@x\pgfmathresult pt% \pgf@x\pgfmathresult\pgf@x% \pgf@x4\pgf@x% \advance\pgf@x by1pt% - \pgfmathsqrt@\pgf@x% + \pgfmathsqrt@{\pgf@sys@tonumber\pgf@x}% \pgf@yc\pgfmathresult\pgfarrowlinewidth% yc is inset miter \pgf@yc.5\pgf@yc% % Inner length (pgfutil@tempdima) is now arrowlength - front miter - back miter @@ -1054,24 +1054,24 @@ % Compute front miter length: \pgf@xa\pgfarrowlength% \advance\pgf@xa by-\pgfarrowinset% - \pgfmathdivide@\pgf@xa\pgfarrowwidth% + \pgfmathdivide@{\pgf@sys@tonumber\pgf@xa}{\pgf@sys@tonumber\pgfarrowwidth}% \let\pgf@temp@quot\pgfmathresult% \pgf@x\pgfmathresult pt% \pgf@x\pgfmathresult\pgf@x% \pgf@x4\pgf@x% \advance\pgf@x by1pt% - \pgfmathsqrt@\pgf@x% + \pgfmathsqrt@{\pgf@sys@tonumber\pgf@x}% \pgf@xc\pgfmathresult\pgfarrowlinewidth% xc is front miter \pgf@xc.5\pgf@xc \pgf@xa\pgf@temp@quot\pgfarrowlinewidth% xa is extra harpoon miter % Compute back miter length: - \pgfmathdivide@\pgfarrowinset\pgfarrowwidth% + \pgfmathdivide@{\pgf@sys@tonumber\pgfarrowinset}{\pgf@sys@tonumber\pgfarrowwidth}% \let\pgf@temp@quot\pgfmathresult% \pgf@x\pgfmathresult pt% \pgf@x\pgfmathresult\pgf@x% \pgf@x4\pgf@x% \advance\pgf@x by1pt% - \pgfmathsqrt@\pgf@x% + \pgfmathsqrt@{\pgf@sys@tonumber\pgf@x}% \pgf@yc\pgfmathresult\pgfarrowlinewidth% yc is back miter \pgf@yc.5\pgf@yc \pgf@ya\pgf@temp@quot\pgfarrowlinewidth% ya is extra harpoon miter @@ -1088,7 +1088,7 @@ \ifdim\pgf@yb=45pt% \def\pgfmathresult{1.414213}% \else% - \pgfmathsin@{\pgf@yb}% + \pgfmathsin@{\pgf@sys@tonumber\pgf@yb}% \pgfmathreciprocal@{\pgfmathresult}% \fi% \pgf@yc\pgfmathresult\pgfarrowlinewidth% @@ -1096,7 +1096,7 @@ \pgf@ya-\pgf@ya% \advance\pgf@ya by-90pt% \advance\pgf@ya by\pgf@yb% - \pgfmathsincos@{\pgf@ya}% + \pgfmathsincos@{\pgf@sys@tonumber\pgf@ya}% \pgf@xb\pgfmathresultx\pgf@yc% ya is the back miter \pgf@yb\pgfmathresulty\pgf@yc% yb is the top miter \expandafter\expandafter\expandafter% @@ -1368,7 +1368,7 @@ cap angle/.code={% \pgfmathsetlength\pgf@x{#1}% \pgf@x.5\pgf@x - \pgfmathtan@{\pgf@x}% + \pgfmathtan@{\pgf@sys@tonumber\pgf@x}% \pgfmathreciprocal@{\pgfmathresult}% \pgf@x\pgfmathresult pt% \pgf@x.5\pgf@x% @@ -1530,7 +1530,7 @@ % Compute tips: \pgf@xa\pgfarrow@inc pt% \ifodd\pgfarrown\pgf@ya.25\pgf@xa\else\pgf@ya.5\pgf@xa\fi% - \pgfmathsincos@\pgf@ya% + \pgfmathsincos@{\pgf@sys@tonumber\pgf@ya}% \pgf@x.5\pgfarrowlength% \pgf@xa\pgfmathresultx\pgf@x% \ifpgfarrowroundcap diff --git a/Master/texmf-dist/tex/generic/pgf/libraries/pgflibrarycurvilinear.code.tex b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibrarycurvilinear.code.tex index 18fa1951b05..2ae9eb00e5a 100644 --- a/Master/texmf-dist/tex/generic/pgf/libraries/pgflibrarycurvilinear.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibrarycurvilinear.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/libraries/pgflibrarycurvilinear.code.tex,v 1.3 2013/10/07 15:51:46 tantau Exp $ +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/libraries/pgflibrarycurvilinear.code.tex,v 1.4 2015/05/14 14:43:05 cfeuersaenger Exp $ % % This file defines commands for computing points in curvilinear @@ -75,7 +75,7 @@ \pgf@yb=-\pgf@y% \advance\pgf@x by\pgf@xa% \advance\pgf@y by\pgf@ya% - \pgfmathveclen@{\pgf@x}{\pgf@y}% + \pgfmathveclen@{\pgf@sys@tonumber\pgf@x}{\pgf@sys@tonumber\pgf@y}% \let\pgf@curvilinear@lenab\pgfmathresult% \pgf@process{#3}% \edef\pgf@curvilinear@line@c{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% @@ -83,26 +83,26 @@ \pgf@yc=-\pgf@y% \advance\pgf@x by\pgf@xb% \advance\pgf@y by\pgf@yb% - \pgfmathveclen@{\pgf@x}{\pgf@y}% + \pgfmathveclen@{\pgf@sys@tonumber\pgf@x}{\pgf@sys@tonumber\pgf@y}% \let\pgf@curvilinear@lenbc\pgfmathresult% \pgf@process{#4}% \edef\pgf@curvilinear@line@d{\noexpand\pgfqpoint{\the\pgf@x}{\the\pgf@y}}% \advance\pgf@x by\pgf@xc% \advance\pgf@y by\pgf@yc% - \pgfmathveclen@{\pgf@x}{\pgf@y}% + \pgfmathveclen@{\pgf@sys@tonumber\pgf@x}{\pgf@sys@tonumber\pgf@y}% \let\pgf@curvilinear@lencd\pgfmathresult % \pgf@x=\pgf@curvilinear@lenab pt% \advance\pgf@x by\pgf@curvilinear@lenbc pt% \advance\pgf@x by\pgf@curvilinear@lencd pt% - \pgfmathreciprocal@{\pgf@x}% + \pgfmathreciprocal@{\pgf@sys@tonumber\pgf@x}% \pgf@curvilinear@time@a\pgfmathresult pt% \pgf@process{\pgfpointcurveattime{\pgf@curvilinear@time@a}{\pgf@curvilinear@line@a}{\pgf@curvilinear@line@b}{\pgf@curvilinear@line@c}{\pgf@curvilinear@line@d}}% \pgf@xb=-\pgf@x% \pgf@yb=-\pgf@y% \advance\pgf@x by\pgf@xa% \advance\pgf@y by\pgf@ya% - \pgfmathveclen@{\pgf@x}{\pgf@y}% + \pgfmathveclen@{\pgf@sys@tonumber\pgf@x}{\pgf@sys@tonumber\pgf@y}% \pgf@curvilinear@length@a\pgfmathresult pt% \ifdim\pgf@curvilinear@length@a>1pt\relax% % Ok, too large, let us make this smaller @@ -113,7 +113,7 @@ \pgf@yb=-\pgf@y% \advance\pgf@x by\pgf@xa% \advance\pgf@y by\pgf@ya% - \pgfmathveclen@{\pgf@x}{\pgf@y}% + \pgfmathveclen@{\pgf@sys@tonumber\pgf@x}{\pgf@sys@tonumber\pgf@y}% \pgf@curvilinear@length@a\pgfmathresult pt% \fi% % Compute three positions: @@ -122,7 +122,7 @@ \pgf@ya=-\pgf@y% \advance\pgf@x by\pgf@xb% \advance\pgf@y by\pgf@yb% - \pgfmathveclen@{\pgf@x}{\pgf@y}% + \pgfmathveclen@{\pgf@sys@tonumber\pgf@x}{\pgf@sys@tonumber\pgf@y}% \pgf@curvilinear@length@b\pgfmathresult pt% \advance\pgf@curvilinear@length@b by\pgf@curvilinear@length@a% \pgf@process{\pgfpointcurveattime{4\pgf@curvilinear@time@a}{\pgf@curvilinear@line@a}{\pgf@curvilinear@line@b}{\pgf@curvilinear@line@c}{\pgf@curvilinear@line@d}} @@ -130,13 +130,13 @@ \pgf@yb=-\pgf@y% \advance\pgf@x by\pgf@xa% \advance\pgf@y by\pgf@ya% - \pgfmathveclen@{\pgf@x}{\pgf@y}% + \pgfmathveclen@{\pgf@sys@tonumber\pgf@x}{\pgf@sys@tonumber\pgf@y}% \pgf@curvilinear@length@c\pgfmathresult pt% \advance\pgf@curvilinear@length@c by\pgf@curvilinear@length@b% \pgf@process{\pgfpointcurveattime{8\pgf@curvilinear@time@a}{\pgf@curvilinear@line@a}{\pgf@curvilinear@line@b}{\pgf@curvilinear@line@c}{\pgf@curvilinear@line@d}} \advance\pgf@x by\pgf@xb% \advance\pgf@y by\pgf@yb% - \pgfmathveclen@{\pgf@x}{\pgf@y}% + \pgfmathveclen@{\pgf@sys@tonumber\pgf@x}{\pgf@sys@tonumber\pgf@y}% \pgf@curvilinear@length@d\pgfmathresult pt% \advance\pgf@curvilinear@length@d by\pgf@curvilinear@length@c% \let\pgf@curvilinear@comp@a\pgf@curvilinear@comp@a@initial% @@ -154,7 +154,7 @@ \def\pgf@curvilinear@comp@a@initial{% - \pgfmathdivide@\pgf@curvilinear@time@a\pgf@curvilinear@length@a% + \pgfmathdivide@{\pgf@sys@tonumber\pgf@curvilinear@time@a}{\pgf@sys@tonumber\pgf@curvilinear@length@a}% \let\pgf@curvilinear@quot@a\pgfmathresult% \let\pgf@curvilinear@comp@a\pgf@curvilinear@comp@a@cont% \pgf@curvilinear@comp@a@cont% @@ -166,7 +166,7 @@ \def\pgf@curvilinear@comp@b@initial{% \pgf@y=\pgf@curvilinear@length@b% \advance\pgf@y by-\pgf@curvilinear@length@a% - \pgfmathdivide@\pgf@curvilinear@time@a\pgf@y% + \pgfmathdivide@{\pgf@sys@tonumber\pgf@curvilinear@time@a}{\pgf@sys@tonumber\pgf@y}% \let\pgf@curvilinear@quot@b\pgfmathresult% \pgf@y\pgfmathresult\pgf@curvilinear@length@a% \pgf@y-\pgf@y% @@ -184,7 +184,7 @@ \pgf@y=\pgf@curvilinear@length@c% \advance\pgf@y by-\pgf@curvilinear@length@b% \pgf@y.5\pgf@y% - \pgfmathdivide@\pgf@curvilinear@time@a\pgf@y% + \pgfmathdivide@{\pgf@sys@tonumber\pgf@curvilinear@time@a}{\pgf@sys@tonumber\pgf@y}% \let\pgf@curvilinear@quot@c\pgfmathresult% \pgf@y\pgf@curvilinear@quot@c\pgf@curvilinear@length@b% \pgf@y-\pgf@y% @@ -202,7 +202,7 @@ \pgf@y=\pgf@curvilinear@length@d% \advance\pgf@y by-\pgf@curvilinear@length@c% \pgf@y.25\pgf@y% - \pgfmathdivide@\pgf@curvilinear@time@a\pgf@y% + \pgfmathdivide@{\pgf@sys@tonumber\pgf@curvilinear@time@a}{\pgf@sys@tonumber\pgf@y}% \let\pgf@curvilinear@quot@d\pgfmathresult% \pgf@y\pgf@curvilinear@quot@d\pgf@curvilinear@length@c% \pgf@y-\pgf@y% @@ -217,7 +217,8 @@ } \def\pgf@curvilinear@comp@e@initial{% - \pgfmathdivide@{8\pgf@curvilinear@time@a}{\pgf@curvilinear@length@d}% + \pgfmathmultiply@{8}{\pgf@sys@tonumber\pgf@curvilinear@time@a}% + \expandafter\pgfmathdivide@\expandafter{\pgfmathresult}{\pgf@sys@tonumber\pgf@curvilinear@length@d}% \let\pgf@curvilinear@quot@e\pgfmathresult% \let\pgf@curvilinear@comp@e\pgf@curvilinear@comp@e@cont% \pgf@curvilinear@comp@e@cont% @@ -353,7 +354,7 @@ {\pgf@sys@tonumber\pgf@x}{\pgf@sys@tonumber\pgf@y}% {\pgf@sys@tonumber\pgf@ya}{\pgf@sys@tonumber\pgf@x}{0pt}{0pt}% \pgftransformshift{\pgfpointscale{-1}{\pgf@curvilinear@line@a}}% - \pgfmathveclen@{\pgfutil@tempdima}{\pgfutil@tempdimb}% + \pgfmathveclen@{\pgf@sys@tonumber\pgfutil@tempdima}{\pgf@sys@tonumber\pgfutil@tempdimb}% \ifdim\pgfutil@tempdima<0pt% \edef\pgfmathresult{-\pgfmathresult}% \fi% diff --git a/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryfixedpointarithmetic.code.tex b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryfixedpointarithmetic.code.tex index f82f8640c4f..50a7521f826 100644 --- a/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryfixedpointarithmetic.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryfixedpointarithmetic.code.tex @@ -273,7 +273,7 @@ } \def\pgfmathfpabs@#1{% \begingroup% - \FPabs\pgfmathresult{#1} + \FPabs\pgfmathresult{#1}% \pgfmath@smuggleone\pgfmathresult% \endgroup% } @@ -561,7 +561,7 @@ \begingroup% \FPmul\pgfmathresult{#1}{0.017453292519943295}% \FPcos\pgfmathresult{\pgfmathresult}% - \FPdiv\pgfmathresult{1}{\pgfmathresult} + \FPdiv\pgfmathresult{1}{\pgfmathresult}% \pgfmath@smuggleone\pgfmathresult% \endgroup% } @@ -576,7 +576,7 @@ \begingroup% \FPmul\pgfmathresult{#1}{0.017453292519943295}% \FPsin\pgfmathresult{\pgfmathresult}% - \FPdiv\pgfmathresult{1}{\pgfmathresult} + \FPdiv\pgfmathresult{1}{\pgfmathresult}% \pgfmath@smuggleone\pgfmathresult% \endgroup% } diff --git a/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryfpu.code.tex b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryfpu.code.tex index dbaf9847cd1..00ce27705f8 100644 --- a/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryfpu.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryfpu.code.tex @@ -157,24 +157,13 @@ \expandafter\let\expandafter#1\csname pgfmathfloat@backup@\string#1\endcsname% }% } -\def\pgfmathfloat@prepareuninstallcmd@csname#1{% - % and store backup information (globally - I don't want to do that - % all the time when the FPU is used!): - {% - \globaldefs=1 - \pgfutil@namelet{pgfmathfloat@backup@#1}{#1}% - \expandafter\gdef\expandafter\pgfmathfloat@uninstall\expandafter{\pgfmathfloat@uninstall - \pgfutil@namelet{#1}{pgfmathfloat@backup@#1}% - }% - }% -} \def\pgfmathfloat@install#1=#2{% \pgfmathfloat@prepareuninstallcmd{#1}% \let#1=#2% } \def\pgfmathfloat@install@csname#1#2{% - \pgfmathfloat@prepareuninstallcmd@csname{#1}% + \expandafter\pgfmathfloat@prepareuninstallcmd\csname #1\endcsname% \pgfutil@namelet{#1}{#2}% } \def\pgfmathfloat@install@unimplemented#1{% @@ -213,8 +202,11 @@ \pgfmathfloat@install\pgfmathmultiply@=\pgfmathfloatmultiply@% \pgfmathfloat@install\pgfmathdivide@=\pgfmathfloatdivide@% \pgfmathfloat@install\pgfmathabs@=\pgfmathfloatabs@% + \pgfmathfloat@install\pgfmathsign@=\pgfmathfloatsign@% \pgfmathfloat@install\pgfmathround@=\pgfmathfloatround@% \pgfmathfloat@install\pgfmathfloor@=\pgfmathfloatfloor@% + \pgfmathfloat@install\pgfmathceil@=\pgfmathfloatceil@ + \pgfmathfloat@install\pgfmathint@=\pgfmathfloatint@ \pgfmathfloat@install\pgfmathmod@=\pgfmathfloatmod@% \pgfmathfloat@install\pgfmathmax@=\pgfmathfloatmax@% \pgfmathfloat@install\pgfmathmin@=\pgfmathfloatmin@% @@ -268,13 +260,12 @@ \pgfmathfloat@install\pgfmathcosh@=\pgfmathfloatcosh@ \pgfmathfloat@install\pgfmathsinh@=\pgfmathfloatsinh@ \pgfmathfloat@install\pgfmathtanh@=\pgfmathfloattanh@ - \pgfmathfloat@install@unimplemented{ceil}% + \expandafter\pgfmathfloat@install\csname pgfmathatan2@\endcsname=\pgfmathfloatatantwo@ \pgfmathfloat@install@unimplemented{frac}% \pgfmathfloat@install@unimplemented{random}% \pgfmathfloat@install@unimplemented{setseed}% \pgfmathfloat@install@unimplemented{Mod}% \pgfmathfloat@install@unimplemented{real}% -% \pgfmathfloat@install@unimplemented{atan2}% % \pgfmathfloat@install@unimplemented{height}% % % @@ -308,6 +299,21 @@ \pgfmathfloat@install\pgfmath@parse@exponent=\pgfmathfloat@parse@float@or@exponent % \pgfmathfloat@install\pgfmathparse=\pgfmathfloatparse% + %\pgfmathfloat@install\pgfmathparse@trynumber@token=\pgfmathfloat@parse@trynumber@token + \pgfmathfloat@install\pgfmathparse@expression@is@number=\pgfmathfloat@parse@expression@is@number +}% + +% This here might bring speed improvements... if implemented +% correctly. +% However, this heuristics might fail in cases like "1+1" vs "1e+1" ... +%\def\pgfmathfloat@parse@trynumber@token{numericfpu} +%\pgfmath@tokens@make{numericfpu}{eE+-Y.0123456789} + +\def\pgfmathfloat@parse@expression@is@number{% + \pgfmathfloatparsenumber{\pgfmath@expression}% + \pgfmath@smuggleone\pgfmathresult% + \endgroup + \ignorespaces }% \def\pgfmathfloat@defineadapter@for@pgf@two@null@null@ONEARG#1{% @@ -993,7 +999,7 @@ \if#2+% \pgfmathfloatifflags{#1}{1}{#3}{#4}% \else - \pgfmathfloatgetflagstomacro#1\pgfmathfloat@loc@TMPa + \pgfmathfloatgetflagstomacro{#1}\pgfmathfloat@loc@TMPa \if#2u% \ifnum\pgfmathfloat@loc@TMPa>2 #3\relax @@ -1424,8 +1430,24 @@ }% \def\pgfmathfloatint@@loop@gobble#1\pgfmathfloat@EOI{}% \let\pgfmathfloatint=\pgfmathfloatint@ -\let\pgfmathfloatfloor=\pgfmathfloatint -\let\pgfmathfloatfloor@=\pgfmathfloatint@ + +\def\pgfmathfloatfloor#1{% + \edef\pgfmathfloat@loc@TMPa{#1}% + \pgfmathfloatcreate{2}{5.0}{-1}% -0.5 + \let\pgfmathfloat@loc@TMPb=\pgfmathresult + \pgfmathfloatadd@{\pgfmathfloat@loc@TMPa}{\pgfmathfloat@loc@TMPb}% + \expandafter\pgfmathfloatround@\expandafter{\pgfmathresult}% +} +\let\pgfmathfloatfloor@=\pgfmathfloatfloor + +\def\pgfmathfloatceil#1{% + \edef\pgfmathfloat@loc@TMPa{#1}% + \pgfmathfloatcreate{1}{5.0}{-1}% +0.5 + \let\pgfmathfloat@loc@TMPb=\pgfmathresult + \pgfmathfloatadd@{\pgfmathfloat@loc@TMPa}{\pgfmathfloat@loc@TMPb}% + \expandafter\pgfmathfloatround@\expandafter{\pgfmathresult}% +} +\let\pgfmathfloatceil@=\pgfmathfloatceil \def\pgfmathfloat@notimplemented#1{% \pgfmath@error{Sorry, the operation '#1' has not yet been implemented in the floating point unit :-(}{}% @@ -1476,7 +1498,34 @@ \pgfmath@smuggleone\pgfmathresult \endgroup }% -\let\pgfmathfloatabs=\pgfmathfloatabs@ +% +% Defines \pgfmathresult to be sign(#1) +\def\pgfmathfloatsign@#1{% + \begingroup + \expandafter\pgfmathfloat@decompose@tok#1\relax\pgfmathfloat@a@S\pgfmathfloat@a@Mtok\pgfmathfloat@a@E + \ifcase\pgfmathfloat@a@S + % 0: + \pgfmathfloatcreate{0}{0.0}{0}% + \or + % +: ok, is positive. + \pgfmathfloatcreate{1}{1.0}{0}% + \or + % -: + \pgfmathfloatcreate{2}{1.0}{0}% + \or + % nan: do nothing. + \pgfmathfloatcreate{\the\pgfmathfloat@a@S}{\the\pgfmathfloat@a@Mtok}{\the\pgfmathfloat@a@E}% + \or + % +infty:. + \pgfmathfloatcreate{1}{1.0}{0}% + \or + % -infty: + \pgfmathfloatcreate{2}{1.0}{0}% + \fi + \pgfmath@smuggleone\pgfmathresult + \endgroup +}% +\let\pgfmathfloatsign=\pgfmathfloatsign@ % Computes the absolute error |#1 - #2| into \pgfmathresult. \def\pgfmathfloatabserror@#1#2{% @@ -1494,8 +1543,8 @@ \let\pgfmathresult=\pgfmathfloat@subtract }{% \pgfmathfloatdivide@{\pgfmathfloat@subtract}{#2}% - \pgfmathfloatabs@{\pgfmathresult}% }% + \pgfmathfloatabs@{\pgfmathresult}% }% \let\pgfmathfloatrelerror=\pgfmathfloatrelerror@ @@ -1567,14 +1616,27 @@ % % #1 is a one-argument macro which assigns \pgfmathresult. \def\pgfmathfloatTRIG@#1#2{% - \expandafter\ifx\csname pgfmathfloatTRIG@NUM\endcsname\relax% - % Lazy evaluation: - \pgfmathfloatcreate{1}{3.6}{2}% - \global\let\pgfmathfloatTRIG@NUM=\pgfmathresult - \pgfmathfloatcreate{1}{2.77777777777778}{-3}% - \global\let\pgfmathfloatTRIG@NUM@INV=\pgfmathresult + \if0\pgfmath@trig@format@choice + % trig format=deg + \expandafter\ifx\csname pgfmathfloatTRIG@NUM\endcsname\relax% + % Lazy evaluation: + \pgfmathfloatcreate{1}{3.6}{2}% + \global\let\pgfmathfloatTRIG@NUM=\pgfmathresult + \pgfmathfloatcreate{1}{2.77777777777778}{-3}% + \global\let\pgfmathfloatTRIG@NUM@INV=\pgfmathresult + \fi + \pgfmathfloatmodknowsinverse@{#2}{\pgfmathfloatTRIG@NUM}{\pgfmathfloatTRIG@NUM@INV}% + \else + % trig format=rad + \expandafter\ifx\csname pgfmathfloatTRIG@rad@NUM\endcsname\relax% + % Lazy evaluation: + \pgfmathfloatcreate{1}{6.28318530717959}{0}% + \global\let\pgfmathfloatTRIG@rad@NUM=\pgfmathresult + \pgfmathfloatcreate{1}{1.59154943091895}{-1}% + \global\let\pgfmathfloatTRIG@rad@NUM@INV=\pgfmathresult + \fi + \pgfmathfloatmodknowsinverse@{#2}{\pgfmathfloatTRIG@rad@NUM}{\pgfmathfloatTRIG@rad@NUM@INV}% \fi - \pgfmathfloatmodknowsinverse@{#2}{\pgfmathfloatTRIG@NUM}{\pgfmathfloatTRIG@NUM@INV}% \pgfmathfloattofixed@{\pgfmathresult}% \expandafter#1\expandafter{\pgfmathresult}% \pgfmathfloatparsenumber{\pgfmathresult}% @@ -1618,11 +1680,19 @@ \fi \pgfmathfloatgreaterthan@{#1}{\pgfmathfloatatan@TMP}% \ifpgfmathfloatcomparison - \pgfmathfloatcreate{1}{9.0}{1}% + \pgfmathiftrigonometricusesdeg{% + \pgfmathfloatcreate{1}{9.0}{1}% + }{% + \pgfmathfloatcreate{1}{1.570796326794}{0}% + }% \else \pgfmathfloatlessthan{#1}{\pgfmathfloatatan@TMPB}% \ifpgfmathfloatcomparison - \pgfmathfloatcreate{2}{9.0}{1}% + \pgfmathiftrigonometricusesdeg{% + \pgfmathfloatcreate{2}{9.0}{1}% + }{% + \pgfmathfloatcreate{2}{1.570796326794}{0}% + }% \else \pgfmathfloattofixed@{#1}% \expandafter\pgfmath@basic@atan@\expandafter{\pgfmathresult}% @@ -1634,6 +1704,76 @@ }% \let\pgfmathfloatatan=\pgfmathfloatatan@ +\def\pgfmathfloatatantwo#1#2{% + % Note: first parameter is y (!), second is x (!) + \begingroup% + \let\pgfmath@trig@format@choice@@=\pgfmath@trig@format@choice + \def\pgfmath@trig@format@choice{0}% + % + \expandafter\pgfmathfloat@decompose@tok#1\relax\pgfmathfloat@a@S\pgfmathfloat@a@Mtok\pgfmathfloat@a@E + \expandafter\pgfmathfloat@decompose#2\relax\pgfmathfloat@b@S\pgfmathfloat@b@M\pgfmathfloat@b@E + \ifnum\pgfmathfloat@a@S=0 + % ok, #1 = 0. Substitute by 1e-16 such that the next \ifnum catches it: + \pgfmathfloat@a@E=-16 % + \fi + % + \ifnum\pgfmathfloat@a@E<-3 % + \ifnum\pgfmathfloat@b@S=2 % + % #2 < 0 + \pgfmathfloatcreate{1}{1.8}{2}% +180 + \else + \ifnum\pgfmathfloat@b@S=1 % + % #2 >0 + \pgfmathfloatcreate{0}{0.0}{0}% + \else + % + or - 90, just use the sign of #1: + \pgfmathfloatcreate{\the\pgfmathfloat@a@S}{9.0}{1}% + \fi + \fi + \else% + \pgfmathfloatabs@{#1}\let\pgfmath@tempa\pgfmathresult% + \pgfmathfloatabs@{#2}\let\pgfmath@tempb\pgfmathresult% + \pgfmathfloatgreaterthan@{\pgfmath@tempa}{\pgfmath@tempb}% + \ifpgfmathfloatcomparison + \pgfmathfloatdivide@{#2}{\pgfmath@tempa}% + \expandafter\pgfmathfloatatan@\expandafter{\pgfmathresult}% + \let\pgfmath@tempa=\pgfmathresult + \pgfmathfloatcreate{1}{9.0}{1}% + \let\pgfmath@tempb=\pgfmathresult + \pgfmathfloatsubtract@{\pgfmath@tempb}{\pgfmath@tempa}% + \else% + \pgfmathfloatdivide@{\pgfmath@tempa}{#2}% + \expandafter\pgfmathfloatatan@\expandafter{\pgfmathresult}% + \expandafter\pgfmathfloatifflags\expandafter{\pgfmathresult}{2}{% + \let\pgfmath@tempa=\pgfmathresult + \pgfmathfloatcreate{1}{1.8}{2}% + \let\pgfmath@tempb=\pgfmathresult + \pgfmathfloatadd@{\pgfmath@tempa}{\pgfmath@tempb}% + }{}% + \fi% + % + \pgfmathfloatifflags{#1}{-}{% + % #1 < 0: + \pgfmathfloatmultiplyfixed@{\pgfmathresult}{-1}% + }{}% + \fi% + \if1\pgfmath@trig@format@choice@@ + % trig format=rad + \pgfmathfloat@scale@deg@to@rad\pgfmathresult + \fi + \pgfmath@smuggleone\pgfmathresult% + \endgroup% +}% +\let\pgfmathfloatatantwo@=\pgfmathfloatatantwo +\expandafter\let\csname pgfmathfloatatan2\endcsname=\pgfmathfloatatantwo +\expandafter\let\csname pgfmathfloatatan2@\endcsname=\pgfmathfloatatantwo@ + +\def\pgfmathfloat@scale@deg@to@rad#1{% + \edef\pgfmathfloat@loc@TMPb{#1}% + \pgfmathfloatcreate{1}{1.74532925199433}{-2}% = pi / 180 + \pgfmathfloatmultiply@{\pgfmathresult}{\pgfmathfloat@loc@TMPb}% +}% + \def\pgfmathfloatsec@#1{\pgfmathfloatTRIG@\pgfmath@basic@cos@{#1}\pgfmathfloatreciprocal@{\pgfmathresult}} \let\pgfmathfloatsec=\pgfmathfloatsec@ \def\pgfmathfloatcosec@#1{\pgfmathfloatTRIG@\pgfmath@basic@sin@{#1}\pgfmathfloatreciprocal@{\pgfmathresult}} @@ -1664,16 +1804,24 @@ \expandafter\def\csname pgfmathfloatlog10@\endcsname#1{% \pgfmathfloatln@{#1}% - \let\pgfmathfloat@log@ten=\pgfmathresult + \let\pgfmathfloat@log@e=\pgfmathresult \pgfmathfloatcreate{1}{4.34294481903252}{-1}% 1/ln(10) - \pgfmathfloatmultiply@{\pgfmathresult}{\pgfmathfloat@log@ten}% + \pgfmathfloatmultiply@{\pgfmathresult}{\pgfmathfloat@log@e}% }% +\pgfutil@namelet{pgfmathfloatlog10}{pgfmathfloatlog10@}% + \expandafter\def\csname pgfmathfloatlog2@\endcsname#1{% \pgfmathfloatln@{#1}% - \let\pgfmathfloat@log@two=\pgfmathresult + \let\pgfmathfloat@log@e=\pgfmathresult \pgfmathfloatcreate{1}{1.44269504088896}{0}% 1/ln(2) - \pgfmathfloatmultiply@{\pgfmathresult}{\pgfmathfloat@log@two}% + \pgfmathfloatmultiply@{\pgfmathresult}{\pgfmathfloat@log@e}% }% +\pgfutil@namelet{pgfmathfloatlog2}{pgfmathfloatlog2@}% + +\expandafter\let\expandafter\pgfmathfloatlogtwo\csname pgfmathfloatlog2\endcsname +\expandafter\let\expandafter\pgfmathfloatlogtwo@\csname pgfmathfloatlog2@\endcsname +\expandafter\let\expandafter\pgfmathfloatlogten\csname pgfmathfloatlog10\endcsname +\expandafter\let\expandafter\pgfmathfloatlogten@\csname pgfmathfloatlog10@\endcsname % Computes log(x) into \pgfmathresult. % diff --git a/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryintersections.code.tex b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryintersections.code.tex index b90e96c8b5a..41c0d1cdc19 100644 --- a/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryintersections.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryintersections.code.tex @@ -11,6 +11,8 @@ % Experimentally, it performed well while computing ~12 intersections of two % plots, each with 600 samples. It failed when the number of samples exceeded 700. +\usepgflibrary{fpu} + \newcount\pgf@intersect@solutions \newif\ifpgf@intersect@sort @@ -50,6 +52,9 @@ % % -> \first may be 0 if point #0 is in the 0'th segment % -> \second may be 42 if point #0 is in the 42'th segment +% +% The "segment index" is actually close to the "time" of the solution. +% If a solution is at "time" 42.2, it will have segment index 42. \def\pgfintersectiongetsolutionsegmentindices#1#2#3{% \ifnum#1<1\relax% \let#2=\pgfutil@empty @@ -59,8 +64,56 @@ \let#2=\pgfutil@empty \let#3=\pgfutil@empty \else% - \edef#2{\csname pgf@intersect@solution@segment@a@#1\endcsname}% - \edef#3{\csname pgf@intersect@solution@segment@b@#1\endcsname}% + \def\pgf@temp##1##2##3##4{% + \edef#2{##1}% + \edef#3{##2}% + }% + \expandafter\let\expandafter\pgf@tempb\csname pgf@intersect@solution@props@#1\endcsname + \expandafter\pgf@temp\pgf@tempb + \fi% + \fi% +}% + +% Gets the time indices of solution #1. +% +% #1: the solution index (i.e. the same argument as in \pgfpointintersectionsolution) +% #2: [output] a macro name which will contain the time of the first path which contains the solution +% It will never be empty. +% #3: [output] a macro name which will contain the time of the second path which contains the solution +% It will never be empty. +% +% Example: \pgfintersectiongetsolutiontimes{0}{\first}{\second} +% +% -> \first may be 0.5 if point #0 is in just in the middle of the path +% -> \second may be 42.8 if point #0 is in the 42'th segment (compare +% \pgfintersectiongetsolutionsegmentindices) and is at 80% of the +% 42'th segment +% +% Note that the precise time inside of a segment may be unavailable +% (currently, it is only computed for curveto paths and not +% necessarily for lineto). If the precise time is unavailable, this +% call will return the value of +% \pgfintersectiongetsolutionsegmentindices (which is a +% "coarse-grained" time). +\def\pgfintersectiongetsolutiontimes#1#2#3{% + \ifnum#1<1\relax% + \let#2=\pgfutil@empty + \let#3=\pgfutil@empty + \else% + \ifnum#1>\pgfintersectionsolutions\relax% + \let#2=\pgfutil@empty + \let#3=\pgfutil@empty + \else% + \def\pgf@temp##1##2##3##4{% + \edef#2{##3}% + \edef#3{##4}% + % + % check for fallback to segment indices: + \ifx#2\pgfutil@empty \edef#2{##1}\fi + \ifx#3\pgfutil@empty \edef#3{##2}\fi + }% + \expandafter\let\expandafter\pgf@tempb\csname pgf@intersect@solution@props@#1\endcsname + \expandafter\pgf@temp\pgf@tempb \fi% \fi% }% @@ -100,7 +153,7 @@ \let\pgf@intersect@path@b=\pgf@intersect@path@temp% % \pgf@intersect@solutions=0\relax% - \def\pgf@intersect@time@offset{0}% + \pgf@intersect@path@reset@a % \ifpgf@intersect@sort@by@second@path% \let\pgf@intersect@temp=\pgf@intersect@path@a% @@ -119,7 +172,7 @@ \else% \pgfutil@namelet{pgfpoint@intersect@solution@\pgfmathcounter}% {pgfpoint@g@intersect@solution@\pgfmathcounter}% - \edef\pgf@marshal{\noexpand\pgf@intersection@set@properties\csname pgfpoint@g@intersect@solution@\pgfmathcounter @props\endcsname}% + \edef\pgf@marshal{\noexpand\pgf@intersection@set@properties{\csname pgfpoint@g@intersect@solution@\pgfmathcounter @props\endcsname}}% \pgf@marshal \ifpgf@intersect@sort% \pgfutil@namelet{pgf@intersect@solution@\pgfmathcounter @time@a}% @@ -131,15 +184,28 @@ \fi% } -\def\pgf@intersection@set@properties#1#2{% - \pgfutil@namedef{pgf@intersect@solution@segment@a@\pgfmathcounter}{#1}% - \pgfutil@namedef{pgf@intersect@solution@segment@b@\pgfmathcounter}{#2}% +\def\pgf@intersection@set@properties#1{% + \pgfutil@namedef{pgf@intersect@solution@props@\pgfmathcounter}{#1}% }% % #1 a global name prefix to store properties. \def\pgf@intersection@store@properties#1{% % we store the time offsets as well and make them available programmatically: - \expandafter\xdef\csname #1@props\endcsname{{\pgf@intersect@time@offset}{\pgf@intersect@time@offset@b}}% + % note that \pgf@intersect@time@a and \pgf@intersect@time@b may be empty. + % + % However, \pgf@intersect@time@offset and + % \pgf@intersect@time@offset@b are *always* valid. In fact,they + % resemble a part of the time: it holds + % 0 <= \pgf@intersect@time@a < 1 + % and \pgf@intersect@time@offset > 0. + % + % If we have an intersection in segment 42 of path A, + % \pgf@intersect@time@offset will be 42. The time inside of that + % segment is given as number in the interval [0,1]. If it is 0.3, + % the total time will be 42.3 and that number will be stored as + % \pgf@intersect@time@a. + % + \expandafter\xdef\csname #1@props\endcsname{{\pgf@intersect@time@offset}{\pgf@intersect@time@offset@b}{\pgf@intersect@time@a}{\pgf@intersect@time@b}}% } \def\pgf@intersectionofpaths#1{% @@ -204,7 +270,7 @@ \def\pgf@intersect@path@process@a{% \pgf@intersect@path@getpoints@a% \let\pgf@intersect@token@after=\pgf@intersect@path@process@b% - \def\pgf@intersect@time@offset@b{0}% + \pgf@intersect@path@reset@b \expandafter\pgf@intersectionofpaths\pgf@intersect@path@b\pgf@stop% \let\pgfpoint@intersect@start=\pgfpoint@intersect@end@a% \let\pgf@intersect@token@after=\pgf@intersect@path@process@a% @@ -214,6 +280,16 @@ \pgf@intersectionofpaths% } +\def\pgf@intersect@path@reset@a{% + \def\pgf@intersect@time@offset{0}% + \def\pgf@intersect@time@a{}% +}% + +\def\pgf@intersect@path@reset@b{% + \def\pgf@intersect@time@offset@b{0}% + \def\pgf@intersect@time@b{}% +}% + \def\pgf@intersect@path@getpoints@a{% \let\pgfpoint@intersect@start@a=\pgfpoint@intersect@start% \let\pgfpoint@intersect@end@a=\pgfpoint@intersect@end% @@ -275,33 +351,43 @@ \def\pgf@intersectionoflines#1#2#3#4{% \pgf@iflinesintersect{#1}{#2}{#3}{#4}% {% - \global\advance\pgf@intersect@solutions by1\relax% - \expandafter\pgfextract@process\csname pgfpoint@g@intersect@solution@\the\pgf@intersect@solutions\endcsname{% + \pgfextract@process\pgf@intersect@solution@candidate{% \pgfpointintersectionoflines{\pgfpoint@intersect@start@a}{\pgfpoint@intersect@end@a}% {\pgfpoint@intersect@start@b}{\pgfpoint@intersect@end@b}% }% - \pgf@intersection@store@properties{pgfpoint@g@intersect@solution@\the\pgf@intersect@solutions}% + \pgf@ifsolution@duplicate{\pgf@intersect@solution@candidate}{% + % ah - we a duplicate. Apparently, we have a hit on an + % endpoint. + }{% + \global\advance\pgf@intersect@solutions by1\relax% + \expandafter\global\expandafter\let\csname pgfpoint@g@intersect@solution@\the\pgf@intersect@solutions\endcsname=\pgf@intersect@solution@candidate + \ifpgf@intersect@sort% + \pgf@xc=\pgf@x% + \pgf@yc=\pgf@y% + \pgf@process{\pgfpointdiff{\pgfpoint@intersect@start@a}{\pgfpoint@intersect@end@a}}% + \edef\pgf@marshal{% + \noexpand\pgfmathveclen@{\pgfmath@tonumber{\pgf@xa}}{\pgfmath@tonumber{\pgf@ya}}% + }% + \pgf@marshal% + \let\pgf@intersect@length@a=\pgfmathresult% + \pgf@process{\pgfpointdiff{\pgfpoint@intersect@start@a}{\pgfqpoint{\pgf@xc}{\pgf@yc}}}% + \edef\pgf@marshal{% + \noexpand\pgfmathveclen@{\pgfmath@tonumber{\pgf@x}}{\pgfmath@tonumber{\pgf@y}}% + }% + \pgf@marshal% + \pgfmathdivide@{\pgfmathresult}{\pgf@intersect@length@a}% + \pgf@x=\pgfmathresult pt\relax% + \advance\pgf@x by\pgf@intersect@time@offset pt\relax% + \edef\pgf@intersect@time@a{\pgfmath@tonumber{\pgf@x}}% + \expandafter\global\expandafter\let\csname pgf@g@intersect@solution@\the\pgf@intersect@solutions @time@a\endcsname= + \pgf@intersect@time@a + \else + \let\pgf@intersect@time@a=\pgfutil@empty + \fi% + \let\pgf@intersect@time@b=\pgfutil@empty + \pgf@intersection@store@properties{pgfpoint@g@intersect@solution@\the\pgf@intersect@solutions}% + }% % - \ifpgf@intersect@sort% - \pgf@xc=\pgf@x% - \pgf@yc=\pgf@y% - \pgf@process{\pgfpointdiff{\pgfpoint@intersect@start@a}{\pgfpoint@intersect@end@a}}% - \edef\pgf@marshal{% - \noexpand\pgfmathveclen@{\pgfmath@tonumber{\pgf@xa}}{\pgfmath@tonumber{\pgf@ya}}% - }% - \pgf@marshal% - \let\pgf@intersect@length@a=\pgfmathresult% - \pgf@process{\pgfpointdiff{\pgfpoint@intersect@start@a}{\pgfqpoint{\pgf@xc}{\pgf@yc}}}% - \edef\pgf@marshal{% - \noexpand\pgfmathveclen@{\pgfmath@tonumber{\pgf@x}}{\pgfmath@tonumber{\pgf@y}}% - }% - \pgf@marshal% - \pgfmathdivide@{\pgfmathresult}{\pgf@intersect@length@a}% - \pgf@x=\pgfmathresult pt\relax% - \advance\pgf@x by\pgf@intersect@time@offset pt\relax% - \expandafter\xdef\csname pgf@g@intersect@solution@\the\pgf@intersect@solutions @time@a\endcsname% - {\pgfmath@tonumber{\pgf@x}}% - \fi% }{}% } @@ -572,6 +658,8 @@ \pgf@intersect@boundingbox@update{#2}% \pgf@intersect@boundingbox@update{#3}% \pgf@intersect@boundingbox@update{#4}% + % (\pgf@xa, \pgf@ya) is lower-left + % (\pgf@xb, \pgf@yb) is upper-right \edef\pgf@intersect@boundingbox@b{% \noexpand\pgf@x=\the\pgf@xa% \noexpand\pgf@y=\the\pgf@ya% @@ -591,6 +679,7 @@ }% \pgf@intersect@boundingbox@a% \pgf@intersect@boundingbox@b% + % check if the two bounding boxes overlap: \ifdim\pgf@xa<\pgf@xb% \else% \ifdim\pgf@x>\pgf@xc% @@ -599,16 +688,21 @@ \else% \ifdim\pgf@y>\pgf@yc% \else% + % compute DIFFERENCE vectors: \advance\pgf@xc by-\pgf@xb% \advance\pgf@yc by-\pgf@yb% \advance\pgf@xa by-\pgf@x% \advance\pgf@ya by-\pgf@y% \let\pgf@intersect@subdivde=\relax% + % check if both difference vectors are point wise + % less than tolerance (i.e. |v|_infty < eps ). + % That means that both bounding boxes are "small enough" \ifdim\pgf@xc<\pgfintersectiontolerance\relax% \ifdim\pgf@xa<\pgfintersectiontolerance\relax% \ifdim\pgf@yc<\pgfintersectiontolerance\relax% \ifdim\pgf@ya<\pgfintersectiontolerance\relax% \pgfextract@process\pgf@intersect@solution@candidate{% + % set (x,y) = mean(the 4 points of the two bounding boxes): \pgf@intersect@boundingbox@a% \pgf@intersect@boundingbox@b% \pgf@x=0.25\pgf@x% @@ -625,20 +719,27 @@ \pgf@ifsolution@duplicate\pgf@intersect@solution@candidate{}% {% \global\advance\pgf@intersect@solutions by1\relax% + \begingroup + \advance\pgf@time@a by\pgf@time@aa% + \divide\pgf@time@a by2\relax% + \advance\pgf@time@a by\pgf@intersect@time@offset pt\relax% + \edef\pgf@intersect@time@a{\pgfmath@tonumber{\pgf@time@a}}% + % + \advance\pgf@time@b by\pgf@time@bb% + \divide\pgf@time@b by2\relax% + \advance\pgf@time@b by\pgf@intersect@time@offset@b pt\relax% + \edef\pgf@intersect@time@b{\pgfmath@tonumber{\pgf@time@b}}% + % \pgf@intersection@store@properties{pgfpoint@g@intersect@solution@\the\pgf@intersect@solutions}% \expandafter\global\expandafter\let% \csname pgfpoint@g@intersect@solution@\the\pgf@intersect@solutions\endcsname=% \pgf@intersect@solution@candidate% - {% - \ifpgf@intersect@sort% - \advance\pgf@time@a by\pgf@time@aa% - \divide\pgf@time@a by2\relax% - \advance\pgf@time@a by\pgf@intersect@time@offset pt\relax% - \expandafter\xdef% - \csname pgf@g@intersect@solution@\the\pgf@intersect@solutions @time@a\endcsname% - {\pgfmath@tonumber{\pgf@time@a}}% - \fi% - }% + \ifpgf@intersect@sort% + \expandafter\xdef% + \csname pgf@g@intersect@solution@\the\pgf@intersect@solutions @time@a\endcsname% + {\pgf@intersect@time@a}% + \fi% + \endgroup }% \fi% \fi% @@ -699,33 +800,74 @@ \ifdim\pgf@y>\pgf@yb\pgf@yb=\pgf@y\fi% } +% The following subroutines are part of a conversion from pgfbasic +% math to FPU. This transition is necessary due to the restricted +% accuracy of pgfbasic. In order to limit the error rate of the +% transition pgfbasic -> FPU, I chose to +% keep the old "pattern" of sorts \advance\pgf@xa by0.5\pgf@y etc and +% simply adapt to some FPU call. +% +% The following routines constitute the "adapter": + +\def\pgf@float@adapter@setxy{% + \pgfmathfloatparsenumber{\pgf@sys@tonumber\pgf@x}\let\pgf@fpu@x=\pgfmathresult + \pgfmathfloatparsenumber{\pgf@sys@tonumber\pgf@y}\let\pgf@fpu@y=\pgfmathresult +}% +\def\pgf@float@adapter@mult#1=#2*#3{% + \pgfmathfloatmultiplyfixed@{#3}{#2}% + \let#1=\pgfmathresult +}% +\def\pgf@float@adapter@advance#1by#2*#3{% + \pgfmathfloatmultiplyfixed@{#3}{#2}% + \let\pgfutil@temp=\pgfmathresult + \pgfmathfloatadd@{#1}{\pgfutil@temp}% + \let#1=\pgfmathresult +}% + +\def\pgf@float@adapter@tostring#1{% + \pgfmathfloattofixed{#1}\edef#1{\pgfmathresult pt }% +}% \def\pgf@curve@subdivide@left#1#2#3#4{% % % The left curve (from t=0 to t=.5) % + \begingroup #1\relax% \pgfutil@tempdima=\pgf@x% \pgfutil@tempdimb=\pgf@y% - \pgf@xa=.5\pgf@x\pgf@ya=.5\pgf@y% - \pgf@xb=.25\pgf@x\pgf@yb=.25\pgf@y% - \pgf@xc=.125\pgf@x\pgf@yc=.125\pgf@y% + \pgf@float@adapter@setxy + \pgf@float@adapter@mult\pgf@fpu@xa=.5*\pgf@fpu@x \pgf@float@adapter@mult\pgf@fpu@ya=.5*\pgf@fpu@y% + \pgf@float@adapter@mult\pgf@fpu@xb=.25*\pgf@fpu@x \pgf@float@adapter@mult\pgf@fpu@yb=.25*\pgf@fpu@y% + \pgf@float@adapter@mult\pgf@fpu@xc=.125*\pgf@fpu@x\pgf@float@adapter@mult\pgf@fpu@yc=.125*\pgf@fpu@y% #2\relax% - \advance\pgf@xa by.5\pgf@x\advance\pgf@ya by.5\pgf@y% - \advance\pgf@xb by.5\pgf@x\advance\pgf@yb by.5\pgf@y% - \advance\pgf@xc by.375\pgf@x\advance\pgf@yc by.375\pgf@y% + \pgf@float@adapter@setxy + \pgf@float@adapter@advance\pgf@fpu@xa by.5*\pgf@fpu@x\pgf@float@adapter@advance\pgf@fpu@ya by.5*\pgf@fpu@y% + \pgf@float@adapter@advance\pgf@fpu@xb by.5*\pgf@fpu@x\pgf@float@adapter@advance\pgf@fpu@yb by.5*\pgf@fpu@y% + \pgf@float@adapter@advance\pgf@fpu@xc by.375*\pgf@fpu@x\pgf@float@adapter@advance\pgf@fpu@yc by.375*\pgf@fpu@y% #3\relax% - \advance\pgf@xb by.25\pgf@x\advance\pgf@yb by.25\pgf@y% - \advance\pgf@xc by.375\pgf@x\advance\pgf@yc by.375\pgf@y% + \pgf@float@adapter@setxy + \pgf@float@adapter@advance\pgf@fpu@xb by.25*\pgf@fpu@x\pgf@float@adapter@advance\pgf@fpu@yb by.25*\pgf@fpu@y% + \pgf@float@adapter@advance\pgf@fpu@xc by.375*\pgf@fpu@x\pgf@float@adapter@advance\pgf@fpu@yc by.375*\pgf@fpu@y% #4\relax% - \advance\pgf@xc by.125\pgf@x\advance\pgf@yc by.125\pgf@y% + \pgf@float@adapter@setxy + \pgf@float@adapter@advance\pgf@fpu@xc by.125*\pgf@fpu@x\pgf@float@adapter@advance\pgf@fpu@yc by.125*\pgf@fpu@y% + % + \pgf@float@adapter@tostring\pgf@fpu@xa + \pgf@float@adapter@tostring\pgf@fpu@ya + \pgf@float@adapter@tostring\pgf@fpu@xb + \pgf@float@adapter@tostring\pgf@fpu@yb + \pgf@float@adapter@tostring\pgf@fpu@xc + \pgf@float@adapter@tostring\pgf@fpu@yc \edef\pgf@marshal{% \noexpand\pgf@curve@subdivde@after% {\noexpand\pgf@x=\the\pgfutil@tempdima\noexpand\pgf@y=\the\pgfutil@tempdimb}% - {\noexpand\pgf@x=\the\pgf@xa\noexpand\pgf@y\the\pgf@ya}% - {\noexpand\pgf@x=\the\pgf@xb\noexpand\pgf@y=\the\pgf@yb} - {\noexpand\pgf@x=\the\pgf@xc\noexpand\pgf@y=\the\pgf@yc}% + {\noexpand\pgf@x=\pgf@fpu@xa\noexpand\pgf@y=\pgf@fpu@ya}% + {\noexpand\pgf@x=\pgf@fpu@xb\noexpand\pgf@y=\pgf@fpu@yb} + {\noexpand\pgf@x=\pgf@fpu@xc\noexpand\pgf@y=\pgf@fpu@yc}% }% + \expandafter + \endgroup \pgf@marshal% } @@ -733,26 +875,43 @@ % % The right curve (from t=0.5 to t=1) % + \begingroup #1\relax% - \pgfutil@tempdima=.125\pgf@x\pgfutil@tempdimb=.125\pgf@y% + \pgf@float@adapter@setxy + \pgf@float@adapter@mult\pgf@float@tmpa=.125*\pgf@fpu@x\pgf@float@adapter@mult\pgf@float@tmpb=.125*\pgf@fpu@y% #2\relax% - \advance\pgfutil@tempdima by.375\pgf@x\advance\pgfutil@tempdimb by.375\pgf@y% - \pgf@xa=.25\pgf@x\pgf@ya=.25\pgf@y% + \pgf@float@adapter@setxy + \pgf@float@adapter@advance\pgf@float@tmpa by.375*\pgf@fpu@x\pgf@float@adapter@advance\pgf@float@tmpb by.375*\pgf@fpu@y% + \pgf@float@adapter@mult\pgf@fpu@xa=.25*\pgf@fpu@x\pgf@float@adapter@mult\pgf@fpu@ya=.25*\pgf@fpu@y% #3\relax% - \advance\pgfutil@tempdima by.375\pgf@x\advance\pgfutil@tempdimb by.375\pgf@y% - \advance\pgf@xa by.5\pgf@x\advance\pgf@ya by.5\pgf@y% - \pgf@xb=.5\pgf@x\pgf@yb=.5\pgf@y% + \pgf@float@adapter@setxy + \pgf@float@adapter@advance\pgf@float@tmpa by.375*\pgf@fpu@x\pgf@float@adapter@advance\pgf@float@tmpb by.375*\pgf@fpu@y% + \pgf@float@adapter@advance\pgf@fpu@xa by.5*\pgf@fpu@x\pgf@float@adapter@advance\pgf@fpu@ya by.5*\pgf@fpu@y% + \pgf@float@adapter@mult\pgf@fpu@xb=.5*\pgf@fpu@x\pgf@float@adapter@mult\pgf@fpu@yb=.5*\pgf@fpu@y% #4\relax% - \advance\pgfutil@tempdima by.125\pgf@x\advance\pgfutil@tempdimb by.125\pgf@y% - \advance\pgf@xa by.25\pgf@x\advance\pgf@ya by.25\pgf@y% - \advance\pgf@xb by.5\pgf@x\advance\pgf@yb by.5\pgf@y% - \pgf@xc=\pgf@x\pgf@yc=\pgf@y% + \pgf@float@adapter@setxy + \pgf@float@adapter@advance\pgf@float@tmpa by.125*\pgf@fpu@x\pgf@float@adapter@advance\pgf@float@tmpb by.125*\pgf@fpu@y% + \pgf@float@adapter@advance\pgf@fpu@xa by.25*\pgf@fpu@x\pgf@float@adapter@advance\pgf@fpu@ya by.25*\pgf@fpu@y% + \pgf@float@adapter@advance\pgf@fpu@xb by.5*\pgf@fpu@x\pgf@float@adapter@advance\pgf@fpu@yb by.5*\pgf@fpu@y% + \let\pgf@fpu@xc=\pgf@fpu@x\let\pgf@fpu@yc=\pgf@fpu@y% + % + \pgf@float@adapter@tostring\pgf@float@tmpa + \pgf@float@adapter@tostring\pgf@float@tmpb + \pgf@float@adapter@tostring\pgf@fpu@xa + \pgf@float@adapter@tostring\pgf@fpu@ya + \pgf@float@adapter@tostring\pgf@fpu@xb + \pgf@float@adapter@tostring\pgf@fpu@yb + \pgf@float@adapter@tostring\pgf@fpu@xc + \pgf@float@adapter@tostring\pgf@fpu@yc \edef\pgf@marshal{% \noexpand\pgf@curve@subdivde@after% - {\pgf@x\the\pgfutil@tempdima\pgf@y\the\pgfutil@tempdimb}% - {\pgf@x\the\pgf@xa\pgf@y\the\pgf@ya}{\pgf@x\the\pgf@xb\pgf@y\the\pgf@yb} - {\pgf@x\the\pgf@xc\pgf@y\the\pgf@yc}% + {\noexpand\pgf@x=\pgf@float@tmpa\noexpand\pgf@y=\pgf@float@tmpb}% + {\noexpand\pgf@x=\pgf@fpu@xa\noexpand\pgf@y=\pgf@fpu@ya} + {\noexpand\pgf@x=\pgf@fpu@xb\noexpand\pgf@y=\pgf@fpu@yb} + {\noexpand\pgf@x=\pgf@fpu@xc\noexpand\pgf@y=\pgf@fpu@yc}% }% + \expandafter + \endgroup \pgf@marshal% } @@ -773,23 +932,26 @@ \pgfmathloop% \ifnum\pgfmathcounter>\pgf@intersect@solutions\relax% \else% - \pgf@process{\csname pgfpoint@g@intersect@solution@\pgfmathcounter\endcsname}% - \advance\pgf@x by-\pgf@xa% - \advance\pgf@y by-\pgf@ya% - \ifdim\pgf@x<0pt\relax\pgf@x=-\pgf@x\fi% - \ifdim\pgf@y<0pt\relax\pgf@y=-\pgf@y\fi% - % - \pgf@x=\pgfintersectiontolerancefactor\pgf@x% - \pgf@y=\pgfintersectiontolerancefactor\pgf@y% - \ifdim\pgf@x<\pgfintersectiontolerance\relax% - \ifdim\pgf@y<\pgfintersectiontolerance\relax% - \let\pgf@intersect@next=\pgfutil@firstoftwo% - \fi% - \fi% + \pgf@ifsolution@duplicate@{\pgfmathcounter}% \repeatpgfmathloop% \pgf@intersect@next% } +\def\pgf@ifsolution@duplicate@#1{% + \pgf@process{\csname pgfpoint@g@intersect@solution@#1\endcsname}% + \advance\pgf@x by-\pgf@xa% + \advance\pgf@y by-\pgf@ya% + \ifdim\pgf@x<0pt\relax\pgf@x=-\pgf@x\fi% + \ifdim\pgf@y<0pt\relax\pgf@y=-\pgf@y\fi% + % + \pgf@x=\pgfintersectiontolerancefactor\pgf@x% + \pgf@y=\pgfintersectiontolerancefactor\pgf@y% + \ifdim\pgf@x<\pgfintersectiontolerance\relax% + \ifdim\pgf@y<\pgfintersectiontolerance\relax% + \let\pgf@intersect@next=\pgfutil@firstoftwo% + \fi% + \fi% +}% \newif\ifpgf@intersect@solutions@sortfinish @@ -798,8 +960,7 @@ \def\pgfintersectionsolutionsortbytime{% \pgf@intersect@solutions@sortfinishtrue% \pgfmathloop% - \ifnum\pgfmathcounter=\pgfintersectionsolutions\relax% - \else% + \ifnum\pgfmathcounter<\pgfintersectionsolutions\relax% \pgfutil@tempcnta=\pgfmathcounter% \advance\pgfutil@tempcnta by1\relax% \ifdim\csname pgf@intersect@solution@\pgfmathcounter @time@a\endcsname pt>% @@ -812,10 +973,8 @@ \pgfintersectionsolutionsortbytime@swap{pgf@intersect@solution@\pgfmathcounter @time@a}% {pgf@intersect@solution@\the\pgfutil@tempcnta @time@a}% % - \pgfintersectionsolutionsortbytime@swap{pgf@intersect@solution@segment@a@\pgfmathcounter}% - {pgf@intersect@solution@segment@a@\the\pgfutil@tempcnta}% - \pgfintersectionsolutionsortbytime@swap{pgf@intersect@solution@segment@b@\pgfmathcounter}% - {pgf@intersect@solution@segment@b@\the\pgfutil@tempcnta}% + \pgfintersectionsolutionsortbytime@swap{pgf@intersect@solution@props@\pgfmathcounter}% + {pgf@intersect@solution@props@\the\pgfutil@tempcnta}% \fi% \repeatpgfmathloop% \ifpgf@intersect@solutions@sortfinish% diff --git a/Master/texmf-dist/tex/generic/pgf/libraries/pgflibrarypatterns.meta.code.tex b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibrarypatterns.meta.code.tex new file mode 100644 index 00000000000..467fa1fee46 --- /dev/null +++ b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibrarypatterns.meta.code.tex @@ -0,0 +1,266 @@ +% Copyright 2015 by Mark Wibrow +% +% 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. + +\def\pgf@pat@type@uncolored{0} +\def\pgf@pat@type@colored{1} +\newif\ifpgf@pat@makepatternimmutable + +\pgfkeys{/pgf/patterns/.cd, + name/.store in=\pgf@pat@name, + number ../.store in=\pgf@pat@number, + type/.is choice, + type/uncolored/.code={\let\pgf@pat@type=\pgf@pat@type@uncolored}, + type/colored/.code={\let\pgf@pat@type=\pgf@pat@type@colored}, + type/form only/.style={/pgf/patterns/type=uncolored}, + type/inherently colored/.style={/pgf/patterns/type=colored}, + x/.store in=\pgf@pat@xvec, + y/.store in=\pgf@pat@yvec, + parameters/.store in=\pgf@pat@parameters, + defaults/.store in=\pgf@pat@defaults, + append to defaults/.code={% + \pgf@pat@addto@macro\pgf@pat@defaults{,#1}% + }, + bottom left/.store in=\pgf@pat@bottomleft, + top right/.store in=\pgf@pat@topright, + tile size/.store in=\pgf@pat@tilesize, + tile transformation/.store in=\pgf@pat@transformation, + code/.store in=\pgf@pat@code, + set up code/.store in=\pgf@pat@declarebefore, + % + name=, + number ..=, + type=uncolored, + x=1cm, y=1cm, + parameters=, + defaults=, + bottom left=\pgfpointorigin, + top right=\pgfpointorigin, + tile size=\pgfpointorigin, + tile transformation=, + code=, + set up code=, +} + +\def\pgf@pat@name@prefix{pgf@pattern@name@meta@} + +\def\pgfifpatternundefined#1{% + \pgfutil@ifundefined{\pgf@pat@name@prefix#1}% +} + +\def\pgf@pat@adddef@to@macro#1#2{% + \expandafter\expandafter\expandafter\def% + \expandafter\expandafter\expandafter#1% + \expandafter\expandafter\expandafter{\expandafter#1\expandafter% + \def\expandafter#2\expandafter{#2}}% +} + +\def\pgf@pat@addto@macro#1#2{% + \expandafter\def\expandafter#1\expandafter{#1#2}}% + +\def\pgf@pat@process#1{% + \pgf@process{#1}% +} + +\def\pgf@pat@doifnotempty#1{% + \ifx#1\pgfutil@empty% + \let\pgf@pat@next=\relax% + \else% + \let\pgf@pat@next=#1% + \fi% + \pgf@pat@next% +} + +\def\pgf@pat@processtransformations#1{#1} +\def\pgf@pat@processpoint#1{% + \pgf@process{#1}% +} + + +\def\pgfdeclarepattern#1{% + \begingroup% + \nullfont% + \def\pgf@pat@options{#1}% + \pgfkeys{/pgf/patterns/.cd, #1}% + \pgf@declarepattern% + \endgroup% +} +\def\pgf@declarepattern{% + \pgfifpatternundefined{\pgf@pat@name}{% + \ifx\pgf@pat@parameters\pgfutil@empty% + % No parameters, so pattern is declared now. + \pgf@pat@declare% + \edef\pgf@marshal{% + \noexpand\pgf@pat@addto@macro\noexpand\pgf@pat@options{,number ..=\pgf@pattern@number}}% + \pgf@marshal% + \fi% + % It is a bit inefficient that all the options for + % immutable patterns are saved when only the type + % and number are needed. + \expandafter\global\expandafter\let\csname\pgf@pat@name@prefix\pgf@pat@name\endcsname=\pgf@pat@options% + }{% + \pgferror{Pattern `\pgf@pat@name' already defined}% + }% +} +\let\pgf@pat@declarebefore=\pgfutil@empty +\let\pgf@pat@declareafter=\pgfutil@empty +\let\pgf@pat@codebefore=\pgfutil@empty +\let\pgf@pat@codeafter=\pgfutil@empty + +\def\pgf@pat@declare{% + \pgfsysprotocol@getcurrentprotocol\pgf@pattern@temp% + {% + % Set up x and y vectors. Should use a scope rather than TeX group? + % Vectors may be needed when the tile bounding box is + % calculated. + \pgfsetxvec{\pgfpoint{\pgf@pat@xvec}{+0pt}}% + \pgfsetyvec{\pgfpoint{+0pt}{\pgf@pat@yvec}}% + \pgf@pat@doifnotempty\pgf@pat@declarebefore% + \pgfinterruptpath% + \pgfpicturetrue% + \pgf@relevantforpicturesizetrue% + \pgftransformreset% + \pgfsysprotocol@setcurrentprotocol\pgfutil@empty% + \pgfsysprotocol@bufferedtrue% + \pgfsys@beginscope% + \pgfinterruptboundingbox% + \pgfsetarrows{-}% + \pgf@pat@doifnotempty\pgf@pat@codebefore + \pgf@pat@code% + \pgf@pat@doifnotempty\pgf@pat@codeafter% + \pgfsys@endscope% + \endpgfinterruptboundingbox% + \pgfsysprotocol@getcurrentprotocol\pgf@pattern@code% + \global\let\pgf@pattern@code=\pgf@pattern@code% + \endpgfinterruptpath% + \pgf@pat@doifnotempty\pgf@pat@declareafter% + \pgf@pat@processpoint{\pgf@pat@bottomleft}% + \pgf@xa=\pgf@x% + \pgf@ya=\pgf@y% + \pgf@pat@processpoint{\pgf@pat@topright}% + \pgf@xb=\pgf@x% + \pgf@yb=\pgf@y% + \pgf@pat@processpoint{\pgf@pat@tilesize}% + \pgf@xc=\pgf@x% + \pgf@yc=\pgf@y% + \begingroup% + \pgftransformreset% + \pgf@pat@processtransformations\pgf@pat@transformation% + \pgfgettransformentries\aa\ab\ba\bb\shiftx\shifty% + \global\edef\pgf@pattern@matrix{{\aa}{\ab}{\ba}{\bb}{\shiftx}{\shifty}}% + \endgroup% + % Now, build a name for the pattern + \pgfutil@tempcnta=\pgf@pattern@number\relax% + \advance\pgfutil@tempcnta by1\relax% + \xdef\pgf@pattern@number{\the\pgfutil@tempcnta}% + \xdef\pgf@marshal{\noexpand\pgfsys@declarepattern@meta% + {\pgf@pattern@number}% + {\the\pgf@xa}{\the\pgf@ya}{\the\pgf@xb}{\the\pgf@yb}{\the\pgf@xc}{\the\pgf@yc}\pgf@pattern@matrix{\pgf@pattern@code}{\pgf@pat@type}}% + }% + \pgf@marshal% + \pgfsysprotocol@setcurrentprotocol\pgf@pattern@temp% + } + +\def\pgf@pat@checkname#1{% + \pgf@pat@@checkname#1[]\pgf@patstop} + +\def\pgf@pat@@checkname#1[#2]#3\pgf@patstop{% + \def\pgf@pat@onlinename{#1}% + \def\pgf@pat@onlineoptions{#2}% +} + + +\def\pgf@pat@unravel#1/{% + \pgfutil@ifnextchar\pgf@stop{\def\pgf@pat@unravelled{#1}}{\pgf@pat@unravel}} + +\pgfkeys{/handlers/.pattern/.code={% + \expandafter\expandafter\expandafter\pgf@pat@unravel\pgfkeyscurrentpath/\pgf@stop% + \pgfpatternalias{#1}{\pgf@pat@unravelled}% +}} + +\def\pgfpatternalias#1#2{% + \begingroup% + \pgf@pat@checkname{#1}% + \expandafter\let\expandafter\pgf@pat@options\expandafter=% + \csname\pgf@pat@name@prefix\pgf@pat@onlinename\endcsname% + \pgf@pat@macroaskeys{/pgf/patterns/.cd}{\pgf@pat@options}% + \pgfutil@toks@\expandafter{\pgf@pat@onlineoptions}% + \edef\pgf@pat@tmp{append to defaults={\the\pgfutil@toks@}}% + \expandafter\pgf@pat@addto@macro\expandafter\pgf@pat@options\expandafter{\expandafter,\pgf@pat@tmp}% + \pgf@pat@addto@macro\pgf@pat@options{,name=#2}% + \expandafter\global\expandafter\let\csname\pgf@pat@name@prefix#2\endcsname=\pgf@pat@options% + \endgroup% +} + + +\let\pgfsetfillpattern@old=\pgfsetfillpattern + +\def\pgf@pat@macroaskeys#1#2{% + \pgfutil@toks@\expandafter{#2}% + \edef\pgf@marshal{\noexpand\pgfkeys{#1, \the\pgfutil@toks@}}% + \pgf@marshal% +} +\def\pgfsetfillpattern#1#2{% + \pgf@pat@checkname{#1}% + \pgfutil@ifundefined{\pgf@pat@name@prefix\pgf@pat@onlinename}{% + \pgfsetfillpattern@old{\pgf@pat@onlinename}{#2}% + }{% + \let\pgf@pat@parameters=\pgfutil@empty% + % Get pattern parameters, type, and number + \expandafter\let\expandafter\pgf@pat@options\expandafter=% + \csname\pgf@pat@name@prefix\pgf@pat@onlinename\endcsname% + \pgf@pat@macroaskeys{/pgf/patterns/.cd}{\pgf@pat@options}% + \ifx\pgf@pat@parameters\pgfutil@empty% + % Immutable pattern. Do nothing. + \else% + % Mutable. Do a *lot*. + \begingroup% + \pgf@pat@macroaskeys{/pgf/pattern keys/.cd}{\pgf@pat@defaults}% + \pgf@pat@macroaskeys{/pgf/pattern keys/.cd}{\pgf@pat@onlineoptions}% + % ...to get the values of the current parameters... + \edef\pgf@pat@current@parameters{\pgf@pat@parameters}% + % ...and the internal pattern name. + \edef\pgf@pat@onlinename{\pgf@pat@onlinename\pgf@pat@current@parameters}% + \let\pgf@pat@name=\pgf@pat@onlinename% + \pgfutil@ifundefined{\pgf@pat@name@prefix\pgf@pat@onlinename}{% + %\ifpgf@pat@makepatternimmutable% + \let\pgf@pat@parameters=\pgfutil@empty% + %\fi% + \pgf@declarepattern% + }{}% + \expandafter% + \endgroup% + \expandafter\def\expandafter\pgf@pat@onlinename\expandafter{\pgf@pat@onlinename}% + \expandafter\let\expandafter\pgf@pat@options\expandafter=% + \csname\pgf@pat@name@prefix\pgf@pat@onlinename\endcsname% + \pgf@pat@macroaskeys{/pgf/patterns/.cd}{\pgf@pat@options}% + \fi% + \ifx\pgf@pat@type\pgf@pat@type@uncolored% + \pgf@pat@setpatternuncolored{\pgf@pat@number}{#2}% + \else% + \pgfsys@setpatterncolored{\pgf@pat@number}% + \fi% + }% +} + +\def\pgf@pat@setpatternuncolored#1#2{% + \pgfutil@colorlet{pgf@tempcolor}{#2}% + \pgfutil@ifundefined{applycolormixins}{}{\applycolormixins{pgf@tempcolor}}% + \pgfutil@extractcolorspec{pgf@tempcolor}{\pgf@tempcolor}% + \expandafter\pgfutil@convertcolorspec\pgf@tempcolor{rgb}{\pgf@rgbcolor}% + \expandafter\pgf@pat@set@fill@patternuncolored\pgf@rgbcolor\relax{#1}% +} +\def\pgf@pat@set@fill@patternuncolored#1,#2,#3\relax#4{% + \pgfsys@setpatternuncolored{#4}{#1}{#2}{#3}% +} + + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: t +%%% End: diff --git a/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryplotmarks.code.tex b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryplotmarks.code.tex index 94862191a3a..b64138dabf3 100644 --- a/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryplotmarks.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/libraries/pgflibraryplotmarks.code.tex @@ -7,7 +7,7 @@ % % See the file doc/generic/pgf/licenses/LICENSE for more details. -\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/libraries/pgflibraryplotmarks.code.tex,v 1.13 2013/07/20 13:56:18 ludewich Exp $ +\ProvidesFileRCS[v\pgfversion] $Header: /cvsroot/pgf/pgf/generic/pgf/libraries/pgflibraryplotmarks.code.tex,v 1.14 2015/08/03 10:04:36 cfeuersaenger Exp $ % A stroked circle mark @@ -23,23 +23,23 @@ \pgfdeclareplotmark{Mercedes star} {% - \pgfpathmoveto{\pgfqpointpolar{90}{\pgfplotmarksize}} - \pgfpathlineto{\pgfpointorigin} - \pgfpathmoveto{\pgfqpointpolar{-30}{\pgfplotmarksize}} - \pgfpathlineto{\pgfpointorigin} - \pgfpathmoveto{\pgfqpointpolar{-150}{\pgfplotmarksize}} - \pgfpathlineto{\pgfpointorigin} + \pgfpathmoveto{\pgfqpointpolar{90}{\pgfplotmarksize}}% + \pgfpathlineto{\pgfpointorigin}% + \pgfpathmoveto{\pgfqpointpolar{-30}{\pgfplotmarksize}}% + \pgfpathlineto{\pgfpointorigin}% + \pgfpathmoveto{\pgfqpointpolar{-150}{\pgfplotmarksize}}% + \pgfpathlineto{\pgfpointorigin}% \pgfusepathqstroke } \pgfdeclareplotmark{Mercedes star flipped} {% - \pgfpathmoveto{\pgfqpointpolar{-90}{\pgfplotmarksize}} - \pgfpathlineto{\pgfpointorigin} - \pgfpathmoveto{\pgfqpointpolar{30}{\pgfplotmarksize}} - \pgfpathlineto{\pgfpointorigin} - \pgfpathmoveto{\pgfqpointpolar{150}{\pgfplotmarksize}} - \pgfpathlineto{\pgfpointorigin} + \pgfpathmoveto{\pgfqpointpolar{-90}{\pgfplotmarksize}}% + \pgfpathlineto{\pgfpointorigin}% + \pgfpathmoveto{\pgfqpointpolar{30}{\pgfplotmarksize}}% + \pgfpathlineto{\pgfpointorigin}% + \pgfpathmoveto{\pgfqpointpolar{150}{\pgfplotmarksize}}% + \pgfpathlineto{\pgfpointorigin}% \pgfusepathqstroke } @@ -50,12 +50,12 @@ \pgfdeclareplotmark{asterisk} {% - \pgfpathmoveto{\pgfqpoint{0pt}{-\pgfplotmarksize}} - \pgfpathlineto{\pgfqpoint{0pt}{\pgfplotmarksize}} - \pgfpathmoveto{\pgfqpointpolar{30}{\pgfplotmarksize}} - \pgfpathlineto{\pgfqpointpolar{210}{\pgfplotmarksize}} - \pgfpathmoveto{\pgfqpointpolar{-30}{\pgfplotmarksize}} - \pgfpathlineto{\pgfqpointpolar{-210}{\pgfplotmarksize}} + \pgfpathmoveto{\pgfqpoint{0pt}{-\pgfplotmarksize}}% + \pgfpathlineto{\pgfqpoint{0pt}{\pgfplotmarksize}}% + \pgfpathmoveto{\pgfqpointpolar{30}{\pgfplotmarksize}}% + \pgfpathlineto{\pgfqpointpolar{210}{\pgfplotmarksize}}% + \pgfpathmoveto{\pgfqpointpolar{-30}{\pgfplotmarksize}}% + \pgfpathlineto{\pgfqpointpolar{-210}{\pgfplotmarksize}}% \pgfusepathqstroke } @@ -64,11 +64,11 @@ \pgfdeclareplotmark{star} {% - \pgfpathmoveto{\pgfpointorigin}\pgfpathlineto{\pgfqpoint{0pt}{\pgfplotmarksize}} - \pgfpathmoveto{\pgfpointorigin}\pgfpathlineto{\pgfqpointpolar{18}{\pgfplotmarksize}} - \pgfpathmoveto{\pgfpointorigin}\pgfpathlineto{\pgfqpointpolar{-54}{\pgfplotmarksize}} - \pgfpathmoveto{\pgfpointorigin}\pgfpathlineto{\pgfqpointpolar{234}{\pgfplotmarksize}} - \pgfpathmoveto{\pgfpointorigin}\pgfpathlineto{\pgfqpointpolar{162}{\pgfplotmarksize}} + \pgfpathmoveto{\pgfpointorigin}\pgfpathlineto{\pgfqpoint{0pt}{\pgfplotmarksize}}% + \pgfpathmoveto{\pgfpointorigin}\pgfpathlineto{\pgfqpointpolar{18}{\pgfplotmarksize}}% + \pgfpathmoveto{\pgfpointorigin}\pgfpathlineto{\pgfqpointpolar{-54}{\pgfplotmarksize}}% + \pgfpathmoveto{\pgfpointorigin}\pgfpathlineto{\pgfqpointpolar{234}{\pgfplotmarksize}}% + \pgfpathmoveto{\pgfpointorigin}\pgfpathlineto{\pgfqpointpolar{162}{\pgfplotmarksize}}% \pgfusepathqstroke } @@ -77,11 +77,11 @@ \pgfdeclareplotmark{10-pointed star} {% - \pgfpathmoveto{\pgfqpoint{0pt}{-\pgfplotmarksize}}\pgfpathlineto{\pgfqpoint{0pt}{\pgfplotmarksize}} - \pgfpathmoveto{\pgfqpointpolar{18}{-\pgfplotmarksize}}\pgfpathlineto{\pgfqpointpolar{18}{\pgfplotmarksize}} - \pgfpathmoveto{\pgfqpointpolar{-54}{-\pgfplotmarksize}}\pgfpathlineto{\pgfqpointpolar{-54}{\pgfplotmarksize}} - \pgfpathmoveto{\pgfqpointpolar{234}{-\pgfplotmarksize}}\pgfpathlineto{\pgfqpointpolar{234}{\pgfplotmarksize}} - \pgfpathmoveto{\pgfqpointpolar{162}{-\pgfplotmarksize}}\pgfpathlineto{\pgfqpointpolar{162}{\pgfplotmarksize}} + \pgfpathmoveto{\pgfqpoint{0pt}{-\pgfplotmarksize}}\pgfpathlineto{\pgfqpoint{0pt}{\pgfplotmarksize}}% + \pgfpathmoveto{\pgfqpointpolar{18}{-\pgfplotmarksize}}\pgfpathlineto{\pgfqpointpolar{18}{\pgfplotmarksize}}% + \pgfpathmoveto{\pgfqpointpolar{-54}{-\pgfplotmarksize}}\pgfpathlineto{\pgfqpointpolar{-54}{\pgfplotmarksize}}% + \pgfpathmoveto{\pgfqpointpolar{234}{-\pgfplotmarksize}}\pgfpathlineto{\pgfqpointpolar{234}{\pgfplotmarksize}}% + \pgfpathmoveto{\pgfqpointpolar{162}{-\pgfplotmarksize}}\pgfpathlineto{\pgfqpointpolar{162}{\pgfplotmarksize}}% \pgfusepathqstroke } @@ -90,21 +90,21 @@ \pgfdeclareplotmark{oplus} {% - \pgfpathcircle{\pgfpointorigin}{\pgfplotmarksize} - \pgfpathmoveto{\pgfqpoint{-\pgfplotmarksize}{0pt}} - \pgfpathlineto{\pgfqpoint{\pgfplotmarksize}{0pt}} - \pgfpathmoveto{\pgfqpoint{0pt}{\pgfplotmarksize}} - \pgfpathlineto{\pgfqpoint{0pt}{-\pgfplotmarksize}} + \pgfpathcircle{\pgfpointorigin}{\pgfplotmarksize}% + \pgfpathmoveto{\pgfqpoint{-\pgfplotmarksize}{0pt}}% + \pgfpathlineto{\pgfqpoint{\pgfplotmarksize}{0pt}}% + \pgfpathmoveto{\pgfqpoint{0pt}{\pgfplotmarksize}}% + \pgfpathlineto{\pgfqpoint{0pt}{-\pgfplotmarksize}}% \pgfusepathqstroke } \pgfdeclareplotmark{oplus*} {% - \pgfpathcircle{\pgfpointorigin}{\pgfplotmarksize} - \pgfpathmoveto{\pgfqpoint{-\pgfplotmarksize}{0pt}} - \pgfpathlineto{\pgfqpoint{\pgfplotmarksize}{0pt}} - \pgfpathmoveto{\pgfqpoint{0pt}{\pgfplotmarksize}} - \pgfpathlineto{\pgfqpoint{0pt}{-\pgfplotmarksize}} + \pgfpathcircle{\pgfpointorigin}{\pgfplotmarksize}% + \pgfpathmoveto{\pgfqpoint{-\pgfplotmarksize}{0pt}}% + \pgfpathlineto{\pgfqpoint{\pgfplotmarksize}{0pt}}% + \pgfpathmoveto{\pgfqpoint{0pt}{\pgfplotmarksize}}% + \pgfpathlineto{\pgfqpoint{0pt}{-\pgfplotmarksize}}% \pgfusepathqfillstroke } @@ -113,21 +113,21 @@ \pgfdeclareplotmark{otimes} {% - \pgfpathcircle{\pgfpointorigin}{\pgfplotmarksize} - \pgfpathmoveto{\pgfqpoint{-.70710678\pgfplotmarksize}{-.70710678\pgfplotmarksize}} - \pgfpathlineto{\pgfqpoint{.70710678\pgfplotmarksize}{.70710678\pgfplotmarksize}} - \pgfpathmoveto{\pgfqpoint{-.70710678\pgfplotmarksize}{.70710678\pgfplotmarksize}} - \pgfpathlineto{\pgfqpoint{.70710678\pgfplotmarksize}{-.70710678\pgfplotmarksize}} + \pgfpathcircle{\pgfpointorigin}{\pgfplotmarksize}% + \pgfpathmoveto{\pgfqpoint{-.70710678\pgfplotmarksize}{-.70710678\pgfplotmarksize}}% + \pgfpathlineto{\pgfqpoint{.70710678\pgfplotmarksize}{.70710678\pgfplotmarksize}}% + \pgfpathmoveto{\pgfqpoint{-.70710678\pgfplotmarksize}{.70710678\pgfplotmarksize}}% + \pgfpathlineto{\pgfqpoint{.70710678\pgfplotmarksize}{-.70710678\pgfplotmarksize}}% \pgfusepathqstroke } \pgfdeclareplotmark{otimes*} {% - \pgfpathcircle{\pgfpointorigin}{\pgfplotmarksize} - \pgfpathmoveto{\pgfqpoint{-.70710678\pgfplotmarksize}{-.70710678\pgfplotmarksize}} - \pgfpathlineto{\pgfqpoint{.70710678\pgfplotmarksize}{.70710678\pgfplotmarksize}} - \pgfpathmoveto{\pgfqpoint{-.70710678\pgfplotmarksize}{.70710678\pgfplotmarksize}} - \pgfpathlineto{\pgfqpoint{.70710678\pgfplotmarksize}{-.70710678\pgfplotmarksize}} + \pgfpathcircle{\pgfpointorigin}{\pgfplotmarksize}% + \pgfpathmoveto{\pgfqpoint{-.70710678\pgfplotmarksize}{-.70710678\pgfplotmarksize}}% + \pgfpathlineto{\pgfqpoint{.70710678\pgfplotmarksize}{.70710678\pgfplotmarksize}}% + \pgfpathmoveto{\pgfqpoint{-.70710678\pgfplotmarksize}{.70710678\pgfplotmarksize}}% + \pgfpathlineto{\pgfqpoint{.70710678\pgfplotmarksize}{-.70710678\pgfplotmarksize}}% \pgfusepathqfillstroke } @@ -136,8 +136,8 @@ \pgfdeclareplotmark{|} {% - \pgfpathmoveto{\pgfqpoint{0pt}{\pgfplotmarksize}} - \pgfpathlineto{\pgfqpoint{0pt}{-\pgfplotmarksize}} + \pgfpathmoveto{\pgfqpoint{0pt}{\pgfplotmarksize}}% + \pgfpathlineto{\pgfqpoint{0pt}{-\pgfplotmarksize}}% \pgfusepathqstroke } @@ -147,8 +147,8 @@ \pgfdeclareplotmark{-} {% - \pgfpathmoveto{\pgfqpoint{\pgfplotmarksize}{0pt}} - \pgfpathlineto{\pgfqpoint{-\pgfplotmarksize}{0pt}} + \pgfpathmoveto{\pgfqpoint{\pgfplotmarksize}{0pt}}% + \pgfpathlineto{\pgfqpoint{-\pgfplotmarksize}{0pt}}% \pgfusepathqstroke } @@ -174,9 +174,9 @@ \pgfdeclareplotmark{triangle} {% - \pgfpathmoveto{\pgfqpoint{0pt}{\pgfplotmarksize}} - \pgfpathlineto{\pgfqpointpolar{-30}{\pgfplotmarksize}} - \pgfpathlineto{\pgfqpointpolar{-150}{\pgfplotmarksize}} + \pgfpathmoveto{\pgfqpoint{0pt}{\pgfplotmarksize}}% + \pgfpathlineto{\pgfqpointpolar{-30}{\pgfplotmarksize}}% + \pgfpathlineto{\pgfqpointpolar{-150}{\pgfplotmarksize}}% \pgfpathclose \pgfusepathqstroke } @@ -186,9 +186,9 @@ \pgfdeclareplotmark{triangle*} {% - \pgfpathmoveto{\pgfqpoint{0pt}{\pgfplotmarksize}} - \pgfpathlineto{\pgfqpointpolar{-30}{\pgfplotmarksize}} - \pgfpathlineto{\pgfqpointpolar{-150}{\pgfplotmarksize}} + \pgfpathmoveto{\pgfqpoint{0pt}{\pgfplotmarksize}}% + \pgfpathlineto{\pgfqpointpolar{-30}{\pgfplotmarksize}}% + \pgfpathlineto{\pgfqpointpolar{-150}{\pgfplotmarksize}}% \pgfpathclose \pgfusepathqfillstroke } @@ -199,10 +199,10 @@ \pgfdeclareplotmark{diamond} {% - \pgfpathmoveto{\pgfqpoint{0pt}{\pgfplotmarksize}} - \pgfpathlineto{\pgfqpoint{.75\pgfplotmarksize}{0pt}} - \pgfpathlineto{\pgfqpoint{0pt}{-\pgfplotmarksize}} - \pgfpathlineto{\pgfqpoint{-.75\pgfplotmarksize}{0pt}} + \pgfpathmoveto{\pgfqpoint{0pt}{\pgfplotmarksize}}% + \pgfpathlineto{\pgfqpoint{.75\pgfplotmarksize}{0pt}}% + \pgfpathlineto{\pgfqpoint{0pt}{-\pgfplotmarksize}}% + \pgfpathlineto{\pgfqpoint{-.75\pgfplotmarksize}{0pt}}% \pgfpathclose \pgfusepathqstroke } @@ -212,10 +212,10 @@ \pgfdeclareplotmark{diamond*} {% - \pgfpathmoveto{\pgfqpoint{0pt}{\pgfplotmarksize}} - \pgfpathlineto{\pgfqpoint{.75\pgfplotmarksize}{0pt}} - \pgfpathlineto{\pgfqpoint{0pt}{-\pgfplotmarksize}} - \pgfpathlineto{\pgfqpoint{-.75\pgfplotmarksize}{0pt}} + \pgfpathmoveto{\pgfqpoint{0pt}{\pgfplotmarksize}}% + \pgfpathlineto{\pgfqpoint{.75\pgfplotmarksize}{0pt}}% + \pgfpathlineto{\pgfqpoint{0pt}{-\pgfplotmarksize}}% + \pgfpathlineto{\pgfqpoint{-.75\pgfplotmarksize}{0pt}}% \pgfpathclose \pgfusepathqfillstroke } @@ -226,11 +226,11 @@ \pgfdeclareplotmark{pentagon} {% - \pgfpathmoveto{\pgfqpoint{0pt}{\pgfplotmarksize}} - \pgfpathlineto{\pgfqpointpolar{18}{\pgfplotmarksize}} - \pgfpathlineto{\pgfqpointpolar{-54}{\pgfplotmarksize}} - \pgfpathlineto{\pgfqpointpolar{234}{\pgfplotmarksize}} - \pgfpathlineto{\pgfqpointpolar{162}{\pgfplotmarksize}} + \pgfpathmoveto{\pgfqpoint{0pt}{\pgfplotmarksize}}% + \pgfpathlineto{\pgfqpointpolar{18}{\pgfplotmarksize}}% + \pgfpathlineto{\pgfqpointpolar{-54}{\pgfplotmarksize}}% + \pgfpathlineto{\pgfqpointpolar{234}{\pgfplotmarksize}}% + \pgfpathlineto{\pgfqpointpolar{162}{\pgfplotmarksize}}% \pgfpathclose \pgfusepathqstroke } @@ -239,11 +239,11 @@ \pgfdeclareplotmark{pentagon*} {% - \pgfpathmoveto{\pgfqpoint{0pt}{\pgfplotmarksize}} - \pgfpathlineto{\pgfqpointpolar{18}{\pgfplotmarksize}} - \pgfpathlineto{\pgfqpointpolar{-54}{\pgfplotmarksize}} - \pgfpathlineto{\pgfqpointpolar{234}{\pgfplotmarksize}} - \pgfpathlineto{\pgfqpointpolar{162}{\pgfplotmarksize}} + \pgfpathmoveto{\pgfqpoint{0pt}{\pgfplotmarksize}}% + \pgfpathlineto{\pgfqpointpolar{18}{\pgfplotmarksize}}% + \pgfpathlineto{\pgfqpointpolar{-54}{\pgfplotmarksize}}% + \pgfpathlineto{\pgfqpointpolar{234}{\pgfplotmarksize}}% + \pgfpathlineto{\pgfqpointpolar{162}{\pgfplotmarksize}}% \pgfpathclose \pgfusepathqfillstroke } @@ -436,15 +436,15 @@ % A stroke-filled heart-shaped mark % created by Magnus Tewes \pgfdeclareplotmark{heart}{% - \pgfpathmoveto{\pgfqpoint{0pt}{-1.75\pgfplotmarksize}} - \pgfpathcurveto{\pgfqpoint{0pt}{-1.75\pgfplotmarksize}}{\pgfqpoint{0pt}{-1.66\pgfplotmarksize}}{\pgfqpoint{-.5\pgfplotmarksize}{-1.165\pgfplotmarksize}} - \pgfpathcurveto{\pgfqpoint{-.5\pgfplotmarksize}{-1.165\pgfplotmarksize}}{\pgfqpoint{-\pgfplotmarksize}{-.75\pgfplotmarksize}}{\pgfqpoint{-\pgfplotmarksize}{0pt}} - \pgfpathcurveto{\pgfqpoint{-\pgfplotmarksize}{0pt}}{\pgfqpoint{-\pgfplotmarksize}{.5825\pgfplotmarksize}}{\pgfqpoint{-.5825\pgfplotmarksize}{.5825\pgfplotmarksize}} - \pgfpathcurveto{\pgfqpoint{-.5825\pgfplotmarksize}{.5825\pgfplotmarksize}}{\pgfqpoint{0pt}{.5825\pgfplotmarksize}}{\pgfqpoint{0pt}{0pt}} - \pgfpathcurveto{\pgfqpoint{0pt}{0pt}}{\pgfqpoint{0pt}{.5825\pgfplotmarksize}}{\pgfqpoint{.5825\pgfplotmarksize}{.5825\pgfplotmarksize}} - \pgfpathcurveto{\pgfqpoint{.5825\pgfplotmarksize}{.5825\pgfplotmarksize}}{\pgfqpoint{\pgfplotmarksize}{.5825\pgfplotmarksize}}{\pgfqpoint{\pgfplotmarksize}{0pt}} - \pgfpathcurveto{\pgfqpoint{\pgfplotmarksize}{0pt}}{\pgfqpoint{\pgfplotmarksize}{-.75\pgfplotmarksize}}{\pgfqpoint{.5\pgfplotmarksize}{-1.165\pgfplotmarksize}} - \pgfpathcurveto{\pgfqpoint{.5\pgfplotmarksize}{-1.165\pgfplotmarksize}}{\pgfqpoint{0pt}{-1.66\pgfplotmarksize}}{\pgfqpoint{0pt}{-1.75\pgfplotmarksize}} + \pgfpathmoveto{\pgfqpoint{0pt}{-1.75\pgfplotmarksize}}% + \pgfpathcurveto{\pgfqpoint{0pt}{-1.75\pgfplotmarksize}}{\pgfqpoint{0pt}{-1.66\pgfplotmarksize}}{\pgfqpoint{-.5\pgfplotmarksize}{-1.165\pgfplotmarksize}}% + \pgfpathcurveto{\pgfqpoint{-.5\pgfplotmarksize}{-1.165\pgfplotmarksize}}{\pgfqpoint{-\pgfplotmarksize}{-.75\pgfplotmarksize}}{\pgfqpoint{-\pgfplotmarksize}{0pt}}% + \pgfpathcurveto{\pgfqpoint{-\pgfplotmarksize}{0pt}}{\pgfqpoint{-\pgfplotmarksize}{.5825\pgfplotmarksize}}{\pgfqpoint{-.5825\pgfplotmarksize}{.5825\pgfplotmarksize}}% + \pgfpathcurveto{\pgfqpoint{-.5825\pgfplotmarksize}{.5825\pgfplotmarksize}}{\pgfqpoint{0pt}{.5825\pgfplotmarksize}}{\pgfqpoint{0pt}{0pt}}% + \pgfpathcurveto{\pgfqpoint{0pt}{0pt}}{\pgfqpoint{0pt}{.5825\pgfplotmarksize}}{\pgfqpoint{.5825\pgfplotmarksize}{.5825\pgfplotmarksize}}% + \pgfpathcurveto{\pgfqpoint{.5825\pgfplotmarksize}{.5825\pgfplotmarksize}}{\pgfqpoint{\pgfplotmarksize}{.5825\pgfplotmarksize}}{\pgfqpoint{\pgfplotmarksize}{0pt}}% + \pgfpathcurveto{\pgfqpoint{\pgfplotmarksize}{0pt}}{\pgfqpoint{\pgfplotmarksize}{-.75\pgfplotmarksize}}{\pgfqpoint{.5\pgfplotmarksize}{-1.165\pgfplotmarksize}}% + \pgfpathcurveto{\pgfqpoint{.5\pgfplotmarksize}{-1.165\pgfplotmarksize}}{\pgfqpoint{0pt}{-1.66\pgfplotmarksize}}{\pgfqpoint{0pt}{-1.75\pgfplotmarksize}}% \pgfpathclose \pgfusepathqfillstroke } diff --git a/Master/texmf-dist/tex/generic/pgf/libraries/shapes/circuits/pgflibraryshapes.gates.logic.code.tex b/Master/texmf-dist/tex/generic/pgf/libraries/shapes/circuits/pgflibraryshapes.gates.logic.code.tex index 8b047f04ab1..72d6a6d22ba 100644 --- a/Master/texmf-dist/tex/generic/pgf/libraries/shapes/circuits/pgflibraryshapes.gates.logic.code.tex +++ b/Master/texmf-dist/tex/generic/pgf/libraries/shapes/circuits/pgflibraryshapes.gates.logic.code.tex @@ -11,9 +11,9 @@ % Common keys for all logic gates. % \pgfkeys{/pgf/.cd,% - logic gate input sep/.initial=0.125cm, - logic gate inputs/.initial={normal,normal},% - logic gate inverted radius/.initial=2pt + logic gate input sep/.initial=0.125cm, + logic gate inputs/.initial={normal,normal},% + logic gate inverted radius/.initial=2pt } @@ -21,77 +21,84 @@ % \expandafter\ifx\csname pgf@lib@sh@logicgate@parseinputs\endcsname\relax% \def\pgf@lib@sh@logicgate@parseinputs#1{% - \edef\pgf@lib@sh@temp{\pgfkeysvalueof{/pgf/logic gate inputs}}% - \c@pgf@counta#1\relax% - \c@pgf@countb0\relax% - \expandafter\pgfutil@in@\expandafter,\expandafter{\pgf@lib@sh@temp}% - \ifpgfutil@in@% - \let\pgf@lib@sh@next\pgf@lib@sh@logicgate@parseinputs@long% - \else% - \let\pgf@lib@sh@next\pgf@lib@sh@logicgate@parseinputs@short% - \fi% - \pgf@lib@sh@next% -} + \edef\pgf@lib@sh@temp{\pgfkeysvalueof{/pgf/logic gate inputs}}% + \c@pgf@counta#1\relax% + \c@pgf@countb0\relax% + \expandafter\pgfutil@in@\expandafter,\expandafter{\pgf@lib@sh@temp}% + \ifpgfutil@in@% + \let\pgf@lib@sh@next\pgf@lib@sh@logicgate@parseinputs@long% + \else% + \let\pgf@lib@sh@next\pgf@lib@sh@logicgate@parseinputs@short% + \fi% + \pgf@lib@sh@next% +} \def\pgf@lib@sh@itext{i} \def\pgf@lib@sh@invertedtext{inverted} +\def\pgf@lib@sh@atchar{@} +\def\pgf@lib@sh@gobbletilat#1@{} +\def\pgf@lib@sh@gobbletilatcomma#1@,{} % -% The `short' version for input specifcation is an extension of -% ideas due to Juergen Werber and Christoph Bartoschek. +% The `short' version for input specifcation is an extension of +% ideas due to Juergen Werber and Christoph Bartoschek. % \def\pgf@lib@sh@logicgate@parseinputs@short{% - \expandafter\pgf@lib@sh@logicgate@parseinputs@@short\pgf@lib@sh@temp\pgf@stop% + \expandafter\pgf@lib@sh@logicgate@parseinputs@@short\pgf@lib@sh@temp @% } \def\pgf@lib@sh@logicgate@parseinputs@@short#1{% - \ifx#1\pgf@stop% - \edef\pgf@lib@sh@logicgate@numinputs{\the\c@pgf@countb}% - \let\pgf@lib@sh@next\relax% - \else% - \ifnum\c@pgf@countb=\c@pgf@counta% - \edef\pgf@lib@sh@logicgate@numinputs{\the\c@pgf@countb}% - \let\pgf@lib@sh@next\relax% - \else% - \advance\c@pgf@countb1\relax% - \expandafter\ifx\pgf@lib@sh@itext#1% - \expandafter\pgf@sh@resavedmacro\expandafter{\csname input-\the\c@pgf@countb\endcsname}{% - \expandafter\def\csname input-\the\c@pgf@countb\endcsname{i}}% - \else% - \expandafter\pgf@sh@resavedmacro\expandafter{\csname input-\the\c@pgf@countb\endcsname}{% - \expandafter\def\csname input-\the\c@pgf@countb\endcsname{n}}% - \fi% - \let\pgf@lib@sh@next\pgf@lib@sh@logicgate@parseinputs@@short% - \fi% - \fi% - \pgf@lib@sh@next% + \def\pgf@lib@sh@tmp{#1}% + \ifx\pgf@lib@sh@tmp\pgf@lib@sh@atchar% + \edef\pgf@lib@sh@logicgate@numinputs{\the\c@pgf@countb}% + \let\pgf@lib@sh@next=\relax% + \else% + \ifnum\c@pgf@countb=\c@pgf@counta% + \edef\pgf@lib@sh@logicgate@numinputs{\the\c@pgf@countb}% + \let\pgf@lib@sh@next=\pgf@lib@sh@gobbletilat% + \else% + \advance\c@pgf@countb by1\relax% + \expandafter\ifx\pgf@lib@sh@itext#1% + \expandafter\pgf@sh@resavedmacro\expandafter{\csname input-\the\c@pgf@countb\endcsname}{% + \expandafter\def\csname input-\the\c@pgf@countb\endcsname{i}}% + \else% + \expandafter\pgf@sh@resavedmacro\expandafter{\csname input-\the\c@pgf@countb\endcsname}{% + \expandafter\def\csname input-\the\c@pgf@countb\endcsname{n}}% + \fi% + \let\pgf@lib@sh@next=\pgf@lib@sh@logicgate@parseinputs@@short% + \fi% + \fi% + \pgf@lib@sh@next% } + + \def\pgf@lib@sh@logicgate@parseinputs@long{% - \expandafter\pgf@lib@sh@logicgate@parseinputs@@long\pgf@lib@sh@temp,\pgf@stop,% + \expandafter\pgf@lib@sh@logicgate@parseinputs@@long\pgf@lib@sh@temp,@,% } \def\pgf@lib@sh@logicgate@parseinputs@@long#1,{% - \ifx#1\pgf@stop% - \edef\pgf@lib@sh@logicgate@numinputs{\the\c@pgf@countb}% - \let\pgf@lib@sh@next\relax% - \else% - \ifnum\c@pgf@countb=\c@pgf@counta% - \edef\pgf@lib@sh@logicgate@numinputs{\the\c@pgf@countb}% - \let\pgf@lib@sh@next\relax% - \else% - \advance\c@pgf@countb1\relax% - \def\pgf@lib@sh@temp{#1}% - \ifx\pgf@lib@sh@invertedtext\pgf@lib@sh@temp% - \expandafter\pgf@sh@resavedmacro\expandafter{\csname input-\the\c@pgf@countb\endcsname}{% - \expandafter\def\csname input-\the\c@pgf@countb\endcsname{i}}% - \else% - \expandafter\pgf@sh@resavedmacro\expandafter{\csname input-\the\c@pgf@countb\endcsname}{% - \expandafter\def\csname input-\the\c@pgf@countb\endcsname{n}}% - \fi% - \let\pgf@lib@sh@next\pgf@lib@sh@logicgate@parseinputs@@@long% - \fi% - \fi% - \pgf@lib@sh@next% + \def\pgf@lib@sh@tmp{#1}% + \ifx\pgf@lib@sh@tmp\pgf@lib@sh@atchar% + \edef\pgf@lib@sh@logicgate@numinputs{\the\c@pgf@countb}% + \let\pgf@lib@sh@next=\relax% + \else% + \ifnum\c@pgf@countb=\c@pgf@counta% + \edef\pgf@lib@sh@logicgate@numinputs{\the\c@pgf@countb}% + \let\pgf@lib@sh@next=\pgf@lib@sh@gobbletilatcomma% + \else% + \advance\c@pgf@countb by1\relax% + \def\pgf@lib@sh@temp{#1}% + \ifx\pgf@lib@sh@invertedtext\pgf@lib@sh@temp% + \expandafter\pgf@sh@resavedmacro\expandafter{\csname input-\the\c@pgf@countb\endcsname}{% + \expandafter\def\csname input-\the\c@pgf@countb\endcsname{i}}% + \else% + \expandafter\pgf@sh@resavedmacro\expandafter{\csname input-\the\c@pgf@countb\endcsname}{% + \expandafter\def\csname input-\the\c@pgf@countb\endcsname{n}}% + \fi% + \let\pgf@lib@sh@next=\pgf@lib@sh@logicgate@parseinputs@@@long% + \fi% + \fi% + \pgf@lib@sh@next% } \def\pgf@lib@sh@logicgate@parseinputs@@@long{% - \pgfutil@ifnextchar x{\pgf@lib@sh@logicgate@parseinputs@@long}% - {\pgf@lib@sh@logicgate@parseinputs@@long}% + \pgfutil@ifnextchar x{\pgf@lib@sh@logicgate@parseinputs@@long}% + {\pgf@lib@sh@logicgate@parseinputs@@long}% } \fi% |