diff options
Diffstat (limited to 'macros/latex/contrib/l3kernel/l3int.dtx')
-rw-r--r-- | macros/latex/contrib/l3kernel/l3int.dtx | 2679 |
1 files changed, 0 insertions, 2679 deletions
diff --git a/macros/latex/contrib/l3kernel/l3int.dtx b/macros/latex/contrib/l3kernel/l3int.dtx deleted file mode 100644 index 9fa2a547ff..0000000000 --- a/macros/latex/contrib/l3kernel/l3int.dtx +++ /dev/null @@ -1,2679 +0,0 @@ -% \iffalse meta-comment -% -%% File: l3int.dtx -% -% Copyright (C) 1990-2024 The LaTeX Project -% -% It may be distributed and/or modified under the conditions of the -% LaTeX Project Public License (LPPL), either version 1.3c of this -% license or (at your option) any later version. The latest version -% of this license is in the file -% -% https://www.latex-project.org/lppl.txt -% -% This file is part of the "l3kernel bundle" (The Work in LPPL) -% and all files in that bundle must be distributed together. -% -% ----------------------------------------------------------------------- -% -% The development version of the bundle can be found at -% -% https://github.com/latex3/latex3 -% -% for those people who are interested. -% -%<*driver> -\documentclass[full,kernel]{l3doc} -\begin{document} - \DocInput{\jobname.dtx} -\end{document} -%</driver> -% \fi -% -% \title{^^A -% The \pkg{l3int} module\\ Integers^^A -% } -% -% \author{^^A -% The \LaTeX{} Project\thanks -% {^^A -% E-mail: -% \href{mailto:latex-team@latex-project.org} -% {latex-team@latex-project.org}^^A -% }^^A -% } -% -% \date{Released 2024-03-14} -% -% \maketitle -% -% \begin{documentation} -% -% Calculation and comparison of integer values can be carried out -% using literal numbers, \texttt{int} registers, constants and -% integers stored in token list variables. The standard operators -% \texttt{+}, \texttt{-}, \texttt{/} and \texttt{*} and -% parentheses can be used within such expressions to carry -% arithmetic operations. This module carries out these functions -% on \emph{integer expressions} (\enquote{\meta{int expr}}). -% -% \section{Integer expressions} -% -% Throughout this module, (almost) all \texttt{n}-type argument allow -% for an \meta{intexpr} argument with the following syntax. The -% \meta{integer expression} should consist, -% after expansion, of \texttt{+}, \texttt{-}, \texttt{*}, \texttt{/}, -% \texttt{(}, \texttt{)} and of course integer operands. The result -% is calculated by applying standard mathematical rules with the -% following peculiarities: -% \begin{itemize} -% \item \texttt{/} denotes division rounded to the closest integer with -% ties rounded away from zero; -% \item there is an error and the overall expression evaluates to zero -% whenever the absolute value of any intermediate result exceeds -% $2^{31}-1$, except in the case of scaling operations -% $a$\texttt{*}$b$\texttt{/}$c$, for which $a$\texttt{*}$b$ may be -% arbitrarily large (but the operands $a$, $b$, $c$ are still -% constrained to an absolute value at most $2^{31}-1$); -% \item parentheses may not appear after unary \texttt{+} or -% \texttt{-}, namely placing \texttt{+(} or \texttt{-(} at the start -% of an expression or after \texttt{+}, \texttt{-}, \texttt{*}, -% \texttt{/} or~\texttt{(} leads to an error. -% \end{itemize} -% Each integer operand can be either an integer variable (with no need -% for \cs{int_use:N}) or an integer denotation. For example both -% \begin{verbatim} -% \int_show:n { 5 + 4 * 3 - ( 3 + 4 * 5 ) } -% \end{verbatim} -% and -% \begin{verbatim} -% \tl_new:N \l_my_tl -% \tl_set:Nn \l_my_tl { 5 } -% \int_new:N \l_my_int -% \int_set:Nn \l_my_int { 4 } -% \int_show:n { \l_my_tl + \l_my_int * 3 - ( 3 + 4 * 5 ) } -% \end{verbatim} -% show the same result $-6$ because \cs[no-index]{l_my_tl} expands to -% the integer denotation~|5| while the integer variable \cs[no-index]{l_my_int} -% takes the value~$4$. As the \meta{integer expression} is fully -% expanded from left to right during evaluation, fully expandable and -% restricted-expandable functions can both be used, and \cs{exp_not:n} -% and its variants have no effect while \cs{exp_not:N} may incorrectly -% interrupt the expression. -% \begin{texnote} -% Exactly two expansions are needed to evaluate \cs{int_eval:n}. -% The result is \emph{not} an \meta{internal integer}, and therefore -% should be terminated by a space if used in \cs{int_value:w} or in -% a \TeX{}-style integer assignment. -% -% As all \TeX{} integers, integer operands can also be: -% \tn{value}\Arg{\LaTeXe{} counter}; dimension or skip variables, -% converted to integers in~\texttt{sp}; the character code of some -% character given as \texttt{`}\meta{char} or -% \texttt{`\textbackslash}\meta{char}; octal numbers given as -% \texttt{'} followed by digits from \texttt{0} to \texttt{7}; or -% hexadecimal numbers given as |"| followed by digits and upper case -% letters from \texttt{A} to~\texttt{F}. -% \end{texnote} -% -% \begin{function}[EXP]{\int_eval:n} -% \begin{syntax} -% \cs{int_eval:n} \Arg{int expr} -% \end{syntax} -% Evaluates the \meta{int expr} and leaves the result in the -% input stream as an integer denotation: for positive results an -% explicit sequence of decimal digits not starting with~\texttt{0}, -% for negative results \texttt{-}~followed by such a sequence, and -% \texttt{0}~for zero. The \meta{int expr} should consist, -% after expansion, of \texttt{+}, \texttt{-}, \texttt{*}, \texttt{/}, -% \texttt{(}, \texttt{)} and of course integer operands. The result -% is calculated by applying standard mathematical rules with the -% following peculiarities: -% \begin{itemize} -% \item \texttt{/} denotes division rounded to the closest integer with -% ties rounded away from zero; -% \item there is an error and the overall expression evaluates to zero -% whenever the absolute value of any intermediate result exceeds -% $2^{31}-1$, except in the case of scaling operations -% $a$\texttt{*}$b$\texttt{/}$c$, for which $a$\texttt{*}$b$ may be -% arbitrarily large; -% \item parentheses may not appear after unary \texttt{+} or -% \texttt{-}, namely placing \texttt{+(} or \texttt{-(} at the start -% of an expression or after \texttt{+}, \texttt{-}, \texttt{*}, -% \texttt{/} or~\texttt{(} leads to an error. -% \end{itemize} -% Each integer operand can be either an integer variable (with no need -% for \cs{int_use:N}) or an integer denotation. For example both -% \begin{verbatim} -% \int_eval:n { 5 + 4 * 3 - ( 3 + 4 * 5 ) } -% \end{verbatim} -% and -% \begin{verbatim} -% \tl_new:N \l_my_tl -% \tl_set:Nn \l_my_tl { 5 } -% \int_new:N \l_my_int -% \int_set:Nn \l_my_int { 4 } -% \int_eval:n { \l_my_tl + \l_my_int * 3 - ( 3 + 4 * 5 ) } -% \end{verbatim} -% evaluate to $-6$ because \cs[no-index]{l_my_tl} expands to the -% integer denotation~|5|. As the \meta{int expr} is fully -% expanded from left to right during evaluation, fully expandable and -% restricted-expandable functions can both be used, and \cs{exp_not:n} -% and its variants have no effect while \cs{exp_not:N} may incorrectly -% interrupt the expression. -% \begin{texnote} -% Exactly two expansions are needed to evaluate \cs{int_eval:n}. -% The result is \emph{not} an \meta{internal integer}, and therefore -% requires suitable termination if used in a \TeX{}-style integer -% assignment. -% -% As all \TeX{} integers, integer operands can also be dimension or -% skip variables, converted to integers in~\texttt{sp}, or octal -% numbers given as \texttt{'} followed by digits other than -% \texttt{8} and \texttt{9}, or hexadecimal numbers given as -% |"| followed by digits or upper case letters from -% \texttt{A} to~\texttt{F}, or the character code of some character -% or one-character control sequence, given as \texttt{`}\meta{char}. -% \end{texnote} -% \end{function} -% -% \begin{function}[EXP, added = 2018-03-30]{\int_eval:w} -% \begin{syntax} -% \cs{int_eval:w} \meta{int expr} -% \end{syntax} -% Evaluates the \meta{int expr} as described for -% \cs{int_eval:n}. The end of the expression is the first token -% encountered that cannot form part of such an expression. If that -% token is \cs{scan_stop:} it is removed, otherwise not. Spaces do -% \emph{not} terminate the expression. However, spaces terminate -% explict integers, and this may terminate the expression: for -% instance, \cs{int_eval:w} \verb*|1 + 1 9| (with explicit space -% tokens inserted using |~| in a code setting) expands to \texttt{29} -% since the digit~\texttt{9} is not part of the expression. Expansion -% details, etc., are as given for \cs{int_eval:n}. -% \end{function} -% -% \begin{function}[EXP, added = 2018-11-03]{\int_sign:n} -% \begin{syntax} -% \cs{int_sign:n} \Arg{int expr} -% \end{syntax} -% Evaluates the \meta{int expr} then leaves $1$ or $0$ or -% $-1$ in the input stream according to the sign of the result. -% \end{function} -% -% \begin{function}[EXP, updated = 2012-09-26]{\int_abs:n} -% \begin{syntax} -% \cs{int_abs:n} \Arg{int expr} -% \end{syntax} -% Evaluates the \meta{int expr} as described for -% \cs{int_eval:n} and leaves the absolute value of the result in -% the input stream as an \meta{integer denotation} after two -% expansions. -% \end{function} -% -% \begin{function}[EXP, updated = 2012-09-26]{\int_div_round:nn} -% \begin{syntax} -% \cs{int_div_round:nn} \Arg{int expr_1} \Arg{int expr_2} -% \end{syntax} -% Evaluates the two \meta{int expr}s as described earlier, -% then divides the first value by the second, and rounds the result -% to the closest integer. Ties are rounded away from zero. -% Note that this is identical to using -% |/| directly in an \meta{int expr}. The result is left in -% the input stream as an \meta{integer denotation} after two expansions. -% \end{function} -% -% \begin{function}[EXP, updated = 2012-02-09]{\int_div_truncate:nn} -% \begin{syntax} -% \cs{int_div_truncate:nn} \Arg{int expr_1} \Arg{int expr_2} -% \end{syntax} -% Evaluates the two \meta{int expr}s as described earlier, -% then divides the first value by the second, and rounds the result -% towards zero. Note that division using |/| -% rounds to the closest integer instead. -% The result is left in the input stream as an -% \meta{integer denotation} after two expansions. -% \end{function} -% -% \begin{function}[EXP, updated = 2012-09-26]{\int_max:nn, \int_min:nn} -% \begin{syntax} -% \cs{int_max:nn} \Arg{int expr_1} \Arg{int expr_2} -% \cs{int_min:nn} \Arg{int expr_1} \Arg{int expr_2} -% \end{syntax} -% Evaluates the \meta{int expr}s as described for -% \cs{int_eval:n} and leaves either the larger or smaller value -% in the input stream as an \meta{integer denotation} after two -% expansions. -% \end{function} -% -% \begin{function}[EXP, updated = 2012-09-26]{\int_mod:nn} -% \begin{syntax} -% \cs{int_mod:nn} \Arg{int expr_1} \Arg{int expr_2} -% \end{syntax} -% Evaluates the two \meta{int expr}s as described earlier, -% then calculates the integer remainder of dividing the first -% expression by the second. This is obtained by subtracting -% \cs{int_div_truncate:nn} \Arg{int expr_1} \Arg{int expr_2} times -% \meta{int expr_2} from \meta{int expr_1}. Thus, the result has the -% same sign as \meta{int expr_1} and its absolute value is strictly -% less than that of \meta{int expr_2}. The result is left in the input -% stream as an \meta{integer denotation} after two expansions. -% \end{function} -% -% \section{Creating and initialising integers} -% -% \begin{function}{\int_new:N, \int_new:c} -% \begin{syntax} -% \cs{int_new:N} \meta{integer} -% \end{syntax} -% Creates a new \meta{integer} or raises an error if the name is -% already taken. The declaration is global. The \meta{integer} is -% initially equal to $0$. -% \end{function} -% -% \begin{function}[updated = 2011-10-22]{\int_const:Nn, \int_const:cn} -% \begin{syntax} -% \cs{int_const:Nn} \meta{integer} \Arg{int expr} -% \end{syntax} -% Creates a new constant \meta{integer} or raises an error if the name -% is already taken. The value of the \meta{integer} is set -% globally to the \meta{int expr}. -% \end{function} -% -% \begin{function}{\int_zero:N, \int_zero:c, \int_gzero:N, \int_gzero:c} -% \begin{syntax} -% \cs{int_zero:N} \meta{integer} -% \end{syntax} -% Sets \meta{integer} to $0$. -% \end{function} -% -% \begin{function}[added = 2011-12-13] -% {\int_zero_new:N, \int_zero_new:c, \int_gzero_new:N, \int_gzero_new:c} -% \begin{syntax} -% \cs{int_zero_new:N} \meta{integer} -% \end{syntax} -% Ensures that the \meta{integer} exists globally by applying -% \cs{int_new:N} if necessary, then applies -% \cs[index=int_zero:N]{int_(g)zero:N} to leave -% the \meta{integer} set to zero. -% \end{function} -% -% \begin{function} -% { -% \int_set_eq:NN, \int_set_eq:cN, \int_set_eq:Nc, \int_set_eq:cc, -% \int_gset_eq:NN, \int_gset_eq:cN, \int_gset_eq:Nc, \int_gset_eq:cc -% } -% \begin{syntax} -% \cs{int_set_eq:NN} \meta{integer_1} \meta{integer_2} -% \end{syntax} -% Sets the content of \meta{integer_1} equal to that of -% \meta{integer_2}. -% \end{function} -% -% \begin{function}[EXP, pTF, added=2012-03-03] -% {\int_if_exist:N, \int_if_exist:c} -% \begin{syntax} -% \cs{int_if_exist_p:N} \meta{int} -% \cs{int_if_exist:NTF} \meta{int} \Arg{true code} \Arg{false code} -% \end{syntax} -% Tests whether the \meta{int} is currently defined. This does not -% check that the \meta{int} really is an integer variable. -% \end{function} -% -% \section{Setting and incrementing integers} -% -% \begin{function}[updated = 2011-10-22] -% {\int_add:Nn, \int_add:cn, \int_gadd:Nn, \int_gadd:cn} -% \begin{syntax} -% \cs{int_add:Nn} \meta{integer} \Arg{int expr} -% \end{syntax} -% Adds the result of the \meta{int expr} to the current -% content of the \meta{integer}. -% \end{function} -% -% \begin{function}{\int_decr:N, \int_decr:c, \int_gdecr:N, \int_gdecr:c} -% \begin{syntax} -% \cs{int_decr:N} \meta{integer} -% \end{syntax} -% Decreases the value stored in \meta{integer} by $1$. -% \end{function} -% -% \begin{function}{\int_incr:N, \int_incr:c, \int_gincr:N, \int_gincr:c} -% \begin{syntax} -% \cs{int_incr:N} \meta{integer} -% \end{syntax} -% Increases the value stored in \meta{integer} by $1$. -% \end{function} -% -% \begin{function}[updated = 2011-10-22] -% {\int_set:Nn, \int_set:cn, \int_gset:Nn, \int_gset:cn} -% \begin{syntax} -% \cs{int_set:Nn} \meta{integer} \Arg{int expr} -% \end{syntax} -% Sets \meta{integer} to the value of \meta{int expr}, -% which must evaluate to an integer (as described for -% \cs{int_eval:n}). -% \end{function} -% -% \begin{function}[updated = 2011-10-22] -% {\int_sub:Nn, \int_sub:cn, \int_gsub:Nn, \int_gsub:cn} -% \begin{syntax} -% \cs{int_sub:Nn} \meta{integer} \Arg{int expr} -% \end{syntax} -% Subtracts the result of the \meta{int expr} from the -% current content of the \meta{integer}. -% \end{function} -% -% \section{Using integers} -% -% \begin{function}[updated = 2011-10-22, EXP]{\int_use:N, \int_use:c} -% \begin{syntax} -% \cs{int_use:N} \meta{integer} -% \end{syntax} -% Recovers the content of an \meta{integer} and places it directly -% in the input stream. An error is raised if the variable does -% not exist or if it is invalid. Can be omitted in places where an -% \meta{integer} is required (such as in the first and third arguments -% of \cs{int_compare:nNnTF}). -% \begin{texnote} -% \cs{int_use:N} is the \TeX{} primitive \tn{the}: this is one of -% several \LaTeX3 names for this primitive. -% \end{texnote} -% \end{function} -% -% \section{Integer expression conditionals} -% -% \begin{function}[EXP,pTF]{\int_compare:nNn} -% \begin{syntax} -% \cs{int_compare_p:nNn} \Arg{int expr_1} \meta{relation} \Arg{int expr_2} \\ -% \cs{int_compare:nNnTF} -% ~~\Arg{int expr_1} \meta{relation} \Arg{int expr_2} -% ~~\Arg{true code} \Arg{false code} -% \end{syntax} -% This function first evaluates each of the \meta{int expr}s -% as described for \cs{int_eval:n}. The two results are then -% compared using the \meta{relation}: -% \begin{center} -% \begin{tabular}{ll} -% Equal & |=| \\ -% Greater than & |>| \\ -% Less than & |<| \\ -% \end{tabular} -% \end{center} -% This function is less flexible than \cs{int_compare:nTF} but around -% $5$~times faster. -% \end{function} -% -% \begin{function}[updated = 2013-01-13, EXP, pTF]{\int_compare:n} -% \begin{syntax} -% \cs{int_compare_p:n} \\ -% ~~\{ \\ -% ~~~~\meta{int expr_1} \meta{relation_1} \\ -% ~~~~\ldots{} \\ -% ~~~~\meta{int expr_N} \meta{relation_N} \\ -% ~~~~\meta{int expr_{N+1}} \\ -% ~~\} \\ -% \cs{int_compare:nTF} -% ~~\{ \\ -% ~~~~\meta{int expr_1} \meta{relation_1} \\ -% ~~~~\ldots{} \\ -% ~~~~\meta{int expr_N} \meta{relation_N} \\ -% ~~~~\meta{int expr_{N+1}} \\ -% ~~\} \\ -% ~~\Arg{true code} \Arg{false code} -% \end{syntax} -% This function evaluates the \meta{int expr}s as described -% for \cs{int_eval:n} and compares consecutive result using the -% corresponding \meta{relation}, namely it compares \meta{int expr_1} -% and \meta{int expr_2} using the \meta{relation_1}, then -% \meta{int expr_2} and \meta{int expr_3} using the \meta{relation_2}, -% until finally comparing \meta{int expr_N} and \meta{int expr_{N+1}} -% using the \meta{relation_N}. The test yields \texttt{true} if all -% comparisons are \texttt{true}. Each \meta{int expr} is -% evaluated only once, and the evaluation is lazy, in the sense that -% if one comparison is \texttt{false}, then no other \meta{integer -% expression} is evaluated and no other comparison is performed. -% The \meta{relations} can be any of the following: -% \begin{center} -% \begin{tabular}{ll} -% Equal & |=| or |==| \\ -% Greater than or equal to & |>=| \\ -% Greater than & |>| \\ -% Less than or equal to & |<=| \\ -% Less than & |<| \\ -% Not equal & |!=| \\ -% \end{tabular} -% \end{center} -% This function is more flexible than \cs{int_compare:nNnTF} but -% around $5$~times slower. -% \end{function} -% -% \begin{function}[added = 2013-07-24, EXP, noTF]{\int_case:nn} -% \begin{syntax} -% \cs{int_case:nnTF} \Arg{test int expr} \\ -% ~~|{| \\ -% ~~~~\Arg{int expr case_1} \Arg{code case_1} \\ -% ~~~~\Arg{int expr case_2} \Arg{code case_2} \\ -% ~~~~\ldots \\ -% ~~~~\Arg{int expr case_n} \Arg{code case_n} \\ -% ~~|}| \\ -% ~~\Arg{true code} -% ~~\Arg{false code} -% \end{syntax} -% This function evaluates the \meta{test int expr} and -% compares this in turn to each of the -% \meta{int expr cases}. If the two are equal then the -% associated \meta{code} is left in the input stream -% and other cases are discarded. If any of the -% cases are matched, the \meta{true code} is also inserted into the -% input stream (after the code for the appropriate case), while if none -% match then the \meta{false code} is inserted. The function -% \cs{int_case:nn}, which does nothing if there is no match, is also -% available. For example -% \begin{verbatim} -% \int_case:nnF -% { 2 * 5 } -% { -% { 5 } { Small } -% { 4 + 6 } { Medium } -% { -2 * 10 } { Negative } -% } -% { No idea! } -% \end{verbatim} -% leaves \enquote{\texttt{Medium}} in the input stream. -% \end{function} -% -% \begin{function}[EXP,pTF]{\int_if_even:n, \int_if_odd:n} -% \begin{syntax} -% \cs{int_if_odd_p:n} \Arg{int expr} -% \cs{int_if_odd:nTF} \Arg{int expr} -% ~~\Arg{true code} \Arg{false code} -% \end{syntax} -% This function first evaluates the \meta{int expr} -% as described for \cs{int_eval:n}. It then evaluates if this -% is odd or even, as appropriate. -% \end{function} -% -% \begin{function}[EXP,pTF, added = 2023-05-17]{\int_if_zero:n} -% \begin{syntax} -% \cs{int_if_zero_p:n} \Arg{int expr} -% \cs{int_if_zero:nTF} \Arg{int expr} -% ~~\Arg{true code} \Arg{false code} -% \end{syntax} -% This function first evaluates the \meta{int expr} -% as described for \cs{int_eval:n}. It then evaluates if this -% is zero or not. -% \end{function} -% -% \section{Integer expression loops} -% -% \begin{function}[rEXP]{\int_do_until:nNnn} -% \begin{syntax} -% \cs{int_do_until:nNnn} \Arg{int expr_1} \meta{relation} \Arg{int expr_2} \Arg{code} -% \end{syntax} -% Places the \meta{code} in the input stream for \TeX{} to process, and -% then evaluates the relationship between the two -% \meta{int expr}s as described for \cs{int_compare:nNnTF}. -% If the test is \texttt{false} then the \meta{code} is inserted -% into the input stream again and a loop occurs until the -% \meta{relation} is \texttt{true}. -% \end{function} -% -% \begin{function}[rEXP]{\int_do_while:nNnn} -% \begin{syntax} -% \cs{int_do_while:nNnn} \Arg{int expr_1} \meta{relation} \Arg{int expr_2} \Arg{code} -% \end{syntax} -% Places the \meta{code} in the input stream for \TeX{} to process, and -% then evaluates the relationship between the two -% \meta{int expr}s as described for \cs{int_compare:nNnTF}. -% If the test is \texttt{true} then the \meta{code} is inserted -% into the input stream again and a loop occurs until the -% \meta{relation} is \texttt{false}. -% \end{function} -% -% \begin{function}[rEXP]{\int_until_do:nNnn} -% \begin{syntax} -% \cs{int_until_do:nNnn} \Arg{int expr_1} \meta{relation} \Arg{int expr_2} \Arg{code} -% \end{syntax} -% Evaluates the relationship between the two \meta{int expr}s -% as described for \cs{int_compare:nNnTF}, and then places the -% \meta{code} in the input stream if the \meta{relation} is -% \texttt{false}. After the \meta{code} has been processed by \TeX{} the -% test is repeated, and a loop occurs until the test is -% \texttt{true}. -% \end{function} -% -% \begin{function}[rEXP]{\int_while_do:nNnn} -% \begin{syntax} -% \cs{int_while_do:nNnn} \Arg{int expr_1} \meta{relation} \Arg{int expr_2} \Arg{code} -% \end{syntax} -% Evaluates the relationship between the two \meta{int expr}s -% as described for \cs{int_compare:nNnTF}, and then places the -% \meta{code} in the input stream if the \meta{relation} is -% \texttt{true}. After the \meta{code} has been processed by \TeX{} the -% test is repeated, and a loop occurs until the test is -% \texttt{false}. -% \end{function} -% -% \begin{function}[updated = 2013-01-13, rEXP]{\int_do_until:nn} -% \begin{syntax} -% \cs{int_do_until:nn} \Arg{integer relation} \Arg{code} -% \end{syntax} -% Places the \meta{code} in the input stream for \TeX{} to process, and -% then evaluates the \meta{integer relation} -% as described for \cs{int_compare:nTF}. -% If the test is \texttt{false} then the \meta{code} is inserted -% into the input stream again and a loop occurs until the -% \meta{relation} is \texttt{true}. -% \end{function} -% -% \begin{function}[updated = 2013-01-13, rEXP]{\int_do_while:nn} -% \begin{syntax} -% \cs{int_do_while:nn} \Arg{integer relation} \Arg{code} -% \end{syntax} -% Places the \meta{code} in the input stream for \TeX{} to process, and -% then evaluates the \meta{integer relation} -% as described for \cs{int_compare:nTF}. -% If the test is \texttt{true} then the \meta{code} is inserted -% into the input stream again and a loop occurs until the -% \meta{relation} is \texttt{false}. -% \end{function} -% -% \begin{function}[updated = 2013-01-13, rEXP]{\int_until_do:nn} -% \begin{syntax} -% \cs{int_until_do:nn} \Arg{integer relation} \Arg{code} -% \end{syntax} -% Evaluates the \meta{integer relation} -% as described for \cs{int_compare:nTF}, and then places the -% \meta{code} in the input stream if the \meta{relation} is -% \texttt{false}. After the \meta{code} has been processed by \TeX{} the -% test is repeated, and a loop occurs until the test is -% \texttt{true}. -% \end{function} -% -% \begin{function}[updated = 2013-01-13, rEXP]{\int_while_do:nn} -% \begin{syntax} -% \cs{int_while_do:nn} \Arg{integer relation} \Arg{code} -% \end{syntax} -% Evaluates the \meta{integer relation} -% as described for \cs{int_compare:nTF}, and then places the -% \meta{code} in the input stream if the \meta{relation} is -% \texttt{true}. After the \meta{code} has been processed by \TeX{} the -% test is repeated, and a loop occurs until the test is -% \texttt{false}. -% \end{function} -% -% \section{Integer step functions} -% -% \begin{function}[added = 2012-06-04, updated = 2018-04-22, rEXP] -% {\int_step_function:nN, \int_step_function:nnN, \int_step_function:nnnN} -% \begin{syntax} -% \cs{int_step_function:nN} \Arg{final value} \meta{function} -% \cs{int_step_function:nnN} \Arg{initial value} \Arg{final value} \meta{function} -% \cs{int_step_function:nnnN} \Arg{initial value} \Arg{step} \Arg{final value} \meta{function} -% \end{syntax} -% This function first evaluates the \meta{initial value}, \meta{step} -% and \meta{final value}, all of which should be integer expressions. -% The \meta{function} is then placed in front of each \meta{value} -% from the \meta{initial value} to the \meta{final value} in turn -% (using \meta{step} between each \meta{value}). The \meta{step} must -% be non-zero. If the \meta{step} is positive, the loop stops when -% the \meta{value} becomes larger than the \meta{final value}. If the -% \meta{step} is negative, the loop stops when the \meta{value} -% becomes smaller than the \meta{final value}. The \meta{function} -% should absorb one numerical argument. For example -% \begin{verbatim} -% \cs_set:Npn \my_func:n #1 { [I~saw~#1] \quad } -% \int_step_function:nnnN { 1 } { 1 } { 5 } \my_func:n -% \end{verbatim} -% would print -% \begin{quote} -% [I saw 1] \quad -% [I saw 2] \quad -% [I saw 3] \quad -% [I saw 4] \quad -% [I saw 5] \quad -% \end{quote} -% -% The functions \cs{int_step_function:nN} and \cs{int_step_function:nnN} -% both use a fixed \meta{step} of $1$, and in the case of -% \cs{int_step_function:nN} the \meta{initial value} is also fixed as -% $1$. These functions are provided as simple short-cuts for code clarity. -% \end{function} -% -% \begin{function}[added = 2012-06-04, updated = 2018-04-22] -% {\int_step_inline:nn, \int_step_inline:nnn, \int_step_inline:nnnn} -% \begin{syntax} -% \cs{int_step_inline:nn} \Arg{final value} \Arg{code} -% \cs{int_step_inline:nnn} \Arg{initial value} \Arg{final value} \Arg{code} -% \cs{int_step_inline:nnnn} \Arg{initial value} \Arg{step} \Arg{final value} \Arg{code} -% \end{syntax} -% This function first evaluates the \meta{initial value}, \meta{step} -% and \meta{final value}, all of which should be integer expressions. -% Then for each \meta{value} from the \meta{initial value} to the -% \meta{final value} in turn (using \meta{step} between each -% \meta{value}), the \meta{code} is inserted into the input stream -% with |#1| replaced by the current \meta{value}. Thus the -% \meta{code} should define a function of one argument~(|#1|). -% -% The functions \cs{int_step_inline:nn} and \cs{int_step_inline:nnn} -% both use a fixed \meta{step} of $1$, and in the case of -% \cs{int_step_inline:nn} the \meta{initial value} is also fixed as -% $1$. These functions are provided as simple short-cuts for code clarity. -% \end{function} -% -% \begin{function}[added = 2012-06-04, updated = 2018-04-22] -% {\int_step_variable:nNn, \int_step_variable:nnNn, \int_step_variable:nnnNn} -% \begin{syntax} -% \cs{int_step_variable:nNn} \Arg{final value} \meta{tl~var} \Arg{code} -% \cs{int_step_variable:nnNn} \Arg{initial value} \Arg{final value} \meta{tl~var} \Arg{code} -% \cs{int_step_variable:nnnNn} \Arg{initial value} \Arg{step} \Arg{final value} \meta{tl~var} \Arg{code} -% \end{syntax} -% This function first evaluates the \meta{initial value}, \meta{step} -% and \meta{final value}, all of which should be integer expressions. -% Then for each \meta{value} from the \meta{initial value} to the -% \meta{final value} in turn (using \meta{step} between each -% \meta{value}), the \meta{code} is inserted into the input stream, -% with the \meta{tl~var} defined as the current \meta{value}. Thus -% the \meta{code} should make use of the \meta{tl~var}. -% -% The functions \cs{int_step_variable:nNn} and \cs{int_step_variable:nnNn} -% both use a fixed \meta{step} of $1$, and in the case of -% \cs{int_step_variable:nNn} the \meta{initial value} is also fixed as -% $1$. These functions are provided as simple short-cuts for code clarity. -% \end{function} -% -% \section{Formatting integers} -% -% Integers can be placed into the output stream with formatting. These -% conversions apply to any integer expressions. -% -% \begin{function}[updated = 2011-10-22, EXP]{\int_to_arabic:n, \int_to_arabic:v} -% \begin{syntax} -% \cs{int_to_arabic:n} \Arg{int expr} -% \end{syntax} -% Places the value of the \meta{int expr} in the input -% stream as digits, with category code $12$ (other). -% \end{function} -% -% \begin{function}[updated = 2011-09-17, EXP]{\int_to_alph:n, \int_to_Alph:n} -% \begin{syntax} -% \cs{int_to_alph:n} \Arg{int expr} -% \end{syntax} -% Evaluates the \meta{int expr} and converts the result -% into a series of letters, which are then left in the input stream. -% The conversion rule uses the $26$ letters of the English -% alphabet, in order, adding letters when necessary to increase the total -% possible range of representable numbers. Thus -% \begin{verbatim} -% \int_to_alph:n { 1 } -% \end{verbatim} -% places |a| in the input stream, -% \begin{verbatim} -% \int_to_alph:n { 26 } -% \end{verbatim} -% is represented as |z| and -% \begin{verbatim} -% \int_to_alph:n { 27 } -% \end{verbatim} -% is converted to |aa|. For conversions using other alphabets, use -% \cs{int_to_symbols:nnn} to define an alphabet-specific -% function. The basic \cs{int_to_alph:n} and \cs{int_to_Alph:n} -% functions should not be modified. -% The resulting tokens are digits with category code $12$ (other) and -% letters with category code $11$ (letter). -% \end{function} -% -% \begin{function}[updated = 2011-09-17, EXP]{\int_to_symbols:nnn} -% \begin{syntax} -% \cs{int_to_symbols:nnn} -% ~~\Arg{int expr} \Arg{total symbols} -% ~~\Arg{value to symbol mapping} -% \end{syntax} -% This is the low-level function for conversion of an -% \meta{int expr} into a symbolic form (often -% letters). The \meta{total symbols} available should be given -% as an integer expression. Values are actually converted to symbols -% according to the \meta{value to symbol mapping}. This should be given -% as \meta{total symbols} pairs of entries, a number and the -% appropriate symbol. Thus the \cs{int_to_alph:n} function is defined -% as -% \begin{verbatim} -% \cs_new:Npn \int_to_alph:n #1 -% { -% \int_to_symbols:nnn {#1} { 26 } -% { -% { 1 } { a } -% { 2 } { b } -% ... -% { 26 } { z } -% } -% } -% \end{verbatim} -% \end{function} -% -% \begin{function}[added = 2014-02-11, EXP]{\int_to_bin:n} -% \begin{syntax} -% \cs{int_to_bin:n} \Arg{int expr} -% \end{syntax} -% Calculates the value of the \meta{int expr} and places -% the binary representation of the result in the input stream. -% \end{function} -% -% \begin{function}[added = 2014-02-11, EXP]{\int_to_hex:n, \int_to_Hex:n} -% \begin{syntax} -% \cs{int_to_hex:n} \Arg{int expr} -% \end{syntax} -% Calculates the value of the \meta{int expr} and places -% the hexadecimal (base~$16$) representation of the result in the -% input stream. Letters are used for digits beyond~$9$: lower -% case letters for \cs{int_to_hex:n} and upper case ones for -% \cs{int_to_Hex:n}. -% The resulting tokens are digits with category code $12$ (other) and -% letters with category code $11$ (letter). -% \end{function} -% -% \begin{function}[added = 2014-02-11, EXP]{\int_to_oct:n} -% \begin{syntax} -% \cs{int_to_oct:n} \Arg{int expr} -% \end{syntax} -% Calculates the value of the \meta{int expr} and places -% the octal (base~$8$) representation of the result in the input -% stream. -% The resulting tokens are digits with category code $12$ (other) and -% letters with category code $11$ (letter). -% \end{function} -% -% \begin{function}[updated = 2014-02-11, EXP] -% {\int_to_base:nn, \int_to_Base:nn} -% \begin{syntax} -% \cs{int_to_base:nn} \Arg{int expr} \Arg{base} -% \end{syntax} -% Calculates the value of the \meta{int expr} and -% converts it into the appropriate representation in the \meta{base}; -% the later may be given as an integer expression. For bases greater -% than $10$ the higher \enquote{digits} are represented by -% letters from the English alphabet: lower -% case letters for \cs{int_to_base:n} and upper case ones for -% \cs{int_to_Base:n}. -% The maximum \meta{base} value is $36$. -% The resulting tokens are digits with category code $12$ (other) and -% letters with category code $11$ (letter). -% \begin{texnote} -% This is a generic version of \cs{int_to_bin:n}, \emph{etc.} -% \end{texnote} -% \end{function} -% -% \begin{function}[updated = 2011-10-22, rEXP]{\int_to_roman:n, \int_to_Roman:n} -% \begin{syntax} -% \cs{int_to_roman:n} \Arg{int expr} -% \end{syntax} -% Places the value of the \meta{int expr} in the input -% stream as Roman numerals, either lower case (\cs{int_to_roman:n}) or -% upper case (\cs{int_to_Roman:n}). If the value is negative or zero, -% the output is empty. The Roman numerals are letters with category -% code $11$ (letter). The letters used are |mdclxvi|, repeated as -% needed: the notation with bars (such as $\bar{\mbox{v}}$ for $5000$) -% is \emph{not} used. For instance \cs{int_to_roman:n} |{| 8249 |}| -% expands to |mmmmmmmmccxlix|. -% \end{function} -% -% \section{Converting from other formats to integers} -% -% \begin{function}[updated = 2014-08-25, EXP]{\int_from_alph:n} -% \begin{syntax} -% \cs{int_from_alph:n} \Arg{letters} -% \end{syntax} -% Converts the \meta{letters} into the integer (base~$10$) -% representation and leaves this in the input stream. The -% \meta{letters} are first converted to a string, with no expansion. -% Lower and upper case letters from the English alphabet may be used, -% with \enquote{a} equal to $1$ through to \enquote{z} equal to $26$. -% The function also accepts a leading sign, made of |+| and~|-|. This -% is the inverse function of \cs{int_to_alph:n} and -% \cs{int_to_Alph:n}. -% \end{function} -% -% \begin{function}[added = 2014-02-11, updated = 2014-08-25, EXP] -% {\int_from_bin:n} -% \begin{syntax} -% \cs{int_from_bin:n} \Arg{binary number} -% \end{syntax} -% Converts the \meta{binary number} into the integer (base~$10$) -% representation and leaves this in the input stream. -% The \meta{binary number} is first converted to a string, with no -% expansion. The function accepts a leading sign, made of |+| -% and~|-|, followed by binary digits. This is the inverse function -% of \cs{int_to_bin:n}. -% \end{function} -% -% \begin{function}[added = 2014-02-11, updated = 2014-08-25, EXP] -% {\int_from_hex:n} -% \begin{syntax} -% \cs{int_from_hex:n} \Arg{hexadecimal number} -% \end{syntax} -% Converts the \meta{hexadecimal number} into the integer (base~$10$) -% representation and leaves this in the input stream. Digits greater -% than $9$ may be represented in the \meta{hexadecimal number} by -% upper or lower case letters. The \meta{hexadecimal number} is first -% converted to a string, with no expansion. The function also accepts -% a leading sign, made of |+| and~|-|. This is the inverse function -% of \cs{int_to_hex:n} and \cs{int_to_Hex:n}. -% \end{function} -% -% \begin{function}[added = 2014-02-11, updated = 2014-08-25, EXP] -% {\int_from_oct:n} -% \begin{syntax} -% \cs{int_from_oct:n} \Arg{octal number} -% \end{syntax} -% Converts the \meta{octal number} into the integer (base~$10$) -% representation and leaves this in the input stream. -% The \meta{octal number} is first converted to a string, with no -% expansion. The function accepts a leading sign, made of |+| -% and~|-|, followed by octal digits. This is the inverse function -% of \cs{int_to_oct:n}. -% \end{function} -% -% \begin{function}[updated = 2014-08-25, updated = 2014-08-25, EXP] -% {\int_from_roman:n} -% \begin{syntax} -% \cs{int_from_roman:n} \Arg{roman numeral} -% \end{syntax} -% Converts the \meta{roman numeral} into the integer (base~$10$) -% representation and leaves this in the input stream. The \meta{roman -% numeral} is first converted to a string, with no expansion. The -% \meta{roman numeral} may be in upper or lower case; if the numeral -% contains characters besides |mdclxvi| or |MDCLXVI| then the -% resulting value is $-1$. This is the inverse function of -% \cs{int_to_roman:n} and \cs{int_to_Roman:n}. -% \end{function} -% -% \begin{function}[updated = 2014-08-25, EXP]{\int_from_base:nn} -% \begin{syntax} -% \cs{int_from_base:nn} \Arg{number} \Arg{base} -% \end{syntax} -% Converts the \meta{number} expressed in \meta{base} into the -% appropriate value in base $10$. The \meta{number} is first -% converted to a string, with no expansion. The \meta{number} should -% consist of digits and letters (either lower or upper case), plus -% optionally a leading sign. The maximum \meta{base} value is $36$. -% This is the inverse function of \cs{int_to_base:nn} and -% \cs{int_to_Base:nn}. -% \end{function} -% -% \section{Random integers} -% -% \begin{function}[EXP, added = 2016-12-06, updated = 2018-04-27]{\int_rand:nn} -% \begin{syntax} -% \cs{int_rand:nn} \Arg{int expr_1} \Arg{int expr_2} -% \end{syntax} -% Evaluates the two \meta{int expr}s and produces a -% pseudo-random number between the two (with bounds included). -% This is not available in older versions of \XeTeX{}. -% \end{function} -% -% \begin{function}[EXP, added = 2018-05-05]{\int_rand:n} -% \begin{syntax} -% \cs{int_rand:n} \Arg{int expr} -% \end{syntax} -% Evaluates the \meta{int expr} then produces a -% pseudo-random number between $1$ and the \meta{int expr} (included). -% This is not available in older versions of \XeTeX{}. -% \end{function} -% -% \section{Viewing integers} -% -% \begin{function}{\int_show:N, \int_show:c} -% \begin{syntax} -% \cs{int_show:N} \meta{integer} -% \end{syntax} -% Displays the value of the \meta{integer} on the terminal. -% \end{function} -% -% \begin{function}[added = 2011-11-22, updated = 2015-08-07]{\int_show:n} -% \begin{syntax} -% \cs{int_show:n} \Arg{int expr} -% \end{syntax} -% Displays the result of evaluating the \meta{int expr} -% on the terminal. -% \end{function} -% -% \begin{function}[added = 2014-08-22, updated = 2015-08-03]{\int_log:N, \int_log:c} -% \begin{syntax} -% \cs{int_log:N} \meta{integer} -% \end{syntax} -% Writes the value of the \meta{integer} in the log file. -% \end{function} -% -% \begin{function}[added = 2014-08-22, updated = 2015-08-07]{\int_log:n} -% \begin{syntax} -% \cs{int_log:n} \Arg{int expr} -% \end{syntax} -% Writes the result of evaluating the \meta{int expr} -% in the log file. -% \end{function} -% -% \section{Constant integers} -% -% \begin{variable}[added = 2018-05-07]{\c_zero_int, \c_one_int} -% Integer values used with primitive tests and assignments: their -% self-terminating nature makes these more convenient and faster than -% literal numbers. -% \end{variable} -% -% \begin{variable}[module = int]{\c_max_int} -% The maximum value that can be stored as an integer. -% \end{variable} -% -% \begin{variable}[module = int]{\c_max_register_int} -% Maximum number of registers. -% \end{variable} -% -% \begin{variable}[module = int]{\c_max_char_int} -% Maximum character code completely supported by the engine. -% \end{variable} -% -% \section{Scratch integers} -% -% \begin{variable}{\l_tmpa_int, \l_tmpb_int} -% Scratch integer for local assignment. These are never used by -% the kernel code, and so are safe for use with any \LaTeX3-defined -% function. However, they may be overwritten by other non-kernel -% code and so should only be used for short-term storage. -% \end{variable} -% -% \begin{variable}{\g_tmpa_int, \g_tmpb_int} -% Scratch integer for global assignment. These are never used by -% the kernel code, and so are safe for use with any \LaTeX3-defined -% function. However, they may be overwritten by other non-kernel -% code and so should only be used for short-term storage. -% \end{variable} -% -% \section{Direct number expansion} -% -% \begin{function}[EXP, added = 2018-03-27]{\int_value:w} -% \begin{syntax} -% \cs{int_value:w} \meta{integer} -% \cs{int_value:w} \meta{integer denotation} \meta{optional space} -% \end{syntax} -% Expands the following tokens until an \meta{integer} is formed, and -% leaves a normalized form (no leading sign except for negative -% numbers, no leading digit~|0| except for zero) in the input stream -% as category code $12$ (other) characters. The \meta{integer} can -% consist of any number of signs (with intervening spaces) followed -% by -% \begin{itemize} -% \item an integer variable (in fact, any \TeX{} register except -% \tn{toks}) or -% \item explicit digits (or by |'|\meta{octal digits} or |"|\meta{hexadecimal digits} or |`|\meta{character}). -% \end{itemize} -% In this last case expansion stops once a non-digit is found; if that is a -% space it is removed as in \texttt{f}-expansion, and so \cs{exp_stop_f:} -% may be employed as an end marker. Note that protected functions -% \emph{are} expanded by this process. -% -% This function requires exactly one expansion to produce a value, and so -% is suitable for use in cases where a number is required \enquote{directly}. -% In general, \cs{int_eval:n} is the preferred approach to generating -% numbers. -% \begin{texnote} -% This is the \TeX{} primitive \tn{number}. -% \end{texnote} -% \end{function} -% -% \section{Primitive conditionals} -% -% \begin{function}[EXP]{\if_int_compare:w} -% \begin{syntax} -% \cs{if_int_compare:w} \meta{integer_1} \meta{relation} \meta{integer_2} -% ~~\meta{true code} -% \cs{else:} -% ~~\meta{false code} -% \cs{fi:} -% \end{syntax} -% Compare two integers using \meta{relation}, which must be one of -% |=|, |<| or |>| with category code $12$. -% The \cs{else:} branch is optional. -% \begin{texnote} -% This is the \TeX{} primitive \tn{ifnum}. -% \end{texnote} -% \end{function} -% -% \begin{function}[EXP]{\if_case:w, \or:} -% \begin{syntax} -% \cs{if_case:w} \meta{integer} \meta{case_0} -% ~~\cs{or:} \meta{case_1} -% ~~\cs{or:} |...| -% ~~\cs{else:} \meta{default} -% \cs{fi:} -% \end{syntax} -% Selects a case to execute based on the value of the \meta{integer}. The -% first case (\meta{case_0}) is executed if \meta{integer} is $0$, the second -% (\meta{case_1}) if the \meta{integer} is $1$, \emph{etc.} The -% \meta{integer} may be a literal, a constant or an integer -% expression (\emph{e.g.}~using \cs{int_eval:n}). -% \begin{texnote} -% These are the \TeX{} primitives \tn{ifcase} and \tn{or}. -% \end{texnote} -% \end{function} -% -% \begin{function}[EXP]{\if_int_odd:w} -% \begin{syntax} -% \cs{if_int_odd:w} \meta{tokens} \meta{optional space} -% ~~\meta{true code} -% \cs{else:} -% ~~\meta{true code} -% \cs{fi:} -% \end{syntax} -% Expands \meta{tokens} until a non-numeric token or a space is found, and -% tests whether the resulting \meta{integer} is odd. If so, \meta{true code} -% is executed. The \cs{else:} branch is optional. -% \begin{texnote} -% This is the \TeX{} primitive \tn{ifodd}. -% \end{texnote} -% \end{function} -% -% \end{documentation} -% -% \begin{implementation} -% -% \section{\pkg{l3int} implementation} -% -% \begin{macrocode} -%<*package> -% \end{macrocode} -% -% \begin{macrocode} -%<@@=int> -% \end{macrocode} -% -% \TestFiles{m3int001,m3int002,m3int03} -% -% \begin{variable}{\c_max_register_int} -% Done in \pkg{l3basics}. -% \end{variable} -% -% \begin{macro}{\@@_to_roman:w} -% \begin{macro}{\if_int_compare:w} -% Done in \pkg{l3basics}. -% \end{macro} -% \end{macro} -% -% \begin{macro}{\or:} -% Done in \pkg{l3basics}. -% \end{macro} -% -% \begin{macro}{\int_value:w} -% \begin{macro}{\@@_eval:w} -% \begin{macro}{\@@_eval_end:} -% \begin{macro}{\if_int_odd:w} -% \begin{macro}{\if_case:w} -% Here are the remaining primitives for number comparisons and -% expressions. -% \begin{macrocode} -\cs_new_eq:NN \int_value:w \tex_number:D -\cs_new_eq:NN \@@_eval:w \tex_numexpr:D -\cs_new_eq:NN \@@_eval_end: \tex_relax:D -\cs_new_eq:NN \if_int_odd:w \tex_ifodd:D -\cs_new_eq:NN \if_case:w \tex_ifcase:D -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{variable}{\s_@@_mark,\s_@@_stop} -% Scan marks used throughout the module. -% \begin{macrocode} -\scan_new:N \s_@@_mark -\scan_new:N \s_@@_stop -% \end{macrocode} -% \end{variable} -% -% \begin{macro}[EXP]{\@@_use_none_delimit_by_s_stop:w} -% Function to gobble until a scan mark. -% \begin{macrocode} -\cs_new:Npn \@@_use_none_delimit_by_s_stop:w #1 \s_@@_stop { } -% \end{macrocode} -% \end{macro} -% -% \begin{variable}{\q_@@_recursion_tail,\q_@@_recursion_stop} -% Quarks for recursion. -% \begin{macrocode} -\quark_new:N \q_@@_recursion_tail -\quark_new:N \q_@@_recursion_stop -% \end{macrocode} -% \end{variable} -% -% \begin{macro}[EXP]{\@@_if_recursion_tail_stop_do:Nn,\@@_if_recursion_tail_stop:N} -% Functions to query quarks. -% \begin{macrocode} -\__kernel_quark_new_test:N \@@_if_recursion_tail_stop_do:Nn -\__kernel_quark_new_test:N \@@_if_recursion_tail_stop:N -% \end{macrocode} -% \end{macro} -% -% \subsection{Integer expressions} -% -% \begin{macro}{\int_eval:n} -% \begin{macro}{\int_eval:w} -% Wrapper for \cs{@@_eval:w}: can be used in an integer expression or -% directly in the input stream. It is very slightly faster to use -% \tn{the} rather than \tn{number} to turn the expression to a number. -% When debugging, we introduce parentheses to catch early termination (see \pkg{l3debug}). -% \begin{macrocode} -\cs_new:Npn \int_eval:n #1 - { \tex_the:D \@@_eval:w #1 \@@_eval_end: } -\cs_new:Npn \int_eval:w { \tex_the:D \@@_eval:w } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro}[EXP]{\int_sign:n, \@@_sign:Nw} -% See \cs{int_abs:n}. Evaluate the expression once (and when -% debugging is enabled, check that the expression is well-formed), -% then test the first character to determine the sign. This is -% wrapped in \cs{int_value:w} \ldots{} \cs{exp_stop_f:} to ensure a -% fixed number of expansions and to avoid dealing with closing the -% conditionals. -% \begin{macrocode} -\cs_new:Npn \int_sign:n #1 - { - \int_value:w \exp_after:wN \@@_sign:Nw - \int_value:w \@@_eval:w #1 \@@_eval_end: ; - \exp_stop_f: - } -\cs_new:Npn \@@_sign:Nw #1#2 ; - { - \if_meaning:w 0 #1 - 0 - \else: - \if_meaning:w - #1 - \fi: 1 - \fi: - } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}[EXP]{\int_abs:n} -% \begin{macro}[EXP]{\@@_abs:N} -% \UnitTested -% \begin{macro}[EXP]{\int_max:nn} -% \begin{macro}[EXP]{\int_min:nn} -% \begin{macro}[EXP]{\@@_maxmin:wwN} -% \UnitTested -% \UnitTested -% Functions for $\min$, $\max$, and absolute value with only one -% evaluation. The absolute value is obtained by removing a leading -% sign if any. All three functions expand in two steps. -% \begin{macrocode} -\cs_new:Npn \int_abs:n #1 - { - \int_value:w \exp_after:wN \@@_abs:N - \int_value:w \@@_eval:w #1 \@@_eval_end: - \exp_stop_f: - } -\cs_new:Npn \@@_abs:N #1 - { \if_meaning:w - #1 \else: \exp_after:wN #1 \fi: } -\cs_new:Npn \int_max:nn #1#2 - { - \int_value:w \exp_after:wN \@@_maxmin:wwN - \int_value:w \@@_eval:w #1 \exp_after:wN ; - \int_value:w \@@_eval:w #2 ; - > - \exp_stop_f: - } -\cs_new:Npn \int_min:nn #1#2 - { - \int_value:w \exp_after:wN \@@_maxmin:wwN - \int_value:w \@@_eval:w #1 \exp_after:wN ; - \int_value:w \@@_eval:w #2 ; - < - \exp_stop_f: - } -\cs_new:Npn \@@_maxmin:wwN #1 ; #2 ; #3 - { - \if_int_compare:w #1 #3 #2 ~ - #1 - \else: - #2 - \fi: - } -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macro}[EXP]{\int_div_truncate:nn} -% \UnitTested -% \begin{macro}[EXP]{\int_div_round:nn} -% \UnitTested -% \begin{macro}[EXP]{\int_mod:nn} -% \UnitTested -% \begin{macro}[EXP]{\@@_div_truncate:NwNw} -% \begin{macro}[EXP]{\@@_mod:ww} -% As \cs{@@_eval:w} rounds the result of a division we also provide a -% version that truncates the result. We use an auxiliary to make sure -% numerator and denominator are only evaluated once: this comes in -% handy when those are more expressions are expensive to evaluate -% (\emph{e.g.}, \cs{tl_count:n}). If the numerator |#1#2| is $0$, -% then we divide $0$ by the denominator (this ensures that $0/0$ is -% correctly reported as an error). Otherwise, shift the numerator -% |#1#2| towards $0$ by $(\left\vert\texttt{\#3\#4}\right\vert-1)/2$, which we -% round away from zero. It turns out that this quantity exactly -% compensates the difference between \eTeX{}'s rounding and the -% truncating behaviour that we want. The details are thanks to Heiko -% Oberdiek: getting things right in all cases is not so easy. -% \begin{macrocode} -\cs_new:Npn \int_div_truncate:nn #1#2 - { - \int_value:w \@@_eval:w - \exp_after:wN \@@_div_truncate:NwNw - \int_value:w \@@_eval:w #1 \exp_after:wN ; - \int_value:w \@@_eval:w #2 ; - \@@_eval_end: - } -\cs_new:Npn \@@_div_truncate:NwNw #1#2; #3#4; - { - \if_meaning:w 0 #1 - 0 - \else: - ( - #1#2 - \if_meaning:w - #1 + \else: - \fi: - ( \if_meaning:w - #3 - \fi: #3#4 - 1 ) / 2 - ) - \fi: - / #3#4 - } -% \end{macrocode} -% For the sake of completeness: -% \begin{macrocode} -\cs_new:Npn \int_div_round:nn #1#2 - { \int_value:w \@@_eval:w ( #1 ) / ( #2 ) \@@_eval_end: } -% \end{macrocode} -% Finally there's the modulus operation. -% \begin{macrocode} -\cs_new:Npn \int_mod:nn #1#2 - { - \int_value:w \@@_eval:w \exp_after:wN \@@_mod:ww - \int_value:w \@@_eval:w #1 \exp_after:wN ; - \int_value:w \@@_eval:w #2 ; - \@@_eval_end: - } -\cs_new:Npn \@@_mod:ww #1; #2; - { #1 - ( \@@_div_truncate:NwNw #1 ; #2 ; ) * #2 } -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macro}[EXP]{\__kernel_int_add:nnn} -% Equivalent to \cs{int_eval:n} |{#1+#2+#3}| except that overflow only -% occurs if the final result overflows $[-2^{31}+1,2^{31}-1]$. The -% idea is to choose the order in which the three numbers are added -% together. If |#1| and |#2| have opposite signs (one is in -% $[-2^{31}+1,-1]$ and the other in $[0,2^{31}-1]$) then |#1+#2| -% cannot overflow so we compute the result as |#1+#2+#3|. If they -% have the same sign, then either |#3| has the same sign and the order -% does not matter, or |#3| has the opposite sign and any order in -% which |#3| is not last will work. We use |#1+#3+#2|. -% \begin{macrocode} -\cs_new:Npn \__kernel_int_add:nnn #1#2#3 - { - \int_value:w \@@_eval:w #1 - \if_int_compare:w #2 < \c_zero_int \exp_after:wN \reverse_if:N \fi: - \if_int_compare:w #1 < \c_zero_int + #2 + #3 \else: + #3 + #2 \fi: - \@@_eval_end: - } -% \end{macrocode} -% \end{macro} -% -% \subsection{Creating and initialising integers} -% -% \begin{macro}{\int_new:N, \int_new:c} -% \UnitTested -% Two ways to do this: one for the format and one for the \LaTeXe{} -% package. In plain \TeX{}, \cs{newcount} (and other allocators) are -% \cs{outer}: to allow the code here to work in \enquote{generic} mode -% this is therefore accessed by name. (The same applies to \cs{newbox}, -% \cs{newdimen} and so on.) -% \begin{macrocode} -\cs_new_protected:Npn \int_new:N #1 - { - \__kernel_chk_if_free_cs:N #1 - \cs:w newcount \cs_end: #1 - } -\cs_generate_variant:Nn \int_new:N { c } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\int_const:Nn, \int_const:cn} -% \begin{macro}{\@@_const:nN, \@@_const:eN} -% \begin{macro}{\@@_constdef:Nw} -% \begin{variable}{\c_@@_max_constdef_int} -% \UnitTested -% As stated, most constants can be defined as \tn{chardef} or -% \tn{mathchardef} but that's engine dependent. As a result, there is some -% set up code to determine what can be done. No full engine testing just yet -% so everything is a little awkward. -% We cannot use \cs{int_gset:Nn} because (when |check-declarations| is -% enabled) this runs some checks that constants would fail. -% \begin{macrocode} -\cs_new_protected:Npn \int_const:Nn #1#2 - { \@@_const:eN { \int_eval:n {#2} } #1 } -\cs_generate_variant:Nn \int_const:Nn { c } -\cs_new_protected:Npn \@@_const:nN #1#2 - { - \int_compare:nNnTF {#1} < \c_zero_int - { - \int_new:N #2 - \tex_global:D - } - { - \int_compare:nNnTF {#1} > \c_@@_max_constdef_int - { - \int_new:N #2 - \tex_global:D - } - { - \__kernel_chk_if_free_cs:N #2 - \tex_global:D \@@_constdef:Nw - } - } - #2 = \@@_eval:w #1 \@@_eval_end: - } -\cs_generate_variant:Nn \@@_const:nN { e } -\if_int_odd:w 0 - \cs_if_exist:NT \tex_luatexversion:D { 1 } - \cs_if_exist:NT \tex_omathchardef:D { 1 } - \cs_if_exist:NT \tex_XeTeXversion:D { 1 } ~ - \cs_if_exist:NTF \tex_omathchardef:D - { \cs_new_eq:NN \@@_constdef:Nw \tex_omathchardef:D } - { \cs_new_eq:NN \@@_constdef:Nw \tex_chardef:D } - \tex_global:D \@@_constdef:Nw \c_@@_max_constdef_int 1114111 ~ -\else: - \cs_new_eq:NN \@@_constdef:Nw \tex_mathchardef:D - \tex_global:D \@@_constdef:Nw \c_@@_max_constdef_int 32767 ~ -\fi: -% \end{macrocode} -% \end{variable} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\int_zero:N, \int_zero:c} -% \UnitTested -% \begin{macro}{\int_gzero:N, \int_gzero:c} -% \UnitTested -% Functions that reset an \meta{integer} register to zero. -% \begin{macrocode} -\cs_new_protected:Npn \int_zero:N #1 { #1 = \c_zero_int } -\cs_new_protected:Npn \int_gzero:N #1 { \tex_global:D #1 = \c_zero_int } -\cs_generate_variant:Nn \int_zero:N { c } -\cs_generate_variant:Nn \int_gzero:N { c } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro} -% {\int_zero_new:N, \int_zero_new:c, \int_gzero_new:N, \int_gzero_new:c} -% Create a register if needed, otherwise clear it. -% \begin{macrocode} -\cs_new_protected:Npn \int_zero_new:N #1 - { \int_if_exist:NTF #1 { \int_zero:N #1 } { \int_new:N #1 } } -\cs_new_protected:Npn \int_gzero_new:N #1 - { \int_if_exist:NTF #1 { \int_gzero:N #1 } { \int_new:N #1 } } -\cs_generate_variant:Nn \int_zero_new:N { c } -\cs_generate_variant:Nn \int_gzero_new:N { c } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\int_set_eq:NN, \int_set_eq:cN, \int_set_eq:Nc, \int_set_eq:cc} -% \UnitTested -% \begin{macro} -% {\int_gset_eq:NN, \int_gset_eq:cN, \int_gset_eq:Nc, \int_gset_eq:cc} -% \UnitTested -% Setting equal means using one integer inside the set function of -% another. Check that assigned integer is local/global. No need to -% check that the other one is defined as \TeX{} does it for us. -% \begin{macrocode} -\cs_new_protected:Npn \int_set_eq:NN #1#2 { #1 = #2 } -\cs_generate_variant:Nn \int_set_eq:NN { c , Nc , cc } -\cs_new_protected:Npn \int_gset_eq:NN #1#2 { \tex_global:D #1 = #2 } -\cs_generate_variant:Nn \int_gset_eq:NN { c , Nc , cc } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro}[pTF]{\int_if_exist:N, \int_if_exist:c} -% Copies of the \texttt{cs} functions defined in \pkg{l3basics}. -% \begin{macrocode} -\prg_new_eq_conditional:NNn \int_if_exist:N \cs_if_exist:N - { TF , T , F , p } -\prg_new_eq_conditional:NNn \int_if_exist:c \cs_if_exist:c - { TF , T , F , p } -% \end{macrocode} -% \end{macro} -% -% \subsection{Setting and incrementing integers} -% -% \begin{macro}{\int_add:Nn, \int_add:cn} -% \UnitTested -% \begin{macro}{\int_gadd:Nn, \int_gadd:cn} -% \UnitTested -% \begin{macro}{\int_sub:Nn, \int_sub:cn} -% \UnitTested -% \begin{macro}{\int_gsub:Nn, \int_gsub:cn} -% \UnitTested -% Adding and subtracting to and from a counter. -% Including here the optional |by| would slow down these operations -% by a few percent. -% \begin{macrocode} -\cs_new_protected:Npn \int_add:Nn #1#2 - { \tex_advance:D #1 \@@_eval:w #2 \@@_eval_end: } -\cs_new_protected:Npn \int_sub:Nn #1#2 - { \tex_advance:D #1 - \@@_eval:w #2 \@@_eval_end: } -\cs_new_protected:Npn \int_gadd:Nn #1#2 - { \tex_global:D \tex_advance:D #1 \@@_eval:w #2 \@@_eval_end: } -\cs_new_protected:Npn \int_gsub:Nn #1#2 - { \tex_global:D \tex_advance:D #1 - \@@_eval:w #2 \@@_eval_end: } -\cs_generate_variant:Nn \int_add:Nn { c } -\cs_generate_variant:Nn \int_gadd:Nn { c } -\cs_generate_variant:Nn \int_sub:Nn { c } -\cs_generate_variant:Nn \int_gsub:Nn { c } -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\int_incr:N, \int_incr:c} -% \UnitTested -% \begin{macro}{\int_gincr:N, \int_gincr:c} -% \UnitTested -% \begin{macro}{\int_decr:N, \int_decr:c} -% \UnitTested -% \begin{macro}{\int_gdecr:N, \int_gdecr:c} -% \UnitTested -% Incrementing and decrementing of integer registers is done with -% the following functions. -% \begin{macrocode} -\cs_new_protected:Npn \int_incr:N #1 - { \tex_advance:D #1 \c_one_int } -\cs_new_protected:Npn \int_decr:N #1 - { \tex_advance:D #1 - \c_one_int } -\cs_new_protected:Npn \int_gincr:N #1 - { \tex_global:D \tex_advance:D #1 \c_one_int } -\cs_new_protected:Npn \int_gdecr:N #1 - { \tex_global:D \tex_advance:D #1 - \c_one_int } -\cs_generate_variant:Nn \int_incr:N { c } -\cs_generate_variant:Nn \int_decr:N { c } -\cs_generate_variant:Nn \int_gincr:N { c } -\cs_generate_variant:Nn \int_gdecr:N { c } -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\int_set:Nn, \int_set:cn} -% \UnitTested -% \begin{macro}{\int_gset:Nn, \int_gset:cn} -% \UnitTested -% As integers are register-based \TeX{} issues an error -% if they are not defined. While the |=| sign is optional, this -% version with |=| is slightly quicker than without, while adding the -% optional space after |=| slows things down minutely. -% \begin{macrocode} -\cs_new_protected:Npn \int_set:Nn #1#2 - { #1 = \@@_eval:w #2 \@@_eval_end: } -\cs_new_protected:Npn \int_gset:Nn #1#2 - { \tex_global:D #1 = \@@_eval:w #2 \@@_eval_end: } -\cs_generate_variant:Nn \int_set:Nn { c } -\cs_generate_variant:Nn \int_gset:Nn { c } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \subsection{Using integers} -% -% \begin{macro}{\int_use:N, \int_use:c} -% \UnitTested -% Here is how counters are accessed. -% We hand-code the |c| variant for some speed gain. -% \begin{macrocode} -\cs_new_eq:NN \int_use:N \tex_the:D -\cs_new:Npn \int_use:c #1 { \tex_the:D \cs:w #1 \cs_end: } -% \end{macrocode} -% \end{macro} -% -% \subsection{Integer expression conditionals} -% -% \begin{macro}[EXP]{\@@_compare_error:, \@@_compare_error:Nw} -% Those functions are used for comparison tests which use a simple -% syntax where only one set of braces is required and additional -% operators such as |!=| and |>=| are supported. The tests first -% evaluate their left-hand side, with a trailing -% \cs{@@_compare_error:}. This marker is normally not expanded, -% but if the relation symbol is missing from the test's argument, then -% the marker inserts |=| (and itself) after triggering the relevant -% \TeX{} error. If the first token which appears after evaluating and -% removing the left-hand side is not a known relation symbol, then a -% judiciously placed \cs{@@_compare_error:Nw} gets expanded, -% cleaning up the end of the test and telling the user what the -% problem was. -% \begin{macrocode} -\cs_new_protected:Npn \@@_compare_error: - { - \if_int_compare:w \c_zero_int \c_zero_int \fi: - = - \@@_compare_error: - } -\cs_new:Npn \@@_compare_error:Nw - #1#2 \s_@@_stop - { - { } - \c_zero_int \fi: - \msg_expandable_error:nnn - { kernel } { unknown-comparison } {#1} - \prg_return_false: - } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}[pTF, EXP]{\int_compare:n} -% \begin{macro}[EXP] -% {\@@_compare:w, \@@_compare:Nw, \@@_compare:NNw, \@@_compare:nnN} -% \begin{macro}[EXP] -% { -% \@@_compare_end_=:NNw, -% \@@_compare_=:NNw, -% \@@_compare_<:NNw, -% \@@_compare_>:NNw, -% \@@_compare_==:NNw, -% \@@_compare_!=:NNw, -% \@@_compare_<=:NNw, -% \@@_compare_>=:NNw -% } -% Comparison tests using a simple syntax where only one set of braces -% is required, additional operators such as |!=| and |>=| are -% supported, and multiple comparisons can be performed at once, for -% instance |0 < 5 <= 1|. The idea is to loop through the argument, -% finding one operand at a time, and comparing it to the previous one. -% The looping auxiliary \cs{@@_compare:Nw} reads one \meta{operand} -% and one \meta{comparison} symbol, and leaves roughly -% \begin{quote} -% \meta{operand} \cs{prg_return_false:} \cs{fi:} \\ -% \cs{reverse_if:N} \cs{if_int_compare:w} \meta{operand} \meta{comparison} \\ -% \cs{@@_compare:Nw} -% \end{quote} -% in the input stream. Each call to this auxiliary provides the -% second operand of the last call's \cs{if_int_compare:w}. If one of -% the \meta{comparisons} is \texttt{false}, the \texttt{true} branch -% of the \TeX{} conditional is taken (because of \cs{reverse_if:N}), -% immediately returning \texttt{false} as the result of the test. -% There is no \TeX{} conditional waiting the first operand, so we add -% an \cs{if_false:} and expand by hand with \cs{int_value:w}, thus -% skipping \cs{prg_return_false:} on the first iteration. -% -% Before starting the loop, the first step is to make sure that there -% is at least one relation symbol. We first let \TeX{} evaluate this -% left hand side of the (in)equality using \cs{@@_eval:w}. Since the -% relation symbols |<|, |>|, |=| and |!| are not allowed in integer -% expressions, they would terminate the expression. If the argument contains no -% relation symbol, \cs{@@_compare_error:} is expanded, -% inserting~|=| and itself after an error. In all cases, -% \cs{@@_compare:w} receives as its argument an integer, a relation -% symbol, and some more tokens. We then setup the loop, which is -% ended by the two odd-looking items |e| and |{=nd_}|, with a trailing -% \cs{s_@@_stop} used to grab the entire argument when necessary. -% \begin{macrocode} -\prg_new_conditional:Npnn \int_compare:n #1 { p , T , F , TF } - { - \exp_after:wN \@@_compare:w - \int_value:w \@@_eval:w #1 \@@_compare_error: - } -\cs_new:Npn \@@_compare:w #1 \@@_compare_error: - { - \exp_after:wN \if_false: \int_value:w - \@@_compare:Nw #1 e { = nd_ } \s_@@_stop - } -% \end{macrocode} -% The goal here is to find an \meta{operand} and a \meta{comparison}. -% The \meta{operand} is already evaluated, but we cannot yet grab it -% as an argument. To access the following relation symbol, we remove -% the number by applying \cs{@@_to_roman:w}, after making sure that -% the argument becomes non-positive: its roman numeral representation -% is then empty. Then probe the first two tokens with -% \cs{@@_compare:NNw} to determine the relation symbol, building a -% control sequence from it (\cs{token_to_str:N} gives better errors if -% |#1| is not a character). All the extended forms have an extra |=| -% hence the test for that as a second token. If the relation symbol -% is unknown, then the control sequence is turned by \TeX{} into -% \cs{scan_stop:}, ignored thanks to \tn{unexpanded}, and -% \cs{@@_compare_error:Nw} raises an error. -% \begin{macrocode} -\cs_new:Npn \@@_compare:Nw #1#2 \s_@@_stop - { - \exp_after:wN \@@_compare:NNw - \@@_to_roman:w - 0 #2 \s_@@_mark - #1#2 \s_@@_stop - } -\cs_new:Npn \@@_compare:NNw #1#2#3 \s_@@_mark - { - \__kernel_exp_not:w - \use:c - { - @@_compare_ \token_to_str:N #1 - \if_meaning:w = #2 = \fi: - :NNw - } - \@@_compare_error:Nw #1 - } -% \end{macrocode} -% When the last \meta{operand} is seen, \cs{@@_compare:NNw} receives -% |e| and |=nd_| as arguments, hence calling -% \cs{@@_compare_end_=:NNw} to end the loop: return the result of the -% last comparison (involving the operand that we just found). When a -% normal relation is found, the appropriate auxiliary calls -% \cs{@@_compare:nnN} where |#1| is \cs{if_int_compare:w} or -% \cs{reverse_if:N} \cs{if_int_compare:w}, |#2| is the \meta{operand}, -% and |#3| is one of |<|, |=|, or~|>|. As announced earlier, we leave -% the \meta{operand} for the previous conditional. If this -% conditional is true the result of the test is known, so we remove -% all tokens and return \texttt{false}. Otherwise, we apply the -% conditional |#1| to the \meta{operand} |#2| and the comparison |#3|, -% and call \cs{@@_compare:Nw} to look for additional operands, after -% evaluating the following expression. -% \begin{macrocode} -\cs_new:cpn { @@_compare_end_=:NNw } #1#2#3 e #4 \s_@@_stop - { - {#3} \exp_stop_f: - \prg_return_false: \else: \prg_return_true: \fi: - } -\cs_new:Npn \@@_compare:nnN #1#2#3 - { - {#2} \exp_stop_f: - \prg_return_false: \exp_after:wN \@@_use_none_delimit_by_s_stop:w - \fi: - #1 #2 #3 \exp_after:wN \@@_compare:Nw \int_value:w \@@_eval:w - } -% \end{macrocode} -% The actual comparisons are then simple function calls, using the -% relation as delimiter for a delimited argument and discarding -% \cs{@@_compare_error:Nw} \meta{token} responsible for error -% detection. -% \begin{macrocode} -\cs_new:cpn { @@_compare_=:NNw } #1#2#3 = - { \@@_compare:nnN { \reverse_if:N \if_int_compare:w } {#3} = } -\cs_new:cpn { @@_compare_<:NNw } #1#2#3 < - { \@@_compare:nnN { \reverse_if:N \if_int_compare:w } {#3} < } -\cs_new:cpn { @@_compare_>:NNw } #1#2#3 > - { \@@_compare:nnN { \reverse_if:N \if_int_compare:w } {#3} > } -\cs_new:cpn { @@_compare_==:NNw } #1#2#3 == - { \@@_compare:nnN { \reverse_if:N \if_int_compare:w } {#3} = } -\cs_new:cpn { @@_compare_!=:NNw } #1#2#3 != - { \@@_compare:nnN { \if_int_compare:w } {#3} = } -\cs_new:cpn { @@_compare_<=:NNw } #1#2#3 <= - { \@@_compare:nnN { \if_int_compare:w } {#3} > } -\cs_new:cpn { @@_compare_>=:NNw } #1#2#3 >= - { \@@_compare:nnN { \if_int_compare:w } {#3} < } -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macro}[pTF]{\int_compare:nNn} -% \UnitTested -% More efficient but less natural in typing. -% \begin{macrocode} -\prg_new_conditional:Npnn \int_compare:nNn #1#2#3 { p , T , F , TF } - { - \if_int_compare:w \@@_eval:w #1 #2 \@@_eval:w #3 \@@_eval_end: - \prg_return_true: - \else: - \prg_return_false: - \fi: - } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}[pTF]{\int_if_zero:n} -% \begin{macrocode} -\prg_new_conditional:Npnn \int_if_zero:n #1 { p , T , F , TF } - { - \if_int_compare:w \@@_eval:w #1 = \c_zero_int - \prg_return_true: - \else: - \prg_return_false: - \fi: - } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}[EXP, noTF]{\int_case:nn} -% \begin{macro}{\@@_case:nnTF} -% \begin{macro}{\@@_case:nw, \@@_case_end:nw} -% For integer cases, the first task to fully expand the check -% condition. The over all idea is then much the same as for -% \cs{str_case:nnTF} as described in \pkg{l3str}. -% \begin{macrocode} -\cs_new:Npn \int_case:nnTF #1 - { - \exp:w - \exp_args:Nf \@@_case:nnTF { \int_eval:n {#1} } - } -\cs_new:Npn \int_case:nnT #1#2#3 - { - \exp:w - \exp_args:Nf \@@_case:nnTF { \int_eval:n {#1} } {#2} {#3} { } - } -\cs_new:Npn \int_case:nnF #1#2 - { - \exp:w - \exp_args:Nf \@@_case:nnTF { \int_eval:n {#1} } {#2} { } - } -\cs_new:Npn \int_case:nn #1#2 - { - \exp:w - \exp_args:Nf \@@_case:nnTF { \int_eval:n {#1} } {#2} { } { } - } -\cs_new:Npn \@@_case:nnTF #1#2#3#4 - { \@@_case:nw {#1} #2 {#1} { } \s_@@_mark {#3} \s_@@_mark {#4} \s_@@_stop } -\cs_new:Npn \@@_case:nw #1#2#3 - { - \int_compare:nNnTF {#1} = {#2} - { \@@_case_end:nw {#3} } - { \@@_case:nw {#1} } - } -\cs_new:Npn \@@_case_end:nw #1#2#3 \s_@@_mark #4#5 \s_@@_stop - { \exp_end: #1 #4 } -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macro}[pTF]{\int_if_odd:n} -% \UnitTested -% \begin{macro}[pTF]{\int_if_even:n} -% \UnitTested -% A predicate function. -% \begin{macrocode} -\prg_new_conditional:Npnn \int_if_odd:n #1 { p , T , F , TF} - { - \if_int_odd:w \@@_eval:w #1 \@@_eval_end: - \prg_return_true: - \else: - \prg_return_false: - \fi: - } -\prg_new_conditional:Npnn \int_if_even:n #1 { p , T , F , TF} - { - \reverse_if:N \if_int_odd:w \@@_eval:w #1 \@@_eval_end: - \prg_return_true: - \else: - \prg_return_false: - \fi: - } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \subsection{Integer expression loops} -% -% \begin{macro}{\int_while_do:nn} -% \UnitTested -% \TestMissing{Boundary cases} -% \begin{macro}{\int_until_do:nn} -% \UnitTested -% \TestMissing{Boundary cases} -% \begin{macro}{\int_do_while:nn} -% \UnitTested -% \TestMissing{Boundary cases} -% \begin{macro}{\int_do_until:nn} -% \UnitTested -% \TestMissing{Boundary cases} -% These are quite easy given the above functions. The |while| versions -% test first and then execute the body. The |do_while| does it the -% other way round. -% \begin{macrocode} -\cs_new:Npn \int_while_do:nn #1#2 - { - \int_compare:nT {#1} - { - #2 - \int_while_do:nn {#1} {#2} - } - } -\cs_new:Npn \int_until_do:nn #1#2 - { - \int_compare:nF {#1} - { - #2 - \int_until_do:nn {#1} {#2} - } - } -\cs_new:Npn \int_do_while:nn #1#2 - { - #2 - \int_compare:nT {#1} - { \int_do_while:nn {#1} {#2} } - } -\cs_new:Npn \int_do_until:nn #1#2 - { - #2 - \int_compare:nF {#1} - { \int_do_until:nn {#1} {#2} } - } -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\int_while_do:nNnn} -% \begin{macro}{\int_until_do:nNnn} -% \begin{macro}{\int_do_while:nNnn} -% \begin{macro}{\int_do_until:nNnn} -% As above but not using the more natural syntax. -% \begin{macrocode} -\cs_new:Npn \int_while_do:nNnn #1#2#3#4 - { - \int_compare:nNnT {#1} #2 {#3} - { - #4 - \int_while_do:nNnn {#1} #2 {#3} {#4} - } - } -\cs_new:Npn \int_until_do:nNnn #1#2#3#4 - { - \int_compare:nNnF {#1} #2 {#3} - { - #4 - \int_until_do:nNnn {#1} #2 {#3} {#4} - } - } -\cs_new:Npn \int_do_while:nNnn #1#2#3#4 - { - #4 - \int_compare:nNnT {#1} #2 {#3} - { \int_do_while:nNnn {#1} #2 {#3} {#4} } - } -\cs_new:Npn \int_do_until:nNnn #1#2#3#4 - { - #4 - \int_compare:nNnF {#1} #2 {#3} - { \int_do_until:nNnn {#1} #2 {#3} {#4} } - } -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \subsection{Integer step functions} -% -% \begin{macro}{\int_step_function:nnnN} -% \begin{macro}{\@@_step:wwwN, \@@_step:NwnnN} -% \begin{macro}{\int_step_function:nN} -% \begin{macro}{\int_step_function:nnN} -% Before all else, evaluate the initial value, step, and final value. -% Repeating a function by steps first needs a check on the direction -% of the steps. After that, do the function for the start value then -% step and loop around. It would be more symmetrical to test for a -% step size of zero before checking the sign, but we optimize for the -% most frequent case (positive step). -% \begin{macrocode} -\cs_new:Npn \int_step_function:nnnN #1#2#3 - { - \exp_after:wN \@@_step:wwwN - \int_value:w \@@_eval:w #1 \exp_after:wN ; - \int_value:w \@@_eval:w #2 \exp_after:wN ; - \int_value:w \@@_eval:w #3 ; - } -\cs_new:Npn \@@_step:wwwN #1; #2; #3; #4 - { - \int_compare:nNnTF {#2} > \c_zero_int - { \@@_step:NwnnN > } - { - \int_compare:nNnTF {#2} = \c_zero_int - { - \msg_expandable_error:nnn - { kernel } { zero-step } {#4} - \prg_break: - } - { \@@_step:NwnnN < } - } - #1 ; {#2} {#3} #4 - \prg_break_point: - } -\cs_new:Npn \@@_step:NwnnN #1#2 ; #3#4#5 - { - \if_int_compare:w #2 #1 #4 \exp_stop_f: - \prg_break:n - \fi: - #5 {#2} - \exp_after:wN \@@_step:NwnnN - \exp_after:wN #1 - \int_value:w \@@_eval:w #2 + #3 ; {#3} {#4} #5 - } -\cs_new:Npn \int_step_function:nN - { \int_step_function:nnnN { 1 } { 1 } } -\cs_new:Npn \int_step_function:nnN #1 - { \int_step_function:nnnN {#1} { 1 } } -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\int_step_inline:nn, \int_step_inline:nnn, \int_step_inline:nnnn} -% \begin{macro}{\int_step_variable:nNn, \int_step_variable:nnNn, \int_step_variable:nnnNn} -% \UnitTested -% \begin{macro}{\@@_step:NNnnnn} -% The approach here is to build a function, with a global integer -% required to make the nesting safe (as seen in other in line -% functions), and map that function using \cs{int_step_function:nnnN}. -% We put a \cs{prg_break_point:Nn} so that \texttt{map_break} -% functions from other modules correctly decrement \cs{g__kernel_prg_map_int} -% before looking for their own break point. The first argument is -% \cs{scan_stop:}, so that no breaking function recognizes this break -% point as its own. -% \begin{macrocode} -\cs_new_protected:Npn \int_step_inline:nn - { \int_step_inline:nnnn { 1 } { 1 } } -\cs_new_protected:Npn \int_step_inline:nnn #1 - { \int_step_inline:nnnn {#1} { 1 } } -\cs_new_protected:Npn \int_step_inline:nnnn - { - \int_gincr:N \g__kernel_prg_map_int - \exp_args:NNc \@@_step:NNnnnn - \cs_gset_protected:Npn - { @@_map_ \int_use:N \g__kernel_prg_map_int :w } - } -\cs_new_protected:Npn \int_step_variable:nNn - { \int_step_variable:nnnNn { 1 } { 1 } } -\cs_new_protected:Npn \int_step_variable:nnNn #1 - { \int_step_variable:nnnNn {#1} { 1 } } -\cs_new_protected:Npn \int_step_variable:nnnNn #1#2#3#4#5 - { - \int_gincr:N \g__kernel_prg_map_int - \exp_args:NNc \@@_step:NNnnnn - \cs_gset_protected:Npe - { @@_map_ \int_use:N \g__kernel_prg_map_int :w } - {#1}{#2}{#3} - { - \tl_set:Nn \exp_not:N #4 {##1} - \exp_not:n {#5} - } - } -\cs_new_protected:Npn \@@_step:NNnnnn #1#2#3#4#5#6 - { - #1 #2 ##1 {#6} - \int_step_function:nnnN {#3} {#4} {#5} #2 - \prg_break_point:Nn \scan_stop: { \int_gdecr:N \g__kernel_prg_map_int } - } -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \subsection{Formatting integers} -% -% \begin{macro}{\int_to_arabic:n, \int_to_arabic:v} -% \UnitTested -% Nothing exciting here. -% \begin{macrocode} -\cs_new_eq:NN \int_to_arabic:n \int_eval:n -\cs_generate_variant:Nn \int_to_arabic:n { v } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\int_to_symbols:nnn} -% \UnitTested -% \begin{macro}{\@@_to_symbols:nnnn, \@@_to_symbols:ennn} -% For conversion of integers to arbitrary symbols the method is in -% general as follows. The input number (|#1|) is compared to the total -% number of symbols available at each place (|#2|). If the input is larger -% than the total number of symbols available then the modulus is needed, -% with one added so that the positions don't have to number from -% zero. Using an \texttt{f}-type expansion, this is done so that the system -% is recursive. The actual conversion function therefore gets a `nice' -% number at each stage. Of course, if the initial input was small enough -% then there is no problem and everything is easy. -% \begin{macrocode} -\cs_new:Npn \int_to_symbols:nnn #1#2#3 - { - \int_compare:nNnTF {#1} > {#2} - { - \@@_to_symbols:ennn - { - \int_case:nn - { 1 + \int_mod:nn { #1 - 1 } {#2} } - {#3} - } - {#1} {#2} {#3} - } - { \int_case:nn {#1} {#3} } - } -\cs_new:Npn \@@_to_symbols:nnnn #1#2#3#4 - { - \exp_args:Nf \int_to_symbols:nnn - { \int_div_truncate:nn { #2 - 1 } {#3} } {#3} {#4} - #1 - } -\cs_generate_variant:Nn \@@_to_symbols:nnnn { e } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\int_to_alph:n, \int_to_Alph:n} -% \UnitTested -% These both use the above function with input functions that make sense -% for the alphabet in English. -% \begin{macrocode} -\cs_new:Npn \int_to_alph:n #1 - { - \int_to_symbols:nnn {#1} { 26 } - { - { 1 } { a } - { 2 } { b } - { 3 } { c } - { 4 } { d } - { 5 } { e } - { 6 } { f } - { 7 } { g } - { 8 } { h } - { 9 } { i } - { 10 } { j } - { 11 } { k } - { 12 } { l } - { 13 } { m } - { 14 } { n } - { 15 } { o } - { 16 } { p } - { 17 } { q } - { 18 } { r } - { 19 } { s } - { 20 } { t } - { 21 } { u } - { 22 } { v } - { 23 } { w } - { 24 } { x } - { 25 } { y } - { 26 } { z } - } - } -\cs_new:Npn \int_to_Alph:n #1 - { - \int_to_symbols:nnn {#1} { 26 } - { - { 1 } { A } - { 2 } { B } - { 3 } { C } - { 4 } { D } - { 5 } { E } - { 6 } { F } - { 7 } { G } - { 8 } { H } - { 9 } { I } - { 10 } { J } - { 11 } { K } - { 12 } { L } - { 13 } { M } - { 14 } { N } - { 15 } { O } - { 16 } { P } - { 17 } { Q } - { 18 } { R } - { 19 } { S } - { 20 } { T } - { 21 } { U } - { 22 } { V } - { 23 } { W } - { 24 } { X } - { 25 } { Y } - { 26 } { Z } - } - } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\int_to_base:nn, \int_to_Base:nn} -% \UnitTested -% \begin{macro}{\@@_to_base:nn, \@@_to_Base:nn, -% \@@_to_base:nnN, \@@_to_Base:nnN, \@@_to_base:nnnN, \@@_to_Base:nnnN} -% \begin{macro}{\@@_to_letter:n, \@@_to_Letter:n} -% \UnitTested -% Converting from base ten (|#1|) to a second base (|#2|) starts with -% computing |#1|: if it is a complicated calculation, we shouldn't -% perform it twice. Then check the sign, store it, either \texttt{-} -% or \cs{c_empty_tl}, and feed the absolute value to the next auxiliary -% function. -% \begin{macrocode} -\cs_new:Npn \int_to_base:nn #1 - { \exp_args:Nf \@@_to_base:nn { \int_eval:n {#1} } } -\cs_new:Npn \int_to_Base:nn #1 - { \exp_args:Nf \@@_to_Base:nn { \int_eval:n {#1} } } -\cs_new:Npn \@@_to_base:nn #1#2 - { - \int_compare:nNnTF {#1} < 0 - { \exp_args:No \@@_to_base:nnN { \use_none:n #1 } {#2} - } - { \@@_to_base:nnN {#1} {#2} \c_empty_tl } - } -\cs_new:Npn \@@_to_Base:nn #1#2 - { - \int_compare:nNnTF {#1} < 0 - { \exp_args:No \@@_to_Base:nnN { \use_none:n #1 } {#2} - } - { \@@_to_Base:nnN {#1} {#2} \c_empty_tl } - } -% \end{macrocode} -% Here, the idea is to provide a recursive system to deal with the -% input. The output is built up after the end of the function. -% At each pass, the value in |#1| is checked to see if it is less -% than the new base (|#2|). If it is, then it is converted directly, -% putting the sign back in front. -% On the other hand, if the value to convert is greater than or equal -% to the new base then the modulus and remainder values are found. The -% modulus is converted to a symbol and put on the right, -% and the remainder is carried forward to the next round. -% \begin{macrocode} -\cs_new:Npn \@@_to_base:nnN #1#2#3 - { - \int_compare:nNnTF {#1} < {#2} - { \exp_last_unbraced:Nf #3 { \@@_to_letter:n {#1} } } - { - \exp_args:Nf \@@_to_base:nnnN - { \@@_to_letter:n { \int_mod:nn {#1} {#2} } } - {#1} - {#2} - #3 - } - } -\cs_new:Npn \@@_to_base:nnnN #1#2#3#4 - { - \exp_args:Nf \@@_to_base:nnN - { \int_div_truncate:nn {#2} {#3} } - {#3} - #4 - #1 - } -\cs_new:Npn \@@_to_Base:nnN #1#2#3 - { - \int_compare:nNnTF {#1} < {#2} - { \exp_last_unbraced:Nf #3 { \@@_to_Letter:n {#1} } } - { - \exp_args:Nf \@@_to_Base:nnnN - { \@@_to_Letter:n { \int_mod:nn {#1} {#2} } } - {#1} - {#2} - #3 - } - } -\cs_new:Npn \@@_to_Base:nnnN #1#2#3#4 - { - \exp_args:Nf \@@_to_Base:nnN - { \int_div_truncate:nn {#2} {#3} } - {#3} - #4 - #1 - } -% \end{macrocode} -% Convert to a letter only if necessary, otherwise simply return the -% value unchanged. It would be cleaner to use \cs{int_case:nn}, -% but in our case, the cases are contiguous, so it is forty times faster -% to use the \cs{if_case:w} primitive. The first \cs{exp_after:wN} -% expands the conditional, jumping to the correct case, the second one -% expands after the resulting character to close the conditional. -% Since |#1| might be an expression, and not directly a single digit, -% we need to evaluate it properly, and expand the trailing \cs{fi:}. -% \begin{macrocode} -\cs_new:Npn \@@_to_letter:n #1 - { - \exp_after:wN \exp_after:wN - \if_case:w \@@_eval:w #1 - 10 \@@_eval_end: - a - \or: b - \or: c - \or: d - \or: e - \or: f - \or: g - \or: h - \or: i - \or: j - \or: k - \or: l - \or: m - \or: n - \or: o - \or: p - \or: q - \or: r - \or: s - \or: t - \or: u - \or: v - \or: w - \or: x - \or: y - \or: z - \else: \int_value:w \@@_eval:w #1 \exp_after:wN \@@_eval_end: - \fi: - } -\cs_new:Npn \@@_to_Letter:n #1 - { - \exp_after:wN \exp_after:wN - \if_case:w \@@_eval:w #1 - 10 \@@_eval_end: - A - \or: B - \or: C - \or: D - \or: E - \or: F - \or: G - \or: H - \or: I - \or: J - \or: K - \or: L - \or: M - \or: N - \or: O - \or: P - \or: Q - \or: R - \or: S - \or: T - \or: U - \or: V - \or: W - \or: X - \or: Y - \or: Z - \else: \int_value:w \@@_eval:w #1 \exp_after:wN \@@_eval_end: - \fi: - } -% \end{macrocode} -%\end{macro} -%\end{macro} -%\end{macro} -% -% \begin{macro}{\int_to_bin:n, \int_to_hex:n, \int_to_Hex:n, \int_to_oct:n} -% \UnitTested -% Wrappers around the generic function. -% \begin{macrocode} -\cs_new:Npn \int_to_bin:n #1 - { \int_to_base:nn {#1} { 2 } } -\cs_new:Npn \int_to_hex:n #1 - { \int_to_base:nn {#1} { 16 } } -\cs_new:Npn \int_to_Hex:n #1 - { \int_to_Base:nn {#1} { 16 } } -\cs_new:Npn \int_to_oct:n #1 - { \int_to_base:nn {#1} { 8 } } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\int_to_roman:n, \int_to_Roman:n} -% \UnitTested -% \begin{macro}{\@@_to_roman:N, \@@_to_roman:N} -% \begin{macro} -% { -% \@@_to_roman_i:w, \@@_to_roman_v:w, \@@_to_roman_x:w, -% \@@_to_roman_l:w, \@@_to_roman_c:w, \@@_to_roman_d:w, -% \@@_to_roman_m:w, \@@_to_roman_Q:w, -% \@@_to_Roman_i:w, \@@_to_Roman_v:w, \@@_to_Roman_x:w, -% \@@_to_Roman_l:w, \@@_to_Roman_c:w, \@@_to_Roman_d:w, -% \@@_to_Roman_m:w, \@@_to_Roman_Q:w, -% } -% The \cs{@@_to_roman:w} primitive creates tokens of category -% code $12$ (other). Usually, what is actually wanted is letters. -% The approach here is to convert the output of the primitive into -% letters using appropriate control sequence names. That keeps -% everything expandable. The loop is terminated by the conversion -% of the |Q|. -% \begin{macrocode} -\cs_new:Npn \int_to_roman:n #1 - { - \exp_after:wN \@@_to_roman:N - \@@_to_roman:w \int_eval:n {#1} Q - } -\cs_new:Npn \@@_to_roman:N #1 - { - \use:c { @@_to_roman_ #1 :w } - \@@_to_roman:N - } -\cs_new:Npn \int_to_Roman:n #1 - { - \exp_after:wN \@@_to_Roman_aux:N - \@@_to_roman:w \int_eval:n {#1} Q - } -\cs_new:Npn \@@_to_Roman_aux:N #1 - { - \use:c { @@_to_Roman_ #1 :w } - \@@_to_Roman_aux:N - } -\cs_new:Npn \@@_to_roman_i:w { i } -\cs_new:Npn \@@_to_roman_v:w { v } -\cs_new:Npn \@@_to_roman_x:w { x } -\cs_new:Npn \@@_to_roman_l:w { l } -\cs_new:Npn \@@_to_roman_c:w { c } -\cs_new:Npn \@@_to_roman_d:w { d } -\cs_new:Npn \@@_to_roman_m:w { m } -\cs_new:Npn \@@_to_roman_Q:w #1 { } -\cs_new:Npn \@@_to_Roman_i:w { I } -\cs_new:Npn \@@_to_Roman_v:w { V } -\cs_new:Npn \@@_to_Roman_x:w { X } -\cs_new:Npn \@@_to_Roman_l:w { L } -\cs_new:Npn \@@_to_Roman_c:w { C } -\cs_new:Npn \@@_to_Roman_d:w { D } -\cs_new:Npn \@@_to_Roman_m:w { M } -\cs_new:Npn \@@_to_Roman_Q:w #1 { } -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \subsection{Converting from other formats to integers} -% -% \begin{macro}[rEXP]{\@@_pass_signs:wn, \@@_pass_signs_end:wn} -% Called as \cs{@@_pass_signs:wn} \meta{signs and digits} \cs{s_@@_stop} -% \Arg{code}, this function leaves in the input stream any sign it -% finds, then inserts the \meta{code} before the first non-sign token -% (and removes \cs{s_@@_stop}). More precisely, it deletes any~|+| and -% passes any~|-| to the input stream, hence should be called in an -% integer expression. -% \begin{macrocode} -\cs_new:Npn \@@_pass_signs:wn #1 - { - \if:w + \if:w - \exp_not:N #1 + \fi: \exp_not:N #1 - \exp_after:wN \@@_pass_signs:wn - \else: - \exp_after:wN \@@_pass_signs_end:wn - \exp_after:wN #1 - \fi: - } -\cs_new:Npn \@@_pass_signs_end:wn #1 \s_@@_stop #2 { #2 #1 } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\int_from_alph:n} -% \UnitTested -% \begin{macro}{\@@_from_alph:nN, \@@_from_alph:N} -% First take care of signs then loop through the input using the -% \texttt{recursion} quarks. The \cs{@@_from_alph:nN} auxiliary -% collects in its first argument the value obtained so far, and the -% auxiliary \cs{@@_from_alph:N} converts one letter to an expression -% which evaluates to the correct number. -% \begin{macrocode} -\cs_new:Npn \int_from_alph:n #1 - { - \int_eval:n - { - \exp_after:wN \@@_pass_signs:wn \tl_to_str:n {#1} - \s_@@_stop { \@@_from_alph:nN { 0 } } - \q_@@_recursion_tail \q_@@_recursion_stop - } - } -\cs_new:Npn \@@_from_alph:nN #1#2 - { - \@@_if_recursion_tail_stop_do:Nn #2 {#1} - \exp_args:Nf \@@_from_alph:nN - { \int_eval:n { #1 * 26 + \@@_from_alph:N #2 } } - } -\cs_new:Npn \@@_from_alph:N #1 - { `#1 - \int_compare:nNnTF { `#1 } < { 91 } { 64 } { 96 } } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\int_from_base:nn} -% \UnitTested -% \begin{macro}{\@@_from_base:nnN, \@@_from_base:N} -% Leave the signs into the integer expression, then loop through -% characters, collecting the value found so far in the first argument -% of \cs{@@_from_base:nnN}. To convert a single character, -% \cs{@@_from_base:N} checks first for digits, then distinguishes -% lower from upper case letters, turning them into the appropriate -% number. Note that this auxiliary does not use \cs{int_eval:n}, -% hence is not safe for general use. -% \begin{macrocode} -\cs_new:Npn \int_from_base:nn #1#2 - { - \int_eval:n - { - \exp_after:wN \@@_pass_signs:wn \tl_to_str:n {#1} - \s_@@_stop { \@@_from_base:nnN { 0 } {#2} } - \q_@@_recursion_tail \q_@@_recursion_stop - } - } -\cs_new:Npn \@@_from_base:nnN #1#2#3 - { - \@@_if_recursion_tail_stop_do:Nn #3 {#1} - \exp_args:Nf \@@_from_base:nnN - { \int_eval:n { #1 * #2 + \@@_from_base:N #3 } } - {#2} - } -\cs_new:Npn \@@_from_base:N #1 - { - \int_compare:nNnTF { `#1 } < { 58 } - {#1} - { `#1 - \int_compare:nNnTF { `#1 } < { 91 } { 55 } { 87 } } - } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\int_from_bin:n, \int_from_hex:n, \int_from_oct:n} -% \UnitTested -% Wrappers around the generic function. -% \begin{macrocode} -\cs_new:Npn \int_from_bin:n #1 - { \int_from_base:nn {#1} { 2 } } -\cs_new:Npn \int_from_hex:n #1 - { \int_from_base:nn {#1} { 16 } } -\cs_new:Npn \int_from_oct:n #1 - { \int_from_base:nn {#1} { 8 } } -% \end{macrocode} -% \end{macro} -% -% \begin{variable} -% { -% \c_@@_from_roman_i_int, \c_@@_from_roman_v_int, -% \c_@@_from_roman_x_int, \c_@@_from_roman_l_int, -% \c_@@_from_roman_c_int, \c_@@_from_roman_d_int, -% \c_@@_from_roman_m_int, -% \c_@@_from_roman_I_int, \c_@@_from_roman_V_int, -% \c_@@_from_roman_X_int, \c_@@_from_roman_L_int, -% \c_@@_from_roman_C_int, \c_@@_from_roman_D_int, -% \c_@@_from_roman_M_int -% } -% Constants used to convert from Roman numerals to integers. -% \begin{macrocode} -\int_const:cn { c_@@_from_roman_i_int } { 1 } -\int_const:cn { c_@@_from_roman_v_int } { 5 } -\int_const:cn { c_@@_from_roman_x_int } { 10 } -\int_const:cn { c_@@_from_roman_l_int } { 50 } -\int_const:cn { c_@@_from_roman_c_int } { 100 } -\int_const:cn { c_@@_from_roman_d_int } { 500 } -\int_const:cn { c_@@_from_roman_m_int } { 1000 } -\int_const:cn { c_@@_from_roman_I_int } { 1 } -\int_const:cn { c_@@_from_roman_V_int } { 5 } -\int_const:cn { c_@@_from_roman_X_int } { 10 } -\int_const:cn { c_@@_from_roman_L_int } { 50 } -\int_const:cn { c_@@_from_roman_C_int } { 100 } -\int_const:cn { c_@@_from_roman_D_int } { 500 } -\int_const:cn { c_@@_from_roman_M_int } { 1000 } -% \end{macrocode} -% \end{variable} -% -% \begin{macro}{\int_from_roman:n} -% \UnitTested -% \TestMissing{boundary cases / wrong input?} -% \begin{macro}{\@@_from_roman:NN} -% \begin{macro}{\@@_from_roman_error:w} -% The method here is to iterate through the input, finding the -% appropriate value for each letter and building up a sum. This is -% then evaluated by \TeX{}. If any unknown letter is found, skip to -% the closing parenthesis and insert |*0-1| afterwards, to replace the -% value by $-1$. -% \begin{macrocode} -\cs_new:Npn \int_from_roman:n #1 - { - \int_eval:n - { - ( - 0 - \exp_after:wN \@@_from_roman:NN \tl_to_str:n {#1} - \q_@@_recursion_tail \q_@@_recursion_tail \q_@@_recursion_stop - ) - } - } -\cs_new:Npn \@@_from_roman:NN #1#2 - { - \@@_if_recursion_tail_stop:N #1 - \int_if_exist:cF { c_@@_from_roman_ #1 _int } - { \@@_from_roman_error:w } - \@@_if_recursion_tail_stop_do:Nn #2 - { + \use:c { c_@@_from_roman_ #1 _int } } - \int_if_exist:cF { c_@@_from_roman_ #2 _int } - { \@@_from_roman_error:w } - \int_compare:nNnTF - { \use:c { c_@@_from_roman_ #1 _int } } - < - { \use:c { c_@@_from_roman_ #2 _int } } - { - + \use:c { c_@@_from_roman_ #2 _int } - - \use:c { c_@@_from_roman_ #1 _int } - \@@_from_roman:NN - } - { - + \use:c { c_@@_from_roman_ #1 _int } - \@@_from_roman:NN #2 - } - } -\cs_new:Npn \@@_from_roman_error:w #1 \q_@@_recursion_stop #2 - { #2 * 0 - 1 } -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \subsection{Viewing integer} -% -% \begin{macro}{\int_show:N, \int_show:c} -% \UnitTested -% \begin{macro}{\@@_show:nN} -% Diagnostics. -% \begin{macrocode} -\cs_new_eq:NN \int_show:N \__kernel_register_show:N -\cs_generate_variant:Nn \int_show:N { c } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\int_show:n} -% \UnitTested -% We don't use the \TeX{} primitive \tn{showthe} to show integer -% expressions: this gives a more unified output. -% \begin{macrocode} -\cs_new_protected:Npn \int_show:n - { \__kernel_msg_show_eval:Nn \int_eval:n } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\int_log:N, \int_log:c} -% Diagnostics. -% \begin{macrocode} -\cs_new_eq:NN \int_log:N \__kernel_register_log:N -\cs_generate_variant:Nn \int_log:N { c } -% \end{macrocode} -% \end{macro} -% -% \begin{macro}{\int_log:n} -% Similar to \cs{int_show:n}. -% \begin{macrocode} -\cs_new_protected:Npn \int_log:n - { \__kernel_msg_log_eval:Nn \int_eval:n } -% \end{macrocode} -% \end{macro} -% -%\subsection{Random integers} -% -% \begin{macro}{\int_rand:nn} -% Defined in \pkg{l3fp-random}. -% \end{macro} -% -% \subsection{Constant integers} -% -% \begin{variable}{\c_zero_int, \c_one_int} -% The zero is defined in \pkg{l3basics}. -% \begin{macrocode} -\int_const:Nn \c_one_int { 1 } -% \end{macrocode} -% \end{variable} -% -% \begin{variable}{\c_max_int} -% The largest number allowed is $2^{31}-1$ -% \begin{macrocode} -\int_const:Nn \c_max_int { 2 147 483 647 } -% \end{macrocode} -% \end{variable} -% -% \begin{variable}{\c_max_char_int} -% The largest character code is $1114111$ (hexadecimal |10FFFF|) in -% \XeTeX{} and \LuaTeX{} and $255$ in other engines. In many places -% \pTeX{} and \upTeX{} support larger character codes but for instance -% the values of \tn{lccode} are restricted to $[0,255]$. -% \begin{macrocode} -\int_const:Nn \c_max_char_int - { - \if_int_odd:w 0 - \cs_if_exist:NT \tex_luatexversion:D { 1 } - \cs_if_exist:NT \tex_XeTeXversion:D { 1 } ~ - "10FFFF - \else: - "FF - \fi: - } -% \end{macrocode} -% \end{variable} -% -% \subsection{Scratch integers} -% -% \begin{variable}{\l_tmpa_int, \l_tmpb_int} -% \begin{variable}{\g_tmpa_int, \g_tmpb_int} -% We provide two local and two global scratch counters, maybe we -% need more or less. -% \begin{macrocode} -\int_new:N \l_tmpa_int -\int_new:N \l_tmpb_int -\int_new:N \g_tmpa_int -\int_new:N \g_tmpb_int -% \end{macrocode} -% \end{variable} -% \end{variable} -% -% \subsection{Integers for earlier modules} -% -%<@@=seq> -% -% \begin{variable}{\l_@@_internal_a_int, \l_@@_internal_b_int} -% \begin{macrocode} -\int_new:N \l_@@_internal_a_int -\int_new:N \l_@@_internal_b_int -% \end{macrocode} -% \end{variable} -% -% \begin{macrocode} -%</package> -% \end{macrocode} -% -% \end{implementation} -% -% \PrintIndex |