LaTeXML
view release on metacpan or search on metacpan
lib/LaTeXML/Package/pgfmath.code.tex.ltxml view on Meta::CPAN
cosh => sub { cosh($_[0]); },
cot => sub { cot(pgfmathargradians($_[0])); },
deg => sub { rad2deg($_[0]); },
# depth => sub { },
exp => sub { exp($_[0]); },
factorial => sub { pgfmathfactorial($_[0]); },
false => sub { 0; },
floor => sub { floor($_[0]); },
# frac => sub { },
# gcd => sub { },
# height => sub { },
hex => sub { sprintf("%x", $_[0]); },
Hex => sub { sprintf("%X", $_[0]); },
int => sub { int($_[0]); },
ifthenelse => sub { ($_[0] ? $_[1] : $_[2]); },
iseven => sub { (int($_[0]) % 2) == 0 },
isodd => sub { (int($_[0]) % 2) == 1 },
# isprime => sub { },
ln => sub { log($_[0]); },
log10 => sub { log($_[0]) / $LOG10; },
log2 => sub { log($_[0]) / $LOG2; },
max => sub { max(@_); },
min => sub { min(@_); },
mod => sub { pgfmath_mod_trunc($_[0], $_[1]); },
Mod => sub { pgfmath_mod_floor($_[0], $_[1]); },
not => sub { !$_[0]; },
oct => sub { sprintf("%o", $_[0]); },
pow => sub { $_[0]**$_[1]; },
rad => sub { deg2rad($_[0]); },
# rand => sub { },
# random => sub { },
real => sub { $_[0] + 0.0; },
# rnd => sub { },
round => sub { round($_[0]); },
scalar => sub { SetCondition(T_CS('\ifpgfmathunitsdeclared'), 0, 'global'); $_[0]; },
sec => sub { sec(pgfmathargradians($_[0])); },
sign => sub { ($_[0] > 0 ? 1 : ($_[0] < 0 ? -1 : 0)); },
sin => sub { sin(pgfmathargradians($_[0])); },
sinh => sub { sinh($_[0]); },
sqrt => sub { sqrt($_[0]); },
subtract => sub { $_[0] - $_[1]; },
tan => sub { tan(pgfmathargradians($_[0])); },
tanh => sub { tanh($_[0]); },
true => sub { 1; },
veclen => sub { sqrt($_[0] * $_[0] + $_[1] * $_[1]); },
# width => sub { },
# Additional functions from tikz-cd; these need to get parameters from the current math font!
axis_height => sub { "2.5"; }, # sigma[22]
rule_thickness => sub { "0.39998"; }, # xi[8]
};
$::RD_HINT = 1;
# Why can't I manage to import a few functions to be visible to the grammar actions?
# NOTE Not yet done: quoted strings, extensible functions
$PGFMATHGrammarSpec = << 'EoGrammar';
# {BEGIN { use LaTeXML::Package::Pool; }}
# { use LaTeXML::Package::Pool; }
# { LaTeXML::Package::Pool->import(qw(pgfmath_apply)); }
<skip:'[\s\{\}]*'> # braces ignored during parse...
formula :
expr /\?/ expr /:/ expr { ($item[1] ? $item[3] : $item[5]); }
| expr CMP expr { LaTeXML::Package::Pool::pgfmath_apply($item[2], $item[1], $item[3]); }
| expr
expr :
term (ADDOP term { [$item[1],$item[2]]; })(s?)
{ LaTeXML::Package::Pool::pgfmath_leftrecapply($item[1],map(@$_,@{$item[2]})); }
term :
factor (MULOP factor { [$item[1],$item[2]]; })(s?)
{ LaTeXML::Package::Pool::pgfmath_leftrecapply($item[1],map(@$_,@{$item[2]})); }
# addPostfix[$base] ; adds any following sub/super scripts to $base.
addPostfix :
/^\Z/ { $arg[0];} # short circuit!
| POSTFIX addPostfix[LaTeXML::Package::Pool::pgfmath_apply($item[1],$arg[0])]
| { $arg[0]; }
factor : simplefactor /\^/ simplefactor { $item[1] ** $item[3]; }
| simplefactor addPostfix[$item[1]]
simplefactor :
/\(/ formula /(?:\)|^\Z)/ { $item[2]; } # Let unclosed () succeed at end?
| PREFIX simplefactor { LaTeXML::Package::Pool::pgfmath_apply($item[1],$item[2]); }
| SIZER /\(/ QTEX /\)/ { LaTeXML::Package::Pool::pgfmath_sizer($item[1], $item[3]); }
| FUNCTION /\(/ formula (/,/ formula { $item[2]; })(s?) /\)/
{ LaTeXML::Package::Pool::pgfmath_apply($item[1], $item[3], @{$item[4]}); }
| FUNCTION simplefactor
{ LaTeXML::Package::Pool::pgfmath_apply($item[1], $item[2]); }
| FUNCTION0 { LaTeXML::Package::Pool::pgfmath_apply($item[1]); }
| NUMBER UNIT { LaTeXML::Package::Pool::pgfmath_convert($item[1],$item[2]); }
| NUMBER REGISTER { LaTeXML::Package::Pool::pgfmath_apply('*', $item[1], $item[2]); }
# really count_register dimension_register!
| REGISTER REGISTER { LaTeXML::Package::Pool::pgfmath_apply('*', $item[1], $item[2]); }
| NUMBER
| REGISTER
REGISTER : # these need to set dimension flag!!!
/\\wd/ CS { LaTeXML::Package::Pool::pgfmath_setunitsdeclared();
LaTeXML::Package::Pool::pgfmath_getwidth($item[2]); }
| /\\ht/ CS { LaTeXML::Package::Pool::pgfmath_setunitsdeclared();
LaTeXML::Package::Pool::pgfmath_getheight($item[2]); }
| /\\dp/ CS { LaTeXML::Package::Pool::pgfmath_setunitsdeclared();
LaTeXML::Package::Pool::pgfmath_getdepth($item[2]); }
| CS { LaTeXML::Package::Pool::pgfmath_register($item[1]); }
CS : /\\[a-zA-Z@]*/
# NOTE: Need to recognize octal, binary and hex! AND scientific notation!
NUMBER :
/(?:\d+\.?\d*|\d*\.?\d+)(:?[eE][+-]?\d+)?/ { $item[1]+0.0; }
| /0b[01]+/ { oct($item[1]); } # !!!
| /0x[0-9a-fA-F]+/ { hex($item[1]); }
| /0[0-9]+/ { oct($item[1]); }
| /\./ { 0.0; } # pgf treats a single dot as a zero
UNIT :
/(?:ex|em|pt|pc|in|bp|cm|mm|dd|cc|sp)/
FUNCTION0 : /(?:e|pi|false|rand|rnd|true|axis_height|rule_thickness)/
| /([a-zA-Z][a-zA-Z0-9]*)/ { LaTeXML::Package::Pool::pgfmath_checkuserconstant($item[1]); }
FUNCTION : /(?:abs|acos|asin|atan2|atan|angle|bin|ceil|cos|cosec|cosh|cot|deg|exp|factorial|floor|frac|hex|Hex|int|iseven|isodd|isprime|ln|log10|log2|neg|not|oct|rad|real|round|sec|sign|sin|sinh|sqrt|tan|tanh|add|and|divide|div|equal|gcd|greater|...
| /([a-zA-Z][a-zA-Z0-9]*)/ { LaTeXML::Package::Pool::pgfmath_checkuserfunction($item[1]); }
# ? array|scalar
# These take boxes!
SIZER : /(?:depth|height|width)/
QTEX : /"[^"]*"/
CMP : /==/ | /\>/ | /\</ | /!=/ | /\>=/ | /\<=/ | /&&/ | /||/
PREFIX : /\-/ | /!/ | /\+/
POSTFIX : /!/ | /r/
ADDOP : /\+/ | /=/ | /\-/
MULOP : /\*/ | /\//
EoGrammar
}
#======================================================================
1;
( run in 2.750 seconds using v1.01-cache-2.11-cpan-d8267643d1d )