diff options
Diffstat (limited to 'Master/texmf-dist')
18 files changed, 6836 insertions, 5972 deletions
diff --git a/Master/texmf-dist/doc/generic/xint/CHANGES.html b/Master/texmf-dist/doc/generic/xint/CHANGES.html index 7055bf2e04e..c55d211a14e 100644 --- a/Master/texmf-dist/doc/generic/xint/CHANGES.html +++ b/Master/texmf-dist/doc/generic/xint/CHANGES.html @@ -4,7 +4,7 @@ <meta charset="utf-8" /> <meta name="generator" content="pandoc" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" /> - <meta name="author" content="xint 1.4k" /> + <meta name="author" content="xint 1.4l" /> <title>CHANGE LOG</title> <style> html { @@ -170,35 +170,44 @@ <body> <header id="title-block-header"> <h1 class="title">CHANGE LOG</h1> -<p class="author">xint 1.4k</p> -<p class="date">2022/05/18</p> +<p class="author">xint 1.4l</p> +<p class="date">2022/05/29</p> </header> <nav id="TOC" role="doc-toc"> <ul> +<li><a href="#l-20220529" +id="toc-l-20220529"><code>1.4l (2022/05/29)</code></a> +<ul> +<li><a href="#bug-fixes" id="toc-bug-fixes">Bug fixes</a></li> +<li><a href="#new-features" id="toc-new-features">New features</a></li> +<li><a href="#documentation" +id="toc-documentation">Documentation</a></li> +</ul></li> <li><a href="#k-20220518" id="toc-k-20220518"><code>1.4k (2022/05/18)</code></a> <ul> <li><a href="#breaking-changes" id="toc-breaking-changes">Breaking changes</a></li> -<li><a href="#bug-fixes" id="toc-bug-fixes">Bug fixes</a></li> -<li><a href="#new-features" id="toc-new-features">New features</a></li> +<li><a href="#bug-fixes-1" id="toc-bug-fixes-1">Bug fixes</a></li> +<li><a href="#new-features-1" id="toc-new-features-1">New +features</a></li> </ul></li> <li><a href="#j-20210713" id="toc-j-20210713"><code>1.4j (2021/07/13)</code></a> <ul> -<li><a href="#bug-fixes-1" id="toc-bug-fixes-1">Bug fixes</a></li> +<li><a href="#bug-fixes-2" id="toc-bug-fixes-2">Bug fixes</a></li> </ul></li> <li><a href="#i-20210611" id="toc-i-20210611"><code>1.4i (2021/06/11)</code></a> <ul> -<li><a href="#new-features-1" id="toc-new-features-1">New +<li><a href="#new-features-2" id="toc-new-features-2">New features</a></li> -<li><a href="#bug-fixes-2" id="toc-bug-fixes-2">Bug fixes</a></li> +<li><a href="#bug-fixes-3" id="toc-bug-fixes-3">Bug fixes</a></li> </ul></li> <li><a href="#h-20210527" id="toc-h-20210527"><code>1.4h (2021/05/27)</code></a> <ul> -<li><a href="#bug-fixes-3" id="toc-bug-fixes-3">Bug fixes</a></li> +<li><a href="#bug-fixes-4" id="toc-bug-fixes-4">Bug fixes</a></li> </ul></li> <li><a href="#g-20210525" id="toc-g-20210525"><code>1.4g (2021/05/25)</code></a> @@ -206,54 +215,54 @@ id="toc-g-20210525"><code>1.4g (2021/05/25)</code></a> <li><a href="#breaking-changes-1" id="toc-breaking-changes-1">Breaking changes</a></li> <li><a href="#deprecated" id="toc-deprecated">Deprecated</a></li> -<li><a href="#new-features-2" id="toc-new-features-2">New +<li><a href="#new-features-3" id="toc-new-features-3">New features</a></li> -<li><a href="#bug-fixes-4" id="toc-bug-fixes-4">Bug fixes</a></li> +<li><a href="#bug-fixes-5" id="toc-bug-fixes-5">Bug fixes</a></li> </ul></li> <li><a href="#f-20210510" id="toc-f-20210510"><code>1.4f (2021/05/10)</code></a> <ul> <li><a href="#breaking-changes-2" id="toc-breaking-changes-2">Breaking changes</a></li> -<li><a href="#bug-fixes-5" id="toc-bug-fixes-5">Bug fixes</a></li> +<li><a href="#bug-fixes-6" id="toc-bug-fixes-6">Bug fixes</a></li> </ul></li> <li><a href="#e-20210505" id="toc-e-20210505"><code>1.4e (2021/05/05)</code></a> <ul> <li><a href="#breaking-changes-3" id="toc-breaking-changes-3">Breaking changes</a></li> -<li><a href="#new-features-3" id="toc-new-features-3">New +<li><a href="#new-features-4" id="toc-new-features-4">New features</a></li> -<li><a href="#bug-fixes-6" id="toc-bug-fixes-6">Bug fixes</a></li> +<li><a href="#bug-fixes-7" id="toc-bug-fixes-7">Bug fixes</a></li> </ul></li> <li><a href="#d-20210329" id="toc-d-20210329"><code>1.4d (2021/03/29)</code></a> <ul> <li><a href="#breaking-changes-4" id="toc-breaking-changes-4">Breaking changes</a></li> -<li><a href="#bug-fixes-7" id="toc-bug-fixes-7">Bug fixes</a></li> +<li><a href="#bug-fixes-8" id="toc-bug-fixes-8">Bug fixes</a></li> </ul></li> <li><a href="#c-20210220" id="toc-c-20210220"><code>1.4c (2021/02/20)</code></a> <ul> -<li><a href="#bug-fixes-8" id="toc-bug-fixes-8">Bug fixes</a></li> +<li><a href="#bug-fixes-9" id="toc-bug-fixes-9">Bug fixes</a></li> </ul></li> <li><a href="#b-20200225" id="toc-b-20200225"><code>1.4b (2020/02/25)</code></a> <ul> <li><a href="#future" id="toc-future">Future</a></li> -<li><a href="#new-features-4" id="toc-new-features-4">New +<li><a href="#new-features-5" id="toc-new-features-5">New features</a></li> -<li><a href="#bug-fixes-9" id="toc-bug-fixes-9">Bug fixes</a></li> +<li><a href="#bug-fixes-10" id="toc-bug-fixes-10">Bug fixes</a></li> </ul></li> <li><a href="#a-20200219" id="toc-a-20200219"><code>1.4a (2020/02/19)</code></a> <ul> <li><a href="#breaking-changes-5" id="toc-breaking-changes-5">Breaking changes</a></li> -<li><a href="#new-features-5" id="toc-new-features-5">New +<li><a href="#new-features-6" id="toc-new-features-6">New features</a></li> -<li><a href="#bug-fixes-10" id="toc-bug-fixes-10">Bug fixes</a></li> +<li><a href="#bug-fixes-11" id="toc-bug-fixes-11">Bug fixes</a></li> </ul></li> <li><a href="#section" id="toc-section"><code>1.4 (2020/01/31)</code></a> @@ -263,7 +272,7 @@ changes</a></li> <li><a href="#improvements-and-new-features" id="toc-improvements-and-new-features">Improvements and new features</a></li> -<li><a href="#bug-fixes-11" id="toc-bug-fixes-11">Bug fixes</a></li> +<li><a href="#bug-fixes-12" id="toc-bug-fixes-12">Bug fixes</a></li> <li><a href="#todo" id="toc-todo">TODO</a></li> </ul></li> <li><a href="#f-20190910" @@ -272,7 +281,7 @@ id="toc-f-20190910"><code>1.3f (2019/09/10)</code></a> <li><a href="#improvements-and-new-features-1" id="toc-improvements-and-new-features-1">Improvements and new features</a></li> -<li><a href="#bug-fixes-12" id="toc-bug-fixes-12">Bug fixes</a></li> +<li><a href="#bug-fixes-13" id="toc-bug-fixes-13">Bug fixes</a></li> </ul></li> <li><a href="#e-20190405" id="toc-e-20190405"><code>1.3e (2019/04/05)</code></a> @@ -282,7 +291,7 @@ changes</a></li> <li><a href="#improvements-and-new-features-2" id="toc-improvements-and-new-features-2">Improvements and new features</a></li> -<li><a href="#bug-fixes-13" id="toc-bug-fixes-13">Bug fixes</a></li> +<li><a href="#bug-fixes-14" id="toc-bug-fixes-14">Bug fixes</a></li> </ul></li> <li><a href="#d-20190106" id="toc-d-20190106"><code>1.3d (2019/01/06)</code></a> @@ -292,7 +301,7 @@ changes</a></li> <li><a href="#improvements-and-new-features-3" id="toc-improvements-and-new-features-3">Improvements and new features</a></li> -<li><a href="#bug-fixes-14" id="toc-bug-fixes-14">Bug fixes</a></li> +<li><a href="#bug-fixes-15" id="toc-bug-fixes-15">Bug fixes</a></li> </ul></li> <li><a href="#c-20180617" id="toc-c-20180617"><code>1.3c (2018/06/17)</code></a> @@ -300,7 +309,7 @@ id="toc-c-20180617"><code>1.3c (2018/06/17)</code></a> <li><a href="#improvements-and-new-features-4" id="toc-improvements-and-new-features-4">Improvements and new features</a></li> -<li><a href="#bug-fixes-15" id="toc-bug-fixes-15">Bug fixes</a></li> +<li><a href="#bug-fixes-16" id="toc-bug-fixes-16">Bug fixes</a></li> </ul></li> <li><a href="#b-20180518" id="toc-b-20180518"><code>1.3b (2018/05/18)</code></a> @@ -316,7 +325,7 @@ id="toc-a-20180307"><code>1.3a (2018/03/07)</code></a> <li><a href="#improvements-and-new-features-6" id="toc-improvements-and-new-features-6">Improvements and new features</a></li> -<li><a href="#bug-fixes-16" id="toc-bug-fixes-16">Bug fixes</a></li> +<li><a href="#bug-fixes-17" id="toc-bug-fixes-17">Bug fixes</a></li> </ul></li> <li><a href="#section-1" id="toc-section-1"><code>1.3 (2018/03/01)</code></a> @@ -333,7 +342,7 @@ id="toc-q-20180206"><code>1.2q (2018/02/06)</code></a> <li><a href="#improvements-and-new-features-8" id="toc-improvements-and-new-features-8">Improvements and new features</a></li> -<li><a href="#bug-fixes-17" id="toc-bug-fixes-17">Bug fixes</a></li> +<li><a href="#bug-fixes-18" id="toc-bug-fixes-18">Bug fixes</a></li> </ul></li> <li><a href="#p-20171205" id="toc-p-20171205"><code>1.2p (2017/12/05)</code></a> @@ -343,7 +352,7 @@ changes</a></li> <li><a href="#improvements-and-new-features-9" id="toc-improvements-and-new-features-9">Improvements and new features</a></li> -<li><a href="#bug-fixes-18" id="toc-bug-fixes-18">Bug fixes</a></li> +<li><a href="#bug-fixes-19" id="toc-bug-fixes-19">Bug fixes</a></li> </ul></li> <li><a href="#o-20170829" id="toc-o-20170829"><code>1.2o (2017/08/29)</code></a> @@ -369,7 +378,7 @@ changes</a></li> <li><a href="#improvements-and-new-features-11" id="toc-improvements-and-new-features-11">Improvements and new features</a></li> -<li><a href="#bug-fixes-19" id="toc-bug-fixes-19">Bug fixes</a></li> +<li><a href="#bug-fixes-20" id="toc-bug-fixes-20">Bug fixes</a></li> </ul></li> <li><a href="#l-20170726" id="toc-l-20170726"><code>1.2l (2017/07/26)</code></a> @@ -378,7 +387,7 @@ id="toc-l-20170726"><code>1.2l (2017/07/26)</code></a> <li><a href="#improvements-and-new-features-12" id="toc-improvements-and-new-features-12">Improvements and new features</a></li> -<li><a href="#bug-fixes-20" id="toc-bug-fixes-20">Bug fixes</a></li> +<li><a href="#bug-fixes-21" id="toc-bug-fixes-21">Bug fixes</a></li> </ul></li> <li><a href="#k-20170106" id="toc-k-20170106"><code>1.2k (2017/01/06)</code></a> @@ -388,7 +397,7 @@ changes</a></li> <li><a href="#improvements-and-new-features-13" id="toc-improvements-and-new-features-13">Improvements and new features</a></li> -<li><a href="#bug-fixes-21" id="toc-bug-fixes-21">Bug fixes</a></li> +<li><a href="#bug-fixes-22" id="toc-bug-fixes-22">Bug fixes</a></li> </ul></li> <li><a href="#j-20161222" id="toc-j-20161222"><code>1.2j (2016/12/22)</code></a> @@ -396,7 +405,7 @@ id="toc-j-20161222"><code>1.2j (2016/12/22)</code></a> <li><a href="#improvements-and-new-features-14" id="toc-improvements-and-new-features-14">Improvements and new features</a></li> -<li><a href="#bug-fixes-22" id="toc-bug-fixes-22">Bug fixes</a></li> +<li><a href="#bug-fixes-23" id="toc-bug-fixes-23">Bug fixes</a></li> </ul></li> <li><a href="#i-20161213" id="toc-i-20161213"><code>1.2i (2016/12/13)</code></a> @@ -407,7 +416,7 @@ changes</a></li> <li><a href="#improvements-and-new-features-15" id="toc-improvements-and-new-features-15">Improvements and new features</a></li> -<li><a href="#bug-fixes-23" id="toc-bug-fixes-23">Bug fixes</a></li> +<li><a href="#bug-fixes-24" id="toc-bug-fixes-24">Bug fixes</a></li> </ul></li> <li><a href="#h-20161120" id="toc-h-20161120"><code>1.2h (2016/11/20)</code></a> @@ -415,7 +424,7 @@ id="toc-h-20161120"><code>1.2h (2016/11/20)</code></a> <li><a href="#improvements-and-new-features-16" id="toc-improvements-and-new-features-16">Improvements and new features</a></li> -<li><a href="#bug-fixes-24" id="toc-bug-fixes-24">Bug fixes</a></li> +<li><a href="#bug-fixes-25" id="toc-bug-fixes-25">Bug fixes</a></li> </ul></li> <li><a href="#g-20160319" id="toc-g-20160319"><code>1.2g (2016/03/19)</code></a> @@ -434,7 +443,7 @@ changes</a></li> <li><a href="#improvements-and-new-features-18" id="toc-improvements-and-new-features-18">Improvements and new features</a></li> -<li><a href="#bug-fixes-25" id="toc-bug-fixes-25">Bug fixes</a></li> +<li><a href="#bug-fixes-26" id="toc-bug-fixes-26">Bug fixes</a></li> </ul></li> <li><a href="#e-20151122" id="toc-e-20151122"><code>1.2e (2015/11/22)</code></a> @@ -442,7 +451,7 @@ id="toc-e-20151122"><code>1.2e (2015/11/22)</code></a> <li><a href="#improvements-and-new-features-19" id="toc-improvements-and-new-features-19">Improvements and new features</a></li> -<li><a href="#bug-fixes-26" id="toc-bug-fixes-26">Bug fixes</a></li> +<li><a href="#bug-fixes-27" id="toc-bug-fixes-27">Bug fixes</a></li> </ul></li> <li><a href="#d-20151118" id="toc-d-20151118"><code>1.2d (2015/11/18)</code></a> @@ -450,7 +459,7 @@ id="toc-d-20151118"><code>1.2d (2015/11/18)</code></a> <li><a href="#improvements-and-new-features-20" id="toc-improvements-and-new-features-20">Improvements and new features</a></li> -<li><a href="#bug-fixes-27" id="toc-bug-fixes-27">Bug fixes</a></li> +<li><a href="#bug-fixes-28" id="toc-bug-fixes-28">Bug fixes</a></li> </ul></li> <li><a href="#c-20151116" id="toc-c-20151116"><code>1.2c (2015/11/16)</code></a> @@ -458,12 +467,12 @@ id="toc-c-20151116"><code>1.2c (2015/11/16)</code></a> <li><a href="#improvements-and-new-features-21" id="toc-improvements-and-new-features-21">Improvements and new features</a></li> -<li><a href="#bug-fixes-28" id="toc-bug-fixes-28">Bug fixes</a></li> +<li><a href="#bug-fixes-29" id="toc-bug-fixes-29">Bug fixes</a></li> </ul></li> <li><a href="#b-20151029" id="toc-b-20151029"><code>1.2b (2015/10/29)</code></a> <ul> -<li><a href="#bug-fixes-29" id="toc-bug-fixes-29">Bug fixes</a></li> +<li><a href="#bug-fixes-30" id="toc-bug-fixes-30">Bug fixes</a></li> </ul></li> <li><a href="#a-20151019" id="toc-a-20151019"><code>1.2a (2015/10/19)</code></a> @@ -471,7 +480,7 @@ id="toc-a-20151019"><code>1.2a (2015/10/19)</code></a> <li><a href="#improvements-and-new-features-22" id="toc-improvements-and-new-features-22">Improvements and new features</a></li> -<li><a href="#bug-fixes-30" id="toc-bug-fixes-30">Bug fixes</a></li> +<li><a href="#bug-fixes-31" id="toc-bug-fixes-31">Bug fixes</a></li> </ul></li> <li><a href="#section-2" id="toc-section-2"><code>1.2 (2015/10/10)</code></a> @@ -497,7 +506,7 @@ changes</a></li> <li><a href="#improvements-and-new-features-24" id="toc-improvements-and-new-features-24">Improvements and new features</a></li> -<li><a href="#bug-fixes-31" id="toc-bug-fixes-31">Bug fixes</a></li> +<li><a href="#bug-fixes-32" id="toc-bug-fixes-32">Bug fixes</a></li> </ul></li> <li><a href="#n-20140401" id="toc-n-20140401"><code>1.09n (2014/04/01)</code></a></li> @@ -549,17 +558,68 @@ id="toc-section-9"><code>1.03 (2013/04/14)</code></a></li> id="toc-section-10"><code>1.0 (2013/03/28)</code></a></li> </ul> </nav> -<pre><code>Source: xint.dtx 1.4k 2022/05/18 (doc 2022/05/18) +<pre><code>Source: xint.dtx 1.4l 2022/05/29 (doc 2022/05/29) Author: Jean-Francois Burnol Info: Expandable operations on big integers, decimals, fractions License: LPPL 1.3c</code></pre> +<h2 id="l-20220529"><code>1.4l (2022/05/29)</code></h2> +<h3 id="bug-fixes">Bug fixes</h3> +<ul> +<li><p><strong>xintkernel</strong>: ever since <code>1.4</code>, loading +anyone of the <code>xint*sty</code> packages left the catcode of the +character of ascii code <code>1</code> to the internal custom value +<code>3</code>.</p></li> +<li><p><strong>xintfrac</strong>: the <code>\xintPFloat</code> checks +for an output being an integer in decimal notation or a number with a +one-digit trimmed mantissa could fail if +<code>\xintPFloatMinTrimmed</code> (added at <code>1.4k</code>) was +large enough, e.g. equal to the target precision. Then, the outputs +always kept trailing zeros, as expected in general but not for those +special cases.</p></li> +<li><p><strong>xintlog</strong>, <strong>xinttrig</strong>: since +<code>1.4e</code> the message emitted if +<code>\usepackage{xintlog}</code> or <code>\usepackage{xinttrig}</code> +was encountered in place of the correct +<code>\usepackage{xintexpr}</code> was wrong. It advised to use +<code>\input xintexpr.sty\relax</code>, which would have failed with +LaTeX. The warning is corrected and now the macro file in place of +aborting will (be it with or without LaTeX) trigger the loading of +<code>xintexpr</code> (hence of itself after it).</p></li> +<li><p>The possibility to run <code>latex</code> directly on +<code>xint.dtx</code> had been broken since <code>1.4i</code>.</p></li> +</ul> +<h3 id="new-features">New features</h3> +<ul> +<li><p><strong>xintfrac</strong>: <code>\xintRawBraced</code> as a +public alias to an <strong>xintfrac</strong> entry point to its core +input handler. Experimental additions <code>\xintSignBit</code> and +<code>\xintFloatBraced</code>. Deprecate <code>\xintTeXfromSci</code> in +favor of new name <code>\xintTeXFromSci</code>, and remove its +<code>\expanded</code> wrapper (so it is not f-expandable anymore). Add +<code>\xintTeXFromScifracmacro</code>.</p></li> +<li><p><strong>xintfrac</strong>, <strong>xintexpr</strong>: +<code>\xintFracToSci</code> and <code>\xintFracToDecimal</code> now +behave like all other <strong>xintfrac</strong> macros in terms of +allowed arguments and f-expandability and have been moved back to +<strong>xintfrac</strong>.</p></li> +</ul> +<h3 id="documentation">Documentation</h3> +<ul> +<li><p>Renewed random shuffling of large parts of the documentation has +greatly improved it.</p></li> +<li><p>Simpler build flow to produce a <code>pdf</code> containing both +user manual and source code. Removal of dependency on <code>grep</code> +binary for such builds or the one of <code>sourcexint.pdf</code>. Fix of +various obsoleted comments in extracted files involved in the +documentation build process.</p></li> +</ul> <h2 id="k-20220518"><code>1.4k (2022/05/18)</code></h2> <h3 id="breaking-changes">Breaking changes</h3> <ul> <li><p><strong>xintfrac</strong>: the longstanding (but documented as undecided and unstable) way of <code>\xintFloat</code> to output the zero value was <code>0.e0</code> and it has now been modified into -<code>0.0e0</code>. Customizable via +<code>0.0e0</code>. Now customizable via <code>\xintFloatZero</code>.</p></li> <li><p><strong>xintfrac</strong>/<strong>xintexpr</strong>: the behaviour of <code>\xintPFloat</code> (hence of @@ -572,17 +632,17 @@ with a single-digit (trimmed) mantissa, no <code>.0</code> is used.</p> <code>\xintPFloatLengthOneSuffix</code>, and <code>\xintPFloatZero</code>.</p> <p>Also, <code>\xintPFloat</code> trims trailing zeros from the full -significand only if there are at least <code>4</code> of them, see -<code>\xintPFloatMinTrimmed</code>.</p></li> -<li><p><strong>xintfrac</strong>/<strong>xintexpr</strong>: definition -of <code>\xintFracToSci</code> migrated from the former to the -latter.</p></li> +significand only if there are, by default, at least <code>4</code> of +them, see <code>\xintPFloatMinTrimmed</code>.</p></li> +<li><p><strong>xintfrac</strong>/<strong>xintexpr</strong>: macro +definition of <code>\xintFracToSci</code> migrated from the former to +the latter (see <code>1.4l</code> for update).</p></li> <li><p><strong>xintexpr</strong>: <code>\xintexpr{Safe,Restore}Catcodes</code> pairs now behave like a “last in first out” stack. Check the <code>pdf</code> documentation for details.</p></li> </ul> -<h3 id="bug-fixes">Bug fixes</h3> +<h3 id="bug-fixes-1">Bug fixes</h3> <ul> <li><p><strong>xintexpr</strong>: the <code>\xintexpr{Safe,Restore}Catcodes</code> were documented at user @@ -596,7 +656,7 @@ modified).</p></li> reset the catcodes to their status prior to the sanitization done by the macro at the start of its execution.</p></li> </ul> -<h3 id="new-features">New features</h3> +<h3 id="new-features-1">New features</h3> <ul> <li><p><strong>xintfrac</strong>: <code>\xintPFloatZero</code>, <code>\xintPFloatIntSuffix</code>, @@ -609,7 +669,7 @@ expression). Also added <code>\xintFloatZero</code>.</p></li> <li><p><strong>xintfrac</strong>: <code>\xintFloatToDecimal</code>.</p></li> <li><p><strong>xintexpr</strong>: <code>\xintFracToDecimal</code>, an -alternative to <code>\xintFracToSci</code> for the configuration of +alternative to the default <code>\xintFracToSci</code> configuration of <code>\xintexprPrintOne</code>.</p></li> <li><p><strong>xintexpr</strong>: long awaited syntax <code>\xintieval[D]{...}</code> and <code>\xintfloateval[Q]{...}</code> @@ -618,7 +678,7 @@ and <code>\xintfloateval{[Q]...}</code> is kept for backwards compatibility.</p></li> </ul> <h2 id="j-20210713"><code>1.4j (2021/07/13)</code></h2> -<h3 id="bug-fixes-1">Bug fixes</h3> +<h3 id="bug-fixes-2">Bug fixes</h3> <ul> <li><strong>xinttools</strong>: a brace removal bug affected the venerable <code>\xintSeq</code> if producing a single number @@ -626,7 +686,7 @@ venerable <code>\xintSeq</code> if producing a single number <code>{10}</code>). Thanks to Christophe Poulain for report.</li> </ul> <h2 id="i-20210611"><code>1.4i (2021/06/11)</code></h2> -<h3 id="new-features-1">New features</h3> +<h3 id="new-features-2">New features</h3> <ul> <li><p><strong>xintexpr</strong>: the concept of simultaneous assignments is extended: in case of more variables than values the @@ -641,7 +701,7 @@ single numeric argument: since <code>1.4</code> a lone argument had to be a <code>nutple</code> (which was automatically unpacked). It can now again be a number.</p></li> </ul> -<h3 id="bug-fixes-2">Bug fixes</h3> +<h3 id="bug-fixes-3">Bug fixes</h3> <ul> <li><p><strong>xintexpr</strong>: simultaneous assignments via <code>\xintdefvar</code> to 10 or more variables was broken if the right @@ -662,7 +722,7 @@ variables (currently <code>subs()</code>, <code>subsm()</code>, <code>seq</code>.</p></li> </ul> <h2 id="h-20210527"><code>1.4h (2021/05/27)</code></h2> -<h3 id="bug-fixes-3">Bug fixes</h3> +<h3 id="bug-fixes-4">Bug fixes</h3> <ul> <li><p><strong>xintexpr</strong>: the recent <code>1.4g</code> introduced a bug breaking input of the type @@ -697,7 +757,7 @@ way: <code>2^3^4==2^(3^4)</code>.</p></li> <code>\xintTeXOver</code>, <code>\xintTeXsignedOver</code>. The old names will emit warnings.</li> </ul> -<h3 id="new-features-2">New features</h3> +<h3 id="new-features-3">New features</h3> <ul> <li><p>Messages written to the terminal and log file during the handling of recovery from exceptions use a new mechanism; when in interactive @@ -709,7 +769,7 @@ about 7 or 8 years too late) to help typesetting values output by <code>\xintfloateval</code> in a more useful way than <code>\xintTeXFrac</code> (formerly <code>\xintFrac</code>).</p></li> </ul> -<h3 id="bug-fixes-4">Bug fixes</h3> +<h3 id="bug-fixes-5">Bug fixes</h3> <ul> <li><p><strong>xintexpr</strong>: with <strong>xintbinhex</strong> loaded, <code>"</code> is recognized as prefix for hexadecimal input; @@ -777,7 +837,7 @@ powers, see the bug fixes below.</p></li> <li><p><strong>xintexpr</strong>: the <code>float_()</code> function got renamed into <code>float_dgt()</code>.</p></li> </ul> -<h3 id="bug-fixes-5">Bug fixes</h3> +<h3 id="bug-fixes-6">Bug fixes</h3> <ul> <li><p><strong>xintexpr</strong>: the documentation said <code>float_()</code> function had been renamed <code>float_dgt()</code> @@ -863,7 +923,7 @@ pre-rounding to the Digits precision.</p></li> over the process to <code>\xintPFloat</code> (without the rounding to Digits, of course).</p></li> </ul> -<h3 id="new-features-3">New features</h3> +<h3 id="new-features-4">New features</h3> <ul> <li><p><strong>xintlog</strong>: now working up to <code>62</code> digits. The legacy faster <code>poormanlog</code>-based macros are kept @@ -888,7 +948,7 @@ the letter <code>e</code>.</p></li> like <code>\xintDecToString</code> but starts by removing trailing zeroes.</p></li> </ul> -<h3 id="bug-fixes-6">Bug fixes</h3> +<h3 id="bug-fixes-7">Bug fixes</h3> <ul> <li><strong>xintfrac</strong>, <strong>xintexpr</strong>: it was not possible to use <code>\xinttheDigits</code> in the right hand side of an @@ -910,7 +970,7 @@ applied to fractions is now always in lowest terms.</p></li> around the name. By the way, quotes were never used for function names.</p></li> </ul> -<h3 id="bug-fixes-7">Bug fixes</h3> +<h3 id="bug-fixes-8">Bug fixes</h3> <ul> <li><p>Ever since <code>1.3</code> the <code>quo()</code> and <code>rem()</code> functions in <code>\xintexpr</code> (not the ones in @@ -935,7 +995,7 @@ inside an <code>\xintdeffunc</code> caused the defined function to be broken.</p></li> </ul> <h2 id="c-20210220"><code>1.4c (2021/02/20)</code></h2> -<h3 id="bug-fixes-8">Bug fixes</h3> +<h3 id="bug-fixes-9">Bug fixes</h3> <ul> <li>Fix <code>1.4</code> regression which broke syntax <code>varname(...)</code> which supposedly is allowed and inserts a @@ -960,7 +1020,7 @@ so much better names. Besides, since <code>1.4</code>, <code>\xintexpr</code> can be used directly in typesetting flow.</p></li> </ul> -<h3 id="new-features-4">New features</h3> +<h3 id="new-features-5">New features</h3> <ul> <li><p>Function <code>zip()</code> is modeled on Python’s function of the same name.</p></li> @@ -977,7 +1037,7 @@ strangely there was no way to customize the output of <code>\xintfloateval</code>. The added <code>\xintPFloatE</code> fixes this.</p></li> </ul> -<h3 id="bug-fixes-9">Bug fixes</h3> +<h3 id="bug-fixes-10">Bug fixes</h3> <ul> <li><code>\xintieval{[D]...}</code> with a negative <code>D</code> (a feature added at <code>1.4a</code>) used erroneously a catcode 12 @@ -991,7 +1051,7 @@ feature added at <code>1.4a</code>) used erroneously a catcode 12 <li>The macros implementing customization of <code>\xintthealign</code> have modified meanings and names.</li> </ul> -<h3 id="new-features-5">New features</h3> +<h3 id="new-features-6">New features</h3> <ul> <li><p><code>\xintthespaceseparated</code> (serves to provide suitable input to PS-Tricks <code>\listplot</code>).</p></li> @@ -1004,7 +1064,7 @@ of <code>10^(-D)</code>.</p> <code>\xintRound</code>, <code>\xintiTrunc</code>, and <code>\xintiRound</code> macros of <strong>xintfrac</strong>.</p></li> </ul> -<h3 id="bug-fixes-10">Bug fixes</h3> +<h3 id="bug-fixes-11">Bug fixes</h3> <ul> <li><p>Usage of <code>round()</code> and <code>trunc()</code> within <code>\xintdeffunc</code> got broken at <code>1.4</code>.</p></li> @@ -1234,7 +1294,7 @@ example a correct variable or function name in place of the not recognized one. But don’t expect miracles when trying to intervene in the midst of a purely expandable expansion…</p></li> </ul> -<h3 id="bug-fixes-11">Bug fixes</h3> +<h3 id="bug-fixes-12">Bug fixes</h3> <p>Bugs? Those identified in <code>1.3f</code> were almost features. As per <code>1.4</code> the code base of <strong>xintexpr</strong> received multiple successive core refactorings and added numerous new features, @@ -1271,7 +1331,7 @@ token e.g. <code>\xintDigits := 32\relax</code>.</p> expressions by <code>\xintdeffunc</code>. And make them usable also inside macro definitions via <code>\xintNewExpr</code>.</p></li> </ul> -<h3 id="bug-fixes-12">Bug fixes</h3> +<h3 id="bug-fixes-13">Bug fixes</h3> <ul> <li><p><strong>xintexpr</strong>: fix bug preventing usage of <code>\xintdefefunc</code> to define a function without variables.</p> @@ -1318,7 +1378,7 @@ shortcomings.</p></li> be negative; it then means to trim (and round) from the output at float precision that many least significant digits.</p></li> </ul> -<h3 id="bug-fixes-13">Bug fixes</h3> +<h3 id="bug-fixes-14">Bug fixes</h3> <ul> <li>Some bugfixes related to user functions with no variables at all; they were dysfunctional.</li> @@ -1361,7 +1421,7 @@ value zero),</p></li> <code>\xinttheexpr...\relax</code> etc…, but with the (comma-separated) expression as a usual braced macro argument.</p></li> </ul> -<h3 id="bug-fixes-14">Bug fixes</h3> +<h3 id="bug-fixes-15">Bug fixes</h3> <ul> <li><strong>xintcore</strong>, <strong>xintexpr</strong> : division in <code>\xintiiexpr</code> was broken for a zero dividend and a one-digit @@ -1393,7 +1453,7 @@ work if that catcode is already frozen.</p></li> <code>sourcexint.pdf</code> is better hyperlinked and includes indices for the macros defined by each package.</p></li> </ul> -<h3 id="bug-fixes-15">Bug fixes</h3> +<h3 id="bug-fixes-16">Bug fixes</h3> <ul> <li><strong>xintfrac</strong>: since <code>1.3</code> release, it loaded <strong>xintgcd</strong> in contradiction to what the documentation says @@ -1444,7 +1504,7 @@ inputs having one hundred digits or more.</p></li> <code>\xintDivFloor</code>, <code>\xintMod</code>, <code>\xintModTrunc</code>, which had been left out so far.</p></li> </ul> -<h3 id="bug-fixes-16">Bug fixes</h3> +<h3 id="bug-fixes-17">Bug fixes</h3> <ul> <li><strong>xintexpr</strong>: the mechanism for adjunction to the expression parsers of user defined functions was refactored and improved @@ -1495,7 +1555,7 @@ features</h3> <li><strong>xintexpr</strong>: tacit multiplication extended to cases such as <code>3!4!5!</code> or <code>(1+2)3</code>.</li> </ul> -<h3 id="bug-fixes-17">Bug fixes</h3> +<h3 id="bug-fixes-18">Bug fixes</h3> <ul> <li><strong>xintcore</strong>: sadly, refactoring at <code>1.2l</code> of subtraction left an extra character in an inner macro causing @@ -1543,7 +1603,7 @@ built-in functions. It is associated with floored division, like the Python language <code>divmod()</code>. Related support macros added to <strong>xintcore</strong>, and <strong>xintfrac</strong>.</p></li> </ul> -<h3 id="bug-fixes-18">Bug fixes</h3> +<h3 id="bug-fixes-19">Bug fixes</h3> <ul> <li><p><strong>xintgcd</strong>: <code>\xintBezout{6}{3}</code> (for example) expanded to <code>{6}{3}{-0}{-1}{3}</code>, but the @@ -1656,7 +1716,7 @@ but limited to a few thousand digits. The <code>1.08</code> routines could handle tens of thousands of digits, but not in a reasonable time.</li> </ul> -<h3 id="bug-fixes-19">Bug fixes</h3> +<h3 id="bug-fixes-20">Bug fixes</h3> <ul> <li><p>user manual: the <code>Changes</code> section wrongly stated at <code>1.2l</code> that the macros of <strong>xintbinhex</strong> had @@ -1725,7 +1785,7 @@ in this example a second <code>\relax</code>.</p></li> interface yet, it is done in preparation for next major release and is completely unstable and undocumented.</p></li> </ul> -<h3 id="bug-fixes-20">Bug fixes</h3> +<h3 id="bug-fixes-21">Bug fixes</h3> <ul> <li><p><strong>xintbinhex</strong>: since <code>1.2 (2015/10/10)</code>, <code>\xintHexToDec</code> was broken due to an undefined macro (it was @@ -1784,7 +1844,7 @@ variables.)</p></li> improved <code>\xintNewExpr</code> compatibility. Also <code>\xintFirstItem:f:csv</code>.</p></li> </ul> -<h3 id="bug-fixes-21">Bug fixes</h3> +<h3 id="bug-fixes-22">Bug fixes</h3> <ul> <li><p>the <code>1.2f</code> half-integer powers computed within <code>\xintfloatexpr</code> had a silly rounding to the target precision @@ -1823,7 +1883,7 @@ horizontal and vertical rules which bring the documentation of the except that implementation of some math functions is still lacking.</p></li> </ul> -<h3 id="bug-fixes-22">Bug fixes</h3> +<h3 id="bug-fixes-23">Bug fixes</h3> <ul> <li>fix two <code>1.2i</code> regressions caused by undefined macros (<code>\xintNthElt</code> in certain branches and <code>[list][N]</code> @@ -1893,7 +1953,7 @@ should have been removed long ago) and uses only the more apt “macro”, as after all, all of <strong>xint</strong> is about expansion of macros (plus the use of <code>\numexpr</code>).</p></li> </ul> -<h3 id="bug-fixes-23">Bug fixes</h3> +<h3 id="bug-fixes-24">Bug fixes</h3> <ul> <li><code>\xintDecSplitL</code> and <code>\xintDecSplitR</code> from <strong>xint</strong> produced their output in a spurious brace pair @@ -1913,7 +1973,7 @@ prefix, now <code>\thexintexpr</code>, <code>\thexintiexpr</code>, <code>\thexintfloatexpr</code>, and <code>\thexintiiexpr</code> are provided as synonyms to <code>\xinttheexpr</code>, etc…</p></li> </ul> -<h3 id="bug-fixes-24">Bug fixes</h3> +<h3 id="bug-fixes-25">Bug fixes</h3> <ul> <li><p>the <code>(cond)?{foo}{bar}</code> operator from <strong>xintexpr</strong> mis-behaved in certain circumstances (such as @@ -2026,7 +2086,7 @@ initial <code>\romannumeral</code> anymore.</p></li> random shuffling of sections and well thought additions; cuts were considered and even performed.</p></li> </ul> -<h3 id="bug-fixes-25">Bug fixes</h3> +<h3 id="bug-fixes-26">Bug fixes</h3> <ul> <li><p>squaring macro <code>\xintSqr</code> from <strong>xintfrac.sty</strong> was broken due to a misspelled sub-macro @@ -2056,7 +2116,7 @@ its included code samples has been entirely re-written; the <em>Commands of the xintexpr package</em> section has been extended and reviewed entirely.</p></li> </ul> -<h3 id="bug-fixes-26">Bug fixes</h3> +<h3 id="bug-fixes-27">Bug fixes</h3> <ul> <li><p>in <strong>xintfrac</strong>: the <code>\xintFloatFac</code> from release <code>1.2</code> parsed its argument only through @@ -2082,7 +2142,7 @@ x/(2*y).</p></li> <li><p>some documentation enhancements, particularly in the chapter on xintexpr.sty, and also in the code source comments.</p></li> </ul> -<h3 id="bug-fixes-27">Bug fixes</h3> +<h3 id="bug-fixes-28">Bug fixes</h3> <ul> <li>in <strong>xintcore</strong>: release <code>1.2c</code> had inadvertently broken the <code>\xintiiDivRound</code> macro.</li> @@ -2097,14 +2157,14 @@ features</h3> <li><p>on-going code improvements and documentation enhancements, but stopped in order to issue this bugfix release.</p></li> </ul> -<h3 id="bug-fixes-28">Bug fixes</h3> +<h3 id="bug-fixes-29">Bug fixes</h3> <ul> <li>in <strong>xintcore</strong>: recent release <code>1.2</code> introduced a bug in the subtraction (happened when 00000001 was found under certain circumstances at certain mod 8 locations).</li> </ul> <h2 id="b-20151029"><code>1.2b (2015/10/29)</code></h2> -<h3 id="bug-fixes-29">Bug fixes</h3> +<h3 id="bug-fixes-30">Bug fixes</h3> <ul> <li>in <strong>xintcore</strong>: recent release <code>1.2</code> introduced a bug in the division macros, causing a crash when the @@ -2126,7 +2186,7 @@ regarding brace stripping.</p></li> <code>\romannumeral`&&@</code> (<code>^</code> being used as letter, had to find another character usable with catcode 7).</p></li> </ul> -<h3 id="bug-fixes-30">Bug fixes</h3> +<h3 id="bug-fixes-31">Bug fixes</h3> <ul> <li>in <strong>xintexpr</strong>: recent release <code>1.2</code> introduced a bad bug in the parsing of decimal numbers and as a result @@ -2409,7 +2469,7 @@ even number of items to the format expected by the <code>TikZ</code> standard macro parameter <code>#</code>. Not all constructs are compatible with <code>\xintNewExpr</code>.</p></li> </ul> -<h3 id="bug-fixes-31">Bug fixes</h3> +<h3 id="bug-fixes-32">Bug fixes</h3> <ul> <li><p><code>\xintZapFirstSpaces</code> hence also <code>\xintZapSpaces</code> from package <strong>xinttools</strong> were diff --git a/Master/texmf-dist/doc/generic/xint/README.md b/Master/texmf-dist/doc/generic/xint/README.md index 26efec3af43..b11925c2698 100644 --- a/Master/texmf-dist/doc/generic/xint/README.md +++ b/Master/texmf-dist/doc/generic/xint/README.md @@ -1,8 +1,8 @@ % README -% xint 1.4k -% 2022/05/18 +% xint 1.4l +% 2022/05/29 - Source: xint.dtx 1.4k 2022/05/18 (doc 2022/05/18) + Source: xint.dtx 1.4l 2022/05/29 (doc 2022/05/29) Author: Jean-Francois Burnol Info: Expandable operations on big integers, decimals, fractions License: LPPL 1.3c @@ -24,6 +24,14 @@ available up to 62 digits of precision. The syntax supports dummy variables (to generate sequences of values) and nested structures. Support for user-declared functions and variables is implemented. +Here is an example of everyday typical calculation by `xintexpr` users: + + \xinteval{reduce(add(1/i^3, i=1..25))} + +It expands to: + + 2560976152652211536408111110189/2131858131361319942957376000000 + Usage on the command line ========================= @@ -55,20 +63,49 @@ Installation [MikTeX](http://www.miktex.org/). Thus, use the package manager to update your distribution. -Alternatives: +The simplest alternative is to download +[`xint.tds.zip`](http://mirror.ctan.org/install/macros/generic/xint.tds.zip) +and install the `xint` package files and documentation in a suitable +TDS-compliant repertory via `unzip`. For example, on a macOS system, +installation in user repertory: + + unzip xint.tds.zip -d ~/Library/texmf + +Admin privileges may be needed when moving the files into the TeX +installation. + +Else, one can download `xint.dtx` and optionally `Makefile` from +https://www.ctan.org/tex-archive/macros/generic/xint and proceed from +there. The package files are extracted automatically from +`etex xint.dtx`. So if one does not need to build the documentation, +one only has to move the files with extension `.sty` to one's working +repertory and start using them. -- download - [`xint.tds.zip`](http://mirror.ctan.org/install/macros/generic/xint.tds.zip) - and install in a suitable TDS-compliant repertory via `unzip`. "admin" - privilges might be needed, as well as a file database rebuild (`texhash`). - For example, on macos x, installation into user home folder (no `sudo`, - and no `texhash` as it is recommended to not have a ls-R file there) +Here are various options to build the documentation, from the more +automated to the more manual: - unzip xint.tds.zip -d ~/Library/texmf +- (with `Makefile`) run `make help` or `make helpless` (on Unix-like + systems) for extracting package files and receiving further + instructions, or directly `make xint.pdf` to both extract package + files and build the user documentation in the current repertory. + The commented source code will be obtained from `make sourcexint.pdf`. + This process requires `latexmk`. The `CHANGES.html` target requires + `pandoc`. -- all files can be extracted using `etex xint.dtx`, or `make` if the - `Makefile` included in the CTAN upload is present; see the file `INSTALL`, - if present, else read the help in extracted file `Makefile.mk`. +- (without `Makefile`) run `etex xint.dtx` then rename the extracted + `Makefile.mk` to `Makefile` and proceed as in the previous item. + +- (with no `make`) run `latexmk` on `xint.dtx`. This will both extract + package files and build a `dvi` combining the user documentation and + the commented source code. Finish with `dvipdfmx xint.dvi`. + +- (with no `make`) execute `etex xint.dtx` to extract files then run + `latexmk` on `xint.tex` and `sourcexint.tex`, or perhaps on + `xint-all.tex` to combine user manual and source code in one `pdf`. + +- (with no `make` and no `latexmk`) proceed as in one of the previous + two items but with `latex` sufficiently many times in place of + `latexmk`. Finish with `dvipdfmx`, or use `pdflatex` initially. Documentation ============= @@ -83,12 +120,6 @@ Documentation `sourcexint.pdf`: commented source code (`texdoc --list xint` or `texdoc sourcexint`) -Requirements -============ - -Since release `1.4`, `xintexpr` requires the `\expanded` primitive. This -is a functionality of all major TeX engines since TeXLive 2019. - License ======= @@ -107,9 +138,10 @@ This Work has the LPPL maintenance status `author-maintained`. The Author of this Work is `Jean-Francois Burnol`. -This Work consists of the files `Makefile`, `INSTALL`, and `xint.dtx` -and its extracted and derived files inclusive of the documentation -files `xint.pdf`, `sourcexint.pdf` and `CHANGES.html`. +This Work consists of the files `xint.dtx` and `Makefile` and +extracted files inclusive of the macro files `xint*sty` as +well as derived documentation files such as `xint.pdf`, +`sourcexint.pdf` and `CHANGES.html` See `xint.pdf` for contact information. diff --git a/Master/texmf-dist/doc/generic/xint/sourcexint.pdf b/Master/texmf-dist/doc/generic/xint/sourcexint.pdf Binary files differindex 559adccd364..6c01348a46b 100644 --- a/Master/texmf-dist/doc/generic/xint/sourcexint.pdf +++ b/Master/texmf-dist/doc/generic/xint/sourcexint.pdf diff --git a/Master/texmf-dist/doc/generic/xint/xint.pdf b/Master/texmf-dist/doc/generic/xint/xint.pdf Binary files differindex 52f8052d930..0042a3091ad 100644 --- a/Master/texmf-dist/doc/generic/xint/xint.pdf +++ b/Master/texmf-dist/doc/generic/xint/xint.pdf diff --git a/Master/texmf-dist/source/generic/xint/Makefile b/Master/texmf-dist/source/generic/xint/Makefile index 185090f99d5..2bf5aaaeefd 100644 --- a/Master/texmf-dist/source/generic/xint/Makefile +++ b/Master/texmf-dist/source/generic/xint/Makefile @@ -1,5 +1,5 @@ # Makefile for building and installing xint -# (C) 2014-2021 Jean-Francois Burnol +# (C) 2014-2022 Jean-Francois Burnol # distributed under LPPL 1.3c. # Tested with GNU Make 3.81 on Mac OS X Mavericks, diff --git a/Master/texmf-dist/source/generic/xint/xint.dtx b/Master/texmf-dist/source/generic/xint/xint.dtx index 213000e7521..4235de9233a 100644 --- a/Master/texmf-dist/source/generic/xint/xint.dtx +++ b/Master/texmf-dist/source/generic/xint/xint.dtx @@ -3,27 +3,27 @@ % Extract all files via "etex xint.dtx" and do "make help" % or follow instructions from extracted README.md. %<*dtx> -\def\xintdtxtimestamp {Time-stamp: <18-05-2022 at 20:55:23 CEST>} +\def\xintdtxtimestamp {Time-stamp: <29-05-2022 at 11:55:32 CEST>} %</dtx> -%<*drv> +%<*xintdrv|sourcedrv|alldrv> %% --------------------------------------------------------------- -\def\xintdocdate {2022/05/18} -\def\xintbndldate{2022/05/18} -\def\xintbndlversion {1.4k} -%</drv> +\def\xintdocdate {2022/05/29} +\def\xintbndldate{2022/05/29} +\def\xintbndlversion {1.4l} +%</xintdrv|sourcedrv|alldrv> %<readme>% README %<changes>% CHANGE LOG -%<readme|changes>% xint 1.4k -%<readme|changes>% 2022/05/18 +%<readme|changes>% xint 1.4l +%<readme|changes>% 2022/05/29 %<readme|changes> -%<readme|changes> Source: xint.dtx 1.4k 2022/05/18 (doc 2022/05/18) +%<readme|changes> Source: xint.dtx 1.4l 2022/05/29 (doc 2022/05/29) %<readme|changes> Author: Jean-Francois Burnol %<readme|changes> Info: Expandable operations on big integers, decimals, fractions %<readme|changes> License: LPPL 1.3c %<readme|changes> %<*!readme&!changes&!dohtmlsh&!makefile> %% --------------------------------------------------------------- -%% The xint bundle 1.4k 2022/05/18 +%% The xint bundle 1.4l 2022/05/29 %% Copyright (C) 2013-2022 by Jean-Francois Burnol %<xintkernel>%% xintkernel: Paraphernalia for the xint packages %<xinttools>%% xinttools: Expandable and non-expandable utilities @@ -60,6 +60,14 @@ available up to 62 digits of precision. The syntax supports dummy variables (to generate sequences of values) and nested structures. Support for user-declared functions and variables is implemented. +Here is an example of everyday typical calculation by `xintexpr` users: + + \xinteval{reduce(add(1/i^3, i=1..25))} + +It expands to: + + 2560976152652211536408111110189/2131858131361319942957376000000 + Usage on the command line ========================= @@ -91,20 +99,50 @@ Installation [MikTeX](http://www.miktex.org/). Thus, use the package manager to update your distribution. -Alternatives: +The simplest alternative is to download +[`xint.tds.zip`](http://mirror.ctan.org/install/macros/generic/xint.tds.zip) +and install the `xint` package files and documentation in a suitable +TDS-compliant repertory via `unzip`. For example, on a macOS system, +installation in user repertory: + + unzip xint.tds.zip -d ~/Library/texmf + +Admin privileges may be needed when moving the files into the TeX +installation. + +Else, one can download `xint.dtx` and optionally `Makefile` from +https://www.ctan.org/tex-archive/macros/generic/xint and proceed from +there. The package files are extracted automatically from +`etex xint.dtx`. So if one does not need to build the documentation, +one only has to move the files with extension `.sty` to one's working +repertory and start using them. + +Here are various options to build the documentation, from the more +automated to the more manual: + +- (with `Makefile`) run `make help` or `make helpless` (on Unix-like + systems) for extracting package files and receiving further + instructions, or directly `make xint.pdf` to both extract package + files and build the user documentation in the current repertory. + The commented source code will be obtained from `make sourcexint.pdf`. + This process requires `latexmk`. The `CHANGES.html` target requires + `pandoc`. -- download - [`xint.tds.zip`](http://mirror.ctan.org/install/macros/generic/xint.tds.zip) - and install in a suitable TDS-compliant repertory via `unzip`. "admin" - privilges might be needed, as well as a file database rebuild (`texhash`). - For example, on macos x, installation into user home folder (no `sudo`, - and no `texhash` as it is recommended to not have a ls-R file there) +- (without `Makefile`) run `etex xint.dtx` then rename the extracted + `Makefile.mk` to `Makefile` and proceed as in the previous item. - unzip xint.tds.zip -d ~/Library/texmf +- (with no `make`) run `latexmk` on `xint.dtx`. This will both extract + package files and build a `dvi` combining the user documentation and + the commented source code. Finish with `dvipdfmx xint.dvi`. + +- (with no `make`) execute `etex xint.dtx` to extract files then run + `latexmk` on `xint.tex` and `sourcexint.tex`, or perhaps on + `xint-all.tex` to combine user manual and source code in one `pdf`. + +- (with no `make` and no `latexmk`) proceed as in one of the previous + two items but with `latex` sufficiently many times in place of + `latexmk`. Finish with `dvipdfmx`, or use `pdflatex` initially. -- all files can be extracted using `etex xint.dtx`, or `make` if the - `Makefile` included in the CTAN upload is present; see the file `INSTALL`, - if present, else read the help in extracted file `Makefile.mk`. Documentation ============= @@ -119,12 +157,6 @@ Documentation `sourcexint.pdf`: commented source code (`texdoc --list xint` or `texdoc sourcexint`) -Requirements -============ - -Since release `1.4`, `xintexpr` requires the `\expanded` primitive. This -is a functionality of all major TeX engines since TeXLive 2019. - License ======= @@ -143,15 +175,68 @@ This Work has the LPPL maintenance status `author-maintained`. The Author of this Work is `Jean-Francois Burnol`. -This Work consists of the files `Makefile`, `INSTALL`, and `xint.dtx` -and its extracted and derived files inclusive of the documentation -files `xint.pdf`, `sourcexint.pdf` and `CHANGES.html`. +This Work consists of the files `xint.dtx` and `Makefile` and +extracted files inclusive of the macro files `xint*sty` as +well as derived documentation files such as `xint.pdf`, +`sourcexint.pdf` and `CHANGES.html` See `xint.pdf` for contact information. %</readme>-------------------------------------------------------- %<*changes>------------------------------------------------------- +`1.4l (2022/05/29)` +---- + +### Bug fixes + + - **xintkernel**: ever since `1.4`, loading anyone of the `xint*sty` + packages left the catcode of the character of ascii code `1` to + the internal custom value `3`. + + - **xintfrac**: the `\xintPFloat` checks for an output being an integer + in decimal notation or a number with a one-digit trimmed mantissa + could fail if `\xintPFloatMinTrimmed` (added at `1.4k`) was large + enough, e.g. equal to the target precision. Then, the outputs always + kept trailing zeros, as expected in general but not for those special + cases. + + - **xintlog**, **xinttrig**: since `1.4e` the message emitted if + `\usepackage{xintlog}` or `\usepackage{xinttrig}` was encountered in + place of the correct `\usepackage{xintexpr}` was wrong. It advised + to use `\input xintexpr.sty\relax`, which would have failed with + LaTeX. The warning is corrected and now the macro file in place of + aborting will (be it with or without LaTeX) trigger the loading of + `xintexpr` (hence of itself after it). + + + - The possibility to run `latex` directly on `xint.dtx` had been broken + since `1.4i`. + +### New features + + - **xintfrac**: `\xintRawBraced` as a public alias to an **xintfrac** + entry point to its core input handler. Experimental additions + `\xintSignBit` and `\xintFloatBraced`. Deprecate `\xintTeXfromSci` + in favor of new name `\xintTeXFromSci`, and remove its `\expanded` + wrapper (so it is not f-expandable anymore). Add + `\xintTeXFromScifracmacro`. + + - **xintfrac**, **xintexpr**: `\xintFracToSci` and `\xintFracToDecimal` + now behave like all other **xintfrac** macros in terms of allowed + arguments and f-expandability and have been moved back to + **xintfrac**. + +### Documentation + + - Renewed random shuffling of large parts of the documentation has + greatly improved it. + + - Simpler build flow to produce a `pdf` containing both user manual and + source code. Removal of dependency on `grep` binary for such builds or + the one of `sourcexint.pdf`. Fix of various obsoleted comments in + extracted files involved in the documentation build process. + `1.4k (2022/05/18)` ---- @@ -159,7 +244,7 @@ See `xint.pdf` for contact information. - **xintfrac**: the longstanding (but documented as undecided and unstable) way of `\xintFloat` to output the zero value was `0.e0` and - it has now been modified into `0.0e0`. Customizable via + it has now been modified into `0.0e0`. Now customizable via `\xintFloatZero`. - **xintfrac**/**xintexpr**: the behaviour of `\xintPFloat` (hence of @@ -173,12 +258,12 @@ See `xint.pdf` for contact information. `\xintPFloatIntSuffix`, `\xintPFloatLengthOneSuffix`, and `\xintPFloatZero`. - Also, `\xintPFloat` trims trailing zeros from the - full significand only if there are at least `4` of them, see + Also, `\xintPFloat` trims trailing zeros from the full significand + only if there are, by default, at least `4` of them, see `\xintPFloatMinTrimmed`. - - **xintfrac**/**xintexpr**: definition of `\xintFracToSci` migrated - from the former to the latter. + - **xintfrac**/**xintexpr**: macro definition of `\xintFracToSci` + migrated from the former to the latter (see `1.4l` for update). - **xintexpr**: `\xintexpr{Safe,Restore}Catcodes` pairs now behave like a "last in first out" stack. Check the `pdf` documentation for @@ -207,8 +292,8 @@ See `xint.pdf` for contact information. - **xintfrac**: `\xintFloatToDecimal`. - - **xintexpr**: `\xintFracToDecimal`, an alternative to - `\xintFracToSci` for the configuration of `\xintexprPrintOne`. + - **xintexpr**: `\xintFracToDecimal`, an alternative to the default + `\xintFracToSci` configuration of `\xintexprPrintOne`. - **xintexpr**: long awaited syntax `\xintieval[D]{...}` and `\xintfloateval[Q]{...}` now implemented. The legacy syntax with @@ -1720,7 +1805,6 @@ releases. They will all get removed at some future release. attempted to use with 1+99999999 a subroutine expecting only 8-digits numbers). - `1.2a (2015/10/19)` ---- @@ -2574,6 +2658,74 @@ Initial announcement: > The packages may be used with Plain and with LaTeX. %</changes>------------------------------------------------------ +%<*dates>------------------------------------------------------- +`1.4l (2022/05/29)` +`1.4k (2022/05/18)` +`1.4j (2021/07/13)` +`1.4i (2021/06/11)` +`1.4h (2021/05/27)` +`1.4g (2021/05/25)` +`1.4f (2021/05/10)` +`1.4e (2021/05/05)` +`1.4d (2021/03/29)` +`1.4c (2021/02/20)` +`1.4b (2020/02/25)` +`1.4a (2020/02/19)` +`1.4 (2020/01/31)` +`1.3f (2019/09/10)` +`1.3e (2019/04/05)` +`1.3d (2019/01/06)` +`1.3c (2018/06/17)` +`1.3b (2018/05/18)` +`1.3a (2018/03/07)` +`1.3 (2018/03/01)` +`1.2q (2018/02/06)` +`1.2p (2017/12/05)` +`1.2o (2017/08/29)` +`1.2n (2017/08/06)` +`1.2m (2017/07/31)` +`1.2l (2017/07/26)` +`1.2k (2017/01/06)` +`1.2j (2016/12/22)` +`1.2i (2016/12/13)` +`1.2h (2016/11/20)` +`1.2g (2016/03/19)` +`1.2f (2016/03/12)` +`1.2e (2015/11/22)` +`1.2d (2015/11/18)` +`1.2c (2015/11/16)` +`1.2b (2015/10/29)` +`1.2a (2015/10/19)` +`1.2 (2015/10/10)` +`1.1c (2015/09/12)` +`1.1b (2015/08/31)` +`1.1a (2014/11/07)` +`1.1 (2014/10/28)` +`1.09n (2014/04/01)` +`1.09m (2014/02/26)` +`1.09kb (2014/02/13)` +`1.09k (2014/01/21)` +`1.09j (2014/01/09)` +`1.09i (2013/12/18)` +`1.09h (2013/11/28)` +`1.09g (2013/11/22)` +`1.09f (2013/11/04)` +`1.09e (2013/10/29)` +`1.09d (2013/10/22)` +`1.09c (2013/10/09)` +`1.09b (2013/10/03)` +`1.09a (2013/09/24)` +`1.08b (2013/06/14)` +`1.08a (2013/06/11)` +`1.08 (2013/06/07)` +`1.07 (2013/05/25)` +`1.06b (2013/05/14)` +`1.06 (2013/05/07)` +`1.05 (2013/05/01)` +`1.04 (2013/04/25)` +`1.03 (2013/04/14)` +`1.0 (2013/03/28)` +%</dates>------------------------------------------------------ %<*makefile>------------------------------------------------------ # This file: Makefile.mk (generated from xint.dtx) # "make --file=Makefile.mk help" @@ -2611,8 +2763,7 @@ make helpless displays this help using the less pager. make doc - produces all documentation, requires Latexmk and Pandoc, - (as well as grep and file output redirection ">") + produces all documentation, requires Latexmk and Pandoc. make all produces all documentation, then creates xint.tds.zip. @@ -2621,12 +2772,16 @@ make xint.tds.zip same as "make all" make xint.pdf - extracts files and produces xint.pdf, using latex and dvipdfmx. - Requires Latexmk. + extracts files and produces xint.pdf (user manual), + using latex and dvipdfmx. Requires Latexmk. make sourcexint.pdf - extracts files and produces sourcexint.pdf, using latex, makeindex - and dvipdfmx. Requires Latexmk (as well as grep and file ">" redirection). + extracts files and produces sourcexint.pdf (source code), + using latex and dvipdfmx. Requires Latexmk. + +make xint-all.pdf + extracts files and produces xint-all.pdf (manual + code), + using latex and dvipdfmx. Requires Latexmk. make CHANGES.html requires Pandoc. @@ -2692,15 +2847,14 @@ packages = xintkernel.sty xintcore.sty xint.sty xintfrac.sty xintexpr.sty\ # specified. Notice that if "make -f Makefile.mk" is executed, this will # actually extract again Makefile.mk which will be overwritten but this # does not seem to be problematic. -extracted = $(packages) xint.tex xint.ins README.md CHANGES.md doHTMLs.sh +extracted = $(packages) xint.tex sourcexint.tex xint-all.tex\ + README.md CHANGES.md xint-dates.txt doHTMLs.sh filesfortex = $(packages) filesforsource = xint.dtx Makefile filesfordoc = xint.pdf sourcexint.pdf README.md CHANGES.html auxiliaryfiles = xint.dvi xint.aux xint.toc xint.log\ - sourcexint.dvi sourcexint.aux sourcexint.toc sourcexint.log -xint_cmd = latexmk xint -sourcexint_cmd = latexmk -jobname=sourcexint\ - -latex='latex %O "\chardef\dosourcexint=1 \input{%S}"' xint.tex + sourcexint.dvi sourcexint.aux sourcexint.toc sourcexint.log\ + xint-all.dvi xint-all.aux xint-all.toc xint-all.log all: $(extracted) doc xint.tds.zip @echo 'make all done.' @@ -2708,21 +2862,21 @@ all: $(extracted) doc xint.tds.zip $(extracted): xint.dtx etex xint.dtx -xint-dates.txt: CHANGES.md - grep '^`[1-9].* (.*/.*/.*)`$$' CHANGES.md > xint-dates.txt - rm -f sourcexint.dvi - doc: xint.pdf sourcexint.pdf CHANGES.html @echo 'make doc done.' xint.pdf: xint.dtx xint.tex - $(xint_cmd) + latexmk xint.tex dvipdfmx xint.dvi -sourcexint.pdf: xint.dtx xint.tex xint-dates.txt - $(sourcexint_cmd) +sourcexint.pdf: xint.dtx sourcexint.tex + latexmk sourcexint.tex dvipdfmx sourcexint.dvi +xint-all.pdf: xint.dtx xint-all.tex + latexmk xint-all.tex + dvipdfmx xint-all.dvi + CHANGES.html: CHANGES.md doHTMLs.sh chmod u+x doHTMLs.sh && ./doHTMLs.sh @@ -2776,12 +2930,13 @@ uninstalllocal: clean: rm -fr auto/ TEMP*/ rm -f $(auxiliaryfiles)\ + xint-all.fls xint-all.fdb_latexmk\ sourcexint.fls sourcexint.fdb_latexmk\ xint.fls xint.fdb_latexmk cleanall: clean rm -f $(extracted) CHANGES.html xint-dates.txt \ - xint.pdf sourcexint.pdf xint.tds.zip xint.zip Makefile.mk + xint.pdf sourcexint.pdf xint-all.pdf xint.tds.zip xint.zip Makefile.mk %</makefile>$----------------------------------------------------- %<*dohtmlsh>------------------------------------------------------ #! /bin/sh @@ -2804,42 +2959,94 @@ pandoc -o CHANGES.html -s --toc -V highlighting-css=' body{margin: 0; margin- #TOC {float: right; position: relative; top: 100px; margin-bottom: 100px; margin-left: 20px;}' CHANGES.md %</dohtmlsh>------------------------------------------------------ -%<*drv>----------------------------------------------------------- -%% Extracting files (but you have done that already probably): -%% - etex xint.dtx -%% -%% To produce manually xint.pdf from extracted xint.tex (and other files): -%% - latex xint.tex (thrice) -%% - dvipdfmx xint.dvi -%% Or xelatex thrice on xint.tex, or pdflatex thrice (produces bigger sized -%% pdf). +%<*xintdrv>----------------------------------------------------------- +%% To extract files: +%% (but this is probably already done as you read this one) +%% etex xint.dtx %% -%% To produce manually sourcexint.pdf from extracted xint.tex (and other files): -%% - grep '^`[1-9].* (.*/.*/.*)`$' CHANGES.md > xint-dates.txt -%% - latexmk -jobname=sourcexint\ -%% -latex="latex %O \\\\chardef\\\\dosourcexint=1 \\\\input{%S}"\ -%% xint.tex -%% - dvipdfmx sourcexint.dvi +%% Then execute: +%% make --file=Makefile.mk xint.pdf %% +%% Alternative for build without `make': +%% latexmk xint.tex +%% dvipdfmx xint.dvi %% (quoting in the above may need shell-dependant changes) %% -%% To get xint.pdf to include also the source code: -%% - replace 1 by 0 in \chardef\NoSourceCode line below, -%% - make clean then make xint.pdf +%% One can also tell latexmk to use xelatex or pdflatex. +%% Or use one of them directly enough times on xint.tex. %% -%% This will use latexmk. Without it execute latex thrice on xint.tex then -%% dvipdfmx. Don't forget producing xint-dates.txt via the grep command. +%% To produce the documented source code sourcexint.pdf: +%% make --file=Makefile.mk sourcexint.pdf +%% (check sourcexint.tex for alternatives to `make') +%% +%% To produce xint-all.pdf with both user doc and source code: +%% make --file=Makefile.mk xint-all.pdf +%% (check xint-all.tex for alternatives to `make') \NeedsTeXFormat{LaTeX2e} \ProvidesFile{xint.tex}% -[\xintbndldate\space v\xintbndlversion\space driver file for xint documentation (JFB)]% -\PassOptionsToClass{a4paper,fontsize=10pt}{scrdoc} -\chardef\NoSourceCode 1 % set it to 0 if source code inclusion desired +[\xintbndldate\space v\xintbndlversion\space xint documentation (JFB)]% +\PassOptionsToClass{a4paper,fontsize=10pt}{scrartcl} +\chardef\NoSourceCode 1 \input xint.dtx %%% Local Variables: %%% mode: latex %%% TeX-PDF-from-DVI: "Dvipdfmx" %%% End: -%</drv>----------------------------------------------------------- +%</xintdrv>----------------------------------------------------------- +%<*sourcedrv>----------------------------------------------------------- +%% To extract files: +%% (but this is probably already done as you read this one) +%% etex xint.dtx +%% +%% Then execute: +%% make --file=Makefile.mk sourcexint.pdf +%% +%% Alternative for build without `make': +%% latexmk sourcexint.tex +%% dvipdfmx sourcexint.dvi +%% +%% One can intruct latexmk (see its documentation) to use xelatex +%% or pdflatex, or use them directly on sourcexint.tex. +\NeedsTeXFormat{LaTeX2e} +\ProvidesFile{sourcexint.tex}% +[\xintbndldate\space v\xintbndlversion\space xint commented code (JFB)]% +\PassOptionsToClass{a4paper,fontsize=10pt}{scrartcl} +\chardef\NoSourceCode=0\chardef\dosourcexint=1 +\input xint.dtx +%%% Local Variables: +%%% mode: latex +%%% TeX-PDF-from-DVI: "Dvipdfmx" +%%% End: +%</sourcedrv>----------------------------------------------------------- +%<*alldrv>----------------------------------------------------------- +%% To extract files: +%% (but this is probably already done as you read this one) +%% etex xint.dtx +%% +%% Then execute: +%% make --file=Makefile.mk xint-all.pdf +%% +%% Alternative for build without `make': +%% latexmk xint-all.tex +%% dvipdfmx xint-all.dvi +%% +%% One can intruct latexmk (see its documentation) to use xelatex +%% or pdflatex, or use them directly on xint-all.tex. +%% +%% Another way is to run latex (enough times, then dvipdfmx) or +%% pdflatex directly on source file xint.dtx. The produced xint.pdf +%% will then combine user manual and commented source code. +\NeedsTeXFormat{LaTeX2e} +\ProvidesFile{xint-all.tex}% +[\xintbndldate\space v\xintbndlversion\space xint user plus source doc (JFB)]% +\PassOptionsToClass{a4paper,fontsize=10pt}{scrartcl} +\chardef\NoSourceCode=0 +\input xint.dtx +%%% Local Variables: +%%% mode: latex +%%% TeX-PDF-from-DVI: "Dvipdfmx" +%%% End: +%</alldrv>----------------------------------------------------------- %<*dtx>----------------------------------------------------------- ^^Bfi^^Begroup \chardef\noetex 0 @@ -2855,11 +3062,10 @@ pandoc -o CHANGES.html -s --toc -V highlighting-css=' body{margin: 0; margin- \chardef\extractfiles 1 % 1 = extract and typeset, 2 = only typeset \chardef\NoSourceCode 0 % 0 = include source code, 1 = do not \NeedsTeXFormat{LaTeX2e}% - \PassOptionsToClass{a4paper,fontsize=10pt}{scrdoc}% + \PassOptionsToClass{a4paper,fontsize=10pt}{scrartcl}% \else - % latex/pdflatex/xelatex on xint.tex + % latex/pdflatex/xelatex on xint.tex or sourcexint.tex or xint-all.tex \chardef\extractfiles 2 % no extractions, but typeset - % \NoSourceCode is set-up in xint.tex \fi \ProvidesFile{xint.dtx}[bundle source (\xintbndlversion, \xintbndldate) % and documentation (\xintdocdate)]% @@ -2887,15 +3093,16 @@ pandoc -o CHANGES.html -s --toc -V highlighting-css=' body{margin: 0; margin- \Msg{* \space\space\space\space xintlog.sty^^J}% \Msg{*^^J}% \Msg{* Rename Makefile.mk to Makefile if the latter is absent^^J}% -\Msg{* (or use --file=Makefile.mk option to "make") then "make help"^^J}% -\Msg{* provides information on targets. In particular:^^J}% -\Msg{* - the "doc" target builds all documentation,^^J}% +\Msg{* (or use --file=Makefile.mk option of "make")^^J}% +\Msg{* then "make help" will provide information.^^J}% +\Msg{* In particular:^^J}% +\Msg{* - the "doc" target builds xint.pdf and sourcexint.pdf,^^J}% \Msg{* - the "xint.tds.zip" target additionally prepares a TDS-compliant^^J}% \Msg{*\space\space\space archive.^^J}% -\Msg{* This requires Latexmk (for xint.pdf and sourcexint.pdf) and Pandoc^^J}% -\Msg{* (for CHANGES.html).^^J}% +\Msg{* Building with "make" requires "Latexmk".^^J}% +\Msg{* The target "CHANGES.html" requires "Pandoc".^^J}% \Msg{*^^J}% -\Msg{* Or check instructions in xint.tex for manual compilation.^^J}% +\Msg{* Instructions for builds without "make" are in file xint.tex.^^J}% \Msg{*^^J}% \Msg{* Happy TeXing!^^J}% \Msg{*^^J}% @@ -2915,6 +3122,7 @@ pandoc -o CHANGES.html -s --toc -V highlighting-css=' body{margin: 0; margin- \generate{\nopreamble\nopostamble \file{README.md}{\from{xint.dtx}{readme}} \file{CHANGES.md}{\from{xint.dtx}{changes}} + \file{xint-dates.txt}{\from{xint.dtx}{dates}} % pure tex will use ^^I notation for TAB character, don't want that. % anyway, since 2021/05/30, tex xint.dtx has been made a no-op. % there is a problem with xelatex, it generates ^^I if not with -8bit @@ -2922,7 +3130,9 @@ pandoc -o CHANGES.html -s --toc -V highlighting-css=' body{margin: 0; margin- \file{doHTMLs.sh}{\from{xint.dtx}{dohtmlsh}} \usepreamble\defaultpreamble \usepostamble\defaultpostamble - \file{xint.tex}{\from{xint.dtx}{drv}} + \file{xint.tex}{\from{xint.dtx}{xintdrv}} + \file{sourcexint.tex}{\from{xint.dtx}{sourcedrv}} + \file{xint-all.tex}{\from{xint.dtx}{alldrv}} \file{xintkernel.sty}{\from{xint.dtx}{xintkernel}} \file{xinttools.sty}{\from{xint.dtx}{xinttools}} \file{xintcore.sty}{\from{xint.dtx}{xintcore}} @@ -2940,6 +3150,12 @@ pandoc -o CHANGES.html -s --toc -V highlighting-css=' body{margin: 0; margin- \ifnum\extractfiles=0 % no LaTeX, files now extracted. Stop. \MessageDeFin\expandafter\end \fi +\ifnum\extractfiles=1 % direct run on xint.dtx + \expandafter\def\expandafter\MessageDeFin\expandafter{\MessageDeFin +\Msg{* Direct latex run on xint.dtx: please repeat at least 3 times.^^J}% +\Msg{********************************************************************^^J}% +}% +\fi \ifnum\extractfiles=3 % \newlinechar10 \errhelp{Extraction must be done via an engine with e-TeX extensions.^^J% @@ -2954,11 +3170,26 @@ pandoc -o CHANGES.html -s --toc -V highlighting-css=' body{margin: 0; margin- %----------------------------------------------------------------- % -*- coding: utf-8; mode: latex, fill-column: 78; -*- % -\ifdefined\dosourcexint % this toggle is set from make sourcexint.pdf rule +\makeatletter +% counts used in particular in the samples from the documentation of the +% xintseries.sty package +\newcount\cnta +\newcount\cntb +\newcount\cntc + +\ifdefined\dosourcexint \chardef\NoSourceCode 0 \else \chardef\dosourcexint 0 \fi +% \dosourcexint=1 means producing only source code. +% It is set in sourcexint.tex. Prior to 1.4l it was +% set in the call with latexmk + \input syntax. +% +% \dosourcexint=0 and \NoSourceCode=1 : include only user doc +% \dosourcexint=0 and \NoSourceCode=0 : combine user doc and source code +% \dosourcexint=1 and \NoSourceCode=1 : never happens but would mean to do +% nothing! % default is to assume latex + dvipdfmx \chardef\Withdvipdfmx 1 @@ -2976,58 +3207,144 @@ pandoc -o CHANGES.html -s --toc -V highlighting-css=' body{margin: 0; margin- \fi % Get rid of HARASSMENT by KOMA-Script -\makeatletter \def\class@shoulddisablepackagewarning@list{tocloft.} -\makeatother \ifnum\Withdvipdfmx=1 \def\pgfsysdriver{pgfsys-dvipdfm.def} -\documentclass [dvipdfm, dvipdfmx, dvipdfmx-outline-open]{scrdoc} +\documentclass [dvipdfm, dvipdfmx, dvipdfmx-outline-open]{scrartcl} \else -\documentclass {scrdoc} +\documentclass {scrartcl} \fi +%%% START OF CUSTOM doc.sty LOADING (May 21, 2022) +% +% For some legacy reason (because I started like this and it +% worked to my satisfaction) I had used scrdoc.cls all those +% years, without in fact needing most of its features. +% +% It loads ltxdoc class, from which again I need very little. On +% testing May 20, 2022 the upcoming LaTeX 2022-06-01 I had some +% problems with ltxdoc not having suitable interface for rolling +% back to doc=V2. +% +% I did experiment with indices for sourcexint.pdf from 2018 to +% 2019 but it made the build process significantly lengthier, +% created heavy-sized PDF, had various issues in my context +% (possibly the kind of issues doc V3 addresses about indexing +% non-macro things, hyperlinks,...), and these indices basically +% had not any real use as PDF search proves efficient enough, +% and the structures of local tables of contents makes for +% agreeable enough navigation via the input mark-up using +% sectioning commands. +% +% Thus it turns out I need very little of doc.sty, and almost +% nothing of ltxdoc.cls and scrdoc.cls. +% +% Let's load the doc=V2 version to avoid having to work around +% hypdoc loading interfering with my use of hyperref and as said +% above I don't need the hyperlinked cross-referencing as I have +% it via my own mark-up to a sufficiently good enough extent, +% and this holds for many many years. And I will not now change +% my mark-up. +\ifdefined\IfFormatAtLeastTF + \IfFormatAtLeastTF{2022/06/01}% + {% + \IfFileExists{doc-2021-06-01.sty}% + {\usepackage{doc}[=v2]}% +% Why on earth do I lose my time doing this? + {\GenericError + {(xint build doc)\@spaces}% + {xint build error: % + Your LaTeX installation seems to be broken, format is\MessageBreak + 2022-06-01 or later but `doc' package in its `v2' version\MessageBreak + seems to not be available. \space Will try with `doc' but if\MessageBreak + its `v3' is used there will be an option clash error\MessageBreak + regarding hyperref.}% + {}% + {Please make sure `doc' package matches your LaTeX format.}% + \usepackage{doc}% + }% + }% + {\usepackage{doc}}% +\else +\usepackage{doc} +\fi + +% And let's keep from ltxdoc only some minimal stuff +% Page geometry is set by geometry package and a4paper option from +% xint.tex file. +\AtBeginDocument{\MakeShortVerb{\|}} +\DeclareFontShape{OT1}{cmtt}{bx}{n}{<-> ssub * cmtt/m/n}{} +\DeclareFontFamily{OMS}{cmtt}{\skewchar\font 48} % '60 +\DeclareFontShape{OMS}{cmtt}{m}{n}{<-> ssub * cmsy/m/n}{} +\DeclareFontShape{OMS}{cmtt}{bx}{n}{<-> ssub * cmsy/b/n}{} +\DeclareFontShape{OT1}{cmss}{m}{it}{<->ssub*cmss/m/sl}{} +\CodelineNumbered +\DisableCrossrefs +\setcounter{StandardModuleDepth}{1} +\def\cmd#1{\cs{\expandafter\cmd@to@cs\string#1}} +\def\cmd@to@cs#1#2{\char\number`#2\relax} +\DeclareRobustCommand\cs[1]{\texttt{\bslash#1}}% was \char`\\ +\providecommand\marg[1]{% + {\ttfamily\char`\{}\meta{#1}{\ttfamily\char`\}}} +\providecommand\oarg[1]{% + {\ttfamily[}\meta{#1}{\ttfamily]}} +\providecommand\parg[1]{% + {\ttfamily(}\meta{#1}{\ttfamily)}} +\@addtoreset{CodelineNo}{part} +% \def\partname{File}% j'utilise Part défini plus bas +% Je n'utilise pas d'index en fait +\gdef\codeline@wrindex#1{\if@filesw + \begingroup + \let\protect\noexpand + \immediate\write\@indexfile + {\string\indexentry{#1}% + {\filesep\number\c@CodelineNo}}% + \endgroup\fi} +\let\filesep\@empty + +% There is very little we seem to need from the scrdoc extras: +% Page geometry is set by geometry package and a4paper option from +% xint.tex file. So it seems I only need (perhaps) this hologo thing: +\usepackage{hologo} +\DeclareRobustCommand*{\eTeX}{\hologo{eTeX}}% +% +%%% END OF CUSTOM LOADING OF PACKAGE doc.sty V2 + % Remove from sectioning commands insertion of marks, because we % will do it ourself. \usepackage{etoolbox} -\makeatletter \patchcmd{\@sect}% {\expandafter\csname#1mark\expandafter\endcsname\expandafter{\@currentheadentry}}% - {}{}{} + {}{}{\Error@CouldNotApplyFirstPatch@sect} \patchcmd{\@sect}% {\expandafter\csname#1mark\expandafter\endcsname\expandafter{\@currentheadentry}}% - {}{}{} + {}{}{\Error@CouldNotApplySecondPatch@sect} % This one now needed too, Jeudi 30 janvier 2020 % \expandafter \ifx \csname #1mark\endcsname \@gobble \@mkboth {}{}\else % \csname #1mark\expandafter \endcsname \expandafter {\@currentheadentry }\fi % \@gobble est long donc simplement \def\partmark #1{}% -\makeatother - - -\makeatletter -\PassOptionsToPackage{bookmarks=true}{hyperref} - \ifnum\NoSourceCode=1 \OnlyDescription \fi -% counts used in particular in the samples from the documentation of the -% xintseries.sty package -\newcount\cnta -\newcount\cntb -\newcount\cntc - \pagestyle{headings} \ifxetex \else \usepackage[T1]{fontenc} +% je suis passé à utf8 le 28 février 2016 \usepackage[utf8]{inputenc} +% (2016/12/08): utilisé où ? +% (2018/05/22): utilisé dans les commentaires de la division de xint.sty \DeclareUnicodeCharacter{03B4}{\ensuremath{\delta}}%δ +% pour exemple de \xintnewdummy \DeclareUnicodeCharacter{03BE}{\ensuremath{\xi}}%ξ +% (2019/03/31): utilisé dans mes commentaires de xinttrig.sty \DeclareUnicodeCharacter{03C0}{\ensuremath{\pi}}%π +% (2019/04/24): utilisé dans un commentaire de xintlog.sty \DeclareUnicodeCharacter{2260}{\ensuremath{\neq}}%≠ \fi @@ -3048,6 +3365,7 @@ pandoc -o CHANGES.html -s --toc -V highlighting-css=' body{margin: 0; margin- \fi \usepackage{pifont}% for \ding{73} (hollow star) +% needed also for build of sourcexint.pdf \usepackage{xinttools} \usepackage{enumitem} @@ -3058,8 +3376,14 @@ pandoc -o CHANGES.html -s --toc -V highlighting-css=' body{margin: 0; margin- \usepackage{graphicx} \usepackage[english]{babel} -\usepackage[autolanguage,np]{numprint} -\AtBeginDocument{\npthousandsep{,\hskip .5pt plus .1pt minus .1pt}} + +% 2022/05/24: appears to not be used anywhere anymore in the doc +% \usepackage[autolanguage,np]{numprint} +% \AtBeginDocument{\npthousandsep{,\hskip .5pt plus .1pt minus .1pt}} + +% But surprisingly it is via numprint that I was loading array package +% whose extended syntax for tabular preambles is used... +\usepackage{array} \usepackage[dvipsnames,svgnames]{xcolor} \definecolor{xintnamecolor}{RGB}{228,57,0} @@ -3133,7 +3457,6 @@ pandoc -o CHANGES.html -s --toc -V highlighting-css=' body{margin: 0; margin- % SNUGFRAMED % ========== -\makeatletter \newenvironment{snugframed}{% \fboxsep \dimexpr2\fontcharwd\font`X\relax \advance\linewidth-2\fboxsep @@ -3146,12 +3469,11 @@ pandoc -o CHANGES.html -s --toc -V highlighting-css=' body{margin: 0; margin- \MakeFramed {\advance\hsize-\width \@totalleftmargin\z@ \linewidth\hsize \@setminipage}% }{\par\unskip\@minipagefalse\endMakeFramed} -\makeatother % HYPERREF % ======== -\usepackage[pdfencoding=unicode]{hyperref} +\usepackage{hyperref} \hypersetup{% linktoc=all,% @@ -3168,9 +3490,11 @@ pdfpagemode=UseNone,% } \usepackage{hypcap} + \ifnum\dosourcexint=1 -\hypersetup{pdftitle={The xint packages source code}} +\hypersetup{pdftitle={The xintexpr and allied packages source code}} \fi + \usepackage{bookmark} % FONTS @@ -3179,16 +3503,13 @@ pdfpagemode=UseNone,% \usepackage[zerostyle=a,straightquotes,scaled=0.95]{newtxtt} \usepackage{newtxmath} -\makeatletter -\makeatother - \ifnum\dosourcexint=1 \else -\renewcommand\familydefault\ttdefault -\usepackage[noendash]{mathastext}% pas de endash dans newtxtt + \renewcommand\familydefault\ttdefault + \usepackage[noendash]{mathastext}% pas de endash dans newtxtt \fi \frenchspacing % sans-serif in footnotes, TOC, titles, etc... @@ -3230,7 +3551,6 @@ pdfpagemode=UseNone,% \newdimen\margegauchetoc \AtBeginDocument{\margegauchetoc \dimexpr 5\fontcharwd\font`X\relax} -\makeatletter \etocsetstyle{subsection} {\begingroup\normalfont \setlength{\premulticols}{0pt}% @@ -3280,8 +3600,6 @@ pdfpagemode=UseNone,% \let\HOOKLOCALTOC\empty% quick hack to get style I want in User defined functions \etocsetlevel{table}{6} -\makeatother - \addtocontents{toc}{\protect\hypersetup{hidelinks}} % ===================== @@ -3294,27 +3612,27 @@ pdfpagemode=UseNone,% % \fexpan 22 octobre 2013 \newcommand\fexpan {\hyperref[ssec:expansions]{\textit{f}-expan}} +% \xexpan ajouté 28 mai 2022 +\newcommand\xexpan {\hyperref[ssec:expansions]{\textit{x}-expan}} % Septembre 2015 % Address updated to github repo's one, May 2018 +% They did s/master/main/ already a few years back, May 2022 \def\liiibigint - {\href{https://github.com/latex3/latex3/tree/master/l3trial/l3bigint}{l3bigint}} + {\href{https://github.com/latex3/latex3/tree/main/l3trial/l3bigint}{l3bigint}} + +% May 2022 +\def\liiistrformat +% {\href{https://github.com/latex3/latex3/tree/main/l3experimental/l3str}{l3str}} + {\href{https://ctan.org/pkg/l3experimental}{l3str-format}} +%\def\liiistrformatnew +% {\href{https://github.com/latex3/latex3/tree/main/l3trial/l3str-format-new}{l3str-format-new}} -% \fixmeaning -\makeatletter -% \def\fixmeaning {\expandafter\fix@meaning\meaning} -% \expandafter\edef\expandafter\fix@meaning -% \expandafter #\expandafter1\string\romannumeral#2#3% -% {#1\string\romannumeral`\string^\string^@} -% Pour 1.4 -\let\fixmeaning\meaning -\makeatother % Margin Notes % ============ % Nothing here can be used in vertical mode directly. -\makeatletter \def\MyMarginNote {\@ifnextchar[\@MyMarginNote{\@MyMarginNote[]}}% \let\inmarg\MyMarginNote % \smash needs \hbox here since LaTeX 2018/12/01 @@ -3435,7 +3753,6 @@ pdfpagemode=UseNone,% \kern\dimexpr\FrameSep+\FrameRule\relax}}}% \vskip\dp\strutbox }\strut\@esphack} -\makeatother % \centeredline: OUR OWN LITTLE MACRO FOR CENTERING LINES % ======================================================= @@ -3452,7 +3769,6 @@ pdfpagemode=UseNone,% % Note (2020): somewhat obsoleted for many years by my usage of % everbatim and everbatim* environments. -\makeatletter \newif\ifinlefted \newcommand*\leftedline {% @@ -3469,15 +3785,12 @@ pdfpagemode=UseNone,% \bgroup \aftergroup\leftedline@ } -\makeatother - % verbatim macros and environments % ================================ % % June 2013, then October 2014. % ----------------------------- % -\makeatletter \catcode`_ 11 % some of my verbatim environments do not make the space active (\lverb e.g.). Then @@ -3596,7 +3909,6 @@ pdfpagemode=UseNone,% \AtBeginDocument {\SetSoftWrapIcon }% ok car ttzfamily déjà fait \catcode`_ 8 -\makeatother % everbatim environment % ===================== @@ -3613,7 +3925,6 @@ pdfpagemode=UseNone,% % Verbatim with an \everypar hook, mainly to have background color, followed by % execution of the contents (not limited by a group-scope) -\makeatletter \catcode`_ 11 \def\everbatim {\s@everbatim\@everbatim} @@ -3649,7 +3960,8 @@ pdfpagemode=UseNone,% }% \obeylines \@vobeyspaces } -\def\everbatimtop {\MacroFont \small}% +% 27 mai 2022, plus de \small +\def\everbatimtop {\MacroFont }% \let\everbatimhook\empty \def\everbatimeverypar{\strut {\color{everbatimbgcolor}\vrule\@width\linewidth }% @@ -3762,6 +4074,8 @@ pdfpagemode=UseNone,% % source, this can be changed by \everbhook. % " comme caractère d'échappement. Par exemple pour colorier des parties. +% Le "" redonne à { et } leurs catcodes normaux mais attention c'est +% alors à utiliser avec un terminateur ;! pour la partie concernée \def\restoreeverbhook{\def\everbhook{% \def\"{\begingroup\catcode123 1 \catcode 125 2 \everbescape }% \catcode`\" 0 \catcode`\@ 14 @@ -3786,14 +4100,12 @@ pdfpagemode=UseNone,% }% \catcode`_8 -\makeatother % \printnumber % ============ \catcode`_ 11 -\makeatletter \catcode`& 3 \def\allowsplits_a {\futurelet\printnumber_token\allowsplits_b }% \def\allowsplits_b{\ifx\printnumber_token\@sptoken\space\fi\allowsplits_c } @@ -3808,7 +4120,6 @@ pdfpagemode=UseNone,% \hyphenpenalty \z@ \catcode`& 4 -\makeatother \catcode`_ 8 % Parameters for lists @@ -3882,6 +4193,10 @@ pdfpagemode=UseNone,% \newcommand\prec[1]{\hyperlink{\detokenize{prec-#1}}{#1}} \newcommand\precdesc[1]{\item[\texttt{#1}]\hypertarget{\detokenize{prec-#1}}{}\leavevmode}% +%\let\var\relax % défini par koma-script-source-doc que scrdoc + % utilise avec LaTeX 2022/06/01 + % mais finalement je n'utilise plus scrdoc/ltxdoc + % mais doc directement. \newcommand\var[1]{\hyperlink{\detokenize{var-#1}}{#1}} \newcommand\vardesc[1]{\item[#1]\hypertarget{\detokenize{var-#1}}{}}% @@ -3922,7 +4237,6 @@ pdfpagemode=UseNone,% {TOC}% \xspace }% -\makeatletter \protected\def\MakeNameUp#1{% \ifcsname #1nameUp\endcsname \expandafter\@firstoftwo\else @@ -3932,7 +4246,6 @@ pdfpagemode=UseNone,% {\ifinheader\fbox{\textup{#1}}\else#1\fi}% {#1}% } -\makeatother \newif\ifinheader % doit être protégé \protected\def\inheadertrue{\let\ifinheader\iftrue} @@ -3957,18 +4270,19 @@ pdfpagemode=UseNone,% % =============== % \ttzfamily done at begin document -\newcommand\ctanpackage[1]{\href{https://ctan.org/pkg/#1}{#1}} +\DeclareRobustCommand\ctanpackage[1]{\href{https://ctan.org/pkg/#1}{#1}} +\makeatother \begin{document}\thispagestyle{empty} \pdfbookmark[1]{Title page}{TOP} \def\partname{Part} \addto\captionsenglish{\def\partname{Part}} {% -\normalfont\Large\parindent0pt \parfillskip 0pt\relax - \leftskip 2cm plus 1fil \rightskip 2cm plus 1fil +\normalfont\Huge\parindent0pt \parfillskip 0pt\relax + \leftskip 0cm plus 1fil \rightskip 0cm plus 1fil \ifnum\dosourcexint=1 - The \xintnameimp packages source code\par + The \xintexprnameimp and allied packages source code\par \gdef\DOCxintfrontpage {\texorpdfstring {\hyperref[frontpage]{\relax{\color{xintnameimpcolor}TOC}}}% @@ -4001,8 +4315,9 @@ pdfpagemode=UseNone,% \def\DOCxintexprmacros {\texorpdfstring - {\hyperref[sec:oldxintexpr]{\relax{\color{xintnamecolor}\MakeNameUp{xintexpr}}}}% - {xintexpr}% + {\hyperref[sec:oldxintexpr]{\relax{\color{xintnamecolor}\MakeNameUp{xintexpr + (old doc)}}}}% + {xintexpr (old doc)}% \xspace }% \def\DOCexamples @@ -4024,11 +4339,18 @@ pdfpagemode=UseNone,% \DOCxintfrontpage, \DOCxintexprintro, \xintexprname, + \DOCxintexprmacros, \xinttrigname, \xintlogname, + \xinttoolsname, + \DOCexamples, \csname xint bundlename\endcsname}} \markboth{\makebox[0pt]{\xintRunningHeader}}{\makebox[0pt]{\xintRunningHeader}} +% 18 mai 2019, turned into an environment 27 mai 2022 +\newenvironment{TeXnote}{\par\small\medskip\noindent\textbf{\TeX hackers note: + }}{\par\medskip} + % Skips safely. \ifnum\dosourcexint=1 \catcode`+ 0 \catcode0 9 % n'importe quoi sauf 15 (car ^^@) @@ -4036,8 +4358,7 @@ pdfpagemode=UseNone,% +expandafter+iffalse+fi \fi % - -\newcommand\TeXnote{\par\smallskip\textbf{\TeX hackers note: }} +\makeatletter \etocsetlevel{toctobookmark}{6} @@ -4061,26 +4382,116 @@ pdfpagemode=UseNone,% \etocsettagdepth {implementation}{none} \etocsettocdepth{subsection} +%% Legacy etoc style for part, we add an improvement to get "Part" hyperlinked +%% `part': +\etocsetstyle{part} + {\addpenalty\@M\etocskipfirstprefix} + {\addpenalty\@secpenalty} + {\begingroup + \etocfontminusone + \addvspace{\etocsepminusone}% + \parindent \z@ + \leftskip \etocminusoneleftmargin + \rightskip \etocminusonerightmargin + \parfillskip \@flushglue + % original from etoc : + %\vbox{\etocifnumbered{\etocpartname\enspace\etocnumber.\quad}{}...} + \vbox{\etocifnumbered{\etoclink{\etocpartname\enspace\etocthenumber.}\quad}{}% + \etocname + \baselineskip\etocbaselinespreadminusone\baselineskip + \par}% + \addpenalty\@M\addvspace{\etocsepzero}% + \endgroup} + {}% + +% THIS IS THE FIRST HALF OF THE TOC ON PAGE 1 \tableofcontents + +% May 23 2022, some hack to replace the \etocmulticolstyle and +% have same output except that Part line will use full line width +% +% Formerly I used this but the Part was then folded... +% \etocmulticolstyle [2]{\parskip\z@skip%\raggedcolumns +% \setlength{\columnsep}{\leftmarginii}% +% \setlength{\columnseprule}{0pt}% +% }% +% +\etocsetstyle{part}% @minusone in etoc.sty + {\addpenalty\@M\etocskipfirstprefix} +% May 23, 2022 +% Small hack to configure to our taste the TOC for the pdf combining +% the user manual and the source code. We want a Part III in the TOC, +% and the sections of Part II with a multicols. We can not open the +% multicols in the `part' style and have it closed in the 4th argument +% of \etocsettyle, as it needs to be closed when Part III will be +% typeset. Thanks to \etocskipfirstprefix we can simply close it +% in the "EtocPrefix", this \end{multicols} will be skipped for the +% first one. +% +% However, as this closes a group we will use \etocglobaldefs for this +% toc else \etocname, etc... would not have the good meanings. I think +% there must be some hack like this in etoc manual. + {\end{multicols}% + \addpenalty\@secpenalty\addvspace{\etocbelowtocskip}% + } + {\begingroup % from etoc.sty default Part style + \etocfontminusone + \addvspace{\etocsepminusone}% + \parindent \z@ + \leftskip \etocminusoneleftmargin + \rightskip \etocminusonerightmargin + \parfillskip \@flushglue + % \etoclink is handy else only the number get hyperlinked + \vbox{\etocifnumbered{\etoclink{\etocpartname\enspace\etocthenumber.\quad}}{}\etocname + \baselineskip\etocbaselinespreadminusone\baselineskip + \par}% + \addpenalty\@M\addvspace{\etocsepzero}% + \endgroup + % now emulate what \etocmulticolstyle would have set-up + \let\etocoldpar\par% surely fishy by now but I am copying from + % how \etocsettocstyle is used by \etocmulticolstyle + \addvspace{\etocabovetocskip}% configured below + \multicolpretolerance\etocmulticolpretolerance + \multicoltolerance\etocmulticoltolerance + \setlength{\columnsep}{\etoccolumnsep}% + \setlength{\multicolsep}{\etocmulticolsep}% + \begin{multicols}{2}[\parskip\z@skip%\raggedcolumns + \setlength{\columnsep}{\leftmarginii}% + \setlength{\columnseprule}{0pt}% + \etocoldpar + %\addvspace{\etocinnertopsep} + \addvspace{\etocabovetocskip}]% + }% + {\end{multicols}\addvspace{\etocbelowtocskip}}% + +% this macro is defined by etoc for use in its own display styles +% like the one from \etocmulticolstyle. We use it manually above. \renewcommand*\etocabovetocskip{\bigskipamount} -\makeatletter -\etocmulticolstyle [2]{\parskip\z@skip%\raggedcolumns - \setlength{\columnsep}{\leftmarginii}% - \setlength{\columnseprule}{0pt}% -}% + \makeatother + +\etocsettocstyle{}{} + \etocsettagdepth {part1A}{none} \etocsettagdepth {part1B}{none} \etocsettagdepth {macros} {section} \ifnum\NoSourceCode=1 \etocsettagdepth {implementation}{none} \else - \etocsettagdepth {implementation}{section} + \ifnum\dosourcexint=1 + \etocsettagdepth {implementation}{section} + \else + \etocsettagdepth {implementation}{part} + \fi \fi -\vspace*{2\baselineskip} +% seems unneeded now +%\vspace*{2\baselineskip} +% THIS IS THE SECOND HALF OF THE TOC ON PAGE 1, WITH PARTS II AND III +\etocglobaldefs \tableofcontents +\etoclocaldefs \etocignoredepthtags @@ -4258,7 +4669,7 @@ pdfpagemode=UseNone,% precision. It works both with Plain \TeX\ and with \LaTeX. \xinttrigname and \xintlogname are loaded automatically by \xintexprname; - they can not be loaded directly via a separate |\usepackage| (in \LaTeX). + they should not be loaded directly via a separate |\usepackage| (in \LaTeX). \ctanpackage{poormanlog} is a \TeX{} and \LaTeX{} package by the author which is loaded automatically by \xintlogname. @@ -4272,7 +4683,6 @@ pdfpagemode=UseNone,% \vfill \clearpage - \etocdepthtag.toc {part1A} \csname Start herenameUp\endcsname @@ -4282,49 +4692,102 @@ pdfpagemode=UseNone,% \etocsetnexttocdepth{section} \localtableofcontents -\section {Introduction and changes} +\section {Introduction} + +\localtableofcontents + +\begin{framed} + \emph{\emph{\textsc{Jürgen Gilg}}'s interest into what he called + \emph{|"XINT"|} was instrumental in keeping the author motivated + over the years. +% \emph pas compatible avec plusieurs paragraphes ! + We exchanged on many topics extending beyond \TeX{} and often reacted + similarly to private and public events. I knew he was a very kind + and devoted person, who took care of the needs of others prior to + his own, although he never mentioned it. +% + Jürgen suffered a sudden, unexpected, and deadly stroke in + May 2022. I will miss his friendship profundly.} +\end{framed} + +\subsection{Basic usage and purpose} \begin{itemize} \item To use with |etex|, |pdftex|, ..., i.e.\@ with \TeX{} engines activating the e\TeX{} extensions: \begin{everbatim} \input xintexpr.sty -\xintfloateval{sqrt(13), cos(1), exp(13.3)}% uses 16 digits per default -\xintDigits*:=32;% reload log and trig libraries -\xintfloateval{sqrt(13), cos(1), exp(13.3)}% now with 32 digits -\xinteval{2^1000}% exact computations -\xinteval{reduce(add(1/i, i=1..50))}% dummy variables \end{everbatim} \item To use with the \LaTeX{} macro layer (|latex|, |pdflatex|, ...): \begin{everbatim} \usepackage{xintexpr} -% and here you have to wait for \begin{document}... -% or rather you can start playing immediately: -\typeout{\xinteval{sqrt(13, 60)}} \end{everbatim} \end{itemize} -\xintexprname is a package to do expandable computations, either exactly with -arbitrarily big inputs (fractions, arbitrarily long decimal expansions, ...), -or in the sense of floating point numbers (logarithm, exponential, sine, -cosine, ...). The math functions are implemented up to \dtt{62} digits of -precision. The square root (as well of course as the four operations) achieve -correct rounding in arbitrary precision. +Some random examples: +\begin{everbatim*} +$\sqrt{13}, \cos(1), \exp(13.3) = \xintfloateval{sqrt(13), cos(1), exp(13.3)}$\par +\end{everbatim*} +\begin{everbatim*} +\begin{center} + \xintDigits*:=32;% this sets the precision to 32 digits for the math functions + \begin{minipage}{34\fontcharwd\font`0} + \xintfloateval{sqrt(13), cos(1), exp(13.3)}\par + \end{minipage}% +\end{center} +\end{everbatim*} +\begin{everbatim*} +$2^{1000}=\printnumber{\xinteval{2^1000}}$\par% exact computations +\end{everbatim*} +\begin{everbatim*} +% dummy variables +\[\sum_{i=1}^{50}\frac1i=\xintTeXFrac{\xinteval{reduce(add(1/i, i=1..50))}}\] +\end{everbatim*} +\begin{everbatim*} +\[\sum_{i=1}^{50}\frac1{i^2}=\xintTeXFrac{\xinteval{reduce(add(1/i^2, i=1..50))}}\] +\end{everbatim*} +Computations are done expandably. This means that for example +\begin{everbatim} +\typeout{\xinteval{sqrt(13, 70)}} +\end{everbatim} +will compute on the fly while writing out to the log file (|\typeout| is +the \LaTeX\ idiom), here the square root of \dtt{13} correctly rounded +to \dtt{70} significant digits. + +Indeed, \xintexprname is a package to do expandable computations, either +exactly with arbitrarily big inputs (fractions, arbitrarily long decimal +expansions, ...), or in the sense of floating point numbers (logarithm, +exponential, sine, cosine, ...). The math functions are implemented up +to \dtt{62} digits of precision. The square root (as well of course as +the four operations) achieve correct rounding in arbitrary precision +(i.e.\@ even with more than \dtt{62} digits, and may even handle +thousands of digits but reasonable range is not beyond a few hundreds). The syntax to modify the precision used for floating point evaluations is \begin{everbatim} \xintDigits*:= <Number>; -\end{everbatim} -Use the |*| (\csbxint{Digits*}), else the scientific libraries will not be -reloaded. The current precision is available as \csbxint{theDigits}, +\end{everbatim}\smallskip +\begin{footnotesize} + For reasons of the history of the package, one usually will want to + use indeed the |*| (see \csbxint{Digits}), as the more lightweight + variant without it does let the four operations and the square root + obey the new setting but it does not recalibrate the \xinttrigname and + \xintlogname libraries and their built-in constants.\par +\end{footnotesize} +The current precision is available as \csbxint{theDigits}, and defaults +to \dtt{16}, but in this documentation I might be using simply |Digits| to refer to it. -The tables of the built-in -\hyperref[tab:precedences]{operators} and \hyperref[tab:functions]{functions} +The table of \hyperref[tab:precedences]{built-in operators} +and the one of \hyperref[tab:functions]{built-in functions} will give a quick overview of the available syntax. -The simplest way\footnote{I am assuming here Mac OS or Linux, -adapt to your environment} to test the syntax is to work interactively on the command line -(this feature is available since April 2021, the version of + +\subsection{\ctanpackage{xintsession}} + +The simplest way\footnote{I am assuming here in the displayed example a + Unixen system, i.e. Mac OS or Linux, adapt to your environment.} to +test the syntax is to work interactively on the command line (this +feature is available since April 2021, the version of \ctanpackage{xintsession} used here is |1.3a|): \begin{everbatim} rlwrap etex xintsession @@ -4366,384 +4829,36 @@ No pages of output. Transcript written on xintsession.log. \end{everbatim} -\medskip - -Warning: I don't have the time to maintain perfectly such large documentation. -In preparing the |1.4| release I may have missed updating some bits -which got randomly shuffled to new places (at least I did delete large -sections, which was a hard decision to take, almost breaking the palimpsest -quality of the document). Reports welcome.% -% -\footnote{Thanks to Jürgen Gilg for keeping the author motivated and helping - proof-read the 1.4 documentation. Sadly, Jürgen passed away unexpectedly in - 2022. His enthusiasm, kindness, and friendship will be profundly missed.} - -\subsection{Breaking changes since the \texttt{1.4} release} - -\subsubsection{Breaking changes at the \texttt{1.4k} release} - -\begin{enumerate}[noitemsep] - \item Changed behaviour for nested - \csbxint{exprSafeCatcodes}/\csbxint{exprRestoreCatcodes}. - \item The output format of \csbxint{floateval}, which by default is produced - by \csbxint{PFloat}, has changed once more (!): integers (without - scientific exponent) get now printed without a trailing "\dtt{.0}". - Furthermore trailing zeros in the significand are removed only if there are - at least \dtt{4} of them. This changed behaviour is reversible - via customizing macros. - \item \csbxint{Float} now outputs the zero value as - "\dtt{\xintFloat{0}}". Customizable via \csbxint{FloatZero}. -\end{enumerate} - -\subsubsection{Breaking changes at the \texttt{1.4g} release} - -\begin{enumerate}[noitemsep] - \item Power operators |**| and |^| are now parsed - in a right associative way:% -% - \footnote{Don't try |2^3^4^5| at home. This is BIG.} -\begin{everbatim*} -$${({(5^4)}^3)}^2=5^{4\cdot3\cdot2}=\xinteval{((5^4)^3)^2}=\xinteval{5^24}$$ -$$5^{4^{3^2}} = 5^{262144}\approx \xintTeXfromSci{\xintfloateval{5^4^3^2}}$$ -\end{everbatim*} - - \item Single character operators |&|, \verb=|=, and |=| (which were - deprecated since |1.1|) have been removed. Use |&&|, \verb=||= and |==| - respectively. -\end{enumerate} - -\subsubsection{Breaking changes at the \texttt{1.4f} release} - -\begin{enumerate}[noitemsep] -\item \csbxint{ieval}|{[-D]...}|\IMPORTANT{} - which quantizes to a multiple of |1eD| when - |D| is positive now does \emph{NOT append the |D| trailing zeroes anymore}! -\item \func{float\string_dgt} is the new name of |float_()|, as already - documented but - not yet done at |1.4e|. -\item Powers in \csbxint{floateval} with big exponents are computed with more - accuracy. -\item For |Digits| at most \dtt{8}, powers in \csbxint{floateval} with integer - or half-integer exponents do not use \func{log10}/\func{pow10} method but - (as for |Digits| at least \dtt{9}) the \csbxint{FloatPower} based approach, - allowing very big integer of half-integer exponents while keeping accuracy. -\item Computations with math functions in \csbxint{floateval} at a setting of - |Digits| higher than \dtt{62} will produce an output limited to the smallest - of |Digits| and \dtt{64} digits. -\end{enumerate} - -\subsubsection{Breaking changes at the \texttt{1.4e} release} - -In principle, I try for breaking changes regarding output to happen only at -major releases. But it is not as if I had a gigantic user base, and sometimes -it is needed to move forward; and as the \TeX\ world does not have a -``pinning'' mechanism like Python's world, the distinction between minor and -major releases is a bit rhetorical. So |1.4e| behaves like a major release. -It is not one because a complete rework of the foundations of floating point -support is needed... - -|1.4e| changes the output format used by \csbxint{eval}, \csbxint{ieval}, and -\csbxint{floateval} (in short all is modified!). - -\begin{itemize} -\item \csbxint{floateval} output macro \csbxint{PFloat} has been modified. In - particular mantissas are trimmed of trailing zeros. - {\setbox8\hbox{Integers are printed with a zero after the decimal mark.}% - \rule[0.5ex]{\wd8}{1pt}\kern-\wd8\box8}\CHANGED{1.4k again} -\item \csbxint{eval} output macro \csbxint{FracToSci} has been modified, - regarding the handling of numbers involving a decimal exponent; rather than - printing out an integer mantissa, it uses scientific notation, - i.e.\@ more specifically it uses the same conventions as - \csbxint{PFloat}, but of course without pre-rounding to the |Digits| precision. - The \csa{xintFracToSciE} macro was removed because \csbxint{PFloatE} - is used in its place. - - Notice though that fractions are still not automatically reduced to lowest - terms even on output. I hesitated about this, but when for example the - computation is a large power of an already known to be irreducible fraction, - it would be a very costly operation to apply \csbxint{Irr} or \csbxint{PIrr} - to it. -\item \csbxint{ieval} was modified to use on output - \csbxint{DecToString}, not \csbxint{FracToSci}. - - This means than in case of usage of the |[D]| optional argument with a - negative |D| (i.e.\@ rounding the output to a multiple of a positive power - of ten) the output does not use scientific notation but is an integer ending - with explicit zeros. - - Update: at |1.4f| this was changed again.\IMPORTANT{} Now no trailing zeroes - are added at all! - - Nothing was changed to output for the case of a positive |[D]| (i.e.\@ - rounding to |D| figures after decimal point). One now only needs to - configure the new \csbxint{iexprPrintOne} to be \csbxint{DecToStringREZ} in - order for trailing zeros in decimal expansions to get trimmed rather than - there being always exactly |D| figures after decimal point. -\item Fractional powers are now allowed in \csbxint{eval}; powers with integer - exponents are still computed exactly of course, except that if the integer - exponent is \dtt{10000} or more, or if it is is - evaluated that the output will contain more than (about) \dtt{10000} digits - (separately for the numerator and denominator), - then the floating-point branch is taken forcedly. More details on fractional - powers are available in \xintlogname. -\item \csa{poormanloghack} is now a no-op; to use the logarithm, - exponential, and powers based on \ctanpackage{poormanlog}, set Digits to at - most \dtt{8}. Don't forget the |*| in the |\xintDigits*:=8;| syntax. - \item The \csbxint{floatexprPrintOne} macro interface has changed, it is now - to be used with (an expandable) macro either allowing or requiring the - rounding precision to be present as |[P]|, not |{P}|. Its default - is the user level \csbxint{PFloat} whose behaviour has changed. -\end{itemize} - -\begin{framed} - STARTING FROM HERE THE DOCUMENTATION MAY NOT BE UP-TO-DATE AT |1.4e| - RELEASE, IT MAY CONTAIN OBSOLETE INFORMATION -\end{framed} - -\subsection{Features added since the \texttt{1.4} release} - -For bugfixes and possibly more details check |CHANGES.html|: -\centeredline{|texdoc --list xint|} - - -\begin{itemize} -\item The most important has been the improved support for logarithm, exponential, -sine, etc...\@ added at the \texttt{1.4e} release of \texttt{2021/05/05}: - -They\NewWith{1.4e !!} are now supported up to \dtt{62} digits and achieve «correct rounding»% -% -\footnote{This means that the produced value is the rounding to |Digits| - significant digits of the theoretical exact mathematical value. The - rounding mode is currently not customizable and is «rounding to nearest, - ties go to infinity of same sign».} -% -at least -in \dtt{99\%} of cases% -% -\footnote{It is even better than that, but depends a bit on how |Digits| is - located relative to some thresholds governing Taylor series - or other approximation means.} -% -for |Digits| being at least \dtt{9}. - -For Digits up to \dtt{8}, a special more approximate implementation is used, -and the functions achieve the correct rounding (particularly at |Digits| -equal to \dtt{8} or \dtt{7}) less often, but are significantly faster -(especially logarithm, exponential, powers) than working with \dtt{9} digits -or more. The achieved precision is largely enough for plots. - -See \xintlogname and \xinttrigname for some additional information. - -\item The long awaited\NewWith{1.4k} syntax \csbxint{ieval}|[D]{...}| and - \csbxint{floateval}|[Q]{...}| has been implemented. The legacy - \csbxint{ieval}|{[D]...}| and \csbxint{floateval}|{[Q]...}| syntax is kept - for backwards compatibility. - -\item \csbxint{FloatToDecimal}, \csbxint{FracToDecimal}.\NewWith{1.4k} - -\item \csbxint{PFloat}\NewWith{1.4k} is customizable via \csbxint{PFloatZero}, - \csbxint{PFloatIntSuffix}, \csbxint{PFloatLengthOneSuffix}, - \csbxint{PFloatNoSciEmax}, \csbxint{PFloatNoSciEmin} and - \csbxint{PFloatMinTrimmed}. - -\item \csbxint{FloatZero}.\NewWith{1.4k} - -\item The concept of simultaneous assignments is extended:\NewWith{1.4i} in - case of more variables than values the extraneous variables do not cause an - error message but are simply set to the |nil| value; in case of more values - than variables, the last variable is defined to be the ople concatenating - all the extra values. See \csbxint{defvar}. - -\item Built-in\NewWith{1.4i} functions usable with arbitrarily many arguments - such as \func{max}, \func{gcd}, or \func{len} are now again usable with a - single numeric argument: since |1.4| a lone argument had to be a |nutple| - (which was automatically unpacked). It can now again be a number. - - \item \csbxint{TeXfromSci}\NewWith{1.4g} - - \item The constraints for the replacement macro to be used for - \csbxint{exprPrintOne} have been much simplified. See the - documentation of \csbxint{FracToSci} which is the package default. - %\NewWith{1.4e} - - \item \csbxint{iexprPrintOne} was added, with default - \csbxint{DecToString}.%\NewWith{1.4e} - - \item \csbxint{DecToStringREZ} was added.%\NewWith{1.4e} - - \item The function \func{zip}. - - \item The function \func{flat}. - - \item Chaining of \hyperlink{\detokenize{prec-10}}{comparison operators} à la - Python (no short-circuit, though) and |l3fp|. - - \item \csbxint{PFloatE} to specify like \csa{xintFracToSciE} (now defunct at - |1.4e|) does for - \csbxint{eval} since |1.4| the separator to use between mantissa and - exponent in the output of \csbxint{floateval} output. - - \item \csbxint{thespaceseparated} (serves to provide suitable input - to PS-Tricks |\listplot|). - - \item The optional argument |[D]| to \csbxint{iexpr} (or \csbxint{ieval}) - can be negative, with about the same meaning as the non-negative case, i.e. - rounding to an integer multiple of |1e-D|. But attention that at |1.4f|, - for |D<0|, this is now interpreted as the rounded quotient by |1e-D| (no - trailing zeros appended, no scientific exponent either). - - \item Also the second argument of \func{trunc} and \func{round} can be - negative (but then it enacts quantization, e.g |trunc(1234,-2)| produces - \dtt{\xinteval{trunc(1234,-2)}}). Matching updates to the support - macros \csbxint{Trunc}, \csbxint{Round}, \csbxint{iTrunc}, and - \csbxint{iRound}. - - \item Support by \func{add} and \func{mul} for \keyword{omit}, \keyword{abort} - and \func{break}.% -% - -\end{itemize} - -\subsection{The \texttt{1.4} release of \texttt{2020/01/31}} - -|1.4| brought some new features (involving significant evolution of the -\xintexprname.sty source code) and a few (but important) breaking changes. -See |CHANGES.html| which contains information which may not yet have been -included into this PDF documentation. - -The main new feature was (initial) support for nested structures. For a quick -idea of already available related abilities check for example \func{ndseq} or -\csbxint{defufunc}. See also \csbxint{thealign}. However, please grant the -author a few decades to finish absorbing Python/NumPy. - -\begin{framed} - The main breaking changes were: - \begin{itemize} - \item \xintexprname |1.4| requires the |\expanded| primitive, which is - provided by all major \TeX{} engines since \TeX Live 2019. The macro - packages \xintname, \xintfracname, \xinttoolsname et al.\@ do not (yet) - require |\expanded|. - - It is probable also |\pdfstrcmp| (|\strcmp|) will be required at some point - but it has been provided by major \TeX{} engines for a long time already. - - \item \csbxint{eval} (and \csbxint{expr}) output does not use anymore the - \xintfracname ``raw'' format |A/B[N]|, rather it uses scientific notation - |AeN/B|, dropping the exponent and/or denominator if they are - respectively \dtt{0} and/or \dtt{1}. This means that output can now be - copied pasted directly to competing software on the market, such as Python - or Maple. The output format of \csbxint{floatexpr} (which uses macro - \csbxint{PFloat}) was left un-modified although the prettifying done by it - is not necessarily the best choice when displaying a nested structure via - \csbxint{thealign} (perhaps next major release will reconsider that - choice); and the way the zero value is output by \csbxint{floateval}, - currently \dtt{\xintfloateval{0}} is yet to be chosen definitely. The - used (\emph{expandable}) macro for output can be specified by user. - - \item Syntax such as |x*[a, b, c]| or |[a, b, c]+x| for itemwise operation - on «lists» has been (provisorily) dropped. Indeed, the brackets |[...]| - are now genuine constructors of nestable structures, and implementing the - feature (analogous to NumPy's concepts) will require overloading all - scalar infix operators. Alternative already exist in the syntax for - example |seq(x*y, y = a,b,c)|. Actually in future |x*[a, b, c]| will be - as |[x*a, x*b, x*c]| i.e.\@ will keep the brackets, which prior to |1.4| - on their own were no different from parentheses. - \end{itemize} -\end{framed} - -\subsection{Known bugs/features (last updated at \texttt{1.4j})} - -\begin{description} -\item[if(100>0,(100,125),(100,128)) breaks my code:] -% - This is a feature. This is a syntax error, as the comma serves to contatenate - "oples" (see \autoref{oples}), and parentheses do not create analogs of - "tuples", so this input is parsed the same as -\begin{everbatim} - if(100>0,100,125,100,128) -\end{everbatim} - which is an error as \func{if} requires exactly three arguments, not - five. Use: -\begin{everbatim} - if(100>0,[100,125],[100,128]) -\end{everbatim} - which will expand to the "tuple" |[100,125]|. -\item[{\detokenize{\xintdeffunc foo(x):= gcd((x>0)?{[x,125]}{[x,128]});} - creates a broken function:}] -% - Bug. Normally \func{gcd} (and other - multi-arguments functions) work both with open lists of arguments or - bracketed lists ("nutples") and the above syntax would work perfectly fine - in numerical context. But the presence of the \oper{?} breaks in - \csbxint{deffunc} context the flexibility of \func{gcd}. - - Currently working alternatives: -\begin{everbatim} -\xintdeffunc foo(x) := gcd(if(x>0, [x,125], [x,128])); -\xintdeffunc foo(x) := if(x>0, gcd(x,125), gcd(x,128)); -\xintdeffunc foo(x) := if(x>0, gcd([x,125]), gcd([x,128])); -\xintdeffunc foo(x) := gcd((x>0)?{x,125}{x,128}); -\xintdeffunc foo(x) := (x>0)?{gcd(x,125)}{gcd(x,128)}; -\xintdeffunc foo(x) := (x>0)?{gcd([x,125])}{gcd([x,128])}; -\end{everbatim} - The same problem will arise with an \oper{??} nested inside \func{gcd} or - similar functions, in an \csbxint{deffunc}. - - \item[{\detokenize{\xinteval{0^-.5}} says "0 raised to power -1"}] -% - Feature. Half integer exponents are handled via a square-root extraction, so - here \xintexprname wanted to first raise \dtt{0} to power \dtt{-1}, as - reported. +\subsection{\ctanpackage{polexpr}} - \item[{Comparison operator \detokenize{==} crashes with nutples}] -% - Not yet implemented... +The package \ctanpackage{polexpr} enriches the \csbxint{eval} syntax +(but not the one of \csbxint{floateval}) with a polynomial type with +associated constructor |pol([c0,c1,...])|, and polynomial specific +functions such as |polgcd(pol1, pol2, ...)|. - \item[{I liked the ``broadcasting'' \detokenize{[1..10]^10} syntax, but it - was removed at 1.4}] -% - Patience...\@ |seq(x^10,x=1..10)| is alternative (add external |[..]| to get - a nutple). - \item[{\detokenize{1e\numexpr5+2\relax} crashes}] -% - Not clear yet if bug or feature. - The syntax accepted in the scientific part is limited, and failure - is expected: hitting a |\numexpr| - when parsing a number triggers insertion of a tacit multiplication and then - |1e| is missing the scientific exponent. The same happens with |1e(2+3)|. - Use syntax such as |1e\the\numexpr5+2\relax|, or |1e\xinteval{5+2}| - (although here this relies on output format of |\xinteval| using integer - notation with no decoration in this case). +Full usage of polynomials (and algebraic notations |c_0 + c_1 x + c_2 +x^2 + ...| for input and also output) goes through a dedicated |\poldef| +parser which is based upon \csbxint{defvar}/\csbxint{deffunc} and is a +necessary step to then access via a dedicated macro interface operations +such as identifying all rational roots and isolating all real roots to +arbitrary precision. - \item[{seq(1e-i,i=1..5) crashes}] -% - Not clear if bug or feature. Use |seq(1e\xinteval{-i},i=1..5)| or, as a - possibly faster way |seq(1e\xintiieval{-i},i=\xintiiexpr1..5\relax)|. +The simplest manner to experiment with \ctanpackage{polexpr} is via the +|&pol| mode of \ctanpackage{xintsession}. - \item[{omit/abort if nested and not last in the sub-expression cause a crash}] -% - For example |seq(subs((i)?{i}{abort},t=i)+10, i=-2, -1, 0, 1)| crashes, due - to the presence of the |+10|. This is a longstanding limitation, applying - ever since |omit/abort| were added to the syntax at |1.1|. Even without - the |+10| the nested case was broken by a |1.4| regression and got fixed - only at |1.4h|. The non-nested case |seq((i)?{i}{abort}+10, i=-2, -1, 0, - 1)| works and the «must be last in expression if nested» limitation is - currently considered a feature. +\subsection{\ctanpackage{bnumexpr}} -\item[{seq([i,i\string^2], i=1..10) crashes with Ooops, looks like we are missing a - ]. Aborting!}] -% - The cause is that the square brackets do not hide the comma from |seq()| - parsing. This will probably remain ``wont-fix''. Work-arounds: either use - an extra pair of parentheses |seq(([i,i^2]), ...)| or hide the inner - comma within braces |seq([i{,}i^2], ...)|. -\end{description} +This small package loads \xintcorename and provides the functionality of +the integer-only \csbxint{iiexpr}/\csbxint{iieval} parser, but dropping +support for nested structures, functions, variables, boolean branching, +etc...\@ It includes by default support for hexadecimal input (with |"| +prefix) and output based upon \xintbinhexname. Compared to +|\the\numexpr| it adds support for arbitrarily large integers, powers +with |**| and |^|, factorials via |!| postfix operator, floored division +and associated modulo, and comma separated multi-item expressions. -The list stops here, but there are certainly other pending bugs in my bug-log, -and many more I am not yet aware of. In particular it is already mentioned in -the \csbxint{deffunc} documentation that it can not parse currently the -entirety of the available purely numerical syntax, some (documented or not, -known or not) limitations apply. +It also offers a user-level interface to add extra infix or postfix +operators. \subsection{License and installation instructions} @@ -4759,50 +4874,72 @@ Else, \href{https://ctan.org/pkg/xint}{CTAN} access provides |xint.tds.zip| which has all source code and documentation in a TDS-compliant archive, only waiting to be |unzip -d <DIR>| into some suitable hierarchical structure. -Else, |etex xint.dtx| extracts all source code. A |Makefile| is also provided -with targets such as |xint.pdf| or |sourcexint.pdf|. Even if your system does -not allow executing |make|, the rules it contains can be imitated manually -(if possible using |Latexmk|). +Check |README.md| for more possibilities. -With \TeX\ distributions providing a |"texdoc"| or similar utility, -\centeredline{|texdoc --list xint|} -gives the choice to display one of: -\begin{itemize}[nosep] -\item |xint.pdf| (this file), -\item |sourcexint.pdf| (source code), -\item |README.md|, -\item |CHANGES.html|. -\end{itemize} +% Else, |etex xint.dtx| extracts all source code. A |Makefile| is also provided +% with targets such as |xint.pdf| or |sourcexint.pdf|. Even if your system does +% not allow executing |make|, the rules it contains can be imitated manually +% (if possible using |Latexmk|). \subsection{Printing big numbers on the page}\label{ssec:printnumber} + When producing very long numbers there is the question of printing them on the page, without going beyond the page limits. In this document, I have most - of the time made use of these macros (not provided by the package:) - -% + of the time made use of a ``|\printnumber|'' macros, not provided by + the package, and which is coded like this (with some extra decorations): \everb|@ \def\allowsplits #1{\ifx #1\relax \else #1\hskip 0pt plus 1pt\relax \expandafter\allowsplits\fi}% \def\printnumber #1{\expandafter\allowsplits \romannumeral-`0#1\relax }% -% \printnumber thus first ``fully'' expands its argument. | -It may be used like this: +This macro triggers ``\fexpan sion'' of its argument (and indeed +\csbxint{eval} and friends expand completely under such triggering), +then it goes through the computation result character by character +inserting \TeX\ potential break points in-between them. % \begin{everbatim*} \printnumber{\xintiieval{100!^3}}\newline \end{everbatim*}% -The rendering here uses extra decoration. + +\subsection{The package documentation} + +With \TeX\ distributions providing a |"texdoc"| or similar utility, +\centeredline{|texdoc --list xint|} +will offer the choice to visualize one of those files: +\begin{enumerate}[nosep] +\item |xint.pdf| (this file) +\item |sourcexint.pdf| (commented (hmm...) source code) +\item |CHANGES.html| +\item |README.md| +\end{enumerate} + +Warning: I don't have the time to maintain perfectly such large +documentation. It currently combines old documentation which never +really got updated and may be locally obsolete with more recent stuff +mostly written on occasion of the |1.4| release of January 2020 and the +|1.4e| one of May 2021, and the intervening changes might also have made +some of it not completely accurate, despite my best efforts. Bug +reports and feature requests are most welcome. + +The section formerly included with this documentation and documenting +the changes since the |1.4| release has been removed as it was too +time-consuming to maintain it here. Please refer to |CHANGES.html| for +the detailed listing: \centeredline{|texdoc CHANGES.html|} On the +internet: +\centeredline{\url{http://mirrors.ctan.org/macros/generic/xint/CHANGES.html}} +% +A one-page condensed ``timeline'' is to be found at the start of +|sourcexint.pdf|. \clearpage \expandafter\let\csname Start herenameUp\endcsname\undefined \csname xintexprnameUp\endcsname -\section{\xintexprname syntax reference and user guide} +\section{Syntax reference and user guide} \RaisedLabel{sec:expr} \localtableofcontents - \subsection{The three parsers} \xintexprname provides three numerical expression parsers corresponding to @@ -4893,7 +5030,8 @@ the output be formatted with such separators. would be a bit cumbersome in a \TeX{} workflow, if only for matters of syntax highlighting in \TeX-aware text editors). \begin{everbatim*} -\xintiieval{add((i/:7)?{omit}{i^5}, i=1000..1020)}% only add fifth powers of multiples of 7 +% add the i^5 only if i is a multiple of 7 +\xintiieval{add((i/:7)?{omit}{i^5}, i=1000..1020)} \end{everbatim*} \item \csbxint{floateval}\oarg{Q}\marg{expression} does floating point @@ -4912,6 +5050,8 @@ the output be formatted with such separators. last, this is not required anymore.\NewWith{1.4k} The legacy syntax is and will keep being allowed. + + The infix operator \oper{/} will compute the correct rounding of the exact fraction. The operator \oper{//} is floored division and \oper{/:} is its associated modulo (see also \func{divmod}). @@ -5001,31 +5141,107 @@ is \csbxint{floateval} and \csbxint{floatexpr}. \label{xintfloatexprPrintOne} \label{xintboolexprPrintOne} -The package provides only minimal facilities for formatting the numeric -output. A possibly not up-to-date list is (the first two use math -mode mark-up): \csbxint{TeXfromSci}, \csbxint{TeXFrac}, \csbxint{DecToString}, -\csbxint{PRaw}, \csbxint{FracToSci}, \csbxint{FracToDecimal}, -\csbxint{PFloat} and -\csbxint{FloatToDecimal}. More advanced formatting is left for the user to -provide by own macros or possibly using third-party packages. +The package provides only minimal facilities for formatting the output +from \csbxint{eval} or \csbxint{floateval} or\dots. And this output may +well consist of comma separated values, even nested ones with, by +default, square brackets. See the section about \csbxint{thealign} and +its customization possibilities. -It is indeed possible to configure the parsers to use custom macros for output. -Here are the default package definitions: +Rather to condemn the user customization to have to employ macros able +to handle such comma separated lists, possibly nested, the package +provides an interface to customize the handling of individual numerical +leaves. Here are the default definitions to this effect: \begin{everbatim} -\def\xintexprEmptyItem{[]} -\def\xintexprPrintOne{\xintFracToSci} -\def\xintiexprPrintOne{\xintDecToString} -\def\xintiiexprPrintOne #1{#1} -\def\xintfloatexprPrintOne{\xintPFloat} +\def\xintexprEmptyItem{[]} % (all parsers) +\def\xintexprPrintOne #1{\xintFracToSci{#1}} % \xinteval +\def\xintiexprPrintOne #1{\xintDecToString{#1}} % \xintieval +\def\xintiiexprPrintOne#1{#1} % \xintiieval +\def\xintfloatexprPrintOne [#1]#2{\xintPFloat[#1]{#2}} % \xintfloateval \def\xintboolexprPrintOne#1{\xintiiifNotZero{#1}{True}{False}} \end{everbatim} -The typesetter for \csa{xintiiexpr} simply prints ``as is'', but this -may change in future, if some internal format is used requiring a -conversion step. Users can copy the above (\LaTeX\ users may want to -use |\renewcommand|) and modify the chosen macros. +They can be re-defined to one's wishes. \LaTeX\ users will want to use +|\renewcommand| for this. +\begin{TeXnote} + \begin{itemize} + \item Actually, the defaults are more done in the style +\begin{everbatim} +\let\xintexprPrintOne\xintFracToSci +\end{everbatim} + thus sparing grabbing the argument |#1|. And one can do +\begin{everbatim} +\def\xintexprPrintOne{\xintFracToSci} +\end{everbatim} + too. + \item |\xintexprPrintOne| defaults in truth to some private variant of + \csbxint{FracToSci} with exactly the same output but able to understand + only certain limited types of inputs as used internally. This private + variant is not \fexpan dable. + \item |\xintfloatexprPrintOne| defaults in fact to a private variant of + \csbxint{PFloat} which assumes the optional argument |[P]| is present as + it will be the case always in this context. This optional argument + |[P]| is the optional argument |[Q]| of \csbxint{floateval} (or + |Digis+Q| if |Q<0|). + \item The typesetter for \csbxint{iiexpr} simply prints ``as is'', but this + may change in future, if some internal format is used requiring a + conversion step. + \end{itemize} +\end{TeXnote} -Regarding the current behaviour of \csbxint{floateval}, here is the -default configuration of \csbxint{PFloat}: +Here is a possibly not up-to-date list of macros of interest, whose +documentations you might consider reading (the first two require math +mode): +\begin{itemize}[nosep] +\item \csbxint{TeXFromSci}, +\item \csbxint{TeXFrac}, +\item \csbxint{DecToString}, +\item \csbxint{PRaw}, +\item \csbxint{FracToSci}, +\item \csbxint{FracToDecimal}, +\item \csbxint{PFloat}, +\item and \csbxint{FloatToDecimal}. +\end{itemize} +Naming scheme, as one can see, has been pretty much incoherent, apologies. + +Among packages providing macros formatting numeric values, there are +\ctanpackage{numprint} and its macro |\np| (or |\numprint| without the +option |np|), and \ctanpackage{siunitx} +and its |\num|, and possibly more packages not known to the author.% +% +\footnote{There does not seems to be yet a \LaTeX\ user level interface to the + \liiistrformat\ package, part of |l3experimental|, which provides an + implementation of the Python |format| function.} +% +These macros are suitable in combination with \csbxint{Float} as in the +example below to customize the \csbxint{floateval} output. +% 27 mai 2022, en effet \num{1/7} ne marche pas et \numprint{1/7} non plus +Numerical output from \csbxint{eval} is more challenging as +individual values may naturally contain the |/| character for fractions which the +above mentioned packages will not know how to handle, as far as I know. + + +Example, with \LaTeX\ and |\num| from \ctanpackage{siunitx}: +\begin{everbatim} +\def\printwithnum[#1]#2{\num{\xintFloat[#1]{#2}}} +\renewcommand\xintfloatexprPrintOne{\printwithnum} +\end{everbatim} +We used |\def| with delimited parameters to define |\printwithnum| +because the optional argument will always be present at time of use, and +further the macro will be submitted to |\expanded|, but \LaTeX2e +commands with optional arguments defined via |\newcommand| are not +compatible with being submitted to |\expanded|. +\begin{TeXnote} + |\num| is a |\protected| macro, hence it will remain intact in the + |\expanded| phase. The argument |\xintFloat[#1]{#2}| will thus expand + before |\num| itself. In the case at hand |\num| is a macro which would + anyhow have triggered expansion of its argument before further processing. +\end{TeXnote} + + +The current behaviour of \csbxint{floateval} corresponds to this set-up: +\begin{everbatim} +\def\xintfloatexprPrintOne [#1]#2{\xintPFloat[#1]{#2}} +\end{everbatim} +and to this default configuration of \csbxint{PFloat}: \begin{everbatim} \def\xintPFloatE{e} \def\xintPFloatZero{0} @@ -5035,39 +5251,35 @@ default configuration of \csbxint{PFloat}: \def\xintPFloatNoSciEmin{-4} \def\xintPFloatMinTrimmed{4} \end{everbatim} -With the custom + +With the custom replacement \begin{everbatim} \def\xintfloatexprPrintOne{\xintFloatToDecimal} \end{everbatim} -the \csbxint{floateval} output wil use decimal fixed point notation, +the \csbxint{floateval} output will use decimal fixed point notation, i.e.\@ no scientific exponents, and as many zeros as are needed (but no more, as trailing zeros will be removed from the significant digits). -Here is an example with the -default configuration and then when using \csbxint{FloatToDecimal}: +Here is an example comparing outputs from the +default configuration and custom ones: \begingroup % DÉBUT DU GROUPE POUR DES EXEMPLES \begin{everbatim*} -\xintfloateval{exp(-32.456)/2000}\newline +\xintfloateval{exp(-32.456)/2000} (default, i.e. PFloat)\newline \def\xintfloatexprPrintOne{\xintFloatToDecimal}% -\xintfloateval{exp(-32.456)/2000}\par +\xintfloateval{exp(-32.456)/2000} (FloatToDecimal)\newline +\def\xintfloatexprPrintOne[#1]#2{\xintTeXFromSci{\xintFloat[#1]{#2}}}% +$\xintfloateval{exp(-32.456)/2000}$ (TeXFromSci on Float)\par % math mode required \end{everbatim*} -Similarly, with -\begin{everbatim} -\def\xintexprPrintOne{\xintFracToDecimal} -\end{everbatim} -the \csbxint{eval} output will use decimal fixed point notation (for the -numerators; the denominators are simply post-fixed with a |/| -delimiter). See \csbxint{FracToDecimal}, which like \csbxint{FracToSci} -however is not really a user level macro, it is restricted on its input -format, it understands only what is needed for the internal structure -currently used by \csbxint{eval}. Here is with the same input as above: -\begin{everbatim*} -\xinteval{exp(-32.456)/2000}\newline +Some examples showing now the effect of sensible customizations on \csbxint{eval}: +\begin{everbatim*} +\xinteval{exp(-32.456)/2000} (default, i.e. FracToSci)\newline \def\xintexprPrintOne{\xintFracToDecimal}% -\xinteval{exp(-32.456)/2000}\par +\xinteval{exp(-32.456)/2000} (FracToDecimal)\newline +\def\xintexprPrintOne#1{\xintTeXFromSci{\xintFracToSci{#1}}}% +$\xinteval{exp(-32.456)/2000}$ (TexFromSci on FracToSci)\par % math mode required \end{everbatim*} Notice that the |/2000| denominator remains ``as is'' in the -output in both cases, in conformity with the documented behaviour of +output, in conformity with the documented behaviour of \csbxint{FracToSci} in the first example and of \csbxint{FracToDecimal} for the second example. This has not changed since |1.4| (the handling of the numerator part has changed at |1.4e| and again slightly at @@ -5075,15 +5287,22 @@ of the numerator part has changed at |1.4e| and again slightly at \dtt{0} or \dtt{0.0} depending on the input) but is to be considered unstable and undecided so far. -A more costly typesetter could be for example: +A slightly more costly typesetter could be for example: \begin{everbatim} \def\xintexprPrintOne#1{\xintDecToStringREZ{\xintIrr{#1}}} \end{everbatim} -Then the fraction (inclusive of its power of ten part) will be reduced -to lowest terms (see \csbxint{Irr}), next the trailing zeros will be -moved as an exponent (positive or negative) to the numerator, and -finally this numerator with a power of ten part will be printed in -decimal fixed point notation, with as few zeros as are needed. With the +Then +\begin{itemize}[nosep] +\item the fraction (inclusive of its power of ten part) will be reduced + to lowest terms (see \csbxint{Irr}), +\item next the trailing zeros will be moved as an exponent (positive or + negative) to the numerator, +\item this numerator with a power of ten part will be printed in decimal + fixed point notation, with as few zeros as are needed, +\item and finally the denominator |B|, which has been trimmed of trailing + zeros, will be printed as |/B| or not at all if |B=1|. +\end{itemize} +With the use case above: \begin{everbatim*} \def\xintexprPrintOne#1{\xintDecToStringREZ{\xintIrr{#1}}} @@ -5098,82 +5317,99 @@ educated to identify its presence and handle it. Slightly faster (see \end{everbatim} which with the used example produces the same output. +One can also consider this for math mode: +\begin{everbatim*} +\def\xintexprPrintOne#1{\xintTeXFromSci{\xintDecToStringREZ{\xintIrr{#1}}}} +$\xinteval{exp(-32.456)/2000}$\par +\end{everbatim*} +See our hesitations about what \csbxint{TeXFromSci} should do with +denominators. + +\begin{TeXnote} + One can hope that in future \csbxint{DecToString} will identify + denominators being products of only two's and five's, but even then of + course \csbxint{TeXFromSci} will have to decide how to handle other + denominators. +\end{TeXnote} + \endgroup % FIN DU GROUPE POUR LES EXEMPLES -\medskip -Nested structures (for full internal details, see \autoref{oples}) -are rendered by default using left and right brackets, -commas and spaces in a non-customizable way, except via -\csa{xintexprEmptyItem}. For full customizability, use -\csbxint{thealign}, which is described in the next section. % The \csbxint{PFloatE} is now allowed to a be macro with an argument delimited % by a dot, this argument will be the exponent.\NewWith{1.4e} The output must be produced % \fexpan dably and again be delimited by a dot. The default does not grab the % exponent and simply inserts the letter |e|. -\paragraph{\TeX hackers note:} -Attention! The macros used in place of \csbxint{FracToSci} and -\csbxint{PFloat} must currently understand the raw \xintfracname format -|A/B[N]|, with the |/B| and |[N]| parts being optional. These requirements -may change at any release. - -Currently the interface for the macro used by -\csbxint{floatexprPrintOne} % changed at |1.4e|.\CHANGED{1.4e} -must be the same as -\csbxint{PFloat}. %, i.e. the target precision is |[P]| not a -%braced argument. -But it will always be employed with the |[P|] present hence does not -have to consider it to be optional. - -The replacement macros must be compatible with expansion-only context, but do not -have to be \fexpan dable. - -% % pour mémoire -% \footnote{The constraints on any replacement to \csbxint{FracToSci} are much -% simplified at |1.4e|. Previously it had to be able to accept also input in -% fixed point notation, and in scientific notation with a catcode 12 |e|.} -% % +\begin{TeXnote} + The macro used as customization of \csbxint{exprPrintOne} (whose default is + a private variant of \csbxint{FracToSci} with exactly same output) must + understand the internal \xintfracname format |A/B[N]|, but with the |/B| and + |[N]| parts being only optional. This is not a problem when using for this + task (nested) macros of \xintfracname, as they of course accept such + inputs as argument and in fact much more general ones. + + In particular one can benefit from \csbxint{Raw}, or \csbxint{RawBraced}, to + convert the argument into a well defined shape (|A/B[N]| for the former and + |{N}{A}{B}| for the latter) and then work from there. + + The macro used by \csbxint{floatexprPrintOne} has the guarantee that the + |[P]| will be always present at expansion time. -\subsubsection{\csh{xintthealign} for multiple items outputs} + The customization should be compatible with being exposed to |\expanded| + (which is like expansion in an |\edef|), either from being completely + expandable or at the opposite from being |\protected|. \LaTeX2e commands + defined via |\newcommand| as macros with one optional parameter are not + compatible with this requirement. + + Attention! The interface requirements described above for the macros + customizing the behaviours of \csbxint{exprPrintOne} and + \csbxint{floatexprPrintOne} may change at any release... as they + depend on some internal structures and it is not certain backwards + compatiblity will be maintained systematically in case of evolution. +\end{TeXnote} + + +\subsubsection{\csh{xintthealign} for general oples and nutples} \label{xintthealign} With \csbxint{thealign} one can get nested data use a \TeX{} alignment in the -output. Attention, this must be followed by \csbxint{expr} et al., never by -\csbxint{theexpr} or \csbxint{eval}. -Here is an example : +output. Here is an example : \begin{everbatim*} \xintthealign\xintexpr ndseq(1/(i+j), i = 1..10; j=1..10)\relax \end{everbatim*} +Attention, this \csa{xintthealign} must be a prefix to \csbxint{expr}, +or \csbxint{floatexpr} etc..., but there will be low-level \TeX\ errors +if it is used to prefix \csbxint{eval} et al. or \csbxint{theexpr} et al. -It is possible to customize the behaviour of |\xintthealign|.\CHANGED{1.4a} -The helper macros, apart from |\xintexpralignbegin| and |\xintexpralignend| -will be subjected to a complete (|\expanded|) expansion (once).% -% -\footnote{\csa{xintexpralignend} is expanded once, after the body has been - submitted to exhaustive expansion, and prior to the expansion of - \csa{xintexpralignbegin}.} -% -The package -uses here |\protected| with no strong reason, as the replacement tokens are -not expanding anyhow, but the idea is that this allows to define a macro in an -|\edef| and later change the meaning of the auxiliary macros depending on what -one wants to do with the expansion result. See also further down the \LaTeX{} -example with a matrix environment, where |\noexpand| rather than |\protected| -is used. +It is possible to customize the behaviour of |\xintthealign|. For example:\CHANGED{1.4a} \begin{everbatim} \protected\def\xintexpralignbegin {\halign\bgroup\tabskip2ex\hfil##&&##\hfil\cr}% \def\xintexpralignend {\crcr\egroup}% removed \protected at 1.4c \protected\def\xintexpralignlinesep {,\cr}% separates "lines" -\protected\def\xintexpralignleftsep {&}% at left of first item in a "line" (after brackets) +\protected\def\xintexpralignleftsep {&}% at left of first item in a "line" + % (after "left bracket") \protected\def\xintexpraligninnersep {,&}% at the left of non-first items -\protected\def\xintexpralignrightsep {&}% at right of last item in a "line" (before brackets) +\protected\def\xintexpralignrightsep {&}% at right of last item in a "line" + % (before "right bracket") \protected\def\xintexpralignleftbracket {[}% \protected\def\xintexpralignrightbracket{]}% \end{everbatim} -Although we will try to keep stable the way «regular arrays» are -rendered,\UNSTABLE{} the |\xintthealign| macro (and its associated customizability) is -considered work-in-progress and may experience breaking changes. +The above definitions use |\protected| with no strong reason, as the +replacement tokens are not expanding anyhow, but the idea is that this +allows to execute a computation via an |\edef| and later one can change +the meaning of the auxiliary macros depending on what one wants to do +with the expansion result. + +\begin{TeXnote} + \csa{xintexpralignend} is expanded once, after the body has been submitted + to exhaustive expansion (|\expanded| induced), and prior to the expansion of + \csa{xintexpralignbegin}. +\end{TeXnote} + +Although we will try to keep stable the way «regular arrays» as in the +above example are rendered by default,\UNSTABLE{} the |\xintthealign| +macro (and its associated customizability) is to be considered +work-in-progress and may experience breaking changes. Use for example this for outputting to a file or a terminal: \begin{everbatim} @@ -5189,12 +5425,10 @@ Use for example this for outputting to a file or a terminal: \def\xintexpralignrightbracket{]}% \end{everbatim} -\medskip - -And here is an example using a |pmatrix| environment. But it will not break +In the \LaTeX{} example next using a |pmatrix| environment, |\noexpand| +rather than |\protected| is used. This environment will not break across pages, contrarily to the display produced by the default \csbxint{thealign} configuration which uses \TeX{}'s |\halign|. - %\kern10\baselineskip %\hbox{Big empty space here} %\kern-11\baselineskip @@ -5545,7 +5779,8 @@ precedence, use parentheses for disambiguation. remaining conditionals will still be evaluated. \begin{everbatim*} -\xintifboolexpr{1<=2!=3<4>1}{true}{\error}, \xintifboolexpr{1<=2>=3<4>1}{\error}{false}, +\xintifboolexpr{1<=2!=3<4>1}{true}{\error}, +\xintifboolexpr{1<=2>=3<4>1}{\error}{false}, \xintifboolexpr{3 != 3! == 6 != 4! == 24}{true}{\error} \end{everbatim*} @@ -6692,7 +6927,8 @@ like extracting directly), but it is leaner to drop the extra «packing». implementation of the Brent-Salamin algorithm for the computation of $\pi$: \begin{everbatim*} \xintDigits:= 87\relax % we target 84 digits, and use 3 guard digits -\xintdeffloatfunc BS(a, b, t, p):= 0.5*(a+b), sqrt(a*b), t-p*sqr(a-b), \xintiiexpr 2p\relax; +\xintdeffloatfunc BS(a, b, t, p):= 0.5*(a+b), sqrt(a*b), t-p*sqr(a-b), + \xintiiexpr 2p\relax; \xinteval {trunc(% I feel truncation is better than rounding to display decimals of π \xintfloatexpr @@ -6802,7 +7038,8 @@ An optional final semi-colon in the input before the closing parenthesis is allowed. \begin{everbatim*} \begin{multicols}{2} -\xintthealign\xintexpr ndseq(a+b+c+d, a=1000,2000,3000; b=100,200,300; c=10,20,30; d=1,2,3;)\relax +\xintthealign\xintexpr ndseq(a+b+c+d, a=1000,2000,3000; b=100,200,300; + c=10,20,30; d=1,2,3;)\relax \end{multicols}% in case of page break, this makes amusing zigzag rendering \end{everbatim*} @@ -6966,7 +7203,8 @@ from Python with \emph{tuple} or \emph{list} types: rules (inclusive of negative indices). Notice though that stepping is currently not supported. \begin{everbatim*} -\xinttheiiexpr (1..20)[6:13]\relax\ = \xinttheiiexpr (1..20)[6-20:13-20]\relax\newline +\xinttheiiexpr (1..20)[6:13]\relax\ = \xinttheiiexpr (1..20)[6-20:13-20]\relax +\newline \xinttheiiexpr [1..20][6:13]\relax\ = \xinttheiiexpr [1..20][6-20:13-20]\relax \end{everbatim*} @@ -7074,7 +7312,8 @@ part, or hexadecimal input), or is looking for an infix operator, and: impacts only situations with a division operator as the last seen operator, as multiplication is mathematically associative. \begin{everbatim*} -\xinttheexpr 1/(3)5, (1+2)/(3+4)(5+6), 2/x(10), 2/10x, 3/y\xintiiexpr 5+6\relax, 1/x(y)\relax\ +\xinttheexpr 1/(3)5, (1+2)/(3+4)(5+6), 2/x(10), 2/10x, + 3/y\xintiiexpr 5+6\relax, 1/x(y)\relax\ differ from\newline\xinttheexpr 1/3*5, (1+2)/(3+4)*(5+6), 2/x*(10), 2/10*x, 3/y*\xintiiexpr 5+6\relax, 1/x*(y)\relax\par \end{everbatim*} @@ -7131,11 +7370,13 @@ Simultaneous assignments\NewWith{1.4i} with more variables than values do not raise an error but simply set the extra variables to the \dtt{nil} value. \begin{everbatim*} \xintdefiivar a, b, c := [1, 2];% will be automatically unpacked -The value of a is \xinteval{a}, the one of b is \xinteval{b} and the one of c is \xinteval{c}. +The value of a is \xinteval{a}, the one of b is \xinteval{b} and +the one of c is \xinteval{c}. \end{everbatim*} \begin{everbatim*} \xintdefiivar a, b, c := 314;% -The value of a is \xinteval{a}, the one of b is \xinteval{b} and the one of c is \xinteval{c}. +The value of a is \xinteval{a}, the one of b is \xinteval{b} and +the one of c is \xinteval{c}. \end{everbatim*} Notice that \dtt{nil} variables must be used with caution as they break @@ -7260,15 +7501,19 @@ it is encountered in the typesetting flow, the print-out will be rounded to \xintfloatexpr 2.7182818284590452353602874713526624977572470936999595749669676 \relax -\relax\newline % but we can see via the \xintexpr wrapper all the digits were there -% rounding can be forced using an extra 0+, the float() function, or the [D] option. -% tidbit: comparison operators do not pre-round, so 1.2345678 is not same as (1.2345678+0) -% in low precision. -\begingroup\xintDigits:=4;% with 2 guard digits, this makes 4+2=6 digits from "0+" rounding +\relax\newline +% +% but we can see via the \xintexpr wrapper all the digits were there rounding +% can be forced using an extra 0+, the float() function, or the [D] option. +% tidbit: comparison operators do not pre-round, so 1.2345678 is not same as +% (1.2345678+0) in low precision. +% +\begingroup\xintDigits:=4;% 4) \xintifboolfloatexpr{1.2345 == 1.23456} {\error}{Different! Comparisons do not pre-round to Digits precision.}\newline 5) \xintifboolfloatexpr{1.2345 == 1.2345 + 0} - {\error}{Different! Right hand side rounded from operation, left hand side not rounded.}\par + {\error}{Different! Right hand side rounded from operation, + left hand side not rounded.}\par \endgroup \end{everbatim*} @@ -7560,11 +7805,11 @@ illustrate to make thinks clear. We start with this: It produces in the log: \begin{everbatim} -Package xintexpr Info: (on line 10) +Package xintexpr Info: (on line 2) Function foo for \xintexpr parser associated to \XINT_expr_userfunc_foo wit h meaning macro:#1#2#3->{\xintAdd {\xintAdd {\xintAdd {#1}{#2}}{#3}}{\xintPow { \xintAdd {\xintAdd {#1}{#2}}{#3}}{2}}} -Package xintexpr Info: (on line 11) +Package xintexpr Info: (on line 3) Function bar for \xintexpr parser associated to \XINT_expr_userfunc_bar wit h meaning macro:#1#2#3->\expanded \bgroup \expanded {\unexpanded {\XINT_expr_se q:_b {\xintbareeval S + S^2\relax !S}}{\xintAdd {\xintAdd {#1}{#2}}{#3}}^} @@ -7840,7 +8085,7 @@ dimension): \def\xintexprPrintOne #1{\xintTeXFrac{#1}}% \def\xintexpralignbegin {\begin{pmatrix}}% \def\xintexpralignend {\end{pmatrix}}% -\def\xintexpralignlinesep {\noexpand\\[2\jot]}% needed to counteract an internal \expanded +\def\xintexpralignlinesep {\noexpand\\[2\jot]}% counteract an internal \expanded \def\xintexpraligninnersep {&}% \let\xintexpralignleftbracket\empty \let\xintexpralignleftsep\empty \let\xintexpralignrightbracket\empty \let\xintexpralignrightsep\empty @@ -7875,7 +8120,8 @@ precision for the evaluation. \def\CR{\cr} \halign {\tabskip1ex -\hfil\bfseries#&\xintDigits:=\xintiloopindex\relax \xintthefloatexpr Rump(77617,33096)#\cr +\hfil\bfseries#&\xintDigits:=\xintiloopindex\relax + \xintthefloatexpr Rump(77617,33096)#\cr \xintiloop [8+1] \xintiloopindex &\relax\CR \ifnum\xintiloopindex<40 \repeat @@ -8428,16 +8674,1390 @@ expansion. never-ending one-dimensional one...\par \end{footnotesize} +\subsection{Known bugs/features (last updated at \texttt{1.4j})} + +\begin{description} +\item[if(100>0,(100,125),(100,128)) breaks my code:] +% + This is a feature. This is a syntax error, as the comma serves to contatenate + "oples" (see \autoref{oples}), and parentheses do not create analogs of + "tuples", so this input is parsed the same as +\begin{everbatim} + if(100>0,100,125,100,128) +\end{everbatim} + which is an error as \func{if} requires exactly three arguments, not + five. Use: +\begin{everbatim} + if(100>0,[100,125],[100,128]) +\end{everbatim} + which will expand to the "tuple" |[100,125]|. +\item[{\detokenize{\xintdeffunc foo(x):= gcd((x>0)?{[x,125]}{[x,128]});} + creates a broken function:}] +% + Bug. Normally \func{gcd} (and other + multi-arguments functions) work both with open lists of arguments or + bracketed lists ("nutples") and the above syntax would work perfectly fine + in numerical context. But the presence of the \oper{?} breaks in + \csbxint{deffunc} context the flexibility of \func{gcd}. + + Currently working alternatives: +\begin{everbatim} +\xintdeffunc foo(x) := gcd(if(x>0, [x,125], [x,128])); +\xintdeffunc foo(x) := if(x>0, gcd(x,125), gcd(x,128)); +\xintdeffunc foo(x) := if(x>0, gcd([x,125]), gcd([x,128])); +\xintdeffunc foo(x) := gcd((x>0)?{x,125}{x,128}); +\xintdeffunc foo(x) := (x>0)?{gcd(x,125)}{gcd(x,128)}; +\xintdeffunc foo(x) := (x>0)?{gcd([x,125])}{gcd([x,128])}; +\end{everbatim} + The same problem will arise with an \oper{??} nested inside \func{gcd} or + similar functions, in an \csbxint{deffunc}. + + \item[{\detokenize{\xinteval{0^-.5}} says "0 raised to power -1"}] +% + Feature. Half integer exponents are handled via a square-root extraction, so + here \xintexprname wanted to first raise \dtt{0} to power \dtt{-1}, as + reported. + + \item[{Comparison operator \detokenize{==} crashes with nutples}] +% + Not yet implemented... + + \item[{I liked the ``broadcasting'' \detokenize{[1..10]^10} syntax, but it + was removed at 1.4}] +% + Patience...\@ |seq(x^10,x=1..10)| is alternative (add external |[..]| to get + a nutple). + \item[{\detokenize{1e\numexpr5+2\relax} crashes}] +% + Not clear yet if bug or feature. + The syntax accepted in the scientific part is limited, and failure + is expected: hitting a |\numexpr| + when parsing a number triggers insertion of a tacit multiplication and then + |1e| is missing the scientific exponent. The same happens with |1e(2+3)|. + Use syntax such as |1e\the\numexpr5+2\relax|, or |1e\xinteval{5+2}| + (although here this relies on output format of |\xinteval| using integer + notation with no decoration in this case). + + \item[{seq(1e-i,i=1..5) crashes}] +% + Not clear if bug or feature. Use |seq(1e\xinteval{-i},i=1..5)| or, as a + possibly faster way |seq(1e\xintiieval{-i},i=\xintiiexpr1..5\relax)|. + + \item[{omit/abort if nested and not last in the sub-expression cause a crash}] +% + For example |seq(subs((i)?{i}{abort},t=i)+10, i=-2, -1, 0, 1)| crashes, due + to the presence of the |+10|. This is a longstanding limitation, applying + ever since |omit/abort| were added to the syntax at |1.1|. Even without + the |+10| the nested case was broken by a |1.4| regression and got fixed + only at |1.4h|. The non-nested case |seq((i)?{i}{abort}+10, i=-2, -1, 0, + 1)| works and the «must be last in expression if nested» limitation is + currently considered a feature. + +\item[{seq([i,i\string^2], i=1..10) crashes with Ooops, looks like we are missing a + ]. Aborting!}] +% + The cause is that the square brackets do not hide the comma from |seq()| + parsing. This will probably remain ``wont-fix''. Work-arounds: either use + an extra pair of parentheses |seq(([i,i^2]), ...)| or hide the inner + comma within braces |seq([i{,}i^2], ...)|. +\end{description} + +The list stops here, but there are certainly other pending bugs in my bug-log, +and many more I am not yet aware of. In particular it is already mentioned in +the \csbxint{deffunc} documentation that it can not parse currently the +entirety of the available purely numerical syntax, some (documented or not, +known or not) limitations apply. + + \clearpage \etocdepthtag.toc {part1B} \let\xintexprnameUp\undefined +\csname xintexpr (old doc)nameUp\endcsname +\section{The macros of \xintexprname (ancient documentation, mostly)}% +\RaisedLabel{sec:oldxintexpr} + +\localtableofcontents + +The \xintexprname package was first released with version |1.07| +(|2013/05/25|) of the \xintname bundle. It was substantially enhanced with +release |1.1| from |2014/10/28|. + +The |1.4| release from |2020/01/31| maintains the same general architecture +but needed adapting all the code base for the switch from |\csname| to +|\expanded| techniques. On this occasion the mechanism for defining functions +was substantially strengthened. The parser core mechanisms were improved too. + +The package loads automatically \xintfracname and \xinttoolsname. + +This section should be trimmed to contain only information not +already covered in \autoref{sec:expr}. + +\subsection{The \csh{xintexpr} expressions} +\label{xintexpr} +\label{xinttheexpr} +\label{thexintexpr} +\label{xintthe} + +An \xintexprname{}ession is a construct +\csbxint{expr}\meta{expandable\_expression}|\relax|\etype{x} where the +expandable expression is read and completely expanded from left to right. + +An |\xintexpr...\relax| \emph{must} end in a |\relax| (which will be absorbed). +Contrarily to a |\numexpr| expression, it is printable\CHANGED{1.4} as is without a prefix +|\the| or |\number| (don't use them with |\xintexpr| this will raise an +error). + +But one can use |\xintthe| prefix if one does need the explicit digits and +other characters as in the final typesetted result. + +As an alternative and equivalent syntax to +\begin{everbatim} +\xintexpr round(<expression>, D)\relax +\end{everbatim} +there is +\begin{everbatim} +\xintiexpr [D] <expression> \relax +\end{everbatim} +For |D>0| this produces a decimal number with |D| figures after the decimal +mark, which is the rounding of the expression. For |D=0| the rounding to an +integer is produced. For |D<0| (and this was changed at |1.4f|), the rounded +quotient of the expression by \verb=1e|D|= is produced. +\begin{itemize} +\item the expression may contain arbitrarily many levels of nested parenthesized + sub-expressions, +\item the expression may contain explicitely or from a macro expansion a + sub-expression |\xintexpr...\relax|, which itself may contain a + sub-expressions etc\dots +\item to let sub-contents evaluate as a sub-unit it should thus be either + \begin{enumerate} + \item parenthesized, + \item or a sub-expression |\xintexpr...\relax|. + \end{enumerate} + \item to use an expression as argument to macros from \xintfracname, + or more generally to macros which expand their arguments, one must use the + |\xinttheexpr...\relax| or |\xintthe\xintexpr...\relax| forms. + \item one should not use |\xintthe\xintexpr...\relax| as a sub-constituent of + another expression but only the + |\xintexpr...\relax| form which is more efficient in this context. + \item each \xintexprname{}ession, whether prefixed or not with |\xintthe|, is + completely expandable and obtains its result in two expansion steps. +\end{itemize} + +The information now following is possibly in need of updates. + +\begin{itemize}[parsep=0pt, labelwidth=\leftmarginii, + itemindent=0pt, listparindent=\leftmarginiii, leftmargin=\leftmarginii] +\item An expression is built the standard way with opening and closing + parentheses, infix operators, and (big) numbers, with possibly a fractional + part, and/or scientific notation (except for \csbxint{iiexpr} which only + admits big integers). All variants work with comma separated expressions. On + output each comma will be followed by a space. A decimal number must have + digits either before or after the decimal mark. + +\item As everything gets expanded, the characters |.|, |+|, |-|, |*|, |/|, |^|, + |!|, |&|, \verb+|+, |?|, |:|, |<|, |>|, |=|, |(|, |)|, |"|, |]|, |[|, |@| + and the comma |,| should not (if used in the expression) be active. For + example, the French language in |Babel| system, for pdf\LaTeX, activates |!|, + |?|, |;| and |:|. Turn off the activity before expressions using such characters. + + Alternatively the macro \csbxint{exprSafeCatcodes} resets all + characters potentially needed by \csbxint{expr} to their standard catcodes + and \csbxint{exprRestoreCatcodes} restores the former status. + +\item Count registers and |\numexpr|-essions are accepted (LaTeX{}'s counters + can be inserted using |\value|) natively without |\the| or |\number| as + prefix. Also dimen registers and control sequences, skip registers and + control sequences (\LaTeX{}'s lengths), |\dimexpr|-essions, + |\glueexpr|-essions are automatically unpacked using |\number|, discarding + the stretch and shrink components and giving the dimension value in |sp| + units ($1/65536$th of a \TeX{} point). Furthermore, tacit multiplication is + implied, when the (count or dimen or glue) register or variable, or the + (|\numexpr| or |\dimexpr| or |\glueexpr|) expression is immediately prefixed + by a (decimal) number. See \autoref{ssec:tacit multiplication} for the complete rules + of tacit multiplication.\IMPORTANT + +\item With a macro |\x| defined like this: + % + \leftedline{|\def\x {\xintexpr \a + \b \relax}| or |\edef\x {\xintexpr + \a+\b\relax}|} + % + one may then do |\xintthe\x|, either for printing the result on the page or + to use it in some other macros expanding their arguments. The |\edef| does + the computation immediately but keeps it in a protected form. + Naturally, the |\edef| is only possible if |\a| and |\b| are already + defined. With both approaches the |\x| can be inserted in other expressions, + as for example (assuming naturally as we use an |\edef| that in the + `yet-to-be computed' case the |\a| and |\b| now have some suitable meaning): + % + \leftedline {|\edef\y {\xintexpr \x^3\relax}|} + +\item There is also \csbxint{boolexpr}| ... \relax| and + \csbxint{theboolexpr}| ... \relax|. + +\item See also + \csbxint{ifboolexpr} (\autoref{xintifboolexpr}) and the + \func{bool} and \func{togl} functions + in \autoref{sec:expr}. Here is an example. Well in fact the + example ended up using only \csbxint{boolexpr} so it + was modified to use \csbxint{ifboolexpr}. +\catcode`| 12 % +\begin{everbatim*} +\xintdeffunc A(p,q,r) = p && (q || r) ; +\xintdeffunc B(p,q,r) = p || (q && r) ; +\xintdeffunc C(p,q,r) = xor(p, q, r) ; + +\centeredline{\normalcolor +\begin{tabular}{ccrclcl} + \xintFor* #1 in {{False}{True}} \do {% + \xintFor* #2 in {{False}{True}} \do {% + \xintFor* #3 in {{False}{True}} \do {% + #1 &AND &(#2 &OR )&is&\textcolor[named]{OrangeRed} + {\xintifboolexpr{A(#1,#2,#3)}{true}{false}}\\ + #1 &OR &(#2 &AND )&is&\textcolor[named]{OrangeRed} + {\xintifboolexpr{B(#1,#2,#3)}{yes}{no}}\\ + #1 &XOR & #2 &XOR  &is&\textcolor[named]{OrangeRed} + {\xintifboolexpr{C(#1,#2,#3)}{oui}{non}}\\ +}}} +\end{tabular}% +} +\end{everbatim*}\catcode`| 13 + +\item See also \csbxint{ifsgnexpr}. + +\item There is \csbxint{floatexpr}| ... \relax| where the algebra is done + in floating point approximation (also for each intermediate result). Use the + syntax |\xintDigits:=N\relax| to set the precision. Default: $16$ digits. + % + \leftedline{|\xintthefloatexpr 2^100000\relax:| \dtt{\xintthefloatexpr + 2^100000\relax }} + % + The square-root operation can be used in |\xintexpr|, it is computed + as a float with the precision set by |\xintDigits| or by the optional + second argument: + % +\begin{everbatim*} +\xinttheexpr sqrt(2,60)\relax\newline +Here the [60] is to avoid truncation to |\xinttheDigits| of precision on output. +\newline +\printnumber{\xintthefloatexpr [60] sqrt(2,60)\relax} +\end{everbatim*} + + Floats are quickly indispensable when using the power function, as exact + results will easily have hundreds, even thousands of digits. + % +\begin{everbatim*} +\xintDigits:=48\relax \xintthefloatexpr 2^100000\relax +\end{everbatim*} + + Only integer and (in |\xintfloatexpr...\relax|) half-integer exponents are + allowed. + +\item if one uses \emph{macros} within |\xintexpr..\relax| one should + obviously take into account that the parser will \emph{not} see the macro + arguments, hence one cannot use the syntax there, except if the arguments + are themselves wrapped as |\xinttheexpr...\relax| and assuming the macro + \fexpan ds these arguments. +\end{itemize} +\subsection{\texorpdfstring{\texttt{\protect\string\numexpr}}{\textbackslash + numexpr} or \texorpdfstring{\texttt{\protect\string\dimexpr}}{\textbackslash + dimexpr} expressions, count and dimension registers and variables} +\label{ssec:countinexpr} + +Count registers, count control sequences, dimen registers, dimen control +sequences (like |\parindent|), skips and skip control sequences, |\numexpr|, +|\dimexpr|, |\glueexpr|, |\fontdimen| can be inserted directly, they will be +unpacked using |\number| which gives the internal value in terms of scaled +points for the dimensional variables: $1$\,|pt|${}=65536$\,|sp| (stretch and +shrink components are thus discarded). + +Tacit multiplication (see \autoref{ssec:tacit multiplication}) is implied, +when a number or decimal number prefixes such a register or control sequence. +\LaTeX{} lengths are skip control sequences and \LaTeX{} counters should be +inserted using |\value|. + +Release |1.2| of the |\xintexpr| parser also recognizes and prefixes with +|\number| the |\ht|, |\dp|, and |\wd| \TeX{} primitives as well as the +|\fontcharht|, |\fontcharwd|, |\fontchardp| and |\fontcharic| \eTeX{} +primitives. + +In the case of numbered registers like |\count255| or |\dimen0| (or |\ht0|), +the resulting digits will be re-parsed, so for example |\count255 0| is like +|100| if |\the\count255| would give |10|. The same happens with inputs such +as |\fontdimen6\font|. And |\numexpr 35+52\relax| will be exactly as if |87| +as been encountered by the parser, thus more digits may follow: |\numexpr +35+52\relax 000| is like |87000|. If a new |\numexpr| follows, it is treated +as what would happen when |\xintexpr| scans a number and finds a non-digit: it +does a tacit multiplication. +\begin{everbatim*} +\xinttheexpr \numexpr 351+877\relax\numexpr 1000-125\relax\relax{} is the same +as \xinttheexpr 1228*875\relax. +\end{everbatim*} + +Control sequences however (such as |\parindent|) are picked up as a whole by +|\xintexpr|, and the numbers they define cannot be extended extra digits, a +syntax error is raised if the parser finds digits rather than a legal +operation after such a control sequence. + +A token list variable must be prefixed by |\the|, it will not be unpacked +automatically (the parser will actually try |\number|, and thus fail). Do not +use |\the| but only |\number| with a dimen or skip, as the |\xintexpr| parser +doesn't understand |pt| and its presence is a syntax error. To use a dimension +expressed in terms of points or other \TeX{} recognized units, incorporate it in +|\dimexpr...\relax|. + +Regarding how dimensional expressions are converted by \TeX{} into scaled points +see also \autoref{sec:Dimensions}. + +\subsection{Catcodes and spaces} + +The main problems are caused by active characters, because \csbxint{expr} et +al.\@ expand forward whatever comes from token stream; they apply |\string| +only in a second step. For example the catcode of |&| from |&&| Boolean +disjunction is not really important as long as it is not active, or comment, +or escape...\@ or brace...\@ or ignored...\@ in brief, as long as it is reasonable, +and in particular whether |@| is of catcode letter or other does not matter. + +It is always possible to insert manually the |\string| in the expression +before a problematic (but reasonable) character catcode, or even to use +|\detokenize| for a big chunk. + +\subsubsection{\csh{xintexprSafeCatcodes}} +\label{xintexprSafeCatcodes} + +Some problems with active characters can be resolved on the fly by prefixing +them by |\string| but some aspects of the parsing done by \csbxint{expr} +involves delimited macros which need the comma, equality sign and closing +parenthesis to have their standard catcodes. + +So \csbxint{exprSafeCatcodes} is provided as a utility to set in one go +catcodes of many characters to \csbxint{expr}-safely compatible values. This +is a non-expandable step as it changes catcodes. +% This is used +% internally by \csbxint{NewExpr} (restoring the catcodes on exit), hence it +% does not have to be protected against active characters when used at +% top-level. + +\csbxint{defvar}, \csbxint{deffunc}, et al., use it, and then they restore +catcodes to the prior state via \csbxint{exprRestoreCatcodes}. + +% As \csbxint{NewExpr} and \csbxint{deffunc} and variants use internally some +% |\scantokens|, they will (reasonably) succeed in sanitizing catcodes in the +% expressions, even if all is from the replacement text of some macro whose +% definition was done under some special catcode regime. + +% \csbxint{deffunc} is more lenient than \csbxint{defvar} regarding catcodes of +% characters in expression bodies as it does some |\scantokens| which will reset +% compatible catcodes. + +% Even if used in a context where catcodes are already set, \csbxint{deffunc}, +% \csbxint{defvar} and variants ignore completely the colon in |:=| so it can +% have any (reasonable) catcode. Moreover it is optional. + +% The semi-colon in the syntax of \csbxint{Digits} is no real problem either +% (cf. \csbxint{Digits} documentation). + +\subsubsection{\csh{xintexprRestoreCatcodes}} +\label{xintexprRestoreCatcodes} + +Restores the catcodes to the state prevailing at the time of the last executed +\csbxint{exprSafeCatcodes} (if located at the same \LaTeX\ environment or +\TeX\ grouping level). + +Prior to |1.4k|, in a situation like the following: +\begin{everbatim} +\xintexprSafeCatcodes +....stuff possibly changing catcodes +\xintexprSafeCatcodes +....stuff possibly changing catcodes +\xintexprSafeCatcodes +....stuff possibly changing catcodes +\xintexprRestoreCatcodes +\end{everbatim} +On exit, the catcodes recovered their status as prior to the \emph{first} +\csbxint{exprSafeCatcodes}. Since |1.4k|, they are set to what they were +prior to the \emph{last} \csbxint{exprSafeCatcodes}, i.e. the mechanism is now +similar to a ``last in, first out'' stack. + +Note that no global assignments are made so the behaviour can be modified +by usage of \TeX\ groups or \LaTeX\ environments: e.g. if an +\csbxint{exprSafeCatcodes} is issued inside a \LaTeX\ environment it does not +have to be paired by \csbxint{exprRestoreCatcodes} explicitly, the catcode +scope is limited by the environment. + +\bigskip + +Spaces inside an |\xinttheexpr...\relax| should mostly be +innocuous (except inside macro arguments). + +|\xintexpr| and |\xinttheexpr| are for the most part agnostic regarding +catcodes, % (unbraced) digits, binary operators, minus and plus signs as +% prefixes, dot as decimal mark, parentheses, may be indifferently of catcode +% letter or other or subscript or superscript, ..., except that they +% should not be \emph{active}, as for example are |!?;:| with |babel-french|.% +% % +% \footnote{Furthermore, although \csbxint{expr} uses \csa{string}, it is +% escape-char agnostic. It should work with any \csa{escapechar} setting +% including -1.} +but the characters +% |+|, |-|, |*|, |/|, |^|, |!|, |&|, \verb+|+, |?|, |:|, |<|, |>|, +%|=|, |(|, |)|, |"|, |[|, |]|, |;|, +in the expression should not be «active» (except on purpose) as everything is +expanded along the way, and |\xintexpr| will choke on typesetting related +commands. One can use |\string| to prefix a problematic character. + + +Digits, slash, square brackets, minus sign, in the output from an +|\xinttheexpr| are all of catcode 12. For |\xintthefloatexpr| the `e' in the +output has its standard catcode ``letter''. + + + + +\subsection{Expandability, \csh{xintexpro}} + +As is the case with all other package macros |\xintexpr| \fexpan ds (in two +steps) to its final (somewhat protected) result; and |\xinttheexpr| \fexpan ds +(in two steps) to the chain of digits (and possibly minus sign |-|, decimal +mark |.|, fraction slash |/|, scientific |e|, square brackets |[|, |]|) +representing the result. + +The once expanded |\xintexpr| is |\romannumeral0\xintexpro|. And there +are similarly |\xintiexpro| |\xintiiexpro| and |\xintfloatexpro|. For an +example see \autoref{ssec:fibonacci}. + +An expression can only be legally finished by a |\relax| token, which +will be absorbed. + +It is quite possible to nest expressions among themselves; for example, if one +needs inside an |\xintiiexpr...\relax| to do some computations with fractions, +rounding the final result to an integer, one just has to insert +|\xintiexpr...\relax|. The functioning of the infix operators will not be in +the least affected from the fact that the outer ``environment'' is the +|\xintiiexpr| one. + + +\subsection{\csh{xintDigits*}, \csh{xintSetDigits*}} +\label{xintDigits*} +\label{xintSetDigits*} + +These starred variants of \csbxint{Digits} and \csbxint{SetDigits} execute +\csbxint{reloadxinttrig} and \csbxint{reloadxintlog}. + +\subsection{\csh{xintiexpr}, \csh{xinttheiexpr}} +\label{xintiexpr}\label{xinttheiexpr}\label{thexintiexpr} + +Equivalent\etype{x} to doing |\xintexpr round(...)\relax| (more precisely, +|round| is applied to each leaf item of the |ople| independently of its +depth). + +Intermediate calculations are exact, only the final output gets +rounded. Half integers are rounded towards $+\infty$ for positive +numbers and towards $-\infty$ for negative ones. + +An optional parameter |D| within brackets, immediately after |\xintiexpr| is +allowed: it instructs (for |D>0|) the expression to do its final rounding to +the nearest value with that many digits after the decimal mark, i.e.\@ +|\xintiexpr [D] <expression>\relax| is equivalent (in case of a single +expression) to |\xintexpr round(<expression>, D)\relax|. + +|\xintiexpr [0] ...| is the same as |\xintiexpr ...| and rounds to an integer. + +The case of negative |D| gives quantization to an integer multiple of +\dtt{1e-D}.\NewWith{1.4a} This was modified at |1.4f| and the produced value +is now the rounded quotient by \dtt{1e-D} (i.e. no trailing zeros nor +scientific exponent in the output). + +If truncation rather than rounding is needed on can use |\xintexpr +trunc(...)\relax| for truncation to an integer or |\xintexpr +trunc(...,D)\relax| for quantization to an integer multiple or \dtt{1eD} (if +|D>0|, for |D<0| the analog would be |trunc((...)/1e-D)|). But +this works only for a single scalar value. + +\begin{framed} + When defining a macro doing something such as |\xintiexpr #1\relax|, + it is recommended to rather use |\xintiexpr\empty #1\relax|, as the + |#1| may start with a |[| which without the |\empty| would be + interpreted by |\xintiexpr| as the start of the optional |[D]|. +\end{framed} + +\subsection{\csh{xintiiexpr}, \csh{xinttheiiexpr}} +\label{xintiiexpr}\label{xinttheiiexpr}\label{thexintiiexpr} + +This variant\etype{x} does not know fractions. It deals almost only with long +integers. Comma separated lists of expressions are allowed. + +\begin{framed} + It maps |/| to the \emph{rounded} quotient. The operator + |//| is, like in |\xintexpr...\relax|, mapped to \emph{truncated} division. + The Euclidean quotient (which for positive operands is like the truncated + quotient) was, prior to release |1.1|, associated to |/|. The function + |quo(a,b)| can still be employed. +\end{framed} + +The \csbxint{iiexpr}-essions use the `ii' macros for addition, subtraction, +multiplication, power, square, sums, products, Euclidean quotient and +remainder. + +The |round|, |trunc|, |floor|, |ceil| functions are still available, and are +about the only places where fractions can be used, but |/| within, if not +somehow hidden will be executed as integer rounded division. To avoid this one +can wrap the input in \dtt{qfrac}: this means however that none of the normal +expression parsing will be executed on the argument. + +To understand the illustrative examples, recall that |round| and |trunc| have +a second (non negative) optional argument. In a normal \csbxint{expr}-essions, +|round| and |trunc| are mapped to \csbxint{Round} and \csbxint{Trunc}, in +\csbxint{iiexpr}-essions, they are mapped to \csbxint{iRound} and +\csbxint{iTrunc}. + + +\begin{everbatim*} +\xinttheiiexpr 5/3, round(5/3,3), trunc(5/3,3), trunc(\xintDiv {5}{3},3), +trunc(\xintRaw {5/3},3)\relax{} are problematic, but +% +\xinttheiiexpr 5/3, round(qfrac(5/3),3), trunc(qfrac(5/3),3), floor(qfrac(5/3)), +ceil(qfrac(5/3))\relax{} work! +\end{everbatim*} + +On the other hand decimal numbers and scientific numbers can be used directly +as arguments to the |num|, |round|, or any function producing an integer. + +\begin{framed} + Scientific numbers will be + represented with as many zeroes as necessary, thus one does not want to + insert \dtt{num(1e100000)} for example in an \csa{xintiiexpr}ession! +\end{framed} + +% +\begin{everbatim*} +\xinttheiiexpr num(13.4567e3)+num(10000123e-3)\relax +% should (num truncates) compute 13456+10000 +\end{everbatim*} +% + +The |reduce| function is not available and will raise an error. The |frac| +function also. The |sqrt| function is mapped to \csbxint{iiSqrt} which gives +a truncated square root. The |sqrtr| function is mapped to \csbxint{iiSqrtR} +which gives a rounded square root. + +One can use the Float macros if one is careful to use |num|, or |round| +etc\dots on their output. + +\begin{everbatim*} +\xinttheiiexpr \xintFloatSqrt [20]{2}, + \xintFloatSqrt [20]{3}\relax % no operations +\end{everbatim*} +The above went through because no actual operations were carried out. But it +is dangerous because the ``printer'' for \csbxint{theiiexpr} could choke on +such values. By default however it does nothing. + +In the next example there will be an addition. So we firt apply |round| to +get integers (the second argument of |round| and |trunc| tells how many digits +from after the decimal mark one should keep.) +\begin{everbatim*} +\xinttheiiexpr round(\xintFloatSqrt [20]{2},19) + + round(\xintFloatSqrt [20]{3},19)\relax +\end{everbatim*} + +The whole point of \csbxint{iiexpr} is to gain some speed in +\emph{integer-only} algorithms, and the above explanations related to how to +nevertheless use fractions therein are a bit peripheral. We observed +(2013/12/18) of the order of $30$\% speed gain when dealing with numbers with +circa one hundred digits (1.2: this info may be obsolete). + + +\subsection{\csh{xintboolexpr}, \csh{xinttheboolexpr}} +\label{xintboolexpr}\label{xinttheboolexpr}\label{thexintboolexpr} + +Equivalent\etype{x} to doing |\xintexpr ...\relax| and returning $True$ if the +result does not vanish, and $False$ if the result is zero. As |\xintexpr|, this +can be used on comma separated lists of expressions, and even bracketed lists. +\CHANGED{1.4} + +It can be customized, one only needs to modify the following: +\begin{everbatim} +\def\xintboolexprPrintOne#1{\xintiiifNotZero{#1}{True}{False}}% +\end{everbatim} +Not only are |True| and |False| usable in input, also |true| and |false| are +pre-declared variables. + +Maybe obsolete: + +There is slight quirk in case it is used as a sub-expression: the boolean +expression needs at least one logic operation else the value is not +standardized to |1| or |0|, for example we get from +\begin{everbatim*} +\xinttheexpr \xintboolexpr 1.23\relax\relax\newline +\end{everbatim*}which is to be compared with +\begin{everbatim*} +\xinttheboolexpr 1.23\relax +\end{everbatim*} + +% A related issue existed with +% |\xinttheexpr \xintiexpr 1.23\relax\relax|, which was fixed with |1.1| +% release, and I decided back then not to add the needed overhead also to the +% |\xintboolexpr| context, as one only needs to use |?(1.23)| for example or +% involve the |1.23| in any logic operation like |1.23 'and' 3.45|, or involve +% the |\xintboolexpr ..\relax | itself with any logical operation, contrarily to +% the sub-|\xintiexpr| case where |\xinttheexpr 1+\xintiexpr 1.23\relax\relax| +% did behave contrarily to expectations until |1.1|. + + +\subsection{\csh{xintfloatexpr}, + \csh{xintthefloatexpr}} +\label{xintfloatexpr}\label{xintthefloatexpr}\label{thexintfloatexpr} + +\csbxint{floatexpr}|...\relax|\etype{x} is exactly like |\xintexpr...\relax| +but with the four binary operations and the power function mapped to +\csa{xintFloatAdd}, \csa{xintFloatSub}, \csa{xintFloatMul}, \csa{xintFloatDiv} +and \csa{xintFloatPower}, respectively.\footnote{Since |1.2f| the \string^ + handles half-integer exponents, contrarily to \csa{xintFloatPower}.} + +The target precision for the computation is from the +current setting of |\xintDigits|. Comma separated lists of expressions are +allowed. + +An optional parameter within brackets |[Q]| is allowed at the very start +of the expression: +\begin{itemize} +\item if positive it instructs the macro to round the result to that + many digits of precision. It thus makes sense to employ it only if + this parameter is less than the \csbxint{theDigits} precision. +\item if negative it means to trim off that many digits (of course, in + the sense of rounding the values to shorter mantissas). Don't use it + to trim all digits (or more than all)! +\end{itemize} + +Since |1.2f| all float operations first round their arguments; a parsed number +is not rounded prior to its use as operand to such a float operation. + + +|\xintDigits:=36\relax|\xintDigits:=36\relax +% +\leftedline{|\xintthefloatexpr + (1/13+1/121)*(1/179-1/173)/(1/19-1/18)\relax|} +% +\leftedline{\dtt{\xintthefloatexpr + (1/13+1/121)*(1/179-1/173)/(1/19-1/18)\relax}} +% 0.00564487459334466559166166079096852897 +% +\leftedline{|\xintthefloatexpr\xintexpr + (1/13+1/121)*(1/179-1/173)/(1/19-1/18)\relax\relax|} +% +\leftedline{\dtt{\xintthefloatexpr\xintexpr + (1/13+1/121)*(1/179-1/173)/(1/19-1/18)\relax\relax}} + +\xintDigits := 16; + +The latter is the rounding of the exact result. The former one has +its last three digits wrong due to the cumulative effect of rounding errors +in the intermediate computations, as compared to exact evaluations. + + + + +I recall here from \autoref{ssec:floatingpoint} that with release |1.2f| the +float macros for addition, subtraction, multiplication and division round +their arguments first to |P| significant places with |P| the asked-for +precision of the output; and similarly the power macros and the +square root macro. This does not modify anything for computations with +arguments having at most |P| significant places already. + +\begin{framed} + When defining a macro doing something such as |\xintfloatexpr #1\relax|, + it is recommended to rather use |\xintfloatexpr\empty #1\relax|, as the + |#1| may start with a |[| which without the |\empty| would be + interpreted by |\xintfloatexpr| as the start of the optional |[Q]|. +\end{framed} + +\subsection{\csh{xinteval}, \csh{xintieval}, \csh{xintiieval}, + \csh{xintfloateval}} +\label{xinteval}\label{xintieval}\label{xintiieval}\label{xintfloateval} + +\csbxint{eval}\etype{x} is an \fexpan dable macro which is basically +defined in such a way that |\xinteval|\marg{expression} behaves like +\csbxint{theexpr}\marg{expression}|\relax|. It expands completely in +two steps and delivers its output using digits, the dot |.| as decimal +separator, the letter |e| for scientific notation, the slash |/| for +fractions, as well as commas in case of multi-items expression and +square brackets |[| and |]| for nesting. + +\csbxint{ieval}\etype{x} is similarly related to \csbxint{theiexpr}. It +admits an optional argument |[D]| which may be located in the expected +location from conventions of \LaTeX2e macros with optional argument, but +had been long constrained (until |1.4k|) to be inside the braces at the +start of the expression. +\begin{everbatim*} +\xintieval[7]{355/113} = \xintieval{[7]355/113} +\end{everbatim*} +\begin{framed} + When defining a macro doing something such as |\xintieval{#1}|, + it is recommended to rather use |\xintieval{\empty #1}|, as the + |#1| may start with a |[| which without the |\empty| would be + interpreted by |\xintieval| as the start of the optional |[D]|. +\end{framed} + +\csbxint{iieval}\etype{x} is similarly related to \csbxint{theiiexpr}. +% \begin{everbatim*} +% \xintiieval{add(x^2, x = 100..110), add(x^3, x = 100..110)} +% \end{everbatim*} + +\csbxint{floateval}\etype{x} is similarly related to +\csbxint{thefloatexpr}. It admits an optional argument |[Q]| which +may be located either outside (since |1.4k|) or inside the braces. +\begin{everbatim*} +\xintfloateval [7]{355/113} = \xintfloateval{[7] 355/113} +\end{everbatim*} + +When negative, the optional argument tells how many digits to remove +from the prevailing precision: +\begin{everbatim*} +\xintfloateval[-2]{355/113}= +\xintfloateval{[-2]355/113} has \xinttheDigits\ minus 2 digits. +\end{everbatim*} + +\begin{framed} + When defining a macro doing something such as |\xintfloateval{#1}|, + it is recommended to rather use |\xintfloateval{\empty #1}|, as the + |#1| may start with a |[| which without the |\empty| would be + interpreted by |\xintfloateval| as the start of the optional |[Q]|. +\end{framed} + + +The \csbxint{eval} et al. macros have the advantage that they can be +nested within things such as the |\num| macro of +\href{http://ctan.org/pkg/siunitx}{siunitx}, which would choke on some +of the syntax elements which are allowed inside +\csb{xinttheexpr}|...\relax|, such as brackets. Hidden inside the +braces as argument to \csbxint{eval} et al., they do not cause a +breakage of |\num| anymore. + +And regarding \csbxint{ieval} and \csbxint{floateval} one sees here the +advantage that their respective optional arguments can (and had to until +|1.4k|) be located within the braces too... + +\subsection{Using an expression parser within another one} + +This was already illustrated before. In the following: +\begin{everbatim*} +\xintfloatexpr \xintexpr add(1/i, i=1234..1243)\relax ^100\relax +\end{everbatim*}, +the inner sum is computed exactly. Then it will be rounded to |\xinttheDigits| +significant digits, and then its power will be evaluated as a float operation. +One should avoid the "|\xintthe|" parsers in inner positions as this induces +digit by digit parsing of the inner computation result by the outer parser. +Here is the same computation done with floats all the way: +\begin{everbatim*} +\xintfloatexpr add(1/i, i=1234..1243)^100\relax +\end{everbatim*} + +Not surprisingly this differs from the previous one which was exact until +raising to the |100|th power. + +The fact that the inner expression occurs inside a bigger one has nil +influence on its behaviour. There is the limitation though that the outputs +from \csbxint{expr} and \csbxint{floatexpr} can not be used directly in +\csbxint{theiiexpr} integer-only parser. But one can do: +\begin{everbatim*} +\xintiiexpr round(\xintfloatexpr 3.14^10\relax)\relax % or trunc +\end{everbatim*} + + +\subsection{The \csh{xintthecoords} macro} +\label{xintthecoords} + +It converts (in two expansion steps) the expansion result of +\csbxint{floatexpr} (or \csbxint{expr} or \csbxint{iiexpr}) into the |(a, b) +(c, d) ...| format for list of coordinates as expected by the |TikZ| +|coordinates| syntax.% +\begin{everbatim*} +\begin{figure}[htbp] +\centering\begin{tikzpicture}[scale=10]\xintDigits:=8\relax + \clip (-1.1,-.25) rectangle (.3,.25); + \draw [blue] (-1.1,0)--(1,0); + \draw [blue] (0,-1)--(0,+1); + \draw [red] plot[smooth] coordinates {% +%%% \xintthecoords converts output of next expression into the +%%% (x1, y1) (x2, y2) ... +%%% format + \xintthecoords\xintfloatexpr +%%% This syntax -1+[0..4]/2 is currenty dropped at xint 1.4 +%%% seq((x^2-1,mul(x-t,t=-1+[0..4]/2)),x=-1.2..[0.1]..+1.2)\relax +%%% Use this: + seq((x^2-1,mul(x-t,t=seq(-1+u/2, u=0..4))),x=-1.2..[0.1]..+1.2) + \relax + }; +\end{tikzpicture} +\caption{Coordinates with \cs{xintthecoords}.} +\end{figure} +\end{everbatim*} + +% Notice: if x goes not take exactly value 1 or -1, the origin appears slightly +% off the curve, not MY fault!!! +It is currently undecided how \csa{xintthecoords} should handle bracketed +data.\UNSTABLE{} Currently, it (or |TikZ|) will break it the input contains +nested structures. One can use it with \func{flat} which removes all nesting. +And in combination with \func{zip} it is easy to plot data given by some +mechanism in separate +lists of x- and y-coordinates (see an example in next section) + +\subsection{The \csh{xintthespaceseparated} macro} +\label{xintthespaceseparated} + +It converts (in two expansion steps)\NewWith{1.4a} the expansion result of +\csbxint{floatexpr} (or \csbxint{expr} or \csbxint{iiexpr}) into the space +separated format suitable for usage with |PS-Tricks| |\listplot| macro. + +Here is for example some syntax (the replacement text of |\foo|, which is used +here only to show that indeed complete expansion is attained in two steps) +which can be used as argument to |\listplot|. Using 4 fractional decimal +digits is sufficient when unit is the centimeter (it gives a fixed point +precision of one micron, amply enough for plots...). +\begin{everbatim*} +\oodef\foo{% +\xintthespaceseparated +\xintiexpr[4]\xintfloatexpr seq((i, log10(i)), i=1..[0.5]..10)\relax\relax +}\meaning\foo +\end{everbatim*} + +Here we don't really need the inner |\xintfloatexpr...\relax| because the +\func{log10} function works the same in the exact parser |\xintexpr| but in +general this is recommended. + +It is currently undecided how \csa{xintthespaceseparated} should handle +bracketed data.\UNSTABLE{} Currently, it (or |\listplot|) will break if the +input contains nested structures. One can use it with \func{flat} which +removes all nesting. And in combination with \func{zip} it is easy to plot +data given by some mechanism in separate lists of x- and y-coordinates. + +\begin{everbatim*} +% let's imagine we have something like this +\def\Xcoordinates{1, 3, 5, 7, 9} +\def\Ycoordinates{1, 9, 25, 49, 81} +% then: +|\xintthespaceseparated\xintexpr flat(zip([\Xcoordinates], [\Ycoordinates]))\relax| +is suitable to use as argument to |\listplot|, as it expands to +\xintthespaceseparated\xintexpr flat(zip([\Xcoordinates], [\Ycoordinates]))\relax +\end{everbatim*} + +\subsection{\csh{xintifboolexpr}, \csh{xintifboolfloatexpr}, \csh{xintifbooliiexpr}} +\label{xintifboolexpr} +\label{xintifboolfloatexpr} +\label{xintifbooliiexpr} + +\csh{xintifboolexpr}\marg{expr}\marg{YES}\marg{NO}\etype{xnn} does +\csbxint{theexpr}<expr>|\relax| and then executes the \meta{YES} or the +\meta{NO} branch depending on whether the outcome was non-zero or zero. Thus +one can read \emph{if bool expr} as meaning \emph{if not zero}: +\centeredline{if \meta{expr}-ession does not vanish do \meta{YES} else do + \meta{NO}} + +The expression is not limited to using only comparison operators and Boolean +logic (|<|, |>|, |==|, |!=|, |&&|, \verb+||+, \func{all}, \func{any}, +\func{xor}, \func{bool}, \func{togl}, ...), it can be the most general +computation. + +\csh{xintifboolfloatexpr}\marg{expr}\marg{YES}\marg{NO}\etype{xnn} does +\csbxint{thefloatexpr}\meta{expr}|\relax| and then executes the \meta{YES} or the +\meta{NO} branch depending on whether the outcome was non zero or zero. + +\csh{xintifbooliiexpr}\marg{expr}\marg{YES}\marg{NO}\etype{xnn} does +\csbxint{theiiexpr}\meta{expr}|\relax| and then executes the \meta{YES} or the +\meta{NO} branch depending on whether the outcome was non zero or zero. + +The expression argument must be a single one, comma separated sub-expressions +will cause low-level errors. + +\subsection{\csh{xintifsgnexpr}, \csh{xintifsgnfloatexpr}, \csh{xintifsgniiexpr}} +\label{xintifsgnexpr} +\label{xintifsgnfloatexpr} +\label{xintifsgniiexpr} + +\csh{xintifsgnexpr}\marg{expr}\marg{<0}\marg{=0}\marg{>0}\etype{xnnn} evaluates +the \csbxint{expr}ession and chooses the branch corresponding to its sign. + +\csh{xintifsgnfloatexpr}\marg{expr}\marg{<0}\marg{=0}\marg{>0}\etype{xnnn} evaluates +the \csbxint{floatexpr}ession and chooses the branch corresponding to its sign. + +\csh{xintifsgniiexpr}\marg{expr}\marg{<0}\marg{=0}\marg{>0}\etype{xnnn} evaluates +the \csbxint{iiexpr}ession and chooses the branch corresponding to its sign. + +The expression argument must be a single one, comma separated sub-expressions +will cause low-level errors. + +\subsection{The \csh{xintNewExpr}, \csh{xintNewIIExpr}, + \csh{xintNewFloatExpr}, \csh{xintNewIExpr}, and \csh{xintNewBoolExpr} + macros} +\label{xintNewExpr} +\label{xintNewIIExpr} +\label{xintNewFloatExpr} +\label{xintNewIExpr} +\label{xintNewBoolExpr} + +\csbxint{NewExpr} macro is used as: +% +\leftedline{|\xintNewExpr{\myformula}[n]|\marg{stuff}, where} +\begin{itemize} +\item \meta{stuff} will be inserted inside |\xinttheexpr . . . \relax|, +\item |n| is an integer between zero and nine, inclusive, which is the number + of parameters of |\myformula|, +\item the placeholders |#1|, |#2|, ..., |#n| are used inside \meta{stuff} in + their usual r\^ole,% +% +\catcode`# 12 +\footnote{if \csa{xintNewExpr} is used inside a macro, + the |#|'s must be doubled as usual.} + \footnote{the |#|'s will in pratice have their usual + catcode, but category code other |#|'s are accepted too.} +\catcode`# 6 +% +\item the |[n]| is \emph{mandatory}, even for |n=0|.% +\footnote{there is some use for \csa{xintNewExpr}|[0]| compared to an + \csa{edef} as \csa{xintNewExpr} has some built-in catcode protection.} +\item the macro |\myformula| is defined without checking if it already exists, + \LaTeX{} users might prefer to do first |\newcommand*\myformula {}| to get a + reasonable error message in case |\myformula| already exists, +\item the protection against active characters is done automatically (as long + as the whole thing has not already been fetched as a macro argument and + the catcodes correspondingly already frozen). +\end{itemize} + +It (if it succeeds) will be a completely expandable macro entirely built-up using |\xintAdd|, +|\xintSub|, |\xintMul|, |\xintDiv|, |\xintPow|, etc\dots as corresponds to the +expression written with the infix operators. +Macros created by |\xintNewExpr| can thus be nested. + +\begin{everbatim*} + \xintNewFloatExpr \FA [2]{(#1+#2)^10} + \xintNewFloatExpr \FB [2]{sqrt(#1*#2)} +\begin{enumerate}[nosep] + \item \FA {5}{5} + \item \FB {30}{10} + \item \FA {\FB {30}{10}}{\FB {40}{20}} +\end{enumerate} +\end{everbatim*} + +The documentation is much shortened here because \csbxint{NewExpr} and \csbxint{deffunc} +are very much related one with the other. + +\begin{framed} + ATTENTION! + + The original spirit of \csbxint{NewExpr} was to define a (possibly very big) + macro using only \xintfracname, and this means in particular that it must be + used only with arguments compatible with the \xintfracname input + format.\IMPORTANTf + + Thus an |\xintexpr| declared variable has no chance to work, it must be + wrapped explicitly in |\xinteval{...}| to be fetched as argument to a macro + constructed by \csbxint{NewExpr}. +\end{framed} + +They share essentially the same limitations. + +Notice though that \csbxint{NewFloatExpr} accepts and recognizes the optional +argument |[Q]| of \csbxint{floatexpr}, contrarily to \csbxint{deffloatfunc}. +Use an |\empty| in case the contents are not known in advance. + + +Historical note: prior to |1.4|, \xintexprname used a |\csname..\endcsname| +encapsulation technique which impacted the string pool memory. The +\csbxint{NewExpr} was designed as a method to pre-parse the expression and +produce one single, gigantic, nested usage of the relevant \xintfracname +macros. This way, only those macros were expanded which had nil impact on the +\TeX{} string pool. + +Later on it was found that this mechanism could be employed to define +functions. Basically underneath |98%| of \csbxint{NewExpr} and +\csbxint{deffunc} are using the same shared code. + +\xintDigits:= 16\relax + +\subsection{Analogies and differences of \csh{xintiiexpr} with \csh{numexpr}} + +\csbxint{iiexpr}|..\relax| is a parser of expressions knowing only (big) +integers. There are, besides the enlarged range of allowable inputs, some +important differences of syntax between |\numexpr| and |\xintiiexpr| and +variants: +\begin{itemize} +\item Contrarily to |\numexpr|, the |\xintiiexpr| parser will stop expanding + only after having encountered (and swallowed) a \emph{mandatory} |\relax| + token. +\item In particular, spaces between digits (and not only around infix + operators or parentheses) do not stop |\xintiiexpr|, contrarily to the + situation with |numexpr|: |\the\numexpr 7 + 3 5\relax| expands (in one + step)% +% +\footnote {The |\numexpr| triggers continued expansion after the space + following the |3| to check if some operator like |+| is upstream. But + after having found the |5| it treats it as and end-marker.} +% + to \dtt{\detokenize\expandafter{\the\numexpr 7 + 3 5\relax}\unskip}, whereas + |\xintthe\xintiiexpr 7 + 3 5\relax| expands (in two steps) to + \dtt{\detokenize\expandafter\expandafter\expandafter {\xintthe\xintiiexpr 7 + + 3 5\relax}}.% +% +\footnote {Since |1.2l| one can also use the underscore |_| to separate digits +for readability of long numbers.} + +\item Inside an |\edef|, an expression |\xintiiexpr...\relax| get fully + evaluated, whereas |\numexpr| without |\the| or |\number| prefix would not, + if not itself embedded in another |\the\numexpr| or similar context. +\item (ctd.) The private format to which |\xintiiexpr...\relax| (et al.) + evaluates may use |\xintthe| prefix to turn into explicit digits, + (for example in arguments to some macros which expand their arguments). The |\the| \TeX\ primitive prefix would + not work here. +\item (ctd.) One can embed a |\numexpr...\relax| (with its |\relax|!) inside an + |\xintiiexpr...\relax| without |\the| or |\number|, but the reverse situation + requires usage of |\xintthe| or \csbxint{eval} user interface, +\item |\numexpr -(1)\relax| is illegal. In contrast |\xintiiexpr -(1)\relax| is + perfectly legal and gives the expected result (what else ?). +\item |\numexpr 2\cnta\relax| is illegal (with |\cnta| a |\count| register.) + In contrast + |\xintiiexpr 2\cnta\relax| is perfectly legal and will do the tacit + multiplication. +\item |\the\numexpr| or |\number\numexpr| expands in one step, but + |\xintthe\xintiiexpr| or |\xinttheiiexpr| needs two steps. +\end{itemize} + +\subsection{Chaining expressions for expandable algorithmics} +\label{ssec:fibonacci} + +We will see in this section how to chain |\xintexpr|-essions with +|\expandafter|'s, like it is possible with |\numexpr|. For this it is +convenient to use |\romannumeral0\xintexpro| which is the once-expanded form of +|\xintexpr|, as we can then chain using only one |\expandafter| each time. + +For example, here is the code employed +on the title page to compute (expandably, of course!) the 1250th Fibonacci +number: + +\begin{everbatim*} +\catcode`_ 11 +\def\Fibonacci #1{% \Fibonacci{N} computes F(N) with F(0)=0, F(1)=1. + \expandafter\Fibonacci_a\expandafter + {\the\numexpr #1\expandafter}\expandafter + {\romannumeral0\xintiiexpro 1\expandafter\relax\expandafter}\expandafter + {\romannumeral0\xintiiexpro 1\expandafter\relax\expandafter}\expandafter + {\romannumeral0\xintiiexpro 1\expandafter\relax\expandafter}\expandafter + {\romannumeral0\xintiiexpro 0\relax}} +% +\def\Fibonacci_a #1{% + \ifcase #1 + \expandafter\Fibonacci_end_i + \or + \expandafter\Fibonacci_end_ii + \else + \ifodd #1 + \expandafter\expandafter\expandafter\Fibonacci_b_ii + \else + \expandafter\expandafter\expandafter\Fibonacci_b_i + \fi + \fi {#1}% +}% * signs are omitted from the next macros, tacit multiplications +\def\Fibonacci_b_i #1#2#3{\expandafter\Fibonacci_a\expandafter + {\the\numexpr #1/2\expandafter}\expandafter + {\romannumeral0\xintiiexpro sqr(#2)+sqr(#3)\expandafter\relax + \expandafter}\expandafter + {\romannumeral0\xintiiexpro (2#2-#3)#3\relax}% +}% end of Fibonacci_b_i +\def\Fibonacci_b_ii #1#2#3#4#5{\expandafter\Fibonacci_a\expandafter + {\the\numexpr (#1-1)/2\expandafter}\expandafter + {\romannumeral0\xintiiexpro sqr(#2)+sqr(#3)\expandafter\relax + \expandafter}\expandafter + {\romannumeral0\xintiiexpro (2#2-#3)#3\expandafter\relax\expandafter}\expandafter + {\romannumeral0\xintiiexpro #2#4+#3#5\expandafter\relax\expandafter}\expandafter + {\romannumeral0\xintiiexpro #2#5+#3(#4-#5)\relax}% +}% end of Fibonacci_b_ii +% code as used on title page: +%\def\Fibonacci_end_i #1#2#3#4#5{\xintthe#5} +%\def\Fibonacci_end_ii #1#2#3#4#5{\xinttheiiexpr #2#5+#3(#4-#5)\relax} +% new definitions: +\def\Fibonacci_end_i #1#2#3#4#5{{#4}{#5}}% {F(N+1)}{F(N)} in \xintexpr format +\def\Fibonacci_end_ii #1#2#3#4#5% + {\expandafter + {\romannumeral0\xintiiexpro #2#4+#3#5\expandafter\relax + \expandafter}\expandafter + {\romannumeral0\xintiiexpro #2#5+#3(#4-#5)\relax}}% idem. +% \FibonacciN returns F(N) (in encapsulated format: needs \xintthe for printing) +\def\FibonacciN {\expandafter\xint_secondoftwo\romannumeral-`0\Fibonacci }% +\catcode`_ 8 +\end{everbatim*} + + +The macro |\Fibonacci| produces not one specific value |F(N)| but a pair of +successive values |{F(N)}{F(N+1)}| which can then serve as starting point of +another routine devoted to compute a whole sequence |F(N), F(N+1), +F(N+2),....|. Each of |F(N)| and |F(N+1)| is kept in the encapsulated internal +\xintexprname format. + +|\FibonacciN| produces the single |F(N)|. It also keeps it in the private +format; thus printing it will need the |\xintthe| prefix. + +\begingroup\footnotesize\sffamily\baselineskip 10pt +Here a code snippet which +checks the routine via a \string\message\ of the first $51$ Fibonacci +numbers (this is not an efficient way to generate a sequence of such +numbers, it is only for validating \csa{FibonacciN}). +% +\begin{everbatim} +\def\Fibo #1.{\xintthe\FibonacciN {#1}}% +\message{\xintiloop [0+1] \expandafter\Fibo\xintiloopindex., + \ifnum\xintiloopindex<49 \repeat \xintthe\FibonacciN{50}.} +\end{everbatim} +\endgroup + +The way we use |\expandafter|'s to chain successive |\xintiiexpro| evaluations +is exactly analogous to what is possible with |\numexpr|. The various +|\romannumeral0\xintiiexpro| could very well all have been |\xintiiexpr|'s but +then we would have needed |\expandafter\expandafter\expandafter| each +time. + +\begin{framed} + There is a difference though: |\numexpr| does \emph{NOT} expand inside an + |\edef|, and to force its expansion we must prefix it with |\the| or + |\number| or |\romannumeral| or another |\numexpr| which is itself prefixed, + etc\dots. + + But |\xintexpr|, |\xintiexpr|, ..., expand fully in an |\edef|, with the + completely expanded + result encapsulated in a private format. + + Using |\xintthe| as prefix is necessary to print the result (like |\the| or + |\number| in the case of |\numexpr|), but it is not necessary to get the + computation done (contrarily to the situation with |\numexpr|). +\end{framed} + + +Our |\Fibonacci| expands completely under \fexpan sion, so we can use +\hyperref[fdef]{\ttfamily\char92fdef} rather than |\edef| in a situation such +as +% +\leftedline {|\fdef \X {\FibonacciN {100}}|\;,} +% +but it is usually about as efficient to employ |\edef|. And if we want +% +\leftedline{|\edef \Y {(\FibonacciN{100},\FibonacciN{200})}|\;,} +% +then |\edef| is necessary. + +Allright, so let's now give the code to generate |{F(N)}{F(N+1)}{F(N+2)}...|, +using |\Fibonacci| for the first two and then using the standard recursion +|F(N+2)=F(N+1)+F(N)|: + +\catcode`_ 11 +\def\FibonacciSeq #1#2{%#1=starting index, #2>#1=ending index + \expandafter\Fibonacci_Seq\expandafter + {\the\numexpr #1\expandafter}\expandafter{\the\numexpr #2-1}% +}% +\def\Fibonacci_Seq #1#2{% + \expandafter\Fibonacci_Seq_loop\expandafter + {\the\numexpr #1\expandafter}\romannumeral0\Fibonacci {#1}{#2}% +}% +\def\Fibonacci_Seq_loop #1#2#3#4{% standard Fibonacci recursion + {#3}\unless\ifnum #1<#4 \Fibonacci_Seq_end\fi + \expandafter\Fibonacci_Seq_loop\expandafter + {\the\numexpr #1+1\expandafter}\expandafter + {\romannumeral0\xintiiexpro #2+#3\relax}{#2}{#4}% +}% +\def\Fibonacci_Seq_end\fi\expandafter\Fibonacci_Seq_loop\expandafter + #1\expandafter #2#3#4{\fi {#3}}% +\catcode`_ 8 + +\begingroup +\everb|@ +\catcode`_ 11 +\def\FibonacciSeq #1#2{%#1=starting index, #2>#1=ending index + \expandafter\Fibonacci_Seq\expandafter + {\the\numexpr #1\expandafter}\expandafter{\the\numexpr #2-1}% +}% +\def\Fibonacci_Seq #1#2{% + \expandafter\Fibonacci_Seq_loop\expandafter + {\the\numexpr #1\expandafter}\romannumeral0\Fibonacci {#1}{#2}% +}% +\def\Fibonacci_Seq_loop #1#2#3#4{% standard Fibonacci recursion + {#3}\unless\ifnum #1<#4 \Fibonacci_Seq_end\fi + \expandafter\Fibonacci_Seq_loop\expandafter + {\the\numexpr #1+1\expandafter}\expandafter + {\romannumeral0\xintiiexpro #2+#3\relax}{#2}{#4}% +}% +\def\Fibonacci_Seq_end\fi\expandafter\Fibonacci_Seq_loop\expandafter + #1\expandafter #2#3#4{\fi {#3}}% +\catcode`_ 8 +| +\endgroup + +This |\FibonacciSeq| macro is +completely expandable but it is not \fexpan dable. + +This is not a problem in the next example which uses \csbxint{For*} as the +latter applies repeatedly full expansion to what comes next each time it +fetches an item from its list argument. Thus \csbxint{For*} still manages to +generate the list via iterated full expansion. + + +\begin{figure*}[ht!] + \phantomsection\label{fibonacci} + \newcounter{myindex} + \fdef\Fibxxx{\FibonacciN {30}}% + \setcounter{myindex}{30}% +\centeredline{\tabskip 1ex +\vbox{\halign{\bfseries#.\hfil&#\hfil &\hfil #\cr + \xintFor* #1 in {\FibonacciSeq {30}{59}}\do + {\themyindex &\xintthe#1 & + \xintiiRem{\xintthe#1}{\xintthe\Fibxxx}\stepcounter{myindex}\cr }}% +}\vrule +\vbox{\halign{\bfseries#.\hfil&#\hfil &\hfil #\cr + \xintFor* #1 in {\FibonacciSeq {60}{89}}\do + {\themyindex &\xintthe#1 & + \xintiiRem{\xintthe#1}{\xintthe\Fibxxx}\stepcounter{myindex}\cr }}% +}\vrule +\vbox{\halign{\bfseries#.\hfil&#\hfil &\hfil #\cr + \xintFor* #1 in {\FibonacciSeq {90}{119}}\do + {\themyindex &\xintthe#1 & + \xintiiRem{\xintthe#1}{\xintthe\Fibxxx}\stepcounter{myindex}\cr }}% +}}% +% +\centeredline{Some Fibonacci numbers together with their residues modulo + |F(30)|\dtt{=\xintthe\Fibxxx}} +\end{figure*} + +\begingroup +\def\everbhook{\catcode`@ 14 }% +% à propos après donc de nombreuses années j'ai fait finalement +% un bug report https://github.com/latex3/latex2e/issues/823 +\everb|@ +\newcounter{myindex}% not "index", which would overwrite theindex environment! +% (many have probably been bitten by this trap) +\tabskip 1ex + \fdef\Fibxxx{\FibonacciN {30}}% + \setcounter{myindex}{30}% +\vbox{\halign{\bfseries#.\hfil&#\hfil &\hfil #\cr + \xintFor* #1 in {\FibonacciSeq {30}{59}}\do + {\themyindex &\xintthe#1 & + \xintiiRem{\xintthe#1}{\xintthe\Fibxxx}\stepcounter{myindex}\cr }}% +}\vrule +\vbox{\halign{\bfseries#.\hfil&#\hfil &\hfil #\cr + \xintFor* #1 in {\FibonacciSeq {60}{89}}\do + {\themyindex &\xintthe#1 & + \xintiiRem{\xintthe#1}{\xintthe\Fibxxx}\stepcounter{myindex}\cr }}% +}\vrule +\vbox{\halign{\bfseries#.\hfil&#\hfil &\hfil #\cr + \xintFor* #1 in {\FibonacciSeq {90}{119}}\do + {\themyindex &\xintthe#1 & + \xintiiRem{\xintthe#1}{\xintthe\Fibxxx}\stepcounter{myindex}\cr }}% +}% +| +\endgroup + +This produces the Fibonacci numbers from |F(30)| to |F(119)|, and +computes also all the +congruence classes modulo |F(30)|. The output has +been put in a \hyperref[fibonacci]{float}, which appears +\vpageref[above]{fibonacci}. I leave to the mathematically inclined +readers the task to explain the visible patterns\dots |;-)|. + +\subsection{When expandability is too much} + +Let's use the macros of \autoref{ssec:fibonacci} related to Fibonacci numbers. +Notice that the $47$th Fibonacci number is \dtt{\xintthe\FibonacciN {47}} thus +already too big for \TeX{} and \eTeX{}. + + +The |\FibonacciN| macro found in \autoref{ssec:fibonacci} is completely +expandable, it is even \fexpan dable. We need a wrapper with |\xintthe| +prefix +\begin{everbatim*} +\def\theFibonacciN{\xintthe\FibonacciN} +\end{everbatim*} +to print in the document or to use within |\message| (or \LaTeX\ |typeout|) to +write to the log and terminal. + +\begingroup + \def\A {1859} \def\B {1573} + \edef\X {\theFibonacciN\A} \edef\Y {\theFibonacciN\B} + \edef\GCDAB {\xintiiGCD\A\B}\edef\Z {\theFibonacciN\GCDAB} + \edef\GCDXY{\xintiiGCD\X\Y} + + The |\xintthe| prefix also allows its use it as argument to the \xintname + macros: for example if we are interested in knowing how many digits + $F(1250)$ has, it suffices to issue |\xintLen {\theFibonacciN {1250}}| + (which expands to \dtt{\xintLen {\theFibonacciN {1250}}}). Or if we want to + check the formula $gcd(F(1859),F(1573))=F(gcd(1859,1573))=F(143)$, we only + need% +% +\footnote{The + \csa{xintiiGCD} macro is provided by both the \xintgcdname package (since + |1.0|) and by the \xintname package (since |1.3d|).} +% +\begin{everbatim} +$\xintiiGCD{\theFibonacciN{1859}}{\theFibonacciN{1573}}=% + \theFibonacciN{\xintiiGCD{1859}{1573}}$ +\end{everbatim} +% +which produces: +% +\leftedline{$\dtt{\xintiiGCD{\X}{\Y}}=\dtt{\theFibonacciN{\GCDAB}}$} + +The |\theFibonacciN| macro expanded its |\xintiiGCD{1859}{1573}| argument via the +services of |\numexpr|: this step allows only things obeying the \TeX{} bound, +naturally! (but \dtt{F(\xintiiPow2{31}}) would be rather big anyhow...). + +This is very convenient but of course it repeats the complete evaluation each +time it is done. In practice, it is often useful to store the result of such +evaluations in macros. Any |\edef| will break expandability, but if the goal +is at some point to print something to the |dvi| or |pdf| output, and not only +to the |log| file, then expandability has to be broken one day or another! + +Hence, in practice, if we want to print in the document some computation +results, we can proceed like this and avoid having to repeat identical +evaluations: +\begin{everbatim} +\begingroup + \def\A {1859} \def\B {1573} + \edef\X {\theFibonacciN\A} \edef\Y {\theFibonacciN\B} + \edef\GCDAB {\xintiiGCD\A\B}\edef\Z {\theFibonacciN\GCDAB} + \edef\GCDXY{\xintiiGCD\X\Y} +The identity $\gcd(F(\A),F(\B))=F(\gcd(\A,\B))$ can be checked via evaluation +of both sides: $\gcd(F(\A),F(\B))=\gcd(\printnumber\X,\printnumber\Y)= +\printnumber{\GCDXY} = F(\gcd(\A,\B)) = F(\GCDAB) =\printnumber\Z$.\par + % some further computations involving \A, \B, \X, \Y +\endgroup % closing the group removes assignments to \A, \B, ... +% or choose longer names less susceptible to overwrite something. +% Note: there is no LaTeX \newecommand which would be to \edef like +% \newcommand is to \def +\end{everbatim} +The identity $\gcd(F(\A),F(\B))=F(\gcd(\A,\B))$ can be checked via evaluation +of both sides: $\gcd(F(\A),F(\B))=\gcd(\printnumber\X,\printnumber\Y)= +\printnumber{\GCDXY} = F(\gcd(\A,\B)) = F(\GCDAB) =\printnumber\Z$.\par +\endgroup + +One may legitimately ask the author: why expandability +to such extremes, for things such as big fractions or floating point numbers +(even continued fractions...) which anyhow can not be used directly within +\TeX's primitives such as |\ifnum|? Why insist on a concept +which is foreign to the vast majority of \TeX\ users and even programmers? + +I have no answer: it made definitely sense at the start of \xintname (see +\autoref{ssec:origins}) and once started I could not stop. + + +\subsection{Acknowledgements (2013/05/25)} + +I was greatly helped in my preparatory thinking, prior to producing such an +expandable parser, by the commented source of the +\href{https://ctan.org/pkg/l3kernel}{l3fp} package, specifically the +|l3fp-parse.dtx| file (in the version of April-May 2013; I think there was in +particular a text called ``roadmap'' which was helpful). Also the source of the +|calc| package was instructive, despite the fact that here for |\xintexpr| the +principles are necessarily different due to the aim of achieving expandability. + +\clearpage +\expandafter\let\csname xintexpr (old doc)nameUp\endcsname\undefined \csname xinttrignameUp\endcsname -\def\n{|{N}|} -\def\m{|{M}|} -\def\x{|{x}|} -\section{Macros of the \xinttrigname package} +\section{The \xinttrigname package} \RaisedLabel{sec:trig} \localtableofcontents @@ -8662,6 +10282,7 @@ precision (recall that |*| is mapped to exact multiplication in \noindent \begin{everbatim*} \xintDigits* := 48\relax +Digits at \xinttheDigits:\newline $sind(17)\approx\xintfloateval{sind(17)}$\newline $cosd(17)\approx\xintfloateval{cosd(17)}$\newline $tand(17)\approx\xintfloateval{tand(17)}$\newline @@ -8674,6 +10295,7 @@ $atand(3)\approx\xintfloateval{atand(3)}$\newline $tan(atan(7))\approx\xintfloateval{tan(atan(7))}$\newline $asind(sind(25))\approx\xintfloateval{asind(sind(25))}$\par\medskip \noindent\xintDigits* := 24\relax +Digits at \xinttheDigits:\newline $sind(17)\approx\xintfloateval{sind(17)}$\newline $cosd(17)\approx\xintfloateval{cosd(17)}$\newline $tand(17)\approx\xintfloateval{tand(17)}$\newline @@ -8695,7 +10317,7 @@ $asind(sind(25))\approx\xintfloateval{asind(sind(25))}$\par \def\m{|{M}|} \def\x{|{x}|} -\section{Macros of the \xintlogname package} +\section{The \xintlogname package} \RaisedLabel{sec:log} This package provides logarithms, exponentials and fractional powers for use @@ -8785,13 +10407,13 @@ The reason is that the log/exp approach loses accuracy for very big exponents (say for exponents of the order of \dtt{100000000} or more). Here is an example of a precise computation with a very large exponent (\dtt{\xintiieval{12^16}}): \begin{everbatim*} -$\xintTeXfromSci{\xintfloateval{1.00000001^\xintiiexpr 12^16\relax}}$\newline +$\xintTeXFromSci{\xintfloateval{1.00000001^\xintiiexpr 12^16\relax}}$\newline \xintDigits:=48;%\xintreloadxintlog is not done as log10/pow10 will not be used -$\xintTeXfromSci{\xintfloateval{1.00000001^12^16}}$\newline +$\xintTeXFromSci{\xintfloateval{1.00000001^12^16}}$\newline \xintDigits:=64;%\xintreloadxintlog is not done as log10/pow10 will not be used -$\xintTeXfromSci{\xintfloateval{1.00000001^12^16}}$\newline +$\xintTeXFromSci{\xintfloateval{1.00000001^12^16}}$\newline \xintDigits:=80;%\xintreloadxintlog is not done as log10/pow10 will not be used -$\xintTeXfromSci{\xintfloateval{1.00000001^12^16}}$ +$\xintTeXFromSci{\xintfloateval{1.00000001^12^16}}$ \xintDigits:=16;% \end{everbatim*} @@ -8886,6 +10508,2730 @@ anecdotical evidence showing it is good. \clearpage \let\xintlognameUp\undefined +\csname xinttoolsnameUp\endcsname +\def\n{|{N}|} +\def\m{|{M}|} +\def\x{|{x}|} +\section{Macros of the \xinttoolsname package} + +\RaisedLabel{sec:tools} + +These utilities used to be provided within the \xintname package; since |1.09g| +(|2013/11/22|) they have been moved to an independently usable package +\xinttoolsname, which has none of the \xintname facilities regarding big +numbers. Whenever relevant release |1.09h| has made the macros |\long| so they +accept |\par| tokens on input. + +The completely expandable utilities (up to \csbxint{iloop}) are documented +first, then the non expandable utilities. + +\autoref{sec:examples} +gives additional (some quite dated) examples of use of macros of this package. + +\xinttoolsname is automatically loaded by \xintexprname. + +\localtableofcontents + +\subsection{\csh{xintRevWithBraces}}\label{xintRevWithBraces} + +%{\small New in release |1.06|.\par} + +\edef\X{\xintRevWithBraces{12345}} +\edef\y{\xintRevWithBraces\X} +\expandafter\def\expandafter\w\expandafter + {\romannumeral0\xintrevwithbraces{{\A}{\B}{\C}{\D}{\E}}} + +% +\csa{xintRevWithBraces}\marg{list}\etype{f} first does the \fexpan sion of its +argument then it reverses the order of the tokens, or braced material, it +encounters, maintaining existing braces and adding a brace pair around each +naked token encountered. Space tokens (in-between top level braces or naked +tokens) are gobbled. This macro is mainly thought out for use on a \meta{list} +of such braced material; with such a list as argument the \fexpan sion will only +hit against the first opening brace, hence do nothing, and the braced stuff may +thus be macros one does not want to expand. +% +\leftedline{|\edef\x{\xintRevWithBraces{12345}}|} +% +\leftedline{|\meaning\x:|\dtt{\meaning\X}} +% +\leftedline{|\edef\y{\xintRevWithBraces\x}|} +% +\leftedline{|\meaning\y:|\dtt{\meaning\y}} +% +The examples above could be defined with |\edef|'s because the braced material +did not contain macros. Alternatively: +% +\leftedline{|\expandafter\def\expandafter\w\expandafter|} +% +\leftedline{|{\romannumeral0\xintrevwithbraces{{\A}{\B}{\C}{\D}{\E}}}|} +% +\leftedline{|\meaning\w:|\dtt{\meaning\w}} +% +The macro \csa{xintReverseWithBracesNoExpand}\etype{n} does the same job +without the initial expansion of its argument. + + +\subsection{\csh{xintZapFirstSpaces}, \csh{xintZapLastSpaces}, \csh{xintZapSpaces}, \csh{xintZapSpacesB}} +\label{xintZapFirstSpaces} +\label{xintZapLastSpaces} +\label{xintZapSpaces} +\label{xintZapSpacesB} +%{\small New with release |1.09f|.\par} + +\csa{xintZapFirstSpaces}\marg{stuff}\etype{n} does not do \emph{any} expansion +of its argument, nor brace removal of any sort, nor does it alter \meta{stuff} +in anyway apart from stripping away all \emph{leading} spaces. + +This macro will be mostly of interest to programmers who will know what I will +now be talking about. \emph{The essential points, naturally, are the complete + expandability and the fact that no brace removal nor any other alteration is + done to the input.} + +\TeX's input scanner already converts consecutive blanks into single space +tokens, but |\xintZapFirstSpaces| handles successfully also inputs with +consecutive multiple space tokens. +However, it is assumed that \meta{stuff} does not contain (except inside braced +sub-material) space tokens of character code distinct from $32$. + +It expands in two steps, and if the goal is to apply it to the +expansion text of |\x| to define |\y|, then one can do: +|\odef\y{\romannumeral0\expandafter\xintzapfirstspaces\expandafter{\x}}| +(one can also define a wrapper macro to |\xintZapFirstSpaces| in order to +expand once the argument first, but \xinttoolsname not being a programming +layer, it provides no «Generate Variants» facilities). + +Other use case: inside a macro which received a parameter |#1|, one can do +|\oodef\x{\xintZapFirstSpaces {#1}}|, or, if |#1|, after leading spaces have +been stripped can accept |\edef| expansion, one can do +|\edef\x{\xintZapFirstSpaces{#1}}|. + +\begingroup +\def\x { \a { \X } { \b \Y } } +% +\leftedline{|\xintZapFirstSpaces { \a { \X } { \b \Y } }->|% +\dtt{\color{magenta}{}\expandafter\detokenize\expandafter +{\romannumeral0\expandafter\xintzapfirstspaces\expandafter{\x}}}+++} +\endgroup + +\medskip + +\noindent\csbxint{ZapLastSpaces}\marg{stuff}\etype{n} does not do \emph{any} expansion of +its argument, nor brace removal of any sort, nor does it alter \meta{stuff} in +anyway apart from stripping away all \emph{ending} spaces. The same remarks as +for \csbxint{ZapFirstSpaces} apply. + +\begingroup +\def\x { \a { \X } { \b \Y } } +% +\leftedline{|\xintZapLastSpaces { \a { \X } { \b \Y } }->|% +\dtt{\color{magenta}{}\expandafter\detokenize\expandafter +{\romannumeral0\expandafter\xintzaplastspaces\expandafter{\x}}}+++} +\endgroup + +\medskip + +\noindent\csbxint{ZapSpaces}\marg{stuff}\etype{n} does not do \emph{any} +expansion of its +argument, nor brace removal of any sort, nor does it alter \meta{stuff} in +anyway apart from stripping away all \emph{leading} and all \emph{ending} +spaces. The same remarks as for \csbxint{ZapFirstSpaces} apply. + +\begingroup +\def\x { \a { \X } { \b \Y } } +% +\leftedline{|\xintZapSpaces { \a { \X } { \b \Y } }->|% +\dtt{\color{magenta}{}\expandafter\detokenize\expandafter +{\romannumeral0\expandafter\xintzapspaces\expandafter{\x}}}+++} +\endgroup + +\medskip + +\noindent\csbxint{ZapSpacesB}\marg{stuff}\etype{n} does not do \emph{any} +expansion of +its argument, nor does it alter \meta{stuff} in anyway apart from stripping away +all leading and all ending spaces and possibly removing one level of braces if +\meta{stuff} had the shape |<spaces>{braced}<spaces>|. The same remarks as for +\csbxint{ZapFirstSpaces} apply. + +\begingroup +\def\x { \a { \X } { \b \Y } } +% +\leftedline{|\xintZapSpacesB { \a { \X } { \b \Y } }->|% +\dtt{\color{magenta}{}\expandafter\detokenize\expandafter +{\romannumeral0\expandafter\xintzapspacesb\expandafter{\x}}}+++} +\def\x { { \a { \X } { \b \Y } } } +% +\leftedline{|\xintZapSpacesB { { \a { \X } { \b \Y } } }->|% +\dtt{\color{magenta}{}\expandafter\detokenize\expandafter +{\romannumeral0\expandafter\xintzapspacesb\expandafter{\x}}}+++} +\endgroup + The spaces here at the start and end of the output come from the braced + material, and are not removed (one would need a second application for that; + recall though that the \xintname zapping macros do not expand their argument). + +\subsection{\csh{xintCSVtoList}} +\label{xintCSVtoList} +\label{xintCSVtoListNoExpand} + + +\csa{xintCSVtoList}|{a,b,c...,z}|\etype{f} returns |{a}{b}{c}...{z}|. A +\emph{list} is by +convention in this manual simply a succession of tokens, where each braced thing +will count as one item (``items'' are defined according to the rules of \TeX{} +for fetching undelimited parameters of a macro, which are exactly the same rules +as for \LaTeX{} and macro arguments [they are the same things]). The word +`list' in `comma separated list of items' has its usual linguistic meaning, +and then an ``item'' is what is delimited by commas. + +So \csa{xintCSVtoList} takes on input a `comma separated list of items' and +converts it into a `\TeX{} list of braced items'. The argument to +|\xintCSVtoList| may be a macro: it will first be +\hyperref[ssec:expansions]{\fexpan ded}. Hence the item before the first comma, +if it is itself a macro, will be expanded which may or may not be a good thing. +A space inserted at the start of the first item serves to stop that expansion +(and disappears). The macro \csbxint{CSVtoListNoExpand}\etype{n} does the same +job without +the initial expansion of the list argument. + +Apart from that no expansion of the items is done and the list items may thus be +completely arbitrary (and even contain perilous stuff such as unmatched |\if| +and |\fi| tokens). + +Contiguous spaces and tab characters, are collapsed by \TeX{} +into single spaces. All such spaces around commas% +% +\footnote{and multiple space tokens are not a problem; but those at the + top level (not hidden inside braces) \emph{must} be of character code + |32|.} +% +\fbox{are removed}, as well as +the spaces at the start and the spaces at the end of the list.% +% +\footnote{let us recall that this is all done completely expandably... + There is absolutely no alteration of any sort of the item apart from + the stripping of initial and final space tokens (of character code + |32|) and brace removal if and only if the item apart from intial and + final spaces (or more generally multiple |char 32| space tokens) is + braced.} +% +The items may contain explicit |\par|'s or +empty lines (converted by the \TeX{} input parsing into |\par| tokens). + +\begingroup + +\edef\X{\xintCSVtoList { 1 ,{ 2 , 3 , 4 , 5 }, a , {b,T} U , { c , d } , { {x , + y} } }} + +% +\leftedline{|\xintCSVtoList { 1 ,{ 2 , 3 , 4 , 5 }, a , {b,T} U , { c , d } , + { {x , y} } }|} +% +\leftedline{|->|% +{\makeatletter\dtt{\expandafter\strip@prefix\meaning\X}}} + +One sees on this example how braces protect commas from +sub-lists to be perceived as delimiters of the top list. Braces around an entire +item are removed, even when surrounded by spaces before and/or after. Braces for +sub-parts of an item are not removed. + +We observe also that there is a slight difference regarding the brace stripping +of an item: if the braces were not surrounded by spaces, also the initial and +final (but no other) spaces of the \emph{enclosed} material are removed. This is +the only situation where spaces protected by braces are nevertheless removed. + +From the rules above: for an empty argument (only spaces, no braces, no comma) +the output is +\dtt{\expandafter\detokenize\expandafter{\romannumeral0\xintcsvtolist { }}} +(a list with one empty item), +for ``|<opt. spaces>{}<opt. +spaces>|'' the output is +\dtt{\expandafter\detokenize\expandafter + {\romannumeral0\xintcsvtolist { {} }}} +(again a list with one empty item, the braces were removed), +for ``|{ }|'' the output is +\dtt{\expandafter\detokenize\expandafter + {\romannumeral0\xintcsvtolist {{ }}}} +(again a list with one empty item, the braces were removed and then +the inner space was removed), +for ``| { }|'' the output is +\dtt{\expandafter\detokenize\expandafter +{\romannumeral0\xintcsvtolist { { }}}} (again a list with one empty item, the initial space served only to stop the expansion, so this was like ``|{ }|'' as input, the braces were removed and the inner space was stripped), +for ``\texttt{\ \{\ \ \}\ }'' the output is +\dtt{\expandafter\detokenize\expandafter +{\romannumeral0\xintcsvtolist { { } }}} (this time the ending space of the first +item meant that after brace removal the inner spaces were kept; recall though +that \TeX{} collapses on input consecutive blanks into one space token), +for ``|,|'' the output consists of two consecutive +empty items +\dtt{\expandafter\detokenize\expandafter{\romannumeral0\xintcsvtolist + {,}}}. Recall that on output everything is braced, a |{}| is an ``empty'' +item. +% +Most of the above is mainly irrelevant for every day use, apart perhaps from the +fact to be noted that an empty input does not give an empty output but a +one-empty-item list (it is as if an ending comma was always added at the end of +the input). + +\def\y { \a,\b,\c,\d,\e} +\expandafter\def\expandafter\Y\expandafter{\romannumeral0\xintcsvtolist{\y}} +\def\t {{\if},\ifnum,\ifx,\ifdim,\ifcat,\ifmmode} +\expandafter\def\expandafter\T\expandafter{\romannumeral0\xintcsvtolist{\t}} + +% +\leftedline{|\def\y{ \a,\b,\c,\d,\e} \xintCSVtoList\y->|% + {\makeatletter\dtt{\expandafter\strip@prefix\meaning\Y}}} +% +\leftedline{|\def\t {{\if},\ifnum,\ifx,\ifdim,\ifcat,\ifmmode}|} +% +\leftedline +{|\xintCSVtoList\t->|\makeatletter\dtt{\expandafter\strip@prefix\meaning\T}} +% +The results above were automatically displayed using \TeX's primitive +\csa{meaning}, which adds a space after each control sequence name. These spaces +are not in the actual braced items of the produced lists. The first items |\a| +and |\if| were either preceded by a space or braced to prevent expansion. The +macro \csa{xintCSVtoListNoExpand} would have done the same job without the +initial expansion of the list argument, hence no need for such protection but if +|\y| is defined as |\def\y{\a,\b,\c,\d,\e}| we then must do: +% +\leftedline{|\expandafter\xintCSVtoListNoExpand\expandafter {\y}|} Else, we +may have direct use: % +% +\leftedline{|\xintCSVtoListNoExpand + {\if,\ifnum,\ifx,\ifdim,\ifcat,\ifmmode}|} +% +\leftedline{|->|\dtt{\expandafter\detokenize\expandafter + {\romannumeral0\xintcsvtolistnoexpand + {\if,\ifnum,\ifx,\ifdim,\ifcat,\ifmmode}}}} +% +Again these spaces are an artefact from the use in the source of the document of +\csa{meaning} (or rather here, \csa{detokenize}) to display the result of using +\csa{xintCSVtoListNoExpand} (which is done for real in this document +source). + +For the similar conversion from comma separated list to braced items list, but +without removal of spaces around the commas, there is +\csa{xintCSVtoListNonStripped}\etype{f} and +\csa{xintCSVtoListNonStrippedNoExpand}\etype{n}. + +\endgroup + +\subsection{\csh{xintNthElt}}\label{xintNthElt} + + +\def\macro #1{\the\numexpr 9-#1\relax} + +\csa{xintNthElt\x}\marg{list}\etype{\numx f} gets (expandably) the |x|th +item of the \meta{list}. A braced item will lose one level of brace +pairs. The token list is first \fexpan ded. + +Items are counted starting at one. + +\leftedline{|\xintNthElt {3}{{agh}\u{zzz}\v{Z}}| is + \texttt{\xintNthElt {3}{{agh}\u{zzz}\v{Z}}}} +% +\leftedline{|\xintNthElt {3}{{agh}\u{{zzz}}\v{Z}}| is + \texttt{\expandafter\expandafter\expandafter + \detokenize\expandafter\expandafter\expandafter {\xintNthElt + {3}{{agh}\u{{zzz}}\v{Z}}}}} +% +\leftedline{|\xintNthElt {2}{{agh}\u{{zzz}}\v{Z}}| is + \texttt{\expandafter\expandafter\expandafter + \detokenize\expandafter\expandafter\expandafter {\xintNthElt + {2}{{agh}\u{{zzz}}\v{Z}}}}} +% +\leftedline{|\xintNthElt {37}{\xintiiFac {100}}|\dtt{=\xintNthElt + {37}{\xintiiFac {100}}} is the thirty-seventh digit of $100!$.} +% +\leftedline{|\xintNthElt {10}{\xintFtoCv + {566827/208524}}|\dtt{=\xintNthElt {10}{\xintFtoCv + {566827/208524}}}} +\leftedline{is the tenth convergent of $566827/208524$ (uses \xintcfracname + package).} +% +\leftedline{|\xintNthElt {7}{\xintCSVtoList {1,2,3,4,5,6,7,8,9}}|% + \dtt{=\xintNthElt {7}{\xintCSVtoList {1,2,3,4,5,6,7,8,9}}}} +% +\leftedline{|\xintNthElt {0}{\xintCSVtoList {1,2,3,4,5,6,7,8,9}}|% + \dtt{=\xintNthElt {0}{\xintCSVtoList {1,2,3,4,5,6,7,8,9}}}} +% +\leftedline{|\xintNthElt {-3}{\xintCSVtoList {1,2,3,4,5,6,7,8,9}}|% + \dtt{=\xintNthElt {-3}{\xintCSVtoList {1,2,3,4,5,6,7,8,9}}}} + +If |x=0|, +the macro returns the \emph{length} of the expanded list: this is not equivalent +to \csbxint{Length} which does no pre-expansion. And it is different from +\csbxint{Len} which is to be used only on integers or fractions. + +If |x<0|, the macro returns the \verb+|x|+th element from the end of the list. +Thus for example |x=-1| will fetch the last item of the list. +% +\leftedline {|\xintNthElt {-5}{{{agh}}\u{zzz}\v{Z}}| is + \texttt{\expandafter\expandafter\expandafter \detokenize + \expandafter\expandafter\expandafter{\xintNthElt {-5}{{{agh}}\u{zzz}\v{Z}}}}} + +The macro \csa{xintNthEltNoExpand}\etype{\numx n} does the same job but without +first expanding the list argument: |\xintNthEltNoExpand {-4}{\u\v\w T\x\y\z}| is +\xintNthEltNoExpand {-4}{\a\b\c\u\v\w T\x\y\z}. + +If |x| is strictly larger (in absolute value) than the length of the list +then |\xintNthElt| produces empty contents. + +\subsection{\csh{xintNthOnePy}} +\label{xintNthOnePy} + +\csa{xintNthOnePy\x}\marg{list}\etype{\numx f} gets (expandably) the |x|th +item of the \meta{list}, adding a brace pair if there wasn't one.\NewWith{1.4} + +Attention, items are counted starting at zero. For negative index, behaves +as \csbxint{NthElt}. + +If the index is out of range, the empty output is returned. If the input list +was empty (had no items) the empty output is returned. + +\subsection{\csh{xintKeep}}\label{xintKeep} + +\csa{xintKeep\x}\marg{list}\etype{\numx f} expands the token list argument |L| +and produces a new list, depending on the value of |x|: +\begin{itemize}[nosep] +\item if |x>0|, the new list contains the first |x| items from |L| (counting + starts at one.) \emph{Each + such item will be output within a brace pair.} Use \csbxint{KeepUnbraced} if + this is not desired. This means that if the list item was braced to start + with, there is no modification, but if it was a token without braces, + then it acquires them. +\item if |x>=length(L)|, the new list is the old one with all its items now + braced. +\item if |x=0| the empty list is returned. +\item if |x<0| the last \verb+|x|+ elements compose the output in the same + order as in the initial list; as the macro proceeds by removing head items + the kept items end up in output as they were in input: no added braces. +\item if |x<=-length(L)| the output is identical with the input. +\end{itemize} + +\csa{xintKeepNoExpand} does the same without first \fexpan ding its list +argument. +% +\begin{everbatim*} +\fdef\test {\xintKeep {17}{\xintKeep {-69}{\xintSeq {1}{100}}}}\meaning\test\par +\noindent\fdef\test {\xintKeep {7}{{1}{2}{3}{4}{5}{6}{7}{8}{9}}}\meaning\test\par +\noindent\fdef\test {\xintKeep {-7}{{1}{2}{3}{4}{5}{6}{7}{8}{9}}}\meaning\test\par +\noindent\fdef\test {\xintKeep {7}{123456789}}\meaning\test\par +\noindent\fdef\test {\xintKeep {-7}{123456789}}\meaning\test\par +\end{everbatim*} + + +\subsection{\csh{xintKeepUnbraced}}\label{xintKeepUnbraced} + +Same as \csbxint{Keep} but no brace pairs are added around the kept items from +the head of the list in the case |x>0|: each such item will lose one level of +braces. Thus, to remove braces from all items of the list, one can use +\csbxint{KeepUnbraced} with its first argument larger than the length of the +list; the same is obtained from \csbxint{ListWithSep}|{}|\marg{list}. But the +new list will then have generally many more items than the original ones, +corresponding to the unbraced original items. + +For |x<0| the macro is no different from \csbxint{Keep}. Hence the name is a +bit misleading because brace removal will happen only if |x>0|. + +\csa{xintKeepUnbracedNoExpand} does the same without first \fexpan ding +its list argument. +% +\begin{everbatim*} +\fdef\test {\xintKeepUnbraced {10}{\xintSeq {1}{100}}}\meaning\test\par +\noindent\fdef\test {\xintKeepUnbraced {7}{{1}{2}{3}{4}{5}{6}{7}{8}{9}}}% + \meaning\test\par +\noindent\fdef\test {\xintKeepUnbraced {-7}{{1}{2}{3}{4}{5}{6}{7}{8}{9}}}% + \meaning\test\par +\noindent\fdef\test {\xintKeepUnbraced {7}{123456789}}\meaning\test\par +\noindent\fdef\test {\xintKeepUnbraced {-7}{123456789}}\meaning\test\par +\end{everbatim*} + +\subsection{\csh{xintTrim}}\label{xintTrim} + +\csa{xintTrim\x}\marg{list}\etype{\numx f} expands the list argument and +gobbles its first |x| elements. +\begin{itemize}[nosep] +\item if |x>0|, the first |x| items from |L| are gobbled. The remaining items + are not modified. +\item if |x>=length(L)|, the returned list is empty. +\item if |x=0| the original list is returned (with no added braces.) +\item if |x<0| the last \verb+|x|+ items of the list are removed. \emph{The + head items end up braced in the output.} Use \csbxint{TrimUnbraced} if + this is not desired. +\item if |x<=-length(L)| the output is empty. +\end{itemize} + +\csa{xintTrimNoExpand} does the same without first \fexpan ding its list +argument. +\begin{everbatim*} +\fdef\test {\xintTrim {17}{\xintTrim {-69}{\xintSeq {1}{100}}}}\meaning\test\par +\noindent\fdef\test {\xintTrim {7}{{1}{2}{3}{4}{5}{6}{7}{8}{9}}}\meaning\test\par +\noindent\fdef\test {\xintTrim {-7}{{1}{2}{3}{4}{5}{6}{7}{8}{9}}}\meaning\test\par +\noindent\fdef\test {\xintTrim {7}{123456789}}\meaning\test\par +\noindent\fdef\test {\xintTrim {-7}{123456789}}\meaning\test\par +\end{everbatim*} + +\subsection{\csh{xintTrimUnbraced}}\label{xintTrimUnbraced} + +Same as \csbxint{Trim} but in case of a negative |x| (cutting items from +the tail), the kept items from the head are not enclosed in brace pairs. They +will lose one level of braces. The name is a bit misleading +because when |x>0| there is no brace-stripping done on the kept items, because +the macro works simply by gobbling the head ones. + +\csa{xintTrimUnbracedNoExpand} does the same without first \fexpan ding its list +argument. + +\begin{everbatim*} +\fdef\test {\xintTrimUnbraced {-90}{\xintSeq {1}{100}}}\meaning\test\par +\noindent\fdef\test {\xintTrimUnbraced {7}{{1}{2}{3}{4}{5}{6}{7}{8}{9}}}% + \meaning\test\par +\noindent\fdef\test {\xintTrimUnbraced {-7}{{1}{2}{3}{4}{5}{6}{7}{8}{9}}}% + \meaning\test\par +\noindent\fdef\test {\xintTrimUnbraced {7}{123456789}}\meaning\test\par +\noindent\fdef\test {\xintTrimUnbraced {-7}{123456789}}\meaning\test\par +\end{everbatim*} + +\subsection{\csh{xintListWithSep}}\label{xintListWithSep} + + +\def\macro #1{\the\numexpr 9-#1\relax} + +\csa{xintListWithSep}\marg{sep}\marg{list}\etype{nf} inserts the separator +\meta{sep} in-between all items of the given list of braced items (or +individual tokens). The items are fetched as does \TeX\ with undelimited macro +arguments, thus they end up unbraced in output. If the \meta{list} is only one +(or multiple) space tokens, the output is empty. + +The list argument \meta{list} gets \fexpan ded first (thus if it is a macro +whose contents are braced items, the first opening brace stops the expansion, +and it is as if the macro had been expanded once.) The separator \meta{sep} is +not pre-expanded, it ends up as is in the output (if the \meta{list} contained +at least two items.) + +The variant \csa{xintListWithSepNoExpand}\etype{nn} does the same +job without the initial expansion of the \meta{list} argument. +\begin{everbatim*} +\edef\foo{\xintListWithSep{, }{123456789{10}{11}{12}}}\meaning\foo\newline +\edef\foo{\xintListWithSep{:}{\xintiiFac{20}}}\meaning\foo\newline +\oodef\FOO{\xintListWithSepNoExpand{\FOO}{\bat\baz\biz\buz}}\meaning\FOO\newline +% a braced item or a space stops the f-expansion: +\oodef\foo{\xintListWithSep{\FOO}{{\bat}\baz\biz\buz}}\meaning\foo\newline +\oodef\foo{\xintListWithSep{\FOO}{ \bat\baz\biz\buz}}\meaning\foo\par +\end{everbatim*} + +\subsection{\csh{xintApply}}\label{xintApply} + + +\def\macro #1{\the\numexpr 9-#1\relax} + +\csa{xintApply}|{\macro}|\marg{list}\etype{ff} expandably applies the one +parameter macro |\macro| to each item in the \meta{list} given as second +argument and returns a new list with these outputs: each item is given one after +the other as parameter to |\macro| which is expanded at that time (as usual, +\emph{i.e.\@} fully for what comes first), the results are braced and output +together as a succession of braced items (if |\macro| is defined to start with a +space, the space will be gobbled and the |\macro| will not be expanded; it is +allowed to have its own arguments, the list items serve as last arguments to +|\macro|). Hence |\xintApply{\macro}{{1}{2}{3}}| returns +|{\macro{1}}{\macro{2}}{\macro{3}}| where all instances of |\macro| have been +already \fexpan ded. + +Being expandable, |\xintApply| is useful for example inside alignments where +implicit groups make standard loops constructs usually fail. In such situation +it is often not wished that the new list elements be braced, see +\csbxint{ApplyUnbraced}. The |\macro| does not have to be expandable: +|\xintApply| will try to expand it, the expansion may remain partial. + +The \meta{list} may +itself be some macro expanding (in the previously described way) to the list of +tokens to which the macro |\macro| will be applied. For example, if the +\meta{list} expands to some positive number, then each digit will be replaced by +the result of applying |\macro| on it. % +% +\leftedline{|\def\macro #1{\the\numexpr + 9-#1\relax}|} % +% +\leftedline{|\xintApply\macro{\xintiiFac + {20}}|\dtt{=\xintApply\macro{\xintiiFac {20}}}} + +The macro \csa{xintApplyNoExpand}\etype{fn} does the same job without the first +initial expansion which gave the \meta{list} of braced tokens to which |\macro| +is applied. + +\subsection{\csh{xintApplyUnbraced}}\label{xintApplyUnbraced} + + +\csa{xintApplyUnbraced}|{\macro}|\marg{list}\etype{ff} is like \csbxint{Apply}. +The difference is that after having expanded its list argument, and applied +|\macro| in turn to each item from the list, it reassembles the outputs without +enclosing them in braces. The net effect is the same as doing +% +\leftedline{|\xintListWithSep {}{\xintApply {\macro}|\marg{list}|}|} This is +useful for preparing a macro which will itself define some other macros or make +assignments, as the scope will not be limited by brace pairs. +% +\begin{everbatim*} +\def\macro #1{\expandafter\def\csname myself#1\endcsname {#1}} +\xintApplyUnbraced\macro{{elta}{eltb}{eltc}} +\begin{enumerate}[nosep,label=(\arabic{*})] +\item \meaning\myselfelta +\item \meaning\myselfeltb +\item \meaning\myselfeltc +\end{enumerate} +\end{everbatim*} + +% +The macro \csa{xintApplyUnbracedNoExpand}\etype{fn} does the same job without +the first initial expansion which gave the \meta{list} of braced tokens to which +|\macro| is applied. + +\subsection{\csh{xintSeq}}\label{xintSeq} + +\csa{xintSeq}|[d]{x}{y}|\etype{{{\upshape[\numx]}}\numx\numx} generates +expandably |{x}{x+d}...| up to and possibly including |{y}| if |d>0| or down +to and including |{y}| if |d<0|. Naturally |{y}| is omitted if |y-x| is not a +multiple of |d|. If |d=0| the macro returns |{x}|. If |y-x| and |d| have +opposite signs, the macro returns nothing. If the optional argument |d| is +omitted it is taken to be the sign of |y-x|. Hence |\xintSeq {1}{0}| is not +empty but |{1}{0}|. But |\xintSeq [1]{1}{0}| is empty. + + +The arguments |x| and |y| are expanded inside a |\numexpr| so they may be +count registers or a \LaTeX{} |\value{countername}|, or arithmetic with such +things. + +% +\begin{everbatim*} +\xintListWithSep{,\hskip2pt plus 1pt minus 1pt }{\xintSeq {12}{-25}} +\end{everbatim*} +% +\begin{everbatim*} +\xintiiSum{\xintSeq [3]{1}{1000}} +\end{everbatim*} + +When the macro is used without the optional argument |d|, it can only generate +up to about $5000$ numbers\IMPORTANT, the precise value depends upon some +\TeX{} memory parameter (input save stack). + +With the optional argument |d| the macro proceeds differently (but less +efficiently) and does not stress the input save stack. + + + +\subsection{\csh{xintloop}, \csh{xintbreakloop}, \csh{xintbreakloopanddo}, \csh{xintloopskiptonext}} +\label{xintloop} +\label{xintbreakloop} +\label{xintbreakloopanddo} +\label{xintloopskiptonext} + +|\xintloop|\meta{stuff}|\if<test>...\repeat|\xtype{} is an expandable loop +compatible with nesting. However to break out of the loop one almost always need +some un-expandable step. The cousin \csbxint{iloop} is \csbxint{loop} with an +embedded expandable mechanism allowing to exit from the loop. The iterated +macros may contain |\par| tokens or empty lines. + +If a sub-loop is to be used all the material from the start of the main loop and +up to the end of the entire subloop should be braced; these braces will be +removed and do not create a group. The simplest to allow the nesting of one or +more sub-loops is to brace everything between \csa{xintloop} and \csa{repeat}, +being careful not to leave a space between the closing brace and |\repeat|. + +As this loop and \csbxint{iloop} will primarily be of interest to experienced +\TeX{} macro programmers, my description will assume that the user is +knowledgeable enough. Some examples in this document will be perhaps more +illustrative than my attemps at explanation of use. + +One can abort the loop with \csbxint{breakloop}; this should not be used inside +the final test, and one should expand the |\fi| from the corresponding test +before. One has also \csbxint{breakloopanddo} whose first argument will be +inserted in the token stream after the loop; one may need a macro such as +|\xint_afterfi| to move the whole thing after the |\fi|, as a simple +|\expandafter| will not be enough. + +One will usually employ some count registers to manage the exit test from the +loop; this breaks expandability, see \csbxint{iloop} for an expandable integer +indexed loop. Use in alignments will be complicated by the fact that cells +create groups, and also from the fact that any encountered unexpandable material +will cause the \TeX{} input scanner to insert |\endtemplate| on each encountered +|&| or |\cr|; thus |\xintbreakloop| may not work as expected, but the situation +can be resolved via |\xint_firstofone{&}| or use of |\TAB| with |\def\TAB{&}|. +It is thus simpler for alignments to use rather than \csbxint{loop} either the +expandable \csbxint{ApplyUnbraced} or the non-expandable but alignment +compatible \csbxint{ApplyInline}, \csbxint{For} or \csbxint{For*}. + +As an example, let us suppose we have two macros |\A|\marg{i}\marg{j} and +|\B|\marg{i}\marg{j} behaving like (small) integer valued matrix entries, and we +want to define a macro |\C|\marg{i}\marg{j} giving the matrix product (|i| and +|j| may be count registers). We will assume that |\A[I]| expands to the number +of rows, |\A[J]| to the number of columns and want the produced |\C| to act in +the same manner. The code is very dispendious in use of |\count| registers, not +optimized in any way, not made very robust (the defined macro can not have the +same name as the first two matrices for example), we just wanted to quickly +illustrate use of the nesting capabilities of |\xintloop|.% +% +\footnote{for a more sophisticated implementation of matrix + multiplication, inclusive of determinants, inverses, and display + utilities, with entries big integers or decimal numbers or even + fractions see some code online posted + from + November 11, 2013.} +% + + +\begin{everbatim*} +\newcount\rowmax \newcount\colmax \newcount\summax +\newcount\rowindex \newcount\colindex \newcount\sumindex +\newcount\tmpcount +\makeatletter +\def\MatrixMultiplication #1#2#3{% + \rowmax #1[I]\relax + \colmax #2[J]\relax + \summax #1[J]\relax + \rowindex 1 + \xintloop % loop over row index i + {\colindex 1 + \xintloop % loop over col index k + {\tmpcount 0 + \sumindex 1 + \xintloop % loop over intermediate index j + \advance\tmpcount \numexpr #1\rowindex\sumindex*#2\sumindex\colindex\relax + \ifnum\sumindex<\summax + \advance\sumindex 1 + \repeat }% + \expandafter\edef\csname\string#3{\the\rowindex.\the\colindex}\endcsname + {\the\tmpcount}% + \ifnum\colindex<\colmax + \advance\colindex 1 + \repeat }% + \ifnum\rowindex<\rowmax + \advance\rowindex 1 + \repeat + \expandafter\edef\csname\string#3{I}\endcsname{\the\rowmax}% + \expandafter\edef\csname\string#3{J}\endcsname{\the\colmax}% + \def #3##1{\ifx[##1\expandafter\Matrix@helper@size + \else\expandafter\Matrix@helper@entry\fi #3{##1}}% +}% +\def\Matrix@helper@size #1#2#3]{\csname\string#1{#3}\endcsname }% +\def\Matrix@helper@entry #1#2#3% + {\csname\string#1{\the\numexpr#2.\the\numexpr#3}\endcsname }% +\def\A #1{\ifx[#1\expandafter\A@size + \else\expandafter\A@entry\fi {#1}}% +\def\A@size #1#2]{\ifx I#23\else4\fi}% 3rows, 4columns +\def\A@entry #1#2{\the\numexpr #1+#2-1\relax}% not pre-computed... +\def\B #1{\ifx[#1\expandafter\B@size + \else\expandafter\B@entry\fi {#1}}% +\def\B@size #1#2]{\ifx I#24\else3\fi}% 4rows, 3columns +\def\B@entry #1#2{\the\numexpr #1-#2\relax}% not pre-computed... +\makeatother +\MatrixMultiplication\A\B\C \MatrixMultiplication\C\C\D +\MatrixMultiplication\C\D\E \MatrixMultiplication\C\E\F +\begin{multicols}2 + \[\begin{pmatrix} + \A11&\A12&\A13&\A14\\ + \A21&\A22&\A23&\A24\\ + \A31&\A32&\A33&\A34 + \end{pmatrix} + \times + \begin{pmatrix} + \B11&\B12&\B13\\ + \B21&\B22&\B23\\ + \B31&\B32&\B33\\ + \B41&\B42&\B43 + \end{pmatrix} + = + \begin{pmatrix} + \C11&\C12&\C13\\ + \C21&\C22&\C23\\ + \C31&\C32&\C33 + \end{pmatrix}\] + \[\begin{pmatrix} + \C11&\C12&\C13\\ + \C21&\C22&\C23\\ + \C31&\C32&\C33 + \end{pmatrix}^2 = \begin{pmatrix} + \D11&\D12&\D13\\ + \D21&\D22&\D23\\ + \D31&\D32&\D33 + \end{pmatrix}\] + \[\begin{pmatrix} + \C11&\C12&\C13\\ + \C21&\C22&\C23\\ + \C31&\C32&\C33 + \end{pmatrix}^3 = \begin{pmatrix} + \E11&\E12&\E13\\ + \E21&\E22&\E23\\ + \E31&\E32&\E33 + \end{pmatrix}\] + \[\begin{pmatrix} + \C11&\C12&\C13\\ + \C21&\C22&\C23\\ + \C31&\C32&\C33 + \end{pmatrix}^4 = \begin{pmatrix} + \F11&\F12&\F13\\ + \F21&\F22&\F23\\ + \F31&\F32&\F33 + \end{pmatrix}\] +\end{multicols} +\end{everbatim*} + + +\subsection{\csh{xintiloop}, \csh{xintiloopindex}, \csh{xintouteriloopindex}, + \csh{xintbreakiloop}, \csh{xintbreakiloopanddo}, \csh{xintiloopskiptonext}, +\csh{xintiloopskipandredo}} +\label{xintiloop} +\label{xintbreakiloop} +\label{xintbreakiloopanddo} +\label{xintiloopskiptonext} +\label{xintiloopskipandredo} +\label{xintiloopindex} +\label{xintouteriloopindex} + +\csa{xintiloop}|[start+delta]|\meta{stuff}|\if<test> ... \repeat|\xtype{} is a +completely expandable nestable loop. complete expandability depends naturally on +the actual iterated contents, and complete expansion will not be achievable +under a sole \fexpan sion, as is indicated by the hollow star in the margin; +thus the loop can be used inside an |\edef| but not inside arguments to the +package macros. It can be used inside an |\xintexpr..\relax|. The +|[start+delta]| is mandatory, not optional. + +This loop benefits via \csbxint{iloopindex} to (a limited access to) the integer +index of the iteration. The starting value |start| (which may be a |\count|) and +increment |delta| (\emph{id.}) are mandatory arguments. A space after the +closing square bracket is not significant, it will be ignored. Spaces inside the +square brackets will also be ignored as the two arguments are first given to a +|\numexpr...\relax|. Empty lines and explicit |\par| tokens are accepted. + +As with \csbxint{loop}, this tool will mostly be of interest to advanced users. +For nesting, one puts inside braces all the +material from the start (immediately after |[start+delta]|) and up to and +inclusive of the inner loop, these braces will be removed and do not create a +loop. In case of nesting, \csbxint{outeriloopindex} gives access to the index of +the outer loop. If needed one could write on its model a macro giving access to +the index of the outer outer loop (or even to the |nth| outer loop). + +The \csa{xintiloopindex} and \csa{xintouteriloopindex} can not be used inside +braces, and generally speaking this means they should be expanded first when +given as argument to a macro, and that this macro receives them as delimited +arguments, not braced ones. Or, but naturally this will break expandability, one +can assign the value of \csa{xintiloopindex} to some |\count|. Both +\csa{xintiloopindex} and \csa{xintouteriloopindex} extend to the litteral +representation of the index, thus in |\ifnum| tests, if it comes last one has to +correctly end the macro with a |\space|, or encapsulate it in a +|\numexpr..\relax|. + +When the repeat-test of the loop is, for example, |\ifnum\xintiloopindex<10 +\repeat|, this means that the last iteration will be with |\xintiloopindex=10| +(assuming |delta=1|). There is also |\ifnum\xintiloopindex=10 \else\repeat| to +get the last iteration to be the one with |\xintiloopindex=10|. + +One has \csbxint{breakiloop} and \csbxint{breakiloopanddo} to abort the loop. +The syntax of |\xintbreakiloopanddo| is a bit surprising, the sequence of tokens +to be executed after breaking the loop is not within braces but is delimited by +a dot as in: +% +\leftedline{|\xintbreakiloopanddo <afterloop>.etc.. etc... \repeat|} +% +The reason is that one may wish to use the then current value of +|\xintiloopindex| in |<afterloop>| but it can't be within braces at the time it +is evaluated. However, it is not that easy as |\xintiloopindex| must be expanded +before, so one ends up with code like this: +% +\leftedline +{|\expandafter\xintbreakiloopanddo\expandafter\macro\xintiloopindex.%|} +% +\leftedline{|etc.. etc.. \repeat|} +% +As moreover the |\fi| from the test leading to the decision of breaking out of +the loop must be cleared out of the way, the above should be +a branch of an expandable conditional test, else one needs something such +as: +% +\leftedline +{|\xint_afterfi{\expandafter\xintbreakiloopanddo\expandafter\macro\xintiloopindex.}%|} +% +\leftedline{|\fi etc..etc.. \repeat|} + +There is \csbxint{iloopskiptonext} to abort the current iteration and skip to +the next, \hyperref[xintiloopskipandredo]{\ttfamily\hyphenchar\font45 \char92 + xintiloopskip\-and\-redo} to skip to the end of the current iteration and redo +it with the same value of the index (something else will have to change for this +not to become an eternal loop\dots ). + +Inside alignments, if the looped-over text contains a |&| or a |\cr|, any +un-expandable material before a \csbxint{iloopindex} will make it fail because +of |\endtemplate|; in such cases one can always either replace |&| by a macro +expanding to it or replace it by a suitable |\firstofone{&}|, and similarly for +|\cr|. + +\phantomsection\label{edefprimes} +As an example, let us construct an |\edef\z{...}| which will define |\z| to be a +list of prime numbers: +\begin{everbatim*} +\begingroup +\edef\z +{\xintiloop [10001+2] + {\xintiloop [3+2] + \ifnum\xintouteriloopindex<\numexpr\xintiloopindex*\xintiloopindex\relax + \xintouteriloopindex, + \expandafter\xintbreakiloop + \fi + \ifnum\xintouteriloopindex=\numexpr + (\xintouteriloopindex/\xintiloopindex)*\xintiloopindex\relax + \else + \repeat + }% no space here + \ifnum \xintiloopindex < 10999 \repeat }% +\meaning\z\endgroup +\end{everbatim*}and we should have taken +some steps to not have a trailing comma, but +the point was to show that one can do that in an |\edef|\,! See also +\autoref{ssec:primesII} which extracts from this code its way of testing +primality. + +Let us create an alignment where each row will contain all divisors of its +first entry. +Here is the output, thus obtained without any count register: +\begin{everbatim*} +\begin{multicols}2 +\tabskip1ex \normalcolor +\halign{&\hfil#\hfil\cr + \xintiloop [1+1] + {\expandafter\bfseries\xintiloopindex & + \xintiloop [1+1] + \ifnum\xintouteriloopindex=\numexpr + (\xintouteriloopindex/\xintiloopindex)*\xintiloopindex\relax + \xintiloopindex&\fi + \ifnum\xintiloopindex<\xintouteriloopindex\space % CRUCIAL \space HERE + \repeat \cr }% + \ifnum\xintiloopindex<30 + \repeat +} +\end{multicols} +\end{everbatim*} +We wanted this first entry in bold face, but |\bfseries| leads to +unexpandable tokens, so the |\expandafter| was necessary for |\xintiloopindex| +and |\xintouteriloopindex| not to be confronted with a hard to digest +|\endtemplate|. An alternative way of coding: +% +\begin{everbatim} +\tabskip1ex +\def\firstofone #1{#1}% +\halign{&\hfil#\hfil\cr + \xintiloop [1+1] + {\bfseries\xintiloopindex\firstofone{&}% + \xintiloop [1+1] \ifnum\xintouteriloopindex=\numexpr + (\xintouteriloopindex/\xintiloopindex)*\xintiloopindex\relax + \xintiloopindex\firstofone{&}\fi + \ifnum\xintiloopindex<\xintouteriloopindex\space % \space is CRUCIAL + \repeat \firstofone{\cr}}% + \ifnum\xintiloopindex<30 \repeat } +\end{everbatim} + +\begin{framed} + The next utilities are not compatible with expansion-only context. +\end{framed} + +\subsection{\csh{xintApplyInline}}\label{xintApplyInline} + + +\csa{xintApplyInline}|{\macro}|\marg{list}\ntype{o{\lowast f}} works non +expandably. It applies the one-parameter |\macro| to the first element of the +expanded list (|\macro| may have itself some arguments, the list item will be +appended as last argument), and is then re-inserted in the input stream after +the tokens resulting from this first expansion of |\macro|. The next item is +then handled. + +This is to be used in situations where one needs to do some repetitive +things. It is not expandable and can not be completely expanded inside a +macro definition, to prepare material for later execution, contrarily to what +\csbxint{Apply} or \csbxint{ApplyUnbraced} achieve. + +\begin{everbatim*} +\def\Macro #1{\advance\cnta #1 , \the\cnta} +\cnta 0 +0\xintApplyInline\Macro {3141592653}. +\end{everbatim*} +The first argument |\macro| does not have to be an expandable macro. + +\csa{xintApplyInline} submits its second, token list parameter to an +\hyperref[ssec:expansions]{\fexpan +sion}. Then, each \emph{unbraced} item will also be \fexpan ded. This provides +an easy way to insert one list inside another. \emph{Braced} items are not +expanded. Spaces in-between items are gobbled (as well as those at the start +or the end of the list), but not the spaces \emph{inside} the braced items. + +\csa{xintApplyInline}, despite being non-expandable, does survive to +contexts where the executed |\macro| closes groups, as happens inside +alignments with the tabulation character |&|. +This tabular provides an example:\par +\begin{everbatim*} +\centerline{\normalcolor\begin{tabular}{ccc} + $N$ & $N^2$ & $N^3$ \\ \hline + \def\Row #1{ #1 & \xintiiSqr {#1} & \xintiiPow {#1}{3} \\ \hline }% + \xintApplyInline \Row {\xintCSVtoList{17,28,39,50,61}} +\end{tabular}}\medskip +\end{everbatim*} + +We see that despite the fact that the first encountered tabulation character in +the first row close a group and thus erases |\Row| from \TeX's memory, +|\xintApplyInline| knows how to deal with this. + +Using \csbxint{ApplyUnbraced} is an alternative: the difference is that +this would have prepared all rows first and only put them back into the +token stream once they are all assembled, whereas with |\xintApplyInline| +each row is constructed and immediately fed back into the token stream: when +one does things with numbers having hundreds of digits, one learns that +keeping on hold and shuffling around hundreds of tokens has an impact on +\TeX{}'s speed (make this ``thousands of tokens'' for the impact to be +noticeable). + +One may nest various |\xintApplyInline|'s. For example (see the +\hyperref[float]{table} \vpageref{float}):\par +\begin{everbatim*} +\begin{figure*}[ht!] + \centering\phantomsection\label{float} + \def\Row #1{#1:\xintApplyInline {\Item {#1}}{0123456789}\\ }% + \def\Item #1#2{&\xintiiPow {#1}{#2}}% + \centeredline {\begin{tabular}{ccccccccccc} &0&1&2&3&4&5&6&7&8&9\\ \hline + \xintApplyInline \Row {0123456789} + \end{tabular}} +\end{figure*} +\end{everbatim*} + +One could not move the definition of |\Item| inside the tabular, +as it would get lost after the first |&|. But this +works: +\everb|@ +\begin{tabular}{ccccccccccc} + &0&1&2&3&4&5&6&7&8&9\\ \hline + \def\Row #1{#1:\xintApplyInline {&\xintiiPow {#1}}{0123456789}\\ }% + \xintApplyInline \Row {0123456789} +\end{tabular} +| + +A limitation is that, contrarily to what one may have expected, the +|\macro| for an |\xintApplyInline| can not be used to define +the |\macro| for a nested sub-|\xintApplyInline|. For example, +this does not work:\par +\everb|@ + \def\Row #1{#1:\def\Item ##1{&\xintiiPow {#1}{##1}}% + \xintApplyInline \Item {0123456789}\\ }% + \xintApplyInline \Row {0123456789} % does not work +| +\noindent But see \csbxint{For}. + +\subsection{\csh{xintFor}, \csh{xintFor*}}\label{xintFor}\label{xintFor*} + +\csbxint{For}\ntype{on} is a new kind of for loop.\footnote{first introduced + with \xintname |1.09c| of |2013/10/09|.} Rather than using macros +for encapsulating list items, its behaviour is like a macro with parameters: +|#1|, |#2|, \dots, |#9| are used to represent the items for up to nine levels of +nested loops. Here is an example: +% +\everb|@ +\xintFor #9 in {1,2,3} \do {% + \xintFor #1 in {4,5,6} \do {% + \xintFor #3 in {7,8,9} \do {% + \xintFor #2 in {10,11,12} \do {% + $$#9\times#1\times#3\times#2=\xintiiPrd{{#1}{#2}{#3}{#9}}$$}}}} +| +\noindent This example illustrates that one does not have to use |#1| as the +first one: +the order is arbitrary. But each level of nesting should have its specific macro +parameter. Nine levels of nesting is presumably overkill, but I did not know +where it was reasonable to stop. |\par| tokens are accepted in both the comma +separated list and the replacement text. + +\begin{framed} + \TeX nical notes: + +\begin{itemize} + \item The |#1| is replaced in the iterated-over text exactly as in general + \TeX\ macros or \LaTeX\ commands. This spares the user quite a few + |\expandafter|'s or other tricks needed with loops which have the + values encapsulated in macros, like \LaTeX's |\@for| and |\@tfor|. + + \item \csa{xintFor} (and \csa{xintFor*}) isn't purely expandable: one can + not use it inside an |\edef|. But it may be used, as will be shown in + examples, in some contexts such as \LaTeX's |tabular| which are usually + hostile to non-expandable loops. + + \item \csa{xintFor} (and \csa{xintFor*}) does some assignments prior to + executing each iteration of the replacement text, but it acts purely + expandably after the last iteration, hence if for example the replacement + text ends with a |\\|, the loop can be used insided a tabular and be + followed by a |\hline| without creating the dreaded ``|Misplaced + \noalign|'' error. + + \item As stated in previous item the first iteration follows some + non-expandable internal dealings. This means for example that in \LaTeX{}, + one can not inject a |\multicolumn| in the first iteration. Sometimes one + way work around this by injecting father |&\multicolumn| or |\\ + \multicolumn|. + + \item It does not create groups. + + \item It makes no global assignments. + + \item The iterated replacement text may close a group which was opened even + before the start of the loop (typical example being with |&| in + alignments). +\begin{everbatim*} +\begin{tabular}{rccccc} + \hline + \xintFor #1 in {A, B, C} \do {% + #1:\xintFor #2 in {a, b, c, d, e} \do {&($ #2 \to #1 $)}\\ }% + \hline +\end{tabular} +\end{everbatim*} + + \item There is no facility provided which would give access to a count of + the number of iterations as it is technically not easy to do so it in a + way working with nested loops while maintaining the ``expandable after + done'' property; something in the spirit of \csbxint{iloopindex} is + possible but this approach would bring its own limitations and + complications. Hence the user is invited to update her own count or + \LaTeX{} counter or macro at each iteration, if needed. + + \item A |\macro| whose definition uses internally an \csbxint{For} loop + may be used inside another \csbxint{For} loop even if the two loops both + use the same macro parameter. The loop definition inside |\macro| + must use |##| as is the general rule for definitions done inside macros. + + \item \csbxint{For} is for comma separated values and \csbxint{For*} for + lists of braced items; their respective expansion policies differ. They + are described later. +\end{itemize} +\unskip +\end{framed} + +\noindent Regarding \csbxint{For}: +\begin{itemize}[nosep, listparindent=\leftmarginiii] +\item the spaces between the various declarative elements are all optional, +\item in the list of comma separated values, spaces around the commas or at + the start and end are ignored, +\item if an item must contain itself its own commas, then it should + be braced, and the braces will be removed before feeding the iterated-over + text, +\item the list may be a macro, it is expanded only once, +\item items are not pre-expanded. The first item should be braced or start + with a space if the list is explicit and the item should not be + pre-expanded, +\item empty items give empty |#1|'s in the replacement text, they are not + skipped, +\item an empty list executes once the replacement text with an empty parameter + value, +\item the list, if not a macro, \fbox{must be braced.} +\end{itemize} + +\noindent Regarding \csbxint{For*}:\ntype{{\lowast f}n} +\begin{itemize}[nosep, listparindent=\leftmarginiii] +\item it handles lists of braced items (or naked tokens), +\item it \hyperref[ssec:expansions]{\fexpan ds} the list, +\item and more generally it \hyperref[ssec:expansions]{\fexpan ds} each naked + token encountered + before assigning the |#1| values (gobbling spaces in the process); + this + makes it easy to simulate concatenation of multiple lists|\x|, |\y|: + if |\x| expands to |{1}{2}{3}| and |\y| expands to |{4}{5}{6}| then |{\x\y}| + as argument to |\xintFor*| has the same effect as |{{1}{2}{3}{4}{5}{6}}|. + + For a further illustration see the use of |\xintFor*| at the end of + \autoref{ssec:fibonacci}. +\item spaces at the start, end, or in-between items are gobbled (but naturally + not the spaces inside \emph{braced} items), +\item except if the list argument is a macro (with no parameters), \fbox{it + must be braced.}, +\item an empty list leads to an empty result. +\end{itemize} + +The macro \csbxint{Seq} which generates arithmetic sequences is to be used +with \csbxint{For*} as its output consists of successive braced numbers (given +as digit tokens). +\begin{everbatim*} +\xintFor* #1 in {\xintSeq [+2]{-7}{+2}}\do {stuff + with #1\xintifForLast{\par}{\newline}} +\end{everbatim*} + + +When nesting \csa{xintFor*} loops, using \csa{xintSeq} in the inner loops is +inefficient, as the arithmetic sequence will be re-created each time. A more +efficient style is: +% +\begin{everbatim} + \edef\innersequence {\xintSeq[+2]{-50}{50}}% + \xintFor* #1 in {\xintSeq {13}{27}} \do + {\xintFor* #2 in \innersequence \do {stuff with #1 and #2}% + .. some other macros .. } +\end{everbatim} + +This is a general remark applying for any nesting of loops, one should avoid +recreating the inner lists of arguments at each iteration of the outer loop. + + +When the loop is defined inside a macro for later execution the |#| characters +must be doubled.% +% +\footnote{sometimes what seems to be a macro argument isn't really; in + \csa{raisebox\{1cm\}\{}\csa{xintFor \#1 in \{a,b,c\} }\csa{do + \{\#1\}\}} no doubling should be done.} +% +For example: +% +\begin{everbatim*} +\def\T{\def\z {}% + \xintFor* ##1 in {{u}{v}{w}} \do {% + \xintFor ##2 in {x,y,z} \do {% + \expandafter\def\expandafter\z\expandafter {\z\sep (##1,##2)} }% + }% +}% +\T\def\sep {\def\sep{, }}\z +\end{everbatim*} + +Similarly when the replacement text +of |\xintFor| defines a macro with parameters, the macro character |#| must be +doubled. + + +The iterated macros as well as the list items are allowed to contain explicit +|\par| tokens. + + +\subsection{\csh{xintifForFirst}, \csh{xintifForLast}} +\label{xintifForFirst}\label{xintifForLast} + +\csbxint{ifForFirst}\,\texttt{\{YES branch\}\{NO branch\}}\etype{nn} + and \csbxint{ifForLast}\,\texttt{\{YES + branch\}\hskip 0pt plus 0.2em \{NO branch\}}\etype{nn} execute the |YES| or +|NO| branch +if the +\csbxint{For} +or \csbxint{For*} loop is currently in its first, respectively last, iteration. + +Designed to work as expected under nesting (but see frame next.) Don't forget +an empty brace pair |{}| if a branch is to do nothing. May be used multiple +times in the replacement text of the loop. + +\begin{framed} + \noindent Pay attention to these implementation features: + \begin{itemize}[nosep, listparindent=\leftmarginiii] + \item \emph{if an inner \csbxint{For} loop is positioned before the + \csb{xintifForFirst} or \csb{xintifForLast} of the outer loop it will + contaminate their settings. This applies also naturally if the inner loop + arises from the expansion of some macro located before the outer + conditionals.} + + One fix is to make sure that the outer conditionals are expanded before the + inner loop is executed, e.g. this will be the case if the inner loop is + located inside one of the branches of the conditional. + + Another approach is to enclose, if feasible, the inner loop in a group of + its own. + \item \emph{if the replacement text closes a group (e.g. from a |&| inside an + alignment), the conditionals will lose their ascribed meanings and end up + possibly undefined, depending whether there is some outer loop whose + execution started before the opening of the group.} + + The fix is to arrange things so that the conditionals are expanded + before \TeX\ encounters the closing-group token. + \end{itemize} +\end{framed} + +\subsection{ \csh{xintBreakFor}, \csh{xintBreakForAndDo}} +\label{xintBreakFor}\label{xintBreakForAndDo} + +One may immediately terminate an \csbxint{For} or \csbxint{For*} loop with +\csbxint{BreakFor}. + +\begin{framed} + As it acts by clearing up all the rest of the replacement text when + encountered, it will not work from inside some |\if...\fi| without + suitable |\expandafter| or swapping technique. + + Also it can't be used from inside braces as from there it can't see the end + of the replacement text. +\end{framed} + +There is also \csbxint{BreakForAndDo}. Both are illustrated by various examples +in the next section which is devoted to ``forever'' loops. + +\subsection{\csh{xintintegers}, \csh{xintdimensions}, \csh{xintrationals}} +\label{xintegers}\label{xintintegers} +\label{xintdimensions}\label{xintrationals} + +If the list argument to \csbxint{For} (or \csbxint{For*}, both are equivalent in +this context) is \csbxint{integers} (equivalently \csbxint{egers}) or more +generally \csbxint{integers}|[||start|\allowbreak|+|\allowbreak|delta||]| +(\emph{the whole within braces}!)% +% +\footnote{the |start+delta| optional specification may have extra spaces + around the plus sign of near the square brackets, such spaces are + removed. The same applies with \csa{xintdimensions} and + \csa{xintrationals}.}, +% +then \csbxint{For} does an infinite iteration where +|#1| (or |#2|, \dots, |#9|) will run through the arithmetic sequence of (short) +integers with initial value |start| and increment |delta| (default values: +|start=1|, |delta=1|; if the optional argument is present it must contains both +of them, and they may be explicit integers, or macros or count registers). The +|#1| (or |#2|, \dots, |#9|) will stand for |\numexpr <opt sign><digits>\relax|, +and the litteral representation as a string of digits can thus be obtained as +\fbox{\csa{the\#1}} or |\number#1|. Such a |#1| can be used in an |\ifnum| test +with no need to be postfixed with a space or a |\relax| and one should +\emph{not} add them. + +If the list argument is \csbxint{dimensions} or more generally +\csbxint{dimensions}|[||start|\allowbreak|+|\allowbreak|delta||]| (\emph{within + braces}!), then +\csbxint{For} does an infinite iteration where |#1| (or |#2|, \dots, |#9|) will +run through the arithmetic sequence of dimensions with initial value +|start| and increment |delta|. Default values: |start=0pt|, |delta=1pt|; if +the optional argument is present it must contain both of them, and they may +be explicit specifications, or macros, or dimen registers, or length macros +in \LaTeX{} (the stretch and shrink components will be discarded). The |#1| +will be |\dimexpr <opt sign><digits>sp\relax|, from which one can get the +litteral (approximate) representation in points via |\the#1|. So |#1| can be +used anywhere \TeX{} expects a dimension (and there is no need in conditionals +to insert a |\relax|, and one should \emph{not} do it), and to print its value +one uses \fbox{\csa{the\#1}}. The chosen representation guarantees exact +incrementation with no rounding errors accumulating from converting into +points at each step. + + + + + + +If the list argument to \csbxint{For} (or \csbxint{For*}) is \csbxint{rationals} +or more generally +\csbxint{rationals}|[||start|\allowbreak|+|\allowbreak|delta||]| (\emph{within + braces}!), then \csbxint{For} does an infinite iteration where |#1| (or |#2|, +\dots, |#9|) will run through the arithmetic sequence of \xintfracname fractions +with initial value |start| and increment |delta| (default values: |start=1/1|, +|delta=1/1|). This loop works \emph{only with \xintfracname loaded}. if the +optional argument is present it must contain both of them, and they may be given +in any of the formats recognized by \xintfracname (fractions, decimal +numbers, numbers in scientific notations, numerators and denominators in +scientific notation, etc...) , or as macros or count registers (if they are +short integers). The |#1| (or |#2|, \dots, |#9|) will be an |a/b| fraction +(without a |[n]| part), where +the denominator |b| is the product of the denominators of +|start| and |delta| (for reasons of speed |#1| is not reduced to irreducible +form, and for another reason explained later |start| and |delta| are not put +either into irreducible form; the input may use explicitely \csa{xintIrr} to +achieve that). +\begin{everbatim*} +\begingroup\small +\noindent\parbox{\dimexpr\linewidth-3em}{\color[named]{OrangeRed}% +\xintFor #1 in {\xintrationals [10/21+1/21]} \do +{#1=\xintifInt {#1} + {\textcolor{blue}{\xintTrunc{10}{#1}}} + {\xintTrunc{10}{#1}}% display in blue if an integer + \xintifGt {#1}{1.123}{\xintBreakFor}{, }% + }} +\endgroup\smallskip +\end{everbatim*} + +\smallskip The example above confirms that computations are done exactly, and +illustrates that the two initial (reduced) denominators are not multiplied when +they are found to be equal. It is thus recommended to input |start| and |delta| +with a common smallest possible denominator, or as fixed point numbers with the +same numbers of digits after the decimal mark; and this is also the reason why +|start| and |delta| are not by default made irreducible. As internally the +computations are done with numerators and denominators completely expanded, one +should be careful not to input numbers in scientific notation with exponents in +the hundreds, as they will get converted into as many zeroes. + +\begin{everbatim*} +\noindent\parbox{\dimexpr.7\linewidth}{\raggedright +\xintFor #1 in {\xintrationals [0.000+0.125]} \do +{\edef\tmp{\xintTrunc{3}{#1}}% + \xintifInt {#1} + {\textcolor{blue}{\tmp}} + {\tmp}% + \xintifGt {#1}{2}{\xintBreakFor}{, }% + }}\smallskip +\end{everbatim*} + +We see here that \csbxint{Trunc} outputs (deliberately) zero as $0$, not (here) +$0.000$, the idea being not to lose the information that the truncated thing was +truly zero. Perhaps this behaviour should be changed? or made optional? Anyhow +printing of fixed points numbers should be dealt with via dedicated packages +such as |numprint| or |siunitx|.\par + + +\subsection{\csh{xintForpair}, \csh{xintForthree}, \csh{xintForfour}}\label{xintForpair}\label{xintForthree}\label{xintForfour} + +The syntax\ntype{on} is illustrated in this +example. The notation is the usual one for |n|-uples, with parentheses and +commas. Spaces around commas and parentheses are ignored. +% +\begin{everbatim*} +{\centering\begin{tabular}{cccc} + \xintForpair #1#2 in { ( A , a ) , ( B , b ) , ( C , c ) } \do {% + \xintForpair #3#4 in { ( X , x ) , ( Y , y ) , ( Z , z ) } \do {% + $\Biggl($\begin{tabular}{cc} + -#1- & -#3-\\ + -#4- & -#2-\\ + \end{tabular}$\Biggr)$&}\\\noalign{\vskip1\jot}}% +\end{tabular}\\} +\end{everbatim*} + +\csbxint{Forpair} must be followed by either |#1#2|, |#2#3|, |#3#4|, \dots, or +|#8#9| with |#1| usable as an alias for |#1#2|, |#2| as alias for |#2#3|, +etc \dots\ and similarly for \csbxint{Forthree} (using |#1#2#3| or simply +|#1|, |#2#3#4| or simply |#2|, \dots) and \csbxint{Forfour} (with |#1#2#3#4| +etc\dots). + +Nesting works as long as the macro parameters are distinct among |#1|, |#2|, +..., |#9|. A macro which expands to an \csa{xintFor} or a +\csa{xintFor(pair,three,four)} can be used in another one with no constraint +about using distinct macro parameters. + +|\par| tokens are accepted in both the comma separated list and the +replacement text. + + +\subsection{\csh{xintAssign}}\label{xintAssign} + +\csa{xintAssign}\meta{braced things}\csa{to}% +\meta{as many cs as they are things} %\ntype{{(f$\to$\lowast [x)}{\lowast N}} +% +defines (without checking if something gets overwritten) the control sequences +on the right of \csa{to} to expand to the successive tokens or braced items +located to the left of \csa{to}. \csa{xintAssign} is not an expandable macro. + +\fexpan sion is first applied to the material in front of \csa{xintAssign} +which is fetched as one argument if it is braced. Then the expansion of this +argument is examined and successive items are assigned to the macros following +|\to|. There must be exactly as many macros as items. No check is done. The +macro assignments are done with removal of one level of brace pairs from each +item. + +After the initial \fexpan sion, each assigned (brace-stripped) item will be +expanded according to the setting of the optional parameter. + +For example |\xintAssign [e]...| means that all assignments are done using +|\edef|. With |[f]| the assignments will be made using +\hyperref[fdef]{\ttfamily\char92fdef}. The default is simply to make the +definitions with |\def|, corresponding to an empty optional paramter |[]|. +Possibilities for the optional parameter are: |[], [g], [e], [x], [o], [go], +[oo], [goo], [f], [gf]|. For example |[oo]| means a double expansion. +\begin{everbatim*} +\xintAssign \xintiiDivision{1000000000000}{133333333}\to\Q\R +\meaning\Q\newline +\meaning\R\newline +\xintAssign {{\xintiiDivision{1000000000000}{133333333}}}\to\X +\meaning\X\newline +\xintAssign [oo]{{\xintiiDivision{1000000000000}{133333333}}}\to\X +\meaning\X\newline +\xintAssign \xintiiPow{7}{13}\to\SevenToThePowerThirteen +\meaning\SevenToThePowerThirteen\par +\end{everbatim*} + +Two special cases: +\begin{itemize}[nosep] +\item if after this initial expansion no brace is found immediately after + \csa{xintAssign}, it is assumed that there is only one control sequence + following |\to|, and this control sequence is then defined via |\def| (or + what is set-up by the optional parameter) to expand to the material between + \csa{xintAssign} and \csa{to}. +\item if the material between \csa{xintAssign} and |\to| is enclosed in two + brace pairs, the first brace pair is removed, then the \fexpan sion is + immediately stopped by the inner brace pair, hence \csa{xintAssign} now + finds a unique item and thus defines only a single macro to be this item, + which is now stripped of the second pair of braces. +\end{itemize} + + +\emph{Note:} prior to release |1.09j|, |\xintAssign| did an |\edef| by default +for each item assignment but it now does |\def| corresponding to no or empty +optional parameter. + +It is allowed for the successive braced items to be separated by spaces. They +are removed during the assignments. But if a single macro is defined (which +happens if the argument after \fexpan sion does not start with a brace), +naturally the scooped up material has all intervening spaces, as it is +considered a +single item. But an upfront initial space will have been absorbed by \fexpan +sion. +\begin{everbatim*} +\def\X{ {a} {b} {c} {d} }\def\Y { u {a} {b} {c} {d} } +\xintAssign\X\to\A\B\C\D +\xintAssign\Y\to\Z +\meaning\A, \meaning\B, \meaning\C, \meaning\D+++\newline +\meaning\Z+++\par +\end{everbatim*} +As usual successive space characters in input make for a single \TeX\ space token. + + +\subsection{\csh{xintAssignArray}}\label{xintAssignArray} + +\xintAssignArray \xintBezout {1000}{113}\to\Bez + +\csa{xintAssignArray}\meta{braced things}\csa{to}\csa{myArray} +% +%\ntype{{(f$\to$\lowast x)}N} +% +first expands fully what comes immediately after |\xintAssignArray| and +expects to find a list of braced things |{A}{B}...| (or tokens). It then +defines \csa{myArray} as a macro with one parameter, such that \csa{myArray\x} +expands to give the |x|th braced thing of this original +list (the argument \texttt{\x} itself is fed to a |\numexpr| by |\myArray|, +and |\myArray| expands in two steps to its output). With |0| as parameter, +\csa{myArray}|{0}| returns the number |M| of elements of the array so that the +successive elements are \csa{myArray}|{1}|, \dots, \csa{myArray}|{M}|. +% +\leftedline{|\xintAssignArray \xintBezout {1000}{113}\to\Bez|} will set +|\Bez{0}| to \dtt{\Bez0}, |\Bez{1}| to \dtt{\Bez1}, |\Bez{2}| to +\dtt{\Bez2}, and |\Bez{3}| to \dtt{\Bez3}: +\dtt{$\Bez1\times1000+\Bez2\times113=\Bez3$.} +This macro is incompatible with expansion-only contexts. + +\csa{xintAssignArray} admits an optional parameter, for example +|\xintAssignArray [e]| means that the definitions of the macros will be made +with |\edef|. The empty optional parameter (default) means that definitions +are done with |\def|. Other possibilities: |[], [o], [oo], [f]|. Contrarily to +\csbxint{Assign} one can not use the |g| here to make the definitions global. +For this, one should rather do |\xintAssignArray| within a group starting with +|\globaldefs 1|. + + +\subsection{\csh{xintDigitsOf}}\label{xintDigitsOf} + +This is a synonym for \csbxint{AssignArray},\ntype{fN} to be used to define +an array giving all the digits of a given (positive, else the minus sign will +be treated as first item) number. +\begingroup\xintDigitsOf\xintiiPow {7}{500}\to\digits +% +\leftedline{|\xintDigitsOf\xintiiPow {7}{500}\to\digits|} +\noindent $7^{500}$ has |\digits{0}=|\digits{0} digits, and the 123rd among them +(starting from the most significant) is +|\digits{123}=|\digits{123}. +\endgroup + +\subsection{\csh{xintRelaxArray}}\label{xintRelaxArray} + +\csa{xintRelaxArray}\csa{myArray} %\ntype{N} +% +(globally) sets to \csa{relax} all macros which were defined by the previous +\csa{xintAssignArray} with \csa{myArray} as array macro. + +\clearpage +\let\xinttoolsnameUp\undefined +\def\n{|{N}|} +\def\m{|{M}|} +\def\x{|{x}|} + +\csname ExamplesnameUp\endcsname +\section {Additional (old) examples with \xinttoolsname or \xintexprname or both} +\RaisedLabel{sec:examples} + +Note: \xintexprname.sty automatically loads \xinttoolsname.sty. + +The examples given here start to feel dated and are currently in need of some +rewrite to better illustrate newer features of the package. + + +\localtableofcontents + +\subsection{More examples with dummy variables} +\label{ssec:moredummies} + +These examples were first added to this manual at the time of the |1.1| +release (|2014/10/29|). + +\begin{everbatim*} +Prime numbers are always cool +\xinttheiiexpr seq((seq((subs((x/:m)?{(m*m>x)?{1}{0}}{-1},m=2n+1)) + ??{break(0)}{omit}{break(1)},n=1++))?{x}{omit}, + x=10001..[2]..10200)\relax +\end{everbatim*} + +The syntax in this last example may look a bit involved (...\@ and it is so I +admit). First |x/:m| computes |x modulo m| (this is the modulo with respect to +floored division). The |(x)?{yes}{no}| construct checks if |x| (which +\emph{must} be within parentheses) is true or false, i.e.\@ non zero or zero. It +then executes either the |yes| or the |no| branch, the non chosen branch is +\emph{not} evaluated. Thus if |m| divides |x| we are in the second (``false'') +branch. This gives a |-1|. This |-1| is the argument to a |??| branch which is +of the type |(y)??{y<0}{y=0}{y>0}|, thus here the |y<0|, i.e.\@, |break(0)| is +chosen. This |0| is thus given to another |?| which consequently chooses +|omit|, hence the number is not kept in the list. The numbers which survive +are the prime numbers. + +\begin{everbatim*} +The first Fibonacci number beyond |2^64|, |2^64|, and the index are respectively +\xinttheiiexpr subs(iterr(0,1;(@1>N)?{break(@1,N,i)}{@1+@2},i=1++),N=2^64)\relax. +\end{everbatim*} + +% A006877 In the `3x+1' problem, these values for the starting value set new +% records for number of steps to reach 1. (Formerly M0748) 14 1, 2, 3, 6, 7, +% 9, 18, 25, 27, 54, 73, 97, 129, 171, 231, 313, 327, 649, 703, 871, 1161, +% 2223, 2463, 2919, 3711, 6171, 10971, 13255, 17647, 23529, 26623, 34239, +% 35655, 52527, 77031, 106239, 142587, 156159, 216367, 230631, 410011, 511935, +% 626331, 837799 + +One more recursion: +\begin{everbatim*} +\def\syr #1{\xinttheiiexpr + rseq(#1; (@<=1)?{break(i)}{odd(@)?{3@+1}{@//2}},i=0++)\relax} +The 3x+1 problem: \syr{231}\par +\end{everbatim*} + +OK, a final one:% +\begin{everbatim*} +\def\syrMax #1{\xintiiexpr iterr(#1,#1;even(i)? + {(@2<=1)?{break(@1,i//2)} + {odd(@2)?{3@2+1}{@2//2}}} + {(@1>@2)?{@1}{@2}},i=0++)\relax } +With initial value 1161, the maximal intermediate value and the number of steps +needed to reach 1 are respectively \syrMax{1161}.\par +\end{everbatim*} + +Look at the + \hyperlink{BrentSalamin}{Brent-Salamin algorithm implementation} for a more + interesting recursion. + +% \begin{everbatim*} +% \newcommand\Factors [1]{\xinttheiiexpr +% subs(seq((i/:3=1)?{omit}{[L][i]},i=0..len(L)-1), +% L=rseq(#1;(p^2>[@][0])?{([@][0]>1)?{break(1,[@][0],1)}{abort}} +% {(([@][0])/:p)?{omit} +% {iter(([@][0])//p; (@/:p)?{break(@,p,e)}{@//p},e=1++)}},p=2++))\relax } +% \Factors {41^4*59^2*29^3*13^5*17^8*29^2*59^4*37^6} +% \end{everbatim*} + +% This might look a bit scary, I admit.% +% % +% \footnote{Look at the +% \hyperlink{BrentSalamin}{Brent-Salamin algorithm implementation} for a much +% saner example.} +% % + +% \xintexprname has minimal tools and +% is obstinate about doing everything expandably! We are hampered by absence of a +% notion of ``nuple''. The algorithm divides |N| by |2| until no more possible, +% then by |3|, then by |4| (which is silly), then by |5|, then by |6| (silly +% again), \dots. + +% The variable |L=rseq(#1;...)| expands, if one follows the steps, to a comma +% separated list starting with the initial (evaluated) |N=#1| and then +% pseudo-triplets where the first item is |N| trimmed of small primes, the +% second item is the last prime divisor found, and the third item is its +% exponent in original |N|. + +% The algorithm needs to keep handy the last computed quotient by prime powers, +% hence all of them, but at the very end it will be cleaner to get rid of them +% (this corresponds to the first line in the code above). This is achieved in a +% cumbersome inefficient way; indeed each item extraction |[L][i]| is costly: it +% is not like accessing an array stored in memory, due to expandability, nothing +% can be stored in memory! Nevertheless, this step could be done here in a far +% less inefficient manner if there was a variant of |seq| which, in the spirit +% of \csbxint{iloopindex}, would know how many steps it had been through so far. +% This is a feature to be added to |\xintexpr|! (as well as a |++| construct +% allowing a non unit step). + +% Notice that in |iter(([@][0])//p;| the |@| refers to the previous triplet (or +% in the first step to |N|), but the latter |@| showing up in |(@/:p)?| refers +% to the previous value computed by |iter|. + +% \begin{snugframed} +% Parentheses are essential in |..([y][0])| else the parser will see |..[| and +% end up in ultimate confusion, and also in |([@][0])/:p| else the parser will +% see the itemwise operator |]/| on lists and again be very confused (I could +% implement a |]/:| on lists, but in this situation this would also be very +% confusing to the parser.) +% \end{snugframed} + +% See \autoref{ssec:factorize} for a routine |\Factorize| written directly with +% \xintname macros. Last time I checked |\Factors| was about seven times slower +% than |\Factorize| in test cases such as +% |16246355912554185673266068721806243461403654781833| and others. Among the +% various things explaining the speed difference, there is fact that the +% |\Factorize| algorithm step by increments of two, not one, and also it divides +% only once, obtaining quotient and remainder in one go. These two things +% already make for a speed-up factor of about four. Thus, |\Factors| is not +% completely inefficient in comparison, and was quite easier to come up with +% than |\Factorize|. + +\subsection{Completely expandable prime test} +\label{ssec:primesI} + +Let us now construct a completely expandable macro which returns $1$ if its +given input is prime and $0$ if not: +\everb|@ +\def\remainder #1#2{\the\numexpr #1-(#1/#2)*#2\relax } +\def\IsPrime #1% + {\xintANDof {\xintApply {\remainder {#1}}{\xintSeq {2}{\xintiiSqrt{#1}}}}} +| + +This uses \csbxint{iiSqrt} and assumes its input is at least $5$. Rather than +\xintname's own \csbxint{iiRem} we used a quicker |\numexpr| expression as we +are dealing with short integers. Also we used \csbxint{ANDof} which will +return $1$ only if all the items are non-zero. The macro is a bit +silly with an even input, ok, let's enhance it to detect an even input: +\everb|@ +\def\IsPrime #1% + {\xintiiifOdd {#1} + {\xintANDof % odd case + {\xintApply {\remainder {#1}} + {\xintSeq [2]{3}{\xintiiSqrt{#1}}}% + }% + } + {\xintifEq {#1}{2}{1}{0}}% + } +| + +We used the \xintname expandable tests (on big integers or fractions) +in order for |\IsPrime| to be \fexpan dable. + +Our integers are short, but without |\expandafter|'s with +|\@firstoftwo|, % @ n'est plus actif dans le dtx 1.1 ! +or some other related techniques, +direct use of |\ifnum..\fi| tests is dangerous. So to make the macro more +efficient we are going to use the expandable tests provided by the package +\href{http://ctan.org/pkg/etoolbox}{etoolbox}% +% +\footnote{\url{http://ctan.org/pkg/etoolbox}}. +% +The macro becomes: +% +\everb|@ +\def\IsPrime #1% + {\ifnumodd {#1} + {\xintANDof % odd case + {\xintApply {\remainder {#1}}{\xintSeq [2]{3}{\xintiiSqrt{#1}}}}} + {\ifnumequal {#1}{2}{1}{0}}} +| + +In the odd case however we have to assume the integer is at least $7$, as +|\xintSeq| generates an empty list if |#1=3| or |5|, and |\xintANDof| returns +$1$ when supplied an empty list. Let us ease up a bit |\xintANDof|'s work by +letting it work on only $0$'s and $1$'s. We could use: +% +\everb|@ +\def\IsNotDivisibleBy #1#2% + {\ifnum\numexpr #1-(#1/#2)*#2=0 \expandafter 0\else \expandafter1\fi} +| +\noindent +where the |\expandafter|'s are crucial for this macro to be \fexpan dable and +hence work within the applied \csbxint{ANDof}. Anyhow, now that we have loaded +\href{http://ctan.org/pkg/etoolbox}{etoolbox}, we might as well use: +% +\everb|@ +\newcommand{\IsNotDivisibleBy}[2]{\ifnumequal{#1-(#1/#2)*#2}{0}{0}{1}} +| +\noindent +Let us enhance our prime macro to work also on the small primes: +\everb|@ +\newcommand{\IsPrime}[1] % returns 1 if #1 is prime, and 0 if not + {\ifnumodd {#1} + {\ifnumless {#1}{8} + {\ifnumequal{#1}{1}{0}{1}}% 3,5,7 are primes + {\xintANDof + {\xintApply + { \IsNotDivisibleBy {#1}}{\xintSeq [2]{3}{\xintiiSqrt{#1}}}}% + }}% END OF THE ODD BRANCH + {\ifnumequal {#1}{2}{1}{0}}% EVEN BRANCH +} +| + +The input is still assumed positive. There is a deliberate blank before +\csa{IsNotDivisibleBy} to use this feature of \csbxint{Apply}: a space stops the +expansion of the applied macro (and disappears). This expansion will be done by +\csbxint{ANDof}, which has been designed to skip everything as soon as it finds +a false (i.e.\@ zero) input. This way, the efficiency is considerably improved. + +We did generate via the \csbxint{Seq} too many potential divisors though. Later +sections give two variants: one with \csbxint{iloop} (\autoref{ssec:primesII}) +which is still expandable and another one (\autoref{ssec:primesIII}) which is a +close variant of the |\IsPrime| code above but with the \csbxint{For} loop, thus +breaking expandability. The \hyperref[ssec:primesII]{xintiloop variant} does not +first evaluate the integer square root, the \hyperref[ssec:primesIII]{xintFor + variant} still does. I did not compare their efficiencies. + + +Let us construct with this expandable primality test a table of the prime +numbers up to $1000$. We need to count how many we have in order to know how +many tab stops one shoud add in the last row.% +% +\footnote{although a tabular row may have less tabs than in the + preamble, there is a problem with the \char`\|\space\space vertical + rule, if one does that.} +% +There is some subtlety for this +last row. Turns out to be better to insert a |\\| only when we know for sure we +are starting a new row; this is how we have designed the |\OneCell| macro. And +for the last row, there are many ways, we use again |\xintApplyUnbraced| but +with a macro which gobbles its argument and replaces it with a tabulation +character. The \csbxint{For*} macro would be more elegant here. +% +\everb?@ +\newcounter{primecount} +\newcounter{cellcount} +\newcommand{\NbOfColumns}{13} +\newcommand{\OneCell}[1]{% + \ifnumequal{\IsPrime{#1}}{1} + {\stepcounter{primecount} + \ifnumequal{\value{cellcount}}{\NbOfColumns} + {\\\setcounter{cellcount}{1}#1} + {&\stepcounter{cellcount}#1}% + } % was prime + {}% not a prime, nothing to do +} +\newcommand{\OneTab}[1]{&} +\begin{tabular}{|*{\NbOfColumns}{r}|} +\hline +2 \setcounter{cellcount}{1}\setcounter{primecount}{1}% + \xintApplyUnbraced \OneCell {\xintSeq [2]{3}{999}}% + \xintApplyUnbraced \OneTab + {\xintSeq [1]{1}{\the\numexpr\NbOfColumns-\value{cellcount}\relax}}% + \\ +\hline +\end{tabular} +There are \arabic{primecount} prime numbers up to 1000. +? + +The table has been put in \hyperref[primesupto1000]{float} which appears +\vpageref{primesupto1000}. +We had to be careful to use in the last row \csbxint{Seq} with its optional +argument |[1]| so as to not generate a decreasing sequence from |1| to |0|, but +really an empty sequence in case the row turns out to already have all its +cells (which doesn't happen here but would with a number of columns dividing +$168$). +% +\newcommand{\IsNotDivisibleBy}[2]{\ifnumequal{#1-(#1/#2)*#2}{0}{0}{1}} + +\newcommand{\IsPrime}[1] + {\ifnumodd {#1} + {\ifnumless {#1}{8} + {\ifnumequal{#1}{1}{0}{1}}% 3,5,7 are primes + {\xintANDof + {\xintApply + { \IsNotDivisibleBy {#1}}{\xintSeq [2]{3}{\xintiiSqrt{#1}}}}% + }}% END OF THE ODD BRANCH + {\ifnumequal {#1}{2}{1}{0}}% EVEN BRANCH +} + +\newcounter{primecount} +\newcounter{cellcount} +\newcommand{\NbOfColumns}{13} +\newcommand{\OneCell}[1] + {\ifnumequal{\IsPrime{#1}}{1} + {\stepcounter{primecount} + \ifnumequal{\value{cellcount}}{\NbOfColumns} + {\\\setcounter{cellcount}{1}#1} + {&\stepcounter{cellcount}#1}% + } % was prime + {}% not a prime nothing to do +} +\newcommand{\OneTab}[1]{&} +\begin{figure*}[ht!] + \centering + \phantomsection\label{primesupto1000} + \begin{tabular}{|*{\NbOfColumns}{r}|} + \hline + 2\setcounter{cellcount}{1}\setcounter{primecount}{1}% + \xintApplyUnbraced \OneCell {\xintSeq [2]{3}{999}}% + \xintApplyUnbraced \OneTab + {\xintSeq [1]{1}{\the\numexpr\NbOfColumns-\value{cellcount}\relax}}% + \\ + \hline + \end{tabular} +\smallskip +\centeredline{There are \arabic{primecount} prime numbers up to 1000.} +\end{figure*} + +\subsection{Another completely expandable prime test} +\label{ssec:primesII} + +The |\IsPrime| macro from \autoref{ssec:primesI} checked expandably if a (short) +integer was prime, here is a partial rewrite using \csbxint{iloop}. We use the +|etoolbox| expandable conditionals for convenience, but not everywhere as +|\xintiloopindex| can not be evaluated while being braced. This is also the +reason why |\xintbreakiloopanddo| is delimited, and the next macro +|\SmallestFactor| which returns the smallest prime factor examplifies that. One +could write more efficient completely expandable routines, the aim here was only +to illustrate use of the general purpose \csbxint{iloop}. A little table giving +the first values of |\SmallestFactor| follows, its coding uses \csbxint{For}, +which is described later; none of this uses count registers. +% + + +\begin{everbatim*} +% clean up possible left-over mess from previous examples +\let\IsPrime\undefined \let\SmallestFactor\undefined +\newcommand{\IsPrime}[1] % returns 1 if #1 is prime, and 0 if not + {\ifnumodd {#1} + {\ifnumless {#1}{8} + {\ifnumequal{#1}{1}{0}{1}}% 3,5,7 are primes + {\if + \xintiloop [3+2] + \ifnum#1<\numexpr\xintiloopindex*\xintiloopindex\relax + \expandafter\xintbreakiloopanddo\expandafter1\expandafter.% + \fi + \ifnum#1=\numexpr (#1/\xintiloopindex)*\xintiloopindex\relax + \else + \repeat 00\expandafter0\else\expandafter1\fi + }% + }% END OF THE ODD BRANCH + {\ifnumequal {#1}{2}{1}{0}}% EVEN BRANCH +}% +\catcode`_ 11 +\newcommand{\SmallestFactor}[1] % returns the smallest prime factor of #1>1 + {\ifnumodd {#1} + {\ifnumless {#1}{8} + {#1}% 3,5,7 are primes + {\xintiloop [3+2] + \ifnum#1<\numexpr\xintiloopindex*\xintiloopindex\relax + \xint_afterfi{\xintbreakiloopanddo#1.}% + \fi + \ifnum#1=\numexpr (#1/\xintiloopindex)*\xintiloopindex\relax + \xint_afterfi{\expandafter\xintbreakiloopanddo\xintiloopindex.}% + \fi + \iftrue\repeat + }% + }% END OF THE ODD BRANCH + {2}% EVEN BRANCH +}% +\catcode`_ 8 +{\centering + \begin{tabular}{|c|*{10}c|} + \hline + \xintFor #1 in {0,1,2,3,4,5,6,7,8,9}\do {&\bfseries #1}\\ + \hline + \bfseries 0&--&--&2&3&2&5&2&7&2&3\\ + \xintFor #1 in {1,2,3,4,5,6,7,8,9}\do + {\bfseries #1% + \xintFor #2 in {0,1,2,3,4,5,6,7,8,9}\do + {&\SmallestFactor{#1#2}}\\}% + \hline + \end{tabular}\par +} +\end{everbatim*} + +\subsection{Miller-Rabin Pseudo-Primality expandably} +\label{ssec:PrimesIV} + + +% At the time of writing, the code at the link above is still the version from +% April 2016 and it needed some hacks to get recursive (pseudo)-functions +% defined. Since |1.2h| of |2016/11/20| there is \csbxint{NewFunction} which +% allows us here to avoid such internal hacking. + +% And since |1.3| of |2018/03/01|, it is possible to use \csbxint{defiifunc} +% also for recursive definitions, so we use it here, but we can benefit from it +% only for modular exponentiation as the rest of the code uses |iter| or |break| +% statements which are not yet compatible with \csbxint{defiifunc}. + +The |isPseudoPrime(n)| is usable in \csbxint{iiexpr}-essions and establishes +if its (positive) argument is a Miller-Rabin PseudoPrime to the bases $2, 3, +5, 7, 11, 13, 17$. If this is true and $n<341550071728321$ (which has 15 +digits) then $n$ really is a prime number. + +Similarly $n=3825123056546413051$ (19 digits) is the smallest composite number +which is a strong pseudo prime for bases $2, 3, 5, 7, 11, 13, 17, 19$ and +$23$. It is easy to extend the code below to include these additional tests +(we could make the list of tested bases an argument too, now that I think +about it.) + +For more information see + \centeredline{\url{https://en.wikipedia.org/wiki/Miller%E2%80%93Rabin_primality_test#Deterministic_variants_of_the_test}} + and +\centeredline{\url{http://primes.utm.edu/prove/prove2_3.html}} + +In particular, according to \textsc{Jaeschke} \emph{On strong pseudoprimes to + several bases,} Math. Comp., 61 (1993) 915-926, if $n < 4,759,123,141$ it is +enough to establish Rabin-Miller pseudo-primality to bases $a = 2, 7, 61$ to +prove that $n$ is prime. This range is enough for \TeX\ numbers and we could +then write a very fast expandable primality test for such numbers using only +|\numexpr|. Left as an exercise\dots + +\begin{everbatim*} +% I -------------------------------- Modular Exponentiation +% Computes x^m modulo n (with m non negative). +% We will always use it with 1 < x < n +% +% With xint 1.4 we should use ? and ?? (although in the case at hand ifsgn() +% and if() would be ok but I should not say that). +% +\xintdefiifunc powmod_a(x, m, n) := + isone(m)? + % m=1, return x modulo n + { x /: n } + % m > 1 test if odd or even and do recursive call + { odd(m)? { x*sqr(powmod_a(x, m//2, n)) /: n } + { sqr(powmod_a(x, m//2, n)) /: n } + } + ; +\xintdefiifunc powmod(x, m, n) := (m)?{powmod_a(x, m, n)}{1}; + +%% Syntax used before xint 1.4: +% \xintdefiifunc powmod_a(x, m, n) := +% ifone(m, +% % m=1, return x modulo n +% x /: n, +% % m > 1 test if odd or even and do recursive call +% if(odd(m), (x*sqr(powmod_a(x, m//2, n))) /: n, +% sqr(powmod_a(x, m//2, n)) /: n +% ) +% ); +% \xintdefiifunc powmod(x, m, n) := if(m, powmod_a(x, m, n), 1); + +% II ------------------------------ Miller-Rabin compositeness witness + +% n=2^k m + 1 with m odd and k at least 1 + +% Choose 1<x<n. +% compute y=x^m modulo n +% if equals 1 we can't say anything +% if equals n-1 we can't say anything +% else put j=1, and +% compute repeatedly the square, incrementing j by 1 each time, +% thus always we have y^{2^{j-1}} +% -> if at some point n-1 mod n found, we can't say anything and break out +% -> if however we never find n-1 mod n before reaching +% z=y^{2^{k-1}} with j=k +% we then have z^2=x^{n-1}. + % Suppose z is not -1 mod n. If z^2 is 1 mod n, then n can be prime only if + % z is 1 mod n, and we can go back up, until initial y, and we have already + % excluded y=1. Thus if z is not -1 mod n and z^2 is 1 then n is not prime. + % But if z^2 is not 1, then n is not prime by Fermat. Hence (z not -1 mod n) + % implies (n is composite). (Miller test) + +% let's use again xintexpr indecipherable (except to author) syntax. Of course +% doing it with macros only would be faster. + +% Here \xintdefiifunc is not usable because not compatible with iter, break, ... +% but \xintNewFunction comes to the rescue. + +\xintNewFunction{isCompositeWitness}[4]{% x=#1, n=#2, m=#3, k=#4 + subs((y==1)?{0} + {iter(y;(j==#4)?{break(!(@==#2-1))} + {(@==#2-1)?{break(0)}{sqr(@)/:#2}},j=1++)} + ,y=powmod(#1,#3,#2))} + +% added note (2018/03/07) it is possible in the above that m=#3 is never +% zero, so we should rather call powmod_a for a small gain, but I don't +% have time to re-read the code comments and settle this. + +% III ------------------------------------- Strong Pseudo Primes + +% cf +% http://oeis.org/A014233 +% <http://mathworld.wolfram.com/Rabin-MillerStrongPseudoprimeTest.html> +% <http://mathworld.wolfram.com/StrongPseudoprime.html> + +% check if positive integer <49 si a prime. +% 2,3,5,7,11,13,17,19,23,29,31,37,41,43,47 +\def\IsVerySmallPrime #1% + {\ifnum#1=1 \xintdothis0\fi + \ifnum#1=2 \xintdothis1\fi + \ifnum#1=3 \xintdothis1\fi + \ifnum#1=5 \xintdothis1\fi + \ifnum#1=\numexpr (#1/2)*2\relax\xintdothis0\fi + \ifnum#1=\numexpr (#1/3)*3\relax\xintdothis0\fi + \ifnum#1=\numexpr (#1/5)*5\relax\xintdothis0\fi + \xintorthat 1} + +\xintNewFunction{isPseudoPrime}[1]{% n = #1 + (#1<49)?% use ? syntax to evaluate only what is needed +% prior to 1.4 we had \xintthe#1 here but the actual tokens represented +% by this #1 when isPseudoPrime() function expands have changed and +% the correct way is now \xintiieval{#1} to hand over explicit digits to +% the \IsVerySmallPrime macro. + {\IsVerySmallPrime{\xintiieval{#1}}} + {(even(#1))? + {0} + {subs(% + % L expands to two values m, k hence isCompositeWitness does get + % its four variables x, n, m, k + isCompositeWitness(2, #1, L)? + {0}% + {isCompositeWitness(3, #1, L)? + {0}% + {isCompositeWitness(5, #1, L)? + {0}% + {isCompositeWitness(7, #1, L)? + {0}% +% above enough for N<3215031751 hence all TeX numbers + {isCompositeWitness(11, #1, L)? + {0}% +% above enough for N<2152302898747, hence all 12-digits numbers + {isCompositeWitness(13, #1, L)? + {0}% +% above enough for N<3474749660383 + {isCompositeWitness(17, #1, L)? + {0}% +% above enough for N<341550071728321 + {1}% + }% not needed to comment-out end of lines spaces inside + }% \xintexpr but this is too much of a habit for me with TeX! + }% I left some after the ? characters. + }% + }% + }% this computes (m, k) such that n = 2^k m + 1, m odd, k>=1 + , L=iter(#1//2;(even(@))?{@//2}{break(@,k)},k=1++))% + }% + }% +} + +% if needed: +%\def\IsPseudoPrime #1{\xinttheiiexpr isPseudoPrime(#1)\relax} + +\noindent The smallest prime number at least equal to 3141592653589 is +\xintiiexpr + seq(isPseudoPrime(3141592653589+n)? + {break(3141592653589+n)}{omit}, n=0++)\relax. +% we could not use 3141592653589++ syntax because it works only with TeX numbers +\par +\end{everbatim*} + + + + + +\subsection{A table of factorizations} +\label{ssec:factorizationtable} + +As one more example with \csbxint{iloop} let us use an alignment to display the +factorization of some numbers. The loop will actually only play a minor r\^ole +here, just handling the row index, the row contents being almost entirely +produced via a macro |\factorize|. The factorizing macro does not use +|\xintiloop| as it didn't appear to be the convenient tool. As |\factorize| will +have to be used on |\xintiloopindex|, it has been defined as a delimited macro. + +To spare some fractions of a second in the compilation time of this document +(which has many many other things to do), \number"7FFFFFED{} and +\number"7FFFFFFF, which turn out to be prime numbers, are not given to +|factorize| but just typeset directly; this illustrates use of +\csbxint{iloopskiptonext}. + +The code next generates a \hyperref[floatfactorize]{table} which has +been made into a float appearing \vpageref{floatfactorize}. Here is now +the code for factorization; the conditionals use the package provided +|\xint_firstoftwo| and |\xint_secondoftwo|, one could have employed +rather \LaTeX{}'s own |\@firstoftwo| and |\@secondoftwo|, or, simpler +still in \LaTeX{} context, the |\ifnumequal|, |\ifnumless| \dots, +utilities from the package |etoolbox| which do exactly that under the +hood. Only \TeX{} acceptable numbers are treated here, but it would be +easy to make a translation and use the \xintname macros, thus extending +the scope to big numbers; naturally up to a cost in speed. + +The reason for some strange looking expressions is to avoid arithmetic overflow. + +\begin{everbatim*} +\catcode`_ 11 +\def\abortfactorize #1\xint_secondoftwo\fi #2#3{\fi} + +\def\factorize #1.{\ifnum#1=1 \abortfactorize\fi + \ifnum\numexpr #1-2=\numexpr ((#1/2)-1)*2\relax + \expandafter\xint_firstoftwo + \else\expandafter\xint_secondoftwo + \fi + {2&\expandafter\factorize\the\numexpr#1/2.}% + {\factorize_b #1.3.}}% + +\def\factorize_b #1.#2.{\ifnum#1=1 \abortfactorize\fi + \ifnum\numexpr #1-(#2-1)*#2<#2 + #1\abortfactorize + \fi + \ifnum \numexpr #1-#2=\numexpr ((#1/#2)-1)*#2\relax + \expandafter\xint_firstoftwo + \else\expandafter\xint_secondoftwo + \fi + {#2&\expandafter\factorize_b\the\numexpr#1/#2.#2.}% + {\expandafter\factorize_b\the\numexpr #1\expandafter.% + \the\numexpr #2+2.}}% +\catcode`_ 8 +\begin{figure*}[ht!] +\centering\phantomsection\label{floatfactorize}\normalcolor +\tabskip1ex +\centeredline{\vbox{\halign {\hfil\strut#\hfil&&\hfil#\hfil\cr\noalign{\hrule} + \xintiloop ["7FFFFFE0+1] + \expandafter\bfseries\xintiloopindex & + \ifnum\xintiloopindex="7FFFFFED + \number"7FFFFFED\cr\noalign{\hrule} + \expandafter\xintiloopskiptonext + \fi + \expandafter\factorize\xintiloopindex.\cr\noalign{\hrule} + \ifnum\xintiloopindex<"7FFFFFFE + \repeat + \bfseries \number"7FFFFFFF&\number "7FFFFFFF\cr\noalign{\hrule} +}}} +\centeredline{A table of factorizations} +\end{figure*} +\end{everbatim*} + +\subsection{Another table of primes} +\label{ssec:primesIII} + +As a further example, let us dynamically generate a tabular with the first $50$ +prime numbers after $12345$. First we need a macro to test if a (short) number +is prime. Such a completely expandable macro was given in \autoref{ssec:primesI}, +here we consider a variant which will be slightly more efficient. This new +|\IsPrime| has two parameters. The first one is a macro which it redefines to +expand to the result of the primality test applied to the second argument. For +convenience we use the \href{http://ctan.org/pkg/etoolbox}{etoolbox} wrappers to +various |\ifnum| tests, although here there isn't anymore the constraint of +complete expandability (but using explicit |\if..\fi| in tabulars has its +quirks); equivalent tests are provided by \xintname, but they have some overhead +as they are able to deal with arbitrarily big integers. + +\def\IsPrime #1#2% +{\edef\TheNumber {\the\numexpr #2}% positive integer + \ifnumodd {\TheNumber} + {\ifnumgreater {\TheNumber}{1} + {\edef\ItsSquareRoot{\xintiiSqrt \TheNumber}% + \xintFor ##1 in {\xintintegers [3+2]}\do + {\ifnumgreater {##1}{\ItsSquareRoot} + {\def#1{1}\xintBreakFor} + {}% + \ifnumequal {\TheNumber}{(\TheNumber/##1)*##1} + {\def#1{0}\xintBreakFor } + {}% + }} + {\def#1{0}}}% 1 is not prime + {\ifnumequal {\TheNumber}{2}{\def#1{1}}{\def#1{0}}}% +}% + +\everb|@ +\def\IsPrime #1#2% """color[named]{PineGreen}#1=\Result, #2=tested number (assumed >0).;! +{\edef\TheNumber {\the\numexpr #2}%"""color[named]{PineGreen} hence #2 may be a count or \numexpr.;! + \ifnumodd {\TheNumber} + {\ifnumgreater {\TheNumber}{1} + {\edef\ItsSquareRoot{\xintiiSqrt \TheNumber}% + \xintFor """color{red}##1;! in {"""color{red}\xintintegers;! [3+2]}\do + {\ifnumgreater {"""color{red}##1;!}{\ItsSquareRoot} """color[named]{PineGreen}% "textcolor{red}{##1} is a \numexpr.;! + {\def#1{1}\xintBreakFor} + {}% + \ifnumequal {\TheNumber}{(\TheNumber/##1)*##1} + {\def#1{0}\xintBreakFor } + {}% + }} + {\def#1{0}}}% 1 is not prime + {\ifnumequal {\TheNumber}{2}{\def#1{1}}{\def#1{0}}}% +} +| + +As we used \csbxint{For} inside a macro we had to double the |#| in its |#1| +parameter. Here is now the code which creates the prime table (the table has +been put in a \hyperref[primes]{float}, which should be found on page +\pageref{primes}): + +\everb?@ +\newcounter{primecount} +\newcounter{cellcount} +\begin{figure*}[ht!] + \centering + \begin{tabular}{|*{7}c|} + \hline + \setcounter{primecount}{0}\setcounter{cellcount}{0}% + \xintFor """color{red}#1;! in {"""color{red}\xintintegers;! [12345+2]} \do +"""color[named]{PineGreen}% "textcolor{red}{#1} is a \numexpr.;! + {\IsPrime\Result{#1}% + \ifnumgreater{\Result}{0} + {\stepcounter{primecount}% + \stepcounter{cellcount}% + \ifnumequal {\value{cellcount}}{7} + {"""color{red}\the#1;! \\\setcounter{cellcount}{0}} + {"""color{red}\the#1;! &}} + {}% + \ifnumequal {\value{primecount}}{50} + {\xintBreakForAndDo + {\multicolumn {6}{l|}{These are the first 50 primes after 12345.}\\}} + {}% + }\hline +\end{tabular} +\end{figure*} +? + +\begin{figure*}[ht!] + \centering\phantomsection\label{primes} + \begin{tabular}{|*{7}c|} + \hline + \setcounter{primecount}{0}\setcounter{cellcount}{0}% + \xintFor #1 in {\xintintegers [12345+2]} \do + {\IsPrime\Result{#1}% + \ifnumgreater{\Result}{0} + {\stepcounter{primecount}% + \stepcounter{cellcount}% + \ifnumequal {\value{cellcount}}{7} + {\the#1 \\\setcounter{cellcount}{0}} + {\the#1 &}} + {}% + \ifnumequal {\value{primecount}}{50} + {\xintBreakForAndDo + {\multicolumn {6}{l|}{These are the first 50 primes after 12345.}\\}} + {}% + }\hline +\end{tabular} +\end{figure*} + +\subsection{Factorizing again} +\label{ssec:factorize} + +Here is an \fexpan dable macro which computes the factors of an integer. It +uses the \xintname macros only. +\begin{everbatim*} +\catcode`\@ 11 +\let\factorize\relax +\newcommand\Factorize [1] + {\romannumeral0\expandafter\factorize\expandafter{\romannumeral-`0#1}}% +\newcommand\factorize [1]{\xintiiifOne{#1}{ 1}{\factors@a #1.{#1};}}% +\def\factors@a #1.{\xintiiifOdd{#1} + {\factors@c 3.#1.}% + {\expandafter\factors@b \expandafter1\expandafter.\romannumeral0\xinthalf{#1}.}}% +\def\factors@b #1.#2.{\xintiiifOne{#2} + {\factors@end {2, #1}}% + {\xintiiifOdd{#2}{\factors@c 3.#2.{2, #1}}% + {\expandafter\factors@b \the\numexpr #1+\@ne\expandafter.% + \romannumeral0\xinthalf{#2}.}}% +}% +\def\factors@c #1.#2.{% + \expandafter\factors@d\romannumeral0\xintiidivision {#2}{#1}{#1}{#2}% +}% +\def\factors@d #1#2#3#4{\xintiiifNotZero{#2} + {\xintiiifGt{#3}{#1} + {\factors@end {#4, 1}}% ultimate quotient is a prime with power 1 + {\expandafter\factors@c\the\numexpr #3+\tw@.#4.}}% + {\factors@e 1.#3.#1.}% +}% +\def\factors@e #1.#2.#3.{\xintiiifOne{#3} + {\factors@end {#2, #1}}% + {\expandafter\factors@f\romannumeral0\xintiidivision {#3}{#2}{#1}{#2}{#3}}% +}% +\def\factors@f #1#2#3#4#5{\xintiiifNotZero{#2} + {\expandafter\factors@c\the\numexpr #4+\tw@.#5.{#4, #3}}% + {\expandafter\factors@e\the\numexpr #3+\@ne.#4.#1.}% +}% +\def\factors@end #1;{\xintlistwithsep{, }{\xintRevWithBraces {#1}}}% +\catcode`@ 12 +\end{everbatim*} +The macro will be acceptably efficient only with numbers having somewhat small +prime factors. +\begin{everbatim} +\Factorize{16246355912554185673266068721806243461403654781833} +\end{everbatim} +\begingroup\fdef\Z +{\Factorize{16246355912554185673266068721806243461403654781833}} +\noindent{\small\dtt{\Z}} + + +It puts a little stress on the input save stack in order +not be bothered with previously gathered things.\footnote{2015/11/18 I have + not revisited this code for a long time, and perhaps I could improve it now + with some new techniques.} + +Its output is a comma separated list with the number first, then its prime +factors with multiplicity. Let's produce something prettier: +\begin{everbatim*} +\catcode`_ 11 +\def\ShowFactors #1{\expandafter + \ShowFactors_a\romannumeral-`0\Factorize{#1},\relax,\relax,} +\def\ShowFactors_a #1,{#1=\ShowFactors_b} +\def\ShowFactors_b #1,#2,{\if\relax#1\else#1^{#2}\expandafter\ShowFactors_b\fi} +\catcode`_ 8 +\end{everbatim*} +\begin{everbatim} +$$\ShowFactors{16246355912554185673266068721806243461403654781833}$$ +\end{everbatim} +$$\csname ShowFactors_a\expandafter\endcsname\Z,\relax,\relax,$$ +\endgroup + +If we only considered small integers, we could write pure |\numexpr| methods +which would be very much faster (especially if we had a table of small primes +prepared first) but still ridiculously slow compared to any non expandable +implementation, not to mention use of programming languages directly accessing +the CPU registers\dots + +\subsection{The Quick Sort algorithm illustrated}\label{ssec:quicksort} + +First a completely expandable macro which sorts a comma separated list of +numbers.% +% +\footnote{The code in earlier versions of this manual handled inputs composed + of braced items. I have switched to comma separated inputs on the occasion + of (link removed) + The version here is like + |code 3| on + (link removed) (which is about |3x| faster + than the earlier code it replaced in this manual) with a modification to + make it more efficient if the data has many repeated values. + + A faster routine (for sorting hundreds of values) is provided as |code 6| at + the link mentioned in the footnote, it is based on Merge Sort, but limited + to inputs which one can handle as \TeX{} dimensions.% + + This |code 6| could be extended to handle more general numbers, as + acceptable by \xintfracname. I have also written a non expandable version, + which is even faster, but this matters really only when handling hundreds or + rather thousands of values.} +% + +The |\QSx| macro expands its list argument, which may thus be a macro; its +comma separated items must expand to integers or decimal numbers or fractions +or scientific notation as acceptable to \xintfracname, but if an item is +itself some (expandable) macro, this macro will be expanded each time the item +is considered in a comparison test! This is actually good if the macro expands +in one step to the digits, and there are many many digits, but bad if the macro +needs to do many computations. Thus |\QSx| should be used with either explicit +numbers or with items being macros expanding in one step to the numbers +(particularly if these numbers are very big). + +If the interest is only in \TeX{} integers, then one should replace the +|\xintifCmp| macro with a suitable conditional, possibly helped by tools such as +|\ifnumgreater|, |\ifnumequal| and |\ifnumless| from +\href{http://ctan.org/pkg/etoolbox}{etoolbox} (\LaTeX{} only; I didn't see a +direct equivalent to |\xintifCmp|.) Or, if we are dealing with decimal numbers +with at most four+four digits, then one should use suitable |\ifdim| tests. +Naturally this will boost consequently the speed, from having skipped all the +overhead in parsing fractions and scientific numbers as are acceptable by +\xintfracname macros, and subsequent treatment. + +\begin{everbatim*} +% THE QUICK SORT ALGORITHM EXPANDABLY +% \usepackage{xintfrac} in the preamble (latex) +\makeatletter +% use extra safe delimiters +\catcode`! 3 \catcode`? 3 +\def\QSx {\romannumeral0\qsx }% +% first we check if empty list (else \qsx@finish will not find a comma) +\def\qsx #1{\expandafter\qsx@a\romannumeral-`0#1,!,?}% +\def\qsx@a #1{\ifx,#1\expandafter\qsx@abort\else + \expandafter\qsx@start\fi #1}% +\def\qsx@abort #1?{ }% +\def\qsx@start {\expandafter\qsx@finish\romannumeral0\qsx@b,}% +\def\qsx@finish ,#1{ #1}% +% +% we check if empty of single and if not pick up the first as Pivot: +\def\qsx@b ,#1#2,#3{\ifx?#3\xintdothis\qsx@empty\fi + \ifx!#3\xintdothis\qsx@single\fi + \xintorthat\qsx@separate {#1#2}{}{}{#1#2}#3}% +\def\qsx@empty #1#2#3#4#5{ }% +\def\qsx@single #1#2#3#4#5?{, #4}% +\def\qsx@separate #1#2#3#4#5#6,% +{% + \ifx!#5\expandafter\qsx@separate@done\fi + \xintifCmp {#5#6}{#4}% + \qsx@separate@appendtosmaller + \qsx@separate@appendtoequal + \qsx@separate@appendtogreater {#5#6}{#1}{#2}{#3}{#4}% +}% +% +\def\qsx@separate@appendtoequal #1#2{\qsx@separate {#2,#1}}% +\def\qsx@separate@appendtogreater #1#2#3{\qsx@separate {#2}{#3,#1}}% +\def\qsx@separate@appendtosmaller #1#2#3#4{\qsx@separate {#2}{#3}{#4,#1}}% +% +\def\qsx@separate@done\xintifCmp #1% + \qsx@separate@appendtosmaller + \qsx@separate@appendtoequal + \qsx@separate@appendtogreater #2#3#4#5#6#7?% +{% + \expandafter\qsx@f\expandafter {\romannumeral0\qsx@b #4,!,?}{\qsx@b #5,!,?}{#3}% +}% +% +\def\qsx@f #1#2#3{#2, #3#1}% +% +\catcode`! 12 \catcode`? 12 +\makeatother + +% EXAMPLE +\begingroup +\edef\z {\QSx {1.0, 0.5, 0.3, 1.5, 1.8, 2.0, 1.7, 0.4, 1.2, 1.4, + 1.3, 1.1, 0.7, 1.6, 0.6, 0.9, 0.8, 0.2, 0.1, 1.9}} +\meaning\z + +\def\a {3.123456789123456789}\def\b {3.123456789123456788} +\def\c {3.123456789123456790}\def\d {3.123456789123456787} +\oodef\z {\QSx { \a, \b, \c, \d}}% +% The space before \a to let it not be expanded during the conversion from CSV +% values to List. The \oodef expands exactly twice (via a bunch of \expandafter's) +\meaning\z +\endgroup +\end{everbatim*} (the spaces after \string\d, etc...\@ come from the use of the +|\meaning| primitive.) + +The choice of pivot as first element is bad if the list is already almost +sorted. Let's add a variant which will pick up the pivot index randomly. The +previous routine worked also internally with comma separated lists, but for a +change this one will use internally lists of braced items (the initial +conversion via \csbxint{CSVtoList} handles all potential spurious space +problems). + +\unless\ifxetex % pour tester compilation de xint.dtx avec xetex qui n'a pas + % \pdfuniformdeviate +\begin{everbatim*} +% QuickSort expandably on comma separated values with random choice of pivots +% ====> Requires availability of \pdfuniformdeviate <==== +% \usepackage{xintfrac, xinttools} in preamble +\makeatletter +\def\QSx {\romannumeral0\qsx }% This is a f-expandable macro. +% This converts from comma separated values on input and back on output. +% **** NOTE: these steps (and the other ones too, actually) are costly if input +% has thousands of items. +\def\qsx #1{\xintlistwithsep{, }% + {\expandafter\qsx@sort@a\expandafter{\romannumeral0\xintcsvtolist{#1}}}}% +% +% we check if empty or single or double and if not pick up the first as Pivot: +\def\qsx@sort@a #1% + {\expandafter\qsx@sort@b\expandafter{\romannumeral0\xintlength{#1}}{#1}}% +\def\qsx@sort@b #1{\ifcase #1 + \expandafter\qsx@sort@empty + \or\expandafter\qsx@sort@single + \or\expandafter\qsx@sort@double + \else\expandafter\qsx@sort@c\fi {#1}}% +\def\qsx@sort@empty #1#2{ }% +\def\qsx@sort@single #1#2{#2}% +\catcode`_ 11 +\def\qsx@sort@double #1#2{\xintifGt #2{\xint_exchangetwo_keepbraces}{}#2}% +\catcode`_ 8 +\def\qsx@sort@c #1#2{% + \expandafter\qsx@sort@sep@a\expandafter + {\romannumeral0\xintnthelt{\pdfuniformdeviate #1+\@ne}{#2}}#2?}% +\def\qsx@sort@sep@a #1{\qsx@sort@sep@loop {}{}{}{#1}}% +\def\qsx@sort@sep@loop #1#2#3#4#5% +{% + \ifx?#5\expandafter\qsx@sort@sep@done\fi + \xintifCmp {#5}{#4}% + \qsx@sort@sep@appendtosmaller + \qsx@sort@sep@appendtoequal + \qsx@sort@sep@appendtogreater {#5}{#1}{#2}{#3}{#4}% +}% +% +\def\qsx@sort@sep@appendtoequal #1#2{\qsx@sort@sep@loop {#2{#1}}}% +\def\qsx@sort@sep@appendtogreater #1#2#3{\qsx@sort@sep@loop {#2}{#3{#1}}}% +\def\qsx@sort@sep@appendtosmaller #1#2#3#4{\qsx@sort@sep@loop {#2}{#3}{#4{#1}}}% +% +\def\qsx@sort@sep@done\xintifCmp #1% + \qsx@sort@sep@appendtosmaller + \qsx@sort@sep@appendtoequal + \qsx@sort@sep@appendtogreater #2#3#4#5#6% +{% + \expandafter\qsx@sort@recurse\expandafter + {\romannumeral0\qsx@sort@a {#4}}{\qsx@sort@a {#5}}{#3}% +}% +% +\def\qsx@sort@recurse #1#2#3{#2#3#1}% +% +\makeatother + +% EXAMPLES +\begingroup +\edef\z {\QSx {1.0, 0.5, 0.3, 1.5, 1.8, 2.0, 1.7, 0.4, 1.2, 1.4, + 1.3, 1.1, 0.7, 1.6, 0.6, 0.9, 0.8, 0.2, 0.1, 1.9}} +\meaning\z + +\def\a {3.123456789123456789}\def\b {3.123456789123456788} +\def\c {3.123456789123456790}\def\d {3.123456789123456787} +\oodef\z {\QSx { \a, \b, \c, \d}}% +% The space before \a to let it not be expanded during the conversion from CSV +% values to List. The \oodef expands exactly twice (via a bunch of \expandafter's) +\meaning\z + +\def\somenumbers{% +3997.6421, 8809.9358, 1805.4976, 5673.6478, 3179.1328, 1425.4503, 4417.7691, +2166.9040, 9279.7159, 3797.6992, 8057.1926, 2971.9166, 9372.2699, 9128.4052, +1228.0931, 3859.5459, 8561.7670, 2949.6929, 3512.1873, 1698.3952, 5282.9359, +1055.2154, 8760.8428, 7543.6015, 4934.4302, 7526.2729, 6246.0052, 9512.4667, +7423.1124, 5601.8436, 4433.5361, 9970.4849, 1519.3302, 7944.4953, 4910.7662, +3679.1515, 8167.6824, 2644.4325, 8239.4799, 4595.1908, 1560.2458, 6098.9677, +3116.3850, 9130.5298, 3236.2895, 3177.6830, 5373.1193, 5118.4922, 2743.8513, +8008.5975, 4189.2614, 1883.2764, 9090.9641, 2625.5400, 2899.3257, 9157.1094, +8048.4216, 3875.6233, 5684.3375, 8399.4277, 4528.5308, 6926.7729, 6941.6278, +9745.4137, 1875.1205, 2755.0443, 9161.1524, 9491.1593, 8857.3519, 4290.0451, +2382.4218, 3678.2963, 5647.0379, 1528.7301, 2627.8957, 9007.9860, 1988.5417, +2405.1911, 5065.8063, 5856.2141, 8989.8105, 9349.7840, 9970.3013, 8105.4062, +3041.7779, 5058.0480, 8165.0721, 9637.7196, 1795.0894, 7275.3838, 5997.0429, +7562.6481, 8084.0163, 3481.6319, 8078.8512, 2983.7624, 3925.4026, 4931.5812, +1323.1517, 6253.0945}% + +\oodef\z {\QSx \somenumbers}% produced as a comma+space separated list +% black magic as workaround to the shrinkability of spaces in last line... +\hsize 87\fontcharwd\font`0 +\lccode`~=32 +\lowercase{\def~}{\discretionary{}{}{\kern\fontcharwd\font`0}}\catcode32 13 +\noindent\phantom{00}\scantokens\expandafter{\meaning\z}\par +\endgroup +\end{everbatim*} +\fi % fin de si pas xetex + + +All the previous examples were with numbers which could have been handled via +|\ifdim| tests rather than the \csbxint{ifCmp} macro from \xintfracname; using +|\ifdim| tests would naturally be faster. Even faster routine is |code 6| at +(link removed) which uses |\pdfescapestring| and a +Merge Sort algorithm. + +We then turn to a graphical illustration of the algorithm.% +% +\footnote{I have rewritten (2015/11/21) the routine to do only once (and not thrice) the + needed calls to \csa{xintifCmp}, up to the price of one additional |\edef|, + although due to the context execution time on our side is not an issue and + moreover is anyhow overwhelmed by the TikZ's activities. Simultaneously I + have updated the code. + The + variant with the choice of pivot on the right has more overhead: the reason + is simply that we do not convert the data into an array, but maintain a list + of tokens with self-reorganizing delimiters.} +% +For simplicity the pivot is always chosen as the first list item. Then we also +give a variant which picks up the last item as pivot. +\begin{everbatim*} +% in LaTeX preamble: +% \usepackage{xintfrac, xinttools} +% \usepackage{color} +% or, when using Plain TeX: +% \input xintfrac.sty \input xinttools.sty +% \input color.tex +% +% Color definitions +\definecolor{LEFT}{RGB}{216,195,88} +\definecolor{RIGHT}{RGB}{208,231,153} +\definecolor{INERT}{RGB}{199,200,194} +\definecolor{INERTpiv}{RGB}{237,237,237} +\definecolor{PIVOT}{RGB}{109,8,57} +% Start of macro defintions +\makeatletter +% \catcode`? 3 % a bit too paranoid. Normal ? will do. +% +% argument will never be empty +\def\QS@cmp@a #1{\QS@cmp@b #1??}% +\def\QS@cmp@b #1{\noexpand\QS@sep@A\@ne{#1}\QS@cmp@d {#1}}% +\def\QS@cmp@d #1#2{\ifx ?#2\expandafter\QS@cmp@done\fi + \xintifCmp {#1}{#2}\tw@\@ne\z@{#2}\QS@cmp@d {#1}}% +\def\QS@cmp@done #1?{?}% +% +\def\QS@sep@A #1?{\QSLr\QS@sep@L #1\thr@@?#1\thr@@?#1\thr@@?}% +\def\QS@sep@L #1#2{\ifcase #1{#2}\or\or\else + \expandafter\QS@sep@I@start\fi \QS@sep@L}% +\def\QS@sep@I@start\QS@sep@L {\noexpand\empty?\QSIr\QS@sep@I}% +\def\QS@sep@I #1#2{\ifcase#1\or{#2}\or\else\expandafter\QS@sep@R@start\fi\QS@sep@I}% +\def\QS@sep@R@start\QS@sep@I {\noexpand\empty?\QSRr\QS@sep@R}% +\def\QS@sep@R #1#2{\ifcase#1\or\or{#2}\else\expandafter\QS@sep@done\fi\QS@sep@R}% +\def\QS@sep@done\QS@sep@R {\noexpand\empty?}% +% +\def\QS@loop {% + \xintloop + % pivot phase + \def\QS@pivotcount{0}% + \let\QSLr\DecoLEFTwithPivot \let\QSIr \DecoINERT + \let\QSRr\DecoRIGHTwithPivot \let\QSIrr\DecoINERT + \centerline{\QS@list}% + % sorting phase + \ifnum\QS@pivotcount>\z@ + \def\QSLr {\QS@cmp@a}\def\QSRr {\QS@cmp@a}% + \def\QSIr {\QSIrr}\let\QSIrr\relax + \edef\QS@list{\QS@list}% compare + \let\QSLr\relax\let\QSRr\relax\let\QSIr\relax + \edef\QS@list{\QS@list}% separate + \def\QSLr ##1##2?{\ifx\empty##1\else\noexpand \QSLr {{##1}##2}\fi}% + \def\QSIr ##1##2?{\ifx\empty##1\else\noexpand \QSIr {{##1}##2}\fi}% + \def\QSRr ##1##2?{\ifx\empty##1\else\noexpand \QSRr {{##1}##2}\fi}% + \edef\QS@list{\QS@list}% gather + \let\QSLr\DecoLEFT \let\QSRr\DecoRIGHT + \let\QSIr\DecoINERTwithPivot \let\QSIrr\DecoINERT + \centerline{\QS@list}% + \repeat }% +% +% \xintFor* loops handle gracefully empty lists. +\def\DecoLEFT #1{\xintFor* ##1 in {#1} \do {\colorbox{LEFT}{##1}}}% +\def\DecoINERT #1{\xintFor* ##1 in {#1} \do {\colorbox{INERT}{##1}}}% +\def\DecoRIGHT #1{\xintFor* ##1 in {#1} \do {\colorbox{RIGHT}{##1}}}% +\def\DecoPivot #1{\begingroup + \color{PIVOT}\advance\fboxsep-\fboxrule\fbox{#1}\endgroup}% +% +\def\DecoLEFTwithPivot #1{\xdef\QS@pivotcount{\the\numexpr\QS@pivotcount+\@ne}% + \xintFor* ##1 in {#1} \do + {\xintifForFirst {\DecoPivot {##1}}{\colorbox{LEFT}{##1}}}}% +\def\DecoINERTwithPivot #1{\xdef\QS@pivotcount{\the\numexpr\QS@pivotcount+\@ne}% + \xintFor* ##1 in {#1} \do + {\xintifForFirst {\colorbox{INERTpiv}{##1}}{\colorbox{INERT}{##1}}}}% +\def\DecoRIGHTwithPivot #1{\xdef\QS@pivotcount{\the\numexpr\QS@pivotcount+\@ne}% + \xintFor* ##1 in {#1} \do + {\xintifForFirst {\DecoPivot {##1}}{\colorbox{RIGHT}{##1}}}}% +% +\def\QuickSort #1{% warning: not compatible with empty #1. + % initialize, doing conversion from comma separated values + % to a list of braced items + \edef\QS@list{\noexpand\QSRr{\xintCSVtoList{#1}}}% + % may \edef's are to follow anyhow +% earlier I did a first drawing of the list, here with the color of RIGHT elements, +% but the color should have been for example white, anyway I drop this first line + %\let\QSRr\DecoRIGHT + %\par\centerline{\QS@list}% +% + % loop as many times as needed + \QS@loop }% +% +% \catcode`? 12 % in case we had used a funny ? as delimiter. +\makeatother +%% End of macro definitions. +%% Start of Example +\begingroup\offinterlineskip +\small +% \QuickSort {1.0, 0.5, 0.3, 1.5, 1.8, 2.0, 1.7, 0.4, 1.2, 1.4, +% 1.3, 1.1, 0.7, 1.6, 0.6, 0.9, 0.8, 0.2, 0.1, 1.9} +% \medskip +% with repeated values +\QuickSort {1.0, 0.5, 0.3, 0.8, 1.5, 1.8, 2.0, 1.7, 0.4, 1.2, 1.4, + 1.3, 1.1, 0.7, 0.3, 1.6, 0.6, 0.3, 0.8, 0.2, 0.8, 0.7, 1.2} +\endgroup +\end{everbatim*} + +Here is the variant which always picks the pivot as the rightmost element. + +\begin{everbatim*} +\makeatletter +% +\def\QS@cmp@a #1{\noexpand\QS@sep@A\expandafter\QS@cmp@d\expandafter + {\romannumeral0\xintnthelt{-1}{#1}}#1??}% +% +\def\DecoLEFTwithPivot #1{\xdef\QS@pivotcount{\the\numexpr\QS@pivotcount+\@ne}% + \xintFor* ##1 in {#1} \do + {\xintifForLast {\DecoPivot {##1}}{\colorbox{LEFT}{##1}}}} +\def\DecoINERTwithPivot #1{\xdef\QS@pivotcount{\the\numexpr\QS@pivotcount+\@ne}% + \xintFor* ##1 in {#1} \do + {\xintifForLast {\colorbox{INERTpiv}{##1}}{\colorbox{INERT}{##1}}}} +\def\DecoRIGHTwithPivot #1{\xdef\QS@pivotcount{\the\numexpr\QS@pivotcount+\@ne}% + \xintFor* ##1 in {#1} \do + {\xintifForLast {\DecoPivot {##1}}{\colorbox{RIGHT}{##1}}}} +\def\QuickSort #1{% + % initialize, doing conversion from comma separated values + % to a list of braced items + \edef\QS@list{\noexpand\QSLr {\xintCSVtoList{#1}}}% + % many \edef's are to follow anyhow + % + % loop as many times as needed + \QS@loop }% +\makeatother +\begingroup\offinterlineskip +\small +% \QuickSort {1.0, 0.5, 0.3, 1.5, 1.8, 2.0, 1.7, 0.4, 1.2, 1.4, +% 1.3, 1.1, 0.7, 1.6, 0.6, 0.9, 0.8, 0.2, 0.1, 1.9} +% \medskip +% with repeated values +\QuickSort {1.0, 0.5, 0.3, 0.8, 1.5, 1.8, 2.0, 1.7, 0.4, 1.2, 1.4, + 1.3, 1.1, 0.7, 0.3, 1.6, 0.6, 0.3, 0.8, 0.2, 0.8, 0.7, 1.2} +\endgroup +\end{everbatim*} + +The choice of the first or last item as pivot is not a good one as nearly +ordered lists will take quadratic time. But for explaining the algorithm via a +graphical interpretation, it is not that bad. If one wanted to pick up the +pivot randomly, the routine would have to be substantially rewritten: in +particular the |\Deco..withPivot| macros need to know where the pivot is, and +currently this is implemented by using either |\xintifForFirst| or +|\xintifForLast|. + +\clearpage + +\expandafter\let\csname ExamplesnameUp\endcsname\undefined + \csname xint bundlenameUp\endcsname \def\xintRunningHeader{{\inheadertrue\catcode`,12\relax @@ -8898,10 +13244,7 @@ anecdotical evidence showing it is good. \xintbinhexname, \xintgcdname, \xintseriesname, - \xintcfracname, - \xinttoolsname, - \DOCxintexprmacros, - \DOCexamples}} + \xintcfracname}} \markboth{\makebox[0pt]{\xintRunningHeader}}{\makebox[0pt]{\xintRunningHeader}} \etocdepthtag.toc {macros} @@ -8910,7 +13253,7 @@ anecdotical evidence showing it is good. \renewcommand{\etocaftertochook}{\addvspace{\bigskipamount}} \part{The macro layer for expandable computations: \xintcorename, \xintname, - \xintfracname,...\@} + \xintfracname, and some extras} \RaisedLabel[15]{sec:bundle} @@ -9225,8 +13568,9 @@ tokens). By convention in this manual \fexpan sion (``full expansion'' or ``full first expansion'') will be this \TeX{} process of expanding repeatedly the first token seen. For those familiar with \LaTeX3 (which is not used by \xintname) -this is what is called in its documentation full expansion (whereas expansion -inside |\edef| would be described I think as ``exhaustive'' expansion). +this is what is called in its documentation full expansion, whereas expansion +inside |\edef| would be described I think as ``exhaustive'' expansion +and will be referred too in this manual as \xexpan sion. Most of the package macros, and all those dealing with computations% % @@ -9520,9 +13864,8 @@ mathematical result is an integer. The |B=1| is not removed.% in the scientific notation as described in the documentation of \csbxint{Float}. - The exceptions are \csbxint{PFloat} and its variant \csbxint{PFloatb} which - do some customizable pretty printing of the result. The former is also used - by default by \csbxint{floateval}. + The exception is \csbxint{PFloat} which does some customizable pretty + printing of the result. \end{itemize} \subsection{Count registers and variables}\label{sec:useofcount} @@ -9773,7 +14116,7 @@ recover the $1238/1157$ therein! \end{framed} -\subsection{\csh{ifcase}, \csh{ifnum}, ...\@ constructs}\label{sec:ifcase} +\subsection{\csh{ifcase}, \csh{ifnum}, \texorpdfstring{...\@}{...} constructs}\label{sec:ifcase} When using things such as |\ifcase \xintSgn{\A}| one has to make sure to leave a space after the closing brace for \TeX{} to @@ -9829,7 +14172,8 @@ As an alternative to |\edef| the package provides |\oodef| which expands exactly twice the replacement text, and |\fdef| which applies \fexpan sion to the replacement text during the definition. \begin{everbatim*} -\def\x{1729728} \def\y{352827927} \oodef\w {\xintiiMul\x\y} \fdef\z{\xintiiMul {\x}{\y}} +\def\x{1729728}\def\y{352827927} +\oodef\w {\xintiiMul\x\y} \fdef\z{\xintiiMul {\x}{\y}} \meaning\w, \meaning\z \end{everbatim*} @@ -10009,45 +14353,88 @@ un-helpful error messages already in her daily practice of \subsection{Package namespace, catcodes} -The bundle packages needs that the \csa{space} and \csa{empty} control -sequences are pre-defined with the identical meanings as in Plain \TeX{} (or -\LaTeX2e which has the same macros). - -Private macros of \xintkernelname, \xintcorename, \xinttoolsname, -\xintname, \xintfracname, \xintexprname, \xintbinhexname, \xintgcdname, -\xintseriesname, and \xintcfracname{} use one or more underscores |_| as -private letter, to reduce the risk of getting overwritten. They almost -all begin either with |\XINT_| or with |\xint_|, a handful of these -private macros such as \csa{XINTsetupcatcodes}, \csa{XINTdigits} and -those with names such as |\XINTinFloat...| or |\XINTinfloat...| do not -have any underscore in their names (for obscure legacy reasons). - -\xintkernelname provides \hyperref[odef]{|\odef|}, \hyperref[oodef]{|\oodef|}, -\hyperref[fdef]{|\fdef|}: if macros with these names already exist -\xinttoolsname will not overwrite them. The same meanings are independently -available under the names |\xintodef|, |\xintoodef|, etc... - -Apart from |\thexintexpr|, |\thexintiexpr|, ...\@ -all other public macros from the \xintname bundle packages start with |\xint|. +This section reviews (probably with some omissions) important +miscellany regarding control sequence names and catcode matters and is +basically in its entirety a +\begin{TeXnote} +\begin{itemize} +\item The bundle packages %\CHANGED{1.4} + force the |\space| and |\empty| + control sequences into having their default meanings as in Plain \TeX{} or + \LaTeX2e formats. +\item Private macros (or internally used |\count| registers, and one private + |\toks|) have names starting with |\xint_| or |\XINT_|. Some, for legacy or + technical reasons, have |\xint| or |\XINT| prefix with no underscore. +\item All public macros have their names starting with |\xint| except for: + \begin{itemize} + \item the \xintkernelname provided \hyperref[odef]{|\odef|}, + \hyperref[oodef]{|\oodef|}, \hyperref[fdef]{|\fdef|}. If macros with + these names already exist \xinttoolsname will not overwrite them. Their + meanings are also available under the names \csbxint{odef}, \csbxint{oodef}, + etc... + \item deprecated |\thexintexpr| etc..., which will be removed at next major + release. Use \csbxint{theexpr} etc... rather. + \item deprecated |\poormanloghack| which is now a no-op and will be removed + at next major release. + \end{itemize} + +\item Whether in arguments of \xintfracname macros or inside + \csbxint{expr}essions active characters will cause naturally problems, one + thinks in particular of characters made active by |babel| languages such as + |babel-french| for |!?;:|, and for example the |!| if used as factorial + operator will cause breakage. Prefixing with |\string| is one option, and + there is also |\detokenize|. + +\item Precautions are not needed (but see next item) for + \csbxint{defvar} and \csbxint{deffunc} as they use automatically + \csbxint{exprSafeCatcodes} and \csbxint{exprRestoreCatcodes} to temporarily + set catcodes to safe values. + +\item \csbxint{exprSafeCatcodes} and \csbxint{exprRestoreCatcodes} can be + employed at user level too. They should be used in case of need before and + after macro definitions themselves using \csbxint{expr}, \csbxint{defvar} or + \csbxint{deffunc}. Indeed the latter two won't be able to ``fix'' + problematic characters already present at definition time when expansion is + later done. In the \LaTeX\ preamble, |babel| has not yet activated + (normally) characters, so these precautions should be unneeded there. + +\item For the \xintfracname macros to be able to parse their inputs, standard + catcodes in the argument are assumed for the digits (of course), the plus + and minus signs, the dot, the letter |e|, the forward slash, the square + brackets. Spaces should be avoided although they may go unnoticed + sometimes. + +\item For the \xintexprname expressions there is more leeway: the digit tokens + must have their standard catcodes, the letters must have their standard + catcodes for variable and function names to be recognized, but other + characters may mostly have unusual catcodes, if non-letter and not extremes. + A few syntax elements are implemented via delimited macros and normal + catcodes must be in effect for the comma, the equal sign and the closing + parenthesis for those to work. Spaces are gobbled. The |e| of scientific + notation may be |E| on input, \xintfracname macros on the other hand will + not recognize the |E|. -For the good functioning of the macros, standard catcodes are assumed for the -minus sign, the forward slash, the square brackets, the letter `e'. These -requirements are dropped inside an |\xintexpr|-ession: spaces are gobbled, -catcodes mostly do not matter, the |e| of scientific notation may be |E| (on -input) \dots{} +\item +At loading time the + catcode configuration may be arbitrary as long as it satisfies the following + requirements: + \begin{itemize}[nosep] + \item \dtt{\%} has its normal category code, + \item \dtt{\char92} has its normal category code, + \item Latin letters have their normal category code "letter", + \item Digits have their normal category code "other". + \end{itemize} + Nothing more is assumed, for example |{| and |}| may have unusual catcodes + at package loading time. This will be admittedly unusual especially in + \LaTeX\ as |\usepackage{xintexpr}| would then have had to be replaced by + something such as |\usepackage<xintexpr>|... -If a character used in the |\xintexpr| syntax is made active, -this will surely cause problems; prefixing it with |\string| is one option. -There is \csbxint{exprSafeCatcodes} and \csbxint{exprRestoreCatcodes} to -temporarily turn off potentially active characters. +\item Loading the packages causes no insertion of space tokens. -\begin{framed} - For advanced \TeX\ users. At loading time of the packages the - catcode configuration may be arbitrary as long as it satisfies the following - requirements: the percent is of category code comment character, the - backslash is of category code escape character, digits have category code - other and letters have category code letter. Nothing else is assumed. -\end{framed} +\item The previous two items also apply to usage of \csbxint{reloadxintlog} + and of \csbxint{reloadxinttrig}. +\end{itemize} +\end{TeXnote} \subsection{Origins of the package} \label{ssec:origins} @@ -10137,6 +14524,9 @@ It provides a few macros possibly useful in other contexts. \label{odef} \label{oodef} \label{fdef} +\label{xintodef} +\label{xintoodef} +\label{xintfdef} \csa{oodef}|\controlsequence {<stuff>}| does \everb|@ @@ -10170,6 +14560,9 @@ faster than |\edef| when expanding macros from the \xintname bundle, when the result has a few dozens of digits. |\oodef| needs thousands of digits it seems to become competitive. +\xintkernelname will not define these macros if the control sequence names +already exist. It provides them always under the names |\xintodef|, +|\xintoodef| and |\xintfdef| respectively. \subsection{\csh{xintReverseOrder}}\label{xintReverseOrder} @@ -10439,7 +14832,7 @@ It would be nice if the engine provided some user interface for \par \smallskip -\TeXnote +\begin{TeXnote} currently the implementation of \csbxint{UniformDeviate} consumes exactly 5 calls to the engine primitive at each execution; the improved |x/2^{56}| non-uniformity could be obtained with only 2 calls, but paranoïa about the @@ -10459,8 +14852,14 @@ let's raise 100 times a random integer to the tenth power:% \InputIfFileExists{JFBUORDI}{}{}% \ifdefined\JFBUORDI \footnote{% - \if0\pdfstrcmp{IMAC}{\JFBUORDI}Timings done during dvi build on a computer with a |2.4GHz| cpu.\else - \if0\pdfstrcmp{MBA}{\JFBUORDI}Timings done during dvi build on a computer with a |2GHz| cpu.\else + \if0\pdfstrcmp{IMAC}{\JFBUORDI}Timings done during dvi build on a + computer with a |2.8GHz| % + %quadri-core + cpu, old but still kicking, and with a locally compiled |latex| binary.\else + \if0\pdfstrcmp{MBA}{\JFBUORDI}Timings done during dvi build on a + computer with a |2GHz| % + %dual-core + cpu, old but still kicking, and with a locally compiled |latex| binary.\else %\error DOCUMENTATION SEEMINGLY BUILT NOT ON AN AUTHOR-OWNED SYSTEM, BUT \string\JFBUORDI\space IS DEFINED, WEIRD!\fi\fi } @@ -10470,23 +14869,23 @@ let's raise 100 times a random integer to the tenth power:% % \begin{everbatim*} \pdfsetrandomseed 12345678 -\pdfresettimer\romannumeral\xintreplicate - {100}{\fdef\foo{\xintiiPow{\xintUniformDeviate{100000000}}{10}}}% +\pdfresettimer +\romannumeral\xintreplicate{100} + {\fdef\foo{\xintiiPow{\xintUniformDeviate{100000000}}{10}}}% \the\dimexpr\pdfelapsedtime sp\relax\space (with \string\xintUniformDeviate)\newline -(last result: \foo)\newline \pdfsetrandomseed 12345678 -\pdfresettimer\romannumeral\xintreplicate - {100}{\fdef\foo{\xintiiPow{\pdfuniformdeviate 100000000}{10}}}% -\the\dimexpr\pdfelapsedtime sp\relax\space (with \string\pdfuniformdeviate)\newline -(last result: \foo)\par +\pdfresettimer +\romannumeral\xintreplicate{100} + {\fdef\foo{\xintiiPow{\pdfuniformdeviate 100000000}{10}}}% +\the\dimexpr\pdfelapsedtime sp\relax\space (with \string\pdfuniformdeviate)\par \end{everbatim*} -\TeXnote -the macros \csbxint{RandomDigits} or \csbxint{iiRandRange}, and their +The macros \csbxint{RandomDigits} or \csbxint{iiRandRange}, and their variants, as well as the supporting macros for \func{random} generate random decimal digits eight by eight as if using \csa{xintUniformDeviate}|{100000000}|, but via a direct optimized call made possibly by the range being a power of 10. +\end{TeXnote} \clearpage \let\xintkernelnameUp\undefined @@ -10746,9 +15145,12 @@ $M,N>0$ it is the same as the Euclidean quotient \csbxint{iiQuo}. \begin{everbatim*} \xintiiQuo{1000}{57} (Euclidean), \xintiiDivTrunc{1000}{57} (truncated), \xintiiDivRound{1000}{57} (rounded)\newline -\xintiiQuo{-1000}{57}, \xintiiDivTrunc{-1000}{57} (t), \xintiiDivRound{-1000}{57} (r)\newline -\xintiiQuo{1000}{-57}, \xintiiDivTrunc{1000}{-57} (t), \xintiiDivRound{1000}{-57} (r)\newline -\xintiiQuo{-1000}{-57}, \xintiiDivTrunc{-1000}{-57} (t), \xintiiDivRound{-1000}{-57} (r)\par +\xintiiQuo{-1000}{57}, \xintiiDivTrunc{-1000}{57} (t), \xintiiDivRound{-1000}{57} (r) +\newline +\xintiiQuo{1000}{-57}, \xintiiDivTrunc{1000}{-57} (t), \xintiiDivRound{1000}{-57} (r) +\newline +\xintiiQuo{-1000}{-57}, \xintiiDivTrunc{-1000}{-57} (t), \xintiiDivRound{-1000}{-57} (r) +\par \end{everbatim*} \subsection{\csh{xintiiDivFloor}}\label{xintiiDivFloor} @@ -11538,8 +15940,10 @@ auxiliary file, the macro context may cause a reduced maximum). \xintRandomDigits{92} \end{everbatim*} -\TeXnote the digits are produced eight by eight by the same method which would -result from \csbxint{UniformDeviate}|{100000000}| but with less overhead. +\begin{TeXnote} + the digits are produced eight by eight by the same method which would result + from \csbxint{UniformDeviate}|{100000000}| but with less overhead. +\end{TeXnote} % \subsection{\csh{\xintOneRandomDigit}}\label{xintOneRandomDigit} @@ -11571,8 +15975,10 @@ Transcript written on temp.log. This can be lifted by increasing the \TeX\ memory settings (installation dependent). -\TeXnote the digits are produced eight by eight by the same method which would -result from \csbxint{UniformDeviate}|{100000000}| but with less overhead. +\begin{TeXnote} + the digits are produced eight by eight by the same method which would result + from \csbxint{UniformDeviate}|{100000000}| but with less overhead. +\end{TeXnote} \subsection{(WIP) \csh{xintiiRandRange}}\label{xintiiRandRange} @@ -11584,7 +15990,8 @@ Python's function of the same name, it is an error if |A<=0|. xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\newline \xintiiRandRange{\xintNum{1e40}}\newline \pdfsetrandomseed 271828314 -\xinttheiiexpr randrange(num(1e40))\relax\newline % bare 1e40 not understood by \xintiiexpr +\xinttheiiexpr randrange(num(1e40))\relax\newline +% bare 1e40 not understood by \xintiiexpr \pdfsetrandomseed 271828314 \xinttheexpr randrange(1e40)\relax \end{everbatim*} @@ -11604,8 +16011,10 @@ able to generate all numbers with fourty digits as random numbers, and this makes the previous section about usage of \csbxint{XRandomDigits} to generate millions of digits a bit comical... -\TeXnote the digits are produced eight by eight by the same method which would -result from \csbxint{UniformDeviate}|{100000000}| but with less overhead. +\begin{TeXnote} + the digits are produced eight by eight by the same method which would result + from \csbxint{UniformDeviate}|{100000000}| but with less overhead. +\end{TeXnote} \subsection{(WIP) \csh{xintiiRandRangeAtoB}}\label{xintiiRandRangeAtoB} @@ -11615,16 +16024,21 @@ Python's function of the same name, it is an error if |B<=A|. \begin{everbatim*} \pdfsetrandomseed 271828314 12345678911111111111111111111\newline -\xintiiRandRangeAtoB{12345678911111111111111111111}{12345678922222222222222222222}\newline +\xintiiRandRangeAtoB{12345678911111111111111111111}{12345678922222222222222222222}% +\newline \pdfsetrandomseed 271828314 \def\test{% -\xinttheiiexpr randrange(12345678911111111111111111111,12345678922222222222222222222)\relax}% +\xinttheiiexpr + randrange(12345678911111111111111111111,12345678922222222222222222222) +\relax}% \romannumeral\xintreplicate{10}{\test\newline}% 12345678922222222222222222222 \end{everbatim*} -\TeXnote the digits are produced eight by eight by the same method which would -result from \csbxint{UniformDeviate}|{100000000}| but with less overhead. +\begin{TeXnote} + the digits are produced eight by eight by the same method which would result + from \csbxint{UniformDeviate}|{100000000}| but with less overhead. +\end{TeXnote} \clearpage \let\xintnameUp\undefined @@ -11679,60 +16093,72 @@ names will raise warnings and will be removed at next major release. \localtableofcontents -\subsection{\csh{xintTeXfromSci}}\label{xintTeXfromSci} +\subsection{\csh{xintTeXFromSci}}\label{xintTeXFromSci} -Experimental.\etype{} This typesetting math-mode-only macro expects an input +Experimental.\xtype{} This typesetting math-mode-only macro expects an input which is already in, or will expand to, decimal or scientific notation.\NewWith{1.4g} A trailing |/B| is accepted and will be handled differently according to whether it follows some scientific exponent |eN| part or not. -This macro is designed to be used as a typesetting wrapper for \csbxint{eval} -or \csbxint{floateval} output. It does no «reflowing» of the mantissa as the -input is expected to have been already «prettified» (for example via the -removal of trailing zeros, of a scientific part if the exponent is small, -etc...) and simply transforms the |e<exponent>| part, if actually present, -into |\cdot 10^{exponent}|. A fractional part |/B| if found in the expansion -of the input must be last and will be tranformed into |\cdot B^{-1}| if there -was a scientific part, else the output will be |\frac{A}{B}| (or the \TeX\ -equivalent) with |A| the numerator.% -% -\footnote{I am hesitating whether the |\frac{A}{B}| branch choice should - require |A| to be an integer, or will also, as currently, be done with |A| - being a number in decimal notation.} +It was formerly |\xintTeXfromSci|. Old name deprecated. Also it used +to be \fexpan dable but is now only \xexpan dable. Use |\expanded| if +needed.\CHANGED{1.4l} + +This macro can be used as a typesetting wrapper for \csbxint{eval} or +\csbxint{floateval} output: it expects its input (after expansion) to +have been already «prettified» for example via the removal of trailing +zeros, usage of fixed point notation if scientific exponent is small, +etc\dots\ % +It simply transforms the |e<exponent>| part, if actually present, into +|\cdot 10^{exponent}|. A fractional part |/B| if found in the expansion +of the input must be last and will be tranformed into |\cdot B^{-1}| if +there was a scientific part, else the output will be using |\frac{A}{B}| +(or the \TeX\ equivalent in place of |\frac|) with |A| the numerator. + +\begin{TeXnote} + \begin{itemize} + \item I am hesitating whether the |\frac{A}{B}| branch choice should + require |A| to be an integer, or will also, as currently, be done + with |A| being a number in decimal notation. Please advise. + \item The package does: +\begin{everbatim} +\ifdefined\frac + \protected\def\xintTeXFromScifracmacro#1#2{\frac{#2}{#1}}% +\else + \protected\def\xintTeXFromScifracmacro#1#2{{#2\over#1}}% +\fi +\end{everbatim} + Customize as desired. Notice the interversion of arguments. + \end{itemize} +\end{TeXnote} + +Example: \begin{everbatim*} -$\xintTeXfromSci{\xintfloateval{1.1^10000/5}}$, $\xintTeXfromSci{\xinteval{1.1^10000/5}}$\par +$\xintTeXFromSci{\xintfloateval{1.1^10000/5}}$, +$\xintTeXFromSci{\xinteval{1.1^10000/5}}$\par \end{everbatim*} -The macro applies complete expansion to its argument, hence its input can be -expressed using \csbxint{FracToSci} but it is simpler to use \csbxint{eval} -which applies and expands completely \csbxint{FracToSci}, as per default -setting of \csbxint{exprPrintOne}. -Note though that the macro can handle only one value. If one intends to -achieve the same effect but with comma separated or bracketed values, the way -to proceed is via a redefinition of \csbxint{floatexprPrintOne} and/or -\csbxint{exprPrintOne}. +The above examples are in the case of a single numerical value. To +handle more complex outputs from \csbxint{eval} or \csbxint{floateval} +one will need to proceed via a redefinition of +\csbxint{floatexprPrintOne} and/or \csbxint{exprPrintOne} like this: \begin{everbatim*} -\[\def\xintfloatexprPrintOne[#1]#2{\xintTeXfromSci{\xintPFloat[#1]{#2}}} +\[\def\xintfloatexprPrintOne[#1]#2{\xintTeXFromSci{\xintPFloat[#1]{#2}}} \xintfloateval[10]{2^100, 3^100, 13^100}\] \end{everbatim*} \par\vskip-\belowdisplayskip \begin{everbatim*} -\[\def\xintexprPrintOne#1{\xintTeXfromSci{\xintFracToSci{#1}}} +\[\def\xintexprPrintOne#1{\xintTeXFromSci{\xintFracToSci{#1}}} \xinteval{sqrt(2^101,60), 355/113, 6.02e23/1000}\] \end{everbatim*}% attention à l'espace TeX est en mode horizontal après display -This will however make impossible, due to the added \TeX\ mark-up in the +This will however make then impossible, due to the added \TeX\ mark-up in the output, the nesting of \csbxint{floateval}/\csbxint{eval} inside one another. -But the \csbxint{expr}|...\relax| syntax remains usable and is indeed the -recommended way as it is more efficient, only in certain very special -situations does one need the «eval» which produces explicit digits, and then -usually the output will be an integer, so will remain invariant and usable as -before. Anyway, in the above examples we localized the redefinitions to the -equation construct which is scope-limiting (as is already the underlying \TeX\ -math display using |$$|). - -Some similar effect is also possible without \csbxint{TeXfromSci}, +The core \csbxint{expr}|...\relax| syntax remains usable and is anyhow the +recommended way for such nesting as it is more efficient. + +Some similar effect is also possible without \csbxint{TeXFromSci}, simply by a customization of \csbxint{PFloatE} like this: \begin{everbatim*} \begingroup @@ -11740,10 +16166,10 @@ simply by a customization of \csbxint{PFloatE} like this: $\xintfloateval{1.1^10000/5}$, $\xinteval{1.1^10000/5}$ \endgroup\newline \end{everbatim*}% -This method is simpler-minded and will leave trailing |/B|'s «as is», though. - -And of course, with this poor man method too the presence of \TeX\ mark-up -makes nesting dangerous, so we limited by security the definition to a group. +This method is simpler-minded but will leave the trailing |/B|'s «as +is», even if the numerator has no scientific exponent part. The +presence of extra \TeX\ mark-up in the output has the consequences +on nesting which were mentioned above. \subsection{\csh{xintTeXFrac}}\label{xintTeXFrac} @@ -11754,7 +16180,8 @@ format |A/B[n]|. If the denominator |B| is \dtt{1}, the output is |A\cdot 10^n|. If the exponent |n| is \dtt{0}, the |[\cdot]10^n| part is omitted. \begin{everbatim*} -$\xintTeXFrac {178.000/25600000}$, $\xintTeXFrac {178.000/1}$, $\xintTeXFrac {3.5/5.7}$\newline +$\xintTeXFrac {178.000/25600000}$, $\xintTeXFrac {178.000/1}$, +$\xintTeXFrac {3.5/5.7}$\newline \end{everbatim*}% The input, if in a fraction form, is not simplified in any way, except for transforming numerator and denominator into integers, separating a power of @@ -11781,7 +16208,8 @@ This does the same as \csa{xintTeXFrac}\etype{\Ff} except that the \csa{over} primitive is used for the fraction (in case the denominator is not one; and a pair of braces contains the |A\over B| part). \begin{everbatim*} -$\xintTeXOver {178.000/25600000}$, $\xintTeXOver {178.000/1}$, $\xintTeXOver {3.5/5.7}$\newline +$\xintTeXOver {178.000/25600000}$, $\xintTeXOver {178.000/1}$, +$\xintTeXOver {3.5/5.7}$\newline \end{everbatim*}% It is the new name of |\xintFwOver|.\CHANGED{1.4g} @@ -11844,11 +16272,16 @@ denominator: \xintRaw {178000/25600000} \end{everbatim*} +\subsection{\csh{xintRawBraced}}\label{xintRawBraced} + +This macro expands and parses its input\etype{\Ff} |f| as all +\xintfracname macros and produces as output |{N}{A}{B}| (with \TeX\ +braces) where \csbxint{Raw} would have returned |A/B[N]|.\NewWith{1.4l} + \subsection{\csh{xintNumerator}}\label{xintNumerator} The input data\etype{\Ff} is parsed as if by \csbxint{Raw} into |A/B[N]| -format and -the macro outputs |A| if |N<=0|, or |A| extended by |N| zeroes if |N>0|. +and then |A| is returned if |N<=0|, or |A| extended by |N| zeroes if |N>0|. \begin{everbatim*} \xintNumerator {178000/25600000[17]}\newline \xintNumerator {312.289001/20198.27}\newline @@ -11859,8 +16292,7 @@ the macro outputs |A| if |N<=0|, or |A| extended by |N| zeroes if |N>0|. \subsection{\csh{xintDenominator}}\label{xintDenominator} The input data\etype{\Ff} is parsed as if by \csbxint{Raw} into |A/B[N]| -format and -the macro outputs |B| if |N>0|, or |B| extended by \verb+|N|+ zeroes if |N<=0|. +and then |B| is returned if |N>0|, or |B| extended by \verb+|N|+ zeroes if |N<=0|. \begin{everbatim*} \xintDenominator {178000/25600000[17]}\newline \xintDenominator {312.289001/20198.27}\newline @@ -11870,8 +16302,8 @@ the macro outputs |B| if |N>0|, or |B| extended by \verb+|N|+ zeroes if |N<=0|. \subsection{\csh{xintRawWithZeros}}\label{xintRawWithZeros} -This macro parses the input\etype{\Ff} and outputs |A/B|, with |A| -as would be returned by \csa{xintNumerator}|{f}| and |B| as would be returned by +This macro parses the input\etype{\Ff} and outputs |A'/B'|, with |A'| +as would be returned by \csa{xintNumerator}|{f}| and |B'| as would be returned by \csa{xintDenominator}|{f}|. \begin{everbatim*} \xintRawWithZeros{178000/25600000[17]}\newline @@ -11889,8 +16321,6 @@ trailing zeroes of |A| and |B| are suppressed and |N| is accordingly adjusted. \xintREZ {178000/25600000[17]} \end{everbatim*} -This macro is used internally by various other constructs; its implementation -was redone entirely at |1.3a|, and it got faster on long inputs. \subsection{\csh{xintIrr}}\label{xintIrr} @@ -11994,8 +16424,10 @@ The definitive behaviour remains to be decided regarding these last two points. \begin{everbatim*} \xintDecToStringREZ{0}, \xintDecToStringREZ{1/2}, \xintDecToStringREZ{0.5000}\newline \xintDecToStringREZ{1.23456789e5}, \xintDecToStringREZ {1.23456789e-3}\newline -\xintDecToStringREZ{12345e-1}, \xintDecToStringREZ {12345e-2}, \xintDecToStringREZ{12345e-3}\newline -\xintDecToStringREZ{12345e-4}, \xintDecToStringREZ {12345e-5}, \xintDecToStringREZ{12345e-6}\newline +\xintDecToStringREZ{12345e-1}, \xintDecToStringREZ {12345e-2}, +\xintDecToStringREZ{12345e-3}\newline +\xintDecToStringREZ{12345e-4}, \xintDecToStringREZ {12345e-5}, +\xintDecToStringREZ{12345e-6}\newline \xintDecToStringREZ{1.234567890000e12}, \xintDecToStringREZ{1.23456000e-5/10}\newline \xintDecToStringREZ{70/14} % is not reduced to lowest terms \end{everbatim*} @@ -12022,8 +16454,10 @@ remove trailing zeros, in fact \csbxint{DecToStringREZ}|{f}| is defined as \begin{everbatim*} \xintDecToString{0}, \xintDecToString{1/2}, \xintDecToString{0.5000}\newline \xintDecToString{1.23456789e5}, \xintDecToString {1.23456789e-3}\newline -\xintDecToString{12345e-1}, \xintDecToString {12345e-2}, \xintDecToString{12345e-3}\newline -\xintDecToString{12345e-4}, \xintDecToString {12345e-5}, \xintDecToString{12345e-6}\newline +\xintDecToString{12345e-1}, \xintDecToString {12345e-2}, \xintDecToString{12345e-3}% +\newline +\xintDecToString{12345e-4}, \xintDecToString {12345e-5}, \xintDecToString{12345e-6}% +\newline \xintDecToString{1.234567890000e12}, \xintDecToString{1.23456000e-5/10}\newline \xintDecToString{70/14} \end{everbatim*} @@ -12044,6 +16478,85 @@ Any replacement of \csbxint{DecToString} as the expansion of \item to accept on input |A| or |A[N]|. \end{itemize} +\subsection{\csh{xintFracToSci}}\label{xintFracToSci} + +\csa{xintFracToSci}\etype{\Ff} was initially at |1.4| a private macro +which served as default customization of \csbxint{exprPrintOne} and, +despite being documented in the user manual, was not supposed to be used +at user level (not being \fexpan dable it could not be nested within +macros of \xintfracname, and besides accepted a limited range of +inputs). + +It has now been upgraded to behave like all other \xintfracname +macros.\CHANGED{1.4l} + +Here is what it does: +\begin{itemize}[noitemsep,nosep] +\item it first parses the input like any other \xintfracname macro and + convert it into the ``raw'' |A/B[N]| format, +\item it then produces this output: |A/B| if |N=0| (and |/B| is omitted + if not |1|), and for |N| not zero, the + output numerator will be |AeN| written in scientific notation exactly like it + would by \csbxint{PFloat} but without of course prior rounding to a + given number of digits; the trailing zeros in the + significand will be removed always (the \csbxint{PFloatMinTrimmed} + configuration is ignored). Then this value in scientific notation (or + in decimal fixed point notation if the scientific exponent is in the + \csbxint{PFloatNoSciEmin} to \csbxint{PFloatNoSciEmax} range) will be + attached to a trailing denominator |/B| (omitted if it is |/1|). +\end{itemize} +Please note: +\begin{itemize} +\item there is no reduction of the fraction |A/B| to lowest terms, +\item trailing zeros in the integer denominator |B| are not moved and + incorporated into the final scientific exponent, +\item no attempt is made to check if |B| is a product of only |2|'s and + |5|'s and thus could be integrated into some pure decimal notation for + the numerator or at least its significand. +\end{itemize} +Changes\CHANGED{1.4k} of \csbxint{PFloat} at |1.4k| have an impact here. +In particular the zero value will give \dtt{0} whether the input was +some |0|, |0e-5|, |0/3|, |0.00|, etc\dots, whereas at |1.4e| it would +have been \dtt{0.0} for cases triggering some \csbxint{PFloat} +subroutine. + +The general blueprint is still to be considered \emph{unstable}. + +The output routine of \csbxint{eval} is customizable via redefining +\csbxint{exprPrintOne} whose current default is (equivalent to): +\begin{everbatim} +\def\xintexprPrintOne{\xintFracToSci} +\end{everbatim} + +\subsection{\csh{xintFracToDecimal}} +\label{xintFracToDecimal} + +\csa{xintFracToDecimal}\etype{\Ff} is a variant of \csbxint{FracToSci} which +differs from it in so far as it outputs a numerator using decimal notation, +i.e. with as many zeros as are needed (and no more) and no scientific +exponent. The denominator goes through ``as is'' except if it is |1|, then it +is omitted.\NewWith{1.4k} + +In other terms its behaviour is currently intermediate between +\csbxint{DecToString} and \csbxint{DecToStringREZ}, as it does not +remove trailing zeros of the denominator. Consider its behaviour as +\emph{unstable}. + +It can be used to customize \csbxint{exprPrintOne}: +\begin{everbatim} +\def\xintexprPrintOne{\xintFracToDecimal} +\end{everbatim} + +It was initially at |1.4k| a private macro which served as an alternative to +\csb{xintFracToSci} default customization of \csbxint{exprPrintOne} and, +despite being documented in the user manual, was not supposed to be used at +user level (not being \fexpan dable it could not be nested within macros of +\xintfracname, and besides accepted a limited range of inputs). + +It has now been upgraded to behave like all other \xintfracname +macros.\CHANGED{1.4l} + + \subsection{\csh{xintTrunc}}\label{xintTrunc} \csa{xintTrunc}|{x}{f}|\etype{\numx\Ff} returns the start of the decimal @@ -12504,6 +17017,12 @@ be an integer. The sign of a fraction.\etype{\Ff} +\subsection{\csh{xintSignBit}}\label{xintSignBit} + +Expands to \dtt{1} for negative input, to \dtt{0} else.\etype{\Ff} + +Added at |1.4l|. + \subsection{\csh{xintOpp}}\label{xintOpp} The opposite of a fraction.\etype{\Ff} @@ -12756,7 +17275,8 @@ will now always be in the form |A/B[n]|. The original, for big integers only No simplification attempted. \begin{everbatim*} -$\xintIsOne {21921379213/21921379213}\neq\xintIsOne {1.00000000000000000000000000000001}$ +$\xintIsOne {21921379213/21921379213}\neq + \xintIsOne {1.00000000000000000000000000000001}$ \end{everbatim*} \subsection{\csh{xintGCD}}\label{xintGCD} @@ -12821,42 +17341,54 @@ See \csbxint{iiLCMof} for the integer only variant. \label{xintDigits} \label{xinttheDigits} -The syntax |\xintDigits := D;| assigns the value of |D| to the number of -digits to be used by floating point operations (this uses internally a -|\mathchardef| assignement, and |D| stands for (or expands to) a legal \TeX\ -number). The default is |16|. The maximal value is |32767|. +The syntax |\xintDigits := N;| or (recommended) |\xintDigits := N\relax| +assigns the value of |N| to the number of digits to be used by floating +point operations (this uses internally a |\mathchardef| assignement, and +|N| stands for (or expands to) a legal \TeX\ number). The default is +|16|. The maximal value is |32767|. + +Accepted syntax includes also |\xintDigits = N;| or |\xintDigits = +N\relax|, i.e.\@ the colon before the equality sign is optional. +% \begin{framed} \xintexprname adds\IMPORTANTf{} the variant \csbxint{Digits*} which executes - \csbxint{reloadxinttrig}. -\end{framed} + \csbxint{reloadxinttrig} and \csbxint{reloadxintlog}. -The expandable macro |\xinttheDigits|\etype{} serves to retrieve (internally -it uses |\number|) the current value. + A priori, you want \csbxint{Digits*}|:=N\relax|. Use + |\xintDigits:=N\relax| only if not needing trigonometric or + logarithm/exponential functions and wanting to avoid the overhead of + reloading their librairies. Perhaps for a local temporary + configuration. +\end{framed} Spaces do not matter as long as they do not occur in-between digits: \begin{everbatim*} -\xintDigits := 24;\xinttheDigits, % -\xintDigits:=36 ;\xinttheDigits, % -\xintDigits:= 16 ;and \xinttheDigits. +\xintDigits := 24\relax\xinttheDigits, % +\xintDigits:=36 \relax\xinttheDigits, % +\xintDigits:= 16 \relax and \xinttheDigits. \end{everbatim*} +As shown above |\xinttheDigits|\etype{} expands to the stored value. + % It has always been the case that an active colon |:| was allowed. -Also |\xintDigits = D;| (i.e.\@ without a colon) is accepted syntax. +An ending active semi-colon |;| is \emph{not} compatible: it can and +will cause low-level \TeX{} errors. This is why the alternative syntax +\begin{everbatim} +\xintDigits:= N\relax +\end{everbatim} +is recommended (with or without the semi-colon). This is hopefully the +syntax now in use in most examples from the documentation. -An ending active semi-colon |;| is \emph{not} compatible: it can and will -cause low-level \TeX{} errors. But this has a trivial workaround: any -non-expanding token can be used in place of the ending semi-colon. For -example a full stop or a |\relax| token. This -non-expanding ending token will get removed from the token stream. % This % restriction always applied, but never got properly documented prior to % |1.3f| release... It is possible to use |\string;| but then there can not be % any space separating it from the digits. -The recommended syntax is thus now |\xintDigits := D\relax| (with or without the colon). -This is the syntax in use in most examples from the documentation. +Actually, any non-expanding token can be used in place of the +|\relax|. This non-expanding ending token (for example a full stop) will +get removed from the token stream. \begin{everbatim*} \xintDigits = 24\def\xinttheDigits, % only for showing it works! don't do that! \xintDigits := 36.\xinttheDigits, % one can use a dot in place of semi-colon @@ -12874,7 +17406,9 @@ expression will be fed to |\numexpr|. It is a shortcut for doing \xintSetDigits{2*8}The value is now \xinttheDigits.\par \end{everbatim*} \begin{framed} - See also the \xintexprname-added variant \csbxint{SetDigits*}. + The \xintexprname-added variant \csbxint{SetDigits*} is + the preferred usage as it does the extra work to update the math + functions from \xinttrigname and \xintlogname. \end{framed} \subsection{\csh{xintFloat}} @@ -12943,6 +17477,37 @@ transitive in the number of kept digits. +\subsection{\csh{xintFloatBraced}} +\label{xintFloatBraced} + +The experimental macro +|\xintFloatBraced[P]{f}|\etype{{\upshape[\numx]}\Ff} does like +\csbxint{Float} but its output consists of three \TeX-braced groups +\centeredline{\marg{sign bit}\marg{scientific exponent}\marg{full width + mantissa with decimal point}} It is provided\NewWith{1.4l} for users +knowing how to pick one or the other of these constituents from usage +of auxiliary macros. Or one can use \csbxint{Assign}: +\begin{everbatim*} +\begingroup +\xintAssign\xintFloatBraced[7]{-3.1234e-14}\to\A\B\C +\string\A\ has meaning \meaning\A\newline +\string\B\ has meaning \meaning\B\newline +\string\C\ has meaning \meaning\C\par +\endgroup +\end{everbatim*} +Some aspects are undecided: +\begin{itemize}[noitemsep] +\item should the first item be rather |-1|, |0|, or |1|? or |-|, nothing, nothing? +\item in case of zero value the output ignores \csbxint{FloatZero}, it + uses a zero exponent and full width fractional mantissa \dtt{\csname + xint_gobble_ii\expandafter\endcsname\romannumeral0\xintfloatbraced{0}} + (here no |[P]| and \csbxint{theDigits} has value + \dtt{\xinttheDigits}), should it be otherwise? +\item should the mantissa be without the decimal separator ? should it + incorporate the sign ? +\item in case the mantissa is without separator, should the exponent be biased to match it? +\end{itemize} + \subsection{\csh{xintFloatToDecimal}} \label{xintFloatToDecimal} @@ -12982,7 +17547,8 @@ notation was used in the output) and integers printed with a trailing |1.4k|\CHANGED{1.4k} brings some breaking changes, which are reversible via customizing macros: \begin{itemize} -\item Integers (when scientific notation is dropped) without a "\dtt{.0}" +\item Integers (when scientific notation is dropped according to + criteria mentioned next) without a "\dtt{.0}" suffix. \item Same for the zero value, now "\dtt{\xintPFloat{0}}". \item Significands are trimmed of trailing zeros only if that removes at least @@ -12995,6 +17561,13 @@ via customizing macros: These changes impact the \csbxint{floateval} output as \csbxint{floatexprPrintOne} defaults to using \csbxint{PFloat}. +\begin{framed} + In\IMPORTANTf\ this documentation ``trailing zeros'' refers not to how + the input looked like, but + to the corresponding mantissa of width |P| or \csbxint{theDigits}. +\end{framed} + + The default rules are thus now: \begin{enumerate}[nolistsep] \item The input is float-rounded to either |Digits| or the optional argument. @@ -13008,8 +17581,6 @@ The default rules are thus now: \item In case of scientific notation output format, and the mantissa has only one digit, no decimal mark is used. \end{enumerate} -Please note that ``trailing zeros'' refers to the ``trailing zeros of the full width -significand after float-rounding'', and not only to trailing zeros used in the input. % The old rules were: % \begin{enumerate}[nosep] @@ -13115,8 +17686,13 @@ The default definition is: \def\xintPFloatMinTrimmed{4} \end{everbatim} Defining it to expand to \dtt{-1} or \dtt{0} will enable the trimming of -trailing zeros always, and setting it to a high value will prevent it -altogther. +trailing zeros always, and setting it to a value at least equal to |P| +(or \csbxint{theDigits} if no |[P]|) will prevent it +altogether. + +This setting\CHANGED{1.4l} is ignored for the case of an integer value, if the +criteria for using fixed point notation are met, and for the case of a +one-digit mantissa in scientific notation. \end{itemize} @@ -13710,13 +18286,18 @@ This can be combined with \csbxint{BinToHex} for round-trips preserving leading zeroes for |4N| binary digits numbers, whereas using \csbxint{HexToBin} gives reproducing round-trips only for |4N| binary numbers numbers not starting with |0000|. -\begin{everbatim*} This zero-fills to 4N digits the input, hence gives here a leading zero in output: -\xintBinToHex{0001111}\newline +\begin{everbatim*} +\xintBinToHex{0001111}\par +\end{everbatim*} Chaining, we end up with 4N-3 digits, as three binary zeroes are trimmed: -\xintHexToBin{\xintBinToHex{0001111}}\newline +\begin{everbatim*} +\xintHexToBin{\xintBinToHex{0001111}}\par +\end{everbatim*} But this will always reproduce the initial input zero-filled to length 4N: +\begin{everbatim*} \xintCHexToBin{\xintBinToHex{0001111}}\par +\end{everbatim*} Another example (visible space characters manually inserted):\newline $000000001111101001010001\xrightarrow{\text{\string\xintBinToHex}} \xintBinToHex{000000001111101001010001}\xrightarrow{\text{\string\xintHexToBin\hphantom{X}}} @@ -13726,7 +18307,6 @@ $000000001111101001010001\xrightarrow{\text{\string\xintBinToHex}} \xintBinToHex{000000001111101001010001}\xrightarrow{\text{\string\xintCHexToBin}} \xintCHexToBin{\xintBinToHex{000000001111101001010001}}$ \par -\end{everbatim*} \clearpage \let\xintbinhexnameUp\undefined @@ -14894,7 +19474,8 @@ For non-numeric input there is \csbxint{GGCFrac}. \end{everbatim*} For regular continued fractions, there is a simpler comma separated format: \begin{everbatim*} -\[-7,6,19,1,33\to\xintTeXFrac{\xintCstoF{-7,6,19,1,33}}=\xintCFrac{\xintCstoF{-7,6,19,1,33}}\] +\[-7,6,19,1,33\to\xintTeXFrac{\xintCstoF{-7,6,19,1,33}}= + \xintCFrac{\xintCstoF{-7,6,19,1,33}}\] \end{everbatim*} The macro \csbxint{FtoCs} produces from a fraction |f| the comma separated list of its coefficients. @@ -15243,7 +19824,8 @@ release |1.09m| spaces before commas are allowed and trimmed automatically {-1+1/3+1/-5+1/7+1/-9+1/11+1/-13}}\] \end{everbatim*} \begin{everbatim*} -\[\xintGCFrac{{1/2}+1/{1/3}+1/{1/4}+1/{1/5}}=\xintTeXFrac{\xintCstoF {1/2,1/3,1/4,1/5}}\] +\[\xintGCFrac{{1/2}+1/{1/3}+1/{1/4}+1/{1/5}}= + \xintTeXFrac{\xintCstoF {1/2,1/3,1/4,1/5}}\] \end{everbatim*} % A generalized continued fraction may produce a reducible fraction @@ -15529,4082 +20111,56 @@ One can also use a centered continued fraction: we get more digits but there are also more computations as the numerators may be either $1$ or $-1$. +\ifnum\NoSourceCode=1 \clearpage -\let\xintcfracnameUp\undefined -\csname xinttoolsnameUp\endcsname -\def\n{|{N}|} -\def\m{|{M}|} -\def\x{|{x}|} -\section{Macros of the \xinttoolsname package} - -\RaisedLabel{sec:tools} - -These utilities used to be provided within the \xintname package; since |1.09g| -(|2013/11/22|) they have been moved to an independently usable package -\xinttoolsname, which has none of the \xintname facilities regarding big -numbers. Whenever relevant release |1.09h| has made the macros |\long| so they -accept |\par| tokens on input. - -The completely expandable utilities (up to \csbxint{iloop}) are documented -first, then the non expandable utilities. - -\autoref{sec:examples} -gives additional (also dated) examples of use of macros of this package. - -\localtableofcontents - -\subsection{\csh{xintRevWithBraces}}\label{xintRevWithBraces} - -%{\small New in release |1.06|.\par} - -\edef\X{\xintRevWithBraces{12345}} -\edef\y{\xintRevWithBraces\X} -\expandafter\def\expandafter\w\expandafter - {\romannumeral0\xintrevwithbraces{{\A}{\B}{\C}{\D}{\E}}} - -% -\csa{xintRevWithBraces}\marg{list}\etype{f} first does the \fexpan sion of its -argument then it reverses the order of the tokens, or braced material, it -encounters, maintaining existing braces and adding a brace pair around each -naked token encountered. Space tokens (in-between top level braces or naked -tokens) are gobbled. This macro is mainly thought out for use on a \meta{list} -of such braced material; with such a list as argument the \fexpan sion will only -hit against the first opening brace, hence do nothing, and the braced stuff may -thus be macros one does not want to expand. -% -\leftedline{|\edef\x{\xintRevWithBraces{12345}}|} -% -\leftedline{|\meaning\x:|\dtt{\meaning\X}} -% -\leftedline{|\edef\y{\xintRevWithBraces\x}|} -% -\leftedline{|\meaning\y:|\dtt{\meaning\y}} -% -The examples above could be defined with |\edef|'s because the braced material -did not contain macros. Alternatively: -% -\leftedline{|\expandafter\def\expandafter\w\expandafter|} -% -\leftedline{|{\romannumeral0\xintrevwithbraces{{\A}{\B}{\C}{\D}{\E}}}|} -% -\leftedline{|\meaning\w:|\dtt{\meaning\w}} -% -The macro \csa{xintReverseWithBracesNoExpand}\etype{n} does the same job -without the initial expansion of its argument. - - -\subsection{\csh{xintZapFirstSpaces}, \csh{xintZapLastSpaces}, \csh{xintZapSpaces}, \csh{xintZapSpacesB}} -\label{xintZapFirstSpaces} -\label{xintZapLastSpaces} -\label{xintZapSpaces} -\label{xintZapSpacesB} -%{\small New with release |1.09f|.\par} - -\csa{xintZapFirstSpaces}\marg{stuff}\etype{n} does not do \emph{any} expansion -of its argument, nor brace removal of any sort, nor does it alter \meta{stuff} -in anyway apart from stripping away all \emph{leading} spaces. - -This macro will be mostly of interest to programmers who will know what I will -now be talking about. \emph{The essential points, naturally, are the complete - expandability and the fact that no brace removal nor any other alteration is - done to the input.} - -\TeX's input scanner already converts consecutive blanks into single space -tokens, but |\xintZapFirstSpaces| handles successfully also inputs with -consecutive multiple space tokens. -However, it is assumed that \meta{stuff} does not contain (except inside braced -sub-material) space tokens of character code distinct from $32$. - -It expands in two steps, and if the goal is to apply it to the -expansion text of |\x| to define |\y|, then one can do: -|\odef\y{\romannumeral0\expandafter\xintzapfirstspaces\expandafter{\x}}| -(one can also define a wrapper macro to |\xintZapFirstSpaces| in order to -expand once the argument first, but \xinttoolsname not being a programming -layer, it provides no «Generate Variants» facilities). - -Other use case: inside a macro which received a parameter |#1|, one can do -|\oodef\x{\xintZapFirstSpaces {#1}}|, or, if |#1|, after leading spaces have -been stripped can accept |\edef| expansion, one can do -|\edef\x{\xintZapFirstSpaces{#1}}|. - -\begingroup -\def\x { \a { \X } { \b \Y } } -% -\leftedline{|\xintZapFirstSpaces { \a { \X } { \b \Y } }->|% -\dtt{\color{magenta}{}\expandafter\detokenize\expandafter -{\romannumeral0\expandafter\xintzapfirstspaces\expandafter{\x}}}+++} -\endgroup - -\medskip - -\noindent\csbxint{ZapLastSpaces}\marg{stuff}\etype{n} does not do \emph{any} expansion of -its argument, nor brace removal of any sort, nor does it alter \meta{stuff} in -anyway apart from stripping away all \emph{ending} spaces. The same remarks as -for \csbxint{ZapFirstSpaces} apply. - -\begingroup -\def\x { \a { \X } { \b \Y } } -% -\leftedline{|\xintZapLastSpaces { \a { \X } { \b \Y } }->|% -\dtt{\color{magenta}{}\expandafter\detokenize\expandafter -{\romannumeral0\expandafter\xintzaplastspaces\expandafter{\x}}}+++} -\endgroup - -\medskip - -\noindent\csbxint{ZapSpaces}\marg{stuff}\etype{n} does not do \emph{any} -expansion of its -argument, nor brace removal of any sort, nor does it alter \meta{stuff} in -anyway apart from stripping away all \emph{leading} and all \emph{ending} -spaces. The same remarks as for \csbxint{ZapFirstSpaces} apply. - -\begingroup -\def\x { \a { \X } { \b \Y } } -% -\leftedline{|\xintZapSpaces { \a { \X } { \b \Y } }->|% -\dtt{\color{magenta}{}\expandafter\detokenize\expandafter -{\romannumeral0\expandafter\xintzapspaces\expandafter{\x}}}+++} -\endgroup - -\medskip - -\noindent\csbxint{ZapSpacesB}\marg{stuff}\etype{n} does not do \emph{any} -expansion of -its argument, nor does it alter \meta{stuff} in anyway apart from stripping away -all leading and all ending spaces and possibly removing one level of braces if -\meta{stuff} had the shape |<spaces>{braced}<spaces>|. The same remarks as for -\csbxint{ZapFirstSpaces} apply. - -\begingroup -\def\x { \a { \X } { \b \Y } } -% -\leftedline{|\xintZapSpacesB { \a { \X } { \b \Y } }->|% -\dtt{\color{magenta}{}\expandafter\detokenize\expandafter -{\romannumeral0\expandafter\xintzapspacesb\expandafter{\x}}}+++} -\def\x { { \a { \X } { \b \Y } } } -% -\leftedline{|\xintZapSpacesB { { \a { \X } { \b \Y } } }->|% -\dtt{\color{magenta}{}\expandafter\detokenize\expandafter -{\romannumeral0\expandafter\xintzapspacesb\expandafter{\x}}}+++} -\endgroup - The spaces here at the start and end of the output come from the braced - material, and are not removed (one would need a second application for that; - recall though that the \xintname zapping macros do not expand their argument). - -\subsection{\csh{xintCSVtoList}} -\label{xintCSVtoList} -\label{xintCSVtoListNoExpand} - - -\csa{xintCSVtoList}|{a,b,c...,z}|\etype{f} returns |{a}{b}{c}...{z}|. A -\emph{list} is by -convention in this manual simply a succession of tokens, where each braced thing -will count as one item (``items'' are defined according to the rules of \TeX{} -for fetching undelimited parameters of a macro, which are exactly the same rules -as for \LaTeX{} and macro arguments [they are the same things]). The word -`list' in `comma separated list of items' has its usual linguistic meaning, -and then an ``item'' is what is delimited by commas. - -So \csa{xintCSVtoList} takes on input a `comma separated list of items' and -converts it into a `\TeX{} list of braced items'. The argument to -|\xintCSVtoList| may be a macro: it will first be -\hyperref[ssec:expansions]{\fexpan ded}. Hence the item before the first comma, -if it is itself a macro, will be expanded which may or may not be a good thing. -A space inserted at the start of the first item serves to stop that expansion -(and disappears). The macro \csbxint{CSVtoListNoExpand}\etype{n} does the same -job without -the initial expansion of the list argument. - -Apart from that no expansion of the items is done and the list items may thus be -completely arbitrary (and even contain perilous stuff such as unmatched |\if| -and |\fi| tokens). - -Contiguous spaces and tab characters, are collapsed by \TeX{} -into single spaces. All such spaces around commas% -% -\footnote{and multiple space tokens are not a problem; but those at the - top level (not hidden inside braces) \emph{must} be of character code - |32|.} -% -\fbox{are removed}, as well as -the spaces at the start and the spaces at the end of the list.% -% -\footnote{let us recall that this is all done completely expandably... - There is absolutely no alteration of any sort of the item apart from - the stripping of initial and final space tokens (of character code - |32|) and brace removal if and only if the item apart from intial and - final spaces (or more generally multiple |char 32| space tokens) is - braced.} -% -The items may contain explicit |\par|'s or -empty lines (converted by the \TeX{} input parsing into |\par| tokens). - -\begingroup - -\edef\X{\xintCSVtoList { 1 ,{ 2 , 3 , 4 , 5 }, a , {b,T} U , { c , d } , { {x , - y} } }} - -% -\leftedline{|\xintCSVtoList { 1 ,{ 2 , 3 , 4 , 5 }, a , {b,T} U , { c , d } , - { {x , y} } }|} -% -\leftedline{|->|% -{\makeatletter\dtt{\expandafter\strip@prefix\meaning\X}}} - -One sees on this example how braces protect commas from -sub-lists to be perceived as delimiters of the top list. Braces around an entire -item are removed, even when surrounded by spaces before and/or after. Braces for -sub-parts of an item are not removed. - -We observe also that there is a slight difference regarding the brace stripping -of an item: if the braces were not surrounded by spaces, also the initial and -final (but no other) spaces of the \emph{enclosed} material are removed. This is -the only situation where spaces protected by braces are nevertheless removed. - -From the rules above: for an empty argument (only spaces, no braces, no comma) -the output is -\dtt{\expandafter\detokenize\expandafter{\romannumeral0\xintcsvtolist { }}} -(a list with one empty item), -for ``|<opt. spaces>{}<opt. -spaces>|'' the output is -\dtt{\expandafter\detokenize\expandafter - {\romannumeral0\xintcsvtolist { {} }}} -(again a list with one empty item, the braces were removed), -for ``|{ }|'' the output is -\dtt{\expandafter\detokenize\expandafter - {\romannumeral0\xintcsvtolist {{ }}}} -(again a list with one empty item, the braces were removed and then -the inner space was removed), -for ``| { }|'' the output is -\dtt{\expandafter\detokenize\expandafter -{\romannumeral0\xintcsvtolist { { }}}} (again a list with one empty item, the initial space served only to stop the expansion, so this was like ``|{ }|'' as input, the braces were removed and the inner space was stripped), -for ``\texttt{\ \{\ \ \}\ }'' the output is -\dtt{\expandafter\detokenize\expandafter -{\romannumeral0\xintcsvtolist { { } }}} (this time the ending space of the first -item meant that after brace removal the inner spaces were kept; recall though -that \TeX{} collapses on input consecutive blanks into one space token), -for ``|,|'' the output consists of two consecutive -empty items -\dtt{\expandafter\detokenize\expandafter{\romannumeral0\xintcsvtolist - {,}}}. Recall that on output everything is braced, a |{}| is an ``empty'' -item. -% -Most of the above is mainly irrelevant for every day use, apart perhaps from the -fact to be noted that an empty input does not give an empty output but a -one-empty-item list (it is as if an ending comma was always added at the end of -the input). - -\def\y { \a,\b,\c,\d,\e} -\expandafter\def\expandafter\Y\expandafter{\romannumeral0\xintcsvtolist{\y}} -\def\t {{\if},\ifnum,\ifx,\ifdim,\ifcat,\ifmmode} -\expandafter\def\expandafter\T\expandafter{\romannumeral0\xintcsvtolist{\t}} - -% -\leftedline{|\def\y{ \a,\b,\c,\d,\e} \xintCSVtoList\y->|% - {\makeatletter\dtt{\expandafter\strip@prefix\meaning\Y}}} -% -\leftedline{|\def\t {{\if},\ifnum,\ifx,\ifdim,\ifcat,\ifmmode}|} -% -\leftedline -{|\xintCSVtoList\t->|\makeatletter\dtt{\expandafter\strip@prefix\meaning\T}} -% -The results above were automatically displayed using \TeX's primitive -\csa{meaning}, which adds a space after each control sequence name. These spaces -are not in the actual braced items of the produced lists. The first items |\a| -and |\if| were either preceded by a space or braced to prevent expansion. The -macro \csa{xintCSVtoListNoExpand} would have done the same job without the -initial expansion of the list argument, hence no need for such protection but if -|\y| is defined as |\def\y{\a,\b,\c,\d,\e}| we then must do: -% -\leftedline{|\expandafter\xintCSVtoListNoExpand\expandafter {\y}|} Else, we -may have direct use: % -% -\leftedline{|\xintCSVtoListNoExpand - {\if,\ifnum,\ifx,\ifdim,\ifcat,\ifmmode}|} -% -\leftedline{|->|\dtt{\expandafter\detokenize\expandafter - {\romannumeral0\xintcsvtolistnoexpand - {\if,\ifnum,\ifx,\ifdim,\ifcat,\ifmmode}}}} -% -Again these spaces are an artefact from the use in the source of the document of -\csa{meaning} (or rather here, \csa{detokenize}) to display the result of using -\csa{xintCSVtoListNoExpand} (which is done for real in this document -source). - -For the similar conversion from comma separated list to braced items list, but -without removal of spaces around the commas, there is -\csa{xintCSVtoListNonStripped}\etype{f} and -\csa{xintCSVtoListNonStrippedNoExpand}\etype{n}. - -\endgroup - -\subsection{\csh{xintNthElt}}\label{xintNthElt} - - -\def\macro #1{\the\numexpr 9-#1\relax} - -\csa{xintNthElt\x}\marg{list}\etype{\numx f} gets (expandably) the |x|th -item of the \meta{list}. A braced item will lose one level of brace -pairs. The token list is first \fexpan ded. - -Items are counted starting at one. - -\leftedline{|\xintNthElt {3}{{agh}\u{zzz}\v{Z}}| is - \texttt{\xintNthElt {3}{{agh}\u{zzz}\v{Z}}}} -% -\leftedline{|\xintNthElt {3}{{agh}\u{{zzz}}\v{Z}}| is - \texttt{\expandafter\expandafter\expandafter - \detokenize\expandafter\expandafter\expandafter {\xintNthElt - {3}{{agh}\u{{zzz}}\v{Z}}}}} -% -\leftedline{|\xintNthElt {2}{{agh}\u{{zzz}}\v{Z}}| is - \texttt{\expandafter\expandafter\expandafter - \detokenize\expandafter\expandafter\expandafter {\xintNthElt - {2}{{agh}\u{{zzz}}\v{Z}}}}} -% -\leftedline{|\xintNthElt {37}{\xintiiFac {100}}|\dtt{=\xintNthElt - {37}{\xintiiFac {100}}} is the thirty-seventh digit of $100!$.} -% -\leftedline{|\xintNthElt {10}{\xintFtoCv - {566827/208524}}|\dtt{=\xintNthElt {10}{\xintFtoCv - {566827/208524}}}} -\leftedline{is the tenth convergent of $566827/208524$ (uses \xintcfracname - package).} -% -\leftedline{|\xintNthElt {7}{\xintCSVtoList {1,2,3,4,5,6,7,8,9}}|% - \dtt{=\xintNthElt {7}{\xintCSVtoList {1,2,3,4,5,6,7,8,9}}}} -% -\leftedline{|\xintNthElt {0}{\xintCSVtoList {1,2,3,4,5,6,7,8,9}}|% - \dtt{=\xintNthElt {0}{\xintCSVtoList {1,2,3,4,5,6,7,8,9}}}} -% -\leftedline{|\xintNthElt {-3}{\xintCSVtoList {1,2,3,4,5,6,7,8,9}}|% - \dtt{=\xintNthElt {-3}{\xintCSVtoList {1,2,3,4,5,6,7,8,9}}}} - -If |x=0|, -the macro returns the \emph{length} of the expanded list: this is not equivalent -to \csbxint{Length} which does no pre-expansion. And it is different from -\csbxint{Len} which is to be used only on integers or fractions. - -If |x<0|, the macro returns the \verb+|x|+th element from the end of the list. -Thus for example |x=-1| will fetch the last item of the list. -% -\leftedline {|\xintNthElt {-5}{{{agh}}\u{zzz}\v{Z}}| is - \texttt{\expandafter\expandafter\expandafter \detokenize - \expandafter\expandafter\expandafter{\xintNthElt {-5}{{{agh}}\u{zzz}\v{Z}}}}} - -The macro \csa{xintNthEltNoExpand}\etype{\numx n} does the same job but without -first expanding the list argument: |\xintNthEltNoExpand {-4}{\u\v\w T\x\y\z}| is -\xintNthEltNoExpand {-4}{\a\b\c\u\v\w T\x\y\z}. - -If |x| is strictly larger (in absolute value) than the length of the list -then |\xintNthElt| produces empty contents. - -\subsection{\csh{xintNthOnePy}} -\label{xintNthOnePy} - -\csa{xintNthOnePy\x}\marg{list}\etype{\numx f} gets (expandably) the |x|th -item of the \meta{list}, adding a brace pair if there wasn't one.\NewWith{1.4} - -Attention, items are counted starting at zero. For negative index, behaves -as \csbxint{NthElt}. - -If the index is out of range, the empty output is returned. If the input list -was empty (had no items) the empty output is returned. - -\subsection{\csh{xintKeep}}\label{xintKeep} - -\csa{xintKeep\x}\marg{list}\etype{\numx f} expands the token list argument |L| -and produces a new list, depending on the value of |x|: -\begin{itemize}[nosep] -\item if |x>0|, the new list contains the first |x| items from |L| (counting - starts at one.) \emph{Each - such item will be output within a brace pair.} Use \csbxint{KeepUnbraced} if - this is not desired. This means that if the list item was braced to start - with, there is no modification, but if it was a token without braces, - then it acquires them. -\item if |x>=length(L)|, the new list is the old one with all its items now - braced. -\item if |x=0| the empty list is returned. -\item if |x<0| the last \verb+|x|+ elements compose the output in the same - order as in the initial list; as the macro proceeds by removing head items - the kept items end up in output as they were in input: no added braces. -\item if |x<=-length(L)| the output is identical with the input. -\end{itemize} - -\csa{xintKeepNoExpand} does the same without first \fexpan ding its list -argument. -% -\begin{everbatim*} -\fdef\test {\xintKeep {17}{\xintKeep {-69}{\xintSeq {1}{100}}}}\meaning\test\par -\noindent\fdef\test {\xintKeep {7}{{1}{2}{3}{4}{5}{6}{7}{8}{9}}}\meaning\test\par -\noindent\fdef\test {\xintKeep {-7}{{1}{2}{3}{4}{5}{6}{7}{8}{9}}}\meaning\test\par -\noindent\fdef\test {\xintKeep {7}{123456789}}\meaning\test\par -\noindent\fdef\test {\xintKeep {-7}{123456789}}\meaning\test\par -\end{everbatim*} - - -\subsection{\csh{xintKeepUnbraced}}\label{xintKeepUnbraced} - -Same as \csbxint{Keep} but no brace pairs are added around the kept items from -the head of the list in the case |x>0|: each such item will lose one level of -braces. Thus, to remove braces from all items of the list, one can use -\csbxint{KeepUnbraced} with its first argument larger than the length of the -list; the same is obtained from \csbxint{ListWithSep}|{}|\marg{list}. But the -new list will then have generally many more items than the original ones, -corresponding to the unbraced original items. - -For |x<0| the macro is no different from \csbxint{Keep}. Hence the name is a -bit misleading because brace removal will happen only if |x>0|. - -\csa{xintKeepUnbracedNoExpand} does the same without first \fexpan ding -its list argument. -% -\begin{everbatim*} -\fdef\test {\xintKeepUnbraced {10}{\xintSeq {1}{100}}}\meaning\test\par -\noindent\fdef\test {\xintKeepUnbraced {7}{{1}{2}{3}{4}{5}{6}{7}{8}{9}}}\meaning\test\par -\noindent\fdef\test {\xintKeepUnbraced {-7}{{1}{2}{3}{4}{5}{6}{7}{8}{9}}}\meaning\test\par -\noindent\fdef\test {\xintKeepUnbraced {7}{123456789}}\meaning\test\par -\noindent\fdef\test {\xintKeepUnbraced {-7}{123456789}}\meaning\test\par -\end{everbatim*} - -\subsection{\csh{xintTrim}}\label{xintTrim} - -\csa{xintTrim\x}\marg{list}\etype{\numx f} expands the list argument and -gobbles its first |x| elements. -\begin{itemize}[nosep] -\item if |x>0|, the first |x| items from |L| are gobbled. The remaining items - are not modified. -\item if |x>=length(L)|, the returned list is empty. -\item if |x=0| the original list is returned (with no added braces.) -\item if |x<0| the last \verb+|x|+ items of the list are removed. \emph{The - head items end up braced in the output.} Use \csbxint{TrimUnbraced} if - this is not desired. -\item if |x<=-length(L)| the output is empty. -\end{itemize} - -\csa{xintTrimNoExpand} does the same without first \fexpan ding its list -argument. -\begin{everbatim*} -\fdef\test {\xintTrim {17}{\xintTrim {-69}{\xintSeq {1}{100}}}}\meaning\test\par -\noindent\fdef\test {\xintTrim {7}{{1}{2}{3}{4}{5}{6}{7}{8}{9}}}\meaning\test\par -\noindent\fdef\test {\xintTrim {-7}{{1}{2}{3}{4}{5}{6}{7}{8}{9}}}\meaning\test\par -\noindent\fdef\test {\xintTrim {7}{123456789}}\meaning\test\par -\noindent\fdef\test {\xintTrim {-7}{123456789}}\meaning\test\par -\end{everbatim*} - -\subsection{\csh{xintTrimUnbraced}}\label{xintTrimUnbraced} - -Same as \csbxint{Trim} but in case of a negative |x| (cutting items from -the tail), the kept items from the head are not enclosed in brace pairs. They -will lose one level of braces. The name is a bit misleading -because when |x>0| there is no brace-stripping done on the kept items, because -the macro works simply by gobbling the head ones. - -\csa{xintTrimUnbracedNoExpand} does the same without first \fexpan ding its list -argument. - -\begin{everbatim*} -\fdef\test {\xintTrimUnbraced {-90}{\xintSeq {1}{100}}}\meaning\test\par -\noindent\fdef\test {\xintTrimUnbraced {7}{{1}{2}{3}{4}{5}{6}{7}{8}{9}}}\meaning\test\par -\noindent\fdef\test {\xintTrimUnbraced {-7}{{1}{2}{3}{4}{5}{6}{7}{8}{9}}}\meaning\test\par -\noindent\fdef\test {\xintTrimUnbraced {7}{123456789}}\meaning\test\par -\noindent\fdef\test {\xintTrimUnbraced {-7}{123456789}}\meaning\test\par -\end{everbatim*} - -\subsection{\csh{xintListWithSep}}\label{xintListWithSep} - - -\def\macro #1{\the\numexpr 9-#1\relax} - -\csa{xintListWithSep}\marg{sep}\marg{list}\etype{nf} inserts the separator -\meta{sep} in-between all items of the given list of braced items (or -individual tokens). The items are fetched as does \TeX\ with undelimited macro -arguments, thus they end up unbraced in output. If the \meta{list} is only one -(or multiple) space tokens, the output is empty. - -The list argument \meta{list} gets \fexpan ded first (thus if it is a macro -whose contents are braced items, the first opening brace stops the expansion, -and it is as if the macro had been expanded once.) The separator \meta{sep} is -not pre-expanded, it ends up as is in the output (if the \meta{list} contained -at least two items.) - -The variant \csa{xintListWithSepNoExpand}\etype{nn} does the same -job without the initial expansion of the \meta{list} argument. -\begin{everbatim*} -\edef\foo{\xintListWithSep{, }{123456789{10}{11}{12}}}\meaning\foo\newline -\edef\foo{\xintListWithSep{:}{\xintiiFac{20}}}\meaning\foo\newline -\oodef\FOO{\xintListWithSepNoExpand{\FOO}{\bat\baz\biz\buz}}\meaning\FOO\newline -% a braced item or a space stops the f-expansion: -\oodef\foo{\xintListWithSep{\FOO}{{\bat}\baz\biz\buz}}\meaning\foo\newline -\oodef\foo{\xintListWithSep{\FOO}{ \bat\baz\biz\buz}}\meaning\foo\par -\end{everbatim*} - -\subsection{\csh{xintApply}}\label{xintApply} - - -\def\macro #1{\the\numexpr 9-#1\relax} - -\csa{xintApply}|{\macro}|\marg{list}\etype{ff} expandably applies the one -parameter macro |\macro| to each item in the \meta{list} given as second -argument and returns a new list with these outputs: each item is given one after -the other as parameter to |\macro| which is expanded at that time (as usual, -\emph{i.e.\@} fully for what comes first), the results are braced and output -together as a succession of braced items (if |\macro| is defined to start with a -space, the space will be gobbled and the |\macro| will not be expanded; it is -allowed to have its own arguments, the list items serve as last arguments to -|\macro|). Hence |\xintApply{\macro}{{1}{2}{3}}| returns -|{\macro{1}}{\macro{2}}{\macro{3}}| where all instances of |\macro| have been -already \fexpan ded. - -Being expandable, |\xintApply| is useful for example inside alignments where -implicit groups make standard loops constructs usually fail. In such situation -it is often not wished that the new list elements be braced, see -\csbxint{ApplyUnbraced}. The |\macro| does not have to be expandable: -|\xintApply| will try to expand it, the expansion may remain partial. - -The \meta{list} may -itself be some macro expanding (in the previously described way) to the list of -tokens to which the macro |\macro| will be applied. For example, if the -\meta{list} expands to some positive number, then each digit will be replaced by -the result of applying |\macro| on it. % -% -\leftedline{|\def\macro #1{\the\numexpr - 9-#1\relax}|} % -% -\leftedline{|\xintApply\macro{\xintiiFac - {20}}|\dtt{=\xintApply\macro{\xintiiFac {20}}}} - -The macro \csa{xintApplyNoExpand}\etype{fn} does the same job without the first -initial expansion which gave the \meta{list} of braced tokens to which |\macro| -is applied. - -\subsection{\csh{xintApplyUnbraced}}\label{xintApplyUnbraced} - - -\csa{xintApplyUnbraced}|{\macro}|\marg{list}\etype{ff} is like \csbxint{Apply}. -The difference is that after having expanded its list argument, and applied -|\macro| in turn to each item from the list, it reassembles the outputs without -enclosing them in braces. The net effect is the same as doing -% -\leftedline{|\xintListWithSep {}{\xintApply {\macro}|\marg{list}|}|} This is -useful for preparing a macro which will itself define some other macros or make -assignments, as the scope will not be limited by brace pairs. -% -\begin{everbatim*} -\def\macro #1{\expandafter\def\csname myself#1\endcsname {#1}} -\xintApplyUnbraced\macro{{elta}{eltb}{eltc}} -\begin{enumerate}[nosep,label=(\arabic{*})] -\item \meaning\myselfelta -\item \meaning\myselfeltb -\item \meaning\myselfeltc -\end{enumerate} -\end{everbatim*} - -% -The macro \csa{xintApplyUnbracedNoExpand}\etype{fn} does the same job without -the first initial expansion which gave the \meta{list} of braced tokens to which -|\macro| is applied. - -\subsection{\csh{xintSeq}}\label{xintSeq} - -\csa{xintSeq}|[d]{x}{y}|\etype{{{\upshape[\numx]}}\numx\numx} generates -expandably |{x}{x+d}...| up to and possibly including |{y}| if |d>0| or down -to and including |{y}| if |d<0|. Naturally |{y}| is omitted if |y-x| is not a -multiple of |d|. If |d=0| the macro returns |{x}|. If |y-x| and |d| have -opposite signs, the macro returns nothing. If the optional argument |d| is -omitted it is taken to be the sign of |y-x|. Hence |\xintSeq {1}{0}| is not -empty but |{1}{0}|. But |\xintSeq [1]{1}{0}| is empty. - - -The arguments |x| and |y| are expanded inside a |\numexpr| so they may be -count registers or a \LaTeX{} |\value{countername}|, or arithmetic with such -things. - -% -\begin{everbatim*} -\xintListWithSep{,\hskip2pt plus 1pt minus 1pt }{\xintSeq {12}{-25}} -\end{everbatim*} -% -\begin{everbatim*} -\xintiiSum{\xintSeq [3]{1}{1000}} -\end{everbatim*} - -When the macro is used without the optional argument |d|, it can only generate -up to about $5000$ numbers\IMPORTANT, the precise value depends upon some -\TeX{} memory parameter (input save stack). - -With the optional argument |d| the macro proceeds differently (but less -efficiently) and does not stress the input save stack. - - - -\subsection{\csh{xintloop}, \csh{xintbreakloop}, \csh{xintbreakloopanddo}, \csh{xintloopskiptonext}} -\label{xintloop} -\label{xintbreakloop} -\label{xintbreakloopanddo} -\label{xintloopskiptonext} - -|\xintloop|\meta{stuff}|\if<test>...\repeat|\xtype{} is an expandable loop -compatible with nesting. However to break out of the loop one almost always need -some un-expandable step. The cousin \csbxint{iloop} is \csbxint{loop} with an -embedded expandable mechanism allowing to exit from the loop. The iterated -macros may contain |\par| tokens or empty lines. - -If a sub-loop is to be used all the material from the start of the main loop and -up to the end of the entire subloop should be braced; these braces will be -removed and do not create a group. The simplest to allow the nesting of one or -more sub-loops is to brace everything between \csa{xintloop} and \csa{repeat}, -being careful not to leave a space between the closing brace and |\repeat|. - -As this loop and \csbxint{iloop} will primarily be of interest to experienced -\TeX{} macro programmers, my description will assume that the user is -knowledgeable enough. Some examples in this document will be perhaps more -illustrative than my attemps at explanation of use. - -One can abort the loop with \csbxint{breakloop}; this should not be used inside -the final test, and one should expand the |\fi| from the corresponding test -before. One has also \csbxint{breakloopanddo} whose first argument will be -inserted in the token stream after the loop; one may need a macro such as -|\xint_afterfi| to move the whole thing after the |\fi|, as a simple -|\expandafter| will not be enough. - -One will usually employ some count registers to manage the exit test from the -loop; this breaks expandability, see \csbxint{iloop} for an expandable integer -indexed loop. Use in alignments will be complicated by the fact that cells -create groups, and also from the fact that any encountered unexpandable material -will cause the \TeX{} input scanner to insert |\endtemplate| on each encountered -|&| or |\cr|; thus |\xintbreakloop| may not work as expected, but the situation -can be resolved via |\xint_firstofone{&}| or use of |\TAB| with |\def\TAB{&}|. -It is thus simpler for alignments to use rather than \csbxint{loop} either the -expandable \csbxint{ApplyUnbraced} or the non-expandable but alignment -compatible \csbxint{ApplyInline}, \csbxint{For} or \csbxint{For*}. - -As an example, let us suppose we have two macros |\A|\marg{i}\marg{j} and -|\B|\marg{i}\marg{j} behaving like (small) integer valued matrix entries, and we -want to define a macro |\C|\marg{i}\marg{j} giving the matrix product (|i| and -|j| may be count registers). We will assume that |\A[I]| expands to the number -of rows, |\A[J]| to the number of columns and want the produced |\C| to act in -the same manner. The code is very dispendious in use of |\count| registers, not -optimized in any way, not made very robust (the defined macro can not have the -same name as the first two matrices for example), we just wanted to quickly -illustrate use of the nesting capabilities of |\xintloop|.% -% -\footnote{for a more sophisticated implementation of matrix - multiplication, inclusive of determinants, inverses, and display - utilities, with entries big integers or decimal numbers or even - fractions see some code online posted - from - November 11, 2013.} -% - - -\begin{everbatim*} -\newcount\rowmax \newcount\colmax \newcount\summax -\newcount\rowindex \newcount\colindex \newcount\sumindex -\newcount\tmpcount -\makeatletter -\def\MatrixMultiplication #1#2#3{% - \rowmax #1[I]\relax - \colmax #2[J]\relax - \summax #1[J]\relax - \rowindex 1 - \xintloop % loop over row index i - {\colindex 1 - \xintloop % loop over col index k - {\tmpcount 0 - \sumindex 1 - \xintloop % loop over intermediate index j - \advance\tmpcount \numexpr #1\rowindex\sumindex*#2\sumindex\colindex\relax - \ifnum\sumindex<\summax - \advance\sumindex 1 - \repeat }% - \expandafter\edef\csname\string#3{\the\rowindex.\the\colindex}\endcsname - {\the\tmpcount}% - \ifnum\colindex<\colmax - \advance\colindex 1 - \repeat }% - \ifnum\rowindex<\rowmax - \advance\rowindex 1 - \repeat - \expandafter\edef\csname\string#3{I}\endcsname{\the\rowmax}% - \expandafter\edef\csname\string#3{J}\endcsname{\the\colmax}% - \def #3##1{\ifx[##1\expandafter\Matrix@helper@size - \else\expandafter\Matrix@helper@entry\fi #3{##1}}% -}% -\def\Matrix@helper@size #1#2#3]{\csname\string#1{#3}\endcsname }% -\def\Matrix@helper@entry #1#2#3% - {\csname\string#1{\the\numexpr#2.\the\numexpr#3}\endcsname }% -\def\A #1{\ifx[#1\expandafter\A@size - \else\expandafter\A@entry\fi {#1}}% -\def\A@size #1#2]{\ifx I#23\else4\fi}% 3rows, 4columns -\def\A@entry #1#2{\the\numexpr #1+#2-1\relax}% not pre-computed... -\def\B #1{\ifx[#1\expandafter\B@size - \else\expandafter\B@entry\fi {#1}}% -\def\B@size #1#2]{\ifx I#24\else3\fi}% 4rows, 3columns -\def\B@entry #1#2{\the\numexpr #1-#2\relax}% not pre-computed... -\makeatother -\MatrixMultiplication\A\B\C \MatrixMultiplication\C\C\D -\MatrixMultiplication\C\D\E \MatrixMultiplication\C\E\F -\begin{multicols}2 - \[\begin{pmatrix} - \A11&\A12&\A13&\A14\\ - \A21&\A22&\A23&\A24\\ - \A31&\A32&\A33&\A34 - \end{pmatrix} - \times - \begin{pmatrix} - \B11&\B12&\B13\\ - \B21&\B22&\B23\\ - \B31&\B32&\B33\\ - \B41&\B42&\B43 - \end{pmatrix} - = - \begin{pmatrix} - \C11&\C12&\C13\\ - \C21&\C22&\C23\\ - \C31&\C32&\C33 - \end{pmatrix}\] - \[\begin{pmatrix} - \C11&\C12&\C13\\ - \C21&\C22&\C23\\ - \C31&\C32&\C33 - \end{pmatrix}^2 = \begin{pmatrix} - \D11&\D12&\D13\\ - \D21&\D22&\D23\\ - \D31&\D32&\D33 - \end{pmatrix}\] - \[\begin{pmatrix} - \C11&\C12&\C13\\ - \C21&\C22&\C23\\ - \C31&\C32&\C33 - \end{pmatrix}^3 = \begin{pmatrix} - \E11&\E12&\E13\\ - \E21&\E22&\E23\\ - \E31&\E32&\E33 - \end{pmatrix}\] - \[\begin{pmatrix} - \C11&\C12&\C13\\ - \C21&\C22&\C23\\ - \C31&\C32&\C33 - \end{pmatrix}^4 = \begin{pmatrix} - \F11&\F12&\F13\\ - \F21&\F22&\F23\\ - \F31&\F32&\F33 - \end{pmatrix}\] -\end{multicols} -\end{everbatim*} - - -\subsection{\csh{xintiloop}, \csh{xintiloopindex}, \csh{xintouteriloopindex}, - \csh{xintbreakiloop}, \csh{xintbreakiloopanddo}, \csh{xintiloopskiptonext}, -\csh{xintiloopskipandredo}} -\label{xintiloop} -\label{xintbreakiloop} -\label{xintbreakiloopanddo} -\label{xintiloopskiptonext} -\label{xintiloopskipandredo} -\label{xintiloopindex} -\label{xintouteriloopindex} - -\csa{xintiloop}|[start+delta]|\meta{stuff}|\if<test> ... \repeat|\xtype{} is a -completely expandable nestable loop. complete expandability depends naturally on -the actual iterated contents, and complete expansion will not be achievable -under a sole \fexpan sion, as is indicated by the hollow star in the margin; -thus the loop can be used inside an |\edef| but not inside arguments to the -package macros. It can be used inside an |\xintexpr..\relax|. The -|[start+delta]| is mandatory, not optional. - -This loop benefits via \csbxint{iloopindex} to (a limited access to) the integer -index of the iteration. The starting value |start| (which may be a |\count|) and -increment |delta| (\emph{id.}) are mandatory arguments. A space after the -closing square bracket is not significant, it will be ignored. Spaces inside the -square brackets will also be ignored as the two arguments are first given to a -|\numexpr...\relax|. Empty lines and explicit |\par| tokens are accepted. - -As with \csbxint{loop}, this tool will mostly be of interest to advanced users. -For nesting, one puts inside braces all the -material from the start (immediately after |[start+delta]|) and up to and -inclusive of the inner loop, these braces will be removed and do not create a -loop. In case of nesting, \csbxint{outeriloopindex} gives access to the index of -the outer loop. If needed one could write on its model a macro giving access to -the index of the outer outer loop (or even to the |nth| outer loop). - -The \csa{xintiloopindex} and \csa{xintouteriloopindex} can not be used inside -braces, and generally speaking this means they should be expanded first when -given as argument to a macro, and that this macro receives them as delimited -arguments, not braced ones. Or, but naturally this will break expandability, one -can assign the value of \csa{xintiloopindex} to some |\count|. Both -\csa{xintiloopindex} and \csa{xintouteriloopindex} extend to the litteral -representation of the index, thus in |\ifnum| tests, if it comes last one has to -correctly end the macro with a |\space|, or encapsulate it in a -|\numexpr..\relax|. - -When the repeat-test of the loop is, for example, |\ifnum\xintiloopindex<10 -\repeat|, this means that the last iteration will be with |\xintiloopindex=10| -(assuming |delta=1|). There is also |\ifnum\xintiloopindex=10 \else\repeat| to -get the last iteration to be the one with |\xintiloopindex=10|. - -One has \csbxint{breakiloop} and \csbxint{breakiloopanddo} to abort the loop. -The syntax of |\xintbreakiloopanddo| is a bit surprising, the sequence of tokens -to be executed after breaking the loop is not within braces but is delimited by -a dot as in: -% -\leftedline{|\xintbreakiloopanddo <afterloop>.etc.. etc... \repeat|} -% -The reason is that one may wish to use the then current value of -|\xintiloopindex| in |<afterloop>| but it can't be within braces at the time it -is evaluated. However, it is not that easy as |\xintiloopindex| must be expanded -before, so one ends up with code like this: -% -\leftedline -{|\expandafter\xintbreakiloopanddo\expandafter\macro\xintiloopindex.%|} -% -\leftedline{|etc.. etc.. \repeat|} -% -As moreover the |\fi| from the test leading to the decision of breaking out of -the loop must be cleared out of the way, the above should be -a branch of an expandable conditional test, else one needs something such -as: -% -\leftedline -{|\xint_afterfi{\expandafter\xintbreakiloopanddo\expandafter\macro\xintiloopindex.}%|} -% -\leftedline{|\fi etc..etc.. \repeat|} - -There is \csbxint{iloopskiptonext} to abort the current iteration and skip to -the next, \hyperref[xintiloopskipandredo]{\ttfamily\hyphenchar\font45 \char92 - xintiloopskip\-and\-redo} to skip to the end of the current iteration and redo -it with the same value of the index (something else will have to change for this -not to become an eternal loop\dots ). - -Inside alignments, if the looped-over text contains a |&| or a |\cr|, any -un-expandable material before a \csbxint{iloopindex} will make it fail because -of |\endtemplate|; in such cases one can always either replace |&| by a macro -expanding to it or replace it by a suitable |\firstofone{&}|, and similarly for -|\cr|. - -\phantomsection\label{edefprimes} -As an example, let us construct an |\edef\z{...}| which will define |\z| to be a -list of prime numbers: -\begin{everbatim*} -\begingroup -\edef\z -{\xintiloop [10001+2] - {\xintiloop [3+2] - \ifnum\xintouteriloopindex<\numexpr\xintiloopindex*\xintiloopindex\relax - \xintouteriloopindex, - \expandafter\xintbreakiloop - \fi - \ifnum\xintouteriloopindex=\numexpr - (\xintouteriloopindex/\xintiloopindex)*\xintiloopindex\relax - \else - \repeat - }% no space here - \ifnum \xintiloopindex < 10999 \repeat }% -\meaning\z\endgroup -\end{everbatim*}and we should have taken -some steps to not have a trailing comma, but -the point was to show that one can do that in an |\edef|\,! See also -\autoref{ssec:primesII} which extracts from this code its way of testing -primality. - -Let us create an alignment where each row will contain all divisors of its -first entry. -Here is the output, thus obtained without any count register: -\begin{everbatim*} -\begin{multicols}2 -\tabskip1ex \normalcolor -\halign{&\hfil#\hfil\cr - \xintiloop [1+1] - {\expandafter\bfseries\xintiloopindex & - \xintiloop [1+1] - \ifnum\xintouteriloopindex=\numexpr - (\xintouteriloopindex/\xintiloopindex)*\xintiloopindex\relax - \xintiloopindex&\fi - \ifnum\xintiloopindex<\xintouteriloopindex\space % CRUCIAL \space HERE - \repeat \cr }% - \ifnum\xintiloopindex<30 - \repeat -} -\end{multicols} -\end{everbatim*} -We wanted this first entry in bold face, but |\bfseries| leads to -unexpandable tokens, so the |\expandafter| was necessary for |\xintiloopindex| -and |\xintouteriloopindex| not to be confronted with a hard to digest -|\endtemplate|. An alternative way of coding: -% -\begin{everbatim} -\tabskip1ex -\def\firstofone #1{#1}% -\halign{&\hfil#\hfil\cr - \xintiloop [1+1] - {\bfseries\xintiloopindex\firstofone{&}% - \xintiloop [1+1] \ifnum\xintouteriloopindex=\numexpr - (\xintouteriloopindex/\xintiloopindex)*\xintiloopindex\relax - \xintiloopindex\firstofone{&}\fi - \ifnum\xintiloopindex<\xintouteriloopindex\space % \space is CRUCIAL - \repeat \firstofone{\cr}}% - \ifnum\xintiloopindex<30 \repeat } -\end{everbatim} - -\begin{framed} - The next utilities are not compatible with expansion-only context. -\end{framed} - -\subsection{\csh{xintApplyInline}}\label{xintApplyInline} - - -\csa{xintApplyInline}|{\macro}|\marg{list}\ntype{o{\lowast f}} works non -expandably. It applies the one-parameter |\macro| to the first element of the -expanded list (|\macro| may have itself some arguments, the list item will be -appended as last argument), and is then re-inserted in the input stream after -the tokens resulting from this first expansion of |\macro|. The next item is -then handled. - -This is to be used in situations where one needs to do some repetitive -things. It is not expandable and can not be completely expanded inside a -macro definition, to prepare material for later execution, contrarily to what -\csbxint{Apply} or \csbxint{ApplyUnbraced} achieve. - -\begin{everbatim*} -\def\Macro #1{\advance\cnta #1 , \the\cnta} -\cnta 0 -0\xintApplyInline\Macro {3141592653}. -\end{everbatim*} -The first argument |\macro| does not have to be an expandable macro. - -\csa{xintApplyInline} submits its second, token list parameter to an -\hyperref[ssec:expansions]{\fexpan -sion}. Then, each \emph{unbraced} item will also be \fexpan ded. This provides -an easy way to insert one list inside another. \emph{Braced} items are not -expanded. Spaces in-between items are gobbled (as well as those at the start -or the end of the list), but not the spaces \emph{inside} the braced items. - -\csa{xintApplyInline}, despite being non-expandable, does survive to -contexts where the executed |\macro| closes groups, as happens inside -alignments with the tabulation character |&|. -This tabular provides an example:\par -\begin{everbatim*} -\centerline{\normalcolor\begin{tabular}{ccc} - $N$ & $N^2$ & $N^3$ \\ \hline - \def\Row #1{ #1 & \xintiiSqr {#1} & \xintiiPow {#1}{3} \\ \hline }% - \xintApplyInline \Row {\xintCSVtoList{17,28,39,50,61}} -\end{tabular}}\medskip -\end{everbatim*} - -We see that despite the fact that the first encountered tabulation character in -the first row close a group and thus erases |\Row| from \TeX's memory, -|\xintApplyInline| knows how to deal with this. - -Using \csbxint{ApplyUnbraced} is an alternative: the difference is that -this would have prepared all rows first and only put them back into the -token stream once they are all assembled, whereas with |\xintApplyInline| -each row is constructed and immediately fed back into the token stream: when -one does things with numbers having hundreds of digits, one learns that -keeping on hold and shuffling around hundreds of tokens has an impact on -\TeX{}'s speed (make this ``thousands of tokens'' for the impact to be -noticeable). - -One may nest various |\xintApplyInline|'s. For example (see the -\hyperref[float]{table} \vpageref{float}):\par -\begin{everbatim*} -\begin{figure*}[ht!] - \centering\phantomsection\label{float} - \def\Row #1{#1:\xintApplyInline {\Item {#1}}{0123456789}\\ }% - \def\Item #1#2{&\xintiiPow {#1}{#2}}% - \centeredline {\begin{tabular}{ccccccccccc} &0&1&2&3&4&5&6&7&8&9\\ \hline - \xintApplyInline \Row {0123456789} - \end{tabular}} -\end{figure*} -\end{everbatim*} - -One could not move the definition of |\Item| inside the tabular, -as it would get lost after the first |&|. But this -works: -\everb|@ -\begin{tabular}{ccccccccccc} - &0&1&2&3&4&5&6&7&8&9\\ \hline - \def\Row #1{#1:\xintApplyInline {&\xintiiPow {#1}}{0123456789}\\ }% - \xintApplyInline \Row {0123456789} -\end{tabular} -| - -A limitation is that, contrarily to what one may have expected, the -|\macro| for an |\xintApplyInline| can not be used to define -the |\macro| for a nested sub-|\xintApplyInline|. For example, -this does not work:\par -\everb|@ - \def\Row #1{#1:\def\Item ##1{&\xintiiPow {#1}{##1}}% - \xintApplyInline \Item {0123456789}\\ }% - \xintApplyInline \Row {0123456789} % does not work -| -\noindent But see \csbxint{For}. - -\subsection{\csh{xintFor}, \csh{xintFor*}}\label{xintFor}\label{xintFor*} - -\csbxint{For}\ntype{on} is a new kind of for loop.\footnote{first introduced - with \xintname |1.09c| of |2013/10/09|.} Rather than using macros -for encapsulating list items, its behaviour is like a macro with parameters: -|#1|, |#2|, \dots, |#9| are used to represent the items for up to nine levels of -nested loops. Here is an example: -% -\everb|@ -\xintFor #9 in {1,2,3} \do {% - \xintFor #1 in {4,5,6} \do {% - \xintFor #3 in {7,8,9} \do {% - \xintFor #2 in {10,11,12} \do {% - $$#9\times#1\times#3\times#2=\xintiiPrd{{#1}{#2}{#3}{#9}}$$}}}} -| -\noindent This example illustrates that one does not have to use |#1| as the -first one: -the order is arbitrary. But each level of nesting should have its specific macro -parameter. Nine levels of nesting is presumably overkill, but I did not know -where it was reasonable to stop. |\par| tokens are accepted in both the comma -separated list and the replacement text. - -\begin{framed} - \TeX nical notes: - -\begin{itemize} - \item The |#1| is replaced in the iterated-over text exactly as in general - \TeX\ macros or \LaTeX\ commands. This spares the user quite a few - |\expandafter|'s or other tricks needed with loops which have the - values encapsulated in macros, like \LaTeX's |\@for| and |\@tfor|. - - \item \csa{xintFor} (and \csa{xintFor*}) isn't purely expandable: one can - not use it inside an |\edef|. But it may be used, as will be shown in - examples, in some contexts such as \LaTeX's |tabular| which are usually - hostile to non-expandable loops. - - \item \csa{xintFor} (and \csa{xintFor*}) does some assignments prior to - executing each iteration of the replacement text, but it acts purely - expandably after the last iteration, hence if for example the replacement - text ends with a |\\|, the loop can be used insided a tabular and be - followed by a |\hline| without creating the dreaded ``|Misplaced - \noalign|'' error. - - \item As stated in previous item the first iteration follows some - non-expandable internal dealings. This means for example that in \LaTeX{}, - one can not inject a |\multicolumn| in the first iteration. Sometimes one - way work around this by injecting father |&\multicolumn| or |\\ - \multicolumn|. - - \item It does not create groups. - - \item It makes no global assignments. - - \item The iterated replacement text may close a group which was opened even - before the start of the loop (typical example being with |&| in - alignments). -\begin{everbatim*} -\begin{tabular}{rccccc} - \hline - \xintFor #1 in {A, B, C} \do {% - #1:\xintFor #2 in {a, b, c, d, e} \do {&($ #2 \to #1 $)}\\ }% - \hline -\end{tabular} -\end{everbatim*} - - \item There is no facility provided which would give access to a count of - the number of iterations as it is technically not easy to do so it in a - way working with nested loops while maintaining the ``expandable after - done'' property; something in the spirit of \csbxint{iloopindex} is - possible but this approach would bring its own limitations and - complications. Hence the user is invited to update her own count or - \LaTeX{} counter or macro at each iteration, if needed. - - \item A |\macro| whose definition uses internally an \csbxint{For} loop - may be used inside another \csbxint{For} loop even if the two loops both - use the same macro parameter. The loop definition inside |\macro| - must use |##| as is the general rule for definitions done inside macros. - - \item \csbxint{For} is for comma separated values and \csbxint{For*} for - lists of braced items; their respective expansion policies differ. They - are described later. -\end{itemize} -\unskip -\end{framed} - -\noindent Regarding \csbxint{For}: -\begin{itemize}[nosep, listparindent=\leftmarginiii] -\item the spaces between the various declarative elements are all optional, -\item in the list of comma separated values, spaces around the commas or at - the start and end are ignored, -\item if an item must contain itself its own commas, then it should - be braced, and the braces will be removed before feeding the iterated-over - text, -\item the list may be a macro, it is expanded only once, -\item items are not pre-expanded. The first item should be braced or start - with a space if the list is explicit and the item should not be - pre-expanded, -\item empty items give empty |#1|'s in the replacement text, they are not - skipped, -\item an empty list executes once the replacement text with an empty parameter - value, -\item the list, if not a macro, \fbox{must be braced.} -\end{itemize} - -\noindent Regarding \csbxint{For*}:\ntype{{\lowast f}n} -\begin{itemize}[nosep, listparindent=\leftmarginiii] -\item it handles lists of braced items (or naked tokens), -\item it \hyperref[ssec:expansions]{\fexpan ds} the list, -\item and more generally it \hyperref[ssec:expansions]{\fexpan ds} each naked - token encountered - before assigning the |#1| values (gobbling spaces in the process); - this - makes it easy to simulate concatenation of multiple lists|\x|, |\y|: - if |\x| expands to |{1}{2}{3}| and |\y| expands to |{4}{5}{6}| then |{\x\y}| - as argument to |\xintFor*| has the same effect as |{{1}{2}{3}{4}{5}{6}}|. - - For a further illustration see the use of |\xintFor*| at the end of - \autoref{ssec:fibonacci}. -\item spaces at the start, end, or in-between items are gobbled (but naturally - not the spaces inside \emph{braced} items), -\item except if the list argument is a macro (with no parameters), \fbox{it - must be braced.}, -\item an empty list leads to an empty result. -\end{itemize} - -The macro \csbxint{Seq} which generates arithmetic sequences is to be used -with \csbxint{For*} as its output consists of successive braced numbers (given -as digit tokens). -\begin{everbatim*} -\xintFor* #1 in {\xintSeq [+2]{-7}{+2}}\do {stuff - with #1\xintifForLast{\par}{\newline}} -\end{everbatim*} - - -When nesting \csa{xintFor*} loops, using \csa{xintSeq} in the inner loops is -inefficient, as the arithmetic sequence will be re-created each time. A more -efficient style is: -% -\begin{everbatim} - \edef\innersequence {\xintSeq[+2]{-50}{50}}% - \xintFor* #1 in {\xintSeq {13}{27}} \do - {\xintFor* #2 in \innersequence \do {stuff with #1 and #2}% - .. some other macros .. } -\end{everbatim} - -This is a general remark applying for any nesting of loops, one should avoid -recreating the inner lists of arguments at each iteration of the outer loop. - - -When the loop is defined inside a macro for later execution the |#| characters -must be doubled.% -% -\footnote{sometimes what seems to be a macro argument isn't really; in - \csa{raisebox\{1cm\}\{}\csa{xintFor \#1 in \{a,b,c\} }\csa{do - \{\#1\}\}} no doubling should be done.} -% -For example: -% -\begin{everbatim*} -\def\T{\def\z {}% - \xintFor* ##1 in {{u}{v}{w}} \do {% - \xintFor ##2 in {x,y,z} \do {% - \expandafter\def\expandafter\z\expandafter {\z\sep (##1,##2)} }% - }% -}% -\T\def\sep {\def\sep{, }}\z -\end{everbatim*} - -Similarly when the replacement text -of |\xintFor| defines a macro with parameters, the macro character |#| must be -doubled. - - -The iterated macros as well as the list items are allowed to contain explicit -|\par| tokens. - - -\subsection{\csh{xintifForFirst}, \csh{xintifForLast}} -\label{xintifForFirst}\label{xintifForLast} - -\csbxint{ifForFirst}\,\texttt{\{YES branch\}\{NO branch\}}\etype{nn} - and \csbxint{ifForLast}\,\texttt{\{YES - branch\}\hskip 0pt plus 0.2em \{NO branch\}}\etype{nn} execute the |YES| or -|NO| branch -if the -\csbxint{For} -or \csbxint{For*} loop is currently in its first, respectively last, iteration. - -Designed to work as expected under nesting (but see frame next.) Don't forget -an empty brace pair |{}| if a branch is to do nothing. May be used multiple -times in the replacement text of the loop. - -\begin{framed} - \noindent Pay attention to these implementation features: - \begin{itemize}[nosep, listparindent=\leftmarginiii] - \item \emph{if an inner \csbxint{For} loop is positioned before the - \csb{xintifForFirst} or \csb{xintifForLast} of the outer loop it will - contaminate their settings. This applies also naturally if the inner loop - arises from the expansion of some macro located before the outer - conditionals.} - - One fix is to make sure that the outer conditionals are expanded before the - inner loop is executed, e.g. this will be the case if the inner loop is - located inside one of the branches of the conditional. - - Another approach is to enclose, if feasible, the inner loop in a group of - its own. - \item \emph{if the replacement text closes a group (e.g. from a |&| inside an - alignment), the conditionals will lose their ascribed meanings and end up - possibly undefined, depending whether there is some outer loop whose - execution started before the opening of the group.} - - The fix is to arrange things so that the conditionals are expanded - before \TeX\ encounters the closing-group token. - \end{itemize} -\end{framed} +\def\xintRunningHeader{{\inheadertrue\catcode`,12\relax + \DOCxintfrontpage, + \DOCxintexprintro, + \csname xint bundlename\endcsname}} -\subsection{ \csh{xintBreakFor}, \csh{xintBreakForAndDo}} -\label{xintBreakFor}\label{xintBreakForAndDo} +\part{The \xintexprname and allied packages source code (not + included, see \protect\dtt{sourcexint.pdf})} -One may immediately terminate an \csbxint{For} or \csbxint{For*} loop with -\csbxint{BreakFor}. +\markboth{\makebox[0pt]{\xintRunningHeader}}{\makebox[0pt]{\xintRunningHeader}} +\vspace{1cm} \begin{framed} - As it acts by clearing up all the rest of the replacement text when - encountered, it will not work from inside some |\if...\fi| without - suitable |\expandafter| or swapping technique. - - Also it can't be used from inside braces as from there it can't see the end - of the replacement text. -\end{framed} - -There is also \csbxint{BreakForAndDo}. Both are illustrated by various examples -in the next section which is devoted to ``forever'' loops. - -\subsection{\csh{xintintegers}, \csh{xintdimensions}, \csh{xintrationals}} -\label{xintegers}\label{xintintegers} -\label{xintdimensions}\label{xintrationals} - -If the list argument to \csbxint{For} (or \csbxint{For*}, both are equivalent in -this context) is \csbxint{integers} (equivalently \csbxint{egers}) or more -generally \csbxint{integers}|[||start|\allowbreak|+|\allowbreak|delta||]| -(\emph{the whole within braces}!)% -% -\footnote{the |start+delta| optional specification may have extra spaces - around the plus sign of near the square brackets, such spaces are - removed. The same applies with \csa{xintdimensions} and - \csa{xintrationals}.}, -% -then \csbxint{For} does an infinite iteration where -|#1| (or |#2|, \dots, |#9|) will run through the arithmetic sequence of (short) -integers with initial value |start| and increment |delta| (default values: -|start=1|, |delta=1|; if the optional argument is present it must contains both -of them, and they may be explicit integers, or macros or count registers). The -|#1| (or |#2|, \dots, |#9|) will stand for |\numexpr <opt sign><digits>\relax|, -and the litteral representation as a string of digits can thus be obtained as -\fbox{\csa{the\#1}} or |\number#1|. Such a |#1| can be used in an |\ifnum| test -with no need to be postfixed with a space or a |\relax| and one should -\emph{not} add them. - -If the list argument is \csbxint{dimensions} or more generally -\csbxint{dimensions}|[||start|\allowbreak|+|\allowbreak|delta||]| (\emph{within - braces}!), then -\csbxint{For} does an infinite iteration where |#1| (or |#2|, \dots, |#9|) will -run through the arithmetic sequence of dimensions with initial value -|start| and increment |delta|. Default values: |start=0pt|, |delta=1pt|; if -the optional argument is present it must contain both of them, and they may -be explicit specifications, or macros, or dimen registers, or length macros -in \LaTeX{} (the stretch and shrink components will be discarded). The |#1| -will be |\dimexpr <opt sign><digits>sp\relax|, from which one can get the -litteral (approximate) representation in points via |\the#1|. So |#1| can be -used anywhere \TeX{} expects a dimension (and there is no need in conditionals -to insert a |\relax|, and one should \emph{not} do it), and to print its value -one uses \fbox{\csa{the\#1}}. The chosen representation guarantees exact -incrementation with no rounding errors accumulating from converting into -points at each step. - - - - - - -If the list argument to \csbxint{For} (or \csbxint{For*}) is \csbxint{rationals} -or more generally -\csbxint{rationals}|[||start|\allowbreak|+|\allowbreak|delta||]| (\emph{within - braces}!), then \csbxint{For} does an infinite iteration where |#1| (or |#2|, -\dots, |#9|) will run through the arithmetic sequence of \xintfracname fractions -with initial value |start| and increment |delta| (default values: |start=1/1|, -|delta=1/1|). This loop works \emph{only with \xintfracname loaded}. if the -optional argument is present it must contain both of them, and they may be given -in any of the formats recognized by \xintfracname (fractions, decimal -numbers, numbers in scientific notations, numerators and denominators in -scientific notation, etc...) , or as macros or count registers (if they are -short integers). The |#1| (or |#2|, \dots, |#9|) will be an |a/b| fraction -(without a |[n]| part), where -the denominator |b| is the product of the denominators of -|start| and |delta| (for reasons of speed |#1| is not reduced to irreducible -form, and for another reason explained later |start| and |delta| are not put -either into irreducible form; the input may use explicitely \csa{xintIrr} to -achieve that). -\begin{everbatim*} -\begingroup\small -\noindent\parbox{\dimexpr\linewidth-3em}{\color[named]{OrangeRed}% -\xintFor #1 in {\xintrationals [10/21+1/21]} \do -{#1=\xintifInt {#1} - {\textcolor{blue}{\xintTrunc{10}{#1}}} - {\xintTrunc{10}{#1}}% display in blue if an integer - \xintifGt {#1}{1.123}{\xintBreakFor}{, }% - }} -\endgroup\smallskip -\end{everbatim*} - -\smallskip The example above confirms that computations are done exactly, and -illustrates that the two initial (reduced) denominators are not multiplied when -they are found to be equal. It is thus recommended to input |start| and |delta| -with a common smallest possible denominator, or as fixed point numbers with the -same numbers of digits after the decimal mark; and this is also the reason why -|start| and |delta| are not by default made irreducible. As internally the -computations are done with numerators and denominators completely expanded, one -should be careful not to input numbers in scientific notation with exponents in -the hundreds, as they will get converted into as many zeroes. - -\begin{everbatim*} -\noindent\parbox{\dimexpr.7\linewidth}{\raggedright -\xintFor #1 in {\xintrationals [0.000+0.125]} \do -{\edef\tmp{\xintTrunc{3}{#1}}% - \xintifInt {#1} - {\textcolor{blue}{\tmp}} - {\tmp}% - \xintifGt {#1}{2}{\xintBreakFor}{, }% - }}\smallskip -\end{everbatim*} - -We see here that \csbxint{Trunc} outputs (deliberately) zero as $0$, not (here) -$0.000$, the idea being not to lose the information that the truncated thing was -truly zero. Perhaps this behaviour should be changed? or made optional? Anyhow -printing of fixed points numbers should be dealt with via dedicated packages -such as |numprint| or |siunitx|.\par - - -\subsection{\csh{xintForpair}, \csh{xintForthree}, \csh{xintForfour}}\label{xintForpair}\label{xintForthree}\label{xintForfour} - -The syntax\ntype{on} is illustrated in this -example. The notation is the usual one for |n|-uples, with parentheses and -commas. Spaces around commas and parentheses are ignored. -% -\begin{everbatim*} -{\centering\begin{tabular}{cccc} - \xintForpair #1#2 in { ( A , a ) , ( B , b ) , ( C , c ) } \do {% - \xintForpair #3#4 in { ( X , x ) , ( Y , y ) , ( Z , z ) } \do {% - $\Biggl($\begin{tabular}{cc} - -#1- & -#3-\\ - -#4- & -#2-\\ - \end{tabular}$\Biggr)$&}\\\noalign{\vskip1\jot}}% -\end{tabular}\\} -\end{everbatim*} - -\csbxint{Forpair} must be followed by either |#1#2|, |#2#3|, |#3#4|, \dots, or -|#8#9| with |#1| usable as an alias for |#1#2|, |#2| as alias for |#2#3|, -etc \dots\ and similarly for \csbxint{Forthree} (using |#1#2#3| or simply -|#1|, |#2#3#4| or simply |#2|, \dots) and \csbxint{Forfour} (with |#1#2#3#4| -etc\dots). - -Nesting works as long as the macro parameters are distinct among |#1|, |#2|, -..., |#9|. A macro which expands to an \csa{xintFor} or a -\csa{xintFor(pair,three,four)} can be used in another one with no constraint -about using distinct macro parameters. - -|\par| tokens are accepted in both the comma separated list and the -replacement text. - - -\subsection{\csh{xintAssign}}\label{xintAssign} - -\csa{xintAssign}\meta{braced things}\csa{to}% -\meta{as many cs as they are things} %\ntype{{(f$\to$\lowast [x)}{\lowast N}} -% -defines (without checking if something gets overwritten) the control sequences -on the right of \csa{to} to expand to the successive tokens or braced items -located to the left of \csa{to}. \csa{xintAssign} is not an expandable macro. - -\fexpan sion is first applied to the material in front of \csa{xintAssign} -which is fetched as one argument if it is braced. Then the expansion of this -argument is examined and successive items are assigned to the macros following -|\to|. There must be exactly as many macros as items. No check is done. The -macro assignments are done with removal of one level of brace pairs from each -item. - -After the initial \fexpan sion, each assigned (brace-stripped) item will be -expanded according to the setting of the optional parameter. - -For example |\xintAssign [e]...| means that all assignments are done using -|\edef|. With |[f]| the assignments will be made using -\hyperref[fdef]{\ttfamily\char92fdef}. The default is simply to make the -definitions with |\def|, corresponding to an empty optional paramter |[]|. -Possibilities for the optional parameter are: |[], [g], [e], [x], [o], [go], -[oo], [goo], [f], [gf]|. For example |[oo]| means a double expansion. -\begin{everbatim*} -\xintAssign \xintiiDivision{1000000000000}{133333333}\to\Q\R -\meaning\Q\newline -\meaning\R\newline -\xintAssign {{\xintiiDivision{1000000000000}{133333333}}}\to\X -\meaning\X\newline -\xintAssign [oo]{{\xintiiDivision{1000000000000}{133333333}}}\to\X -\meaning\X\newline -\xintAssign \xintiiPow{7}{13}\to\SevenToThePowerThirteen -\meaning\SevenToThePowerThirteen\par -\end{everbatim*} - -Two special cases: -\begin{itemize}[nosep] -\item if after this initial expansion no brace is found immediately after - \csa{xintAssign}, it is assumed that there is only one control sequence - following |\to|, and this control sequence is then defined via |\def| (or - what is set-up by the optional parameter) to expand to the material between - \csa{xintAssign} and \csa{to}. -\item if the material between \csa{xintAssign} and |\to| is enclosed in two - brace pairs, the first brace pair is removed, then the \fexpan sion is - immediately stopped by the inner brace pair, hence \csa{xintAssign} now - finds a unique item and thus defines only a single macro to be this item, - which is now stripped of the second pair of braces. -\end{itemize} - - -\emph{Note:} prior to release |1.09j|, |\xintAssign| did an |\edef| by default -for each item assignment but it now does |\def| corresponding to no or empty -optional parameter. - -It is allowed for the successive braced items to be separated by spaces. They -are removed during the assignments. But if a single macro is defined (which -happens if the argument after \fexpan sion does not start with a brace), -naturally the scooped up material has all intervening spaces, as it is -considered a -single item. But an upfront initial space will have been absorbed by \fexpan -sion. -\begin{everbatim*} -\def\X{ {a} {b} {c} {d} }\def\Y { u {a} {b} {c} {d} } -\xintAssign\X\to\A\B\C\D -\xintAssign\Y\to\Z -\meaning\A, \meaning\B, \meaning\C, \meaning\D+++\newline -\meaning\Z+++\par -\end{everbatim*} -As usual successive space characters in input make for a single \TeX\ space token. - - -\subsection{\csh{xintAssignArray}}\label{xintAssignArray} - -\xintAssignArray \xintBezout {1000}{113}\to\Bez - -\csa{xintAssignArray}\meta{braced things}\csa{to}\csa{myArray} -% -%\ntype{{(f$\to$\lowast x)}N} -% -first expands fully what comes immediately after |\xintAssignArray| and -expects to find a list of braced things |{A}{B}...| (or tokens). It then -defines \csa{myArray} as a macro with one parameter, such that \csa{myArray\x} -expands to give the |x|th braced thing of this original -list (the argument \texttt{\x} itself is fed to a |\numexpr| by |\myArray|, -and |\myArray| expands in two steps to its output). With |0| as parameter, -\csa{myArray}|{0}| returns the number |M| of elements of the array so that the -successive elements are \csa{myArray}|{1}|, \dots, \csa{myArray}|{M}|. -% -\leftedline{|\xintAssignArray \xintBezout {1000}{113}\to\Bez|} will set -|\Bez{0}| to \dtt{\Bez0}, |\Bez{1}| to \dtt{\Bez1}, |\Bez{2}| to -\dtt{\Bez2}, and |\Bez{3}| to \dtt{\Bez3}: -\dtt{$\Bez1\times1000+\Bez2\times113=\Bez3$.} -This macro is incompatible with expansion-only contexts. - -\csa{xintAssignArray} admits an optional parameter, for example -|\xintAssignArray [e]| means that the definitions of the macros will be made -with |\edef|. The empty optional parameter (default) means that definitions -are done with |\def|. Other possibilities: |[], [o], [oo], [f]|. Contrarily to -\csbxint{Assign} one can not use the |g| here to make the definitions global. -For this, one should rather do |\xintAssignArray| within a group starting with -|\globaldefs 1|. - - -\subsection{\csh{xintDigitsOf}}\label{xintDigitsOf} - -This is a synonym for \csbxint{AssignArray},\ntype{fN} to be used to define -an array giving all the digits of a given (positive, else the minus sign will -be treated as first item) number. -\begingroup\xintDigitsOf\xintiiPow {7}{500}\to\digits -% -\leftedline{|\xintDigitsOf\xintiiPow {7}{500}\to\digits|} -\noindent $7^{500}$ has |\digits{0}=|\digits{0} digits, and the 123rd among them -(starting from the most significant) is -|\digits{123}=|\digits{123}. -\endgroup - -\subsection{\csh{xintRelaxArray}}\label{xintRelaxArray} - -\csa{xintRelaxArray}\csa{myArray} %\ntype{N} -% -(globally) sets to \csa{relax} all macros which were defined by the previous -\csa{xintAssignArray} with \csa{myArray} as array macro. - -\clearpage -\let\xinttoolsnameUp\undefined -\def\n{|{N}|} -\def\m{|{M}|} -\def\x{|{x}|} - -\csname xintexprnameUp\endcsname -\section{Macros of the \xintexprname package}% -\RaisedLabel{sec:oldxintexpr} - -\localtableofcontents - -The \xintexprname package was first released with version |1.07| -(|2013/05/25|) of the \xintname bundle. It was substantially enhanced with -release |1.1| from |2014/10/28|. - -The |1.4| release from |2020/01/31| maintains the same general architecture -but needed adapting all the code base for the switch from |\csname| to -|\expanded| techniques. On this occasion the mechanism for defining functions -was substantially strengthened. The parser core mechanisms were improved too. - -The package loads automatically \xintfracname and \xinttoolsname. - -This section should be trimmed to contain only information not -already covered in \autoref{sec:expr}. - -\subsection{The \csh{xintexpr} expressions} -\label{xintexpr} -\label{xinttheexpr} -\label{thexintexpr} -\label{xintthe} - -An \xintexprname{}ession is a construct -\csbxint{expr}\meta{expandable\_expression}|\relax|\etype{x} where the -expandable expression is read and completely expanded from left to right. - -An |\xintexpr...\relax| \emph{must} end in a |\relax| (which will be absorbed). -Contrarily to a |\numexpr| expression, it is printable\CHANGED{1.4} as is without a prefix -|\the| or |\number| (don't use them with |\xintexpr| this will raise an -error). - -But one can use |\xintthe| prefix if one does need the explicit digits and -other characters as in the final typesetted result. - -As an alternative and equivalent syntax to -\begin{everbatim} -\xintexpr round(<expression>, D)\relax -\end{everbatim} -there is -\begin{everbatim} -\xintiexpr [D] <expression> \relax -\end{everbatim} -For |D>0| this produces a decimal number with |D| figures after the decimal -mark, which is the rounding of the expression. For |D=0| the rounding to an -integer is produced. For |D<0| (and this was changed at |1.4f|), the rounded -quotient of the expression by \verb=1e|D|= is produced. -\begin{itemize} -\item the expression may contain arbitrarily many levels of nested parenthesized - sub-expressions, -\item the expression may contain explicitely or from a macro expansion a - sub-expression |\xintexpr...\relax|, which itself may contain a - sub-expressions etc\dots -\item to let sub-contents evaluate as a sub-unit it should thus be either - \begin{enumerate} - \item parenthesized, - \item or a sub-expression |\xintexpr...\relax|. - \end{enumerate} - \item to use an expression as argument to macros from \xintfracname, - or more generally to macros which expand their arguments, one must use the - |\xinttheexpr...\relax| or |\xintthe\xintexpr...\relax| forms. - \item one should not use |\xintthe\xintexpr...\relax| as a sub-constituent of - another expression but only the - |\xintexpr...\relax| form which is more efficient in this context. - \item each \xintexprname{}ession, whether prefixed or not with |\xintthe|, is - completely expandable and obtains its result in two expansion steps. -\end{itemize} - -The information now following is possibly in need of updates. - -\begin{itemize}[parsep=0pt, labelwidth=\leftmarginii, - itemindent=0pt, listparindent=\leftmarginiii, leftmargin=\leftmarginii] -\item An expression is built the standard way with opening and closing - parentheses, infix operators, and (big) numbers, with possibly a fractional - part, and/or scientific notation (except for \csbxint{iiexpr} which only - admits big integers). All variants work with comma separated expressions. On - output each comma will be followed by a space. A decimal number must have - digits either before or after the decimal mark. + %\small % not now that there is the Part which is rather large -\item As everything gets expanded, the characters |.|, |+|, |-|, |*|, |/|, |^|, - |!|, |&|, \verb+|+, |?|, |:|, |<|, |>|, |=|, |(|, |)|, |"|, |]|, |[|, |@| - and the comma |,| should not (if used in the expression) be active. For - example, the French language in |Babel| system, for pdf\LaTeX, activates |!|, - |?|, |;| and |:|. Turn off the activity before expressions using such characters. - - Alternatively the macro \csbxint{exprSafeCatcodes} resets all - characters potentially needed by \csbxint{expr} to their standard catcodes - and \csbxint{exprRestoreCatcodes} restores the former status. - -\item Count registers and |\numexpr|-essions are accepted (LaTeX{}'s counters - can be inserted using |\value|) natively without |\the| or |\number| as - prefix. Also dimen registers and control sequences, skip registers and - control sequences (\LaTeX{}'s lengths), |\dimexpr|-essions, - |\glueexpr|-essions are automatically unpacked using |\number|, discarding - the stretch and shrink components and giving the dimension value in |sp| - units ($1/65536$th of a \TeX{} point). Furthermore, tacit multiplication is - implied, when the (count or dimen or glue) register or variable, or the - (|\numexpr| or |\dimexpr| or |\glueexpr|) expression is immediately prefixed - by a (decimal) number. See \autoref{ssec:tacit multiplication} for the complete rules - of tacit multiplication.\IMPORTANT - -\item With a macro |\x| defined like this: + This documentation has been compiled without including the + commented source code, which is available in the separate file + |sourcexint.pdf|, + and will open in a PDF viewer via: % - \leftedline{|\def\x {\xintexpr \a + \b \relax}| or |\edef\x {\xintexpr - \a+\b\relax}|} - % - one may then do |\xintthe\x|, either for printing the result on the page or - to use it in some other macros expanding their arguments. The |\edef| does - the computation immediately but keeps it in a protected form. - Naturally, the |\edef| is only possible if |\a| and |\b| are already - defined. With both approaches the |\x| can be inserted in other expressions, - as for example (assuming naturally as we use an |\edef| that in the - `yet-to-be computed' case the |\a| and |\b| now have some suitable meaning): - % - \leftedline {|\edef\y {\xintexpr \x^3\relax}|} - -\item There is also \csbxint{boolexpr}| ... \relax| and - \csbxint{theboolexpr}| ... \relax|. - -\item See also - \csbxint{ifboolexpr} (\autoref{xintifboolexpr}) and the - \func{bool} and \func{togl} functions - in \autoref{sec:expr}. Here is an example. Well in fact the - example ended up using only \csbxint{boolexpr} so it - was modified to use \csbxint{ifboolexpr}. -\catcode`| 12 % -\begin{everbatim*} -\xintdeffunc A(p,q,r) = p && (q || r) ; -\xintdeffunc B(p,q,r) = p || (q && r) ; -\xintdeffunc C(p,q,r) = xor(p, q, r) ; - -\centeredline{\normalcolor -\begin{tabular}{ccrclcl} - \xintFor* #1 in {{False}{True}} \do {% - \xintFor* #2 in {{False}{True}} \do {% - \xintFor* #3 in {{False}{True}} \do {% - #1 &AND &(#2 &OR )&is&\textcolor[named]{OrangeRed} - {\xintifboolexpr{A(#1,#2,#3)}{true}{false}}\\ - #1 &OR &(#2 &AND )&is&\textcolor[named]{OrangeRed} - {\xintifboolexpr{B(#1,#2,#3)}{yes}{no}}\\ - #1 &XOR & #2 &XOR  &is&\textcolor[named]{OrangeRed} - {\xintifboolexpr{C(#1,#2,#3)}{oui}{non}}\\ -}}} -\end{tabular}% -} -\end{everbatim*}\catcode`| 13 - -\item See also \csbxint{ifsgnexpr}. - -\item There is \csbxint{floatexpr}| ... \relax| where the algebra is done - in floating point approximation (also for each intermediate result). Use the - syntax |\xintDigits:=N\relax| to set the precision. Default: $16$ digits. - % - \leftedline{|\xintthefloatexpr 2^100000\relax:| \dtt{\xintthefloatexpr - 2^100000\relax }} - % - The square-root operation can be used in |\xintexpr|, it is computed - as a float with the precision set by |\xintDigits| or by the optional - second argument: - % -\begin{everbatim*} -\xinttheexpr sqrt(2,60)\relax\newline -Here the [60] is to avoid truncation to |\xinttheDigits| of precision on output.\newline -\printnumber{\xintthefloatexpr [60] sqrt(2,60)\relax} -\end{everbatim*} - - Floats are quickly indispensable when using the power function, as exact - results will easily have hundreds, even thousands of digits. - % -\begin{everbatim*} -\xintDigits:=48\relax \xintthefloatexpr 2^100000\relax -\end{everbatim*} - - Only integer and (in |\xintfloatexpr...\relax|) half-integer exponents are - allowed. - -\item if one uses \emph{macros} within |\xintexpr..\relax| one should - obviously take into account that the parser will \emph{not} see the macro - arguments, hence one cannot use the syntax there, except if the arguments - are themselves wrapped as |\xinttheexpr...\relax| and assuming the macro - \fexpan ds these arguments. -\end{itemize} -\subsection{\texorpdfstring{\texttt{\protect\string\numexpr}}{\textbackslash - numexpr} or \texorpdfstring{\texttt{\protect\string\dimexpr}}{\textbackslash - dimexpr} expressions, count and dimension registers and variables} -\label{ssec:countinexpr} - -Count registers, count control sequences, dimen registers, dimen control -sequences (like |\parindent|), skips and skip control sequences, |\numexpr|, -|\dimexpr|, |\glueexpr|, |\fontdimen| can be inserted directly, they will be -unpacked using |\number| which gives the internal value in terms of scaled -points for the dimensional variables: $1$\,|pt|${}=65536$\,|sp| (stretch and -shrink components are thus discarded). - -Tacit multiplication (see \autoref{ssec:tacit multiplication}) is implied, -when a number or decimal number prefixes such a register or control sequence. -\LaTeX{} lengths are skip control sequences and \LaTeX{} counters should be -inserted using |\value|. - -Release |1.2| of the |\xintexpr| parser also recognizes and prefixes with -|\number| the |\ht|, |\dp|, and |\wd| \TeX{} primitives as well as the -|\fontcharht|, |\fontcharwd|, |\fontchardp| and |\fontcharic| \eTeX{} -primitives. - -In the case of numbered registers like |\count255| or |\dimen0| (or |\ht0|), -the resulting digits will be re-parsed, so for example |\count255 0| is like -|100| if |\the\count255| would give |10|. The same happens with inputs such -as |\fontdimen6\font|. And |\numexpr 35+52\relax| will be exactly as if |87| -as been encountered by the parser, thus more digits may follow: |\numexpr -35+52\relax 000| is like |87000|. If a new |\numexpr| follows, it is treated -as what would happen when |\xintexpr| scans a number and finds a non-digit: it -does a tacit multiplication. -\begin{everbatim*} -\xinttheexpr \numexpr 351+877\relax\numexpr 1000-125\relax\relax{} is the same -as \xinttheexpr 1228*875\relax. -\end{everbatim*} - -Control sequences however (such as |\parindent|) are picked up as a whole by -|\xintexpr|, and the numbers they define cannot be extended extra digits, a -syntax error is raised if the parser finds digits rather than a legal -operation after such a control sequence. - -A token list variable must be prefixed by |\the|, it will not be unpacked -automatically (the parser will actually try |\number|, and thus fail). Do not -use |\the| but only |\number| with a dimen or skip, as the |\xintexpr| parser -doesn't understand |pt| and its presence is a syntax error. To use a dimension -expressed in terms of points or other \TeX{} recognized units, incorporate it in -|\dimexpr...\relax|. - -Regarding how dimensional expressions are converted by \TeX{} into scaled points -see also \autoref{sec:Dimensions}. - -\subsection{Catcodes and spaces} - -The main problems are caused by active characters, because \csbxint{expr} et -al.\@ expand forward whatever comes from token stream; they apply |\string| -only in a second step. For example the catcode of |&| from |&&| Boolean -disjunction is not really important as long as it is not active, or comment, -or escape...\@ or brace...\@ or ignored...\@ in brief, as long as it is reasonable, -and in particular whether |@| is of catcode letter or other does not matter. - -It is always possible to insert manually the |\string| in the expression -before a problematic (but reasonable) character catcode, or even to use -|\detokenize| for a big chunk. - -\subsubsection{\csh{xintexprSafeCatcodes}} -\label{xintexprSafeCatcodes} - -Some problems with active characters can be resolved on the fly by prefixing -them by |\string| but some aspects of the parsing done by \csbxint{expr} -involves delimited macros which need the comma, equality sign and closing -parenthesis to have their standard catcodes. - -So \csbxint{exprSafeCatcodes} is provided as a utility to set in one go -catcodes of many characters to \csbxint{expr}-safely compatible values. This -is a non-expandable step as it changes catcodes. -% This is used -% internally by \csbxint{NewExpr} (restoring the catcodes on exit), hence it -% does not have to be protected against active characters when used at -% top-level. - -\csbxint{defvar}, \csbxint{deffunc}, et al., use it, and then they restore -catcodes to the prior state via \csbxint{exprRestoreCatcodes}. - -% As \csbxint{NewExpr} and \csbxint{deffunc} and variants use internally some -% |\scantokens|, they will (reasonably) succeed in sanitizing catcodes in the -% expressions, even if all is from the replacement text of some macro whose -% definition was done under some special catcode regime. - -% \csbxint{deffunc} is more lenient than \csbxint{defvar} regarding catcodes of -% characters in expression bodies as it does some |\scantokens| which will reset -% compatible catcodes. - -% Even if used in a context where catcodes are already set, \csbxint{deffunc}, -% \csbxint{defvar} and variants ignore completely the colon in |:=| so it can -% have any (reasonable) catcode. Moreover it is optional. - -% The semi-colon in the syntax of \csbxint{Digits} is no real problem either -% (cf. \csbxint{Digits} documentation). - -\subsubsection{\csh{xintexprRestoreCatcodes}} -\label{xintexprRestoreCatcodes} - -Restores the catcodes to the state prevailing at the time of the last executed -\csbxint{exprSafeCatcodes} (if located at the same \LaTeX\ environment or -\TeX\ grouping level). - -Prior to |1.4k|, in a situation like the following: -\begin{everbatim} -\xintexprSafeCatcodes -....stuff possibly changing catcodes -\xintexprSafeCatcodes -....stuff possibly changing catcodes -\xintexprSafeCatcodes -....stuff possibly changing catcodes -\xintexprRestoreCatcodes -\end{everbatim} -On exit, the catcodes recovered their status as prior to the \emph{first} -\csbxint{exprSafeCatcodes}. Since |1.4k|, they are set to what they were -prior to the \emph{last} \csbxint{exprSafeCatcodes}, i.e. the mechanism is now -similar to a ``last in, first out'' stack. - -Note that no global assignments are made so the behaviour can be modified -by usage of \TeX\ groups or \LaTeX\ environments: e.g. if an -\csbxint{exprSafeCatcodes} is issued inside a \LaTeX\ environment it does not -have to be paired by \csbxint{exprRestoreCatcodes} explicitly, the catcode -scope is limited by the environment. - -\bigskip - -Spaces inside an |\xinttheexpr...\relax| should mostly be -innocuous (except inside macro arguments). - -|\xintexpr| and |\xinttheexpr| are for the most part agnostic regarding -catcodes, % (unbraced) digits, binary operators, minus and plus signs as -% prefixes, dot as decimal mark, parentheses, may be indifferently of catcode -% letter or other or subscript or superscript, ..., except that they -% should not be \emph{active}, as for example are |!?;:| with |babel-french|.% -% % -% \footnote{Furthermore, although \csbxint{expr} uses \csa{string}, it is -% escape-char agnostic. It should work with any \csa{escapechar} setting -% including -1.} -but the characters -% |+|, |-|, |*|, |/|, |^|, |!|, |&|, \verb+|+, |?|, |:|, |<|, |>|, -%|=|, |(|, |)|, |"|, |[|, |]|, |;|, -in the expression should not be «active» (except on purpose) as everything is -expanded along the way, and |\xintexpr| will choke on typesetting related -commands. One can use |\string| to prefix a problematic character. - - -Digits, slash, square brackets, minus sign, in the output from an -|\xinttheexpr| are all of catcode 12. For |\xintthefloatexpr| the `e' in the -output has its standard catcode ``letter''. - - - - -\subsection{Expandability, \csh{xintexpro}} - -As is the case with all other package macros |\xintexpr| \fexpan ds (in two -steps) to its final (somewhat protected) result; and |\xinttheexpr| \fexpan ds -(in two steps) to the chain of digits (and possibly minus sign |-|, decimal -mark |.|, fraction slash |/|, scientific |e|, square brackets |[|, |]|) -representing the result. - -The once expanded |\xintexpr| is |\romannumeral0\xintexpro|. is similarly -|\xintiexpro| |\xintiiexpro| and |\xintfloatexpro|. For an example see -\autoref{ssec:fibonacci}. - -An expression can only be legally finished by a |\relax| token, which -will be absorbed. - -It is quite possible to nest expressions among themselves; for example, if one -needs inside an |\xintiiexpr...\relax| to do some computations with fractions, -rounding the final result to an integer, one just has to insert -|\xintiexpr...\relax|. The functioning of the infix operators will not be in -the least affected from the fact that the outer ``environment'' is the -|\xintiiexpr| one. - - -\subsection{\csh{xintDigits*}, \csh{xintSetDigits*}} -\label{xintDigits*} -\label{xintSetDigits*} - -These starred variants of \csbxint{Digits} and \csbxint{SetDigits} execute -\csbxint{reloadxinttrig} and \csbxint{reloadxintlog}. - -\subsection{\csh{xintiexpr}, \csh{xinttheiexpr}} -\label{xintiexpr}\label{xinttheiexpr}\label{thexintiexpr} - -Equivalent\etype{x} to doing |\xintexpr round(...)\relax| (more precisely, -|round| is applied to each leaf item of the |ople| independently of its -depth). - -Intermediate calculations are exact, only the final output gets -rounded. Half integers are rounded towards $+\infty$ for positive -numbers and towards $-\infty$ for negative ones. - -An optional parameter |D| within brackets, immediately after |\xintiexpr| is -allowed: it instructs (for |D>0|) the expression to do its final rounding to -the nearest value with that many digits after the decimal mark, i.e.\@ -|\xintiexpr [D] <expression>\relax| is equivalent (in case of a single -expression) to |\xintexpr round(<expression>, D)\relax|. - -|\xintiexpr [0] ...| is the same as |\xintiexpr ...| and rounds to an integer. - -The case of negative |D| gives quantization to an integer multiple of -\dtt{1e-D}.\NewWith{1.4a} This was modified at |1.4f| and the produced value -is now the rounded quotient by \dtt{1e-D} (i.e. no trailing zeros nor -scientific exponent in the output). - -If truncation rather than rounding is needed on can use |\xintexpr -trunc(...)\relax| for truncation to an integer or |\xintexpr -trunc(...,D)\relax| for quantization to an integer multiple or \dtt{1eD} (if -|D>0|, for |D<0| the analog would be |trunc((...)/1e-D)|). But -this works only for a single scalar value. - - -\subsection{\csh{xintiiexpr}, \csh{xinttheiiexpr}} -\label{xintiiexpr}\label{xinttheiiexpr}\label{thexintiiexpr} - -This variant\etype{x} does not know fractions. It deals almost only with long -integers. Comma separated lists of expressions are allowed. - -\begin{framed} - It maps |/| to the \emph{rounded} quotient. The operator - |//| is, like in |\xintexpr...\relax|, mapped to \emph{truncated} division. - The Euclidean quotient (which for positive operands is like the truncated - quotient) was, prior to release |1.1|, associated to |/|. The function - |quo(a,b)| can still be employed. -\end{framed} - -The \csbxint{iiexpr}-essions use the `ii' macros for addition, subtraction, -multiplication, power, square, sums, products, Euclidean quotient and -remainder. - -The |round|, |trunc|, |floor|, |ceil| functions are still available, and are -about the only places where fractions can be used, but |/| within, if not -somehow hidden will be executed as integer rounded division. To avoid this one -can wrap the input in \dtt{qfrac}: this means however that none of the normal -expression parsing will be executed on the argument. - -To understand the illustrative examples, recall that |round| and |trunc| have -a second (non negative) optional argument. In a normal \csbxint{expr}-essions, -|round| and |trunc| are mapped to \csbxint{Round} and \csbxint{Trunc}, in -\csbxint{iiexpr}-essions, they are mapped to \csbxint{iRound} and -\csbxint{iTrunc}. - - -\begin{everbatim*} -\xinttheiiexpr 5/3, round(5/3,3), trunc(5/3,3), trunc(\xintDiv {5}{3},3), -trunc(\xintRaw {5/3},3)\relax{} are problematic, but -% -\xinttheiiexpr 5/3, round(qfrac(5/3),3), trunc(qfrac(5/3),3), floor(qfrac(5/3)), -ceil(qfrac(5/3))\relax{} work! -\end{everbatim*} - -On the other hand decimal numbers and scientific numbers can be used directly -as arguments to the |num|, |round|, or any function producing an integer. - -\begin{framed} - Scientific numbers will be - represented with as many zeroes as necessary, thus one does not want to - insert \dtt{num(1e100000)} for example in an \csa{xintiiexpr}ession! -\end{framed} - -% -\begin{everbatim*} -\xinttheiiexpr num(13.4567e3)+num(10000123e-3)\relax % should (num truncates) compute 13456+10000 -\end{everbatim*} -% - -The |reduce| function is not available and will raise an error. The |frac| -function also. The |sqrt| function is mapped to \csbxint{iiSqrt} which gives -a truncated square root. The |sqrtr| function is mapped to \csbxint{iiSqrtR} -which gives a rounded square root. - -One can use the Float macros if one is careful to use |num|, or |round| -etc\dots on their output. - -\begin{everbatim*} -\xinttheiiexpr \xintFloatSqrt [20]{2}, \xintFloatSqrt [20]{3}\relax % no operations - -\noindent The next example requires the |round|, and one could not put the |+| inside it: - -\xinttheiiexpr round(\xintFloatSqrt [20]{2},19)+round(\xintFloatSqrt [20]{3},19)\relax - -(the second argument of |round| and |trunc| tells how many digits from after the -decimal mark one should keep.) -\end{everbatim*} - -The whole point of \csbxint{iiexpr} is to gain some speed in -\emph{integer-only} algorithms, and the above explanations related to how to -nevertheless use fractions therein are a bit peripheral. We observed -(2013/12/18) of the order of $30$\% speed gain when dealing with numbers with -circa one hundred digits (1.2: this info may be obsolete). - - -\subsection{\csh{xintboolexpr}, \csh{xinttheboolexpr}} -\label{xintboolexpr}\label{xinttheboolexpr}\label{thexintboolexpr} - -Equivalent\etype{x} to doing |\xintexpr ...\relax| and returning $True$ if the -result does not vanish, and $False$ if the result is zero. As |\xintexpr|, this -can be used on comma separated lists of expressions, and even bracketed lists. -\CHANGED{1.4} - -It can be customized, one only needs to modify the following: -\begin{everbatim} -\def\xintboolexprPrintOne#1{\xintiiifNotZero{#1}{True}{False}}% -\end{everbatim} -Not only are |True| and |False| usable in input, also |true| and |false| are -pre-declared variables. - -Maybe obsolete: - -There is slight quirk in case it is used as a sub-expression: the boolean -expression needs at least one logic operation else the value is not -standardized to |1| or |0|, for example we get from -\begin{everbatim*} -\xinttheexpr \xintboolexpr 1.23\relax\relax\newline -\end{everbatim*}which is to be compared with -\begin{everbatim*} -\xinttheboolexpr 1.23\relax -\end{everbatim*} - -% A related issue existed with -% |\xinttheexpr \xintiexpr 1.23\relax\relax|, which was fixed with |1.1| -% release, and I decided back then not to add the needed overhead also to the -% |\xintboolexpr| context, as one only needs to use |?(1.23)| for example or -% involve the |1.23| in any logic operation like |1.23 'and' 3.45|, or involve -% the |\xintboolexpr ..\relax | itself with any logical operation, contrarily to -% the sub-|\xintiexpr| case where |\xinttheexpr 1+\xintiexpr 1.23\relax\relax| -% did behave contrarily to expectations until |1.1|. - - -\subsection{\csh{xintfloatexpr}, - \csh{xintthefloatexpr}} -\label{xintfloatexpr}\label{xintthefloatexpr}\label{thexintfloatexpr} - -\csbxint{floatexpr}|...\relax|\etype{x} is exactly like |\xintexpr...\relax| -but with the four binary operations and the power function are mapped to -\csa{xintFloatAdd}, \csa{xintFloatSub}, \csa{xintFloatMul}, \csa{xintFloatDiv} -and \csa{xintFloatPower}, respectively.\footnote{Since |1.2f| the \string^ - handles half-integer exponents, contrarily to \csa{xintFloatPower}.} - -The target precision for the computation is from the -current setting of |\xintDigits|. Comma separated lists of expressions are -allowed. - -An optional parameter within brackets is allowed: -\begin{itemize} -\item if positive it instructs the macro to round the result to that many - digits of precision. It thus makes sense to employ it only if this parameter is - less than the \csbxint{theDigits} precision. -\item if negative it means to trim off that many digits (of course, in the - sense of rounding - the values to shorter mantissas). Don't use it to trim all digits (or more than all)! -\end{itemize} - -Since |1.2f| all float operations first round their arguments; a parsed number -is not rounded prior to its use as operand to such a float operation. - -|\thexintfloatexpr| is synonym to |\xintthefloatexpr|. - -|\xintDigits:=36\relax|\xintDigits:=36\relax -% -\leftedline{|\xintthefloatexpr - (1/13+1/121)*(1/179-1/173)/(1/19-1/18)\relax|} -% -\leftedline{\dtt{\xintthefloatexpr - (1/13+1/121)*(1/179-1/173)/(1/19-1/18)\relax}} -% 0.00564487459334466559166166079096852897 -% -\leftedline{|\xintthefloatexpr\xintexpr - (1/13+1/121)*(1/179-1/173)/(1/19-1/18)\relax\relax|} -% -\leftedline{\dtt{\xintthefloatexpr\xintexpr - (1/13+1/121)*(1/179-1/173)/(1/19-1/18)\relax\relax}} - -\xintDigits := 16; - -The latter is the rounding of the exact result. The former one has -its last three digits wrong due to the cumulative effect of rounding errors -in the intermediate computations, as compared to exact evaluations. - - - - -I recall here from \autoref{ssec:floatingpoint} that with release |1.2f| the -float macros for addition, subtraction, multiplication and division round -their arguments first to |P| significant places with |P| the asked-for -precision of the output; and similarly the power macros and the -square root macro. This does not modify anything for computations with -arguments having at most |P| significant places already. - -\subsection{\csh{xinteval}, \csh{xintieval}, \csh{xintiieval}, - \csh{xintfloateval}} -\label{xinteval}\label{xintieval}\label{xintiieval}\label{xintfloateval} - -\csbxint{eval}\etype{x} is an \fexpan dable macro which is basically defined -like this (this is obsolete since |1.4|): -\begin{everbatim} -\def\xinteval#1{\romannumeral-`0\xinttheexpr#1\relax}% THIS IS OLD DEFINITION -\end{everbatim} -thus expands in two steps. -\begin{everbatim*} -\xinteval{add(x^2, x = 100..110), add(x^3, x = 100..110)} -\end{everbatim*} - -\csbxint{ieval}\etype{x} is similarly related to \csbxint{theiexpr}. Its -optional argument may be located in the expected location for \LaTeX\ users -since |1.4k|, but was long constrained to be inside the braces. -\begin{everbatim*} -\xintieval[7]{355/113} = \xintieval{[7]355/113} -\end{everbatim*} - -If one defines a macro which will do something such as |\xintieval{#1}| it is -recommended to code it as |\xintieval{\empty#1}| in case the |#1| will start -with some |[|, which will end up confusing |\xintieval|. - -\csbxint{iieval}\etype{x} is similarly related to \csbxint{theiiexpr}. -\begin{everbatim*} -\xintiieval{add(x^2, x = 100..110), add(x^3, x = 100..110)} -\end{everbatim*} - -\csbxint{floateval}\etype{x} is similarly related to -\csbxint{thefloatexpr}. The same remarks as for |\xintieval| apply. -\begin{everbatim*} -\xintfloateval [7]{355/113} = \xintfloateval{[7] 355/113} -\end{everbatim*} - -When negative, the optional argument tells how many digits to remove from the -prevailing precision (\csbxint{theDigits}): -\begin{everbatim*} -\xintfloateval[-2]{355/113}=\xintfloateval{[-2]355/113} has \xinttheDigits\ minus 2 digits. -\end{everbatim*} - -These macros are useful when one uses some extra wrapper doing some parsing of -its input, like the |\num| macro of -\href{http://ctan.org/pkg/siunitx}{siunitx}, which would choke on some of the -syntax elements allowed inside \csb{xintexpr}|...\relax| (for example -brackets). -As shown in the above examples, these macros, like the underlying parsers -accept arbitrarily many comma separated expressions. - - -\subsection{Using an expression parser within another one} - -This was already illustrated before. In the following: -\begin{everbatim*} -\xintfloatexpr \xintexpr add(1/i, i=1234..1243)\relax ^100\relax -\end{everbatim*}, -the inner sum is computed exactly. Then it will be rounded to |\xinttheDigits| -significant digits, and then its power will be evaluated as a float operation. -One should avoid the "|\xintthe|" parsers in inner positions as this induces -digit by digit parsing of the inner computation result by the outer parser. -Here is the same computation done with floats all the way: -\begin{everbatim*} -\xintfloatexpr add(1/i, i=1234..1243)^100\relax -\end{everbatim*} - -Not surprisingly this differs from the previous one which was exact until -raising to the |100|th power. - -The fact that the inner expression occurs inside a bigger one has nil -influence on its behaviour. There is the limitation though that the outputs -from \csbxint{expr} and \csbxint{floatexpr} can not be used directly in -\csbxint{theiiexpr} integer-only parser. But one can do: -\begin{everbatim*} -\xintiiexpr round(\xintfloatexpr 3.14^10\relax)\relax % or trunc -\end{everbatim*} - - -\subsection{\csh{xintFracToSci}}\label{xintFracToSci} - -% je ne dois pas mettre \Ff car la macro n'utilise pas \XINT_infrac - -\csa{xintFracToSci}\NewWith{1.4} is for usage by \csbxint{eval} for -formatting the output of numbers. It is not meant for direct use at -user level as it currently expects input formatted in the so-called -``relaxed raw format'' from \xintfracname, i.e. |A/B[N]|, with |/B| and -|[N]| being optional parts, and |A|, |B|, |N| being integers, |B| always -positive if present, and |A| having at most one leading minus sign (and -no sign if it is zero, and no leading zeros). - -Here is what it does:\CHANGED{1.4e} -\begin{itemize}[noitemsep,nosep] -\item with input respectively: |A|, |A/B|, |A[N]|, |A/B[N]| -\item it produces this output: |A|, |A/B| (if |B| is not |1|), |A| if - |N=0|, |A/B| if |N=0| (no |B| if |1|), and if - |N| is not zero, the output will be |AeN| written in scientific notation - exactly like it would by \csbxint{PFloat} but without of course prior - rounding to a given number of digits; in particular trailing zeros in the - significand will be removed. Then this value in scientific notation - (or decimal fixed point notation if the scientific exponent is in the - range deciding so by \csbxint{PFloat}) will be attached to a trailing - denominator part |/B| (if not equal to |1|). -\end{itemize} -Please note: -\begin{itemize} -\item there is no reduction of the fraction |A/B| to lowest terms, -\item trailing zeros in |B| are not moved and incorporated -into the final scientific exponent, -\item no attempt is made to check is |B| is only products of |2|'s and - |5|'s and thus could be integrated into some pure decimal notation for - the numerator or at least its significand. -\end{itemize} -This has not changed since |1.4| but is to be considered -\emph{unstable}. Actually even the description above was until |1.4k| -only to be found in the commented source code... So everything is -susceptible to change at some later release. - -Changes\CHANGED{1.4k} of \csbxint{PFloat} at |1.4k| have an impact here. -In particular the zero value will give \dtt{0} whether the input was -some |0|, |0e-5|, |0/3|, |0.00|, etc\dots, whereas at |1.4e| it would -have been -\dtt{0.0} for cases triggering some \csbxint{PFloat} subroutine. See -\csbxint{PFloatZero} for reenacting the |1.4e| behaviour. - -\medskip - -The output routine of \csbxint{eval} uses -\csbxint{exprPrintOne} whose current default definition is: -\begin{everbatim} -\def\xintexprPrintOne{\xintFracToSci} -\end{everbatim} -Any replacement should obey the following blueprint: -\begin{itemize}[noitemsep] -\item to\xtype{} be expandable, but not necessarily \fexpan dable, -\item to accept on input |A|, |A/B|, |A[N]|, or |A/B[N]|, i.e. the - ``relaxed raw'' - \xintfracname format. -\end{itemize} -% These constraints\CHANGED{1.4e} are much simplified at |1.4e| (and -% \csa{xintFracToSci} has been internally simplified to only have to obey -% the reduced constraints, which is a breaking change). - -% At |1.4e| the handling\CHANGED{1.4e} by this macro of input with a scientific -% exponent part has changed. Rather than producing an integer mantissa it now -% does as \csbxint{PFloat}, apart of course from its initial step of -% float-rounding. It trims out trailing zeros of the input always. - -Attention, \csa{xintFracToSci} does not behave as do the public macros from -\xintfracname: -\begin{itemize}[noitemsep] -\item it is expandable, but not \fexpan dable, so it can't appear as argument - to \xintfracname macros without an explicit |\expanded{...}| wrapper - (as they only \fexpan d their arguments). -\item it expects input which after \fexpan sion will be in ``relaxed raw'' - \xintfracname format.\IMPORTANT{} -\end{itemize} - -%\noindent\csa{xintFracToSciE} has been removed at |1.4e|, see \csbxint{PFloatE}. - -\subsection{\csh{xintFracToDecimal}} -\label{xintFracToDecimal} - -% je ne dois pas mettre \Ff car la macro n'utilise pas \XINT_infrac -% mais je pourrais utiliser \xtype -It is a variant of \csbxint{FracToSci}\NewWith{1.4k} -which differs from it in so far as it outputs a numerator using decimal -notation, i.e. with as many zeros as are needed (and no more) and no -scientific exponent. The denominator goes through ``as is'' except if -it is |1|, then it is omitted. - -In other terms its behaviour is currently intermediate between -\csbxint{DecToString} and \csbxint{DecToStringREZ}, as it does not -remove trailing zeros of the denominator. - -It is not meant to be used directly as it shares the same limitations -of \csbxint{FracToSci} for user level usage, but solely as a way to -customize \csbxint{exprPrintOne}: -\begin{everbatim} -\def\xintexprPrintOne{\xintFracToDecimal} -\end{everbatim} -Consider its behaviour as \emph{unstable} and \emph{barely documented}. - - -\subsection{The \csh{xintthecoords} macro} -\label{xintthecoords} - -It converts (in two expansion steps) the expansion result of -\csbxint{floatexpr} (or \csbxint{expr} or \csbxint{iiexpr}) into the |(a, b) -(c, d) ...| format for list of coordinates as expected by the |TikZ| -|coordinates| syntax.% -\begin{everbatim*} -\begin{figure}[htbp] -\centering\begin{tikzpicture}[scale=10]\xintDigits:=8\relax - \clip (-1.1,-.25) rectangle (.3,.25); - \draw [blue] (-1.1,0)--(1,0); - \draw [blue] (0,-1)--(0,+1); - \draw [red] plot[smooth] coordinates {% -%%% (\xintthecoords converts output of next expression into (x1, y1) (x2, y2)... format) - \xintthecoords\xintfloatexpr -%%% This syntax -1+[0..4]/2 is currenty dropped at xint 1.4 -%%% seq((x^2-1,mul(x-t,t=-1+[0..4]/2)),x=-1.2..[0.1]..+1.2)\relax -%%% Use this: - seq((x^2-1,mul(x-t,t=seq(-1+u/2, u=0..4))),x=-1.2..[0.1]..+1.2) - \relax - }; -\end{tikzpicture} -\caption{Coordinates with \cs{xintthecoords}.} -\end{figure} -\end{everbatim*} - -% Notice: if x goes not take exactly value 1 or -1, the origin appears slightly -% off the curve, not MY fault!!! -It is currently undecided how \csa{xintthecoords} should handle bracketed -data.\UNSTABLE{} Currently, it (or |TikZ|) will break it the input contains -nested structures. One can use it with \func{flat} which removes all nesting. -And in combination with \func{zip} it is easy to plot data given by some -mechanism in separate -lists of x- and y-coordinates (see an example in next section) - -\subsection{The \csh{xintthespaceseparated} macro} -\label{xintthespaceseparated} - -It converts (in two expansion steps)\NewWith{1.4a} the expansion result of -\csbxint{floatexpr} (or \csbxint{expr} or \csbxint{iiexpr}) into the space -separated format suitable for usage with |PS-Tricks| |\listplot| macro. - -Here is for example some syntax (the replacement text of |\foo|, which is used -here only to show that indeed complete expansion is attained in two steps) -which can be used as argument to |\listplot|. Using 4 fractional decimal -digits is sufficient when unit is the centimeter (it gives a fixed point -precision of one micron, amply enough for plots...). -\begin{everbatim*} -\oodef\foo{% -\xintthespaceseparated\xintiexpr[4]\xintfloatexpr seq((i, log10(i)), i=1..[0.5]..10)\relax\relax -}\meaning\foo -\end{everbatim*} - -Here we don't really need the inner |\xintfloatexpr...\relax| because the -\func{log10} function works the same in the exact parser |\xintexpr| but in -general this is recommended. - -It is currently undecided how \csa{xintthespaceseparated} should handle -bracketed data.\UNSTABLE{} Currently, it (or |\listplot|) will break if the -input contains nested structures. One can use it with \func{flat} which -removes all nesting. And in combination with \func{zip} it is easy to plot -data given by some mechanism in separate lists of x- and y-coordinates. - -\begin{everbatim*} -% let's imagine we have something like this -\def\Xcoordinates{1, 3, 5, 7, 9} -\def\Ycoordinates{1, 9, 25, 49, 81} -% then: -|\xintthespaceseparated\xintexpr flat(zip([\Xcoordinates], [\Ycoordinates]))\relax| -is suitable to use as argument to |\listplot|, as it expands to -\xintthespaceseparated\xintexpr flat(zip([\Xcoordinates], [\Ycoordinates]))\relax -\end{everbatim*} - -\subsection{\csh{xintifboolexpr}, \csh{xintifboolfloatexpr}, \csh{xintifbooliiexpr}} -\label{xintifboolexpr} -\label{xintifboolfloatexpr} -\label{xintifbooliiexpr} - -\csh{xintifboolexpr}\marg{expr}\marg{YES}\marg{NO}\etype{xnn} does -\csbxint{theexpr}<expr>|\relax| and then executes the \meta{YES} or the -\meta{NO} branch depending on whether the outcome was non-zero or zero. Thus -one can read \emph{if bool expr} as meaning \emph{if not zero}: -\centeredline{if \meta{expr}-ession does not vanish do \meta{YES} else do - \meta{NO}} - -The expression is not limited to using only comparison operators and Boolean -logic (|<|, |>|, |==|, |!=|, |&&|, \verb+||+, \func{all}, \func{any}, -\func{xor}, \func{bool}, \func{togl}, ...), it can be the most general -computation. - -\csh{xintifboolfloatexpr}\marg{expr}\marg{YES}\marg{NO}\etype{xnn} does -\csbxint{thefloatexpr}\meta{expr}|\relax| and then executes the \meta{YES} or the -\meta{NO} branch depending on whether the outcome was non zero or zero. - -\csh{xintifbooliiexpr}\marg{expr}\marg{YES}\marg{NO}\etype{xnn} does -\csbxint{theiiexpr}\meta{expr}|\relax| and then executes the \meta{YES} or the -\meta{NO} branch depending on whether the outcome was non zero or zero. - -The expression argument must be a single one, comma separated sub-expressions -will cause low-level errors. - -\subsection{\csh{xintifsgnexpr}, \csh{xintifsgnfloatexpr}, \csh{xintifsgniiexpr}} -\label{xintifsgnexpr} -\label{xintifsgnfloatexpr} -\label{xintifsgniiexpr} - -\csh{xintifsgnexpr}\marg{expr}\marg{<0}\marg{=0}\marg{>0}\etype{xnnn} evaluates -the \csbxint{expr}ession and chooses the branch corresponding to its sign. - -\csh{xintifsgnfloatexpr}\marg{expr}\marg{<0}\marg{=0}\marg{>0}\etype{xnnn} evaluates -the \csbxint{floatexpr}ession and chooses the branch corresponding to its sign. - -\csh{xintifsgniiexpr}\marg{expr}\marg{<0}\marg{=0}\marg{>0}\etype{xnnn} evaluates -the \csbxint{iiexpr}ession and chooses the branch corresponding to its sign. - -The expression argument must be a single one, comma separated sub-expressions -will cause low-level errors. - -\subsection{The \csh{xintNewExpr}, \csh{xintNewIIExpr}, - \csh{xintNewFloatExpr}, \csh{xintNewIExpr}, and \csh{xintNewBoolExpr} - macros} -\label{xintNewExpr} -\label{xintNewIIExpr} -\label{xintNewFloatExpr} -\label{xintNewIExpr} -\label{xintNewBoolExpr} - -\csbxint{NewExpr} macro is used as: -% -\leftedline{|\xintNewExpr{\myformula}[n]|\marg{stuff}, where} -\begin{itemize} -\item \meta{stuff} will be inserted inside |\xinttheexpr . . . \relax|, -\item |n| is an integer between zero and nine, inclusive, which is the number - of parameters of |\myformula|, -\item the placeholders |#1|, |#2|, ..., |#n| are used inside \meta{stuff} in - their usual r\^ole,% -% -\catcode`# 12 -\footnote{if \csa{xintNewExpr} is used inside a macro, - the |#|'s must be doubled as usual.} - \footnote{the |#|'s will in pratice have their usual - catcode, but category code other |#|'s are accepted too.} -\catcode`# 6 -% -\item the |[n]| is \emph{mandatory}, even for |n=0|.% -\footnote{there is some use for \csa{xintNewExpr}|[0]| compared to an - \csa{edef} as \csa{xintNewExpr} has some built-in catcode protection.} -\item the macro |\myformula| is defined without checking if it already exists, - \LaTeX{} users might prefer to do first |\newcommand*\myformula {}| to get a - reasonable error message in case |\myformula| already exists, -\item the protection against active characters is done automatically (as long - as the whole thing has not already been fetched as a macro argument and - the catcodes correspondingly already frozen). -\end{itemize} - -It (if it succeeds) will be a completely expandable macro entirely built-up using |\xintAdd|, -|\xintSub|, |\xintMul|, |\xintDiv|, |\xintPow|, etc\dots as corresponds to the -expression written with the infix operators. -Macros created by |\xintNewExpr| can thus be nested. - -\begin{everbatim*} - \xintNewFloatExpr \FA [2]{(#1+#2)^10} - \xintNewFloatExpr \FB [2]{sqrt(#1*#2)} -\begin{enumerate}[nosep] - \item \FA {5}{5} - \item \FB {30}{10} - \item \FA {\FB {30}{10}}{\FB {40}{20}} -\end{enumerate} -\end{everbatim*} - -The documentation is much shortened here because \csbxint{NewExpr} and \csbxint{deffunc} -are very much related one with the other. - -\begin{framed} - ATTENTION! - - The original spirit of \csbxint{NewExpr} was to define a (possibly very big) - macro using only \xintfracname, and this means in particular that it must be - used only with arguments compatible with the \xintfracname input - format.\IMPORTANTf - - Thus an |\xintexpr| declared variable has no chance to work, it must be - wrapped explicitly in |\xinteval{...}| to be fetched as argument to a macro - constructed by \csbxint{NewExpr}. -\end{framed} - -They share essentially the same limitations. - -Notice though that \csbxint{NewFloatExpr} accepts and recognizes the optional -argument |[Q]| of \csbxint{floatexpr}, contrarily to \csbxint{deffloatfunc}. -Use an |\empty| in case the contents are not known in advance. - - -Historical note: prior to |1.4|, \xintexprname used a |\csname..\endcsname| -encapsulation technique which impacted the string pool memory. The -\csbxint{NewExpr} was designed as a method to pre-parse the expression and -produce one single, gigantic, nested usage of the relevant \xintfracname -macros. This way, only those macros were expanded which had nil impact on the -\TeX{} string pool. - -Later on it was found that this mechanism could be employed to define -functions. Basically underneath |98%| of \csbxint{NewExpr} and -\csbxint{deffunc} are using the same shared code. - -\xintDigits:= 16\relax - -\subsection{Analogies and differences of \csh{xintiiexpr} with \csh{numexpr}} - -\csbxint{iiexpr}|..\relax| is a parser of expressions knowing only (big) -integers. There are, besides the enlarged range of allowable inputs, some -important differences of syntax between |\numexpr| and |\xintiiexpr| and -variants: -\begin{itemize} -\item Contrarily to |\numexpr|, the |\xintiiexpr| parser will stop expanding - only after having encountered (and swallowed) a \emph{mandatory} |\relax| - token. -\item In particular, spaces between digits (and not only around infix - operators or parentheses) do not stop |\xintiiexpr|, contrarily to the - situation with |numexpr|: |\the\numexpr 7 + 3 5\relax| expands (in one - step)% -% -\footnote {The |\numexpr| triggers continued expansion after the space - following the |3| to check if some operator like |+| is upstream. But - after having found the |5| it treats it as and end-marker.} -% - to \dtt{\detokenize\expandafter{\the\numexpr 7 + 3 5\relax}\unskip}, whereas - |\xintthe\xintiiexpr 7 + 3 5\relax| expands (in two steps) to - \dtt{\detokenize\expandafter\expandafter\expandafter {\xintthe\xintiiexpr 7 - + 3 5\relax}}.% -% -\footnote {Since |1.2l| one can also use the underscore |_| to separate digits -for readability of long numbers.} - -\item Inside an |\edef|, an expression |\xintiiexpr...\relax| get fully - evaluated, whereas |\numexpr| without |\the| or |\number| prefix would not, - if not itself embedded in another |\the\numexpr| or similar context. -\item (ctd.) The private format to which |\xintiiexpr...\relax| (et al.) - evaluates may use |\xintthe| prefix to turn into explicit digits, - (for example in arguments to some macros which expand their arguments). The |\the| \TeX\ primitive prefix would - not work here. -\item (ctd.) One can embed a |\numexpr...\relax| (with its |\relax|!) inside an - |\xintiiexpr...\relax| without |\the| or |\number|, but the reverse situation - requires usage of |\xintthe| or \csbxint{eval} user interface, -\item |\numexpr -(1)\relax| is illegal. In contrast |\xintiiexpr -(1)\relax| is - perfectly legal and gives the expected result (what else ?). -\item |\numexpr 2\cnta\relax| is illegal (with |\cnta| a |\count| register.) - In contrast - |\xintiiexpr 2\cnta\relax| is perfectly legal and will do the tacit - multiplication. -\item |\the\numexpr| or |\number\numexpr| expands in one step, but - |\xintthe\xintiiexpr| or |\xinttheiiexpr| needs two steps. -\end{itemize} + \centeredline{|texdoc sourcexint.pdf|} -\subsection{Chaining expressions for expandable algorithmics} -\label{ssec:fibonacci} -We will see in this section how to chain |\xintexpr|-essions with -|\expandafter|'s, like it is possible with |\numexpr|. For this it is -convenient to use |\romannumeral0\xintexpro| which is the once-expanded form of -|\xintexpr|, as we can then chain using only one |\expandafter| each time. - -For example, here is the code employed -on the title page to compute (expandably, of course!) the 1250th Fibonacci -number: - -\begin{everbatim*} -\catcode`_ 11 -\def\Fibonacci #1{% \Fibonacci{N} computes F(N) with F(0)=0, F(1)=1. - \expandafter\Fibonacci_a\expandafter - {\the\numexpr #1\expandafter}\expandafter - {\romannumeral0\xintiiexpro 1\expandafter\relax\expandafter}\expandafter - {\romannumeral0\xintiiexpro 1\expandafter\relax\expandafter}\expandafter - {\romannumeral0\xintiiexpro 1\expandafter\relax\expandafter}\expandafter - {\romannumeral0\xintiiexpro 0\relax}} -% -\def\Fibonacci_a #1{% - \ifcase #1 - \expandafter\Fibonacci_end_i - \or - \expandafter\Fibonacci_end_ii - \else - \ifodd #1 - \expandafter\expandafter\expandafter\Fibonacci_b_ii - \else - \expandafter\expandafter\expandafter\Fibonacci_b_i - \fi - \fi {#1}% -}% * signs are omitted from the next macros, tacit multiplications -\def\Fibonacci_b_i #1#2#3{\expandafter\Fibonacci_a\expandafter - {\the\numexpr #1/2\expandafter}\expandafter - {\romannumeral0\xintiiexpro sqr(#2)+sqr(#3)\expandafter\relax\expandafter}\expandafter - {\romannumeral0\xintiiexpro (2#2-#3)#3\relax}% -}% end of Fibonacci_b_i -\def\Fibonacci_b_ii #1#2#3#4#5{\expandafter\Fibonacci_a\expandafter - {\the\numexpr (#1-1)/2\expandafter}\expandafter - {\romannumeral0\xintiiexpro sqr(#2)+sqr(#3)\expandafter\relax\expandafter}\expandafter - {\romannumeral0\xintiiexpro (2#2-#3)#3\expandafter\relax\expandafter}\expandafter - {\romannumeral0\xintiiexpro #2#4+#3#5\expandafter\relax\expandafter}\expandafter - {\romannumeral0\xintiiexpro #2#5+#3(#4-#5)\relax}% -}% end of Fibonacci_b_ii -% code as used on title page: -%\def\Fibonacci_end_i #1#2#3#4#5{\xintthe#5} -%\def\Fibonacci_end_ii #1#2#3#4#5{\xinttheiiexpr #2#5+#3(#4-#5)\relax} -% new definitions: -\def\Fibonacci_end_i #1#2#3#4#5{{#4}{#5}}% {F(N+1)}{F(N)} in \xintexpr format -\def\Fibonacci_end_ii #1#2#3#4#5% - {\expandafter - {\romannumeral0\xintiiexpro #2#4+#3#5\expandafter\relax - \expandafter}\expandafter - {\romannumeral0\xintiiexpro #2#5+#3(#4-#5)\relax}}% idem. -% \FibonacciN returns F(N) (in encapsulated format: needs \xintthe for printing) -\def\FibonacciN {\expandafter\xint_secondoftwo\romannumeral-`0\Fibonacci }% -\catcode`_ 8 -\end{everbatim*} - - -The macro |\Fibonacci| produces not one specific value |F(N)| but a pair of -successive values |{F(N)}{F(N+1)}| which can then serve as starting point of -another routine devoted to compute a whole sequence |F(N), F(N+1), -F(N+2),....|. Each of |F(N)| and |F(N+1)| is kept in the encapsulated internal -\xintexprname format. - -|\FibonacciN| produces the single |F(N)|. It also keeps it in the private -format; thus printing it will need the |\xintthe| prefix. - -\begingroup\footnotesize\sffamily\baselineskip 10pt -Here a code snippet which -checks the routine via a \string\message\ of the first $51$ Fibonacci -numbers (this is not an efficient way to generate a sequence of such -numbers, it is only for validating \csa{FibonacciN}). -% -\begin{everbatim} -\def\Fibo #1.{\xintthe\FibonacciN {#1}}% -\message{\xintiloop [0+1] \expandafter\Fibo\xintiloopindex., - \ifnum\xintiloopindex<49 \repeat \xintthe\FibonacciN{50}.} -\end{everbatim} -\endgroup - -The way we use |\expandafter|'s to chain successive |\xintiiexpro| evaluations -is exactly analogous to what is possible with |\numexpr|. The various -|\romannumeral0\xintiiexpro| could very well all have been |\xintiiexpr|'s but -then we would have needed |\expandafter\expandafter\expandafter| each -time. - -\begin{framed} - There is a difference though: |\numexpr| does \emph{NOT} expand inside an - |\edef|, and to force its expansion we must prefix it with |\the| or - |\number| or |\romannumeral| or another |\numexpr| which is itself prefixed, - etc\dots. - - But |\xintexpr|, |\xintiexpr|, ..., expand fully in an |\edef|, with the - completely expanded - result encapsulated in a private format. - - Using |\xintthe| as prefix is necessary to print the result (like |\the| or - |\number| in the case of |\numexpr|), but it is not necessary to get the - computation done (contrarily to the situation with |\numexpr|). -\end{framed} - - -Our |\Fibonacci| expands completely under \fexpan sion, so we can use -\hyperref[fdef]{\ttfamily\char92fdef} rather than |\edef| in a situation such -as -% -\leftedline {|\fdef \X {\FibonacciN {100}}|} -% -but it is usually about as efficient to employ |\edef|. And if we want -% -\leftedline{|\edef \Y {(\FibonacciN{100},\FibonacciN{200})}|,} -% -then |\edef| is necessary. - -Allright, so let's now give the code to generate |{F(N)}{F(N+1)}{F(N+2)}...|, -using |\Fibonacci| for the first two and then using the standard recursion -|F(N+2)=F(N+1)+F(N)|: - -\catcode`_ 11 -\def\FibonacciSeq #1#2{%#1=starting index, #2>#1=ending index - \expandafter\Fibonacci_Seq\expandafter - {\the\numexpr #1\expandafter}\expandafter{\the\numexpr #2-1}% -}% -\def\Fibonacci_Seq #1#2{% - \expandafter\Fibonacci_Seq_loop\expandafter - {\the\numexpr #1\expandafter}\romannumeral0\Fibonacci {#1}{#2}% -}% -\def\Fibonacci_Seq_loop #1#2#3#4{% standard Fibonacci recursion - {#3}\unless\ifnum #1<#4 \Fibonacci_Seq_end\fi - \expandafter\Fibonacci_Seq_loop\expandafter - {\the\numexpr #1+1\expandafter}\expandafter - {\romannumeral0\xintiiexpro #2+#3\relax}{#2}{#4}% -}% -\def\Fibonacci_Seq_end\fi\expandafter\Fibonacci_Seq_loop\expandafter - #1\expandafter #2#3#4{\fi {#3}}% -\catcode`_ 8 - -\begingroup\footnotesize\baselineskip10pt -\everb|@ -\catcode`_ 11 -\def\FibonacciSeq #1#2{%#1=starting index, #2>#1=ending index - \expandafter\Fibonacci_Seq\expandafter - {\the\numexpr #1\expandafter}\expandafter{\the\numexpr #2-1}% -}% -\def\Fibonacci_Seq #1#2{% - \expandafter\Fibonacci_Seq_loop\expandafter - {\the\numexpr #1\expandafter}\romannumeral0\Fibonacci {#1}{#2}% -}% -\def\Fibonacci_Seq_loop #1#2#3#4{% standard Fibonacci recursion - {#3}\unless\ifnum #1<#4 \Fibonacci_Seq_end\fi - \expandafter\Fibonacci_Seq_loop\expandafter - {\the\numexpr #1+1\expandafter}\expandafter - {\romannumeral0\xintiiexpro #2+#3\relax}{#2}{#4}% -}% -\def\Fibonacci_Seq_end\fi\expandafter\Fibonacci_Seq_loop\expandafter - #1\expandafter #2#3#4{\fi {#3}}% -\catcode`_ 8 -| -\endgroup - -This |\FibonacciSeq| macro is -completely expandable but it is not \fexpan dable. - -This is not a problem in the next example which uses \csbxint{For*} as the -latter applies repeatedly full expansion to what comes next each time it -fetches an item from its list argument. Thus \csbxint{For*} still manages to -generate the list via iterated full expansion. - - -\begin{figure*}[ht!] - \phantomsection\label{fibonacci} - \newcounter{myindex} - \fdef\Fibxxx{\FibonacciN {30}}% - \setcounter{myindex}{30}% -\centeredline{\tabskip 1ex -\vbox{\halign{\bfseries#.\hfil&#\hfil &\hfil #\cr - \xintFor* #1 in {\FibonacciSeq {30}{59}}\do - {\themyindex &\xintthe#1 & - \xintiiRem{\xintthe#1}{\xintthe\Fibxxx}\stepcounter{myindex}\cr }}% -}\vrule -\vbox{\halign{\bfseries#.\hfil&#\hfil &\hfil #\cr - \xintFor* #1 in {\FibonacciSeq {60}{89}}\do - {\themyindex &\xintthe#1 & - \xintiiRem{\xintthe#1}{\xintthe\Fibxxx}\stepcounter{myindex}\cr }}% -}\vrule -\vbox{\halign{\bfseries#.\hfil&#\hfil &\hfil #\cr - \xintFor* #1 in {\FibonacciSeq {90}{119}}\do - {\themyindex &\xintthe#1 & - \xintiiRem{\xintthe#1}{\xintthe\Fibxxx}\stepcounter{myindex}\cr }}% -}}% -% -\centeredline{Some Fibonacci numbers together with their residues modulo - |F(30)|\dtt{=\xintthe\Fibxxx}} -\end{figure*} - -\begingroup\footnotesize\baselineskip10pt -\everb|@ -\newcounter{myindex}% not "index", which would overwrite theindex environment! -% (many have probably been bitten by this trap) -\tabskip 1ex - \fdef\Fibxxx{\FibonacciN {30}}% - \setcounter{myindex}{30}% -\vbox{\halign{\bfseries#.\hfil&#\hfil &\hfil #\cr - \xintFor* #1 in {\FibonacciSeq {30}{59}}\do - {\themyindex &\xintthe#1 & - \xintiiRem{\xintthe#1}{\xintthe\Fibxxx}\stepcounter{myindex}\cr }}% -}\vrule -\vbox{\halign{\bfseries#.\hfil&#\hfil &\hfil #\cr - \xintFor* #1 in {\FibonacciSeq {60}{89}}\do - {\themyindex &\xintthe#1 & - \xintiiRem{\xintthe#1}{\xintthe\Fibxxx}\stepcounter{myindex}\cr }}% -}\vrule -\vbox{\halign{\bfseries#.\hfil&#\hfil &\hfil #\cr - \xintFor* #1 in {\FibonacciSeq {90}{119}}\do - {\themyindex &\xintthe#1 & - \xintiiRem{\xintthe#1}{\xintthe\Fibxxx}\stepcounter{myindex}\cr }}% -}% -| -\endgroup - -This produces the Fibonacci numbers from |F(30)| to |F(119)|, and -computes also all the -congruence classes modulo |F(30)|. The output has -been put in a \hyperref[fibonacci]{float}, which appears -\vpageref[above]{fibonacci}. I leave to the mathematically inclined -readers the task to explain the visible patterns\dots |;-)|. - -\subsection{When expandability is too much} - -Let's use the macros of \autoref{ssec:fibonacci} related to Fibonacci numbers. -Notice that the $47$th Fibonacci number is \dtt{\xintthe\FibonacciN {47}} thus -already too big for \TeX{} and \eTeX{}. - - -The |\FibonacciN| macro found in \autoref{ssec:fibonacci} is completely -expandable, it is even \fexpan dable. We need a wrapper with |\xintthe| -prefix -\begin{everbatim*} -\def\theFibonacciN{\xintthe\FibonacciN} -\end{everbatim*} -to print in the document or to use within |\message| (or \LaTeX\ |typeout|) to -write to the log and terminal. - -\begingroup - \def\A {1859} \def\B {1573} - \edef\X {\theFibonacciN\A} \edef\Y {\theFibonacciN\B} - \edef\GCDAB {\xintiiGCD\A\B}\edef\Z {\theFibonacciN\GCDAB} - \edef\GCDXY{\xintiiGCD\X\Y} - - The |\xintthe| prefix also allows its use it as argument to the \xintname - macros: for example if we are interested in knowing how many digits - $F(1250)$ has, it suffices to issue |\xintLen {\theFibonacciN {1250}}| - (which expands to \dtt{\xintLen {\theFibonacciN {1250}}}). Or if we want to - check the formula $gcd(F(1859),F(1573))=F(gcd(1859,1573))=F(143)$, we only - need% -% -\footnote{The - \csa{xintiiGCD} macro is provided by both the \xintgcdname package (since - |1.0|) and by the \xintname package (since |1.3d|).} -% -\begin{everbatim} -$\xintiiGCD{\theFibonacciN{1859}}{\theFibonacciN{1573}}=% - \theFibonacciN{\xintiiGCD{1859}{1573}}$ -\end{everbatim} -% -which produces: -% -\leftedline{$\dtt{\xintiiGCD{\X}{\Y}}=\dtt{\theFibonacciN{\GCDAB}}$} - -The |\theFibonacciN| macro expanded its |\xintiiGCD{1859}{1573}| argument via the -services of |\numexpr|: this step allows only things obeying the \TeX{} bound, -naturally! (but \dtt{F(\xintiiPow2{31}}) would be rather big anyhow...). - -This is very convenient but of course it repeats the complete evaluation each -time it is done. In practice, it is often useful to store the result of such -evaluations in macros. Any |\edef| will break expandability, but if the goal -is at some point to print something to the |dvi| or |pdf| output, and not only -to the |log| file, then expandability has to be broken one day or another! - -Hence, in practice, if we want to print in the document some computation -results, we can proceed like this and avoid having to repeat identical -evaluations: -\begin{everbatim} -\begingroup - \def\A {1859} \def\B {1573} - \edef\X {\theFibonacciN\A} \edef\Y {\theFibonacciN\B} - \edef\GCDAB {\xintiiGCD\A\B}\edef\Z {\theFibonacciN\GCDAB} - \edef\GCDXY{\xintiiGCD\X\Y} -The identity $\gcd(F(\A),F(\B))=F(\gcd(\A,\B))$ can be checked via evaluation -of both sides: $\gcd(F(\A),F(\B))=\gcd(\printnumber\X,\printnumber\Y)= -\printnumber{\GCDXY} = F(\gcd(\A,\B)) = F(\GCDAB) =\printnumber\Z$.\par - % some further computations involving \A, \B, \X, \Y -\endgroup % closing the group removes assignments to \A, \B, ... -% or choose longer names less susceptible to overwrite something. -% Note: there is no LaTeX \newecommand which would be to \edef like \newcommand is to \def -\end{everbatim} -The identity $\gcd(F(\A),F(\B))=F(\gcd(\A,\B))$ can be checked via evaluation -of both sides: $\gcd(F(\A),F(\B))=\gcd(\printnumber\X,\printnumber\Y)= -\printnumber{\GCDXY} = F(\gcd(\A,\B)) = F(\GCDAB) =\printnumber\Z$.\par -\endgroup - -One may legitimately ask the author: why expandability -to such extremes, for things such as big fractions or floating point numbers -(even continued fractions...) which anyhow can not be used directly within -\TeX's primitives such as |\ifnum|? Why insist on a concept -which is foreign to the vast majority of \TeX\ users and even programmers? - -I have no answer: it made definitely sense at the start of \xintname (see -\autoref{ssec:origins}) and once started I could not stop. - - -\subsection{Acknowledgements (2013/05/25)} - -I was greatly helped in my preparatory thinking, prior to producing such an -expandable parser, by the commented source of the -\href{https://ctan.org/pkg/l3kernel}{l3fp} package, specifically the -|l3fp-parse.dtx| file (in the version of April-May 2013; I think there was in -particular a text called ``roadmap'' which was helpful). Also the source of the -|calc| package was instructive, despite the fact that here for |\xintexpr| the -principles are necessarily different due to the aim of achieving expandability. - -\clearpage -\expandafter\let\csname xintexprnameUp\endcsname\undefined -\csname ExamplesnameUp\endcsname -\section {More examples with \xinttoolsname or \xintexprname or both} -\RaisedLabel{sec:examples} - -Note: \xintexprname.sty automatically loads \xinttoolsname.sty. - -The examples given here start to feel dated and are currently in need of some -rewrite to better illustrate newer features of the package. - - -\localtableofcontents - -\subsection{More examples with dummy variables} -\label{ssec:moredummies} - -These examples were first added to this manual at the time of the |1.1| -release (|2014/10/29|). - -\begin{everbatim*} -Prime numbers are always cool -\xinttheiiexpr seq((seq((subs((x/:m)?{(m*m>x)?{1}{0}}{-1},m=2n+1)) - ??{break(0)}{omit}{break(1)},n=1++))?{x}{omit}, - x=10001..[2]..10200)\relax -\end{everbatim*} - -The syntax in this last example may look a bit involved (...\@ and it is so I -admit). First |x/:m| computes |x modulo m| (this is the modulo with respect to -floored division). The |(x)?{yes}{no}| construct checks if |x| (which -\emph{must} be within parentheses) is true or false, i.e.\@ non zero or zero. It -then executes either the |yes| or the |no| branch, the non chosen branch is -\emph{not} evaluated. Thus if |m| divides |x| we are in the second (``false'') -branch. This gives a |-1|. This |-1| is the argument to a |??| branch which is -of the type |(y)??{y<0}{y=0}{y>0}|, thus here the |y<0|, i.e.\@, |break(0)| is -chosen. This |0| is thus given to another |?| which consequently chooses -|omit|, hence the number is not kept in the list. The numbers which survive -are the prime numbers. - -\begin{everbatim*} -The first Fibonacci number beyond |2^64|, |2^64|, and the index are respectively -\xinttheiiexpr subs(iterr(0,1;(@1>N)?{break(@1,N,i)}{@1+@2},i=1++),N=2^64)\relax. -\end{everbatim*} - -% A006877 In the `3x+1' problem, these values for the starting value set new -% records for number of steps to reach 1. (Formerly M0748) 14 1, 2, 3, 6, 7, -% 9, 18, 25, 27, 54, 73, 97, 129, 171, 231, 313, 327, 649, 703, 871, 1161, -% 2223, 2463, 2919, 3711, 6171, 10971, 13255, 17647, 23529, 26623, 34239, -% 35655, 52527, 77031, 106239, 142587, 156159, 216367, 230631, 410011, 511935, -% 626331, 837799 - -One more recursion: -\begin{everbatim*} -\def\syr #1{\xinttheiiexpr rseq(#1; (@<=1)?{break(i)}{odd(@)?{3@+1}{@//2}},i=0++)\relax} -The 3x+1 problem: \syr{231}\par -\end{everbatim*} - -OK, a final one:% -\begin{everbatim*} -\def\syrMax #1{\xintiiexpr iterr(#1,#1;even(i)? - {(@2<=1)?{break(@1,i//2)}{odd(@2)?{3@2+1}{@2//2}}} - {(@1>@2)?{@1}{@2}},i=0++)\relax } -With initial value 1161, the maximal intermediate value and the number of steps -needed to reach 1 are respectively \syrMax{1161}.\par -\end{everbatim*} - -Look at the - \hyperlink{BrentSalamin}{Brent-Salamin algorithm implementation} for a more - interesting recursion. - -% \begin{everbatim*} -% \newcommand\Factors [1]{\xinttheiiexpr -% subs(seq((i/:3=1)?{omit}{[L][i]},i=0..len(L)-1), -% L=rseq(#1;(p^2>[@][0])?{([@][0]>1)?{break(1,[@][0],1)}{abort}} -% {(([@][0])/:p)?{omit} -% {iter(([@][0])//p; (@/:p)?{break(@,p,e)}{@//p},e=1++)}},p=2++))\relax } -% \Factors {41^4*59^2*29^3*13^5*17^8*29^2*59^4*37^6} -% \end{everbatim*} - -% This might look a bit scary, I admit.% -% % -% \footnote{Look at the -% \hyperlink{BrentSalamin}{Brent-Salamin algorithm implementation} for a much -% saner example.} -% % - -% \xintexprname has minimal tools and -% is obstinate about doing everything expandably! We are hampered by absence of a -% notion of ``nuple''. The algorithm divides |N| by |2| until no more possible, -% then by |3|, then by |4| (which is silly), then by |5|, then by |6| (silly -% again), \dots. - -% The variable |L=rseq(#1;...)| expands, if one follows the steps, to a comma -% separated list starting with the initial (evaluated) |N=#1| and then -% pseudo-triplets where the first item is |N| trimmed of small primes, the -% second item is the last prime divisor found, and the third item is its -% exponent in original |N|. - -% The algorithm needs to keep handy the last computed quotient by prime powers, -% hence all of them, but at the very end it will be cleaner to get rid of them -% (this corresponds to the first line in the code above). This is achieved in a -% cumbersome inefficient way; indeed each item extraction |[L][i]| is costly: it -% is not like accessing an array stored in memory, due to expandability, nothing -% can be stored in memory! Nevertheless, this step could be done here in a far -% less inefficient manner if there was a variant of |seq| which, in the spirit -% of \csbxint{iloopindex}, would know how many steps it had been through so far. -% This is a feature to be added to |\xintexpr|! (as well as a |++| construct -% allowing a non unit step). - -% Notice that in |iter(([@][0])//p;| the |@| refers to the previous triplet (or -% in the first step to |N|), but the latter |@| showing up in |(@/:p)?| refers -% to the previous value computed by |iter|. - -% \begin{snugframed} -% Parentheses are essential in |..([y][0])| else the parser will see |..[| and -% end up in ultimate confusion, and also in |([@][0])/:p| else the parser will -% see the itemwise operator |]/| on lists and again be very confused (I could -% implement a |]/:| on lists, but in this situation this would also be very -% confusing to the parser.) -% \end{snugframed} - -% See \autoref{ssec:factorize} for a routine |\Factorize| written directly with -% \xintname macros. Last time I checked |\Factors| was about seven times slower -% than |\Factorize| in test cases such as -% |16246355912554185673266068721806243461403654781833| and others. Among the -% various things explaining the speed difference, there is fact that the -% |\Factorize| algorithm step by increments of two, not one, and also it divides -% only once, obtaining quotient and remainder in one go. These two things -% already make for a speed-up factor of about four. Thus, |\Factors| is not -% completely inefficient in comparison, and was quite easier to come up with -% than |\Factorize|. - -\subsection{Completely expandable prime test} -\label{ssec:primesI} - -Let us now construct a completely expandable macro which returns $1$ if its -given input is prime and $0$ if not: -\everb|@ -\def\remainder #1#2{\the\numexpr #1-(#1/#2)*#2\relax } -\def\IsPrime #1% - {\xintANDof {\xintApply {\remainder {#1}}{\xintSeq {2}{\xintiiSqrt{#1}}}}} -| - -This uses \csbxint{iiSqrt} and assumes its input is at least $5$. Rather than -\xintname's own \csbxint{iiRem} we used a quicker |\numexpr| expression as we -are dealing with short integers. Also we used \csbxint{ANDof} which will -return $1$ only if all the items are non-zero. The macro is a bit -silly with an even input, ok, let's enhance it to detect an even input: -\everb|@ -\def\IsPrime #1% - {\xintiiifOdd {#1} - {\xintANDof % odd case - {\xintApply {\remainder {#1}} - {\xintSeq [2]{3}{\xintiiSqrt{#1}}}% - }% - } - {\xintifEq {#1}{2}{1}{0}}% - } -| - -We used the \xintname expandable tests (on big integers or fractions) -in order for |\IsPrime| to be \fexpan dable. - -Our integers are short, but without |\expandafter|'s with -|\@firstoftwo|, % @ n'est plus actif dans le dtx 1.1 ! -or some other related techniques, -direct use of |\ifnum..\fi| tests is dangerous. So to make the macro more -efficient we are going to use the expandable tests provided by the package -\href{http://ctan.org/pkg/etoolbox}{etoolbox}% -% -\footnote{\url{http://ctan.org/pkg/etoolbox}}. -% -The macro becomes: -% -\everb|@ -\def\IsPrime #1% - {\ifnumodd {#1} - {\xintANDof % odd case - {\xintApply {\remainder {#1}}{\xintSeq [2]{3}{\xintiiSqrt{#1}}}}} - {\ifnumequal {#1}{2}{1}{0}}} -| - -In the odd case however we have to assume the integer is at least $7$, as -|\xintSeq| generates an empty list if |#1=3| or |5|, and |\xintANDof| returns -$1$ when supplied an empty list. Let us ease up a bit |\xintANDof|'s work by -letting it work on only $0$'s and $1$'s. We could use: -% -\everb|@ -\def\IsNotDivisibleBy #1#2% - {\ifnum\numexpr #1-(#1/#2)*#2=0 \expandafter 0\else \expandafter1\fi} -| -\noindent -where the |\expandafter|'s are crucial for this macro to be \fexpan dable and -hence work within the applied \csbxint{ANDof}. Anyhow, now that we have loaded -\href{http://ctan.org/pkg/etoolbox}{etoolbox}, we might as well use: -% -\everb|@ -\newcommand{\IsNotDivisibleBy}[2]{\ifnumequal{#1-(#1/#2)*#2}{0}{0}{1}} -| -\noindent -Let us enhance our prime macro to work also on the small primes: -\everb|@ -\newcommand{\IsPrime}[1] % returns 1 if #1 is prime, and 0 if not - {\ifnumodd {#1} - {\ifnumless {#1}{8} - {\ifnumequal{#1}{1}{0}{1}}% 3,5,7 are primes - {\xintANDof - {\xintApply - { \IsNotDivisibleBy {#1}}{\xintSeq [2]{3}{\xintiiSqrt{#1}}}}% - }}% END OF THE ODD BRANCH - {\ifnumequal {#1}{2}{1}{0}}% EVEN BRANCH -} -| - -The input is still assumed positive. There is a deliberate blank before -\csa{IsNotDivisibleBy} to use this feature of \csbxint{Apply}: a space stops the -expansion of the applied macro (and disappears). This expansion will be done by -\csbxint{ANDof}, which has been designed to skip everything as soon as it finds -a false (i.e.\@ zero) input. This way, the efficiency is considerably improved. - -We did generate via the \csbxint{Seq} too many potential divisors though. Later -sections give two variants: one with \csbxint{iloop} (\autoref{ssec:primesII}) -which is still expandable and another one (\autoref{ssec:primesIII}) which is a -close variant of the |\IsPrime| code above but with the \csbxint{For} loop, thus -breaking expandability. The \hyperref[ssec:primesII]{xintiloop variant} does not -first evaluate the integer square root, the \hyperref[ssec:primesIII]{xintFor - variant} still does. I did not compare their efficiencies. - - -Let us construct with this expandable primality test a table of the prime -numbers up to $1000$. We need to count how many we have in order to know how -many tab stops one shoud add in the last row.% -% -\footnote{although a tabular row may have less tabs than in the - preamble, there is a problem with the \char`\|\space\space vertical - rule, if one does that.} -% -There is some subtlety for this -last row. Turns out to be better to insert a |\\| only when we know for sure we -are starting a new row; this is how we have designed the |\OneCell| macro. And -for the last row, there are many ways, we use again |\xintApplyUnbraced| but -with a macro which gobbles its argument and replaces it with a tabulation -character. The \csbxint{For*} macro would be more elegant here. -% -\everb?@ -\newcounter{primecount} -\newcounter{cellcount} -\newcommand{\NbOfColumns}{13} -\newcommand{\OneCell}[1]{% - \ifnumequal{\IsPrime{#1}}{1} - {\stepcounter{primecount} - \ifnumequal{\value{cellcount}}{\NbOfColumns} - {\\\setcounter{cellcount}{1}#1} - {&\stepcounter{cellcount}#1}% - } % was prime - {}% not a prime, nothing to do -} -\newcommand{\OneTab}[1]{&} -\begin{tabular}{|*{\NbOfColumns}{r}|} -\hline -2 \setcounter{cellcount}{1}\setcounter{primecount}{1}% - \xintApplyUnbraced \OneCell {\xintSeq [2]{3}{999}}% - \xintApplyUnbraced \OneTab - {\xintSeq [1]{1}{\the\numexpr\NbOfColumns-\value{cellcount}\relax}}% - \\ -\hline -\end{tabular} -There are \arabic{primecount} prime numbers up to 1000. -? - -The table has been put in \hyperref[primesupto1000]{float} which appears -\vpageref{primesupto1000}. -We had to be careful to use in the last row \csbxint{Seq} with its optional -argument |[1]| so as to not generate a decreasing sequence from |1| to |0|, but -really an empty sequence in case the row turns out to already have all its -cells (which doesn't happen here but would with a number of columns dividing -$168$). -% -\newcommand{\IsNotDivisibleBy}[2]{\ifnumequal{#1-(#1/#2)*#2}{0}{0}{1}} - -\newcommand{\IsPrime}[1] - {\ifnumodd {#1} - {\ifnumless {#1}{8} - {\ifnumequal{#1}{1}{0}{1}}% 3,5,7 are primes - {\xintANDof - {\xintApply - { \IsNotDivisibleBy {#1}}{\xintSeq [2]{3}{\xintiiSqrt{#1}}}}% - }}% END OF THE ODD BRANCH - {\ifnumequal {#1}{2}{1}{0}}% EVEN BRANCH -} - -\newcounter{primecount} -\newcounter{cellcount} -\newcommand{\NbOfColumns}{13} -\newcommand{\OneCell}[1] - {\ifnumequal{\IsPrime{#1}}{1} - {\stepcounter{primecount} - \ifnumequal{\value{cellcount}}{\NbOfColumns} - {\\\setcounter{cellcount}{1}#1} - {&\stepcounter{cellcount}#1}% - } % was prime - {}% not a prime nothing to do -} -\newcommand{\OneTab}[1]{&} -\begin{figure*}[ht!] - \centering - \phantomsection\label{primesupto1000} - \begin{tabular}{|*{\NbOfColumns}{r}|} - \hline - 2\setcounter{cellcount}{1}\setcounter{primecount}{1}% - \xintApplyUnbraced \OneCell {\xintSeq [2]{3}{999}}% - \xintApplyUnbraced \OneTab - {\xintSeq [1]{1}{\the\numexpr\NbOfColumns-\value{cellcount}\relax}}% - \\ - \hline - \end{tabular} -\smallskip -\centeredline{There are \arabic{primecount} prime numbers up to 1000.} -\end{figure*} - -\subsection{Another completely expandable prime test} -\label{ssec:primesII} - -The |\IsPrime| macro from \autoref{ssec:primesI} checked expandably if a (short) -integer was prime, here is a partial rewrite using \csbxint{iloop}. We use the -|etoolbox| expandable conditionals for convenience, but not everywhere as -|\xintiloopindex| can not be evaluated while being braced. This is also the -reason why |\xintbreakiloopanddo| is delimited, and the next macro -|\SmallestFactor| which returns the smallest prime factor examplifies that. One -could write more efficient completely expandable routines, the aim here was only -to illustrate use of the general purpose \csbxint{iloop}. A little table giving -the first values of |\SmallestFactor| follows, its coding uses \csbxint{For}, -which is described later; none of this uses count registers. -% - - -\begin{everbatim*} -\let\IsPrime\undefined \let\SmallestFactor\undefined % clean up possible previous mess -\newcommand{\IsPrime}[1] % returns 1 if #1 is prime, and 0 if not - {\ifnumodd {#1} - {\ifnumless {#1}{8} - {\ifnumequal{#1}{1}{0}{1}}% 3,5,7 are primes - {\if - \xintiloop [3+2] - \ifnum#1<\numexpr\xintiloopindex*\xintiloopindex\relax - \expandafter\xintbreakiloopanddo\expandafter1\expandafter.% - \fi - \ifnum#1=\numexpr (#1/\xintiloopindex)*\xintiloopindex\relax - \else - \repeat 00\expandafter0\else\expandafter1\fi - }% - }% END OF THE ODD BRANCH - {\ifnumequal {#1}{2}{1}{0}}% EVEN BRANCH -}% -\catcode`_ 11 -\newcommand{\SmallestFactor}[1] % returns the smallest prime factor of #1>1 - {\ifnumodd {#1} - {\ifnumless {#1}{8} - {#1}% 3,5,7 are primes - {\xintiloop [3+2] - \ifnum#1<\numexpr\xintiloopindex*\xintiloopindex\relax - \xint_afterfi{\xintbreakiloopanddo#1.}% - \fi - \ifnum#1=\numexpr (#1/\xintiloopindex)*\xintiloopindex\relax - \xint_afterfi{\expandafter\xintbreakiloopanddo\xintiloopindex.}% - \fi - \iftrue\repeat - }% - }% END OF THE ODD BRANCH - {2}% EVEN BRANCH -}% -\catcode`_ 8 -{\centering - \begin{tabular}{|c|*{10}c|} - \hline - \xintFor #1 in {0,1,2,3,4,5,6,7,8,9}\do {&\bfseries #1}\\ - \hline - \bfseries 0&--&--&2&3&2&5&2&7&2&3\\ - \xintFor #1 in {1,2,3,4,5,6,7,8,9}\do - {\bfseries #1% - \xintFor #2 in {0,1,2,3,4,5,6,7,8,9}\do - {&\SmallestFactor{#1#2}}\\}% - \hline - \end{tabular}\par -} -\end{everbatim*} - -\subsection{Miller-Rabin Pseudo-Primality expandably} -\label{ssec:PrimesIV} - - -% At the time of writing, the code at the link above is still the version from -% April 2016 and it needed some hacks to get recursive (pseudo)-functions -% defined. Since |1.2h| of |2016/11/20| there is \csbxint{NewFunction} which -% allows us here to avoid such internal hacking. - -% And since |1.3| of |2018/03/01|, it is possible to use \csbxint{defiifunc} -% also for recursive definitions, so we use it here, but we can benefit from it -% only for modular exponentiation as the rest of the code uses |iter| or |break| -% statements which are not yet compatible with \csbxint{defiifunc}. - -The |isPseudoPrime(n)| is usable in \csbxint{iiexpr}-essions and establishes -if its (positive) argument is a Miller-Rabin PseudoPrime to the bases $2, 3, -5, 7, 11, 13, 17$. If this is true and $n<341550071728321$ (which has 15 -digits) then $n$ really is a prime number. - -Similarly $n=3825123056546413051$ (19 digits) is the smallest composite number -which is a strong pseudo prime for bases $2, 3, 5, 7, 11, 13, 17, 19$ and -$23$. It is easy to extend the code below to include these additional tests -(we could make the list of tested bases an argument too, now that I think -about it.) - -For more information see - \centeredline{\url{https://en.wikipedia.org/wiki/Miller%E2%80%93Rabin_primality_test#Deterministic_variants_of_the_test}} - and -\centeredline{\url{http://primes.utm.edu/prove/prove2_3.html}} - -In particular, according to \textsc{Jaeschke} \emph{On strong pseudoprimes to - several bases,} Math. Comp., 61 (1993) 915-926, if $n < 4,759,123,141$ it is -enough to establish Rabin-Miller pseudo-primality to bases $a = 2, 7, 61$ to -prove that $n$ is prime. This range is enough for \TeX\ numbers and we could -then write a very fast expandable primality test for such numbers using only -|\numexpr|. Left as an exercise\dots - -\begin{everbatim*} -% I -------------------------------- Modular Exponentiation -% Computes x^m modulo n (with m non negative). -% We will always use it with 1 < x < n -% -% With xint 1.4 we should use ? and ?? (although in the case at hand ifsgn() -% and if() would be ok but I should not say that). -% -\xintdefiifunc powmod_a(x, m, n) := - isone(m)? - % m=1, return x modulo n - { x /: n } - % m > 1 test if odd or even and do recursive call - { odd(m)? { x*sqr(powmod_a(x, m//2, n)) /: n } - { sqr(powmod_a(x, m//2, n)) /: n } - } - ; -\xintdefiifunc powmod(x, m, n) := (m)?{powmod_a(x, m, n)}{1}; - -%% Syntax used before xint 1.4: -% \xintdefiifunc powmod_a(x, m, n) := -% ifone(m, -% % m=1, return x modulo n -% x /: n, -% % m > 1 test if odd or even and do recursive call -% if(odd(m), (x*sqr(powmod_a(x, m//2, n))) /: n, -% sqr(powmod_a(x, m//2, n)) /: n -% ) -% ); -% \xintdefiifunc powmod(x, m, n) := if(m, powmod_a(x, m, n), 1); - -% II ------------------------------ Miller-Rabin compositeness witness - -% n=2^k m + 1 with m odd and k at least 1 - -% Choose 1<x<n. -% compute y=x^m modulo n -% if equals 1 we can't say anything -% if equals n-1 we can't say anything -% else put j=1, and -% compute repeatedly the square, incrementing j by 1 each time, -% thus always we have y^{2^{j-1}} -% -> if at some point n-1 mod n found, we can't say anything and break out -% -> if however we never find n-1 mod n before reaching -% z=y^{2^{k-1}} with j=k -% we then have z^2=x^{n-1}. - % Suppose z is not -1 mod n. If z^2 is 1 mod n, then n can be prime only if - % z is 1 mod n, and we can go back up, until initial y, and we have already - % excluded y=1. Thus if z is not -1 mod n and z^2 is 1 then n is not prime. - % But if z^2 is not 1, then n is not prime by Fermat. Hence (z not -1 mod n) - % implies (n is composite). (Miller test) - -% let's use again xintexpr indecipherable (except to author) syntax. Of course -% doing it with macros only would be faster. - -% Here \xintdefiifunc is not usable because not compatible with iter, break, ... -% but \xintNewFunction comes to the rescue. - -\xintNewFunction{isCompositeWitness}[4]{% x=#1, n=#2, m=#3, k=#4 - subs((y==1)?{0} - {iter(y;(j==#4)?{break(!(@==#2-1))} - {(@==#2-1)?{break(0)}{sqr(@)/:#2}},j=1++)} - ,y=powmod(#1,#3,#2))} - -% added note (2018/03/07) it is possible in the above that m=#3 is never -% zero, so we should rather call powmod_a for a small gain, but I don't -% have time to re-read the code comments and settle this. - -% III ------------------------------------- Strong Pseudo Primes - -% cf -% http://oeis.org/A014233 -% <http://mathworld.wolfram.com/Rabin-MillerStrongPseudoprimeTest.html> -% <http://mathworld.wolfram.com/StrongPseudoprime.html> - -% check if positive integer <49 si a prime. -% 2,3,5,7,11,13,17,19,23,29,31,37,41,43,47 -\def\IsVerySmallPrime #1% - {\ifnum#1=1 \xintdothis0\fi - \ifnum#1=2 \xintdothis1\fi - \ifnum#1=3 \xintdothis1\fi - \ifnum#1=5 \xintdothis1\fi - \ifnum#1=\numexpr (#1/2)*2\relax\xintdothis0\fi - \ifnum#1=\numexpr (#1/3)*3\relax\xintdothis0\fi - \ifnum#1=\numexpr (#1/5)*5\relax\xintdothis0\fi - \xintorthat 1} - -\xintNewFunction{isPseudoPrime}[1]{% n = #1 - (#1<49)?% use ? syntax to evaluate only what is needed -% prior to 1.4 we had \xintthe#1 here but the actual tokens represented -% by this #1 when isPseudoPrime() function expands have changed and -% the correct way is now \xintiieval{#1} to hand over explicit digits to -% the \IsVerySmallPrime macro. - {\IsVerySmallPrime{\xintiieval{#1}}} - {(even(#1))? - {0} - {subs(% - % L expands to two values m, k hence isCompositeWitness does get - % its four variables x, n, m, k - isCompositeWitness(2, #1, L)? - {0}% - {isCompositeWitness(3, #1, L)? - {0}% - {isCompositeWitness(5, #1, L)? - {0}% - {isCompositeWitness(7, #1, L)? - {0}% -% above enough for N<3215031751 hence all TeX numbers - {isCompositeWitness(11, #1, L)? - {0}% -% above enough for N<2152302898747, hence all 12-digits numbers - {isCompositeWitness(13, #1, L)? - {0}% -% above enough for N<3474749660383 - {isCompositeWitness(17, #1, L)? - {0}% -% above enough for N<341550071728321 - {1}% - }% not needed to comment-out end of lines spaces inside - }% \xintexpr but this is too much of a habit for me with TeX! - }% I left some after the ? characters. - }% - }% - }% this computes (m, k) such that n = 2^k m + 1, m odd, k>=1 - , L=iter(#1//2;(even(@))?{@//2}{break(@,k)},k=1++))% - }% - }% -} - -% if needed: -%\def\IsPseudoPrime #1{\xinttheiiexpr isPseudoPrime(#1)\relax} - -\noindent The smallest prime number at least equal to 3141592653589 is -\xintiiexpr - seq(isPseudoPrime(3141592653589+n)? - {break(3141592653589+n)}{omit}, n=0++)\relax. -% we could not use 3141592653589++ syntax because it works only with TeX numbers -\par -\end{everbatim*} - - - - - -\subsection{A table of factorizations} -\label{ssec:factorizationtable} - -As one more example with \csbxint{iloop} let us use an alignment to display the -factorization of some numbers. The loop will actually only play a minor r\^ole -here, just handling the row index, the row contents being almost entirely -produced via a macro |\factorize|. The factorizing macro does not use -|\xintiloop| as it didn't appear to be the convenient tool. As |\factorize| will -have to be used on |\xintiloopindex|, it has been defined as a delimited macro. - -To spare some fractions of a second in the compilation time of this document -(which has many many other things to do), \number"7FFFFFED{} and -\number"7FFFFFFF, which turn out to be prime numbers, are not given to -|factorize| but just typeset directly; this illustrates use of -\csbxint{iloopskiptonext}. - -The code next generates a \hyperref[floatfactorize]{table} which has -been made into a float appearing \vpageref{floatfactorize}. Here is now -the code for factorization; the conditionals use the package provided -|\xint_firstoftwo| and |\xint_secondoftwo|, one could have employed -rather \LaTeX{}'s own |\@firstoftwo| and |\@secondoftwo|, or, simpler -still in \LaTeX{} context, the |\ifnumequal|, |\ifnumless| \dots, -utilities from the package |etoolbox| which do exactly that under the -hood. Only \TeX{} acceptable numbers are treated here, but it would be -easy to make a translation and use the \xintname macros, thus extending -the scope to big numbers; naturally up to a cost in speed. - -The reason for some strange looking expressions is to avoid arithmetic overflow. - -\begin{everbatim*} -\catcode`_ 11 -\def\abortfactorize #1\xint_secondoftwo\fi #2#3{\fi} - -\def\factorize #1.{\ifnum#1=1 \abortfactorize\fi - \ifnum\numexpr #1-2=\numexpr ((#1/2)-1)*2\relax - \expandafter\xint_firstoftwo - \else\expandafter\xint_secondoftwo - \fi - {2&\expandafter\factorize\the\numexpr#1/2.}% - {\factorize_b #1.3.}}% - -\def\factorize_b #1.#2.{\ifnum#1=1 \abortfactorize\fi - \ifnum\numexpr #1-(#2-1)*#2<#2 - #1\abortfactorize - \fi - \ifnum \numexpr #1-#2=\numexpr ((#1/#2)-1)*#2\relax - \expandafter\xint_firstoftwo - \else\expandafter\xint_secondoftwo - \fi - {#2&\expandafter\factorize_b\the\numexpr#1/#2.#2.}% - {\expandafter\factorize_b\the\numexpr #1\expandafter.% - \the\numexpr #2+2.}}% -\catcode`_ 8 -\begin{figure*}[ht!] -\centering\phantomsection\label{floatfactorize}\normalcolor -\tabskip1ex -\centeredline{\vbox{\halign {\hfil\strut#\hfil&&\hfil#\hfil\cr\noalign{\hrule} - \xintiloop ["7FFFFFE0+1] - \expandafter\bfseries\xintiloopindex & - \ifnum\xintiloopindex="7FFFFFED - \number"7FFFFFED\cr\noalign{\hrule} - \expandafter\xintiloopskiptonext - \fi - \expandafter\factorize\xintiloopindex.\cr\noalign{\hrule} - \ifnum\xintiloopindex<"7FFFFFFE - \repeat - \bfseries \number"7FFFFFFF&\number "7FFFFFFF\cr\noalign{\hrule} -}}} -\centeredline{A table of factorizations} -\end{figure*} -\end{everbatim*} - -\subsection{Another table of primes} -\label{ssec:primesIII} - -As a further example, let us dynamically generate a tabular with the first $50$ -prime numbers after $12345$. First we need a macro to test if a (short) number -is prime. Such a completely expandable macro was given in \autoref{ssec:primesI}, -here we consider a variant which will be slightly more efficient. This new -|\IsPrime| has two parameters. The first one is a macro which it redefines to -expand to the result of the primality test applied to the second argument. For -convenience we use the \href{http://ctan.org/pkg/etoolbox}{etoolbox} wrappers to -various |\ifnum| tests, although here there isn't anymore the constraint of -complete expandability (but using explicit |\if..\fi| in tabulars has its -quirks); equivalent tests are provided by \xintname, but they have some overhead -as they are able to deal with arbitrarily big integers. - -\def\IsPrime #1#2% -{\edef\TheNumber {\the\numexpr #2}% positive integer - \ifnumodd {\TheNumber} - {\ifnumgreater {\TheNumber}{1} - {\edef\ItsSquareRoot{\xintiiSqrt \TheNumber}% - \xintFor ##1 in {\xintintegers [3+2]}\do - {\ifnumgreater {##1}{\ItsSquareRoot} - {\def#1{1}\xintBreakFor} - {}% - \ifnumequal {\TheNumber}{(\TheNumber/##1)*##1} - {\def#1{0}\xintBreakFor } - {}% - }} - {\def#1{0}}}% 1 is not prime - {\ifnumequal {\TheNumber}{2}{\def#1{1}}{\def#1{0}}}% -}% - -\everb|@ -\def\IsPrime #1#2% """color[named]{PineGreen}#1=\Result, #2=tested number (assumed >0).;! -{\edef\TheNumber {\the\numexpr #2}%"""color[named]{PineGreen} hence #2 may be a count or \numexpr.;! - \ifnumodd {\TheNumber} - {\ifnumgreater {\TheNumber}{1} - {\edef\ItsSquareRoot{\xintiiSqrt \TheNumber}% - \xintFor """color{red}##1;! in {"""color{red}\xintintegers;! [3+2]}\do - {\ifnumgreater {"""color{red}##1;!}{\ItsSquareRoot} """color[named]{PineGreen}% "textcolor{red}{##1} is a \numexpr.;! - {\def#1{1}\xintBreakFor} - {}% - \ifnumequal {\TheNumber}{(\TheNumber/##1)*##1} - {\def#1{0}\xintBreakFor } - {}% - }} - {\def#1{0}}}% 1 is not prime - {\ifnumequal {\TheNumber}{2}{\def#1{1}}{\def#1{0}}}% -} -| - -As we used \csbxint{For} inside a macro we had to double the |#| in its |#1| -parameter. Here is now the code which creates the prime table (the table has -been put in a \hyperref[primes]{float}, which should be found on page -\pageref{primes}): - -\everb?@ -\newcounter{primecount} -\newcounter{cellcount} -\begin{figure*}[ht!] - \centering - \begin{tabular}{|*{7}c|} - \hline - \setcounter{primecount}{0}\setcounter{cellcount}{0}% - \xintFor """color{red}#1;! in {"""color{red}\xintintegers;! [12345+2]} \do -"""color[named]{PineGreen}% "textcolor{red}{#1} is a \numexpr.;! - {\IsPrime\Result{#1}% - \ifnumgreater{\Result}{0} - {\stepcounter{primecount}% - \stepcounter{cellcount}% - \ifnumequal {\value{cellcount}}{7} - {"""color{red}\the#1;! \\\setcounter{cellcount}{0}} - {"""color{red}\the#1;! &}} - {}% - \ifnumequal {\value{primecount}}{50} - {\xintBreakForAndDo - {\multicolumn {6}{l|}{These are the first 50 primes after 12345.}\\}} - {}% - }\hline -\end{tabular} -\end{figure*} -? - -\begin{figure*}[ht!] - \centering\phantomsection\label{primes} - \begin{tabular}{|*{7}c|} - \hline - \setcounter{primecount}{0}\setcounter{cellcount}{0}% - \xintFor #1 in {\xintintegers [12345+2]} \do - {\IsPrime\Result{#1}% - \ifnumgreater{\Result}{0} - {\stepcounter{primecount}% - \stepcounter{cellcount}% - \ifnumequal {\value{cellcount}}{7} - {\the#1 \\\setcounter{cellcount}{0}} - {\the#1 &}} - {}% - \ifnumequal {\value{primecount}}{50} - {\xintBreakForAndDo - {\multicolumn {6}{l|}{These are the first 50 primes after 12345.}\\}} - {}% - }\hline -\end{tabular} -\end{figure*} - -\subsection{Factorizing again} -\label{ssec:factorize} - -Here is an \fexpan dable macro which computes the factors of an integer. It -uses the \xintname macros only. -\begin{everbatim*} -\catcode`\@ 11 -\let\factorize\relax -\newcommand\Factorize [1] - {\romannumeral0\expandafter\factorize\expandafter{\romannumeral-`0#1}}% -\newcommand\factorize [1]{\xintiiifOne{#1}{ 1}{\factors@a #1.{#1};}}% -\def\factors@a #1.{\xintiiifOdd{#1} - {\factors@c 3.#1.}% - {\expandafter\factors@b \expandafter1\expandafter.\romannumeral0\xinthalf{#1}.}}% -\def\factors@b #1.#2.{\xintiiifOne{#2} - {\factors@end {2, #1}}% - {\xintiiifOdd{#2}{\factors@c 3.#2.{2, #1}}% - {\expandafter\factors@b \the\numexpr #1+\@ne\expandafter.% - \romannumeral0\xinthalf{#2}.}}% -}% -\def\factors@c #1.#2.{% - \expandafter\factors@d\romannumeral0\xintiidivision {#2}{#1}{#1}{#2}% -}% -\def\factors@d #1#2#3#4{\xintiiifNotZero{#2} - {\xintiiifGt{#3}{#1} - {\factors@end {#4, 1}}% ultimate quotient is a prime with power 1 - {\expandafter\factors@c\the\numexpr #3+\tw@.#4.}}% - {\factors@e 1.#3.#1.}% -}% -\def\factors@e #1.#2.#3.{\xintiiifOne{#3} - {\factors@end {#2, #1}}% - {\expandafter\factors@f\romannumeral0\xintiidivision {#3}{#2}{#1}{#2}{#3}}% -}% -\def\factors@f #1#2#3#4#5{\xintiiifNotZero{#2} - {\expandafter\factors@c\the\numexpr #4+\tw@.#5.{#4, #3}}% - {\expandafter\factors@e\the\numexpr #3+\@ne.#4.#1.}% -}% -\def\factors@end #1;{\xintlistwithsep{, }{\xintRevWithBraces {#1}}}% -\catcode`@ 12 -\end{everbatim*} -The macro will be acceptably efficient only with numbers having somewhat small -prime factors. -\begin{everbatim} -\Factorize{16246355912554185673266068721806243461403654781833} -\end{everbatim} -\begingroup\fdef\Z -{\Factorize{16246355912554185673266068721806243461403654781833}} -\noindent{\small\dtt{\Z}} - - -It puts a little stress on the input save stack in order -not be bothered with previously gathered things.\footnote{2015/11/18 I have - not revisited this code for a long time, and perhaps I could improve it now - with some new techniques.} - -Its output is a comma separated list with the number first, then its prime -factors with multiplicity. Let's produce something prettier: -\begin{everbatim*} -\catcode`_ 11 -\def\ShowFactors #1{\expandafter\ShowFactors_a\romannumeral-`0\Factorize{#1},\relax,\relax,} -\def\ShowFactors_a #1,{#1=\ShowFactors_b} -\def\ShowFactors_b #1,#2,{\if\relax#1\else#1^{#2}\expandafter\ShowFactors_b\fi} -\catcode`_ 8 -\end{everbatim*} -\begin{everbatim} -$$\ShowFactors{16246355912554185673266068721806243461403654781833}$$ -\end{everbatim} -$$\csname ShowFactors_a\expandafter\endcsname\Z,\relax,\relax,$$ -\endgroup - -If we only considered small integers, we could write pure |\numexpr| methods -which would be very much faster (especially if we had a table of small primes -prepared first) but still ridiculously slow compared to any non expandable -implementation, not to mention use of programming languages directly accessing -the CPU registers\dots - -\subsection{The Quick Sort algorithm illustrated}\label{ssec:quicksort} - -First a completely expandable macro which sorts a comma separated list of -numbers.% -% -\footnote{The code in earlier versions of this manual handled inputs composed - of braced items. I have switched to comma separated inputs on the occasion - of (link removed) - The version here is like - |code 3| on - (link removed) (which is about |3x| faster - than the earlier code it replaced in this manual) with a modification to - make it more efficient if the data has many repeated values. - - A faster routine (for sorting hundreds of values) is provided as |code 6| at - the link mentioned in the footnote, it is based on Merge Sort, but limited - to inputs which one can handle as \TeX{} dimensions.% - - This |code 6| could be extended to handle more general numbers, as - acceptable by \xintfracname. I have also written a non expandable version, - which is even faster, but this matters really only when handling hundreds or - rather thousands of values.} -% - -The |\QSx| macro expands its list argument, which may thus be a macro; its -comma separated items must expand to integers or decimal numbers or fractions -or scientific notation as acceptable to \xintfracname, but if an item is -itself some (expandable) macro, this macro will be expanded each time the item -is considered in a comparison test! This is actually good if the macro expands -in one step to the digits, and there are many many digits, but bad if the macro -needs to do many computations. Thus |\QSx| should be used with either explicit -numbers or with items being macros expanding in one step to the numbers -(particularly if these numbers are very big). - -If the interest is only in \TeX{} integers, then one should replace the -|\xintifCmp| macro with a suitable conditional, possibly helped by tools such as -|\ifnumgreater|, |\ifnumequal| and |\ifnumless| from -\href{http://ctan.org/pkg/etoolbox}{etoolbox} (\LaTeX{} only; I didn't see a -direct equivalent to |\xintifCmp|.) Or, if we are dealing with decimal numbers -with at most four+four digits, then one should use suitable |\ifdim| tests. -Naturally this will boost consequently the speed, from having skipped all the -overhead in parsing fractions and scientific numbers as are acceptable by -\xintfracname macros, and subsequent treatment. - -\begin{everbatim*} -% THE QUICK SORT ALGORITHM EXPANDABLY -% \usepackage{xintfrac} in the preamble (latex) -\makeatletter -% use extra safe delimiters -\catcode`! 3 \catcode`? 3 -\def\QSx {\romannumeral0\qsx }% -% first we check if empty list (else \qsx@finish will not find a comma) -\def\qsx #1{\expandafter\qsx@a\romannumeral-`0#1,!,?}% -\def\qsx@a #1{\ifx,#1\expandafter\qsx@abort\else - \expandafter\qsx@start\fi #1}% -\def\qsx@abort #1?{ }% -\def\qsx@start {\expandafter\qsx@finish\romannumeral0\qsx@b,}% -\def\qsx@finish ,#1{ #1}% -% -% we check if empty of single and if not pick up the first as Pivot: -\def\qsx@b ,#1#2,#3{\ifx?#3\xintdothis\qsx@empty\fi - \ifx!#3\xintdothis\qsx@single\fi - \xintorthat\qsx@separate {#1#2}{}{}{#1#2}#3}% -\def\qsx@empty #1#2#3#4#5{ }% -\def\qsx@single #1#2#3#4#5?{, #4}% -\def\qsx@separate #1#2#3#4#5#6,% -{% - \ifx!#5\expandafter\qsx@separate@done\fi - \xintifCmp {#5#6}{#4}% - \qsx@separate@appendtosmaller - \qsx@separate@appendtoequal - \qsx@separate@appendtogreater {#5#6}{#1}{#2}{#3}{#4}% -}% -% -\def\qsx@separate@appendtoequal #1#2{\qsx@separate {#2,#1}}% -\def\qsx@separate@appendtogreater #1#2#3{\qsx@separate {#2}{#3,#1}}% -\def\qsx@separate@appendtosmaller #1#2#3#4{\qsx@separate {#2}{#3}{#4,#1}}% -% -\def\qsx@separate@done\xintifCmp #1% - \qsx@separate@appendtosmaller - \qsx@separate@appendtoequal - \qsx@separate@appendtogreater #2#3#4#5#6#7?% -{% - \expandafter\qsx@f\expandafter {\romannumeral0\qsx@b #4,!,?}{\qsx@b #5,!,?}{#3}% -}% -% -\def\qsx@f #1#2#3{#2, #3#1}% -% -\catcode`! 12 \catcode`? 12 -\makeatother - -% EXAMPLE -\begingroup -\edef\z {\QSx {1.0, 0.5, 0.3, 1.5, 1.8, 2.0, 1.7, 0.4, 1.2, 1.4, - 1.3, 1.1, 0.7, 1.6, 0.6, 0.9, 0.8, 0.2, 0.1, 1.9}} -\meaning\z - -\def\a {3.123456789123456789}\def\b {3.123456789123456788} -\def\c {3.123456789123456790}\def\d {3.123456789123456787} -\oodef\z {\QSx { \a, \b, \c, \d}}% -% The space before \a to let it not be expanded during the conversion from CSV -% values to List. The \oodef expands exactly twice (via a bunch of \expandafter's) -\meaning\z -\endgroup -\end{everbatim*} (the spaces after \string\d, etc...\@ come from the use of the -|\meaning| primitive.) - -The choice of pivot as first element is bad if the list is already almost -sorted. Let's add a variant which will pick up the pivot index randomly. The -previous routine worked also internally with comma separated lists, but for a -change this one will use internally lists of braced items (the initial -conversion via \csbxint{CSVtoList} handles all potential spurious space -problems). - -\unless\ifxetex % pour tester compilation de xint.dtx avec xetex qui n'a pas - % \pdfuniformdeviate -\begin{everbatim*} -% QuickSort expandably on comma separated values with random choice of pivots -% ====> Requires availability of \pdfuniformdeviate <==== -% \usepackage{xintfrac, xinttools} in preamble -\makeatletter -\def\QSx {\romannumeral0\qsx }% This is a f-expandable macro. -% This converts from comma separated values on input and back on output. -% **** NOTE: these steps (and the other ones too, actually) are costly if input -% has thousands of items. -\def\qsx #1{\xintlistwithsep{, }% - {\expandafter\qsx@sort@a\expandafter{\romannumeral0\xintcsvtolist{#1}}}}% -% -% we check if empty or single or double and if not pick up the first as Pivot: -\def\qsx@sort@a #1% - {\expandafter\qsx@sort@b\expandafter{\romannumeral0\xintlength{#1}}{#1}}% -\def\qsx@sort@b #1{\ifcase #1 - \expandafter\qsx@sort@empty - \or\expandafter\qsx@sort@single - \or\expandafter\qsx@sort@double - \else\expandafter\qsx@sort@c\fi {#1}}% -\def\qsx@sort@empty #1#2{ }% -\def\qsx@sort@single #1#2{#2}% -\catcode`_ 11 -\def\qsx@sort@double #1#2{\xintifGt #2{\xint_exchangetwo_keepbraces}{}#2}% -\catcode`_ 8 -\def\qsx@sort@c #1#2{% - \expandafter\qsx@sort@sep@a\expandafter - {\romannumeral0\xintnthelt{\pdfuniformdeviate #1+\@ne}{#2}}#2?}% -\def\qsx@sort@sep@a #1{\qsx@sort@sep@loop {}{}{}{#1}}% -\def\qsx@sort@sep@loop #1#2#3#4#5% -{% - \ifx?#5\expandafter\qsx@sort@sep@done\fi - \xintifCmp {#5}{#4}% - \qsx@sort@sep@appendtosmaller - \qsx@sort@sep@appendtoequal - \qsx@sort@sep@appendtogreater {#5}{#1}{#2}{#3}{#4}% -}% -% -\def\qsx@sort@sep@appendtoequal #1#2{\qsx@sort@sep@loop {#2{#1}}}% -\def\qsx@sort@sep@appendtogreater #1#2#3{\qsx@sort@sep@loop {#2}{#3{#1}}}% -\def\qsx@sort@sep@appendtosmaller #1#2#3#4{\qsx@sort@sep@loop {#2}{#3}{#4{#1}}}% -% -\def\qsx@sort@sep@done\xintifCmp #1% - \qsx@sort@sep@appendtosmaller - \qsx@sort@sep@appendtoequal - \qsx@sort@sep@appendtogreater #2#3#4#5#6% -{% - \expandafter\qsx@sort@recurse\expandafter - {\romannumeral0\qsx@sort@a {#4}}{\qsx@sort@a {#5}}{#3}% -}% -% -\def\qsx@sort@recurse #1#2#3{#2#3#1}% -% -\makeatother - -% EXAMPLES -\begingroup -\edef\z {\QSx {1.0, 0.5, 0.3, 1.5, 1.8, 2.0, 1.7, 0.4, 1.2, 1.4, - 1.3, 1.1, 0.7, 1.6, 0.6, 0.9, 0.8, 0.2, 0.1, 1.9}} -\meaning\z - -\def\a {3.123456789123456789}\def\b {3.123456789123456788} -\def\c {3.123456789123456790}\def\d {3.123456789123456787} -\oodef\z {\QSx { \a, \b, \c, \d}}% -% The space before \a to let it not be expanded during the conversion from CSV -% values to List. The \oodef expands exactly twice (via a bunch of \expandafter's) -\meaning\z - -\def\somenumbers{% -3997.6421, 8809.9358, 1805.4976, 5673.6478, 3179.1328, 1425.4503, 4417.7691, -2166.9040, 9279.7159, 3797.6992, 8057.1926, 2971.9166, 9372.2699, 9128.4052, -1228.0931, 3859.5459, 8561.7670, 2949.6929, 3512.1873, 1698.3952, 5282.9359, -1055.2154, 8760.8428, 7543.6015, 4934.4302, 7526.2729, 6246.0052, 9512.4667, -7423.1124, 5601.8436, 4433.5361, 9970.4849, 1519.3302, 7944.4953, 4910.7662, -3679.1515, 8167.6824, 2644.4325, 8239.4799, 4595.1908, 1560.2458, 6098.9677, -3116.3850, 9130.5298, 3236.2895, 3177.6830, 5373.1193, 5118.4922, 2743.8513, -8008.5975, 4189.2614, 1883.2764, 9090.9641, 2625.5400, 2899.3257, 9157.1094, -8048.4216, 3875.6233, 5684.3375, 8399.4277, 4528.5308, 6926.7729, 6941.6278, -9745.4137, 1875.1205, 2755.0443, 9161.1524, 9491.1593, 8857.3519, 4290.0451, -2382.4218, 3678.2963, 5647.0379, 1528.7301, 2627.8957, 9007.9860, 1988.5417, -2405.1911, 5065.8063, 5856.2141, 8989.8105, 9349.7840, 9970.3013, 8105.4062, -3041.7779, 5058.0480, 8165.0721, 9637.7196, 1795.0894, 7275.3838, 5997.0429, -7562.6481, 8084.0163, 3481.6319, 8078.8512, 2983.7624, 3925.4026, 4931.5812, -1323.1517, 6253.0945}% - -\oodef\z {\QSx \somenumbers}% produced as a comma+space separated list -% black magic as workaround to the shrinkability of spaces in last line... -\hsize 87\fontcharwd\font`0 -\lccode`~=32 -\lowercase{\def~}{\discretionary{}{}{\kern\fontcharwd\font`0}}\catcode32 13 -\noindent\phantom{00}\scantokens\expandafter{\meaning\z}\par -\endgroup -\end{everbatim*} -\fi % fin de si pas xetex - - -All the previous examples were with numbers which could have been handled via -|\ifdim| tests rather than the \csbxint{ifCmp} macro from \xintfracname; using -|\ifdim| tests would naturally be faster. Even faster routine is |code 6| at -(link removed) which uses |\pdfescapestring| and a -Merge Sort algorithm. - -We then turn to a graphical illustration of the algorithm.% -% -\footnote{I have rewritten (2015/11/21) the routine to do only once (and not thrice) the - needed calls to \csa{xintifCmp}, up to the price of one additional |\edef|, - although due to the context execution time on our side is not an issue and - moreover is anyhow overwhelmed by the TikZ's activities. Simultaneously I - have updated the code. - The - variant with the choice of pivot on the right has more overhead: the reason - is simply that we do not convert the data into an array, but maintain a list - of tokens with self-reorganizing delimiters.} -% -For simplicity the pivot is always chosen as the first list item. Then we also -give a variant which picks up the last item as pivot. -\begin{everbatim*} -% in LaTeX preamble: -% \usepackage{xintfrac, xinttools} -% \usepackage{color} -% or, when using Plain TeX: -% \input xintfrac.sty \input xinttools.sty -% \input color.tex -% -% Color definitions -\definecolor{LEFT}{RGB}{216,195,88} -\definecolor{RIGHT}{RGB}{208,231,153} -\definecolor{INERT}{RGB}{199,200,194} -\definecolor{INERTpiv}{RGB}{237,237,237} -\definecolor{PIVOT}{RGB}{109,8,57} -% Start of macro defintions -\makeatletter -% \catcode`? 3 % a bit too paranoid. Normal ? will do. -% -% argument will never be empty -\def\QS@cmp@a #1{\QS@cmp@b #1??}% -\def\QS@cmp@b #1{\noexpand\QS@sep@A\@ne{#1}\QS@cmp@d {#1}}% -\def\QS@cmp@d #1#2{\ifx ?#2\expandafter\QS@cmp@done\fi - \xintifCmp {#1}{#2}\tw@\@ne\z@{#2}\QS@cmp@d {#1}}% -\def\QS@cmp@done #1?{?}% -% -\def\QS@sep@A #1?{\QSLr\QS@sep@L #1\thr@@?#1\thr@@?#1\thr@@?}% -\def\QS@sep@L #1#2{\ifcase #1{#2}\or\or\else\expandafter\QS@sep@I@start\fi \QS@sep@L}% -\def\QS@sep@I@start\QS@sep@L {\noexpand\empty?\QSIr\QS@sep@I}% -\def\QS@sep@I #1#2{\ifcase#1\or{#2}\or\else\expandafter\QS@sep@R@start\fi\QS@sep@I}% -\def\QS@sep@R@start\QS@sep@I {\noexpand\empty?\QSRr\QS@sep@R}% -\def\QS@sep@R #1#2{\ifcase#1\or\or{#2}\else\expandafter\QS@sep@done\fi\QS@sep@R}% -\def\QS@sep@done\QS@sep@R {\noexpand\empty?}% -% -\def\QS@loop {% - \xintloop - % pivot phase - \def\QS@pivotcount{0}% - \let\QSLr\DecoLEFTwithPivot \let\QSIr \DecoINERT - \let\QSRr\DecoRIGHTwithPivot \let\QSIrr\DecoINERT - \centerline{\QS@list}% - % sorting phase - \ifnum\QS@pivotcount>\z@ - \def\QSLr {\QS@cmp@a}\def\QSRr {\QS@cmp@a}% - \def\QSIr {\QSIrr}\let\QSIrr\relax - \edef\QS@list{\QS@list}% compare - \let\QSLr\relax\let\QSRr\relax\let\QSIr\relax - \edef\QS@list{\QS@list}% separate - \def\QSLr ##1##2?{\ifx\empty##1\else\noexpand \QSLr {{##1}##2}\fi}% - \def\QSIr ##1##2?{\ifx\empty##1\else\noexpand \QSIr {{##1}##2}\fi}% - \def\QSRr ##1##2?{\ifx\empty##1\else\noexpand \QSRr {{##1}##2}\fi}% - \edef\QS@list{\QS@list}% gather - \let\QSLr\DecoLEFT \let\QSRr\DecoRIGHT - \let\QSIr\DecoINERTwithPivot \let\QSIrr\DecoINERT - \centerline{\QS@list}% - \repeat }% -% -% \xintFor* loops handle gracefully empty lists. -\def\DecoLEFT #1{\xintFor* ##1 in {#1} \do {\colorbox{LEFT}{##1}}}% -\def\DecoINERT #1{\xintFor* ##1 in {#1} \do {\colorbox{INERT}{##1}}}% -\def\DecoRIGHT #1{\xintFor* ##1 in {#1} \do {\colorbox{RIGHT}{##1}}}% -\def\DecoPivot #1{\begingroup\color{PIVOT}\advance\fboxsep-\fboxrule\fbox{#1}\endgroup}% -% -\def\DecoLEFTwithPivot #1{\xdef\QS@pivotcount{\the\numexpr\QS@pivotcount+\@ne}% - \xintFor* ##1 in {#1} \do - {\xintifForFirst {\DecoPivot {##1}}{\colorbox{LEFT}{##1}}}}% -\def\DecoINERTwithPivot #1{\xdef\QS@pivotcount{\the\numexpr\QS@pivotcount+\@ne}% - \xintFor* ##1 in {#1} \do - {\xintifForFirst {\colorbox{INERTpiv}{##1}}{\colorbox{INERT}{##1}}}}% -\def\DecoRIGHTwithPivot #1{\xdef\QS@pivotcount{\the\numexpr\QS@pivotcount+\@ne}% - \xintFor* ##1 in {#1} \do - {\xintifForFirst {\DecoPivot {##1}}{\colorbox{RIGHT}{##1}}}}% -% -\def\QuickSort #1{% warning: not compatible with empty #1. - % initialize, doing conversion from comma separated values to a list of braced items - \edef\QS@list{\noexpand\QSRr{\xintCSVtoList{#1}}}% many \edef's are to follow anyhow -% earlier I did a first drawing of the list, here with the color of RIGHT elements, -% but the color should have been for example white, anyway I drop this first line - %\let\QSRr\DecoRIGHT - %\par\centerline{\QS@list}% -% - % loop as many times as needed - \QS@loop }% -% -% \catcode`? 12 % in case we had used a funny ? as delimiter. -\makeatother -%% End of macro definitions. -%% Start of Example -\begingroup\offinterlineskip -\small -% \QuickSort {1.0, 0.5, 0.3, 1.5, 1.8, 2.0, 1.7, 0.4, 1.2, 1.4, -% 1.3, 1.1, 0.7, 1.6, 0.6, 0.9, 0.8, 0.2, 0.1, 1.9} -% \medskip -% with repeated values -\QuickSort {1.0, 0.5, 0.3, 0.8, 1.5, 1.8, 2.0, 1.7, 0.4, 1.2, 1.4, - 1.3, 1.1, 0.7, 0.3, 1.6, 0.6, 0.3, 0.8, 0.2, 0.8, 0.7, 1.2} -\endgroup -\end{everbatim*} - -Here is the variant which always picks the pivot as the rightmost element. - -\begin{everbatim*} -\makeatletter -% -\def\QS@cmp@a #1{\noexpand\QS@sep@A\expandafter\QS@cmp@d\expandafter - {\romannumeral0\xintnthelt{-1}{#1}}#1??}% -% -\def\DecoLEFTwithPivot #1{\xdef\QS@pivotcount{\the\numexpr\QS@pivotcount+\@ne}% - \xintFor* ##1 in {#1} \do - {\xintifForLast {\DecoPivot {##1}}{\colorbox{LEFT}{##1}}}} -\def\DecoINERTwithPivot #1{\xdef\QS@pivotcount{\the\numexpr\QS@pivotcount+\@ne}% - \xintFor* ##1 in {#1} \do - {\xintifForLast {\colorbox{INERTpiv}{##1}}{\colorbox{INERT}{##1}}}} -\def\DecoRIGHTwithPivot #1{\xdef\QS@pivotcount{\the\numexpr\QS@pivotcount+\@ne}% - \xintFor* ##1 in {#1} \do - {\xintifForLast {\DecoPivot {##1}}{\colorbox{RIGHT}{##1}}}} -\def\QuickSort #1{% - % initialize, doing conversion from comma separated values to a list of braced items - \edef\QS@list{\noexpand\QSLr {\xintCSVtoList{#1}}}% many \edef's are to follow anyhow - % - % loop as many times as needed - \QS@loop }% -\makeatother -\begingroup\offinterlineskip -\small -% \QuickSort {1.0, 0.5, 0.3, 1.5, 1.8, 2.0, 1.7, 0.4, 1.2, 1.4, -% 1.3, 1.1, 0.7, 1.6, 0.6, 0.9, 0.8, 0.2, 0.1, 1.9} -% \medskip -% with repeated values -\QuickSort {1.0, 0.5, 0.3, 0.8, 1.5, 1.8, 2.0, 1.7, 0.4, 1.2, 1.4, - 1.3, 1.1, 0.7, 0.3, 1.6, 0.6, 0.3, 0.8, 0.2, 0.8, 0.7, 1.2} -\endgroup -\end{everbatim*} - -The choice of the first or last item as pivot is not a good one as nearly -ordered lists will take quadratic time. But for explaining the algorithm via a -graphical interpretation, it is not that bad. If one wanted to pick up the -pivot randomly, the routine would have to be substantially rewritten: in -particular the |\Deco..withPivot| macros need to know where the pivot is, and -currently this is implemented by using either |\xintifForFirst| or -|\xintifForLast|. - -\clearpage + To produce a single file |xint-all.pdf| including both the user + documentation and the source code: + \begin{itemize} + \item acquire |xint.dtx| from + \centeredline{\url{https://www.ctan.org/tex-archive/macros/generic/xint}} + and optionally the |Makefile| from the same location, + \item execute |etex xint.dtx| to extract files, + \item run |make --file=Makefile.mk xint-all.pdf| + \end{itemize} + The last step can be simplified into |make xint-all.pdf| if the + |Makefile| was downloaded in step one (or extracted |Makefile.mk| + was renamed into |Makefile|). -\expandafter\let\csname ExamplesnameUp\endcsname\undefined + These steps require not only |make| but also |latexmk|. -\ifnum\NoSourceCode=1 -\bigskip -\begin{framed} - \small This documentation has been compiled without the source code, - which is available in the separate file: - % - \centeredline{|sourcexint.pdf|,} - % - which will open in a PDF viewer via |texdoc sourcexint.pdf|. + See instructions in |xint-all.tex| (which is produced in the second + step) for alternatives without |make| or |latexmk|. - To produce a single file including both the user documentation and the - source code: - \begin{itemize} - \item run |etex| on |xint.dtx| to generate |xint.tex| among other files, - \item edit |xint.tex| to set the |\NoSourceCode| toggle within it to |0|, - \item run |make clean| and then |make xint.pdf|. - \end{itemize} - This will need |latexmk|; if not available you will need in replacement of - the last step to execute manually |latex| on |xint.tex| (thrice) - then |dvipdfmx|. + In particular it is possible to execute |latex| (three times may be + enough, then |dvipdfmx|), or |pdflatex|, directly on |xint.dtx|. This + will produce a file |xint.pdf| including both the user manual and the + commented source code. \end{framed} \fi - +\clearpage +\let\xintcfracnameUp\undefined \ifnum\dosourcexint=1 +fi +catcode`\ 0 @@ -19616,26 +20172,45 @@ currently this is implemented by using either |\xintifForFirst| or \makeatletter \@gobble\fi \StopEventually{\end{document}\endinput} +\etocignoredepthtags +\def\MARGEPAGENO{1.25em} +\etocdepthtag.toc {implementation} +\addtocontents{toc}{\gdef\string\sectioncouleur{{tocsectionimpcolor}}} + \ifnum\dosourcexint=1 -\renewcommand{\etocaftertochook}{\addvspace{\bigskipamount}} -\etocsettocstyle {}{} -\clearpage + \renewcommand{\etocaftertochook}{\addvspace{\bigskipamount}} + \etocsettocstyle {}{} +% \clearpage % \newgeometry{%hmarginratio=4:3, % hscale=0.7,vscale=0.75}% ATTENTION \newgeometry fait % % un reset de vscale si on ne le % % précise pas ici !!! \else -\clearpage + \etocsetnexttocdepth{section} + \part{The \xintexprnameimp and allied packages source code} + \localtableofcontents \fi +\def\xintImpRunningHeader{{\inheadertrue\catcode`,12\relax + \DOCxintfrontpage, + \xintkernelnameimp, + \xinttoolsnameimp, + \xintcorenameimp, + \xintnameimp, + \xintbinhexnameimp, + \xintgcdnameimp, + \xintfracnameimp, + \xintseriesnameimp, + \xintcfracnameimp, + \xintexprnameimp, + \xinttrignameimp, \xintlognameimp}} +\markboth{\makebox[0pt]{\xintImpRunningHeader}}{\makebox[0pt]{\xintImpRunningHeader}} + +\clearpage \makeatletter -\def\MARGEPAGENO{1.25em} \etocsettocdepth{subsubsection}% 2015/09/15 -\etocdepthtag.toc {implementation} -\addtocontents{toc}{\gdef\string\sectioncouleur{{tocsectionimpcolor}}} - \def\storedlinecounts {} \def\StoreCodelineNo #1{\edef\storedlinecounts{% \unexpanded\expandafter{\storedlinecounts}% @@ -19848,21 +20423,6 @@ currently this is implemented by using either |\xintifForFirst| or %% END OF MACRO DEFINITIONS FOR SOURCEXINT -\def\xintImpRunningHeader{{\inheadertrue\catcode`,12\relax - \DOCxintfrontpage, - \xintkernelnameimp, - \xinttoolsnameimp, - \xintcorenameimp, - \xintnameimp, - \xintbinhexnameimp, - \xintgcdnameimp, - \xintfracnameimp, - \xintseriesnameimp, - \xintcfracnameimp, - \xintexprnameimp, - \xinttrignameimp, \xintlognameimp}} -\markboth{\makebox[0pt]{\xintImpRunningHeader}}{\makebox[0pt]{\xintImpRunningHeader}} - \makeatother \section{Timeline (in brief)} @@ -19958,10 +20518,10 @@ Some parts of the code still date back to the initial release, and the code. Warning: pay attention when looking at the code to the catcode configuration -as found in \csbXINT{_setcatcodes}. Additional temporary configuration is used -at some locations. For example |!| is of catcode letter in \xintexprnameimp -and there are locations with funny catcodes e.g. using some letters with the -math shift catcode. +as found in \csbXINT{setcatcodes} from \xintkernelnameimp. Additional +temporary configuration is used at some locations. For example |!| is of +catcode letter in \xintexprnameimp and there are locations with funny catcodes +e.g. using some letters with the math shift catcode. \MakePercentIgnore %\def\gardesactifs {^^A @@ -19999,6 +20559,10 @@ math shift catcode. % \changed[2020/01/11]{1.4} % \csbxint{Replicate}, \csbxint{Gobble}, \csbxint{LastOne}, \csbxint{FirstOne}. % +% \changed{1.4l} +% Fix the |1.4| added bug that |\XINTrestorecatcodes| forgot to restore +% the catcode of |^||^A| which is set to |3| by |\XINTsetcatcodes|. +% % \subsection{Catcodes, \protect\eTeX{} and reload detection} % % The code for reload detection was initially copied from \textsc{Heiko @@ -20007,128 +20571,160 @@ math shift catcode. % The method for catcodes was also initially directly inspired by these % packages. % +% \lverb|1.4l replaces Info level user messages issued in case of problems +% such as \numexpr not being available with Warning level messages (in the +% LaTeX terminolgy). Should arguably be Error level in that case. +% +% xintkernel.sty was the only xint package emitting such an Info, now Warning +% in case of being loaded twice (via \input in non-LaTeX). This was probably +% a left-over from initial development stage of the loading architecture for +% debugging. Starting with 1.4l, it will abort input silently in such case. +% +% Also at 1.4l I refactored a bit the loading code in the xint*sty files for +% no real reason other than losing time.| % \begin{macrocode} \begingroup\catcode61\catcode48\catcode32=10\relax% \catcode13=5 % ^^M \endlinechar=13 % \catcode123=1 % { \catcode125=2 % } - \catcode35=6 % # \catcode44=12 % , - \catcode45=12 % - \catcode46=12 % . \catcode58=12 % : - \catcode95=11 % _ - \expandafter - \ifx\csname PackageInfo\endcsname\relax - \def\y#1#2{\immediate\write-1{Package #1 Info: #2.}}% + \catcode94=7 % ^ + \def\space{ }\newlinechar10 + \let\z\relax + \expandafter\ifx\csname numexpr\endcsname\relax + \expandafter\ifx\csname PackageWarning\endcsname\relax + \immediate\write128{^^JPackage xintkernel Warning:^^J% + \space\space\space\space + \numexpr not available, aborting input.^^J}% \else - \def\y#1#2{\PackageInfo{#1}{#2}}% + \PackageWarningNoLine{xintkernel}{\numexpr not available, aborting input}% \fi - \let\z\relax - \expandafter - \ifx\csname numexpr\endcsname\relax - \y{xintkernel}{\numexpr not available, aborting input}% - \def\z{\endgroup\endinput}% + \def\z{\endgroup\endinput}% + \else + \expandafter\ifx\csname XINTsetupcatcodes\endcsname\relax \else - \expandafter - \ifx\csname XINTsetupcatcodes\endcsname\relax - \else - \y{xintkernel}{I was already loaded, aborting input}% \def\z{\endgroup\endinput}% - \fi \fi + \fi \ifx\z\relax\else\expandafter\z\fi% % \end{macrocode} % \subsubsection{\csh{XINTrestorecatcodes}, \csh{XINTsetcatcodes}, % \csh{XINTrestorecatcodesendinput}} -% \lverb|Renamed at 1.4e without underscores, in connexion with -% easying up reloading process for xintlog.sty and xinttrig.sty.| +% \changed{1.4e} +% \lverb|Renamed \XINT{set,restore}catcodes +% to be without underscores, to facilitate the reloading process +% for xintlog.sty and xinttrig.sty in uncontrolled contexts.| +% \changed{1.4l} +% \lverb|Fix the 1.4 bug of omission of \catcode1 restore. +% +% Reordered all catcodes assignements for easier maintenance and dropped most +% disparate indications of which packages make use of which settings. +% +% The \XINTrestorecatcodes is somewhat misnamed as it is more a template +% to be used in an \edef to help define actual catcode restoring macros. +% +% However \edef needs usually { and } so there is a potential difficulty with +% telling people to do \edef\myrestore{\XINTrestorecatcodes}, and I almost +% added at 1.4l some \XINTsettorestore:#1->\edef#1{\XINTrestorecatcodes} but +% well, this is not public interface anyhow. The reloading method of +% xintlog.sty and xinttrig.sty does protect itself though against such irreal +% usage possibility with non standard { or }. +% +% Removed at 1.4l the \XINT_setcatcodes and \XINT_restorecatcodes not used +% anywhere now. Used by old version of xintsession.tex, but not anymore since +% a while.| % \begin{macrocode} \def\PrepareCatcodes {% \endgroup \def\XINTrestorecatcodes - {% takes care of all, to allow more economical code in modules - \catcode0=\the\catcode0 % - \catcode59=\the\catcode59 % ; xintexpr - \catcode126=\the\catcode126 % ~ xintexpr - \catcode39=\the\catcode39 % ' xintexpr - \catcode34=\the\catcode34 % " xintbinhex, and xintexpr - \catcode63=\the\catcode63 % ? xintexpr - \catcode124=\the\catcode124 % | xintexpr - \catcode38=\the\catcode38 % & xintexpr - \catcode64=\the\catcode64 % @ xintexpr - \catcode33=\the\catcode33 % ! xintexpr - \catcode93=\the\catcode93 % ] -, xintfrac, xintseries, xintcfrac - \catcode91=\the\catcode91 % [ -, xintfrac, xintseries, xintcfrac - \catcode36=\the\catcode36 % $ xintgcd only $ - \catcode94=\the\catcode94 % ^ - \catcode96=\the\catcode96 % ` - \catcode47=\the\catcode47 % / - \catcode41=\the\catcode41 % ) - \catcode40=\the\catcode40 % ( - \catcode42=\the\catcode42 % * - \catcode43=\the\catcode43 % + - \catcode62=\the\catcode62 % > - \catcode60=\the\catcode60 % < - \catcode58=\the\catcode58 % : - \catcode46=\the\catcode46 % . - \catcode45=\the\catcode45 % - - \catcode44=\the\catcode44 % , - \catcode35=\the\catcode35 % # - \catcode95=\the\catcode95 % _ - \catcode125=\the\catcode125 % } - \catcode123=\the\catcode123 % { - \endlinechar=\the\endlinechar - \catcode13=\the\catcode13 % ^^M - \catcode32=\the\catcode32 % - \catcode61=\the\catcode61\relax % = + {% prepared for use in \edef + \catcode0=\the\catcode0 % ^^@ + \catcode1=\the\catcode1 % ^^A + \catcode13=\the\catcode13 % ^^M + \catcode32=\the\catcode32 % <space> + \catcode33=\the\catcode33 % ! + \catcode34=\the\catcode34 % " + \catcode35=\the\catcode35 % # + \catcode36=\the\catcode36 % $ + \catcode38=\the\catcode38 % & + \catcode39=\the\catcode39 % ' + \catcode40=\the\catcode40 % ( + \catcode41=\the\catcode41 % ) + \catcode42=\the\catcode42 % * + \catcode43=\the\catcode43 % + + \catcode44=\the\catcode44 % , + \catcode45=\the\catcode45 % - + \catcode46=\the\catcode46 % . + \catcode47=\the\catcode47 % / + \catcode58=\the\catcode58 % : + \catcode59=\the\catcode59 % ; + \catcode60=\the\catcode60 % < + \catcode61=\the\catcode61 % = + \catcode62=\the\catcode62 % > + \catcode63=\the\catcode63 % ? + \catcode64=\the\catcode64 % @ + \catcode91=\the\catcode91 % [ + \catcode93=\the\catcode93 % ] + \catcode94=\the\catcode94 % ^ + \catcode95=\the\catcode95 % _ + \catcode96=\the\catcode96 % ` + \catcode123=\the\catcode123 % { + \catcode124=\the\catcode124 % | + \catcode125=\the\catcode125 % } + \catcode126=\the\catcode126 % ~ + \endlinechar=\the\endlinechar\relax }% +% \end{macrocode} +% \lverb|The \noexpand here is required. This feels to me a bit surprising, +% but is a fact, and the source of this must be in the \edef implementation +% but I have not checked it out at this time.| +% \begin{macrocode} \edef\XINTrestorecatcodesendinput {% \XINTrestorecatcodes\noexpand\endinput % }% \def\XINTsetcatcodes - {% - \catcode61=12 % = - \catcode32=10 % space - \catcode13=5 % ^^M - \endlinechar=13 % - \catcode123=1 % { - \catcode125=2 % } - \catcode95=11 % _ LETTER - \catcode35=6 % # - \catcode44=12 % , - \catcode45=12 % - - \catcode46=12 % . - \catcode58=11 % : LETTER - \catcode60=12 % < - \catcode62=12 % > - \catcode43=12 % + - \catcode42=12 % * - \catcode40=12 % ( - \catcode41=12 % ) - \catcode47=12 % / - \catcode96=12 % ` - \catcode94=11 % ^ LETTER - \catcode36=3 % $ - \catcode91=12 % [ - \catcode93=12 % ] - \catcode33=12 % ! (xintexpr.sty will use catcode 11) - \catcode64=11 % @ LETTER - \catcode38=7 % & for \romannumeral`&&@ trick. - \catcode124=12 % | - \catcode63=11 % ? LETTER - \catcode34=12 % " - \catcode39=12 % ' - \catcode126=3 % ~ MATH - \catcode59=12 % ; - \catcode0=12 % for \romannumeral`&&@ trick - \catcode1=3 % for ultra-safe séparateur &&A + {% standard settings with a few xint*sty specific ones + \catcode0=12 % for \romannumeral`&&@ + \catcode1=3 % for safe separator &&A + \catcode13=5 % ^^M + \catcode32=10 % <space> + \catcode33=12 % ! but used as LETTER inside xintexpr.sty + \catcode34=12 % " + \catcode35=6 % # + \catcode36=3 % $ + \catcode38=7 % & SUPERSCRIPT for && as replacement of ^^ + \catcode39=12 % ' + \catcode40=12 % ( + \catcode41=12 % ) + \catcode42=12 % * + \catcode43=12 % + + \catcode44=12 % , + \catcode45=12 % - + \catcode46=12 % . + \catcode47=12 % / + \catcode58=11 % : LETTER + \catcode59=12 % ; + \catcode60=12 % < + \catcode61=12 % = + \catcode62=12 % > + \catcode63=11 % ? LETTER + \catcode64=11 % @ LETTER + \catcode91=12 % [ + \catcode93=12 % ] + \catcode94=11 % ^ LETTER + \catcode95=11 % _ LETTER + \catcode96=12 % ` + \catcode123=1 % { + \catcode124=12 % | + \catcode125=2 % } + \catcode126=3 % ~ MATH SHIFT + \endlinechar=13 % }% - \let\XINT_setcatcodes\XINTsetcatcodes - \let\XINT_restorecatcodes\XINTrestorecatcodes \XINTsetcatcodes }% \PrepareCatcodes @@ -20162,7 +20758,7 @@ math shift catcode. \fi \XINT_providespackage \ProvidesPackage {xintkernel}% - [2022/05/18 v1.4k Paraphernalia for the xint packages (JFB)]% + [2022/05/29 v1.4l Paraphernalia for the xint packages (JFB)]% % \end{macrocode} % \subsection{Constants} % \begin{macrocode} @@ -20204,10 +20800,14 @@ math shift catcode. \fi % \end{macrocode} % \subsection{Token management utilities} +% \added{1.2} +% Check if \cs{empty} and \cs{space} have their standard meanings +% and raise a warning if not. % \changed{1.3b} -% |\xint_gobandstop_...| macros because this is handy for +% Moved here |\xint_gobandstop_...| macros because this is handy for % \csbxint{RandomDigits}. -% |1.3g| forces \cs{empty} and \cs{space} to have their standard meanings, +% \changed{1.4} +% Force \cs{empty} and \cs{space} to have their standard meanings, % rather than simply alerting user in the (theoretical) case they don't that % nothing will work. % If some \LaTeX{} user has \cs{renewcommand}ed them they will be long and @@ -20849,7 +21449,7 @@ math shift catcode. }% \newif\ifxintverbose % \end{macrocode} -% \subsection{\csh{ifxintglobaldefs}, \csh{XINT_global}}\label{src-xintglobaldefstrue} +% \subsection{\csh{ifxintglobaldefs}, \csh{XINT_global}} % \changed{1.3c} % \begin{macrocode} \newif\ifxintglobaldefs @@ -21080,38 +21680,36 @@ mode) and will go ahead hoping repair\endcsname \catcode123=1 % { \catcode125=2 % } \catcode64=11 % @ - \catcode35=6 % # \catcode44=12 % , - \catcode45=12 % - \catcode46=12 % . \catcode58=12 % : - \let\z\endgroup + \catcode94=7 % ^ + \def\empty{}\def\space{ }\newlinechar10 + \def\z{\endgroup}% \expandafter\let\expandafter\x\csname ver@xinttools.sty\endcsname \expandafter\let\expandafter\w\csname ver@xintkernel.sty\endcsname - \expandafter - \ifx\csname PackageInfo\endcsname\relax - \def\y#1#2{\immediate\write-1{Package #1 Info: #2.}}% + \expandafter\ifx\csname numexpr\endcsname\relax + \expandafter\ifx\csname PackageWarning\endcsname\relax + \immediate\write128{^^JPackage xinttools Warning:^^J% + \space\space\space\space + \numexpr not available, aborting input.^^J}% \else - \def\y#1#2{\PackageInfo{#1}{#2}}% + \PackageWarningNoLine{xinttools}{\numexpr not available, aborting input}% \fi - \expandafter - \ifx\csname numexpr\endcsname\relax - \y{xinttools}{\numexpr not available, aborting input}% - \aftergroup\endinput + \def\z{\endgroup\endinput}% \else \ifx\x\relax % plain-TeX, first loading of xinttools.sty \ifx\w\relax % but xintkernel.sty not yet loaded. \def\z{\endgroup\input xintkernel.sty\relax}% \fi \else - \def\empty {}% \ifx\x\empty % LaTeX, first loading, % variable is initialized, but \ProvidesPackage not yet seen \ifx\w\relax % xintkernel.sty not yet loaded. \def\z{\endgroup\RequirePackage{xintkernel}}% \fi \else - \aftergroup\endinput % xinttools already loaded. + \def\z{\endgroup\endinput}% xinttools already loaded. \fi \fi \fi @@ -21122,7 +21720,7 @@ mode) and will go ahead hoping repair\endcsname % \begin{macrocode} \XINT_providespackage \ProvidesPackage{xinttools}% - [2022/05/18 v1.4k Expandable and non-expandable utilities (JFB)]% + [2022/05/29 v1.4l Expandable and non-expandable utilities (JFB)]% % \end{macrocode} % \lverb|\XINT_toks is used in macros such as \xintFor. It is not used % elsewhere in the xint bundle.| @@ -23441,38 +24039,36 @@ mode) and will go ahead hoping repair\endcsname \catcode123=1 % { \catcode125=2 % } \catcode64=11 % @ - \catcode35=6 % # \catcode44=12 % , - \catcode45=12 % - \catcode46=12 % . \catcode58=12 % : - \let\z\endgroup + \catcode94=7 % ^ + \def\empty{}\def\space{ }\newlinechar10 + \def\z{\endgroup}% \expandafter\let\expandafter\x\csname ver@xintcore.sty\endcsname \expandafter\let\expandafter\w\csname ver@xintkernel.sty\endcsname - \expandafter - \ifx\csname PackageInfo\endcsname\relax - \def\y#1#2{\immediate\write-1{Package #1 Info: #2.}}% + \expandafter\ifx\csname numexpr\endcsname\relax + \expandafter\ifx\csname PackageWarning\endcsname\relax + \immediate\write128{^^JPackage xintcore Warning:^^J% + \space\space\space\space + \numexpr not available, aborting input.^^J}% \else - \def\y#1#2{\PackageInfo{#1}{#2}}% + \PackageWarningNoLine{xintcore}{\numexpr not available, aborting input}% \fi - \expandafter - \ifx\csname numexpr\endcsname\relax - \y{xintcore}{\numexpr not available, aborting input}% - \aftergroup\endinput + \def\z{\endgroup\endinput}% \else \ifx\x\relax % plain-TeX, first loading of xintcore.sty \ifx\w\relax % but xintkernel.sty not yet loaded. \def\z{\endgroup\input xintkernel.sty\relax}% \fi \else - \def\empty {}% \ifx\x\empty % LaTeX, first loading, % variable is initialized, but \ProvidesPackage not yet seen \ifx\w\relax % xintkernel.sty not yet loaded. \def\z{\endgroup\RequirePackage{xintkernel}}% \fi \else - \aftergroup\endinput % xintkernel already loaded. + \def\z{\endgroup\endinput}% xintkernel already loaded. \fi \fi \fi @@ -23483,7 +24079,7 @@ mode) and will go ahead hoping repair\endcsname % \begin{macrocode} \XINT_providespackage \ProvidesPackage{xintcore}% - [2022/05/18 v1.4k Expandable arithmetic on big integers (JFB)]% + [2022/05/29 v1.4l Expandable arithmetic on big integers (JFB)]% % \end{macrocode} % \subsection{(WIP!) Error conditions and exceptions} % \lverb|As per the Mike Cowlishaw/IBM's General Decimal Arithmetic Specification @@ -26795,38 +27391,36 @@ mode) and will go ahead hoping repair\endcsname \catcode123=1 % { \catcode125=2 % } \catcode64=11 % @ - \catcode35=6 % # \catcode44=12 % , - \catcode45=12 % - \catcode46=12 % . \catcode58=12 % : - \let\z\endgroup + \catcode94=7 % ^ + \def\empty{}\def\space{ }\newlinechar10 + \def\z{\endgroup}% \expandafter\let\expandafter\x\csname ver@xint.sty\endcsname \expandafter\let\expandafter\w\csname ver@xintcore.sty\endcsname - \expandafter - \ifx\csname PackageInfo\endcsname\relax - \def\y#1#2{\immediate\write-1{Package #1 Info: #2.}}% + \expandafter\ifx\csname numexpr\endcsname\relax + \expandafter\ifx\csname PackageWarning\endcsname\relax + \immediate\write128{^^JPackage xint Warning:^^J% + \space\space\space\space + \numexpr not available, aborting input.^^J}% \else - \def\y#1#2{\PackageInfo{#1}{#2}}% + \PackageWarningNoLine{xint}{\numexpr not available, aborting input}% \fi - \expandafter - \ifx\csname numexpr\endcsname\relax - \y{xint}{\numexpr not available, aborting input}% - \aftergroup\endinput + \def\z{\endgroup\endinput}% \else \ifx\x\relax % plain-TeX, first loading of xintcore.sty \ifx\w\relax % but xintkernel.sty not yet loaded. \def\z{\endgroup\input xintcore.sty\relax}% \fi \else - \def\empty {}% \ifx\x\empty % LaTeX, first loading, % variable is initialized, but \ProvidesPackage not yet seen \ifx\w\relax % xintcore.sty not yet loaded. \def\z{\endgroup\RequirePackage{xintcore}}% \fi \else - \aftergroup\endinput % xint already loaded. + \def\z{\endgroup\endinput}% xint already loaded. \fi \fi \fi @@ -26837,7 +27431,7 @@ mode) and will go ahead hoping repair\endcsname % \begin{macrocode} \XINT_providespackage \ProvidesPackage{xint}% - [2022/05/18 v1.4k Expandable operations on big integers (JFB)]% + [2022/05/29 v1.4l Expandable operations on big integers (JFB)]% % \end{macrocode} % \subsection{More token management} % \begin{macrocode} @@ -29374,38 +29968,36 @@ mode) and will go ahead hoping repair\endcsname \catcode123=1 % { \catcode125=2 % } \catcode64=11 % @ - \catcode35=6 % # \catcode44=12 % , - \catcode45=12 % - \catcode46=12 % . \catcode58=12 % : - \let\z\endgroup + \catcode94=7 % ^ + \def\empty{}\def\space{ }\newlinechar10 + \def\z{\endgroup}% \expandafter\let\expandafter\x\csname ver@xintbinhex.sty\endcsname \expandafter\let\expandafter\w\csname ver@xintkernel.sty\endcsname - \expandafter - \ifx\csname PackageInfo\endcsname\relax - \def\y#1#2{\immediate\write-1{Package #1 Info: #2.}}% + \expandafter\ifx\csname numexpr\endcsname\relax + \expandafter\ifx\csname PackageWarning\endcsname\relax + \immediate\write128{^^JPackage xintbinhex Warning:^^J% + \space\space\space\space + \numexpr not available, aborting input.^^J}% \else - \def\y#1#2{\PackageInfo{#1}{#2}}% + \PackageWarningNoLine{xintbinhex}{\numexpr not available, aborting input}% \fi - \expandafter - \ifx\csname numexpr\endcsname\relax - \y{xintbinhex}{\numexpr not available, aborting input}% - \aftergroup\endinput + \def\z{\endgroup\endinput}% \else \ifx\x\relax % plain-TeX, first loading of xintbinhex.sty \ifx\w\relax % but xintkernel.sty not yet loaded. \def\z{\endgroup\input xintkernel.sty\relax}% \fi \else - \def\empty {}% \ifx\x\empty % LaTeX, first loading, % variable is initialized, but \ProvidesPackage not yet seen \ifx\w\relax % xintkernel.sty not yet loaded. \def\z{\endgroup\RequirePackage{xintkernel}}% \fi \else - \aftergroup\endinput % xintbinhex already loaded. + \def\z{\endgroup\endinput}% xintbinhex already loaded. \fi \fi \fi @@ -29416,7 +30008,7 @@ mode) and will go ahead hoping repair\endcsname % \begin{macrocode} \XINT_providespackage \ProvidesPackage{xintbinhex}% - [2022/05/18 v1.4k Expandable binary and hexadecimal conversions (JFB)]% + [2022/05/29 v1.4l Expandable binary and hexadecimal conversions (JFB)]% % \end{macrocode} % \subsection{Constants, etc...} % \lverb|1.2n switches to \csname-governed expansion at various places.| @@ -30039,25 +30631,24 @@ mode) and will go ahead hoping repair\endcsname \catcode123=1 % { \catcode125=2 % } \catcode64=11 % @ - \catcode35=6 % # \catcode44=12 % , - \catcode45=12 % - \catcode46=12 % . \catcode58=12 % : + \catcode94=7 % ^ + \def\empty{}\def\space{ }\newlinechar10 \def\z{\endgroup}% \expandafter\let\expandafter\x\csname ver@xintgcd.sty\endcsname \expandafter\let\expandafter\w\csname ver@xint.sty\endcsname \expandafter\let\expandafter\t\csname ver@xinttools.sty\endcsname - \expandafter - \ifx\csname PackageInfo\endcsname\relax - \def\y#1#2{\immediate\write-1{Package #1 Info: #2.}}% + \expandafter\ifx\csname numexpr\endcsname\relax + \expandafter\ifx\csname PackageWarning\endcsname\relax + \immediate\write128{^^JPackage xintgcd Warning:^^J% + \space\space\space\space + \numexpr not available, aborting input.^^J}% \else - \def\y#1#2{\PackageInfo{#1}{#2}}% + \PackageWarningNoLine{xintgcd}{\numexpr not available, aborting input}% \fi - \expandafter - \ifx\csname numexpr\endcsname\relax - \y{xintgcd}{\numexpr not available, aborting input}% - \aftergroup\endinput + \def\z{\endgroup\endinput}% \else \ifx\x\relax % plain-TeX, first loading of xintgcd.sty \ifx\w\relax % but xint.sty not yet loaded. @@ -30067,7 +30658,6 @@ mode) and will go ahead hoping repair\endcsname \expandafter\def\expandafter\z\expandafter{\z\input xinttools.sty\relax}% \fi \else - \def\empty {}% \ifx\x\empty % LaTeX, first loading, % variable is initialized, but \ProvidesPackage not yet seen \ifx\w\relax % xint.sty not yet loaded. @@ -30077,7 +30667,7 @@ mode) and will go ahead hoping repair\endcsname \expandafter\def\expandafter\z\expandafter{\z\RequirePackage{xinttools}}% \fi \else - \aftergroup\endinput % xintgcd already loaded. + \def\z{\endgroup\endinput}% xintgcd already loaded. \fi \fi \fi @@ -30088,7 +30678,7 @@ mode) and will go ahead hoping repair\endcsname % \begin{macrocode} \XINT_providespackage \ProvidesPackage{xintgcd}% - [2022/05/18 v1.4k Euclide algorithm with xint package (JFB)]% + [2022/05/29 v1.4l Euclide algorithm with xint package (JFB)]% % \end{macrocode} % \subsection{\csh{xintBezout}} % \lverb|& @@ -30646,38 +31236,36 @@ mode) and will go ahead hoping repair\endcsname \catcode123=1 % { \catcode125=2 % } \catcode64=11 % @ - \catcode35=6 % # \catcode44=12 % , - \catcode45=12 % - \catcode46=12 % . \catcode58=12 % : - \let\z\endgroup + \catcode94=7 % ^ + \def\empty{}\def\space{ }\newlinechar10 + \def\z{\endgroup}% \expandafter\let\expandafter\x\csname ver@xintfrac.sty\endcsname \expandafter\let\expandafter\w\csname ver@xint.sty\endcsname - \expandafter - \ifx\csname PackageInfo\endcsname\relax - \def\y#1#2{\immediate\write-1{Package #1 Info: #2.}}% + \expandafter\ifx\csname numexpr\endcsname\relax + \expandafter\ifx\csname PackageWarning\endcsname\relax + \immediate\write128{^^JPackage xintfrac Warning:^^J% + \space\space\space\space + \numexpr not available, aborting input.^^J}% \else - \def\y#1#2{\PackageInfo{#1}{#2}}% + \PackageWarningNoLine{xintfrac}{\numexpr not available, aborting input}% \fi - \expandafter - \ifx\csname numexpr\endcsname\relax - \y{xintfrac}{\numexpr not available, aborting input}% - \aftergroup\endinput + \def\z{\endgroup\endinput}% \else \ifx\x\relax % plain-TeX, first loading of xintfrac.sty \ifx\w\relax % but xint.sty not yet loaded. \def\z{\endgroup\input xint.sty\relax}% \fi \else - \def\empty {}% \ifx\x\empty % LaTeX, first loading, % variable is initialized, but \ProvidesPackage not yet seen \ifx\w\relax % xint.sty not yet loaded. \def\z{\endgroup\RequirePackage{xint}}% \fi \else - \aftergroup\endinput % xintfrac already loaded. + \def\z{\endgroup\endinput}% xintfrac already loaded. \fi \fi \fi @@ -30688,7 +31276,7 @@ mode) and will go ahead hoping repair\endcsname % \begin{macrocode} \XINT_providespackage \ProvidesPackage{xintfrac}% - [2022/05/18 v1.4k Expandable operations on fractions (JFB)]% + [2022/05/29 v1.4l Expandable operations on fractions (JFB)]% % \end{macrocode} % \subsection{\csh{XINT_cntSgnFork}} % \lverb|1.09i. Used internally, #1 must expand to \m@ne, \z@, or \@ne or @@ -30769,7 +31357,7 @@ mode) and will go ahead hoping repair\endcsname \expandafter\XINT_outfrac_P\expandafter {#2}{#1}% }% % \end{macrocode} -% \subsection{\csh{XINT_inFrac}}\label{src-XINT_infrac} +% \subsection{\csh{XINT_infrac}} % \added{1.03} % \lverb|& % Parses fraction, scientific notation, etc... and produces {n}{A}{B} @@ -30822,7 +31410,7 @@ mode) and will go ahead hoping repair\endcsname % expression must be suitably hidden for example in \firstofone type % constructs. % -% Note: when the numerator is found to be zero \XINT_inFrac *always* returns +% Note: when the numerator is found to be zero \XINT_infrac *always* returns % {0}{0}{1}. This behaviour must not change because 1.2g \xintFloat and % XINTinFloat (for example) rely upon it: if the denominator on output is not % 1, then \xintFloat assumes that the numerator is not zero. @@ -30847,9 +31435,15 @@ mode) and will go ahead hoping repair\endcsname % used as delimiter not as operator. Anyway, I thus fixed this problem % belatedly here regarding \XINT_infrac. % | +% \changed{1.4l} +% \lverb|& +% The venerable \XINT_inFrac is used nowhere, only \XINT_infrac is. +% It is deprecated and I will remove it at next major release. +% See \xintRawBraced. +% | % \begin{macrocode} -\def\XINT_inFrac {\romannumeral0\XINT_infrac }% -\def\XINT_infrac #1% +\def\XINT_inFrac {\romannumeral0\XINT_infrac }% this one deprecated +\def\XINT_infrac #1% this one is core xintfrac macro {% \expandafter\XINT_infrac_fork\romannumeral`&&@#1\xint:/\XINT_W[\XINT_W\XINT_T }% @@ -31194,6 +31788,15 @@ mode) and will go ahead hoping repair\endcsname }% \def\XINT_raw #1#2#3{ #2/#3[#1]}% % \end{macrocode} +% \subsection{\csh{xintRawBraced}} +% \added{1.4l} +% \lverb|& +% User level interface to core \romannumeral0\XINT_infrac. Replaces +% \XINT_inFrac which was defined but nowhere used by the xint packages.| +% \begin{macrocode} +\def\xintRawBraced {\romannumeral0\xintrawbraced }% +\let\xintrawbraced \XINT_infrac +% \end{macrocode} % \subsection{\csh{xintiLogTen}} % \added{1.3e} % \lverb|& @@ -31277,6 +31880,44 @@ mode) and will go ahead hoping repair\endcsname \def\XINT_spraw_a\W\XINT_spraw_p #1[\W]{ #1}% \def\XINT_spraw_p #1[\W]{\xintpraw {#1}}% % \end{macrocode} +% \subsection{\csh{xintFracToSci}} +% \added{1.4l} +% \lverb|The macro with this name which was added here at 1.4 then had +% various changes and finally was moved to $xintexprnameimp at 1.4k +% is now called there +% \xint_FracToSci_x and is private. The present macro is public and +% behaves like the other $xintfracnameimp macros: f-expandable and +% accepts general input. Its output is exactly the same as +% \xint_FracToSci_x for same inputs, with the exception of the empty +% input which \xintFracToSci will output as 0 but \xint_FracToSci_x +% as empty. But the latter is not used by \xinteval for an empty +% leaf as it employs then \xintexprEmptyItem.| +% \begin{macrocode} +\def\xintFracToSci{\romannumeral0\xintfractosci}% +\def\xintfractosci#1{\expandafter\XINT_fractosci\romannumeral0\xintraw{#1}}% +\def\XINT_fractosci#1#2/#3[#4]{\expanded{ % + \ifnum#4=\xint_c_ #1#2\else + \romannumeral0\expandafter\XINT_pfloat_a_fork\romannumeral0\xintrez{#1#2[#4]}% + \fi + \if\XINT_isOne{#3}1\else\if#10\else/#3\fi\fi}% +}% +% \end{macrocode} +% \subsection{\csh{xintFracToDecimal}} +% \added{1.4l} +% \lverb|The macro with this name which was added at 1.4k to +% $xintexprnameimp has been removed. The public variant here +% behaves like the other +% $xintfracnameimp macros: f-expandable and accepts general input.| +% \begin{macrocode} +\def\xintFracToDecimal{\romannumeral0\xintfractodecimal}% +\def\xintfractodecimal#1{\expandafter\XINT_fractodecimal\romannumeral0\xintraw{#1}}% +\def\XINT_fractodecimal #1#2/#3[#4]{\expanded{ % + \ifnum#4=\xint_c_ #1#2\else + \romannumeral0\expandafter\XINT_dectostr\romannumeral0\xintrez{#1#2[#4]}% + \fi + \if\XINT_isOne{#3}1\else\if#10\else/#3\fi\fi}% +}% +% \end{macrocode} % \subsection{\csh{xintRawWithZeros}} % \lverb|& % This was called \xintRaw in versions earlier than 1.07| @@ -31476,12 +32117,11 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \expandafter-\romannumeral0\XINT_sgnfrac_P }% % \end{macrocode} -% \subsection{\csh{xintTeXfromSci}} +% \subsection{\csh{xintTeXFromSci}} % \added{1.4g} % \lverb|The main problem is how to name this and related macros. % -% I use \expanded here, as \xintFracToSci is not f-expandable. But why do I -% bother with the external \expanded? +% I use \expanded here, as \xintFracToSci is not f-expandable. % % Some complications as I want this to be usable on output of \xintFracToSci % hence need to handle the case of a /B. After some hesitations I ended with @@ -31490,16 +32130,27 @@ on input line \noexpand\the\inputlineno.&&J}}#2% %:- if scientific part, postfix /B as \cdot B^{-1} %) % | +% \changed{1.4l} +% \lverb|Suppress external \expanded. Keep internal one. +% +% Rename \xintTeXFromSci from \xintTeXfromSci. Keep deprecated old name +% for the moment. +% +% Add \xintTeXFromScifracmacro. Make it \protected. +% +% Nota bene: catcode of ^ is normal one here (else nothing would work). +% | % \begin{macrocode} -\def\xintTeXfromSci#1% +\def\xintTeXfromSci{\xintfracTeXDeprecation\xintTeXfromSci\xintTeXFromSci}% +\def\xintTeXFromSci#1% {% - \expanded{\expandafter\XINT_texfromsci\expanded{#1}/\relax/\xint:}% + \expandafter\XINT_texfromsci\expanded{#1}/\relax/\xint: }% \def\XINT_texfromsci #1/#2#3/#4\xint: {% \XINT_texfromsci_a #1e\relax e\xint: {\ifx\relax#2\xint_dothis\xint_firstofone\fi - \xint_orthat{\XINT_texfromsci_frac{#2#3}}}% + \xint_orthat{\xintTeXFromScifracmacro{#2#3}}}% {\unless\ifx\relax#2\cdot{#2#3}^{-1}\fi}% }% \def\XINT_texfromsci_a #1e#2#3e#4\xint:#5#6% @@ -31507,9 +32158,9 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \ifx\relax#2#5{#1}\else#1\cdot10^{#2#3}#6\fi }% \ifdefined\frac - \def\XINT_texfromsci_frac#1#2{\noexpand\frac{#2}{#1}}% + \protected\def\xintTeXFromScifracmacro#1#2{\frac{#2}{#1}}% \else - \def\XINT_texfromsci_frac#1#2{{#2\over#1}}% + \protected\def\xintTeXFromScifracmacro#1#2{{#2\over#1}}% \fi % \end{macrocode} % \subsection{\csh{xintTeXOver}} @@ -33219,6 +33870,20 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \def\xintSgn {\romannumeral0\xintsgn }% \def\xintsgn #1{\expandafter\XINT_sgn\romannumeral0\xintraw {#1}\xint:}% % \end{macrocode} +% \subsection{\csh{xintSignBit}} +% \added{1.4l} +% \begin{macrocode} +\def\xintSignBit {\romannumeral0\xintsignbit }% +\def\xintsignbit #1{\expandafter\XINT_signbit\romannumeral0\xintraw {#1}\xint:}% +\def\XINT_signbit #1#2\xint: +{% + \xint_UDzerominusfork + #1-{ 0}% + 0#1{ 1}% + 0-{ 0}% + \krof +}% +% \end{macrocode} % \subsection{\csh{xintGCD}} % \changed{1.4} % They replace the former \xintgcdnameimp macros of the same names which @@ -33673,11 +34338,11 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \expandafter\XINT_float_post \romannumeral0\XINTinfloat[\XINTdigits]{#1}\XINTdigits.% }% -\def\XINT_float_opt [\xint:#1]% +\def\XINT_float_opt [\xint: {% - \expandafter\XINT_float_opt_a\the\numexpr #1.% + \expandafter\XINT_float_opt_a\the\numexpr }% -\def\XINT_float_opt_a #1.#2% +\def\XINT_float_opt_a #1]#2% {% \expandafter\XINT_float_post \romannumeral0\XINTinfloat[#1]{#2}#1.% @@ -33698,6 +34363,76 @@ on input line \noexpand\the\inputlineno.&&J}}#2% }% \def\XINT_float_pos_done #1.#2;{ #2e#1}% % \end{macrocode} +% \subsection{\csh{xintFloatBraced}} +% \added{1.4l} +%\lverb|& +% Je ne le fais pas comme un wrapper au-dessus de \xintFloat +% car c'est pénible avec argument optionnel donc finalemnt +% on est obligé de rajouter overhead comme ici. +% +%( Hésitation si on obéit à \xintFloatZero ou pas. Finalement non. +%: Hésitation si on renvoie avec séparateur décimal ou pas. +%: Hésitation si on met l'exposant scientifique en premier. +%: Hésitation si on sépare le signe pour le mettre en premier. +%: Hésitation si on renvoie un exposant pour mantisse normalisée& +% ou pas normalisée. +%) +% +% Finalement je décide {signe}{exposant}{mantisse sans point décimal}. +% Avec en fait 0 ou 1 pour signe (mais ce sign bit mais ça n'a pas grand +% sens en décimal...). Non finalement mantisse avec point décimal. +% | +% \begin{macrocode} +\def\xintFloatBraced{\romannumeral0\xintfloatbraced }% +\def\xintfloatbraced#1{\XINT_floatbr_chkopt #1\xint:}% +\def\XINT_floatbr_chkopt #1% +{% + \ifx [#1\expandafter\XINT_floatbr_opt + \else\expandafter\XINT_floatbr_noopt + \fi #1% +}% +\def\XINT_floatbr_noopt #1\xint:% +{% + \expandafter\XINT_floatbr_post + \romannumeral0\XINTinfloat[\XINTdigits]{#1}\XINTdigits.% +}% +\def\XINT_floatbr_opt [\xint: +{% + \expandafter\XINT_floatbr_opt_a\the\numexpr +}% +\def\XINT_floatbr_opt_a #1]#2% +{% + \expandafter\XINT_floatbr_post + \romannumeral0\XINTinfloat[#1]{#2}#1.% +}% +\def\XINT_floatbr_post #1% +{% + \xint_UDzerominusfork + #1-\XINT_floatbr_zero + 0#1\XINT_floatbr_neg + 0-\XINT_floatbr_pos + \krof #1% +}% +% \end{macrocode} +%\lverb|& +% Hésitation à faire +%( \def\XINT_floatbr_zero #1]#2.{\expandafter\XINT_floatbr_zero_a\xintFloatZero e0e\relax}% +%: \def\XINT_floatbr_zero_a#1e#2e#3\relax{{#1}{#2}}% +%) +% Finalement non. Et même je décide de renvoyer autant de zéros que P. +% De plus depuis j'ai opté pour {sign bit}{exposant}{mantisse} +% Hésitation si mantisse avec ou sans le séparateur décimal. +% Est-ce que je devrais mettre plutôt -0+ au début? +% | +% \begin{macrocode} +\def\XINT_floatbr_zero #1]#2.{\expanded{{0}{0}{0.\xintReplicate{#2-\xint_c_i}0}}}% +\def\XINT_floatbr_neg-{\expandafter\XINT_floatbr_neg_a\romannumeral0\XINT_floatbr_pos}% +\def\XINT_floatbr_neg_a#1{{1}}% +\def\XINT_floatbr_pos #1#2[#3]#4.% +{% + \expanded{{0}{\the\numexpr#3+#4-\xint_c_i}}{#1.#2}% +}% +% \end{macrocode} % \subsection{\csh{XINTinFloat}, \csh{XINTinFloatS}} % \lverb|& % This routine is like \xintFloat but produces an output of the shape A[N] @@ -33763,12 +34498,13 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \def\XINT_infloatS_clean_a !#1.{ }% % \end{macrocode} % \lverb|début de la routine proprement dite, -% l'argument optionnel est obligatoire.| +% l'argument optionnel est obligatoire. +% | % \begin{macrocode} -\def\XINT_infloat [#1]#2% +\def\XINT_infloat [#1]%#2% {% \expandafter\XINT_infloat_a\the\numexpr #1\expandafter.% - \romannumeral0\XINT_infrac {#2}% + \romannumeral0\XINT_infrac% {#2}% }% % \end{macrocode} % \lverb| #1=P, #2=n, #3=A, #4=B.| @@ -34077,6 +34813,11 @@ on input line \noexpand\the\inputlineno.&&J}}#2% % \added{1.3e} % \lverb|Le comportement pour un input nul est non % encore finalisé. Il changera lorsque NaN, +Inf, -Inf existeront. +% +% The optional argument [#1] is in fact mandatory and #1 is +% not pre-expanded in a \numexpr. +% +% The return value here 2^31-2^15 is highly undecided. % | % \begin{macrocode} \def\XINTFloatiLogTen {\the\numexpr\XINTfloatilogten}% @@ -34089,79 +34830,8 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \xint_orthat\XINT_floatilogten_b #1% }% \def\XINT_floatilogten_z 0[0]#1.{-"7FFF8000\relax}% -\def\XINT_floatilogten_a !#1.#2[#3]#4.{#3-#1+#4-1\relax}% -\def\XINT_floatilogten_b #1[#2]#3.{#2+#3-1\relax}% -% \end{macrocode} -% \subsection{\csh{xintFloatSciExp}} -% \added[2022/05/16]{1.4k} -% \lverb|Hesitation about whether keeping the general \romannumeral0 -% trigger which is documented as general rule.| -% \begin{macrocode} -\def\xintFloatSciExp {\the\numexpr\xintfloatsciexp }% -\def\xintpfloatsciexp #1{\XINT_floatsciexp_chkopt #1\xint:}% -\def\XINT_floatsciexp_chkopt #1% -{% - \ifx [#1\expandafter\XINT_floatsciexp_opt - \else\expandafter\XINT_floatsciexp_noopt - \fi #1% -}% -\def\XINT_floatsciexp_noopt #1\xint:% -{% - \expandafter\XINT_floatsciexp\romannumeral0\XINT_infloat[\XINTdigits]{#1}% - \XINTdigits.% -}% -\def\XINT_floatsciexp_opt [\xint:#1]#2% -{% - \expandafter\XINT_floatsciexp\romannumeral0\XINT_infloat[#1]{#2}#1.% -}% -\def\XINT_floatsciexp #1{% - \if #10\xint_dothis\XINT_floatsciexp_z\fi - \if #1!\xint_dothis\XINT_floatsciexp_a\fi - \xint_orthat\XINT_floatsciexp_b #1% -}% -\def\XINT_floatsciexp_z 0[0]#1.{0\relax}% -\def\XINT_floatsciexp_a !#1.#2[#3]#4.{#3-#1+#4-1\relax}% -\def\XINT_floatsciexp_b #1[#2]#3.{#2+#3-1\relax}% -% \end{macrocode} -% \subsection{\csh{xintFloatSignificand}} -% \added[2022/05/16]{1.4k} -% \lverb|Hesitation about whether returning abcd... or a.bcd... -% with a separator -% and slight hesitation about handling of zero.| -% \begin{macrocode} -\def\xintFloatSignificand {\romannumeral0\xintfloatsignificand}% -\def\xintfloatsignificand #1{\XINT_floatsgf_chkopt #1\xint:}% -\def\XINT_floatsgf_chkopt #1% -{% - \ifx [#1\expandafter\XINT_floatsgf_opt - \else\expandafter\XINT_floatsgf_noopt - \fi #1% -}% -\def\XINT_floatsgf_noopt #1\xint:% -{% - \expandafter\XINT_floatsgf_post - \romannumeral0\XINTinfloat[\XINTdigits]{#1}\XINTdigits.% -}% -\def\XINT_floatsgf_opt [\xint:#1]% -{% - \expandafter\XINT_floatsgf_opt_a\the\numexpr #1.% -}% -\def\XINT_floatsgf_opt_a #1.#2% -{% - \expandafter\XINT_floatsgf_post - \romannumeral0\XINTinfloat[#1]{#2}#1.% -}% -\def\XINT_floatsgf_post #1% -{% - \xint_UDzerominusfork - #1-\XINT_floatsgf_zero - 0#1\XINT_floatsgf_neg - 0-\XINT_floatsgf_pos - \krof #1% -}%[ -\def\XINT_floatsgf_zero #1]#2.{\XINT_dsx_addzeros{#2};}% -\def\XINT_floatsgf_neg-{\XINT_floatsgf_pos}% -\def\XINT_floatsgf_pos #1[#2]#3.{ #1}% +\def\XINT_floatilogten_a !#1.#2[#3]#4.{#3-#1+#4-\xint_c_i\relax}% +\def\XINT_floatilogten_b #1[#2]#3.{#2+#3-\xint_c_i\relax}% % \end{macrocode} % \subsection{\csh{xintPFloat}} % \added{1.1} @@ -34221,7 +34891,7 @@ on input line \noexpand\the\inputlineno.&&J}}#2% % as it knows it will % be used always with a [P] argument in the xintexpr.sty context. % | -% \changed[2022/05/18]{1.4k} +% \changed{1.4k} % \lverb|& % Addition of customization via \xintPFloatZero, \xintPFloatLengthOneSuffix, % \xintPFloatNoSciEmax, \xintPFloatNoSciEmin which replace formerly @@ -34257,6 +34927,13 @@ on input line \noexpand\the\inputlineno.&&J}}#2% % % Threshold customizable via \xintPFloatMinTrimmed. % | +% \changed[2022/05/22]{1.4l} +% \lverb|The 1.4k check for canceling the trimming of trailing zeros +% took over priority over the later check for being an integer when +% decimal fixed point notation was used (or being only with a one-digit +% trimmed mantissa). In particular if user set \xintPFloatMinTrimmed to +% the value of Digits (or P) to avoid trimming it also prevented +% recognition of some integers (but not all). Fixed at 1.4l| % \begin{macrocode} \def\xintPFloatE{e}% \def\xintPFloatNoSciEmax{\xint_c_v}% 1e6 uses sci.not. @@ -34283,7 +34960,8 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \expandafter\XINT_pfloat\romannumeral0\XINTinfloatS[\XINTdigits]{#1}% \XINTdigits.% }% -\def\XINT_pfloat_opt [\xint:#1]#2% +\def\XINT_pfloat_opt [\xint:{\expandafter\XINT_pfloat_opt_a\the\numexpr}% +\def\XINT_pfloat_opt_a #1]#2% {% \expandafter\XINT_pfloat\romannumeral0\XINTinfloatS[#1]{#2}% #1.% @@ -34308,28 +34986,15 @@ on input line \noexpand\the\inputlineno.&&J}}#2% #3.#2.#1.% }% % \end{macrocode} -%\lverb|Needed for \xintFracToSci, which uses old pre 1.4k interface.| -% \begin{macrocode} -\def\XINT_pfloat_keeptrimmed_fork#1% -{% - \xint_UDzerominusfork - #1-\XINT_pfloat_keeptrimmed_zero - 0#1\XINT_pfloat_keeptrimmed_neg - 0-\XINT_pfloat_keeptrimmed_pos - \krof #1% -}% -\def\XINT_pfloat_keeptrimmed_zero#1]{\expanded{ \xintPFloatZero}}% -\def\XINT_pfloat_keeptrimmed_neg-{\expandafter-\romannumeral0\XINT_pfloat_keeptrimmed_pos}% -\def\XINT_pfloat_keeptrimmed_pos#1/1[#2]% -{% - \expandafter\XINT_pfloat_a\the\numexpr\xintLength{#1}.#2.#1.% -}% -% \end{macrocode} %\lverb|& %( #1 est la longueur de la mantisse trimmée %: #2 est Digits ou P -%: Si #2-#1 < MinTrimmed, on remet les trailing zeros +%: Si #2-#1 < MinTrimmed, on se prépare à peut-être remettre les trailing zeros %) +% +% On teste pour #2=#1, car c'est le cas le plus fréquent (mais est-ce +% une bonne idée) car on sait qu'alors il n'y a pas de trailing zéros +% donc on va direct vers \XINT_pfloat_a. %| % \begin{macrocode} \def\XINT_pfloat_aa #1.#2.% @@ -34340,39 +35005,79 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \xint_orthat\XINT_pfloat_a #1.% }% % \end{macrocode} +%\lverb|Needed for \xintFracToSci, which uses old pre 1.4k interface, +% where the P parameter was not stored for counting how many zeros +% were trimmed. \xintFracToSci trims always.| +% \begin{macrocode} +\def\XINT_pfloat_a_fork#1% +{% + \xint_UDzerominusfork + #1-\XINT_pfloat_a_zero + 0#1\XINT_pfloat_a_neg + 0-\XINT_pfloat_a_pos + \krof #1% +}% +\def\XINT_pfloat_a_zero#1]{\expanded{ \xintPFloatZero}}% +\def\XINT_pfloat_a_neg-{\expandafter-\romannumeral0\XINT_pfloat_a_pos}% +\def\XINT_pfloat_a_pos#1/1[#2]% +{% + \expandafter\XINT_pfloat_a\the\numexpr\xintLength{#1}.#2.#1.% +}% +% \end{macrocode} %\lverb|& -%( #2 est la longueur de la mantisse trimmée -%: #1 est P mais peut être encore sous la forme \XINTdigits +%( #1 est P > #2 mais peut être encore sous la forme \XINTdigits +%: #2 est la longueur de la mantisse trimmée %: #3 est l'exposant non normalisé %: #4 est la mantisse %) +% On reconstitue les trailing zéros à remettre éventuellement. %| % \begin{macrocode} -\def\XINT_pfloat_i #1.#2.#3.#4.% +\def\XINT_pfloat_i #1.#2.%#3.#4.% {% - \expandafter\XINT_pfloat_j - \the\numexpr#3+#2-#1\expandafter.% - \romannumeral0\XINT_dsx_addzerosnofuss{#1-#2}#4;.#1.% + \expandafter\XINT_pfloat_j\romannumeral\xintreplicate{#1-#2}0.#2.% }% % \end{macrocode} -%\lverb|& -%( #1 est le nouvel exposant non normalisé -%: #2 est la nouvelle mantisse à P chiffres -%: #3 est P (peut être sous forme \XINTdigits) +% \lverb|& +%( #1 est les trailing zeros à remettre peut-être +%: #2 est la longueur de la mantisse trimmée +%: #3#4 est l'exposant N pour mantisse trimmée entière +%: #5 serait la mantisse trimmée %) +% On calcule l'exposant scientifique. +% +% La façon bizarre de mettre #3 est liée aux versions anciennes +% de la macro, héritage conservé pour minimiser effort d'adaptation. %| % \begin{macrocode} -\def\XINT_pfloat_j #1.#2.#3.{\XINT_pfloat_a#3.#1.#2.}% -\def\XINT_pfloat_a #1.#2#3.% +\def\XINT_pfloat_j #1.#2.#3#4.%#5. +{% + \expandafter\XINT_pfloat_b\the\numexpr#2+#3#4-\xint_c_i.% + #3#2.#1.% +}% +% \end{macrocode} +% \lverb|& +%( #1 est la longueur de la mantisse trimmée +%: #2#3 est l'exposant N pour mantisse trimmée +%: #4 serait la mantisse +%) +% On calcule l'exposant scientifique. On est arrivé ici dans +% une branche où on n'a pas besoin de remettre les zéros trimmés +% donc on positionne un dernier argument vide pour \XINT_pfloat_b +% | +% \begin{macrocode} +\def\XINT_pfloat_a #1.#2#3.%#4. {% \expandafter\XINT_pfloat_b\the\numexpr#1+#2#3-\xint_c_i.% - #2#1.% + #2#1..% }% % \end{macrocode} % \lverb|& %( #1 est l'exposant scientifique K %: #2 est le signe ou premier chiffre de l'exposant N pour mantisse trimmée -%: Il est suivi par la longueur de la mantisse trimmée +%: #3 serait la longueur de la mantisse trimmée +%: #4 serait les trailing zéros +%: #5 serait la mantisse trimmée %) % On va vers \XINT_float_P lorsque l'on n'utilise pas la notation % scientifique, mais qu'on a besoin de chiffres non nuls fractionnaires, @@ -34382,7 +35087,7 @@ on input line \noexpand\the\inputlineno.&&J}}#2% % scientifique et que l'exposant scientifique était strictement négatif. %| % \begin{macrocode} -\def\XINT_pfloat_b #1.#2% +\def\XINT_pfloat_b #1.#2%#3.#4.#5. {% \ifnum \xintPFloatNoSciEmax<#1 \xint_dothis\XINT_pfloat_sci\fi \ifnum \xintPFloatNoSciEmin>#1 \xint_dothis\XINT_pfloat_sci\fi @@ -34393,8 +35098,8 @@ on input line \noexpand\the\inputlineno.&&J}}#2% }% % \end{macrocode} % \lverb|& -% #1 is the scientific exponent, #2 is the length of the trimmed mantissa. -% (may be the \XINTdigits token) +% #1 is the scientific exponent, #2 is the length of the trimmed mantissa, +% #3 are the trailing zeros, #4 is the trimmed integer mantissa % % \xintPFloatE can be replaced by any f-expandable macro with a dot-delimited % argument which produces a dot-delimited output. @@ -34405,7 +35110,7 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \ifnum#2=\xint_c_i\expandafter\XINT_pfloat_sci_i\expandafter\fi \expandafter\XINT_pfloat_sci_a\romannumeral`&&@\xintPFloatE #1.% }% -\def\XINT_pfloat_sci_a #1.#2#3.{ #2.#3#1}% +\def\XINT_pfloat_sci_a #1.#2.#3#4.{ #3.#4#2#1}% % \end{macrocode} % \lverb|& % #1#2=\fi\XINT_pfloat_sci_a @@ -34414,44 +35119,46 @@ on input line \noexpand\the\inputlineno.&&J}}#2% % Finally at 1.4k, \xintPFloatLengthOneSuffix for customization. % | % \begin{macrocode} -\def\XINT_pfloat_sci_i #1#2#3.#4.{\expanded{#1 #4\xintPFloatLengthOneSuffix}#3}% +\def\XINT_pfloat_sci_i #1#2#3.#4.#5.{\expanded{#1 #5\xintPFloatLengthOneSuffix}#3}% % \end{macrocode} % \lverb|& -% #1=sci.exp. K, #2=mant. wd L, #3=mantissa +% #1=sci.exp. K, #2=mant. wd L, #3=trailing zéros, #4=trimmed mantissa % % For _N, #1 is at most -1, for _P, #1 is at least 0. For _P there % will be fractional digits, and #1+1 digits before the mark. % | % \begin{macrocode} -\def\XINT_pfloat_N#1.#2.#3.% +\def\XINT_pfloat_N#1.#2.#3.#4.% {% - \expandafter\XINT_pfloat_N_e\romannumeral\xintreplicate{-#1}{0}#3% + \expandafter\XINT_pfloat_N_e\romannumeral\xintreplicate{-#1}{0}#4#3% }% \def\XINT_pfloat_N_e 0{ 0.}% % \end{macrocode} % \lverb|& +% #1=sci.exp. K, #2=mant. wd L, #3=trailing zéros, #4=trimmed mantissa +% % Abusive usage of internal \XINT_split_fromleft_a. % It means using x = -1 - #1 in \xintDecSplit from xint.sty. % We benefit also with the way \xintDecSplit is built upon % \XINT_split_fromleft with a final clean-up which here -% we can shortcut (non \xint_bye. not \xint_bye..). +% we can shortcut via using terminator "\xint_bye." not "\xint_bye.." % | % \begin{macrocode} -\def\XINT_pfloat_P #1.#2.#3.% +\def\XINT_pfloat_P #1.#2.#3.#4.% {% \expandafter\XINT_split_fromleft_a - \the\numexpr\xint_c_vii-#1.#3\xint_bye2345678\xint_bye.% + \the\numexpr\xint_c_vii-#1.#4\xint_bye2345678\xint_bye.#3% }% % \end{macrocode} % \lverb|& -% Here we have an integer so we only need to postfix mantissa #3 -% with #1+1-#2 zeros (#1=sci exp., #2=mantissa width). Less cumbersome -% to do that with \expanded. +% Here we have an integer so we only need to postfix the trimmed mantissa #4 +% with #1+1-#2 zeros (#1=sci exp., #2=trimmed mantissa width). Less cumbersome +% to do that with \expanded. And the trailing zeros #3 ignored here. % | % \begin{macrocode} -\def\XINT_pfloat_Ps #1.#2.#3.% +\def\XINT_pfloat_Ps #1.#2.#3.#4.% {% - \expanded{ #3% + \expanded{ #4% \romannumeral\xintreplicate{#1+\xint_c_i-#2}{0}\xintPFloatIntSuffix}% }% % \end{macrocode} @@ -34475,7 +35182,7 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \expandafter\XINT_floattodec\romannumeral0\XINTinfloatS[#1]% }% % \end{macrocode} -% \lverb|Tentation to try to use direct access to lower entry points +% \lverb|Temptation to try to use direct access to lower entry points % from \xintREZ, but it dates back from very early days and uses old \Z % delimiters (same remarks for the code jumping from \xintFracToSci % to \xintrez)| @@ -36168,38 +36875,36 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \catcode123=1 % { \catcode125=2 % } \catcode64=11 % @ - \catcode35=6 % # \catcode44=12 % , - \catcode45=12 % - \catcode46=12 % . \catcode58=12 % : - \let\z\endgroup + \catcode94=7 % ^ + \def\empty{}\def\space{ }\newlinechar10 + \def\z{\endgroup}% \expandafter\let\expandafter\x\csname ver@xintseries.sty\endcsname \expandafter\let\expandafter\w\csname ver@xintfrac.sty\endcsname - \expandafter - \ifx\csname PackageInfo\endcsname\relax - \def\y#1#2{\immediate\write-1{Package #1 Info: #2.}}% + \expandafter\ifx\csname numexpr\endcsname\relax + \expandafter\ifx\csname PackageWarning\endcsname\relax + \immediate\write128{^^JPackage xintseries Warning:^^J% + \space\space\space\space + \numexpr not available, aborting input.^^J}% \else - \def\y#1#2{\PackageInfo{#1}{#2}}% + \PackageWarningNoLine{xintseries}{\numexpr not available, aborting input}% \fi - \expandafter - \ifx\csname numexpr\endcsname\relax - \y{xintseries}{\numexpr not available, aborting input}% - \aftergroup\endinput + \def\z{\endgroup\endinput}% \else \ifx\x\relax % plain-TeX, first loading of xintseries.sty \ifx\w\relax % but xintfrac.sty not yet loaded. \def\z{\endgroup\input xintfrac.sty\relax}% \fi \else - \def\empty {}% \ifx\x\empty % LaTeX, first loading, % variable is initialized, but \ProvidesPackage not yet seen \ifx\w\relax % xintfrac.sty not yet loaded. \def\z{\endgroup\RequirePackage{xintfrac}}% \fi \else - \aftergroup\endinput % xintseries already loaded. + \def\z{\endgroup\endinput}% xintseries already loaded. \fi \fi \fi @@ -36210,7 +36915,7 @@ on input line \noexpand\the\inputlineno.&&J}}#2% % \begin{macrocode} \XINT_providespackage \ProvidesPackage{xintseries}% - [2022/05/18 v1.4k Expandable partial sums with xint package (JFB)]% + [2022/05/29 v1.4l Expandable partial sums with xint package (JFB)]% % \end{macrocode} % \subsection{\csh{xintSeries}} % \begin{macrocode} @@ -36676,38 +37381,36 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \catcode123=1 % { \catcode125=2 % } \catcode64=11 % @ - \catcode35=6 % # \catcode44=12 % , - \catcode45=12 % - \catcode46=12 % . \catcode58=12 % : - \let\z\endgroup + \catcode94=7 % ^ + \def\empty{}\def\space{ }\newlinechar10 + \def\z{\endgroup}% \expandafter\let\expandafter\x\csname ver@xintcfrac.sty\endcsname \expandafter\let\expandafter\w\csname ver@xintfrac.sty\endcsname - \expandafter - \ifx\csname PackageInfo\endcsname\relax - \def\y#1#2{\immediate\write-1{Package #1 Info: #2.}}% + \expandafter\ifx\csname numexpr\endcsname\relax + \expandafter\ifx\csname PackageWarning\endcsname\relax + \immediate\write128{^^JPackage xintcfrac Warning:^^J% + \space\space\space\space + \numexpr not available, aborting input.^^J}% \else - \def\y#1#2{\PackageInfo{#1}{#2}}% + \PackageWarningNoLine{xintcfrac}{\numexpr not available, aborting input}% \fi - \expandafter - \ifx\csname numexpr\endcsname\relax - \y{xintcfrac}{\numexpr not available, aborting input}% - \aftergroup\endinput + \def\z{\endgroup\endinput}% \else \ifx\x\relax % plain-TeX, first loading of xintcfrac.sty \ifx\w\relax % but xintfrac.sty not yet loaded. \def\z{\endgroup\input xintfrac.sty\relax}% \fi \else - \def\empty {}% \ifx\x\empty % LaTeX, first loading, % variable is initialized, but \ProvidesPackage not yet seen \ifx\w\relax % xintfrac.sty not yet loaded. \def\z{\endgroup\RequirePackage{xintfrac}}% \fi \else - \aftergroup\endinput % xintcfrac already loaded. + \def\z{\endgroup\endinput}% xintcfrac already loaded. \fi \fi \fi @@ -36718,7 +37421,7 @@ on input line \noexpand\the\inputlineno.&&J}}#2% % \begin{macrocode} \XINT_providespackage \ProvidesPackage{xintcfrac}% - [2022/05/18 v1.4k Expandable continued fractions with xint package (JFB)]% + [2022/05/29 v1.4l Expandable continued fractions with xint package (JFB)]% % \end{macrocode} % \subsection{\csh{xintCFrac}} % \begin{macrocode} @@ -38052,26 +38755,25 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \catcode123=1 % { \catcode125=2 % } \catcode64=11 % @ - \catcode35=6 % # \catcode44=12 % , - \catcode45=12 % - \catcode46=12 % . \catcode58=12 % : - \def\z {\endgroup}% + \catcode94=7 % ^ + \def\empty{}\def\space{ }\newlinechar10 + \def\z{\endgroup}% \expandafter\let\expandafter\x\csname ver@xintexpr.sty\endcsname \expandafter\let\expandafter\w\csname ver@xintfrac.sty\endcsname \expandafter\let\expandafter\t\csname ver@xinttools.sty\endcsname - \expandafter - \ifx\csname PackageInfo\endcsname\relax - \def\y#1#2{\immediate\write-1{Package #1 Info: #2.}}% + % I don't think engine exists providing \expanded but not \numexpr + \expandafter\ifx\csname expanded\endcsname\relax + \expandafter\ifx\csname PackageWarning\endcsname\relax + \immediate\write128{^^JPackage xintexpr Warning:^^J% + \space\space\space\space + \expanded not available, aborting input.^^J}% \else - \def\y#1#2{\PackageInfo{#1}{#2}}% + \PackageWarningNoLine{xintexpr}{\expanded not available, aborting input}% \fi - \expandafter - % I don't think engine exists providing \expanded but not \numexpr - \ifx\csname expanded\endcsname\relax - \y{xintexpr}{\expanded not available, aborting input}% - \aftergroup\endinput + \def\z{\endgroup\endinput}% \else \ifx\x\relax % plain-TeX, first loading of xintexpr.sty \ifx\w\relax % but xintfrac.sty not yet loaded. @@ -38083,7 +38785,6 @@ on input line \noexpand\the\inputlineno.&&J}}#2% {\z\input xinttools.sty\relax}% \fi \else - \def\empty {}% \ifx\x\empty % LaTeX, first loading, % variable is initialized, but \ProvidesPackage not yet seen \ifx\w\relax % xintfrac.sty not yet loaded. @@ -38095,7 +38796,7 @@ on input line \noexpand\the\inputlineno.&&J}}#2% {\z\RequirePackage{xinttools}}% \fi \else - \aftergroup\endinput % xintexpr already loaded. + \def\z{\endgroup\endinput}% xintexpr already loaded. \fi \fi \fi @@ -38111,7 +38812,7 @@ on input line \noexpand\the\inputlineno.&&J}}#2% % \begin{macrocode} \XINT_providespackage \ProvidesPackage{xintexpr}% - [2022/05/18 v1.4k Expandable expression parser (JFB)]% + [2022/05/29 v1.4l Expandable expression parser (JFB)]% \catcode`! 11 \let\XINT_Cmp \xintiiCmp \def\XINTfstop{\noexpand\XINTfstop}% @@ -38159,11 +38860,15 @@ on input line \noexpand\the\inputlineno.&&J}}#2% % technique made very difficult implementation of nested structures. % \subsubsection{Bracketed list rendering with prettifying of leaves from nested % braced contents} -% \lverb|1.4 The braces in \XINT:expr:toblistwith are there because there is -% an \expanded trigger. -% -% 1.4d: support for polexpr 0.8 polynomial type. -% | +% \added{1.4} +% \lverb|The braces in \XINT:expr:toblistwith are there because there is +% an \expanded trigger.| +% \changed{1.4d} +% \lverb|Add support for the polexpr 0.8 polynomial type. See \XINT:expr:toblist_a| +% \changed{1.4l} +% \lverb|Let \XINT:expr:toblist_b use #1{#2} with regular { and } in case +% macro #1 is \protected and things are output to external file where former +% #1<#2> would end up with catcode 12 < and >.| % \begin{macrocode} \def\XINT:expr:toblistwith#1#2% {% @@ -38186,10 +38891,12 @@ on input line \noexpand\the\inputlineno.&&J}}#2% <% pol([\XINT:expr:toblist_b #1!#3}^])\XINT:expr:toblist_c #1!}% >% -\def\XINT:expr:toblist_b #1!#2}% -<% - \if\relax#2\relax\xintexprEmptyItem\else#1<#2>\fi\XINT:expr:toblist_c #1!}% ->% +\catcode`{ 1 \catcode`} 2 +\def\XINT:expr:toblist_b #1{% +\def\XINT:expr:toblist_b ##1!##2#1% +{% + \if\relax##2\relax\xintexprEmptyItem\else##1{##2}\fi\XINT:expr:toblist_c ##1!#1% +}}\catcode`{ 12 \catcode`} 12 \XINT:expr:toblist_b<}>% \def\XINT:expr:toblist_c #1}#2% <% \if ^#2\xint_dothis<\xint_gob_til_^>\fi @@ -38322,6 +39029,11 @@ on input line \noexpand\the\inputlineno.&&J}}#2% % % This code is used by \xintiexpr and \xintfloatexpr in case of optional % argument and by the «Universal functions». +% +% Comment at 1.4l: this seems to be used only at private package level, else +% I should modify \XINT:expr:mapwithin_b like I did with \XINT:expr:toblist_b +% to use regular braces in case the applied macro is \protected and +% things end up in external file. % | % % \begin{macrocode} @@ -38335,7 +39047,7 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \if ^#2\expandafter\xint_gob_til_^\else\expandafter\XINT:expr:mapwithin_a\fi #1!#2% }% -\begingroup % should I check lccode s generally if corrupted context at load? +\begingroup \catcode`[ 1 \catcode`] 2 \lccode`[`{ \lccode`]`} \catcode`< 1 \catcode`> 2 \catcode`{ 12 \catcode`} 12 \lowercase<\endgroup @@ -38671,8 +39383,9 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \def\xintifsgnfloatexpr #1{\romannumeral0\xintiiifsgn {\xintthefloatexpr #1\relax}}% \def\xintifsgniiexpr #1{\romannumeral0\xintiiifsgn {\xinttheiiexpr #1\relax}}% % \end{macrocode} -% \subsubsection{\csh{xintFracToSci}} +% \subsubsection{\csh{xint_FracToSci_x}} % \added{1.4} +% Under the name of |\xintFracToSci| and defined in \xintfracnameimp. % \changed{1.4e} % \lverb|Refactored and much simplified % @@ -38700,83 +39413,58 @@ on input line \noexpand\the\inputlineno.&&J}}#2% %: If N is not zero, scientific notation like \xintPFloat,& % i.e. behaviour like \xintfloateval apart from the rounding& % to significands of width Digits.& -% At 1.4k, trimming of zeros is always done, i.e.& +% At 1.4k, trimming of zeros from A is always done, i.e.& % the \xintPFloatMinTrimmed is ignored to keep behaviour.& -% unchanged. +% unchanged. Trailing zeros of B are kept as is. %: The zero gives 0, except in A[N] and A/B[N] cases, it may give& % 0.0 %) % | % \changed{1.4k} % Moved from \xintfracnameimp to \xintexprnameimp. +% \changed{1.4l} +% \lverb|& +% Renamed to \xint_FracToSci_x to make it private and provide in +% $xintfracnameimp another \xintFracToSci with same output but which behaves +% like other macros there: f-expandable and accepting the whole range of +% inputs accepted by the xintfrac public macros. +% +% The private x-expandable macro here will have an empty output for an empty +% input but is never used for an empty input (see \xintexprEmptyItem). +% | % \begin{macrocode} -\def\xintFracToSci #1{\expandafter\XINT_FracToSci\romannumeral`&&@#1/\W[\R}% -\def\XINT_FracToSci #1/#2#3[#4% -{% - \xint_gob_til_W #2\XINT_FracToSci_noslash\W - \xint_gob_til_R #4\XINT_FracToSci_slash_noN\R - \XINT_FracToSci_slash_N #1/#2#3[#4% -}% -\def\XINT_FracToSci_noslash#1\XINT_FracToSci_slash_N #2[#3% -{% - \xint_gob_til_R #3\XINT_FracToSci_noslash_noN\R - \XINT_FracToSci_noslash_N #2[#3% -}% -\def\XINT_FracToSci_noslash_noN\R\XINT_FracToSci_noslash_N #1/\W[\R{#1}% -\def\XINT_FracToSci_noslash_N #1[#2]/\W[\R% -{% - \ifnum#2=\xint_c_ #1\else - \romannumeral0\expandafter\XINT_pfloat_keeptrimmed_fork\romannumeral0\xintrez{#1[#2]}% - \fi -}% -\def\XINT_FracToSci_slash_noN\R\XINT_FracToSci_slash_N #1#2/#3/\W[\R% -{% - #1\xint_gob_til_zero#1\expandafter\iffalse\xint_gobble_ii0\iftrue - #2\if\XINT_isOne{#3}1\else/#3\fi\fi -}% -\def\XINT_FracToSci_slash_N #1#2/#3[#4]/\W[\R% -{% - \ifnum#4=\xint_c_ #1#2\else - \romannumeral0\expandafter\XINT_pfloat_keeptrimmed_fork\romannumeral0\xintrez{#1#2[#4]}% - \fi - \if\XINT_isOne{#3}1\else\if#10\else/#3\fi\fi -}% -\let\xintexprPrintOne\xintFracToSci -% \end{macrocode} -% \subsubsection{\csh{xintFracToDecimal}} -% \added{1.4k} -% \begin{macrocode} -\def\xintFracToDecimal #1{\expandafter\XINT_FracToDecimal\romannumeral`&&@#1/\W[\R}% -\def\XINT_FracToDecimal #1/#2#3[#4% +\def\xint_FracToSci_x #1{\expandafter\XINT_FracToSci_x\romannumeral`&&@#1/\W[\R}% +\def\XINT_FracToSci_x #1/#2#3[#4% {% - \xint_gob_til_W #2\XINT_FracToDecimal_noslash\W - \xint_gob_til_R #4\XINT_FracToDecimal_slash_noN\R - \XINT_FracToDecimal_slash_N #1/#2#3[#4% + \xint_gob_til_W #2\XINT_FracToSci_x_noslash\W + \xint_gob_til_R #4\XINT_FracToSci_x_slash_noN\R + \XINT_FracToSci_x_slash_N #1/#2#3[#4% }% -\def\XINT_FracToDecimal_noslash#1\XINT_FracToDecimal_slash_N #2[#3% +\def\XINT_FracToSci_x_noslash#1\XINT_FracToSci_x_slash_N #2[#3% {% - \xint_gob_til_R #3\XINT_FracToDecimal_noslash_noN\R - \XINT_FracToDecimal_noslash_N #2[#3% + \xint_gob_til_R #3\XINT_FracToSci_x_noslash_noN\R + \XINT_FracToSci_x_noslash_N #2[#3% }% -\def\XINT_FracToDecimal_noslash_noN\R\XINT_FracToDecimal_noslash_N #1/\W[\R{#1}% -\def\XINT_FracToDecimal_noslash_N #1[#2]/\W[\R% +\def\XINT_FracToSci_x_noslash_noN\R\XINT_FracToSci_x_noslash_N #1/\W[\R{#1}% +\def\XINT_FracToSci_x_noslash_N #1[#2]/\W[\R% {% \ifnum#2=\xint_c_ #1\else - \romannumeral0\expandafter\XINT_dectostr\romannumeral0\xintrez{#1[#2]}% + \romannumeral0\expandafter\XINT_pfloat_a_fork\romannumeral0\xintrez{#1[#2]}% \fi }% -\def\XINT_FracToDecimal_slash_noN\R\XINT_FracToDecimal_slash_N #1#2/#3/\W[\R% +\def\XINT_FracToSci_x_slash_noN\R\XINT_FracToSci_x_slash_N #1#2/#3/\W[\R% {% #1\xint_gob_til_zero#1\expandafter\iffalse\xint_gobble_ii0\iftrue #2\if\XINT_isOne{#3}1\else/#3\fi\fi }% -\def\XINT_FracToDecimal_slash_N #1#2/#3[#4]/\W[\R% +\def\XINT_FracToSci_x_slash_N #1#2/#3[#4]/\W[\R% {% \ifnum#4=\xint_c_ #1#2\else - \romannumeral0\expandafter\XINT_dectostr\romannumeral0\xintrez{#1#2[#4]}% + \romannumeral0\expandafter\XINT_pfloat_a_fork\romannumeral0\xintrez{#1#2[#4]}% \fi \if\XINT_isOne{#3}1\else\if#10\else/#3\fi\fi }% +\let\xintexprPrintOne\xint_FracToSci_x % \end{macrocode} % \subsubsection{Small bits we have to put somewhere} % \lverb|& @@ -45144,12 +45832,35 @@ on input line \noexpand\the\inputlineno.&&J}}#2% }% \let\XINT_tmpa\undefined \let\XINT_tmpb\undefined \let\XINT_tmpc\undefined \let\XINT_tmpd\undefined \let\XINT_tmpe\undefined -\ifdefined\RequirePackage\expandafter\xint_firstoftwo\else\expandafter\xint_secondoftwo\fi -{\RequirePackage{xinttrig}% -\RequirePackage{xintlog}}% -{\input xinttrig.sty -\input xintlog.sty -}% +% \end{macrocode} +%\lverb|1.4l makes \usepackage{xintlog} with no prior \usepackage{xintexpr} +% not abort but attempt to do the right thing. We have to work-around the +% fact that LaTeX will ignore a \usepackage here. Simpler for non-LaTeX. +% +% In all cases, notice that the input of xintlog.sty and xinttrig.sty is done +% with xintexpr catcodes in place. And xintlog will sanitize catcodes at time +% of loading poormanlog. Attention also to not mix-up things at time of +% restoring catcodes. This is reason why xintlog.sty and xinttrig.sty have +% their own endinput wrappers. And that the rescue attempt of loading +% xintexpr (which will load xintlog) from xintlog itself is done carefully. +% +% | +% \begin{macrocode} +\ifdefined\RequirePackage + \ifcsname ver@xinttrig.sty\endcsname + \@@input xinttrig.sty\relax + \else + \RequirePackage{xinttrig}% + \fi + \ifcsname ver@xintlog.sty\endcsname + \@@input xintlog.sty\relax + \else + \RequirePackage{xintlog}% + \fi +\else + \input xinttrig.sty + \input xintlog.sty +\fi \XINTrestorecatcodesendinput% % \end{macrocode} % \StoreCodelineNo {xintexpr} @@ -45241,6 +45952,17 @@ on input line \noexpand\the\inputlineno.&&J}}#2% % 2021 standards (not a period of enlightenment generally speaking, though). % % \subsection{Catcodes, \protect\eTeX{} and reload detection} +% \changed{1.4l} +% \lverb|Silly paranoid modification of \z in case { and } do not have their +% normal catcodes when xinttrig.sty is reloaded (initial loading via +% xintexpr.sty does not need this), to define \XINTtrigendinput there and not +% after the \endgroup from \z has already restored possibly bad catcodes. +% +% 1.4l handles much better the situation with \usepackage{xinttrig} without +% previous loading of xintexpr (or same with \input and etex). cf comments in +% xintlog.sty. +% +%| % \begin{macrocode} \begingroup\catcode61\catcode48\catcode32=10\relax% \catcode13=5 % ^^M @@ -45250,35 +45972,49 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \catcode64=11 % @ \catcode35=6 % # \catcode44=12 % , - \catcode45=12 % - \catcode46=12 % . \catcode58=12 % : \catcode94=7 % ^ - \def\z{\endgroup}% \def\empty{}\def\space{ }\newlinechar10 + \def\z{\endgroup}% + \expandafter\let\expandafter\x\csname ver@xinttrig.sty\endcsname \expandafter\let\expandafter\w\csname ver@xintexpr.sty\endcsname \expandafter - \ifx\csname PackageInfo\endcsname\relax - \def\y#1#2{\immediate\write-1{Package #1 Info:^^J% - \space\space\space\space#2.}}% + \ifx\csname PackageWarning\endcsname\relax + \def\y#1#2{\immediate\write128{^^JPackage #1 Warning:^^J% + \space\space\space\space#2.^^J}}% \else - \def\y#1#2{\PackageInfo{#1}{#2}}% + \def\y#1#2{\PackageWarningNoLine{#1}{#2}}% \fi \expandafter \ifx\csname numexpr\endcsname\relax \y{xinttrig}{\numexpr not available, aborting input}% - \aftergroup\endinput + \def\z{\endgroup\endinput}% \else \ifx\w\relax % xintexpr.sty not yet loaded. + \edef\MsgBrk{^^J\space\space\space\space}% \y{xinttrig}% - {Loading should be via \ifx\x\empty\string\usepackage{xintexpr.sty} - \else\string\input\space xintexpr.sty \fi - rather, aborting}% - \aftergroup\endinput + {\ifx\x\empty + xinttrig should not be loaded directly\MessageBreak + The correct way is \string\usepackage{xintexpr}.\MessageBreak + Will try that now% + \else + First loading of xinttrig.sty should be via + \string\input\space xintexpr.sty\relax\MsgBrk + Will try that now% + \fi + }% + \ifx\x\empty + \def\z{\endgroup\RequirePackage{xintexpr}\endinput}% + \else + \def\z{\endgroup\input xintexpr.sty\relax\endinput}% + \fi + \else + \def\z{\endgroup\edef\XINTtrigendinput{\XINTrestorecatcodes\noexpand\endinput}}% \fi \fi \z% -\edef\XINTtrigendinput{\XINTrestorecatcodes\noexpand\endinput}\XINTsetcatcodes% +\XINTsetcatcodes% \catcode`? 12 % \end{macrocode} % \subsection{Library identification} @@ -45288,11 +46024,11 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \else \expandafter\xint_secondoftwo \fi -{\immediate\write-1{Reloading xinttrig library using Digits=\xinttheDigits.}}% -{\expandafter\gdef\csname xintlibver@trig\endcsname{2022/05/18 v1.4k}% +{\immediate\write128{Reloading xinttrig library using Digits=\xinttheDigits.}}% +{\expandafter\gdef\csname xintlibver@trig\endcsname{2022/05/29 v1.4l}% \XINT_providespackage \ProvidesPackage{xinttrig}% -[2022/05/18 v1.4k Trigonometrical functions for xintexpr (JFB)]% +[2022/05/29 v1.4l Trigonometrical functions for xintexpr (JFB)]% }% % \end{macrocode} % \subsection{Ensure used letters are dummy letters} @@ -46562,6 +47298,21 @@ on input line \noexpand\the\inputlineno.&&J}}#2% % % % \subsection{Catcodes, \protect\eTeX{} and reload detection} +% \changed{1.4l} +% \lverb|Silly paranoid modification of \z in case { and } do not have their +% normal catcodes when xintlog.sty is reloaded (initial loading via +% xintexpr.sty does not need this), to define \XINTlogendinput there and not +% after the \endgroup from \z has already restored possibly bad catcodes. +% +% +% 1.4l handles much better the situation with \usepackage{xintlog} without +% previous loading of xintexpr (or same with \input and etex). Instead of +% aborting with a message (which actually was wrong with LaTeX since 1.4e, +% mentioning \input in place of \usepackage), it will initiate loading +% xintexpr itself. This required an adaptation at end of xintexpr and some +% care to not leave bad catcodes. +% +% | % \begin{macrocode} \begingroup\catcode61\catcode48\catcode32=10\relax% \catcode13=5 % ^^M @@ -46571,48 +47322,76 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \catcode64=11 % @ \catcode35=6 % # \catcode44=12 % , - \catcode45=12 % - \catcode46=12 % . \catcode58=12 % : \catcode94=7 % ^ - \def\z{\endgroup}% \def\empty{}\def\space{ }\newlinechar10 + \def\z{\endgroup}% + \expandafter\let\expandafter\x\csname ver@xintlog.sty\endcsname \expandafter\let\expandafter\w\csname ver@xintexpr.sty\endcsname \expandafter - \ifx\csname PackageInfo\endcsname\relax - \def\y#1#2{\immediate\write-1{Package #1 Info:^^J% - \space\space\space\space#2.}}% + \ifx\csname PackageWarning\endcsname\relax + \def\y#1#2{\immediate\write128{^^JPackage #1 Warning:^^J% + \space\space\space\space#2.^^J}}% \else - \def\y#1#2{\PackageInfo{#1}{#2}}% + \def\y#1#2{\PackageWarningNoLine{#1}{#2}}% \fi \expandafter \ifx\csname numexpr\endcsname\relax \y{xintlog}{\numexpr not available, aborting input}% - \aftergroup\endinput + \def\z{\endgroup\endinput}% \else \ifx\w\relax % xintexpr.sty not yet loaded. + \edef\MsgBrk{^^J\space\space\space\space}% \y{xintlog}% - {Loading should be via \ifx\x\empty\string\usepackage{xintexpr.sty} - \else\string\input\space xintexpr.sty \fi - rather, aborting}% - \aftergroup\endinput + {\ifx\x\empty + xintlog should not be loaded directly\MessageBreak + The correct way is \string\usepackage{xintexpr}.\MessageBreak + Will try that now% + \else + First loading of xintlog.sty should be via + \string\input\space xintexpr.sty\relax\MsgBrk + Will try that now% + \fi + }% + \ifx\x\empty + \def\z{\endgroup\RequirePackage{xintexpr}\endinput}% + \else + \def\z{\endgroup\input xintexpr.sty\relax\endinput}% + \fi + \else + \def\z{\endgroup\edef\XINTlogendinput{\XINTrestorecatcodes\noexpand\endinput}}% \fi \fi \z% -\edef\XINTendxintloginput{\XINTrestorecatcodes\noexpand\endinput}\XINTsetcatcodes% +% \end{macrocode} +% \lverb|Here we set catcodes to the package values, the current settings +% having been saved in the \XINTlogendinput macro. We arrive here only if +% xintlog is either loaded from xintexpr or is being reloaded via an \input +% from \xintreloadxintlog. Else we aborted right before via \endinput and do +% not modify catcodes. As xintexpr inputs xintlog.sty at a time the catcode +% configuration is already the package one we pay attention to not use +% \XINTsetupcatcodes which would badly redefine \XINTrestorecatcodesendinput +% as executed at end of xintexpr.sty. There is slight inefficiency here to +% execute \XINTsetcatcodes when xintexpr initiated the xintlog loading, but +% let's live with it.| +% \begin{macrocode} +\XINTsetcatcodes% % \end{macrocode} % \subsection{Library identification} +% \changed{1.4l} +% \lverb|Reloading message also to Terminal not only log file.| % \begin{macrocode} \ifcsname xintlibver@log\endcsname \expandafter\xint_firstoftwo \else \expandafter\xint_secondoftwo \fi -{\immediate\write-1{Reloading xintlog library using Digits=\xinttheDigits.}}% -{\expandafter\gdef\csname xintlibver@log\endcsname{2022/05/18 v1.4k}% +{\immediate\write128{Reloading xintlog library using Digits=\xinttheDigits.}}% +{\expandafter\gdef\csname xintlibver@log\endcsname{2022/05/29 v1.4l}% \XINT_providespackage \ProvidesPackage{xintlog}% -[2022/05/18 v1.4k Logarithms and exponentials for xintexpr (JFB)]% +[2022/05/29 v1.4l Logarithms and exponentials for xintexpr (JFB)]% }% % \end{macrocode} % \subsection{\csh{xintreloadxintlog}} @@ -46626,23 +47405,20 @@ on input line \noexpand\the\inputlineno.&&J}}#2% % \lverb|& % Attention to the catcode regime when loading poormanlog. % -% As I learned the hard way (I never use my user macros), at the worst moment -% when wrapping up the final things for 1.3e release, -% \xintexprSafeCatcodes MUST be followed by some \xintexprRestoreCatcodes -% quickly, else next time it is used (for example by \xintdefvar) the -% \xintexprRestoreCatcodes will restore an obsolete catcode regime... % % Also, for xintlog.sty to be multiple-times loadable, we need to avoid using -% LaTeX's \RequirePackage twice.| +% LaTeX's \RequirePackage twice. +% +%| % \begin{macrocode} -\xintexprSafeCatcodes\catcode`_ 11 +\xintexprSafeCatcodes \unless\ifdefined\XINTinFloatPowTen \ifdefined\RequirePackage \RequirePackage{poormanlog}% \else \input poormanlog.tex \fi\fi -\xintexprRestoreCatcodes\XINTsetcatcodes +\xintexprRestoreCatcodes % \end{macrocode} % \subsection{Macro layer on top of the poormanlog package} % \lverb|This was moved here with some macro renames from xintfrac on occasion @@ -47176,7 +47952,7 @@ on input line \noexpand\the\inputlineno.&&J}}#2% % \end{macrocode} % \subsection{End of package loading for low Digits} % \begin{macrocode} -\ifnum\XINTdigits<9 \expandafter\XINTendxintloginput\fi% +\ifnum\XINTdigits<9 \expandafter\XINTlogendinput\fi% % \end{macrocode} % \subsection{Stored constants} % \lverb|The constants were obtained from Maple at 80 digits: fractional power @@ -48635,7 +49411,7 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \XINTinFloat[\XINTdigitsormax-43]{1/9[0]}.% }% \fi -\XINTendxintloginput% +\XINTlogendinput% % \end{macrocode} % \StoreCodelineNo {xintlog} % \cleardoublepage\let\xintlognameUp\undefined @@ -48648,7 +49424,7 @@ xint.sty:205 xintbinhex.sty:53 xintcfrac.sty:183 xintcore.sty:272 -xintexpr.sty:465 +xintexpr.sty:461 xintfrac.sty:522 xintgcd.sty:41 xintkernel.sty:17 @@ -48658,15 +49434,15 @@ xinttools.sty:157 xinttrig.sty:65 \fi % grep -o "^{%" xint*sty | wc -l -\def\totala{ 2178} +\def\totala{ 2174} \iffalse % grep -c -e "^}%" xint*sty xint.sty:204 xintbinhex.sty:52 xintcfrac.sty:183 xintcore.sty:269 -xintexpr.sty:448 -xintfrac.sty:527 +xintexpr.sty:442 +xintfrac.sty:528 xintgcd.sty:43 xintkernel.sty:17 xintlog.sty:151 @@ -48675,7 +49451,7 @@ xinttools.sty:156 xinttrig.sty:64 \fi % grep -o "^}%" xint*sty | wc -l -\def\totalb{ 2162} +\def\totalb{ 2157} \cleardoublepage \section{Cumulative line count} @@ -48699,8 +49475,8 @@ xinttrig.sty:64 \TeX\strut. Version {\xintbndlversion} of {\xintbndldate}.\par } -\CheckSum {38925}% 1.4j -% 38590 pour 1.4j, 38591 pour 1.4i, 38427 pour 1.4h +\CheckSum {39032}% 1.4l +% 38925 pour 1.4j, 38590 pour 1.4j, 38591 pour 1.4i, 38427 pour 1.4h % 38423 pour 1.4g, 38212 pour 1.4f, 38813 pour 1.4e, 35184 pour 1.4d % 35109 pour 1.4c, 35103 pour 1.4b, 34648 pour 1.4a, 34575 pour 1.4 % 33497 pour 1.3f, 33274 pour 1.3e, 31601 pour 1.3d, 31122 pour 1.3c diff --git a/Master/texmf-dist/tex/generic/xint/xint.sty b/Master/texmf-dist/tex/generic/xint/xint.sty index 800b3fbf5c8..3614cc5a8a3 100644 --- a/Master/texmf-dist/tex/generic/xint/xint.sty +++ b/Master/texmf-dist/tex/generic/xint/xint.sty @@ -21,7 +21,7 @@ %% same distribution. (The sources need not necessarily be %% in the same archive or directory.) %% --------------------------------------------------------------- -%% The xint bundle 1.4k 2022/05/18 +%% The xint bundle 1.4l 2022/05/29 %% Copyright (C) 2013-2022 by Jean-Francois Burnol %% xint: Expandable operations on big integers %% --------------------------------------------------------------- @@ -31,38 +31,36 @@ \catcode123=1 % { \catcode125=2 % } \catcode64=11 % @ - \catcode35=6 % # \catcode44=12 % , - \catcode45=12 % - \catcode46=12 % . \catcode58=12 % : - \let\z\endgroup + \catcode94=7 % ^ + \def\empty{}\def\space{ }\newlinechar10 + \def\z{\endgroup}% \expandafter\let\expandafter\x\csname ver@xint.sty\endcsname \expandafter\let\expandafter\w\csname ver@xintcore.sty\endcsname - \expandafter - \ifx\csname PackageInfo\endcsname\relax - \def\y#1#2{\immediate\write-1{Package #1 Info: #2.}}% + \expandafter\ifx\csname numexpr\endcsname\relax + \expandafter\ifx\csname PackageWarning\endcsname\relax + \immediate\write128{^^JPackage xint Warning:^^J% + \space\space\space\space + \numexpr not available, aborting input.^^J}% \else - \def\y#1#2{\PackageInfo{#1}{#2}}% + \PackageWarningNoLine{xint}{\numexpr not available, aborting input}% \fi - \expandafter - \ifx\csname numexpr\endcsname\relax - \y{xint}{\numexpr not available, aborting input}% - \aftergroup\endinput + \def\z{\endgroup\endinput}% \else \ifx\x\relax % plain-TeX, first loading of xintcore.sty \ifx\w\relax % but xintkernel.sty not yet loaded. \def\z{\endgroup\input xintcore.sty\relax}% \fi \else - \def\empty {}% \ifx\x\empty % LaTeX, first loading, % variable is initialized, but \ProvidesPackage not yet seen \ifx\w\relax % xintcore.sty not yet loaded. \def\z{\endgroup\RequirePackage{xintcore}}% \fi \else - \aftergroup\endinput % xint already loaded. + \def\z{\endgroup\endinput}% xint already loaded. \fi \fi \fi @@ -70,7 +68,7 @@ \XINTsetupcatcodes% defined in xintkernel.sty (loaded by xintcore.sty) \XINT_providespackage \ProvidesPackage{xint}% - [2022/05/18 v1.4k Expandable operations on big integers (JFB)]% + [2022/05/29 v1.4l Expandable operations on big integers (JFB)]% \long\def\xint_firstofthree #1#2#3{#1}% \long\def\xint_secondofthree #1#2#3{#2}% \long\def\xint_thirdofthree #1#2#3{#3}% diff --git a/Master/texmf-dist/tex/generic/xint/xintbinhex.sty b/Master/texmf-dist/tex/generic/xint/xintbinhex.sty index 243b7c325aa..7c6b6131a21 100644 --- a/Master/texmf-dist/tex/generic/xint/xintbinhex.sty +++ b/Master/texmf-dist/tex/generic/xint/xintbinhex.sty @@ -21,7 +21,7 @@ %% same distribution. (The sources need not necessarily be %% in the same archive or directory.) %% --------------------------------------------------------------- -%% The xint bundle 1.4k 2022/05/18 +%% The xint bundle 1.4l 2022/05/29 %% Copyright (C) 2013-2022 by Jean-Francois Burnol %% xintbinhex: Expandable binary and hexadecimal conversions %% --------------------------------------------------------------- @@ -31,38 +31,36 @@ \catcode123=1 % { \catcode125=2 % } \catcode64=11 % @ - \catcode35=6 % # \catcode44=12 % , - \catcode45=12 % - \catcode46=12 % . \catcode58=12 % : - \let\z\endgroup + \catcode94=7 % ^ + \def\empty{}\def\space{ }\newlinechar10 + \def\z{\endgroup}% \expandafter\let\expandafter\x\csname ver@xintbinhex.sty\endcsname \expandafter\let\expandafter\w\csname ver@xintkernel.sty\endcsname - \expandafter - \ifx\csname PackageInfo\endcsname\relax - \def\y#1#2{\immediate\write-1{Package #1 Info: #2.}}% + \expandafter\ifx\csname numexpr\endcsname\relax + \expandafter\ifx\csname PackageWarning\endcsname\relax + \immediate\write128{^^JPackage xintbinhex Warning:^^J% + \space\space\space\space + \numexpr not available, aborting input.^^J}% \else - \def\y#1#2{\PackageInfo{#1}{#2}}% + \PackageWarningNoLine{xintbinhex}{\numexpr not available, aborting input}% \fi - \expandafter - \ifx\csname numexpr\endcsname\relax - \y{xintbinhex}{\numexpr not available, aborting input}% - \aftergroup\endinput + \def\z{\endgroup\endinput}% \else \ifx\x\relax % plain-TeX, first loading of xintbinhex.sty \ifx\w\relax % but xintkernel.sty not yet loaded. \def\z{\endgroup\input xintkernel.sty\relax}% \fi \else - \def\empty {}% \ifx\x\empty % LaTeX, first loading, % variable is initialized, but \ProvidesPackage not yet seen \ifx\w\relax % xintkernel.sty not yet loaded. \def\z{\endgroup\RequirePackage{xintkernel}}% \fi \else - \aftergroup\endinput % xintbinhex already loaded. + \def\z{\endgroup\endinput}% xintbinhex already loaded. \fi \fi \fi @@ -70,7 +68,7 @@ \XINTsetupcatcodes% defined in xintkernel.sty \XINT_providespackage \ProvidesPackage{xintbinhex}% - [2022/05/18 v1.4k Expandable binary and hexadecimal conversions (JFB)]% + [2022/05/29 v1.4l Expandable binary and hexadecimal conversions (JFB)]% \newcount\xint_c_ii^xv \xint_c_ii^xv 32768 \newcount\xint_c_ii^xvi \xint_c_ii^xvi 65536 \def\XINT_tmpa #1{\ifx\relax#1\else diff --git a/Master/texmf-dist/tex/generic/xint/xintcfrac.sty b/Master/texmf-dist/tex/generic/xint/xintcfrac.sty index e538575f50f..e278c56effb 100644 --- a/Master/texmf-dist/tex/generic/xint/xintcfrac.sty +++ b/Master/texmf-dist/tex/generic/xint/xintcfrac.sty @@ -21,7 +21,7 @@ %% same distribution. (The sources need not necessarily be %% in the same archive or directory.) %% --------------------------------------------------------------- -%% The xint bundle 1.4k 2022/05/18 +%% The xint bundle 1.4l 2022/05/29 %% Copyright (C) 2013-2022 by Jean-Francois Burnol %% xintcfrac: Expandable continued fractions with xint package %% --------------------------------------------------------------- @@ -31,38 +31,36 @@ \catcode123=1 % { \catcode125=2 % } \catcode64=11 % @ - \catcode35=6 % # \catcode44=12 % , - \catcode45=12 % - \catcode46=12 % . \catcode58=12 % : - \let\z\endgroup + \catcode94=7 % ^ + \def\empty{}\def\space{ }\newlinechar10 + \def\z{\endgroup}% \expandafter\let\expandafter\x\csname ver@xintcfrac.sty\endcsname \expandafter\let\expandafter\w\csname ver@xintfrac.sty\endcsname - \expandafter - \ifx\csname PackageInfo\endcsname\relax - \def\y#1#2{\immediate\write-1{Package #1 Info: #2.}}% + \expandafter\ifx\csname numexpr\endcsname\relax + \expandafter\ifx\csname PackageWarning\endcsname\relax + \immediate\write128{^^JPackage xintcfrac Warning:^^J% + \space\space\space\space + \numexpr not available, aborting input.^^J}% \else - \def\y#1#2{\PackageInfo{#1}{#2}}% + \PackageWarningNoLine{xintcfrac}{\numexpr not available, aborting input}% \fi - \expandafter - \ifx\csname numexpr\endcsname\relax - \y{xintcfrac}{\numexpr not available, aborting input}% - \aftergroup\endinput + \def\z{\endgroup\endinput}% \else \ifx\x\relax % plain-TeX, first loading of xintcfrac.sty \ifx\w\relax % but xintfrac.sty not yet loaded. \def\z{\endgroup\input xintfrac.sty\relax}% \fi \else - \def\empty {}% \ifx\x\empty % LaTeX, first loading, % variable is initialized, but \ProvidesPackage not yet seen \ifx\w\relax % xintfrac.sty not yet loaded. \def\z{\endgroup\RequirePackage{xintfrac}}% \fi \else - \aftergroup\endinput % xintcfrac already loaded. + \def\z{\endgroup\endinput}% xintcfrac already loaded. \fi \fi \fi @@ -70,7 +68,7 @@ \XINTsetupcatcodes% defined in xintkernel.sty \XINT_providespackage \ProvidesPackage{xintcfrac}% - [2022/05/18 v1.4k Expandable continued fractions with xint package (JFB)]% + [2022/05/29 v1.4l Expandable continued fractions with xint package (JFB)]% \def\xintCFrac {\romannumeral0\xintcfrac }% \def\xintcfrac #1% {% diff --git a/Master/texmf-dist/tex/generic/xint/xintcore.sty b/Master/texmf-dist/tex/generic/xint/xintcore.sty index a11d046dec7..91702aed00a 100644 --- a/Master/texmf-dist/tex/generic/xint/xintcore.sty +++ b/Master/texmf-dist/tex/generic/xint/xintcore.sty @@ -21,7 +21,7 @@ %% same distribution. (The sources need not necessarily be %% in the same archive or directory.) %% --------------------------------------------------------------- -%% The xint bundle 1.4k 2022/05/18 +%% The xint bundle 1.4l 2022/05/29 %% Copyright (C) 2013-2022 by Jean-Francois Burnol %% xintcore: Expandable arithmetic on big integers %% --------------------------------------------------------------- @@ -31,38 +31,36 @@ \catcode123=1 % { \catcode125=2 % } \catcode64=11 % @ - \catcode35=6 % # \catcode44=12 % , - \catcode45=12 % - \catcode46=12 % . \catcode58=12 % : - \let\z\endgroup + \catcode94=7 % ^ + \def\empty{}\def\space{ }\newlinechar10 + \def\z{\endgroup}% \expandafter\let\expandafter\x\csname ver@xintcore.sty\endcsname \expandafter\let\expandafter\w\csname ver@xintkernel.sty\endcsname - \expandafter - \ifx\csname PackageInfo\endcsname\relax - \def\y#1#2{\immediate\write-1{Package #1 Info: #2.}}% + \expandafter\ifx\csname numexpr\endcsname\relax + \expandafter\ifx\csname PackageWarning\endcsname\relax + \immediate\write128{^^JPackage xintcore Warning:^^J% + \space\space\space\space + \numexpr not available, aborting input.^^J}% \else - \def\y#1#2{\PackageInfo{#1}{#2}}% + \PackageWarningNoLine{xintcore}{\numexpr not available, aborting input}% \fi - \expandafter - \ifx\csname numexpr\endcsname\relax - \y{xintcore}{\numexpr not available, aborting input}% - \aftergroup\endinput + \def\z{\endgroup\endinput}% \else \ifx\x\relax % plain-TeX, first loading of xintcore.sty \ifx\w\relax % but xintkernel.sty not yet loaded. \def\z{\endgroup\input xintkernel.sty\relax}% \fi \else - \def\empty {}% \ifx\x\empty % LaTeX, first loading, % variable is initialized, but \ProvidesPackage not yet seen \ifx\w\relax % xintkernel.sty not yet loaded. \def\z{\endgroup\RequirePackage{xintkernel}}% \fi \else - \aftergroup\endinput % xintkernel already loaded. + \def\z{\endgroup\endinput}% xintkernel already loaded. \fi \fi \fi @@ -70,7 +68,7 @@ \XINTsetupcatcodes% defined in xintkernel.sty \XINT_providespackage \ProvidesPackage{xintcore}% - [2022/05/18 v1.4k Expandable arithmetic on big integers (JFB)]% + [2022/05/29 v1.4l Expandable arithmetic on big integers (JFB)]% \csname XINT_Clamped_istrapped\endcsname \csname XINT_ConversionSyntax_istrapped\endcsname \csname XINT_DivisionByZero_istrapped\endcsname diff --git a/Master/texmf-dist/tex/generic/xint/xintexpr.sty b/Master/texmf-dist/tex/generic/xint/xintexpr.sty index 84db61a81a1..d1862e9130f 100644 --- a/Master/texmf-dist/tex/generic/xint/xintexpr.sty +++ b/Master/texmf-dist/tex/generic/xint/xintexpr.sty @@ -21,7 +21,7 @@ %% same distribution. (The sources need not necessarily be %% in the same archive or directory.) %% --------------------------------------------------------------- -%% The xint bundle 1.4k 2022/05/18 +%% The xint bundle 1.4l 2022/05/29 %% Copyright (C) 2013-2022 by Jean-Francois Burnol %% xintexpr: Expandable expression parser %% --------------------------------------------------------------- @@ -31,26 +31,25 @@ \catcode123=1 % { \catcode125=2 % } \catcode64=11 % @ - \catcode35=6 % # \catcode44=12 % , - \catcode45=12 % - \catcode46=12 % . \catcode58=12 % : - \def\z {\endgroup}% + \catcode94=7 % ^ + \def\empty{}\def\space{ }\newlinechar10 + \def\z{\endgroup}% \expandafter\let\expandafter\x\csname ver@xintexpr.sty\endcsname \expandafter\let\expandafter\w\csname ver@xintfrac.sty\endcsname \expandafter\let\expandafter\t\csname ver@xinttools.sty\endcsname - \expandafter - \ifx\csname PackageInfo\endcsname\relax - \def\y#1#2{\immediate\write-1{Package #1 Info: #2.}}% + % I don't think engine exists providing \expanded but not \numexpr + \expandafter\ifx\csname expanded\endcsname\relax + \expandafter\ifx\csname PackageWarning\endcsname\relax + \immediate\write128{^^JPackage xintexpr Warning:^^J% + \space\space\space\space + \expanded not available, aborting input.^^J}% \else - \def\y#1#2{\PackageInfo{#1}{#2}}% + \PackageWarningNoLine{xintexpr}{\expanded not available, aborting input}% \fi - \expandafter - % I don't think engine exists providing \expanded but not \numexpr - \ifx\csname expanded\endcsname\relax - \y{xintexpr}{\expanded not available, aborting input}% - \aftergroup\endinput + \def\z{\endgroup\endinput}% \else \ifx\x\relax % plain-TeX, first loading of xintexpr.sty \ifx\w\relax % but xintfrac.sty not yet loaded. @@ -62,7 +61,6 @@ {\z\input xinttools.sty\relax}% \fi \else - \def\empty {}% \ifx\x\empty % LaTeX, first loading, % variable is initialized, but \ProvidesPackage not yet seen \ifx\w\relax % xintfrac.sty not yet loaded. @@ -74,7 +72,7 @@ {\z\RequirePackage{xinttools}}% \fi \else - \aftergroup\endinput % xintexpr already loaded. + \def\z{\endgroup\endinput}% xintexpr already loaded. \fi \fi \fi @@ -82,7 +80,7 @@ \XINTsetupcatcodes% \XINT_providespackage \ProvidesPackage{xintexpr}% - [2022/05/18 v1.4k Expandable expression parser (JFB)]% + [2022/05/29 v1.4l Expandable expression parser (JFB)]% \catcode`! 11 \let\XINT_Cmp \xintiiCmp \def\XINTfstop{\noexpand\XINTfstop}% @@ -125,10 +123,12 @@ <% pol([\XINT:expr:toblist_b #1!#3}^])\XINT:expr:toblist_c #1!}% >% -\def\XINT:expr:toblist_b #1!#2}% -<% - \if\relax#2\relax\xintexprEmptyItem\else#1<#2>\fi\XINT:expr:toblist_c #1!}% ->% +\catcode`{ 1 \catcode`} 2 +\def\XINT:expr:toblist_b #1{% +\def\XINT:expr:toblist_b ##1!##2#1% +{% + \if\relax##2\relax\xintexprEmptyItem\else##1{##2}\fi\XINT:expr:toblist_c ##1!#1% +}}\catcode`{ 12 \catcode`} 12 \XINT:expr:toblist_b<}>% \def\XINT:expr:toblist_c #1}#2% <% \if ^#2\xint_dothis<\xint_gob_til_^>\fi @@ -224,7 +224,7 @@ \if ^#2\expandafter\xint_gob_til_^\else\expandafter\XINT:expr:mapwithin_a\fi #1!#2% }% -\begingroup % should I check lccode s generally if corrupted context at load? +\begingroup \catcode`[ 1 \catcode`] 2 \lccode`[`{ \lccode`]`} \catcode`< 1 \catcode`> 2 \catcode`{ 12 \catcode`} 12 \lowercase<\endgroup @@ -412,69 +412,38 @@ \def\xintifsgnexpr #1{\romannumeral0\xintiiifsgn {\xinttheexpr #1\relax}}% \def\xintifsgnfloatexpr #1{\romannumeral0\xintiiifsgn {\xintthefloatexpr #1\relax}}% \def\xintifsgniiexpr #1{\romannumeral0\xintiiifsgn {\xinttheiiexpr #1\relax}}% -\def\xintFracToSci #1{\expandafter\XINT_FracToSci\romannumeral`&&@#1/\W[\R}% -\def\XINT_FracToSci #1/#2#3[#4% -{% - \xint_gob_til_W #2\XINT_FracToSci_noslash\W - \xint_gob_til_R #4\XINT_FracToSci_slash_noN\R - \XINT_FracToSci_slash_N #1/#2#3[#4% -}% -\def\XINT_FracToSci_noslash#1\XINT_FracToSci_slash_N #2[#3% -{% - \xint_gob_til_R #3\XINT_FracToSci_noslash_noN\R - \XINT_FracToSci_noslash_N #2[#3% -}% -\def\XINT_FracToSci_noslash_noN\R\XINT_FracToSci_noslash_N #1/\W[\R{#1}% -\def\XINT_FracToSci_noslash_N #1[#2]/\W[\R% -{% - \ifnum#2=\xint_c_ #1\else - \romannumeral0\expandafter\XINT_pfloat_keeptrimmed_fork\romannumeral0\xintrez{#1[#2]}% - \fi -}% -\def\XINT_FracToSci_slash_noN\R\XINT_FracToSci_slash_N #1#2/#3/\W[\R% -{% - #1\xint_gob_til_zero#1\expandafter\iffalse\xint_gobble_ii0\iftrue - #2\if\XINT_isOne{#3}1\else/#3\fi\fi -}% -\def\XINT_FracToSci_slash_N #1#2/#3[#4]/\W[\R% +\def\xint_FracToSci_x #1{\expandafter\XINT_FracToSci_x\romannumeral`&&@#1/\W[\R}% +\def\XINT_FracToSci_x #1/#2#3[#4% {% - \ifnum#4=\xint_c_ #1#2\else - \romannumeral0\expandafter\XINT_pfloat_keeptrimmed_fork\romannumeral0\xintrez{#1#2[#4]}% - \fi - \if\XINT_isOne{#3}1\else\if#10\else/#3\fi\fi + \xint_gob_til_W #2\XINT_FracToSci_x_noslash\W + \xint_gob_til_R #4\XINT_FracToSci_x_slash_noN\R + \XINT_FracToSci_x_slash_N #1/#2#3[#4% }% -\let\xintexprPrintOne\xintFracToSci -\def\xintFracToDecimal #1{\expandafter\XINT_FracToDecimal\romannumeral`&&@#1/\W[\R}% -\def\XINT_FracToDecimal #1/#2#3[#4% +\def\XINT_FracToSci_x_noslash#1\XINT_FracToSci_x_slash_N #2[#3% {% - \xint_gob_til_W #2\XINT_FracToDecimal_noslash\W - \xint_gob_til_R #4\XINT_FracToDecimal_slash_noN\R - \XINT_FracToDecimal_slash_N #1/#2#3[#4% + \xint_gob_til_R #3\XINT_FracToSci_x_noslash_noN\R + \XINT_FracToSci_x_noslash_N #2[#3% }% -\def\XINT_FracToDecimal_noslash#1\XINT_FracToDecimal_slash_N #2[#3% -{% - \xint_gob_til_R #3\XINT_FracToDecimal_noslash_noN\R - \XINT_FracToDecimal_noslash_N #2[#3% -}% -\def\XINT_FracToDecimal_noslash_noN\R\XINT_FracToDecimal_noslash_N #1/\W[\R{#1}% -\def\XINT_FracToDecimal_noslash_N #1[#2]/\W[\R% +\def\XINT_FracToSci_x_noslash_noN\R\XINT_FracToSci_x_noslash_N #1/\W[\R{#1}% +\def\XINT_FracToSci_x_noslash_N #1[#2]/\W[\R% {% \ifnum#2=\xint_c_ #1\else - \romannumeral0\expandafter\XINT_dectostr\romannumeral0\xintrez{#1[#2]}% + \romannumeral0\expandafter\XINT_pfloat_a_fork\romannumeral0\xintrez{#1[#2]}% \fi }% -\def\XINT_FracToDecimal_slash_noN\R\XINT_FracToDecimal_slash_N #1#2/#3/\W[\R% +\def\XINT_FracToSci_x_slash_noN\R\XINT_FracToSci_x_slash_N #1#2/#3/\W[\R% {% #1\xint_gob_til_zero#1\expandafter\iffalse\xint_gobble_ii0\iftrue #2\if\XINT_isOne{#3}1\else/#3\fi\fi }% -\def\XINT_FracToDecimal_slash_N #1#2/#3[#4]/\W[\R% +\def\XINT_FracToSci_x_slash_N #1#2/#3[#4]/\W[\R% {% \ifnum#4=\xint_c_ #1#2\else - \romannumeral0\expandafter\XINT_dectostr\romannumeral0\xintrez{#1#2[#4]}% + \romannumeral0\expandafter\XINT_pfloat_a_fork\romannumeral0\xintrez{#1#2[#4]}% \fi \if\XINT_isOne{#3}1\else\if#10\else/#3\fi\fi }% +\let\xintexprPrintOne\xint_FracToSci_x \def\XINT_embrace#1{{#1}}% \def\xint_gob_til_! #1!{}% ! with catcode 11 \def\xintError:noopening @@ -4579,12 +4548,21 @@ }% \let\XINT_tmpa\undefined \let\XINT_tmpb\undefined \let\XINT_tmpc\undefined \let\XINT_tmpd\undefined \let\XINT_tmpe\undefined -\ifdefined\RequirePackage\expandafter\xint_firstoftwo\else\expandafter\xint_secondoftwo\fi -{\RequirePackage{xinttrig}% -\RequirePackage{xintlog}}% -{\input xinttrig.sty -\input xintlog.sty -}% +\ifdefined\RequirePackage + \ifcsname ver@xinttrig.sty\endcsname + \@@input xinttrig.sty\relax + \else + \RequirePackage{xinttrig}% + \fi + \ifcsname ver@xintlog.sty\endcsname + \@@input xintlog.sty\relax + \else + \RequirePackage{xintlog}% + \fi +\else + \input xinttrig.sty + \input xintlog.sty +\fi \XINTrestorecatcodesendinput% \endinput %% diff --git a/Master/texmf-dist/tex/generic/xint/xintfrac.sty b/Master/texmf-dist/tex/generic/xint/xintfrac.sty index 00de2592152..d94affd6304 100644 --- a/Master/texmf-dist/tex/generic/xint/xintfrac.sty +++ b/Master/texmf-dist/tex/generic/xint/xintfrac.sty @@ -21,7 +21,7 @@ %% same distribution. (The sources need not necessarily be %% in the same archive or directory.) %% --------------------------------------------------------------- -%% The xint bundle 1.4k 2022/05/18 +%% The xint bundle 1.4l 2022/05/29 %% Copyright (C) 2013-2022 by Jean-Francois Burnol %% xintfrac: Expandable operations on fractions %% --------------------------------------------------------------- @@ -31,38 +31,36 @@ \catcode123=1 % { \catcode125=2 % } \catcode64=11 % @ - \catcode35=6 % # \catcode44=12 % , - \catcode45=12 % - \catcode46=12 % . \catcode58=12 % : - \let\z\endgroup + \catcode94=7 % ^ + \def\empty{}\def\space{ }\newlinechar10 + \def\z{\endgroup}% \expandafter\let\expandafter\x\csname ver@xintfrac.sty\endcsname \expandafter\let\expandafter\w\csname ver@xint.sty\endcsname - \expandafter - \ifx\csname PackageInfo\endcsname\relax - \def\y#1#2{\immediate\write-1{Package #1 Info: #2.}}% + \expandafter\ifx\csname numexpr\endcsname\relax + \expandafter\ifx\csname PackageWarning\endcsname\relax + \immediate\write128{^^JPackage xintfrac Warning:^^J% + \space\space\space\space + \numexpr not available, aborting input.^^J}% \else - \def\y#1#2{\PackageInfo{#1}{#2}}% + \PackageWarningNoLine{xintfrac}{\numexpr not available, aborting input}% \fi - \expandafter - \ifx\csname numexpr\endcsname\relax - \y{xintfrac}{\numexpr not available, aborting input}% - \aftergroup\endinput + \def\z{\endgroup\endinput}% \else \ifx\x\relax % plain-TeX, first loading of xintfrac.sty \ifx\w\relax % but xint.sty not yet loaded. \def\z{\endgroup\input xint.sty\relax}% \fi \else - \def\empty {}% \ifx\x\empty % LaTeX, first loading, % variable is initialized, but \ProvidesPackage not yet seen \ifx\w\relax % xint.sty not yet loaded. \def\z{\endgroup\RequirePackage{xint}}% \fi \else - \aftergroup\endinput % xintfrac already loaded. + \def\z{\endgroup\endinput}% xintfrac already loaded. \fi \fi \fi @@ -70,7 +68,7 @@ \XINTsetupcatcodes% defined in xintkernel.sty \XINT_providespackage \ProvidesPackage{xintfrac}% - [2022/05/18 v1.4k Expandable operations on fractions (JFB)]% + [2022/05/29 v1.4l Expandable operations on fractions (JFB)]% \def\XINT_cntSgnFork #1% {% \ifcase #1\expandafter\xint_secondofthree @@ -121,8 +119,8 @@ {% \expandafter\XINT_outfrac_P\expandafter {#2}{#1}% }% -\def\XINT_inFrac {\romannumeral0\XINT_infrac }% -\def\XINT_infrac #1% +\def\XINT_inFrac {\romannumeral0\XINT_infrac }% this one deprecated +\def\XINT_infrac #1% this one is core xintfrac macro {% \expandafter\XINT_infrac_fork\romannumeral`&&@#1\xint:/\XINT_W[\XINT_W\XINT_T }% @@ -397,6 +395,8 @@ \expandafter\XINT_raw\romannumeral0\XINT_infrac }% \def\XINT_raw #1#2#3{ #2/#3[#1]}% +\def\xintRawBraced {\romannumeral0\xintrawbraced }% +\let\xintrawbraced \XINT_infrac \def\xintiLogTen {\the\numexpr\xintilogten}% \def\xintilogten {% @@ -458,6 +458,22 @@ \def\XINT_spraw #1[#2#3]{\xint_gob_til_W #2\XINT_spraw_a\W\XINT_spraw_p #1[#2#3]}% \def\XINT_spraw_a\W\XINT_spraw_p #1[\W]{ #1}% \def\XINT_spraw_p #1[\W]{\xintpraw {#1}}% +\def\xintFracToSci{\romannumeral0\xintfractosci}% +\def\xintfractosci#1{\expandafter\XINT_fractosci\romannumeral0\xintraw{#1}}% +\def\XINT_fractosci#1#2/#3[#4]{\expanded{ % + \ifnum#4=\xint_c_ #1#2\else + \romannumeral0\expandafter\XINT_pfloat_a_fork\romannumeral0\xintrez{#1#2[#4]}% + \fi + \if\XINT_isOne{#3}1\else\if#10\else/#3\fi\fi}% +}% +\def\xintFracToDecimal{\romannumeral0\xintfractodecimal}% +\def\xintfractodecimal#1{\expandafter\XINT_fractodecimal\romannumeral0\xintraw{#1}}% +\def\XINT_fractodecimal #1#2/#3[#4]{\expanded{ % + \ifnum#4=\xint_c_ #1#2\else + \romannumeral0\expandafter\XINT_dectostr\romannumeral0\xintrez{#1#2[#4]}% + \fi + \if\XINT_isOne{#3}1\else\if#10\else/#3\fi\fi}% +}% \def\xintRawWithZeros {\romannumeral0\xintrawwithzeros }% \def\xintrawwithzeros {% @@ -606,15 +622,16 @@ on input line \noexpand\the\inputlineno.&&J}}#2% {% \expandafter-\romannumeral0\XINT_sgnfrac_P }% -\def\xintTeXfromSci#1% +\def\xintTeXfromSci{\xintfracTeXDeprecation\xintTeXfromSci\xintTeXFromSci}% +\def\xintTeXFromSci#1% {% - \expanded{\expandafter\XINT_texfromsci\expanded{#1}/\relax/\xint:}% + \expandafter\XINT_texfromsci\expanded{#1}/\relax/\xint: }% \def\XINT_texfromsci #1/#2#3/#4\xint: {% \XINT_texfromsci_a #1e\relax e\xint: {\ifx\relax#2\xint_dothis\xint_firstofone\fi - \xint_orthat{\XINT_texfromsci_frac{#2#3}}}% + \xint_orthat{\xintTeXFromScifracmacro{#2#3}}}% {\unless\ifx\relax#2\cdot{#2#3}^{-1}\fi}% }% \def\XINT_texfromsci_a #1e#2#3e#4\xint:#5#6% @@ -622,9 +639,9 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \ifx\relax#2#5{#1}\else#1\cdot10^{#2#3}#6\fi }% \ifdefined\frac - \def\XINT_texfromsci_frac#1#2{\noexpand\frac{#2}{#1}}% + \protected\def\xintTeXFromScifracmacro#1#2{\frac{#2}{#1}}% \else - \def\XINT_texfromsci_frac#1#2{{#2\over#1}}% + \protected\def\xintTeXFromScifracmacro#1#2{{#2\over#1}}% \fi \def\xintFwOver {\xintfracTeXDeprecation\xintFwOver\xintTeXOver}% \def\xintTeXOver{\romannumeral0\xintfwover }% @@ -1940,6 +1957,16 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \def\XINT_inv_b #1.#2{ #2[#1]}% \def\xintSgn {\romannumeral0\xintsgn }% \def\xintsgn #1{\expandafter\XINT_sgn\romannumeral0\xintraw {#1}\xint:}% +\def\xintSignBit {\romannumeral0\xintsignbit }% +\def\xintsignbit #1{\expandafter\XINT_signbit\romannumeral0\xintraw {#1}\xint:}% +\def\XINT_signbit #1#2\xint: +{% + \xint_UDzerominusfork + #1-{ 0}% + 0#1{ 1}% + 0-{ 0}% + \krof +}% \def\xintGCD {\romannumeral0\xintgcd}% \def\xintgcd #1% {% @@ -2110,11 +2137,11 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \expandafter\XINT_float_post \romannumeral0\XINTinfloat[\XINTdigits]{#1}\XINTdigits.% }% -\def\XINT_float_opt [\xint:#1]% +\def\XINT_float_opt [\xint: {% - \expandafter\XINT_float_opt_a\the\numexpr #1.% + \expandafter\XINT_float_opt_a\the\numexpr }% -\def\XINT_float_opt_a #1.#2% +\def\XINT_float_opt_a #1]#2% {% \expandafter\XINT_float_post \romannumeral0\XINTinfloat[#1]{#2}#1.% @@ -2134,6 +2161,43 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \expandafter\XINT_float_pos_done\the\numexpr#3+#4-\xint_c_i.#1.#2;% }% \def\XINT_float_pos_done #1.#2;{ #2e#1}% +\def\xintFloatBraced{\romannumeral0\xintfloatbraced }% +\def\xintfloatbraced#1{\XINT_floatbr_chkopt #1\xint:}% +\def\XINT_floatbr_chkopt #1% +{% + \ifx [#1\expandafter\XINT_floatbr_opt + \else\expandafter\XINT_floatbr_noopt + \fi #1% +}% +\def\XINT_floatbr_noopt #1\xint:% +{% + \expandafter\XINT_floatbr_post + \romannumeral0\XINTinfloat[\XINTdigits]{#1}\XINTdigits.% +}% +\def\XINT_floatbr_opt [\xint: +{% + \expandafter\XINT_floatbr_opt_a\the\numexpr +}% +\def\XINT_floatbr_opt_a #1]#2% +{% + \expandafter\XINT_floatbr_post + \romannumeral0\XINTinfloat[#1]{#2}#1.% +}% +\def\XINT_floatbr_post #1% +{% + \xint_UDzerominusfork + #1-\XINT_floatbr_zero + 0#1\XINT_floatbr_neg + 0-\XINT_floatbr_pos + \krof #1% +}% +\def\XINT_floatbr_zero #1]#2.{\expanded{{0}{0}{0.\xintReplicate{#2-\xint_c_i}0}}}% +\def\XINT_floatbr_neg-{\expandafter\XINT_floatbr_neg_a\romannumeral0\XINT_floatbr_pos}% +\def\XINT_floatbr_neg_a#1{{1}}% +\def\XINT_floatbr_pos #1#2[#3]#4.% +{% + \expanded{{0}{\the\numexpr#3+#4-\xint_c_i}}{#1.#2}% +}% \def\XINTinFloat {\romannumeral0\XINTinfloat }% \def\XINTinfloat {\expandafter\XINT_infloat_clean\romannumeral0\XINT_infloat}% @@ -2152,10 +2216,10 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \def\XINT_infloatS_clean #1% {\if #1!\xint_dothis\XINT_infloatS_clean_a\fi\xint_orthat{ }#1}% \def\XINT_infloatS_clean_a !#1.{ }% -\def\XINT_infloat [#1]#2% +\def\XINT_infloat [#1]%#2% {% \expandafter\XINT_infloat_a\the\numexpr #1\expandafter.% - \romannumeral0\XINT_infrac {#2}% + \romannumeral0\XINT_infrac% {#2}% }% \def\XINT_infloat_a #1.#2#3#4% {% @@ -2345,66 +2409,8 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \xint_orthat\XINT_floatilogten_b #1% }% \def\XINT_floatilogten_z 0[0]#1.{-"7FFF8000\relax}% -\def\XINT_floatilogten_a !#1.#2[#3]#4.{#3-#1+#4-1\relax}% -\def\XINT_floatilogten_b #1[#2]#3.{#2+#3-1\relax}% -\def\xintFloatSciExp {\the\numexpr\xintfloatsciexp }% -\def\xintpfloatsciexp #1{\XINT_floatsciexp_chkopt #1\xint:}% -\def\XINT_floatsciexp_chkopt #1% -{% - \ifx [#1\expandafter\XINT_floatsciexp_opt - \else\expandafter\XINT_floatsciexp_noopt - \fi #1% -}% -\def\XINT_floatsciexp_noopt #1\xint:% -{% - \expandafter\XINT_floatsciexp\romannumeral0\XINT_infloat[\XINTdigits]{#1}% - \XINTdigits.% -}% -\def\XINT_floatsciexp_opt [\xint:#1]#2% -{% - \expandafter\XINT_floatsciexp\romannumeral0\XINT_infloat[#1]{#2}#1.% -}% -\def\XINT_floatsciexp #1{% - \if #10\xint_dothis\XINT_floatsciexp_z\fi - \if #1!\xint_dothis\XINT_floatsciexp_a\fi - \xint_orthat\XINT_floatsciexp_b #1% -}% -\def\XINT_floatsciexp_z 0[0]#1.{0\relax}% -\def\XINT_floatsciexp_a !#1.#2[#3]#4.{#3-#1+#4-1\relax}% -\def\XINT_floatsciexp_b #1[#2]#3.{#2+#3-1\relax}% -\def\xintFloatSignificand {\romannumeral0\xintfloatsignificand}% -\def\xintfloatsignificand #1{\XINT_floatsgf_chkopt #1\xint:}% -\def\XINT_floatsgf_chkopt #1% -{% - \ifx [#1\expandafter\XINT_floatsgf_opt - \else\expandafter\XINT_floatsgf_noopt - \fi #1% -}% -\def\XINT_floatsgf_noopt #1\xint:% -{% - \expandafter\XINT_floatsgf_post - \romannumeral0\XINTinfloat[\XINTdigits]{#1}\XINTdigits.% -}% -\def\XINT_floatsgf_opt [\xint:#1]% -{% - \expandafter\XINT_floatsgf_opt_a\the\numexpr #1.% -}% -\def\XINT_floatsgf_opt_a #1.#2% -{% - \expandafter\XINT_floatsgf_post - \romannumeral0\XINTinfloat[#1]{#2}#1.% -}% -\def\XINT_floatsgf_post #1% -{% - \xint_UDzerominusfork - #1-\XINT_floatsgf_zero - 0#1\XINT_floatsgf_neg - 0-\XINT_floatsgf_pos - \krof #1% -}%[ -\def\XINT_floatsgf_zero #1]#2.{\XINT_dsx_addzeros{#2};}% -\def\XINT_floatsgf_neg-{\XINT_floatsgf_pos}% -\def\XINT_floatsgf_pos #1[#2]#3.{ #1}% +\def\XINT_floatilogten_a !#1.#2[#3]#4.{#3-#1+#4-\xint_c_i\relax}% +\def\XINT_floatilogten_b #1[#2]#3.{#2+#3-\xint_c_i\relax}% \def\xintPFloatE{e}% \def\xintPFloatNoSciEmax{\xint_c_v}% 1e6 uses sci.not. \def\xintPFloatNoSciEmin{-\xint_c_iv}% 1e-5 uses sci.not. @@ -2430,7 +2436,8 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \expandafter\XINT_pfloat\romannumeral0\XINTinfloatS[\XINTdigits]{#1}% \XINTdigits.% }% -\def\XINT_pfloat_opt [\xint:#1]#2% +\def\XINT_pfloat_opt [\xint:{\expandafter\XINT_pfloat_opt_a\the\numexpr}% +\def\XINT_pfloat_opt_a #1]#2% {% \expandafter\XINT_pfloat\romannumeral0\XINTinfloatS[#1]{#2}% #1.% @@ -2454,40 +2461,42 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \expandafter\XINT_pfloat_aa\the\numexpr\xintLength{#1}.% #3.#2.#1.% }% -\def\XINT_pfloat_keeptrimmed_fork#1% +\def\XINT_pfloat_aa #1.#2.% +{% + \unless\ifnum\xintPFloatMinTrimmed>\numexpr#2-#1\relax + \xint_dothis\XINT_pfloat_a\fi + \ifnum#2>#1 \xint_dothis{\XINT_pfloat_i #2.}\fi + \xint_orthat\XINT_pfloat_a #1.% +}% +\def\XINT_pfloat_a_fork#1% {% \xint_UDzerominusfork - #1-\XINT_pfloat_keeptrimmed_zero - 0#1\XINT_pfloat_keeptrimmed_neg - 0-\XINT_pfloat_keeptrimmed_pos + #1-\XINT_pfloat_a_zero + 0#1\XINT_pfloat_a_neg + 0-\XINT_pfloat_a_pos \krof #1% }% -\def\XINT_pfloat_keeptrimmed_zero#1]{\expanded{ \xintPFloatZero}}% -\def\XINT_pfloat_keeptrimmed_neg-{\expandafter-\romannumeral0\XINT_pfloat_keeptrimmed_pos}% -\def\XINT_pfloat_keeptrimmed_pos#1/1[#2]% +\def\XINT_pfloat_a_zero#1]{\expanded{ \xintPFloatZero}}% +\def\XINT_pfloat_a_neg-{\expandafter-\romannumeral0\XINT_pfloat_a_pos}% +\def\XINT_pfloat_a_pos#1/1[#2]% {% \expandafter\XINT_pfloat_a\the\numexpr\xintLength{#1}.#2.#1.% }% -\def\XINT_pfloat_aa #1.#2.% +\def\XINT_pfloat_i #1.#2.%#3.#4.% {% - \unless\ifnum\xintPFloatMinTrimmed>\numexpr#2-#1\relax - \xint_dothis\XINT_pfloat_a\fi - \ifnum#2>#1 \xint_dothis{\XINT_pfloat_i #2.}\fi - \xint_orthat\XINT_pfloat_a #1.% + \expandafter\XINT_pfloat_j\romannumeral\xintreplicate{#1-#2}0.#2.% }% -\def\XINT_pfloat_i #1.#2.#3.#4.% +\def\XINT_pfloat_j #1.#2.#3#4.%#5. {% - \expandafter\XINT_pfloat_j - \the\numexpr#3+#2-#1\expandafter.% - \romannumeral0\XINT_dsx_addzerosnofuss{#1-#2}#4;.#1.% + \expandafter\XINT_pfloat_b\the\numexpr#2+#3#4-\xint_c_i.% + #3#2.#1.% }% -\def\XINT_pfloat_j #1.#2.#3.{\XINT_pfloat_a#3.#1.#2.}% -\def\XINT_pfloat_a #1.#2#3.% +\def\XINT_pfloat_a #1.#2#3.%#4. {% \expandafter\XINT_pfloat_b\the\numexpr#1+#2#3-\xint_c_i.% - #2#1.% + #2#1..% }% -\def\XINT_pfloat_b #1.#2% +\def\XINT_pfloat_b #1.#2%#3.#4.#5. {% \ifnum \xintPFloatNoSciEmax<#1 \xint_dothis\XINT_pfloat_sci\fi \ifnum \xintPFloatNoSciEmin>#1 \xint_dothis\XINT_pfloat_sci\fi @@ -2501,21 +2510,21 @@ on input line \noexpand\the\inputlineno.&&J}}#2% \ifnum#2=\xint_c_i\expandafter\XINT_pfloat_sci_i\expandafter\fi \expandafter\XINT_pfloat_sci_a\romannumeral`&&@\xintPFloatE #1.% }% -\def\XINT_pfloat_sci_a #1.#2#3.{ #2.#3#1}% -\def\XINT_pfloat_sci_i #1#2#3.#4.{\expanded{#1 #4\xintPFloatLengthOneSuffix}#3}% -\def\XINT_pfloat_N#1.#2.#3.% +\def\XINT_pfloat_sci_a #1.#2.#3#4.{ #3.#4#2#1}% +\def\XINT_pfloat_sci_i #1#2#3.#4.#5.{\expanded{#1 #5\xintPFloatLengthOneSuffix}#3}% +\def\XINT_pfloat_N#1.#2.#3.#4.% {% - \expandafter\XINT_pfloat_N_e\romannumeral\xintreplicate{-#1}{0}#3% + \expandafter\XINT_pfloat_N_e\romannumeral\xintreplicate{-#1}{0}#4#3% }% \def\XINT_pfloat_N_e 0{ 0.}% -\def\XINT_pfloat_P #1.#2.#3.% +\def\XINT_pfloat_P #1.#2.#3.#4.% {% \expandafter\XINT_split_fromleft_a - \the\numexpr\xint_c_vii-#1.#3\xint_bye2345678\xint_bye.% + \the\numexpr\xint_c_vii-#1.#4\xint_bye2345678\xint_bye.#3% }% -\def\XINT_pfloat_Ps #1.#2.#3.% +\def\XINT_pfloat_Ps #1.#2.#3.#4.% {% - \expanded{ #3% + \expanded{ #4% \romannumeral\xintreplicate{#1+\xint_c_i-#2}{0}\xintPFloatIntSuffix}% }% \def\xintFloatToDecimal {\romannumeral0\xintfloattodecimal }% diff --git a/Master/texmf-dist/tex/generic/xint/xintgcd.sty b/Master/texmf-dist/tex/generic/xint/xintgcd.sty index 3570a8f1eb8..4b62b4be377 100644 --- a/Master/texmf-dist/tex/generic/xint/xintgcd.sty +++ b/Master/texmf-dist/tex/generic/xint/xintgcd.sty @@ -21,7 +21,7 @@ %% same distribution. (The sources need not necessarily be %% in the same archive or directory.) %% --------------------------------------------------------------- -%% The xint bundle 1.4k 2022/05/18 +%% The xint bundle 1.4l 2022/05/29 %% Copyright (C) 2013-2022 by Jean-Francois Burnol %% xintgcd: Euclidean algorithm with xint package %% --------------------------------------------------------------- @@ -31,25 +31,24 @@ \catcode123=1 % { \catcode125=2 % } \catcode64=11 % @ - \catcode35=6 % # \catcode44=12 % , - \catcode45=12 % - \catcode46=12 % . \catcode58=12 % : + \catcode94=7 % ^ + \def\empty{}\def\space{ }\newlinechar10 \def\z{\endgroup}% \expandafter\let\expandafter\x\csname ver@xintgcd.sty\endcsname \expandafter\let\expandafter\w\csname ver@xint.sty\endcsname \expandafter\let\expandafter\t\csname ver@xinttools.sty\endcsname - \expandafter - \ifx\csname PackageInfo\endcsname\relax - \def\y#1#2{\immediate\write-1{Package #1 Info: #2.}}% + \expandafter\ifx\csname numexpr\endcsname\relax + \expandafter\ifx\csname PackageWarning\endcsname\relax + \immediate\write128{^^JPackage xintgcd Warning:^^J% + \space\space\space\space + \numexpr not available, aborting input.^^J}% \else - \def\y#1#2{\PackageInfo{#1}{#2}}% + \PackageWarningNoLine{xintgcd}{\numexpr not available, aborting input}% \fi - \expandafter - \ifx\csname numexpr\endcsname\relax - \y{xintgcd}{\numexpr not available, aborting input}% - \aftergroup\endinput + \def\z{\endgroup\endinput}% \else \ifx\x\relax % plain-TeX, first loading of xintgcd.sty \ifx\w\relax % but xint.sty not yet loaded. @@ -59,7 +58,6 @@ \expandafter\def\expandafter\z\expandafter{\z\input xinttools.sty\relax}% \fi \else - \def\empty {}% \ifx\x\empty % LaTeX, first loading, % variable is initialized, but \ProvidesPackage not yet seen \ifx\w\relax % xint.sty not yet loaded. @@ -69,7 +67,7 @@ \expandafter\def\expandafter\z\expandafter{\z\RequirePackage{xinttools}}% \fi \else - \aftergroup\endinput % xintgcd already loaded. + \def\z{\endgroup\endinput}% xintgcd already loaded. \fi \fi \fi @@ -77,7 +75,7 @@ \XINTsetupcatcodes% defined in xintkernel.sty \XINT_providespackage \ProvidesPackage{xintgcd}% - [2022/05/18 v1.4k Euclide algorithm with xint package (JFB)]% + [2022/05/29 v1.4l Euclide algorithm with xint package (JFB)]% \def\xintBezout {\romannumeral0\xintbezout }% \def\xintbezout #1% {% diff --git a/Master/texmf-dist/tex/generic/xint/xintkernel.sty b/Master/texmf-dist/tex/generic/xint/xintkernel.sty index 3e6c0afa591..6d793505eb6 100644 --- a/Master/texmf-dist/tex/generic/xint/xintkernel.sty +++ b/Master/texmf-dist/tex/generic/xint/xintkernel.sty @@ -21,7 +21,7 @@ %% same distribution. (The sources need not necessarily be %% in the same archive or directory.) %% --------------------------------------------------------------- -%% The xint bundle 1.4k 2022/05/18 +%% The xint bundle 1.4l 2022/05/29 %% Copyright (C) 2013-2022 by Jean-Francois Burnol %% xintkernel: Paraphernalia for the xint packages %% --------------------------------------------------------------- @@ -30,116 +30,111 @@ \endlinechar=13 % \catcode123=1 % { \catcode125=2 % } - \catcode35=6 % # \catcode44=12 % , - \catcode45=12 % - \catcode46=12 % . \catcode58=12 % : - \catcode95=11 % _ - \expandafter - \ifx\csname PackageInfo\endcsname\relax - \def\y#1#2{\immediate\write-1{Package #1 Info: #2.}}% + \catcode94=7 % ^ + \def\space{ }\newlinechar10 + \let\z\relax + \expandafter\ifx\csname numexpr\endcsname\relax + \expandafter\ifx\csname PackageWarning\endcsname\relax + \immediate\write128{^^JPackage xintkernel Warning:^^J% + \space\space\space\space + \numexpr not available, aborting input.^^J}% \else - \def\y#1#2{\PackageInfo{#1}{#2}}% + \PackageWarningNoLine{xintkernel}{\numexpr not available, aborting input}% \fi - \let\z\relax - \expandafter - \ifx\csname numexpr\endcsname\relax - \y{xintkernel}{\numexpr not available, aborting input}% - \def\z{\endgroup\endinput}% + \def\z{\endgroup\endinput}% + \else + \expandafter\ifx\csname XINTsetupcatcodes\endcsname\relax \else - \expandafter - \ifx\csname XINTsetupcatcodes\endcsname\relax - \else - \y{xintkernel}{I was already loaded, aborting input}% \def\z{\endgroup\endinput}% - \fi \fi + \fi \ifx\z\relax\else\expandafter\z\fi% \def\PrepareCatcodes {% \endgroup \def\XINTrestorecatcodes - {% takes care of all, to allow more economical code in modules - \catcode0=\the\catcode0 % - \catcode59=\the\catcode59 % ; xintexpr - \catcode126=\the\catcode126 % ~ xintexpr - \catcode39=\the\catcode39 % ' xintexpr - \catcode34=\the\catcode34 % " xintbinhex, and xintexpr - \catcode63=\the\catcode63 % ? xintexpr - \catcode124=\the\catcode124 % | xintexpr - \catcode38=\the\catcode38 % & xintexpr - \catcode64=\the\catcode64 % @ xintexpr - \catcode33=\the\catcode33 % ! xintexpr - \catcode93=\the\catcode93 % ] -, xintfrac, xintseries, xintcfrac - \catcode91=\the\catcode91 % [ -, xintfrac, xintseries, xintcfrac - \catcode36=\the\catcode36 % $ xintgcd only $ - \catcode94=\the\catcode94 % ^ - \catcode96=\the\catcode96 % ` - \catcode47=\the\catcode47 % / - \catcode41=\the\catcode41 % ) - \catcode40=\the\catcode40 % ( - \catcode42=\the\catcode42 % * - \catcode43=\the\catcode43 % + - \catcode62=\the\catcode62 % > - \catcode60=\the\catcode60 % < - \catcode58=\the\catcode58 % : - \catcode46=\the\catcode46 % . - \catcode45=\the\catcode45 % - - \catcode44=\the\catcode44 % , - \catcode35=\the\catcode35 % # - \catcode95=\the\catcode95 % _ - \catcode125=\the\catcode125 % } - \catcode123=\the\catcode123 % { - \endlinechar=\the\endlinechar - \catcode13=\the\catcode13 % ^^M - \catcode32=\the\catcode32 % - \catcode61=\the\catcode61\relax % = + {% prepared for use in \edef + \catcode0=\the\catcode0 % ^^@ + \catcode1=\the\catcode1 % ^^A + \catcode13=\the\catcode13 % ^^M + \catcode32=\the\catcode32 % <space> + \catcode33=\the\catcode33 % ! + \catcode34=\the\catcode34 % " + \catcode35=\the\catcode35 % # + \catcode36=\the\catcode36 % $ + \catcode38=\the\catcode38 % & + \catcode39=\the\catcode39 % ' + \catcode40=\the\catcode40 % ( + \catcode41=\the\catcode41 % ) + \catcode42=\the\catcode42 % * + \catcode43=\the\catcode43 % + + \catcode44=\the\catcode44 % , + \catcode45=\the\catcode45 % - + \catcode46=\the\catcode46 % . + \catcode47=\the\catcode47 % / + \catcode58=\the\catcode58 % : + \catcode59=\the\catcode59 % ; + \catcode60=\the\catcode60 % < + \catcode61=\the\catcode61 % = + \catcode62=\the\catcode62 % > + \catcode63=\the\catcode63 % ? + \catcode64=\the\catcode64 % @ + \catcode91=\the\catcode91 % [ + \catcode93=\the\catcode93 % ] + \catcode94=\the\catcode94 % ^ + \catcode95=\the\catcode95 % _ + \catcode96=\the\catcode96 % ` + \catcode123=\the\catcode123 % { + \catcode124=\the\catcode124 % | + \catcode125=\the\catcode125 % } + \catcode126=\the\catcode126 % ~ + \endlinechar=\the\endlinechar\relax }% \edef\XINTrestorecatcodesendinput {% \XINTrestorecatcodes\noexpand\endinput % }% \def\XINTsetcatcodes - {% - \catcode61=12 % = - \catcode32=10 % space - \catcode13=5 % ^^M - \endlinechar=13 % - \catcode123=1 % { - \catcode125=2 % } - \catcode95=11 % _ LETTER - \catcode35=6 % # - \catcode44=12 % , - \catcode45=12 % - - \catcode46=12 % . - \catcode58=11 % : LETTER - \catcode60=12 % < - \catcode62=12 % > - \catcode43=12 % + - \catcode42=12 % * - \catcode40=12 % ( - \catcode41=12 % ) - \catcode47=12 % / - \catcode96=12 % ` - \catcode94=11 % ^ LETTER - \catcode36=3 % $ - \catcode91=12 % [ - \catcode93=12 % ] - \catcode33=12 % ! (xintexpr.sty will use catcode 11) - \catcode64=11 % @ LETTER - \catcode38=7 % & for \romannumeral`&&@ trick. - \catcode124=12 % | - \catcode63=11 % ? LETTER - \catcode34=12 % " - \catcode39=12 % ' - \catcode126=3 % ~ MATH - \catcode59=12 % ; - \catcode0=12 % for \romannumeral`&&@ trick - \catcode1=3 % for ultra-safe séparateur &&A + {% standard settings with a few xint*sty specific ones + \catcode0=12 % for \romannumeral`&&@ + \catcode1=3 % for safe separator &&A + \catcode13=5 % ^^M + \catcode32=10 % <space> + \catcode33=12 % ! but used as LETTER inside xintexpr.sty + \catcode34=12 % " + \catcode35=6 % # + \catcode36=3 % $ + \catcode38=7 % & SUPERSCRIPT for && as replacement of ^^ + \catcode39=12 % ' + \catcode40=12 % ( + \catcode41=12 % ) + \catcode42=12 % * + \catcode43=12 % + + \catcode44=12 % , + \catcode45=12 % - + \catcode46=12 % . + \catcode47=12 % / + \catcode58=11 % : LETTER + \catcode59=12 % ; + \catcode60=12 % < + \catcode61=12 % = + \catcode62=12 % > + \catcode63=11 % ? LETTER + \catcode64=11 % @ LETTER + \catcode91=12 % [ + \catcode93=12 % ] + \catcode94=11 % ^ LETTER + \catcode95=11 % _ LETTER + \catcode96=12 % ` + \catcode123=1 % { + \catcode124=12 % | + \catcode125=2 % } + \catcode126=3 % ~ MATH SHIFT + \endlinechar=13 % }% - \let\XINT_setcatcodes\XINTsetcatcodes - \let\XINT_restorecatcodes\XINTrestorecatcodes \XINTsetcatcodes }% \PrepareCatcodes @@ -159,7 +154,7 @@ \fi \XINT_providespackage \ProvidesPackage {xintkernel}% - [2022/05/18 v1.4k Paraphernalia for the xint packages (JFB)]% + [2022/05/29 v1.4l Paraphernalia for the xint packages (JFB)]% \chardef\xint_c_ 0 \chardef\xint_c_i 1 \chardef\xint_c_ii 2 diff --git a/Master/texmf-dist/tex/generic/xint/xintlog.sty b/Master/texmf-dist/tex/generic/xint/xintlog.sty index c5751af1217..6b25bde105d 100644 --- a/Master/texmf-dist/tex/generic/xint/xintlog.sty +++ b/Master/texmf-dist/tex/generic/xint/xintlog.sty @@ -21,7 +21,7 @@ %% same distribution. (The sources need not necessarily be %% in the same archive or directory.) %% --------------------------------------------------------------- -%% The xint bundle 1.4k 2022/05/18 +%% The xint bundle 1.4l 2022/05/29 %% Copyright (C) 2013-2022 by Jean-Francois Burnol %% xintlog: Logarithms and exponentials for xintexpr %% --------------------------------------------------------------- @@ -33,55 +33,69 @@ \catcode64=11 % @ \catcode35=6 % # \catcode44=12 % , - \catcode45=12 % - \catcode46=12 % . \catcode58=12 % : \catcode94=7 % ^ - \def\z{\endgroup}% \def\empty{}\def\space{ }\newlinechar10 + \def\z{\endgroup}% + \expandafter\let\expandafter\x\csname ver@xintlog.sty\endcsname \expandafter\let\expandafter\w\csname ver@xintexpr.sty\endcsname \expandafter - \ifx\csname PackageInfo\endcsname\relax - \def\y#1#2{\immediate\write-1{Package #1 Info:^^J% - \space\space\space\space#2.}}% + \ifx\csname PackageWarning\endcsname\relax + \def\y#1#2{\immediate\write128{^^JPackage #1 Warning:^^J% + \space\space\space\space#2.^^J}}% \else - \def\y#1#2{\PackageInfo{#1}{#2}}% + \def\y#1#2{\PackageWarningNoLine{#1}{#2}}% \fi \expandafter \ifx\csname numexpr\endcsname\relax \y{xintlog}{\numexpr not available, aborting input}% - \aftergroup\endinput + \def\z{\endgroup\endinput}% \else \ifx\w\relax % xintexpr.sty not yet loaded. + \edef\MsgBrk{^^J\space\space\space\space}% \y{xintlog}% - {Loading should be via \ifx\x\empty\string\usepackage{xintexpr.sty} - \else\string\input\space xintexpr.sty \fi - rather, aborting}% - \aftergroup\endinput + {\ifx\x\empty + xintlog should not be loaded directly\MessageBreak + The correct way is \string\usepackage{xintexpr}.\MessageBreak + Will try that now% + \else + First loading of xintlog.sty should be via + \string\input\space xintexpr.sty\relax\MsgBrk + Will try that now% + \fi + }% + \ifx\x\empty + \def\z{\endgroup\RequirePackage{xintexpr}\endinput}% + \else + \def\z{\endgroup\input xintexpr.sty\relax\endinput}% + \fi + \else + \def\z{\endgroup\edef\XINTlogendinput{\XINTrestorecatcodes\noexpand\endinput}}% \fi \fi \z% -\edef\XINTendxintloginput{\XINTrestorecatcodes\noexpand\endinput}\XINTsetcatcodes% +\XINTsetcatcodes% \ifcsname xintlibver@log\endcsname \expandafter\xint_firstoftwo \else \expandafter\xint_secondoftwo \fi -{\immediate\write-1{Reloading xintlog library using Digits=\xinttheDigits.}}% -{\expandafter\gdef\csname xintlibver@log\endcsname{2022/05/18 v1.4k}% +{\immediate\write128{Reloading xintlog library using Digits=\xinttheDigits.}}% +{\expandafter\gdef\csname xintlibver@log\endcsname{2022/05/29 v1.4l}% \XINT_providespackage \ProvidesPackage{xintlog}% -[2022/05/18 v1.4k Logarithms and exponentials for xintexpr (JFB)]% +[2022/05/29 v1.4l Logarithms and exponentials for xintexpr (JFB)]% }% \def\xintreloadxintlog{\input xintlog.sty }% -\xintexprSafeCatcodes\catcode`_ 11 +\xintexprSafeCatcodes \unless\ifdefined\XINTinFloatPowTen \ifdefined\RequirePackage \RequirePackage{poormanlog}% \else \input poormanlog.tex \fi\fi -\xintexprRestoreCatcodes\XINTsetcatcodes +\xintexprRestoreCatcodes \def\PoorManLogBaseTen{\romannumeral0\poormanlogbaseten}% \def\poormanlogbaseten #1% {% @@ -334,7 +348,7 @@ \romannumeral`&&@\XINT:NEhook:f:one:from:two {\romannumeral`&&@\XINTinFloatSciPow#3}}% }% -\ifnum\XINTdigits<9 \expandafter\XINTendxintloginput\fi% +\ifnum\XINTdigits<9 \expandafter\XINTlogendinput\fi% \def\XINT_tmpa{1[0]}% \expandafter\let\csname XINT_c_1_0\endcsname\XINT_tmpa \expandafter\let\csname XINT_c_2_0\endcsname\XINT_tmpa @@ -1392,7 +1406,7 @@ \XINTinFloat[\XINTdigitsormax-43]{1/9[0]}.% }% \fi -\XINTendxintloginput% +\XINTlogendinput% \endinput %% %% End of file `xintlog.sty'. diff --git a/Master/texmf-dist/tex/generic/xint/xintseries.sty b/Master/texmf-dist/tex/generic/xint/xintseries.sty index 8fa98b8c382..1194fb0de6e 100644 --- a/Master/texmf-dist/tex/generic/xint/xintseries.sty +++ b/Master/texmf-dist/tex/generic/xint/xintseries.sty @@ -21,7 +21,7 @@ %% same distribution. (The sources need not necessarily be %% in the same archive or directory.) %% --------------------------------------------------------------- -%% The xint bundle 1.4k 2022/05/18 +%% The xint bundle 1.4l 2022/05/29 %% Copyright (C) 2013-2022 by Jean-Francois Burnol %% xintseries: Expandable partial sums with xint package %% --------------------------------------------------------------- @@ -31,38 +31,36 @@ \catcode123=1 % { \catcode125=2 % } \catcode64=11 % @ - \catcode35=6 % # \catcode44=12 % , - \catcode45=12 % - \catcode46=12 % . \catcode58=12 % : - \let\z\endgroup + \catcode94=7 % ^ + \def\empty{}\def\space{ }\newlinechar10 + \def\z{\endgroup}% \expandafter\let\expandafter\x\csname ver@xintseries.sty\endcsname \expandafter\let\expandafter\w\csname ver@xintfrac.sty\endcsname - \expandafter - \ifx\csname PackageInfo\endcsname\relax - \def\y#1#2{\immediate\write-1{Package #1 Info: #2.}}% + \expandafter\ifx\csname numexpr\endcsname\relax + \expandafter\ifx\csname PackageWarning\endcsname\relax + \immediate\write128{^^JPackage xintseries Warning:^^J% + \space\space\space\space + \numexpr not available, aborting input.^^J}% \else - \def\y#1#2{\PackageInfo{#1}{#2}}% + \PackageWarningNoLine{xintseries}{\numexpr not available, aborting input}% \fi - \expandafter - \ifx\csname numexpr\endcsname\relax - \y{xintseries}{\numexpr not available, aborting input}% - \aftergroup\endinput + \def\z{\endgroup\endinput}% \else \ifx\x\relax % plain-TeX, first loading of xintseries.sty \ifx\w\relax % but xintfrac.sty not yet loaded. \def\z{\endgroup\input xintfrac.sty\relax}% \fi \else - \def\empty {}% \ifx\x\empty % LaTeX, first loading, % variable is initialized, but \ProvidesPackage not yet seen \ifx\w\relax % xintfrac.sty not yet loaded. \def\z{\endgroup\RequirePackage{xintfrac}}% \fi \else - \aftergroup\endinput % xintseries already loaded. + \def\z{\endgroup\endinput}% xintseries already loaded. \fi \fi \fi @@ -70,7 +68,7 @@ \XINTsetupcatcodes% defined in xintkernel.sty \XINT_providespackage \ProvidesPackage{xintseries}% - [2022/05/18 v1.4k Expandable partial sums with xint package (JFB)]% + [2022/05/29 v1.4l Expandable partial sums with xint package (JFB)]% \def\xintSeries {\romannumeral0\xintseries }% \def\xintseries #1#2% {% diff --git a/Master/texmf-dist/tex/generic/xint/xinttools.sty b/Master/texmf-dist/tex/generic/xint/xinttools.sty index eb6f898b355..3f6ae4a48ef 100644 --- a/Master/texmf-dist/tex/generic/xint/xinttools.sty +++ b/Master/texmf-dist/tex/generic/xint/xinttools.sty @@ -21,7 +21,7 @@ %% same distribution. (The sources need not necessarily be %% in the same archive or directory.) %% --------------------------------------------------------------- -%% The xint bundle 1.4k 2022/05/18 +%% The xint bundle 1.4l 2022/05/29 %% Copyright (C) 2013-2022 by Jean-Francois Burnol %% xinttools: Expandable and non-expandable utilities %% --------------------------------------------------------------- @@ -31,38 +31,36 @@ \catcode123=1 % { \catcode125=2 % } \catcode64=11 % @ - \catcode35=6 % # \catcode44=12 % , - \catcode45=12 % - \catcode46=12 % . \catcode58=12 % : - \let\z\endgroup + \catcode94=7 % ^ + \def\empty{}\def\space{ }\newlinechar10 + \def\z{\endgroup}% \expandafter\let\expandafter\x\csname ver@xinttools.sty\endcsname \expandafter\let\expandafter\w\csname ver@xintkernel.sty\endcsname - \expandafter - \ifx\csname PackageInfo\endcsname\relax - \def\y#1#2{\immediate\write-1{Package #1 Info: #2.}}% + \expandafter\ifx\csname numexpr\endcsname\relax + \expandafter\ifx\csname PackageWarning\endcsname\relax + \immediate\write128{^^JPackage xinttools Warning:^^J% + \space\space\space\space + \numexpr not available, aborting input.^^J}% \else - \def\y#1#2{\PackageInfo{#1}{#2}}% + \PackageWarningNoLine{xinttools}{\numexpr not available, aborting input}% \fi - \expandafter - \ifx\csname numexpr\endcsname\relax - \y{xinttools}{\numexpr not available, aborting input}% - \aftergroup\endinput + \def\z{\endgroup\endinput}% \else \ifx\x\relax % plain-TeX, first loading of xinttools.sty \ifx\w\relax % but xintkernel.sty not yet loaded. \def\z{\endgroup\input xintkernel.sty\relax}% \fi \else - \def\empty {}% \ifx\x\empty % LaTeX, first loading, % variable is initialized, but \ProvidesPackage not yet seen \ifx\w\relax % xintkernel.sty not yet loaded. \def\z{\endgroup\RequirePackage{xintkernel}}% \fi \else - \aftergroup\endinput % xinttools already loaded. + \def\z{\endgroup\endinput}% xinttools already loaded. \fi \fi \fi @@ -70,7 +68,7 @@ \XINTsetupcatcodes% defined in xintkernel.sty \XINT_providespackage \ProvidesPackage{xinttools}% - [2022/05/18 v1.4k Expandable and non-expandable utilities (JFB)]% + [2022/05/29 v1.4l Expandable and non-expandable utilities (JFB)]% \newtoks\XINT_toks \xint_firstofone{\let\XINT_sptoken= } %<- space here! \def\xintgodef {\global\xintodef }% diff --git a/Master/texmf-dist/tex/generic/xint/xinttrig.sty b/Master/texmf-dist/tex/generic/xint/xinttrig.sty index ae312937e25..c1005e475ec 100644 --- a/Master/texmf-dist/tex/generic/xint/xinttrig.sty +++ b/Master/texmf-dist/tex/generic/xint/xinttrig.sty @@ -21,7 +21,7 @@ %% same distribution. (The sources need not necessarily be %% in the same archive or directory.) %% --------------------------------------------------------------- -%% The xint bundle 1.4k 2022/05/18 +%% The xint bundle 1.4l 2022/05/29 %% Copyright (C) 2013-2022 by Jean-Francois Burnol %% xinttrig: Trigonometry for the xintexpr package %% --------------------------------------------------------------- @@ -33,46 +33,60 @@ \catcode64=11 % @ \catcode35=6 % # \catcode44=12 % , - \catcode45=12 % - \catcode46=12 % . \catcode58=12 % : \catcode94=7 % ^ - \def\z{\endgroup}% \def\empty{}\def\space{ }\newlinechar10 + \def\z{\endgroup}% + \expandafter\let\expandafter\x\csname ver@xinttrig.sty\endcsname \expandafter\let\expandafter\w\csname ver@xintexpr.sty\endcsname \expandafter - \ifx\csname PackageInfo\endcsname\relax - \def\y#1#2{\immediate\write-1{Package #1 Info:^^J% - \space\space\space\space#2.}}% + \ifx\csname PackageWarning\endcsname\relax + \def\y#1#2{\immediate\write128{^^JPackage #1 Warning:^^J% + \space\space\space\space#2.^^J}}% \else - \def\y#1#2{\PackageInfo{#1}{#2}}% + \def\y#1#2{\PackageWarningNoLine{#1}{#2}}% \fi \expandafter \ifx\csname numexpr\endcsname\relax \y{xinttrig}{\numexpr not available, aborting input}% - \aftergroup\endinput + \def\z{\endgroup\endinput}% \else \ifx\w\relax % xintexpr.sty not yet loaded. + \edef\MsgBrk{^^J\space\space\space\space}% \y{xinttrig}% - {Loading should be via \ifx\x\empty\string\usepackage{xintexpr.sty} - \else\string\input\space xintexpr.sty \fi - rather, aborting}% - \aftergroup\endinput + {\ifx\x\empty + xinttrig should not be loaded directly\MessageBreak + The correct way is \string\usepackage{xintexpr}.\MessageBreak + Will try that now% + \else + First loading of xinttrig.sty should be via + \string\input\space xintexpr.sty\relax\MsgBrk + Will try that now% + \fi + }% + \ifx\x\empty + \def\z{\endgroup\RequirePackage{xintexpr}\endinput}% + \else + \def\z{\endgroup\input xintexpr.sty\relax\endinput}% + \fi + \else + \def\z{\endgroup\edef\XINTtrigendinput{\XINTrestorecatcodes\noexpand\endinput}}% \fi \fi \z% -\edef\XINTtrigendinput{\XINTrestorecatcodes\noexpand\endinput}\XINTsetcatcodes% +\XINTsetcatcodes% \catcode`? 12 \ifcsname xintlibver@trig\endcsname \expandafter\xint_firstoftwo \else \expandafter\xint_secondoftwo \fi -{\immediate\write-1{Reloading xinttrig library using Digits=\xinttheDigits.}}% -{\expandafter\gdef\csname xintlibver@trig\endcsname{2022/05/18 v1.4k}% +{\immediate\write128{Reloading xinttrig library using Digits=\xinttheDigits.}}% +{\expandafter\gdef\csname xintlibver@trig\endcsname{2022/05/29 v1.4l}% \XINT_providespackage \ProvidesPackage{xinttrig}% -[2022/05/18 v1.4k Trigonometrical functions for xintexpr (JFB)]% +[2022/05/29 v1.4l Trigonometrical functions for xintexpr (JFB)]% }% \xintFor* #1 in {iDTVtuwxyzX}\do{\xintensuredummy{#1}}% \def\xintreloadxinttrig{\input xinttrig.sty }% |