% \iffalse %% File: l3int.dtx Copyright (C) 1990-2010 LaTeX3 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 %% %% http://www.latex-project.org/lppl.txt %% %% This file is part of the ``expl3 bundle'' (The Work in LPPL) %% and all files in that bundle must be distributed together. %% %% The released version of this bundle is available from CTAN. %% %% ----------------------------------------------------------------------- %% %% The development version of the bundle can be found at %% %% http://www.latex-project.org/svnroot/experimental/trunk/ %% %% for those people who are interested. %% %%%%%%%%%%% %% NOTE: %% %%%%%%%%%%% %% %% Snapshots taken from the repository represent work in progress and may %% not work or may contain conflicting material! We therefore ask %% people _not_ to put them into distributions, archives, etc. without %% prior consultation with the LaTeX Project Team. %% %% ----------------------------------------------------------------------- % %<*driver|package> \RequirePackage{l3names} % %\fi \GetIdInfo$Id: l3int.dtx 2077 2010-10-17 07:47:48Z will $ {L3 Experimental Integer module} %\iffalse %<*driver> %\fi \ProvidesFile{\filename.\filenameext} [\filedate\space v\fileversion\space\filedescription] %\iffalse \documentclass[full]{l3doc} \begin{document} \DocInput{l3int.dtx} \end{document} % % \fi % % % \title{The \textsf{l3int} package\thanks{This file % has version number \fileversion, last % revised \filedate.}\\ % Integers/counters} % \author{\Team} % \date{\filedate} % \maketitle % % \begin{documentation} % %\section{Integer values} % % % 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} (`\texttt{int expr}'). % %\subsection{Integer expressions} % %\begin{function}{ \int_eval:n / (EXP) } % \begin{syntax} % \cs{int_eval:n} \Arg{integer expression} % \end{syntax} % Evaluates the \meta{integer expression}, expanding any % integer and token list variables within the \meta{expression} % to their content (without requiring \cs{int_use:N}/\cs{tl_use:N}) % and applying the standard mathematical rules. The result of the % calculation is left in the input stream as a number. 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} % both evaluate to \( -6 \). The \Arg{integer expression} may % contain the operators \texttt{+}, \texttt{-}, \texttt{*} and % \texttt{/}, along with parenthesis \texttt{(} and \texttt{)}. %\end{function} % %\begin{function}{ \int_abs:n / (EXP) } % \begin{syntax} % \cs{int_abs:n} \Arg{integer expression} % \end{syntax} % Evaluates the \meta{integer expression} as described for % \cs{int_eval:n} and leaves the absolute value of the result in % the input stream. %\end{function} % %\begin{function}{ \int_div_round:nn / (EXP) } % \begin{syntax} % \cs{int_div_round:nn} \Arg{intexpr1} \Arg{intexpr2} % \end{syntax} % Evaluates the two \meta{integer expressions} as described earlier, % then calculates the result of dividing the first value by the % second, rounding any remainder. Note that division using "/" % is identical to this function. %\end{function} % %\begin{function}{ \int_div_truncate:nn / (EXP) } % \begin{syntax} % \cs{int_div_truncate:nn} \Arg{intexpr1} \Arg{intexpr2} % \end{syntax} % Evaluates the two \meta{integer expressions} as described earlier, % then calculates the result of dividing the first value by the % second, truncating any remainder. Note that division using "/" % rounds the result. %\end{function} % %\begin{function}{ % \int_max:nn / (EXP) | % \int_min:nn / (EXP) | %} % \begin{syntax} % \cs{int_max:nn} \Arg{intexpr1} \Arg{intexpr2} % \cs{int_min:nn} \Arg{intexpr1} \Arg{intexpr2} % \end{syntax} % Evaluates the \meta{integer expressions} as described for % \cs{int_eval:n} and leaves either the larger or smaller value % in the input stream, depending on the function name. %\end{function} % %\begin{function}{ \int_mod:nn / (EXP) } % \begin{syntax} % \cs{int_mod:nn} \Arg{intexpr1} \Arg{intexpr2} % \end{syntax} % Evaluates the two \meta{integer expressions} as described earlier, % then calculates the integer remainder of dividing the first % expression by the second. This is left in the input stream. %\end{function} % %\subsection{Integer variables} % %\begin{function}{ % \int_new:N | % \int_new:c | %} % \begin{syntax} % \cs{int_new:N} \meta{integer} % \end{syntax} % Creates a new \meta{inter} or raises an error if the name is % already taken. The declaration is global. The \meta{integer} will % initially be equal to \( 0 \). %\end{function} % %\begin{function}{ % \int_set_eq:NN | % \int_set_eq:cN | % \int_set_eq:Nc | % \int_set_eq:cc | %} % \begin{syntax} % \cs{int_set_eq:NN} \meta{integer1} \meta{integer 2} % \end{syntax} % Sets the content of \meta{integer1} equal to that of % \meta{integer 2}. This assignment is restricted to the current % \TeX\ group level. %\end{function} % %\begin{function}{ % \int_gset_eq:NN | % \int_gset_eq:cN | % \int_gset_eq:Nc | % \int_gset_eq:cc | %} % \begin{syntax} % \cs{int_gset_eq:NN} \meta{integer1} \meta{integer2} % \end{syntax} % Sets the content of \meta{integer1} equal to that of \meta{integer2}. % This assignment is global and so is not limited by the current % \TeX\ group level. %\end{function} % %\begin{function}{ % \int_add:Nn | % \int_add:cn | %} % \begin{syntax} % \cs{int_add:Nn} \meta{integer} \Arg{integer expression} % \end{syntax} % Adds the result of the \meta{integer expression} to the current % content of the \meta{integer}. This assignment is local. %\end{function} % %\begin{function}{ % \int_gadd:Nn | % \int_gadd:cn | %} % \begin{syntax} % \cs{int_gadd:Nn} \meta{integer} \Arg{integer expression} % \end{syntax} % Adds the result of the \meta{integer expression} to the current % content of the \meta{integer}. This assignment is global. %\end{function} % %\begin{function}{ % \int_decr:N | % \int_decr:c | %} % \begin{syntax} % \cs{int_decr:N} \meta{integer} % \end{syntax} % Decreases the value stored in \meta{integer} by \( 1 \) within % the scope of the current \TeX\ group. %\end{function} % %\begin{function}{ % \int_gdecr:N | % \int_gdecr:c | %} % \begin{syntax} % \cs{int_incr:N} \meta{integer} % \end{syntax} % Decreases the value stored in \meta{integer} by \( 1 \) globally % (\emph{i.e}.~not limited by the current group level). %\end{function} % %\begin{function}{ % \int_incr:N | % \int_incr:c | %} % \begin{syntax} % \cs{int_incr:N} \meta{integer} % \end{syntax} % Increases the value stored in \meta{integer} by \( 1 \) within % the scope of the current \TeX\ group. %\end{function} % %\begin{function}{ % \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 \) globally % (\emph{i.e}.~not limited by the current group level). %\end{function} % %\begin{function}{ % \int_set:Nn | % \int_set:cn | %} % \begin{syntax} % \cs{int_set:Nn} \meta{integer} \Arg{integer expression} % \end{syntax} % Sets \meta{integer} to the value of \meta{integer expression}, % which must evaluate to an integer (as described for % \cs{int_eval:n}). This assignment is restricted to the % current \TeX\ group. %\end{function} % %\begin{function}{ % \int_gset:Nn | % \int_gset:cn | %} % \begin{syntax} % \cs{int_gset:Nn} \meta{integer} \Arg{integer expression} % \end{syntax} % Sets \meta{integer} to the value of \meta{integer expression}, % which must evaluate to an integer (as described for % \cs{int_eval:n}). This assignment is global and is not limited % to the current \TeX\ group level. %\end{function} % %\begin{function}{ % \int_sub:Nn | % \int_sub:cn | %} % \begin{syntax} % \cs{int_sub:Nn} \meta{integer} \Arg{integer expression} % \end{syntax} % Subtracts the result of the \meta{integer expression} to the % current content of the \meta{integer}. This assignment is local. %\end{function} % %\begin{function}{ % \int_gsub:Nn | % \int_gsub:cn | %} % \begin{syntax} % \cs{int_gsub:Nn} \meta{integer} \Arg{integer expression} % \end{syntax} % Subtracts the result of the \meta{integer expression} to the % current content of the \meta{integer}. This assignment is global. %\end{function} % %\begin{function}{ % \int_zero:N | % \int_zero:c | %} % \begin{syntax} % \cs{int_zero:N} \meta{integer} % \end{syntax} % Sets \meta{integer} to \( 0 \) within the scope of the current % \TeX\ group. %\end{function} % %\begin{function}{ % \int_gzero:N | % \int_gzero:c | %} % \begin{syntax} % \cs{int_gzero:N} \meta{integer} % \end{syntax} % Sets \meta{integer} to \( 0 \) globally, \emph{i.e}.~not % restricted by the current \TeX\ group level. %\end{function} % %\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}{ % \int_use:N / (EXP) | % \int_use:c / (EXP) | %} % \begin{syntax} % \cs{int_use:N} \meta{integer} % \end{syntax} % Recovers the content of a \meta{integer} and places it directly % in the input stream. An error will be raised if the variable does % not exist or if it is invalid. Can be omitted in places where a % \meta{integer} is required (such as in the first and third arguments % of \cs{int_compare:nNnTF}). %\end{function} % %\subsection{Comparing integer expressions} % %\begin{function}{ % \int_compare_p:nNn / (EXP) | % \int_compare:nNn / (EXP) (TF) | %} % \begin{syntax} % \cs{int_compare_p:nNn} % ~~\Arg{intexpr1} \meta{relation} \Arg{intexpr2} % \cs{int_compare:nNnTF} % ~~\Arg{intexpr1} \meta{relation} \Arg{intexpr2} % ~~\Arg{true code} \Arg{false code} % \end{syntax} % This function first evaluates each of the \meta{integer expressions} % 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} % The branching versions then leave either \meta{true code} or % \meta{false code} in the input stream, as appropriate to the truth % of the test and the variant of the function chosen. The logical % truth of the test is left in the input stream by the predicate % version. %\end{function} % %\begin{function}{ % \int_compare_p:n / (EXP) | % \int_compare:n / (EXP) (TF) | %} % \begin{syntax} % \cs{int_compare_p:n} % ~~\{ \meta{intexpr1} \meta{relation} \meta{intexpr2} \} % \cs{int_compare:nTF} % ~~\{ \meta{intexpr1} \meta{relation} \meta{intexpr2} \} % ~~\Arg{true code} \Arg{false code} % \end{syntax} % This function first evaluates each of the \meta{integer expressions} % as described for \cs{int_eval:n}. The two results are then % compared using the \meta{relation}: % \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} % The branching versions then leave either \meta{true code} or % \meta{false code} in the input stream, as appropriate to the truth % of the test and the variant of the function chosen. The logical % truth of the test is left in the input stream by the predicate % version. %\end{function} % %\begin{function}{ % \int_if_even_p:n / (EXP) | % \int_if_even:n / (EXP) (TF) | % \int_if_odd_p:n / (EXP) | % \int_if_odd:n / (EXP) (TF) | %} % \begin{syntax} % \cs{int_if_odd_p:n} \Arg{integer expression} % \cs{int_if_odd:nTF} \Arg{integer expression} % ~~\Arg{true code} \Arg{false code} % \end{syntax} % This function first evaluates the \meta{integer expression} % as described for \cs{int_eval:n}. It then evaluates if this % is odd or even, as appropriate. The branching versions then leave % either \meta{true code} or \meta{false code} in the input stream, % as appropriate to the truth of the test and the variant of the % function chosen. The logical truth of the test is left in the input % stream by the predicate version. %\end{function} % %\begin{function}{ \int_do_while:nNnn / (EXP) } % \begin{syntax} % \cs{int_do_while:nNnn} % ~~\Arg{intexpr1} \meta{relation} \Arg{intexpr2} \Arg{code} % \end{syntax} % Evaluates the relationship between the two \meta{integer expressions} % 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 will be repeated, and a loop will occur until the test is % \texttt{false}. % \end{function} % %\begin{function}{ \int_do_until:nNnn / (EXP) } % \begin{syntax} % \cs{int_do_until:nNnn} % ~~\Arg{intexpr1} \meta{relation} \Arg{intexpr2} \Arg{code} % \end{syntax} % Evaluates the relationship between the two \meta{integer expressions} % 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 will be repeated, and a loop will occur until the test is % \texttt{true}. % \end{function} % %\begin{function}{ \int_until_do:nNnn / (EXP) } % \begin{syntax} % \cs{int_until_do:nNnn} % ~~\Arg{intexpr1} \meta{relation} \Arg{intexpr2} \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{integer expressions} as described for \cs{int_compare:nNnTF}. % If the test is \texttt{false} then the \meta{code} will be inserted % into the input stream again and a loop will occur until the % \meta{relation} is \texttt{true}. % \end{function} % %\begin{function}{ \int_while_do:nNnn / (EXP) } % \begin{syntax} % \cs{int_while_do:nNnn} \ % ~~\Arg{intexpr1} \meta{relation} \Arg{intexpr2} \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{integer expressions} as described for \cs{int_compare:nNnTF}. % If the test is \texttt{true} then the \meta{code} will be inserted % into the input stream again and a loop will occur until the % \meta{relation} is \texttt{false}. % \end{function} % %\begin{function}{ \int_do_while:nn / (EXP) } % \begin{syntax} % \cs{int_do_while:nNnn} % ~~\{ \meta{intexpr1} \meta{relation} \meta{intexpr2} \} \Arg{code} % \end{syntax} % Evaluates the relationship between the two \meta{integer expressions} % 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 will be repeated, and a loop will occur until the test is % \texttt{false}. % \end{function} % %\begin{function}{ \int_do_until:nn / (EXP) } % \begin{syntax} % \cs{int_do_until:nn} % ~~\{ \meta{intexpr1} \meta{relation} \meta{intexpr2} \} \Arg{code} % \end{syntax} % Evaluates the relationship between the two \meta{integer expressions} % 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 will be repeated, and a loop will occur until the test is % \texttt{true}. % \end{function} % %\begin{function}{ \int_until_do:nn / (EXP) } % \begin{syntax} % \cs{int_until_do:nn} % ~~\{ \meta{intexpr1} \meta{relation} \meta{intexpr2} \} \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{integer expressions} as described for \cs{int_compare:nTF}. % If the test is \texttt{false} then the \meta{code} will be inserted % into the input stream again and a loop will occur until the % \meta{relation} is \texttt{true}. % \end{function} % %\begin{function}{ \int_while_do:nn / (EXP) } % \begin{syntax} % \cs{int_while_do:nn} \ % ~~\{ \meta{intexpr1} \meta{relation} \meta{intexpr2} \} \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{integer expressions} as described for \cs{int_compare:nTF}. % If the test is \texttt{true} then the \meta{code} will be inserted % into the input stream again and a loop will occur until the % \meta{relation} is \texttt{false}. % \end{function} % %\subsection{Formatting integers} % % Integers can be placed into the output stream with formatting. These % conversions apply to any integer expressions. % %\begin{function}{ \int_to_arabic:n / (EXP) } % \begin{syntax} % \cs{int_to_arabic:n} \Arg{integer expression} % \end{syntax} % Places the value of the \meta{integer expression} in the input % stream as digits, with category code \( 12 \) (other). %\end{function} % %\begin{function}{ % \int_to_alph:n / (EXP) | % \int_to_Alph:n / (EXP) | %} % \begin{syntax} % \cs{int_to_alph:n} \Arg{integer expression} % \end{syntax} % Evaluates the \meta{integer expression} 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. 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_convert_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. %\end{function} % %\begin{function}{ \int_to_binary:n / (EXP) } % \begin{syntax} % \cs{int_to_binary:n} \Arg{integer expression} % \end{syntax} % Calculates the value of the \meta{integer expression} and places % the binary representation of the result in the input stream. %\end{function} % %\begin{function}{ \int_to_hexadecimal:n / (EXP) } % \begin{syntax} % \cs{int_to_binary:n} \Arg{integer expression} % \end{syntax} % Calculates the value of the \meta{integer expression} and places % the hexadecimal (base~\( 16 \)) representation of the result in the % input stream. Upper case letters are used for digits beyond \( 9 \). %\end{function} % %\begin{function}{ \int_to_octal:n / (EXP) } % \begin{syntax} % \cs{int_to_octal:n} \Arg{integer expression} % \end{syntax} % Calculates the value of the \meta{integer expression} and places % the octal (base~\( 8 \)) representation of the result in the input % stream. %\end{function} % %\begin{function}{ % \int_to_roman:n / (EXP) | % \int_to_Roman:n / (EXP) | %} % \begin{syntax} % \cs{int_to_roman:n} \Arg{integer expression} % \end{syntax} % Places the value of the \meta{integer expression} in the input % stream as Roman numerals, either lower case (\cs{int_to_roman:n}) % or upper case (\cs{int_to_Roman:n}). The numerals are letters % with category code \( 11 \) (letter). %\end{function} % %\begin{function}{ \int_to_symbol:n / (EXP) } % \begin{syntax} % \cs{int_to_symbol:n} \Arg{integer expression} % \end{syntax} % Calculates the value of the \meta{integer expression} and places % the symbol representation of the result in the input stream. The % list of symbols used is equivalent to \LaTeXe's \cs{@fnsymbol} % set. %\end{function} % %\subsection{Converting from other formats} % %\begin{function}{ \int_from_alph:n / (EXP) } % \begin{syntax} % \cs{int_from_alpa: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 treated using the English alphabet only, with % `a' equal to \( 1 \) through to `z' equal to \( 26 \). Either lower % or upper case letters may be used. This is the inverse function of % \cs{int_to_alph:n}. %\end{function} % %\begin{function}{ \int_from_binary:n / (EXP) } % \begin{syntax} % \cs{int_from_binary:n} \Arg{binary number} % \end{syntax} % Converts the \meta{binary number} into the integer (base~\( 10 \)) % representation and leaves this in the input stream. %\end{function} % %\begin{function}{ \int_from_hexadecimal:n / (EXP) } % \begin{syntax} % \cs{int_from_binary: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. %\end{function} % %\begin{function}{ \int_from_octal:n / (EXP) } % \begin{syntax} % \cs{int_from_octal:n} \Arg{octal number} % \end{syntax} % Converts the \meta{octal number} into the integer (base~\( 10 \)) % representation and leaves this in the input stream. %\end{function} % %\begin{function}{ \int_from_roman:n / (EXP) } % \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} may be in upper or lower case; if the numeral % is not valid then the resulting value will be \( -1 \). %\end{function} % %\subsection{Low-level conversion functions} % % As well as the higher-level functions already documented, there % are a series of lower-level functions which can be used to carry out % generic conversions. These are used to create the higher-level % versions documented above. % %\begin{function}{ \int_convert_from_base_ten:nn / (EXP) } % \begin{syntax} % \cs{int_convert_from_base_ten:nn} \Arg{integer expression} % ~~\Arg{base} % \end{syntax} % Calculates the value of the \meta{integer expression} 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 `digits' are represented by the upper case % letters from the English alphabet (with normal category codes). The % maximum \meta{base} value is \( 36 \). %\end{function} % %\begin{function}{ \int_convert_to_base_ten:nn / (EXP) } % \begin{syntax} % \cs{int_convert_to_base_ten:nn} \Arg{number} % ~~\Arg{base} % \end{syntax} % Converts the \meta{number} in \meta{base} into the appropriate % value in base \( 10 \). 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 \). %\end{function} % %\begin{function}{ \int_convert_to_symbols:nnn / (EXP) } % \begin{syntax} % \cs{int_convert_to_symbols:nnn} % ~~\Arg{integer expression} \Arg{total symbols} % ~~\meta{value to symbol mapping} % \end{syntax} % This is the low-level function for conversion of an % \meta{integer expression} into a symbolic form (which will often % be 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_convert_to_sybols: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{verbatim} %\end{function} % %\section{Variables and constants} % % \begin{variable}{% % \l_tmpa_int | % \l_tmpb_int | % \l_tmpc_int | % \g_tmpa_int | % \g_tmpb_int | % } % Scratch register for immediate use. They are not used by conditionals % or predicate functions. % \end{variable} % %\begin{function}{ % \int_const:Nn | % \int_const:cn | %} % \begin{syntax} % \cs{int_const:Nn} \meta{integer} \Arg{integer expression} % \end{syntax} % Creates a new constant \meta{integer} or raises an error if the name % is already taken. The value of the \meta{integer} will be set % globally to the \meta{integer expression}. %\end{function} % %\begin{variable}{ \c_max_int } % The maximum value that can be stored as an integer. %\end{variable} % %\begin{variable}{ % \c_minus_one | % \c_zero | % \c_one | % \c_two | % \c_three | % \c_four | % \c_five | % \c_six | % \c_seven | % \c_eight | % \c_nine | % \c_ten | % \c_eleven | % \c_twelve | % \c_thirteen | % \c_fourteen | % \c_fifteen | % \c_sixteen | % \c_thirty_two | % \c_hundred_one | % \c_twohundred_fifty_five | % \c_twohundred_fifty_six | % \c_thousand | % \c_ten_thousand | % \c_ten_thousand_one | % \c_ten_thousand_two | % \c_ten_thousand_three | % \c_ten_thousand_four | % \c_twenty_thousand | %} % Integer values used with primitive tests and assignments: % self-terminating nature makes these more convenient and faster than % literal numbers. %\end{variable} % % \begin{variable}{\c_max_register_int} % Maximum number of registers. % \end{variable} % %\subsection{Internal functions} % % \begin{function}{\int_to_roman:w / (EXP)} % \begin{syntax} % "\int_to_roman:w" \textit{or} % \end{syntax} % Converts to it lowercase roman representation. Note that % it produces a string of letters with catcode 12. % \begin{texnote} % This is the \TeX{} primitive \tn{romannumeral} renamed. % \end{texnote} % \end{function} % % \begin{function}{ % \int_roman_lcuc_mapping:Nnn | % \int_to_roman_lcuc:NN | % } % \begin{syntax} % "\int_roman_lcuc_mapping:Nnn" \Arg{licr} \Arg{LICR} % "\int_to_roman_lcuc:NN" % \end{syntax} % "\int_roman_lcuc_mapping:Nnn" specifies how the roman % numeral (i, v, x, l, c, d, or m) should be % interpreted when converting the number. is the lower case and % is the uppercase mapping. "\int_to_roman_lcuc:NN" is a % recursive function converting the roman numerals. % \end{function} % % % \begin{function}{ % \int_convert_number_with_rule:nnN | % \int_symbol_math_conversion_rule:n | % \int_symbol_text_conversion_rule:n | % } % \begin{syntax} % "\int_convert_number_with_rule:nnN" \Arg{int1} \Arg{int2} % \end{syntax} % "\int_convert_number_with_rule:nnN" converts into letters, % symbols, whatever as defined by . denotes the base % number for the conversion. % \end{function} % %\begin{function}{ % \if_num:w / (EXP) | % \if_int_compare:w / (EXP) %} % \begin{syntax} % "\if_num:w" "\else:" "\fi:" % \end{syntax} % Compare two integers using , which must be one of % \texttt{=}, "<" or ">" with category code \(12\). % The \cs{else:} branch is optional. % \begin{texnote} % These are both names for the \TeX\ primitive \cs{ifnum}. % \end{texnote} %\end{function} % %\begin{function}{ % \if_case:w / (EXP) | % \or: / (EXP) %} % \begin{syntax} % "\if_case:w" "\or:" "\or:" "..." "\else:" % "\fi:" % \end{syntax} % Selects a case to execute based on the value of . The first % case () is executed if is \(0\), the second % () if the is \(1\), \emph{etc}. The % 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 \cs{ifcase} and \cs{or}. % \end{texnote} %\end{function} % %\begin{function}{\int_value:w / (EXP)} % \begin{syntax} % "\int_value:w" % "\int_value:w" % \end{syntax} % Expands until an is formed. One space may be % gobbled in the process. % \begin{texnote} % This is the \TeX\ primitive \tn{number}. % \end{texnote} %\end{function} % %\begin{function}{ % \int_eval:w / (EXP) | % \int_eval_end: %} % \begin{syntax} % "\int_eval:w" "\int_eval_end:" % \end{syntax} % Evaluates as described for \cs{int_eval:n}. % The evalution stops when an unexpandable token with category code % other than \(12\) is read or when \cs{int_eval_end:} is % reached. The latter is gobbled by the scanner mechanism: % \cs{int_eval_end:} itself is unexpandable but used correctly % the entire construct is expandable. % \begin{texnote} % This is the \eTeX\ primitive \cs{numexpr}. % \end{texnote} %\end{function} % %\begin{function}{\if_int_odd:w / (EXP)} % \begin{syntax} % "\if_int_odd:w" "\else:" "\fi:" % "\if_int_odd:w" "\else:" "\fi:" % \end{syntax} % Expands until a non-numeric tokens is found, and % tests whether the resulting is odd. If so, % is executed. The \cs{else:} branch is optional. % \begin{texnote} % This is the \TeX\ primitive \cs{ifodd}. % \end{texnote} %\end{function} % % \end{documentation} % % \begin{implementation} % % \section{\pkg{l3int} implementation} % % \subsection{Internal functions and variables} % % \begin{function}{\int_advance:w} % \begin{syntax} % "\int_advance:w" % \end{syntax} % Increments the count register by the specified amount. % \begin{texnote} % This is \TeX's \tn{advance}. % \end{texnote} % \end{function} % % % \begin{function}{\int_convert_number_to_letter:n / (EXP)} % \begin{syntax} % "\int_convert_number_to_letter:n" \Arg{integer expression} % \end{syntax} % Internal function for turning a number for a different base into a letter or digit. % \end{function} % % \begin{function}{\int_pre_eval_one_arg:Nn | \int_pre_eval_two_args:Nnn} % \begin{syntax} % "\int_pre_eval_one_arg:Nn" \Arg{integer expression} % "\int_pre_eval_one_arg:Nnn" \Arg{int~expr~1} \Arg{int~expr~2} % \end{syntax} % These are expansion helpers; they evaluate their integer expressions % before handing them off to the specified . % \end{function} % % \begin{function}{ \int_get_sign_and_digits:n / (EXP) | % \int_get_sign:n / (EXP ) | % \int_get_digits:n / (EXP) } % \begin{syntax} % "\int_get_sign_and_digits:n" \Arg{number} % \end{syntax} % From an argument that may or may not include a "+" or "-" sign, these % functions expand to the respective components of the number. % \end{function} % % \subsection{Module loading and primitives definitions} % % We start by ensuring that the required packages are loaded. % \begin{macrocode} %<*package> \ProvidesExplPackage {\filename}{\filedate}{\fileversion}{\filedescription} \package_check_loaded_expl: % %<*initex|package> % \end{macrocode} % % \begin{macro}{\int_value:w} % \begin{macro}{\int_eval:n,\int_eval:w,\int_eval_end:} % \begin{macro}{\if_int_compare:w} % \begin{macro}{\if_int_odd:w} % \begin{macro}{\if_num:w} % \begin{macro}{\if_case:w} % \begin{macro}{\int_to_roman:w} % \begin{macro}{\int_advance:w} % Here are the remaining primitives for number comparisons and % expressions. % \begin{macrocode} \cs_set_eq:NN \int_value:w \tex_number:D \cs_set_eq:NN \int_eval:w \etex_numexpr:D \cs_set_protected:Npn \int_eval_end: {\tex_relax:D} \cs_set_eq:NN \if_int_compare:w \tex_ifnum:D \cs_new_eq:NN \if_num:w \tex_ifnum:D \cs_set_eq:NN \if_int_odd:w \tex_ifodd:D \cs_new_eq:NN \if_case:w \tex_ifcase:D \cs_new_eq:NN \int_to_roman:w \tex_romannumeral:D \cs_new_eq:NN \int_advance:w \tex_advance:D % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % % % \begin{macro}{\int_eval:n} % Wrapper for \cs{int_eval:w}. Can be used in an integer expression % or directly in the input stream. % \begin{macrocode} \cs_set:Npn \int_eval:n #1{ \int_value:w \int_eval:w #1\int_eval_end: } % \end{macrocode} % \end{macro} % % % % \subsection{Allocation and setting} % % \begin{macro}{\int_new:N,\int_new:c} % For the \LaTeX3 format: % \begin{macrocode} %<*initex> \alloc_new:nnnN {int} {11} {\c_max_register_int} \tex_countdef:D % % \end{macrocode} % For `l3in2e': % \begin{macrocode} %<*package> \cs_new_protected_nopar:Npn \int_new:N #1 { \chk_if_free_cs:N #1 \newcount #1 } % % \end{macrocode} % \begin{macrocode} \cs_generate_variant:Nn \int_new:N {c} % \end{macrocode} % \end{macro} % % % \begin{macro}{\int_set:Nn} % \begin{macro}{\int_set:cn} % \begin{macro}{\int_gset:Nn} % \begin{macro}{\int_gset:cn} % Setting counters is again something that I would like to make % uniform at the moment to get a better overview. % \begin{macrocode} \cs_new_protected_nopar:Npn \int_set:Nn #1#2{#1 \int_eval:w #2\int_eval_end: %<*check> \chk_local_or_pref_global:N #1 % } \cs_new_protected_nopar:Npn \int_gset:Nn { %<*check> \pref_global_chk: % %<-check> \pref_global:D \int_set:Nn } \cs_generate_variant:Nn\int_set:Nn {cn} \cs_generate_variant:Nn\int_gset:Nn {cn} % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % %\begin{macro}{\int_set_eq:NN} %\begin{macro}{\int_set_eq:cN} %\begin{macro}{\int_set_eq:Nc} %\begin{macro}{\int_set_eq:cc} %\begin{macro}{\int_gset_eq:NN} %\begin{macro}{\int_gset_eq:cN} %\begin{macro}{\int_gset_eq:Nc} %\begin{macro}{\int_gset_eq:cc} % Setting equal means using one integer inside the set function of % another. % \begin{macrocode} \cs_new_protected_nopar:Npn \int_set_eq:NN #1#2 { \int_set:Nn #1 {#2} } \cs_generate_variant:Nn \int_set_eq:NN { c } \cs_generate_variant:Nn \int_set_eq:NN { Nc } \cs_generate_variant:Nn \int_set_eq:NN { cc } \cs_new_protected_nopar:Npn \int_gset_eq:NN #1#2 { \int_gset:Nn #1 {#2} } \cs_generate_variant:Nn \int_gset_eq:NN { c } \cs_generate_variant:Nn \int_gset_eq:NN { Nc } \cs_generate_variant:Nn \int_gset_eq:NN { cc } % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} % % \begin{macro}{\int_incr:N} % \begin{macro}{\int_decr:N} % \begin{macro}{\int_gincr:N} % \begin{macro}{\int_gdecr:N} % \begin{macro}{\int_incr:c} % \begin{macro}{\int_decr:c} % \begin{macro}{\int_gincr:c} % \begin{macro}{\int_gdecr:c} % Incrementing and decrementing of integer registers is done with % the following functions. % \begin{macrocode} \cs_new_protected_nopar:Npn \int_incr:N #1{\int_advance:w#1\c_one %<*check> \chk_local_or_pref_global:N #1 % } \cs_new_protected_nopar:Npn \int_decr:N #1{\int_advance:w#1\c_minus_one %<*check> \chk_local_or_pref_global:N #1 % } \cs_new_protected_nopar:Npn \int_gincr:N { % \end{macrocode} % We make sure that a local variable is not updated globally by % changing the internal test (i.e.\ |\chk_local_or_pref_global:N|) before % making the assignment. This is done by |\pref_global_chk:| which also % issues the necessary |\pref_global:D|. This is not very efficient, but % this code will be only included for debugging purposes. Using % |\pref_global:D| in front of the local function is better in the % production versions. % \begin{macrocode} %<*check> \pref_global_chk: % %<-check> \pref_global:D \int_incr:N} \cs_new_protected_nopar:Npn \int_gdecr:N { %<*check> \pref_global_chk: % %<-check> \pref_global:D \int_decr:N} % \end{macrocode} % With the |\int_add:Nn| functions we can shorten the above code. % If this makes it too slow \ldots % \begin{macrocode} \cs_set_protected_nopar:Npn \int_incr:N #1{\int_add:Nn#1\c_one} \cs_set_protected_nopar:Npn \int_decr:N #1{\int_add:Nn#1\c_minus_one} \cs_set_protected_nopar:Npn \int_gincr:N #1{\int_gadd:Nn#1\c_one} \cs_set_protected_nopar:Npn \int_gdecr:N #1{\int_gadd:Nn#1\c_minus_one} % \end{macrocode} % % \begin{macrocode} \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} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % % % \begin{macro}{\int_zero:N} % \begin{macro}{\int_zero:c} % \begin{macro}{\int_gzero:N} % \begin{macro}{\int_gzero:c} % Functions that reset an \m{int} register to zero. % \begin{macrocode} \cs_new_protected_nopar:Npn \int_zero:N #1 {#1=\c_zero} \cs_generate_variant:Nn \int_zero:N {c} % \end{macrocode} % % \begin{macrocode} \cs_new_protected_nopar:Npn \int_gzero:N #1 {\pref_global:D #1=\c_zero} \cs_generate_variant:Nn \int_gzero:N {c} % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % % \begin{macro}{\int_add:Nn} % \begin{macro}{\int_add:cn} % \begin{macro}{\int_gadd:Nn} % \begin{macro}{\int_gadd:cn} % \begin{macro}{\int_sub:Nn} % \begin{macro}{\int_sub:cn} % \begin{macro}{\int_gsub:Nn} % \begin{macro}{\int_gsub:cn} % Adding and substracting to and from a counter \ldots % We should think of using these functions % \begin{macrocode} \cs_new_protected_nopar:Npn \int_add:Nn #1#2{ % \end{macrocode} % We need to say |by| in case the first argument is a register % accessed by its number, e.g., |\count23|. Not that it should % ever happen but\dots % \begin{macrocode} \int_advance:w #1 by \int_eval:w #2\int_eval_end: %<*check> \chk_local_or_pref_global:N #1 % } \cs_new_nopar:Npn \int_sub:Nn #1#2{ \int_advance:w #1-\int_eval:w #2\int_eval_end: %<*check> \chk_local_or_pref_global:N #1 % } \cs_new_protected_nopar:Npn \int_gadd:Nn { %<*check> \pref_global_chk: % %<-check> \pref_global:D \int_add:Nn } \cs_new_protected_nopar:Npn \int_gsub:Nn { %<*check> \pref_global_chk: % %<-check> \pref_global:D \int_sub:Nn } \cs_generate_variant:Nn \int_add:Nn {cn} \cs_generate_variant:Nn \int_gadd:Nn {cn} \cs_generate_variant:Nn \int_sub:Nn {cn} \cs_generate_variant:Nn \int_gsub:Nn {cn} % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % % % \begin{macro}{\int_use:N} % \begin{macro}{\int_use:c} % Here is how counters are accessed: % \begin{macrocode} \cs_new_eq:NN \int_use:N \tex_the:D \cs_new_nopar:Npn \int_use:c #1{\int_use:N \cs:w#1\cs_end:} % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\int_show:N} % \begin{macro}{\int_show:c} % \begin{macrocode} \cs_new_eq:NN \int_show:N \kernel_register_show:N \cs_new_eq:NN \int_show:c \kernel_register_show:c % \end{macrocode} % \end{macro} % \end{macro} % % % % % \begin{macro}{\int_to_arabic:n} % Nothing exciting here. % \begin{macrocode} \cs_new_nopar:Npn \int_to_arabic:n #1{ \int_eval:n{#1}} % \end{macrocode} % \end{macro} % % % % \begin{macro}{\int_roman_lcuc_mapping:Nnn} % Using \TeX's built-in feature for producing roman numerals has some % surprising features. One is the the characters resulting from % |\int_to_roman:w| have category code~12 so they may fail in % certain comparison tests. Therefore we use a mapping from the % character \TeX{} produces to the character we actually want which % will give us letters with category code~11.% % \begin{macrocode} \cs_new_protected_nopar:Npn \int_roman_lcuc_mapping:Nnn #1#2#3{ \cs_set_nopar:cpn {int_to_lc_roman_#1:}{#2} \cs_set_nopar:cpn {int_to_uc_roman_#1:}{#3} } % \end{macrocode} % \end{macro} % Here are the default mappings. I haven't found any examples of say % Turkish doing the mapping |i \i I| but at least there is a % possibility for it if needed. Note: I have now asked a Turkish % person and he tells me they do the |i I| mapping. % \begin{macrocode} \int_roman_lcuc_mapping:Nnn i i I \int_roman_lcuc_mapping:Nnn v v V \int_roman_lcuc_mapping:Nnn x x X \int_roman_lcuc_mapping:Nnn l l L \int_roman_lcuc_mapping:Nnn c c C \int_roman_lcuc_mapping:Nnn d d D \int_roman_lcuc_mapping:Nnn m m M % \end{macrocode} % For the delimiter we cheat and let it gobble its arguments instead. % \begin{macrocode} \int_roman_lcuc_mapping:Nnn Q \use_none:nn \use_none:nn % \end{macrocode} % % \begin{macro}{\int_to_roman:n} % \begin{macro}{\int_to_Roman:n} % \begin{macro}{\int_to_roman_lcuc:NN} % The commands for producing the lower and upper case roman numerals % run a loop on one character at a time and also carries some % information for upper or lower case with it. We put it through % |\int_eval:n| first which is safer and more flexible. % \begin{macrocode} \cs_new_nopar:Npn \int_to_roman:n #1 { \exp_after:wN \int_to_roman_lcuc:NN \exp_after:wN l \int_to_roman:w \int_eval:n {#1} Q } \cs_new_nopar:Npn \int_to_Roman:n #1 { \exp_after:wN \int_to_roman_lcuc:NN \exp_after:wN u \int_to_roman:w \int_eval:n {#1} Q } \cs_new_nopar:Npn \int_to_roman_lcuc:NN #1#2{ \use:c {int_to_#1c_roman_#2:} \int_to_roman_lcuc:NN #1 } % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % %\begin{macro}{\int_convert_to_symbols:nnn} % 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. This % is more or less the same as \cs{int_convert_number_with_rule:nnN} but % `pre-packaged'. % \begin{macrocode} \cs_new_nopar:Npn \int_convert_to_symbols:nnn #1#2#3 { \int_compare:nNnTF {#1} > {#2} { \exp_args:Nf \int_convert_to_symbols:nnn { \int_div_truncate:nn { #1 - 1 } {#2} } {#2} {#3} \exp_args:Nf \prg_case_int:nnn { \int_eval:n { 1 + \int_mod:nn { #1 - 1 } {#2} } } {#3} { } } { \exp_args:Nf \prg_case_int:nnn { \int_eval:n {#1} } {#3} { } } } % \end{macrocode} %\end{macro} % % % % \begin{macro}{\int_convert_number_with_rule:nnN} % This is our major workhorse for conversions. |#1| is the number we % want converted, |#2| is the base number, and |#3| is the function % converting the number. This function expects to receive a % non-negative integer and as such is ideal for something using % |\if_case:w| internally. % % The basic example is this: We want to convert the number 50 (|#1|) % into an alphabetic equivalent |ax|. For the English language our % list contains 26 elements so this is our argument |#2| while the % function |#3| just turns |1| into |a|, |2| into |b|, etc. Hence our % goal is to turn 50 into the sequence |#3{1}#1{24}| so what we do is % to first divide 50 by 26 and truncating the result returning 1. % Then before we execute this we call the function again but this time % on the result of the remainder of the division. This goes on until % the remainder is less than or equal to the base number where we just % call the function |#3| directly on the number. % % We do a little pre-expansion of the arguments below as they % otherwise have a tendency to grow quite large. % \begin{macrocode} \cs_set_nopar:Npn \int_convert_number_with_rule:nnN #1#2#3{ \int_compare:nNnTF {#1}>{#2} { \exp_args:Nf \int_convert_number_with_rule:nnN { \int_div_truncate:nn {#1-1}{#2} }{#2} #3 % \end{macrocode} % Note that we have to nudge our modulus function so it won't % return~$0$ as that wouldn't work with |\if_case:w| when that % expects a positive number to produce a letter. % \begin{macrocode} \exp_args:Nf #3 { \int_eval:n{1+\int_mod:nn {#1-1}{#2}} } } { \exp_args:Nf #3{ \int_eval:n{#1} } } } % \end{macrocode} % As can be seen it is even simpler to convert to number systems % that contain 0, since then we don't have to add or subtract 1 % here and there. % \end{macro} % % %\begin{macro}{\int_to_alph:n} %\begin{macro}{\int_to_Alph:n} % These both use the above function with input functions that make sense % for the alphabet in English. % \begin{macrocode} \cs_new_nopar:Npn \int_to_alph:n #1 { \int_convert_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_nopar:Npn \int_to_Alph:n #1 { \int_convert_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} %\end{macro} % % \begin{macro}{\int_to_symbol:n} % Turning a number into a symbol is also easy enough. % \begin{macrocode} \cs_new_nopar:Npn \int_to_symbol:n #1{ \mode_if_math:TF { \int_convert_number_with_rule:nnN {#1}{9} \int_symbol_math_conversion_rule:n } { \int_convert_number_with_rule:nnN {#1}{9} \int_symbol_text_conversion_rule:n } } % \end{macrocode} % \end{macro} % \begin{macro}{\int_symbol_math_conversion_rule:n} % \begin{macro}{\int_symbol_text_conversion_rule:n} % Nothing spectacular here. % \begin{macrocode} \cs_new_nopar:Npn \int_symbol_math_conversion_rule:n #1 { \if_case:w #1 \or: * \or: \dagger \or: \ddagger \or: \mathsection \or: \mathparagraph \or: \| \or: ** \or: \dagger\dagger \or: \ddagger\ddagger \fi: } \cs_new_nopar:Npn \int_symbol_text_conversion_rule:n #1 { \if_case:w #1 \or: \textasteriskcentered \or: \textdagger \or: \textdaggerdbl \or: \textsection \or: \textparagraph \or: \textbardbl \or: \textasteriskcentered\textasteriskcentered \or: \textdagger\textdagger \or: \textdaggerdbl\textdaggerdbl \fi: } % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\l_tmpa_int} % \begin{macro}{\l_tmpb_int} % \begin{macro}{\l_tmpc_int} % \begin{macro}{\g_tmpa_int} % \begin{macro}{\g_tmpb_int} % We provide four 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 \l_tmpc_int \int_new:N \g_tmpa_int \int_new:N \g_tmpb_int % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % % % % % \begin{macro}{\int_pre_eval_one_arg:Nn} % \begin{macro}{\int_pre_eval_two_args:Nnn} % These are handy when handing down values to other % functions. All they do is evaluate the number in advance. % \begin{macrocode} \cs_set_nopar:Npn \int_pre_eval_one_arg:Nn #1#2{ \exp_args:Nf#1{\int_eval:n{#2}}} \cs_set_nopar:Npn \int_pre_eval_two_args:Nnn #1#2#3{ \exp_args:Nff#1{\int_eval:n{#2}}{\int_eval:n{#3}} } % \end{macrocode} % \end{macro} % \end{macro} % % % % % % % \subsection{Scanning and conversion} % % %\begin{macro}{\int_from_roman:n} %\begin{macro}[aux]{\int_from_roman_aux:NN} %\begin{macro}[aux]{\int_from_roman_end:w} %\begin{macro}[aux]{\int_from_roman_clean_up: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. % \begin{macrocode} \cs_new_nopar:Npn \int_from_roman:n #1 { \tl_if_blank:nF {#1} { \tex_expandafter:D \int_from_roman_end:w \tex_number:D \etex_numexpr:D \int_from_roman_aux:NN #1 Q \q_stop } } \cs_new_nopar:Npn \int_from_roman_aux:NN #1#2 { \str_if_eq:nnTF {#1} { Q } {#1#2} { \str_if_eq:nnTF {#2} { Q } { \cs_if_exist:cF { c_int_from_roman_ #1 _int } { \int_from_roman_clean_up:w } + \use:c { c_int_from_roman_ #1 _int } #2 } { \cs_if_exist:cF { c_int_from_roman_ #1 _int } { \int_from_roman_clean_up:w } \cs_if_exist:cF { c_int_from_roman_ #2 _int } { \int_from_roman_clean_up:w } \int_compare:nNnTF { \use:c { c_int_from_roman_ #1 _int } } < { \use:c { c_int_from_roman_ #2 _int } } { + \use:c { c_int_from_roman_ #2 _int } - \use:c { c_int_from_roman_ #1 _int } \int_from_roman_aux:NN } { + \use:c { c_int_from_roman_ #1 _int } \int_from_roman_aux:NN #2 } } } } \cs_new_nopar:Npn \int_from_roman_end:w #1 Q #2 \q_stop { \tl_if_empty:nTF {#2} {#1} {#2} } \cs_new_nopar:Npn \int_from_roman_clean_up:w #1 Q { + 0 Q -1 } % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} % %\begin{macro}{\int_convert_from_base_ten:nn} %\begin{macro}[aux]{\int_convert_from_base_ten_aux:nnn} %\begin{macro}{\int_convert_number_to_letter:n} % Converting from base ten ("#1") to a second base ("#2") starts with % a simple sign check. As the input is base \( 10 \) \TeX\ can then % do the actual work with the sign itself. % \begin{macrocode} \cs_new:Npn \int_convert_from_base_ten:nn #1#2 { \int_compare:nNnTF {#1} < { 0 } { - \exp_args:Nnf \int_convert_from_base_ten_aux:nnn { } { \int_eval:n { 0 - ( #1 ) } } {#2} } { \exp_args:Nnf \int_convert_from_base_ten_aux:nnn { } { \int_eval:n {#1} } {#2} } } % \end{macrocode} % Here, the idea is to provide a recursive system to deal with the % input. The output is build up as argument "#1", which is why it % starts off empty in the above. At each pass, the value in "#2" is % checked to see if it is less than the new base ("#3"). If it is % the it is converted directly and the rest of the output is added in. % 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 the remainder is carried forward % to the next round.S % \begin{macrocode} \cs_new:Npn \int_convert_from_base_ten_aux:nnn #1#2#3 { \int_compare:nNnTF {#2} < {#3} { \int_convert_number_to_letter:n {#2} #1 } { \exp_args:Nff \int_convert_from_base_ten_aux:nnn { \int_convert_number_to_letter:n { \int_mod:nn {#2} {#3} } #1 } { \int_div_truncate:nn {#2} {#3} } {#3} } } % \end{macrocode} % Convert to a letter only if necessary, otherwise simply return the % value unchanged. % \begin{macrocode} \cs_new:Npn \int_convert_number_to_letter:n #1 { \prg_case_int:nnn { #1 - 9 } { { 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 } } {#1} } % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} % %\begin{macro}{\int_convert_to_base_ten:nn} %\begin{macro}[aux]{\int_convert_to_base_ten_aux:nn} %\begin{macro}[aux]{\int_convert_to_base_ten_aux:nnN} %\begin{macro}[aux]{\int_convert_to_base_ten_aux:N} %\begin{macro}{\int_get_sign_and_digits:n} %\begin{macro}{\int_get_sign:n} %\begin{macro}{\int_get_digits:n} %\begin{macro}[aux]{\int_get_sign_and_digits_aux:nNNN} %\begin{macro}[aux]{\int_get_sign_and_digits_aux:oNNN} % Conversion to base ten means stripping off the sign then iterating % through the input one token at a time. The total number is then added % up as the code loops. % \begin{macrocode} \cs_new:Npn \int_convert_to_base_ten:nn #1#2 { \int_eval:n { \int_get_sign:n {#1} \exp_args:Nf \int_convert_to_base_ten_aux:nn { \int_get_digits:n {#1} } {#2} } } \cs_new:Npn \int_convert_to_base_ten_aux:nn #1#2 { \int_convert_to_base_ten_aux:nnN { 0 } { #2 } #1 \q_nil } \cs_new:Npn \int_convert_to_base_ten_aux:nnN #1#2#3 { \quark_if_nil:NTF #3 {#1} { \exp_args:Nf \int_convert_to_base_ten_aux:nnN { \int_eval:n { #1 * #2 + \int_convert_to_base_ten_aux:N #3 } } {#2} } } % \end{macrocode} % The conversion here will take lower or upper case letters and turn % them into the appropriate number, hence the two-part nature of the % function. % \begin{macrocode} \cs_new:Npn \int_convert_to_base_ten_aux:N #1 { \int_compare:nNnTF { `#1 } < { 58 } {#1} { \int_eval:n { `#1 - \int_compare:nNnTF { `#1 } < { 91 } { 55 } { 87 } } } } % \end{macrocode} % Finding a number and its sign requires dealing with an arbitrary % list of "+" and "-" symbols. This is done by working through token % by token until there is something else at the start of the input. % The sign of the input is tracked by the first Boolean used by the % auxiliary function. % \begin{macrocode} \cs_new:Npn \int_get_sign_and_digits:n #1 { \int_get_sign_and_digits_aux:nNNN {#1} \c_true_bool \c_true_bool \c_true_bool } \cs_new:Npn \int_get_sign:n #1 { \int_get_sign_and_digits_aux:nNNN {#1} \c_true_bool \c_true_bool \c_false_bool } \cs_new:Npn \int_get_digits:n #1 { \int_get_sign_and_digits_aux:nNNN {#1} \c_true_bool \c_false_bool \c_true_bool } % \end{macrocode} % The auxiliary loops through, finding sign tokens and removing them. % The sign itself is carried through as a flag. % \begin{macrocode} \cs_new:Npn \int_get_sign_and_digits_aux:nNNN #1#2#3#4 { \tl_if_head_eq_charcode:fNTF {#1} - { \bool_if:NTF #2 { \int_get_sign_and_digits_aux:oNNN { \use_none:n #1 } \c_false_bool #3#4 } { \int_get_sign_and_digits_aux:oNNN { \use_none:n #1 } \c_true_bool #3#4 } } { \tl_if_head_eq_charcode:fNTF {#1} + { \int_get_sign_and_digits_aux:oNNN { \use_none:n #1 } #2#3#4 } { \bool_if:NT #3 { \bool_if:NF #2 - } \bool_if:NT #4 {#1} } } } \cs_generate_variant:Nn \int_get_sign_and_digits_aux:nNNN { o } % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} % %\begin{macro}{\int_from_binary:n} %\begin{macro}{\int_from_hexadecimal:n} %\begin{macro}{\int_from_octal:n} %\begin{macro}{\int_to_binary:n} %\begin{macro}{\int_to_hexadecimal:n} %\begin{macro}{\int_to_octal:n} % Wrappers around the generic function. % \begin{macrocode} \cs_new:Npn \int_from_binary:n #1 { \int_convert_to_base_ten:nn {#1} { 2 } } \cs_new:Npn \int_from_hexadecimal:n #1 { \int_convert_to_base_ten:nn {#1} { 16 } } \cs_new:Npn \int_from_octal:n #1 { \int_convert_to_base_ten:nn {#1} { 8 } } \cs_new:Npn \int_to_binary:n #1 { \int_convert_from_base_ten:nn {#1} { 2 } } \cs_new:Npn \int_to_hexadecimal:n #1 { \int_convert_from_base_ten:nn {#1} { 16 } } \cs_new:Npn \int_to_octal:n #1 { \int_convert_from_base_ten:nn {#1} { 8 } } % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} % %\begin{macro}{\int_from_alph:n} %\begin{macro}[aux]{\int_from_alph_aux:n} %\begin{macro}[aux]{\int_from_alph_aux:nN} %\begin{macro}[aux]{\int_from_alph_aux:N} % The aim here is to iterate through the input, converting one letter at % a time to a number. The same approach is also used for base % conversion, but this needs a different final auxiliary. % \begin{macrocode} \cs_new:Npn \int_from_alph:n #1 { \int_eval:n { \int_get_sign:n {#1} \exp_args:Nf \int_from_alph_aux:n { \int_get_digits:n {#1} } } } \cs_new:Npn \int_from_alph_aux:n #1 { \int_from_alph_aux:nN { 0 } #1 \q_nil } \cs_new:Npn \int_from_alph_aux:nN #1#2 { \quark_if_nil:NTF #2 {#1} { \exp_args:Nf \int_from_alph_aux:nN { \int_eval:n { #1 * 26 + \int_from_alph_aux:N #2 } } } } \cs_new:Npn \int_from_alph_aux:N #1 { \int_eval:n { `#1 - \int_compare:nNnTF { `#1 } < { 91 } { 64 } { 96 } } } % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} % % % \begin{macro}{\int_compare_p:n} % \begin{macro}[TF]{\int_compare:n} % Comparison tests using a simple syntax where only one set of braces % is required and additional operators such as "!=" and ">=" are % supported. First some notes on the idea behind this. We wish to % support writing code like % \begin{verbatim} % \int_compare_p:n { 5 + \l_tmpa_int != 4 - \l_tmpb_int } % \end{verbatim} % In other words, we want to somehow add the missing "\int_eval:w" % where required. We can start evaluating from the left using % "\int_eval:w", and we know that since the relation symbols "<", ">", % "=" and "!" are not allowed in such expressions, they will terminate % the expression. Therefore, we first let \TeX\ evaluate this left % hand side of the (in)equality. % \begin{macrocode} \prg_set_conditional:Npnn \int_compare:n #1{p,TF,T,F}{ \exp_after:wN \int_compare_auxi:w \int_value:w \int_eval:w #1\q_stop } % \end{macrocode} % Then the next step is to figure out which relation we should use, so % we have to somehow get rid of the first evaluation so that we can % see what stopped it. "\tex_romannumeral:D" is handy here since its % expansion given a non-positive number is \m{null}. We therefore % simply check if the first token of the left hand side evaluation is % a minus. If not, we insert it and issue "\tex_romannumeral:D", % thereby ridding us of the left hand side evaluation. We do however % save it for later. % \begin{macrocode} \cs_set:Npn \int_compare_auxi:w #1#2\q_stop{ \exp_after:wN \int_compare_auxii:w \tex_romannumeral:D \if:w #1- \else: -\fi: #1#2 \q_mark #1#2 \q_stop } % \end{macrocode} % This leaves the first relation symbol in front and assuming the % right hand side has been input, at least one other token as well. We % support the following forms: |=|, |<|, |>| and the extended |!=|, % |==|, |<=| and |>=|. All the extended forms have an extra |=| so we % check if that is present as well. Then use specific function to % perform the test. % \begin{macrocode} \cs_set:Npn \int_compare_auxii:w #1#2#3\q_mark{ \use:c{ int_compare_ #1 \if_meaning:w =#2 = \fi: :w} } % \end{macrocode} % The actual comparisons are then simple function calls, using the % relation as delimiter for a delimited argument. % Equality is easy: % \begin{macrocode} \cs_set:cpn {int_compare_=:w} #1=#2\q_stop{ \if_int_compare:w #1=\int_eval:w #2 \int_eval_end: \prg_return_true: \else: \prg_return_false: \fi: } % \end{macrocode} % So is the one using |==| -- we just have to use |==| in the % parameter text. % \begin{macrocode} \cs_set:cpn {int_compare_==:w} #1==#2\q_stop{ \if_int_compare:w #1=\int_eval:w #2 \int_eval_end: \prg_return_true: \else: \prg_return_false: \fi: } % \end{macrocode} % Not equal is just about reversing the truth value. % \begin{macrocode} \cs_set:cpn {int_compare_!=:w} #1!=#2\q_stop{ \if_int_compare:w #1=\int_eval:w #2 \int_eval_end: \prg_return_false: \else: \prg_return_true: \fi: } % \end{macrocode} % Less than and greater than are also straight forward. % \begin{macrocode} \cs_set:cpn {int_compare_<:w} #1<#2\q_stop{ \if_int_compare:w #1<\int_eval:w #2 \int_eval_end: \prg_return_true: \else: \prg_return_false: \fi: } \cs_set:cpn {int_compare_>:w} #1>#2\q_stop{ \if_int_compare:w #1>\int_eval:w #2 \int_eval_end: \prg_return_true: \else: \prg_return_false: \fi: } % \end{macrocode} % The less than or equal operation is just the opposite of the greater % than operation. Vice versa for less than or equal. % \begin{macrocode} \cs_set:cpn {int_compare_<=:w} #1<=#2\q_stop{ \if_int_compare:w #1>\int_eval:w #2 \int_eval_end: \prg_return_false: \else: \prg_return_true: \fi: } \cs_set:cpn {int_compare_>=:w} #1>=#2\q_stop{ \if_int_compare:w #1<\int_eval:w #2 \int_eval_end: \prg_return_false: \else: \prg_return_true: \fi: } % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\int_compare_p:nNn} % \begin{macro}[TF]{\int_compare:nNn} % More efficient but less natural in typing. % \begin{macrocode} \prg_set_conditional:Npnn \int_compare:nNn #1#2#3{p}{ \if_int_compare:w \int_eval:w #1 #2 \int_eval:w #3 \int_eval_end: \prg_return_true: \else: \prg_return_false: \fi: } \cs_set_nopar:Npn \int_compare:nNnT #1#2#3 { \tex_ifnum:D \etex_numexpr:D #1 #2 \etex_numexpr:D #3 \scan_stop: \tex_expandafter:D \use:n \tex_else:D \tex_expandafter:D \use_none:n \tex_fi:D } \cs_set_nopar:Npn \int_compare:nNnF #1#2#3 { \tex_ifnum:D \etex_numexpr:D #1 #2 \etex_numexpr:D #3 \scan_stop: \tex_expandafter:D \use_none:n \tex_else:D \tex_expandafter:D \use:n \tex_fi:D } \cs_set_nopar:Npn \int_compare:nNnTF #1#2#3 { \tex_ifnum:D \etex_numexpr:D #1 #2 \etex_numexpr:D #3 \scan_stop: \tex_expandafter:D \use_i:nn \tex_else:D \tex_expandafter:D \use_ii:nn \tex_fi:D } % \end{macrocode} % \end{macro} % \end{macro} % % \begin{macro}{\int_max:nn} % \begin{macro}{\int_min:nn} % \begin{macro}{\int_abs:n} % Functions for $\min$, $\max$, and absolute value. % \begin{macrocode} \cs_set:Npn \int_abs:n #1{ \int_value:w \if_int_compare:w \int_eval:w #1<\c_zero - \fi: \int_eval:w #1\int_eval_end: } \cs_set:Npn \int_max:nn #1#2{ \int_value:w \int_eval:w \if_int_compare:w \int_eval:w #1>\int_eval:w #2\int_eval_end: #1 \else: #2 \fi: \int_eval_end: } \cs_set:Npn \int_min:nn #1#2{ \int_value:w \int_eval:w \if_int_compare:w \int_eval:w #1<\int_eval:w #2\int_eval_end: #1 \else: #2 \fi: \int_eval_end: } % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % % % \begin{macro}{\int_div_truncate:nn} % \begin{macro}{\int_div_round:nn} % \begin{macro}{\int_mod:nn} % As "\int_eval:w" rounds the result of a division we also % provide a version that truncates the result. % \begin{macrocode} % \end{macrocode} % Initial version didn't work correctly with e\TeX's implementation. % \begin{macrocode} %\cs_set:Npn \int_div_truncate_raw:nn #1#2 { % \int_eval:n{ (2*#1 - #2) / (2* #2) } %} % \end{macrocode} % New version by Heiko: % \begin{macrocode} \cs_set:Npn \int_div_truncate:nn #1#2 { \int_value:w \int_eval:w \if_int_compare:w \int_eval:w #1 = \c_zero 0 \else: (#1 \if_int_compare:w \int_eval:w #1 < \c_zero \if_int_compare:w \int_eval:w #2 < \c_zero -( #2 + \else: +( #2 - \fi: \else: \if_int_compare:w \int_eval:w #2 < \c_zero +( #2 + \else: -( #2 - \fi: \fi: 1)/2) \fi: /(#2) \int_eval_end: } % \end{macrocode} % For the sake of completeness: % \begin{macrocode} \cs_set:Npn \int_div_round:nn #1#2 {\int_eval:n{(#1)/(#2)}} % \end{macrocode} % Finally there's the modulus operation. % \begin{macrocode} \cs_set:Npn \int_mod:nn #1#2 { \int_value:w \int_eval:w #1 - \int_div_truncate:nn {#1}{#2} * (#2) \int_eval_end: } % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % % \begin{macro}{\int_if_odd_p:n} % \begin{macro}[TF]{\int_if_odd:n} % \begin{macro}{\int_if_even_p:n} % \begin{macro}[TF]{\int_if_even:n} % A predicate function. % \begin{macrocode} \prg_set_conditional:Npnn \int_if_odd:n #1 {p,TF,T,F} { \if_int_odd:w \int_eval:w #1\int_eval_end: \prg_return_true: \else: \prg_return_false: \fi: } \prg_set_conditional:Npnn \int_if_even:n #1 {p,TF,T,F} { \if_int_odd:w \int_eval:w #1\int_eval_end: \prg_return_false: \else: \prg_return_true: \fi: } % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % % \begin{macro}{\int_while_do:nn} % \begin{macro}{\int_until_do:nn} % \begin{macro}{\int_do_while:nn} % \begin{macro}{\int_do_until:nn} % 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_set:Npn \int_while_do:nn #1#2{ \int_compare:nT {#1}{#2 \int_while_do:nn {#1}{#2}} } \cs_set:Npn \int_until_do:nn #1#2{ \int_compare:nF {#1}{#2 \int_until_do:nn {#1}{#2}} } \cs_set:Npn \int_do_while:nn #1#2{ #2 \int_compare:nT {#1}{\int_do_while:nNnn {#1}{#2}} } \cs_set: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_set: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_set: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_set: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_set: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{Defining constants} % \begin{macro}{\int_const:Nn} % \begin{macro}{\int_const:cn} % As stated, most constants can be defined as |\tex_chardef:D| or % |\tex_mathchardef:D| but that's engine dependent. % \begin{macrocode} \cs_new_protected_nopar:Npn \int_const:Nn #1#2 { \int_compare:nTF { #2 > \c_minus_one } { \int_compare:nTF { #2 > \c_max_register_int } { \int_new:N #1 \int_gset:Nn #1 {#2} } { \chk_if_free_cs:N #1 \tex_global:D \tex_mathchardef:D #1 = \int_eval:n {#2} } } { \int_new:N #1 \int_gset:Nn #1 {#2} } } \cs_generate_variant:Nn \int_const:Nn { c } % \end{macrocode} % \end{macro} % \end{macro} % %\begin{macro}{\c_max_register_int} % This is here as this particular integer is needed both in package % mode and to bootstrap \pkg{l3alloc} % \begin{macrocode} \tex_mathchardef:D \c_max_register_int = 32767 \scan_stop: % \end{macrocode} % \end{macro} % % \begin{macro}{\c_minus_one, % \c_zero, \c_one, \c_two, \c_three, \c_four, \c_five, \c_six, % \c_seven, \c_eight, \c_nine, \c_ten, % \c_eleven, \c_twelve, \c_thirteen, \c_fourteen, \c_fifteen, % \c_sixteen, \c_thirty_two, % \c_hundred_one, % \c_twohundred_fifty_five, \c_twohundred_fifty_six, % \c_thousand, % \c_ten_thousand, % \c_ten_thousand_one, \c_ten_thousand_two, % \c_ten_thousand_three, \c_ten_thousand_four, % \c_twenty_thousand} % And the usual constants, others are still missing. Please, make % every constant a real constant at least for the moment. We can % easily convert things in the end when we have found what % constants are used in critical places and what not. % \begin{macrocode} %% \tex_countdef:D \c_minus_one = 10 \scan_stop: %% \c_minus_one = -1 \scan_stop: %% in l3basics %\int_const:Nn \c_zero {0} \int_const:Nn \c_one {1} \int_const:Nn \c_two {2} \int_const:Nn \c_three {3} \int_const:Nn \c_four {4} \int_const:Nn \c_five {5} \int_const:Nn \c_six {6} \int_const:Nn \c_seven {7} \int_const:Nn \c_eight {8} \int_const:Nn \c_nine {9} \int_const:Nn \c_ten {10} \int_const:Nn \c_eleven {11} \int_const:Nn \c_twelve {12} \int_const:Nn \c_thirteen {13} \int_const:Nn \c_fourteen {14} \int_const:Nn \c_fifteen {15} %% \tex_chardef:D \c_sixteen = 16\scan_stop: %% in l3basics \int_const:Nn \c_thirty_two {32} % \end{macrocode} % The next one may seem a little odd (obviously!) but is useful when % dealing with logical operators. % \begin{macrocode} \int_const:Nn \c_hundred_one {101} \int_const:Nn \c_twohundred_fifty_five{255} \int_const:Nn \c_twohundred_fifty_six {256} \int_const:Nn \c_thousand {1000} \int_const:Nn \c_ten_thousand {10000} \int_const:Nn \c_ten_thousand_one {10001} \int_const:Nn \c_ten_thousand_two {10002} \int_const:Nn \c_ten_thousand_three {10003} \int_const:Nn \c_ten_thousand_four {10004} \int_const:Nn \c_twenty_thousand {20000} % \end{macrocode} % \end{macro} % % \begin{macro}{\c_max_int} % The largest number allowed is $2^{31}-1$ % \begin{macrocode} \int_const:Nn \c_max_int {2147483647} % \end{macrocode} % \end{macro} % %\begin{macro}[aux]{\c_int_from_roman_i_int} %\begin{macro}[aux]{\c_int_from_roman_v_int} %\begin{macro}[aux]{\c_int_from_roman_x_int} %\begin{macro}[aux]{\l_int_from_roman_l_int} %\begin{macro}[aux]{\c_int_from_roman_c_int} %\begin{macro}[aux]{\c_int_from_roman_d_int} %\begin{macro}[aux]{\c_int_from_roman_m_int} %\begin{macro}[aux]{\c_int_from_roman_I_int} %\begin{macro}[aux]{\c_int_from_roman_V_int} %\begin{macro}[aux]{\c_int_from_roman_X_int} %\begin{macro}[aux]{\c_int_from_roman_L_int} %\begin{macro}[aux]{\c_int_from_roman_C_int} %\begin{macro}[aux]{\c_int_from_roman_D_int} %\begin{macro}[aux]{\c_int_from_roman_M_int} % Delayed from earlier. % \begin{macrocode} \int_const:cn { c_int_from_roman_i_int } { 1 } \int_const:cn { c_int_from_roman_v_int } { 5 } \int_const:cn { c_int_from_roman_x_int } { 10 } \int_const:cn { c_int_from_roman_l_int } { 50 } \int_const:cn { c_int_from_roman_c_int } { 100 } \int_const:cn { c_int_from_roman_d_int } { 500 } \int_const:cn { c_int_from_roman_m_int } { 1000 } \int_const:cn { c_int_from_roman_I_int } { 1 } \int_const:cn { c_int_from_roman_V_int } { 5 } \int_const:cn { c_int_from_roman_X_int } { 10 } \int_const:cn { c_int_from_roman_L_int } { 50 } \int_const:cn { c_int_from_roman_C_int } { 100 } \int_const:cn { c_int_from_roman_D_int } { 500 } \int_const:cn { c_int_from_roman_M_int } { 1000 } % \end{macrocode} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} %\end{macro} % % Needed from the tl module: % \begin{macrocode} \int_new:N \g_tl_inline_level_int % \end{macrocode} % % \subsection{Backwards compatibility} % \begin{macrocode} \cs_set_eq:NN \intexpr_value:w \int_value:w \cs_set_eq:NN \intexpr_eval:w \int_eval:w \cs_set_eq:NN \intexpr_eval_end: \int_eval_end: \cs_set_eq:NN \if_intexpr_compare:w \if_int_compare:w \cs_set_eq:NN \if_intexpr_odd:w \if_int_odd:w \cs_set_eq:NN \if_intexpr_case:w \if_case:w \cs_set_eq:NN \intexpr_eval:n \int_eval:n \cs_set_eq:NN \intexpr_compare_p:n \int_compare_p:n \cs_set_eq:NN \intexpr_compare:nTF \int_compare:nTF \cs_set_eq:NN \intexpr_compare:nT \int_compare:nT \cs_set_eq:NN \intexpr_compare:nF \int_compare:nF \cs_set_eq:NN \intexpr_compare_p:nNn \int_compare_p:nNn \cs_set_eq:NN \intexpr_compare:nNnTF \int_compare:nNnTF \cs_set_eq:NN \intexpr_compare:nNnT \int_compare:nNnT \cs_set_eq:NN \intexpr_compare:nNnF \int_compare:nNnF \cs_set_eq:NN \intexpr_abs:n \int_abs:n \cs_set_eq:NN \intexpr_max:nn \int_max:nn \cs_set_eq:NN \intexpr_min:nn \int_min:nn \cs_set_eq:NN \intexpr_div_truncate:nn \int_div_truncate:nn \cs_set_eq:NN \intexpr_div_round:nn \int_div_round:nn \cs_set_eq:NN \intexpr_mod:nn \int_mod:nn \cs_set_eq:NN \intexpr_if_odd_p:n \int_if_odd_p:n \cs_set_eq:NN \intexpr_if_odd:nTF \int_if_odd:nTF \cs_set_eq:NN \intexpr_if_odd:nT \int_if_odd:nT \cs_set_eq:NN \intexpr_if_odd:nF \int_if_odd:nF \cs_set_eq:NN \intexpr_if_even_p:n \int_if_even_p:n \cs_set_eq:NN \intexpr_if_even:nTF \int_if_even:nTF \cs_set_eq:NN \intexpr_if_even:nT \int_if_even:nT \cs_set_eq:NN \intexpr_if_even:nF \int_if_even:nF \cs_set_eq:NN \intexpr_while_do:nn \int_while_do:nn \cs_set_eq:NN \intexpr_until_do:nn \int_until_do:nn \cs_set_eq:NN \intexpr_do_while:nn \int_do_while:nn \cs_set_eq:NN \intexpr_do_until:nn \int_do_until:nn \cs_set_eq:NN \intexpr_while_do:nNnn \int_while_do:nNnn \cs_set_eq:NN \intexpr_until_do:nNnn \int_until_do:nNnn \cs_set_eq:NN \intexpr_do_while:nNnn \int_do_while:nNnn \cs_set_eq:NN \intexpr_do_until:nNnn \int_do_until:nNnn % \end{macrocode} % % \begin{macrocode} % % \end{macrocode} % % Show token usage: % \begin{macrocode} %<*showmemory> \showMemUsage % % \end{macrocode} % % \end{implementation} % \PrintIndex % % % \endinput