From 52964d1da14e73b2713b263628eb109e7dc4c9a6 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Wed, 14 Apr 2021 20:08:06 +0000 Subject: xintsession.tex runtime git-svn-id: svn://tug.org/texlive/trunk@58875 c570f23f-e606-0410-a88d-b1316a301751 --- .../tex/plain/xintsession/xintsession.tex | 416 +++++++++++++++++++++ 1 file changed, 416 insertions(+) create mode 100644 Master/texmf-dist/tex/plain/xintsession/xintsession.tex (limited to 'Master/texmf-dist/tex') diff --git a/Master/texmf-dist/tex/plain/xintsession/xintsession.tex b/Master/texmf-dist/tex/plain/xintsession/xintsession.tex new file mode 100644 index 00000000000..271c6abff66 --- /dev/null +++ b/Master/texmf-dist/tex/plain/xintsession/xintsession.tex @@ -0,0 +1,416 @@ +% Release 0.1 (2021/04/13) of xintsession.tex +% author: Jean-Francois Burnol +% License: LPPL 1.3c (author-maintained) +% Usage: execute etex or pdftex +% then enter "xintsession" at the ** prompt +\input xintexpr.sty\relax% +\input xintbinhex.sty\relax% +\input polexpr.sty\relax% attention will crash if < 0.8 +\let\PolToExprOneTerm\PolToExprOneTermStyleB% +%\let\PolToExprTimes\empty% +% we do assume standard catcodes on loading and use +% \XINT_restorecatcodes as a convenience facility. +% It stores \endlinechar but not \newlinechar +\edef\xsrestorecatcodes{\csname XINT_restorecatcodes\endcsname% + \newlinechar\the\newlinechar\relax}% +\endlinechar 13 % +\newlinechar 10 +\catcode`_ 11 +\catcode`& 11 +\catcode`@ 11 +\catcode`^ 11 +\catcode`" 7 +\catcode0 12 +\newwrite\xs_out +\edef\xs_name{\jobname-\expandafter\xint_gobble_ii\the\year + \expandafter\xint_gobble_i\the\numexpr100+\month\relax + \expandafter\xint_gobble_i\the\numexpr100+\day\relax + _% + \expandafter\xint_gobble_i\the\numexpr(\time+30)/60+99h% + \expandafter\xint_gobble_i\the\numexpr100+\time-60*((\time+30)/60-1).tex}% +\immediate\openout\xs_out=\xs_name\relax +\begingroup\catcode37 12 +\gdef\xs_message#1{\message{#1}\immediate\write\xs_out{%#1}}\endgroup +{\catcode13\active\def +{""J}\catcode32\active\edef {\string }% +\catcode`?=0\catcode`\\=12\relax% +?xdef?xs_logo{% + _____ _____ + ____ ____(_)________ /_________ _________________ + __ |/_/_ /__ __ \ __/ _ \_ |/_/__ __ \_ ___/ + __> < _ / _ / / / /_ / __/_> < __ /_/ / / + /_/|_| /_/ /_/ /_/\__/ \___//_/|_| _ .___//_/ + /_/ + _____ _____ __________ + ___(_)________ /__________________ ________ /___(_)__ ______ + __ /__ __ \ __/ _ \_ ___/ __ `/ ___/ __/_ /__ | / / _ \ + _ / _ / / / /_ / __/ / / /_/ // /__ / /_ _ / __ |/ // __/ + /_/ /_/ /_/\__/ \___//_/ \__,_/ \___/ \__/ /_/ _____/ \___/ +}% +?immediate?write128{% + + xintsession 0.1 + Copyright (c) Jean-Francois Burnol, 2021. + + \jobname is ?jobname + Transcript will go to log and to ?xs_name + + ===> HIT THE KEY NOW! <=== +}}% +\def\xs_no{0}% +\XINT_expr_defvar_one{@___}{{0}}% +\XINT_expr_defvar_one{@__}{{0}}% +\XINT_expr_defvar_one{@_}{{0}}% +\def\xs_fetch{\let\xs_in\empty\xs_fetch_a}% +\begingroup +\catcode13\active% +\gdef\xs_fetch_a#1 +{% + \odef\xs_firstitem{\romannumeral0\xintfirstitem{#1.}}% + \ifcat\relax\expandafter\noexpand\xs_firstitem% + \expandafter\xs_cs% + \else% + \if &\expandafter\noexpand\xs_firstitem% + \expandafter\expandafter\expandafter\xs_magic% + \fi% + \fi% + \if;\expandafter\noexpand\romannumeral0\xintlastitem{#1}% + \xs_fetch_b#1^% + \else% + \message{(Use ; to end multi-line input)}% + \odef\xs_in{\xs_in#1}\expandafter\xs_fetch_a% + \fi% +}% +\endgroup +\def\xs_cs\if;\expandafter\noexpand\romannumeral0\xintlastitem#1#2\fi +{% + \xs_message{(executing \detokenize{#1} in background)} + #1\xs_fetch_a +}% +\def\xs_firstfour#1#2#3#4#5\xint_bye{#1#2#3#4}% +\def\xs_magic\if;\expandafter\noexpand\romannumeral0\xintlastitem#1#2\fi +{% +% this gets rid of spaces and an inadvertent ; except for &fp which is too +% short, but this puts a constraint on magic words, maybe I will revisit + \edef\xs_magic_in{\xs_firstfour#1\empty\empty\empty\empty\xint_bye}% + \ifcsname xs_magic@\xs_magic_in\endcsname + \csname xs_magic@\xs_magic_in\expandafter\endcsname + \else + \xs_message{(\detokenize\expandafter{\xint_gobble_i#1} is not a magic keyword: + ignored)}% + \fi\xs_fetch_a +}% +\def\xs_fetch_b#1;^% +{% + \odef\xs_in{\xs_in#1}\expandafter\xs_fetch_c +}% +\def\xs_fetch_c +{% + \if\relax\romannumeral`""@\detokenize\expandafter{\xs_in}\relax\expandafter\xs_pause\fi + \expandafter\xs_parse_a\xs_in:=^% +}% +\def\xs_pause\expandafter\xs_parse_a\xs_in:=^{\xs_pause_a\xs_fetch_a}% +\def\xs_pause_a\xs_fetch_a +{% + \xs_message{Need a break? OK, use \string\xintresume\space if you change your mind.}% + \xs_resetcats +}% +\def\xs_bye\xs_fetch_a +{% + \xs_message{Did I say something wrong?}% + \xs_message{Session transcript written on \xs_name}% +% \xs_resetcats + \immediate\closeout\xs_out +% expeditive exit because I need to think about generating new output +% filename with a check that it is not same (a minute may be too coarse?). +% Add random postfix? or simply do not bother rather... + \csname bye\endcsname +}% +\def\xs_parse_a#1:=#2% +{% + \xint_gob_til_^#2\xs_calc ^% + \def\xs_left{#1}\xs_parse_b#2% +}% +\def\xs_calc ^#1^% +{% + \edef\xs_no{\the\numexpr1+\xs_no}% + \xs_xintdefvar @_\xs_no=\xs_in;% + \immediate\write\xs_out + {\expandafter\string\xs_xintdefvar\space @_\xs_no:=% + \detokenize\expandafter{\xs_in};}% + \XINT_expr_defvar_one{@___}{\csname XINT_expr_varvalue_@__\endcsname}% + \XINT_expr_defvar_one{@__}{\csname XINT_expr_varvalue_@_\endcsname}% + \XINT_expr_defvar_one{@_}{\csname XINT_expr_varvalue_@_\xs_no\endcsname}% + \xs_message{(@_\xs_no)\space\space\space\space\xs_xinteval{@_\xs_no}}% + \xs_fetch +}% +\def\xs_parse_b #1:=^% +{% + \def\xs_right{#1}\expandafter\xs_parse_c\xs_left(;% +}% +\def\xs_parse_c #1(#2% +{% + \edef\xs_funcname{\expandafter\xint_zapspaces\detokenize{#1} \xint_gobble_i}% + \xint_gob_til_sc#2\xs_defvar;\xs_deffunc +}% +\def\xs_deffunc #1;% +{% +% attention: \xs_xintdeffunc needs to see parentheses immediately + \expandafter\xs_xintdeffunc\xs_left=\xs_right;% + \immediate\write\xs_out + {\expandafter\string\xs_xintdeffunc\space\detokenize\expandafter{\xs_left}:=% + \detokenize\expandafter{\xs_right};}% + \expandafter\ifx\xs_xintdeffunc\poldef + \xs_message{\xs_funcname\space = \PolToExpr{\xs_funcname}}% + \xs_message{Issue \string\PolGenFloatVariant{\xs_funcname} if fp evaluations + with \xs_funcname\space are intended}% + \else\xs_message{Function \xs_funcname\space defined}% + \fi\xs_fetch +}% +\def\xs_defvar;\xs_deffunc +{% + \edef\xs_no{\the\numexpr1+\xs_no}% + \xs_xintdefvar @_\xs_no=\xs_right;% + \immediate\write\xs_out + {\expandafter\string\xs_xintdefvar\space\detokenize\expandafter{\xs_left}:=% + \detokenize\expandafter{\xs_right};}% + \XINT_expr_defvar_one{@___}{\csname XINT_expr_varvalue_@__\endcsname}% + \XINT_expr_defvar_one{@__}{\csname XINT_expr_varvalue_@_\endcsname}% + \XINT_expr_defvar_one{@_}{\csname XINT_expr_varvalue_@_\xs_no\endcsname}% + % this is to allow multiple assignments + \expandafter\xs_xintdefvar\xs_left=@_\xs_no;% + \xs_message{(@_\xs_no)\space\space\space\space\xs_xinteval{@_\xs_no}}% + \xs_fetch +}% +\let\xs_magic@&pau\xs_pause_a +\let\xs_magic@&bye\xs_bye +\def\xs_magic@&fp +{% + \xs_message{fp mode (\xinttheDigits\space digits)}% + \def\xs_mode{fp}% + \def\xs_xintdefvar{\xintdeffloatvar}% + \def\xs_xintdeffunc{\xintdeffloatfunc}% + \def\xs_xinteval{\xintfloateval}% +}% +\expandafter\def\csname xs_magic@&fp1\endcsname +{% + \xintDigits*:=16;% + \xs_message{fp16 mode (trig reloaded)}% + \def\xs_mode{fp16}% + \def\xs_xintdefvar{\xintdeffloatvar}% + \def\xs_xintdeffunc{\xintdeffloatfunc}% + \def\xs_xinteval{\xintfloateval}% +}% +\expandafter\def\csname xs_magic@&fp2\endcsname +{% + \xintDigits*:=24;% + \xs_message{fp24 mode (trig reloaded)}% + \def\xs_mode{fp24}% + \def\xs_xintdefvar{\xintdeffloatvar}% + \def\xs_xintdeffunc{\xintdeffloatfunc}% + \def\xs_xinteval{\xintfloateval}% +}% +\expandafter\def\csname xs_magic@&fp3\endcsname +{% + \xintDigits*:=32;% + \xs_message{fp32 mode (trig reloaded)}% + \def\xs_mode{fp32}% + \def\xs_xintdefvar{\xintdeffloatvar}% + \def\xs_xintdeffunc{\xintdeffloatfunc}% + \def\xs_xinteval{\xintfloateval}% +}% +\def\xs_magic@&exa +{% + \xs_message{exact mode (floating point evaluations use \xinttheDigits\space digits)}% + \def\xs_mode{exact}% + \def\xs_xintdefvar{\xintdefvar}% + \def\xs_xintdeffunc{\xintdeffunc}% + \def\xs_xinteval{\xinteval}% +}% +\def\xs_magic@&int +{% + \xs_message{int mode (integer only: / rounds, // is floored division, /: is modulo)}% + \def\xs_mode{int}% + \def\xs_xintdefvar{\xintdefiivar}% + \def\xs_xintdeffunc{\xintdefiifunc}% + \def\xs_xinteval{\xintiieval}% +}% +\def\xs_magic@&pol +{% + \xs_message{pol mode (i.e. function definitions use \string\poldef)}% + \def\xs_mode{pol}% + \def\xs_xintdefvar{\xintdefvar}% + \def\xs_xintdeffunc{\poldef}% + \def\xs_xinteval{\xinteval}% +}% +\def\xs_magic@&mod{\xs_message{current mode: \xs_mode}}% +\def\xs_setcats +{% + \newlinechar10\endlinechar13% + \catcode13\active\catcode`@ 11\relax +}% +\def\xs_storecats{\edef\xs_resetcats +{% + \newlinechar\the\newlinechar + \endlinechar\the\endlinechar + \catcode13=\the\catcode13 + \catcode`@\the\catcode`@\relax +}}% +\begingroup +\catcode13\active\catcode32\active% +\gdef\xintstart{\edef {\string }\xs_setcats\def +{""J}\message{\xs_logo + Welcome to xintexpr interactive mode! + + - input is `;'-terminated and can extend over multiple lines, + - definitions must be done using the `:=' syntax, not `='. + + Any line starting with a control sequence is executed in the + background, interrupted numerical input resumes at next prompt. + + To pause, say either `;' or `&pause'. + To quit, say `&bye'. + For help say `&help'. + Starting in}\xs_magic@&exa\let +=\xs_fetch}\gdef\xintresume{\edef {\string }\xs_storecats\xs_setcats% +\message{Welcome back to xintexpr interactive mode!}\let +=\xs_fetch}\gdef\xs_help\xs_fetch_a{\def +{""J}\edef {\string }\message{% + - Terminate inputs using the `;' character. + + - Input can extend over multiple lines ( terminated). + + - An empty input (`;' terminated) or the magic word `&pause' puts + the session on hold and switches to normal TeX interaction. + Use \string\xintresume to resume the session. + + - The numerical engine can work in various modes: + * exact mode means using \string\xintexpr context, + * fp mode uses \string\xintfloatexpr, + * int mode uses integer-only \string\xintiiexpr, + * pol mode makes function definitions using \string\poldef. + To activate a mode enter `&' at the prompt + + - Lines starting with any control sequence are handed over to + TeX, and numerical input resumes on next line. + + - To change the floating point precision enter at the prompt: + \string\xintDigits*:= ; + then at next prompt switch to fp mode using `&fp'. + This can be done in the midst of a computation! + +(1/5) HIT KEY +}\let +=\xs_help_b}\gdef\xs_help_b{\def +{""J}\message{% + - Specific toggles `&fp16', `&fp24', `&fp32' are already predefined. + + - Issue `&mode' if you forgot in what mode you are currently in. + + - Definitions (variables or functions) are done using `:='. + + IMPORTANT: currently, using a `=' by oversight will cause + breakage because xintsession thinks it is then a numerical + evaluation, not a definition, but there is no `=' operator in + xintexpr syntax. + + Perhaps in future it will be allowed to make definitions using + `=' and xintsession will check if it is not misinterpreting a + `=' from `<=', `>=', `!=', `==' or `seq()' syntax but this + currently was considered to add too much overhead for the + benefit. + + - Parentheses present before the `:=' trigger a function + definition, else a variable definition is done. + +(2/5) HIT KEY +}\let +=\xs_help_c}\gdef\xs_help_c{\def +{""J}\message{% + - Functions defined in one mode are not available for usage in other + modes without further steps; check xintexpr doc. + + - Polynomial definitions (pol mode) are function definitions + (see polexpr documentation). To use a polynomial also as a + numerical function when back in `fp' mode, issue + \string\PolGenFloatVariant{} at the prompt. + + - Variables defined in any mode can be used in any mode except: + * polynomials can be used as variables only in the pol and the + exact modes, + * integer only mode requires... integer only variables! + One can use num() wrapper see xintexpr documentation. + + - Whenever a variable is defined, or a computation is performed, + the result is assigned a label @_. These automatic + variables can then be used in subsequent computations. + + - In the case of a multi-variable assignment (see xintexpr doc) + the automatic variable @_ holds the whole thing, which + may be a nutple or an ople, in addition to individual variables. + +(3/5) HIT KEY +}\let +=\xs_help_d}\gdef\xs_help_d{\def +{""J}\message{% + - The special variables @_, @__, and @___ hold the last, next + to last and next to next to last evaluation results. + + Known issues: + + - The [P] optional argument of \string\xintfloateval can not + be used because it is not recognized by \string\xintdeffloatvar, + one can use the float() function with its second argument. + + - Sometimes one wishes to use \string\xintexpr...\string\relax wrapper + inside fp mode; this is possible but can not be first in current + input line as it would trigger control sequence execution. Start + with 0+ or use parentheses. + + - The output format of the exact and fp mode is not yet decided + at upstream xintexpr; in particular trailing zeros are not + trimmed and floating point numbers are printed in diverging + ways in exact vs fp modes. Besides, the exact mode does + not do a systematic reduction to lowest terms. Use the + reduce() function (or preduce()). + + - By default, the ** and ^ operators operate only with integer + exponents in exact mode and with half-integers in fp mode. + Fractional powers are available via the pow(x,a) function. +(4/5) HIT KEY +}\let +=\xs_help_e}\gdef\xs_help_e{\def +{""J}\message{% + Known issues (cont.): + + - Refer to xintexpr \string\poormanloghack documentation on + how to let fractional powers be available with ** or ^, + and check polexpr documentation for related information. + + - A session transcript file is created which can be executed by + eTeX to redo all calculations; however @_, @__, and @__ + will not be defined in this context so need to be manually + replaced by the suitable @_. + + Future: + + - a plot() function will be added at some point to export + coordinates into a tex file for usage either with PSTricks or + TikZ/pgf. + + Caveat: + + Misformed xintexpr input can drop you into TeX error mode. + In that case, try escaping using `S'. It does work sometimes. + + Use `&bye' to terminate the session and the TeX run. + +(5/5) You are back to the xintexpr interactive session! (mode: \xs_mode) +}\let +=\xs_fetch\xs_fetch_a}\endgroup +\let\xs_magic@&hel\xs_help +\xsrestorecatcodes +\csname xs_storecats\endcsname +\catcode13\active\def +{\xintstart +}\endinput% -- cgit v1.2.3