summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/expl3/l3int.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/source/latex/expl3/l3int.dtx')
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3int.dtx1222
1 files changed, 857 insertions, 365 deletions
diff --git a/Master/texmf-dist/source/latex/expl3/l3int.dtx b/Master/texmf-dist/source/latex/expl3/l3int.dtx
index d219a9d27bb..f4e582ec12f 100644
--- a/Master/texmf-dist/source/latex/expl3/l3int.dtx
+++ b/Master/texmf-dist/source/latex/expl3/l3int.dtx
@@ -1,15 +1,50 @@
% \iffalse
-%% File: l3int.dtx Copyright (C) 1990-1998 LaTeX3 project
-%
+%% File: l3int.dtx Copyright (C) 1990-2006 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/cgi-bin/cvsweb.cgi/
+%%
+%% 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.
+%%
+%% -----------------------------------------------------------------------
+%
+%<package>\RequirePackage{l3names}
%<*dtx>
- \ProvidesFile{l3int.dtx}
+%\fi
+\def\GetIdInfo$Id: #1.dtx #2 #3-#4-#5 #6 #7$#8{%
+ \def\fileversion{#2}%
+ \def\filedate{#3/#4/#5}%
+ \ProvidesFile{#1.dtx}[#3/#4/#5 v#2 #8]%
+}
+%\iffalse
%</dtx>
-%<package>\NeedsTeXFormat{LaTeX2e}
-%<package>\ProvidesPackage{l3int}
-%<driver> \ProvidesFile{l3int.drv}
-% \fi
-% \ProvidesFile{l3int.dtx}
- [1998/04/20 v1.0c L3 Experimental Integer module]
+%\fi
+\GetIdInfo$Id: l3int.dtx 573 2006-08-21 20:59:37Z morten $
+ {L3 Experimental Integer module}
%
% \iffalse
%<*driver>
@@ -22,7 +57,6 @@
% \fi
%
%
-% \GetFileInfo{l3int.dtx}
% \title{The \textsf{l3int} package\thanks{This file
% has version number \fileversion, last
% revised \filedate.}\\
@@ -31,40 +65,32 @@
% \date{\filedate}
% \maketitle
%
-% \section{Counters}
+% \section{Integers}
%
% \LaTeX3 maintains two type of integer registers for internal use.
-% One (associated with the name "int") uses the builtin counter
-% registers of \TeX{} and is therefore relatively fast and one
-% (associated with the name "fint" for fake counter) that implements the
-% operations within the \TeX{} macro language and is therefore much
-% slower in processing. This type of counter is also far more restricted
-% in its range.
-%
-% The fake counter should be used for variables that are not accessed
-% very often since this saves the important fast internal registers
-% (\TeX{} has only 255 of those). For example, all allocation routines
-% in \LaTeX3 make use of fake counters to remember the values of recent
-% allocated register numbers etc.
-%
-% Since all functions for both types are very similar (they usually
-% differ only in the initial "f") we describe them together. But
-% remember that you need to use "fint" variables when using "fint"
-% functions.
+% One (associated with the name "num") for low level uses in the
+% allocation mechanism using macros only and "int": the one described
+% here.
+%
+% The "int" type uses the built-in counter registers of \TeX{} and is
+% therefore relatively fast compared to the "num" type and should be
+% preferred in all cases as there is little chance we should ever run
+% out of registers when being based on at least \eTeX.
%
% \subsection{Functions}
%
% \begin{function}{%
% \int_new:N |
% \int_new:c |
-% \fint_new:N |
+% \int_new_l:N |
% }
% \begin{syntax}
% "\int_new:N" <int>
-% "\fint_new:N" <fint>
% \end{syntax}
-% Defines <int> to be a new variable of type "int". There is no way to
-% define constant counters with these functions.
+% Globally defines <int> to be a new variable of type "int" although
+% you can still choose if it should be a an "\l_" or "\g_" type.
+% There is no way to define constant counters with these functions.
+% The function "\int_new_l:N" defines <int> locally only.
% \begin{texnote}
% "\int_new:N" is the equivalent to plain \TeX{}'s \tn{newcount}.
% However, the internal register allocation is done differently.
@@ -75,12 +101,9 @@
% \int_incr:N |
% \int_gincr:N |
% \int_gincr:c |
-% \fint_incr:N |
-% \fint_gincr:N |
% }
% \begin{syntax}
% "\int_incr:N" <int>
-% "\fint_incr:N" <fint>
% \end{syntax}
% Increments <int> by one. For global variables the global versions
% should be used.
@@ -90,12 +113,9 @@
% \int_decr:N |
% \int_gdecr:N |
% \int_gdecr:c |
-% \fint_decr:N |
-% \fint_gdecr:N |
% }
% \begin{syntax}
% "\int_decr:N" <int>
-% "\fint_decr:N" <fint>
% \end{syntax}
% Decrements <int> by one. For global variables the global versions
% should be used.
@@ -106,119 +126,101 @@
% \int_set:cn |
% \int_gset:Nn |
% \int_gset:cn |
-% \fint_set:Nn |
-% \fint_gset:Nn |
% }
% \begin{syntax}
-% "\int_set:Nn" <int> "{" <integer> "}"
-% "\fint_set:Nn" <fint> "{" <integer> "}"
+% "\int_set:Nn" <int> "{" <integer expr> "}"
% \end{syntax}
-% These functions will set the <int> register to the <integer> value.
+% These functions will set the <int> register to the <integer expr>
+% value. This value can contain simple calc-like expressions as
+% provided by \eTeX.
% \end{function}
%
+%
% \begin{function}{%
-% \fint_set_eq:NN |
-% \fint_gset_eq:NN |
+% \int_zero:N |
+% \int_zero:c |
+% \int_gzero:N |
+% \int_gzero:c |
% }
% \begin{syntax}
-% "\fint_set_eq:NN" <fint1> <fint2>
+% "\int_zero:N" <int>
% \end{syntax}
-% Fast form for
-% \begin{syntax}
-% "\fint_set:No" <fint1> "{\fint_use:N" <fint2> "}"
-% \end{syntax}
-% when <fint2> is known to be a variable of fake counter. Note that a
-% corresponding function for real counters is not implemented since the
-% "\int_set:Nn" function does this operation sufficiently when then second
-% argument is a <int> instead of "{"<integer>"}" value.
+% These functions sets the <int> register to zero either locally
+% or globally.
% \end{function}
%
+%
% \begin{function}{%
% \int_add:Nn |
% \int_add:cn |
% \int_gadd:Nn |
-% \fint_add:Nn |
-% \fint_gadd:Nn |
% }
% \begin{syntax}
-% "\int_add:Nn" <int> "{" <integer> "}"
-% "\fint_add:Nn" <fint> "{" <integer> "}"
+% "\int_add:Nn" <int> "{" <integer expr> "}"
% \end{syntax}
-% These functions will add to the <int> register the value <integer>. If
-% the second argument is a <int> register too, the surrounding braces
-% can be left out.
-%
-% It not allowed to use a <fint> instead of the <integer>. If a fake
-% counter should be used as the second argument one needs to turn the
-% <fint> first into an <integer> by applying "\fint_use:N".
+% These functions will add to the <int> register the value <integer
+% expr>. If the second argument is a <int> register too, the
+% surrounding braces can be left out.
% \end{function}
%
% \begin{function}{%
% \int_sub:Nn |
% \int_gsub:Nn |
-% \fint_sub:Nn |
-% \fint_gsub:Nn |
% }
% \begin{syntax}
-% "\int_gsub:Nn" <int> "{" <integer> "}"
-% "\fint_gsub:Nn" <fint> "{" <integer> "}"
+% "\int_gsub:Nn" <int> "{" <integer expr> "}"
% \end{syntax}
% These functions will subtract from the <int> register the value
-% <integer>. If the second argument is a <int> register too, the
+% <integer expr>. If the second argument is a <int> register too, the
% surrounding braces can be left out.
-%
-% It is not allowed to use a <fint> instead of the <integer>. If a fake
-% counter should be used as the second argument one needs to turn the
-% <fint> first into an <integer> by applying "\fint_use:N".
% \end{function}
%
% \begin{function}{%
% \int_use:N |
% \int_use:c |
-% \fint_use:N |
% }
% \begin{syntax}
% "\int_use:N" <int>
-% "\fint_use:N" <fint>
% \end{syntax}
% This function returns the integer value kept in <int> in a way
-% suitable for further processing. Be sure to use "\fint_use:N" if you
-% are accessing the value of a fake counter because otherwise your
-% result will be to some surprise to you (there is no check).
+% suitable for further processing.
% \begin{texnote}
% The function "\int_use:N" could be implemented directly as the \TeX{}
% primitive "\tex_the:D" which is also responsible to produce the values for
% other internal quantities. We have chosen to use individual functions
-% for counters, dimenions etc.\ to allow checks and to make the code
-% more selfexplaining.
+% for counters, dimensions etc.\ to allow checks and to make the code
+% more self-explaining.
% \end{texnote}
% \end{function}
%
% \subsection{Formatting a counter value}
%
-% \begin{function}{\int_to_arabic:n |
-% \int_to_alph:n |
-% \int_to_Alph:n |
-% \int_to_roman:n |
-% \int_to_Roman:n |
-% \int_to_symbol:n |
+% \begin{function}{
+% \int_to_arabic:n |
+% \int_to_alph:n |
+% \int_to_Alph:n |
+% \int_to_roman:n |
+% \int_to_Roman:n |
+% \int_to_symbol:n |
% }
% \begin{syntax}
% "\int_to_alph:n" "{" <integer> "}"
% "\int_to_alph:n" <int>
-% "\int_to_alph:n" "{" "\fint_use:N" <fint> "}"
% \end{syntax}
% If some <integer> or the the current value of a <int> should be
% displayed or typeset in a special ways (e.g., as uppercase roman
-% numerals) these function can be used. We need braces if the argument
-% is a simple <integer>, they can be omitted in case of a <int>.
-%
-% To format <fint>s with these functions it is necessary to turn the
-% value of the <fint> first into an <integer> by applying "\fint_use:N"
-% within the argument braces.
+% numerals) these function can be used. We need braces if the
+% argument is a simple <integer>, they can be omitted in case of a
+% <int>. By default the letters produced by "\int_to_roman:n" and
+% "\int_to_Roman:n" have catcode~11.
%
% All functions are fully expandable and will therefore produce the
-% correct output when used inside of deferred writes, etc.
+% correct output when used inside of deferred writes, etc. In case the
+% number in an |alph| or |Alph| function is greater than the default
+% base number (26) it follows a simple conversion rule so that 27 is
+% turned into |aa|, 50 into |ax| and so on and so forth. These two
+% functions can be modified quite easily to take a different base
+% number and conversion rule so that other languages can be supported.
% \begin{texnote}
% These are more or less the internal \LaTeX2 functions \tn{@arabic},
% \tn{@alph}, \tn{Alph}, \tn{@roman}, \tn{@Roman}, and \tn{@fnsymbol}
@@ -226,36 +228,65 @@
% \end{texnote}
% \end{function}
%
-% \subsection{Variable and constants}
+% \subsubsection{Internal functions}
%
-% \begin{variable}{%
-% \c_int_max |
-% \c_fint_max |
+% \begin{function}{\int_to_roman:w}
+% \begin{syntax}
+% "\int_to_roman:w" <integer> <space> \textit{or} <non-expandable token>
+% \end{syntax}
+% Converts <integer> 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 |
% }
-% Constant that denote the maximum value which can be stored in a <int>
-% or <fint> register.
-% \end{variable}
+% \begin{syntax}
+% "\int_roman_lcuc_mapping:Nnn" <roman_char> "{"<licr>"}" "{"<LICR>"}"
+% "\int_to_roman_lcuc:NN" <roman_char> <char>
+% \end{syntax}
+% "\int_roman_lcuc_mapping:Nnn" specifies how the roman
+% numeral <roman\_ char> (i, v, x, l, c, d, or m) should be
+% interpreted when converting the number. <licr> is the lower case and
+% <LICR> 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_alph_default_conversion_rule:n |
+% \int_Alph_default_conversion_rule:n |
+% \int_symbol_math_conversion_rule:n |
+% \int_symbol_text_conversion_rule:n |
+% }
+% \begin{syntax}
+% "\int_convert_number_with_rule:nnN" "{"<int1>"}" "{"<int2>"}" <function>
+% "\int_alph_default_conversion_rule:n" "{"<int>"}"
+% \end{syntax}
+% "\int_convert_number_with_rule:nnN" converts <int1> into letters,
+% symbols, whatever as defined by <function>. <int2> denotes the base
+% number for the conversion.
+% \end{function}
+%
+%
+%
+%
+%
+%
+% \subsection{Variable and constants}
%
% \begin{variable}{%
-% \c_minus_one |
-% \c_zero |
-% \c_one |
-% \c_two |
-% \c_three |
-% \c_sixteen |
-% \c_twohundred_fifty_five |
-% \c_twohundredfiftysix |
-% \c_thousand |
-% \c_ten_thousand |
-% \c_twenty_thousand |
+% \c_max_int |
% }
-% Set of constants denoting useful values.
-% \begin{texnote}
-% Most of these constants have been available under \LaTeX2 under names
-% like \tn{tw@}, \tn{thr@@} etc.
-% \end{texnote}
+% Constant that denote the maximum value which can be stored in an
+% <int> register.
% \end{variable}
%
+%
% \begin{variable}{%
% \l_tmpa_int |
% \l_tmpb_int |
@@ -268,16 +299,143 @@
% \end{variable}
%
%
-% \section{Integer registers}
+% \subsection{Testing and evaluating integer expressions}
+%
+% \begin{function}{%
+% \int_eval:n |
+% \int_div_truncate:nn |
+% \int_div_round:nn |
+% \int_mod:nn |
+% }
+% \begin{syntax}
+% "\int_eval:n" "{"<int~expr>"}" \\
+% "\int_div_truncate:n" "{"<int~expr>"}" "{"<int~expr>"}" \\
+% "\int_mod:nn" "{"<int~expr>"}" "{"<int~expr>"}"
+% \end{syntax}
+% Evaluates the value of a integer expression so that
+% "\int_eval:n {3*5/4}" puts "4" back into the input stream. Note that
+% the results of divisions are rounded by the primitive operations. If
+% you want the result of a division to be truncated use
+% "\int_div_truncate:nn". "\int_div_round:nn" is added for
+% completeness. "\int_mod:nn" returns the remainder of a division. All
+% of these functions are expandable.
+% \begin{texnote}
+% "\int_eval:n" is the \eTeX primitive \tn{numexpr} turned into a function
+% taking an argument.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}{%
+% \int_compare:nNnTF |
+% \int_compare:nNnT |
+% \int_compare:nNnF |
+% }
+% \begin{syntax}
+% "\int_compare:nNnTF" "{"<int~expr>"}" <rel> "{"<int~expr>"}"
+% "{"<true>"}" "{"<false>"}"
+% \end{syntax}
+% These functions test two integer expressions against each other. They
+% are both evaluated by "\int_eval:n". Note that if both expressions
+% are normal integer variables as in
+% \begin{quote}
+% "\int_compare:nNnTF \l_temp_int < \c_zero {negative}{non-negative}"
+% \end{quote}
+% you can safely omit the braces.
+% \begin{texnote}
+% This is the \TeX{} primitive \tn{ifnum} turned into a function.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}{%
+% \int_compare_p:nNn |
+% }
+% \begin{syntax}
+% "\int_compare_p:nNn" "{"<int~expr>"}" <rel> "{"<int~expr>"}"
+% \end{syntax}
+% A predicate version of the above mentioned functions.
+% \end{function}
+%
+% \begin{function}{%
+% \int_if_odd:nTF |
+% \int_if_odd_p:n |
+% }
+% \begin{syntax}
+% "\int_if_odd:nTF" "{"<int~expr>"}" "{"<true>"}" "{"<false>"}"
+% \end{syntax}
+% These functions test if an integer expression is even or odd. We
+% also define a predicate version of it.
+% \begin{texnote}
+% This is the \TeX{} primitive \tn{ifodd} turned into a function.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}{%
+% \int_whiledo:nNnT |
+% \int_whiledo:nNnF |
+% \int_dowhile:nNnT |
+% \int_dowhile:nNnF |
+% }
+% \begin{syntax}
+% "\int_whiledo:nNnT" <int expr> <rel> <int~expr> "{"<true>"}"
+% \end{syntax}
+% "\int_whiledo:nNnT" tests the integer expressions and if true performs
+% the body "T" until the test fails. "\int_dowhile:nNnT" is similar
+% but executes the body first and then performs the check, thus
+% ensuring that the body is executed at least once. The "F" versions
+% are similar but continue the loop as long as the test is false. They
+% could be omitted as it is just a matter of switching the arguments
+% in the test.
+% \end{function}
+%
+
+% \subsection{Conversion}
+%
+% \begin{function}{%
+% \int_convert_from_base_ten:nn |
+% }
+% \begin{syntax}
+% "\int_convert_from_base_ten:nn" "{"<number>"}""{"<base>"}"
+% \end{syntax}
+% Converts the base~10 number <number> into its equivalent
+% representation written in base~<base>. Expandable.
+% \end{function}
+%
+%
+% \begin{function}{%
+% \int_convert_to_base_ten:nn |
+% }
+% \begin{syntax}
+% "\int_convert_to_base_ten:nn" "{"<number>"}""{"<base>"}"
+% \end{syntax}
+% Converts the base~<base> number <number> into its equivalent
+% representation written in base~10. <number> can consist of digits
+% and ascii letters. Expandable.
+% \end{function}
+%
+%
+% \StopEventually{}
+% \subsection{The Implementation}
+%
%
-%
% We start by ensuring that the required packages are loaded.
% \begin{macrocode}
-%<package&!check>\RequirePackage{l3basics}\par
-%<package&check>\RequirePackage{l3chk}\par
-%<*package>
+%<package&!check>\RequirePackage{l3num}
+%<package&check>\RequirePackage{l3chk}
+%<*initex|package>
% \end{macrocode}
%
+% \begin{macro}{\int_to_roman:w}
+% \begin{macro}{\int_to_number:w}
+% \begin{macro}{\int_advance:w}
+% A new name for the primitives.
+% \begin{macrocode}
+\let_new:NN \int_to_roman:w \tex_romannumeral:D
+\let_new:NN \int_to_number:w \tex_number:D
+\let_new:NN \int_advance:w \tex_advance:D
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
% Functions that support \LaTeX's user accessible counters should be
% added here, too. But first the internal counters.
%
@@ -288,12 +446,12 @@
% Incrementing and decrementing of integer registers is done with
% the following functions.
% \begin{macrocode}
-\def_new:Npn \int_incr:N #1{\tex_advance:D#1\c_one
+\def_new:Npn \int_incr:N #1{\int_advance:w#1\c_one
%<*check>
\chk_local_or_pref_global:N #1
%</check>
}
-\def_new:Npn \int_decr:N #1{\tex_advance:D#1\c_minus_one
+\def_new:Npn \int_decr:N #1{\int_advance:w#1\c_minus_one
%<*check>
\chk_local_or_pref_global:N #1
%</check>
@@ -335,16 +493,22 @@
%
%
% \begin{macro}{\int_new:N}
+% \begin{macro}{\int_new_l:N}
% \begin{macro}{\int_new:c}
% Allocation of a new internal counter is already done above. Here we define
% the next likely variant.
% \begin{macrocode}
-\def_new:Npn \int_new:N {} % but since we don't distribute
-\let:NN \int_new:N \newcount % allocation better nick the LaTeX one ...
+%<*initex>
+\alloc_setup_type:nnn {int} \c_eleven \c_max_register_num
+\def_new:Npn \int_new:N #1 {\alloc_reg:NnNN g {int} \tex_countdef:D#1}
+\def_new:Npn \int_new_l:N #1 {\alloc_reg:NnNN l {int} \tex_countdef:D#1}
+%</initex>
+%<package>\let:NN \int_new:N \newcount% allocation better nick the LaTeX one...
\def_new:Npn \int_new:c {\exp_args:Nc \int_new:N}
% \end{macrocode}
% \end{macro}
% \end{macro}
+% \end{macro}
%
%
% \begin{macro}{\int_set:Nn}
@@ -354,7 +518,7 @@
% Setting counters is again something that I would like to make
% uniform at the moment to get a better overview.
% \begin{macrocode}
-\def_new:Npn \int_set:Nn #1#2{#1#2\scan_stop:
+\def_new:Npn \int_set:Nn #1#2{#1 \int_eval:w #2\scan_stop:
%<*check>
\chk_local_or_pref_global:N #1
%</check>
@@ -373,6 +537,21 @@
% \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}
+\def_new:Npn \int_zero:N #1 {#1=\c_zero}
+\def_new:Npn \int_zero:c #1 {\exp_args:Nc \int_zero:N}
+\def_new:Npn \int_gzero:N #1 {\pref_global:D #1=\c_zero}
+\def_new:Npn \int_gzero:c {\exp_args:Nc \int_gzero:N}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
%
% \begin{macro}{\int_add:Nn}
% \begin{macro}{\int_add:cn}
@@ -383,14 +562,19 @@
% We should think of using these functions
% \begin{macrocode}
\def_new:Npn \int_add:Nn #1#2{
- \tex_advance:D#1#2\scan_stop:
+% \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\scan_stop:
%<*check>
\chk_local_or_pref_global:N #1
%</check>
}
\def_new:Npn\int_add:cn{\exp_args:Nc\int_add:Nn}
\def_new:Npn \int_sub:Nn #1#2{
- \tex_advance:D#1-#2\scan_stop:
+ \int_advance:w #1-\int_eval:w #2\scan_stop:
%<*check>
\chk_local_or_pref_global:N #1
%</check>
@@ -415,341 +599,649 @@
% \end{macro}
%
%
-% \begin{macro}{\int_use:N}
-% \begin{macro}{\int_use:c}
+% \begin{macro}{\int_use:N}
+% \begin{macro}{\int_use:c}
% Here is how counters are accessed:
% \begin{macrocode}
\let_new:NN \int_use:N \tex_the:D
\def_new:Npn \int_use:c #1{\int_use:N \cs:w#1\cs_end:}
% \end{macrocode}
-% \end{macro}
-% \end{macro}
-
+% \end{macro}
+% \end{macro}
%
-% \begin{macro}{\int_gincr:c}
-% \begin{macro}{\int_gdecr:c}
+%
+% \begin{macro}{\int_gincr:c}
+% \begin{macro}{\int_gdecr:c}
% We also need \ldots
% \begin{macrocode}
\def_new:Npn \int_gincr:c {\exp_args:Nc \int_gincr:N}
\def_new:Npn \int_gdecr:c {\exp_args:Nc \int_gdecr:N}
% \end{macrocode}
-% \end{macro}
-% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+%
+% \begin{macro}{\int_to_arabic:n}
+% Nothing exciting here.
+% \begin{macrocode}
+\def_new:Npn \int_to_arabic:n #1{\int_to_number:w \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}
+\def_new:Npn \int_roman_lcuc_mapping:Nnn #1#2#3{
+ \def:cpn {int_to_lc_roman_#1:}{#2}
+ \def: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}
+\def_new:Npn \int_to_roman:n #1 {
+ \exp_after:NN \int_to_roman_lcuc:NN \exp_after:NN l
+ \int_to_roman:w \int_eval:n {#1} Q
+}
+\def_new:Npn \int_to_Roman:n #1 {
+ \exp_after:NN \int_to_roman_lcuc:NN \exp_after:NN u
+ \int_to_roman:w \int_eval:n {#1} Q
+}
+\def_new:Npn \int_to_roman_lcuc:NN #1#2{
+ \cs_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_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}
+\def:Npn \int_convert_number_with_rule:nnN #1#2#3{
+ \int_compare:nNnTF {#1}>{#2}
+ {
+ \exp_args:No \int_convert_number_with_rule:nnN
+ { \int_use:N\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:No #3 { \int_use:N\int_eval:n{1+\int_mod:nn {#1-1}{#2}} }
+ }
+ { \exp_args:No #3{ \int_use:N\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_alph_default_conversion_rule:n}
+% \begin{macro}{\int_Alph_default_conversion_rule:n}
+% Now we just set up a default conversion rule. Ideally every language
+% should have one such rule, as say in Danish there are 29 letters in
+% the alphabet.
+% \begin{macrocode}
+\def_new:Npn \int_alph_default_conversion_rule:n #1{
+ \if_case:w #1
+ \or: 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
+ \fi:
+}
+\def_new:Npn \int_Alph_default_conversion_rule:n #1{
+ \if_case:w #1
+ \or: 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
+ \fi:
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+%
+% \begin{macro}{\int_to_alph:n}
+% \begin{macro}{\int_to_Alph:n}
+% The actual functions are just instances of the generic function. The
+% second argument of |\int_convert_number_with_rule:nnN| should of
+% course match the number of |\or:|s in the conversion rule.
+% \begin{macrocode}
+\def_new:Npn \int_to_alph:n #1{
+ \int_convert_number_with_rule:nnN {#1}{26}
+ \int_alph_default_conversion_rule:n
+}
+\def_new:Npn \int_to_Alph:n #1{
+ \int_convert_number_with_rule:nnN {#1}{26}
+ \int_Alph_default_conversion_rule:n
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
%
+% \begin{macro}{\int_to_symbol:n}
+% Turning a number into a symbol is also easy enough.
+% \begin{macrocode}
+\def_new:Npn \int_to_symbol:n #1{
+ \mode_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}
+\def_new: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:
+}
+\def_new: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 two local and two global scratch counters, maybe we
-% need more or less. Instead of using the allocation routines we
-% partly allocate them by hand.
-% \begin{macrocode}
-\chk_new_cs:N \l_tmpa_int
-% \end{macrocode}
-% If it turns out that we don't need local counters then this
-% register should be used for global counter. We might also think of
-% using the |\l_last_alloc_fint| as a scratch register.
+% \begin{macro}{\l_loop_int}
+% We provide four local and two global scratch counters, maybe we
+% need more or less.
% \begin{macrocode}
-\tex_countdef:D\l_tmpa_int 255
+\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
+\int_new:N \l_loop_int % a variable for use in loops (whilenum etc)
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
+% \end{macro}
+%
%
-% \begin{macro}{\c_minus_one}
-% \begin{macro}{\c_zero}
-% \begin{macro}{\c_one}
-% \begin{macro}{\c_two}
-% \begin{macro}{\c_three}
-% \begin{macro}{\c_four}
-% \begin{macro}{\c_sixteen}
-% \begin{macro}{\c_thirty_two}
-% \begin{macro}{\c_twohundred_fifty_five}
-% \begin{macro}{\c_twohundred_fifty_six}
-% \begin{macro}{\c_thousand}
-% \begin{macro}{\c_ten_thousand}
-% \begin{macro}{\c_ten_thousand_one}
-% \begin{macro}{\c_ten_thousand_two}
-% \begin{macro}{\c_ten_thousand_three}
-% \begin{macro}{\c_ten_thousand_four}
-% \begin{macro}{\c_twenty_thousand}
-% \begin{macro}{\c_int_max}
-% 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{macro}{\int_eval:n}
+% \begin{macro}{\int_eval:w}
+% Evaluating a calc expression using normal operators. Many of these
+% are exactly the same as the ones in the \textsf{num} module so we
+% just use them.
% \begin{macrocode}
-\tex_chardef:D \c_zero = 0 \scan_stop:
-\tex_chardef:D \c_one = 1 \scan_stop:
-\tex_chardef:D \c_two = 2 \scan_stop:
-\tex_chardef:D \c_three = 3 \scan_stop:
-\tex_chardef:D \c_four = 4 \scan_stop:
-\tex_chardef:D \c_sixteen = 16 \scan_stop:
-\tex_chardef:D \c_thirty_two = 32 \scan_stop:
-\tex_chardef:D \c_twohundred_fifty_five = 255 \scan_stop:
-\tex_mathchardef:D \c_twohundred_fifty_six = 256 \scan_stop:
-\tex_mathchardef:D \c_thousand = 1000 \scan_stop:
-\tex_mathchardef:D \c_ten_thousand = 10000 \scan_stop:
-\tex_mathchardef:D \c_ten_thousand_one = 10001 \scan_stop:
-\tex_mathchardef:D \c_ten_thousand_two = 10002 \scan_stop:
-\tex_mathchardef:D \c_ten_thousand_three = 10003 \scan_stop:
-\tex_mathchardef:D \c_ten_thousand_four = 10004 \scan_stop:
-\tex_mathchardef:D \c_twenty_thousand = 20000 \scan_stop:
-% already defined ...
-%\int_new:N \c_minus_one
-% \c_minus_one = -1
+\let_new:NN \int_eval:n \num_eval:n
+\let_new:NN \int_eval:w \num_eval:w
% \end{macrocode}
-% The |\c_int_max| will be defined internally as the largest
-% dimen.
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\c_max_int}
+% The largest number allowed is $2^{31}-1$
% \begin{macrocode}
-%\int_new:N \c_int_max
-% \c_int_max = 2147483647
+\const_new:Nn \c_max_int {2147483647}
% \end{macrocode}
% \end{macro}
+%
+% \begin{macro}{\int_pre_eval_one_arg:Nn}
+% \begin{macro}{\int_pre_eval_two_args:Nnn}
+% These might be handy when handing down values to other
+% functions. All they do is evaluate the number in advance.
+% \begin{macrocode}
+\def:Npn \int_pre_eval_one_arg:Nnn #1#2{\exp_args:No#1{\int_eval:w#2}}
+\def:Npn \int_pre_eval_two_args:Nnn #1#2#3{
+ \exp_args:Noo#1{\int_use:N\int_eval:w#2}{\int_use:N\int_eval:w#3}
+}
+% \end{macrocode}
% \end{macro}
% \end{macro}
+%
+% \begin{macro}{\int_div_truncate:nn}
+% \begin{macro}{\int_div_round:nn}
+% \begin{macro}{\int_mod:nn}
+% \begin{macro}{\int_div_truncate_raw:nn}
+% \begin{macro}{\int_div_round_raw:nn}
+% \begin{macro}{\int_mod_raw:nn}
+% As "\num_eval:w" rounds the result of a division we also
+% provide a version that truncates the result.
+% \begin{macrocode}
+\def_new:Npn \int_div_truncate:nn {
+ \int_pre_eval_two_args:Nnn\int_div_truncate_raw:nn
+}
+\def_new:Npn \int_div_truncate_raw:nn #1#2 {
+ \int_eval:n{ (2*#1 - #2) / (2* #2) }
+}
+% \end{macrocode}
+% For the sake of completeness:
+% \begin{macrocode}
+\def_new:Npn \int_div_round:nn {
+ \int_pre_eval_two_args:Nnn\int_div_round_raw:nn
+}
+\def_new:Npn \int_div_round_raw:nn #1#2 {\int_eval:n{#1/#2}}
+% \end{macrocode}
+% Finally there's the modulus operation.
+% \begin{macrocode}
+\def_new:Npn \int_mod:nn {\int_pre_eval_two_args:Nnn\int_mod_raw:nn}
+\def_new:Npn \int_mod_raw:nn #1#2 {
+ \int_eval:n{ #1 - \int_div_truncate_raw:nn {#1}{#2} * #2 }
+}
+% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
+%
+%
+% \begin{macro}{\int_compare:nNnTF}
+% \begin{macro}{\int_compare:nNnT}
+% \begin{macro}{\int_compare:nNnF}
+% Simple comparison tests.
+% \begin{macrocode}
+\let_new:NN \int_compare:nNnTF \num_compare:nNnTF
+\let_new:NN \int_compare:nNnT \num_compare:nNnT
+\let_new:NN \int_compare:nNnF \num_compare:nNnF
+% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
+%
+% \begin{macro}{\int_compare_p:nNn}
+% A predicate function.
+% \begin{macrocode}
+\let_new:NN \int_compare_p:nNn \num_compare_p:nNn
+% \end{macrocode}
% \end{macro}
+%
+% \begin{macro}{\int_if_odd_p:n}
+% \begin{macro}{\int_if_odd:nTF}
+% \begin{macro}{\int_if_odd:nT}
+% \begin{macro}{\int_if_odd:nF}
+% A predicate function.
+% \begin{macrocode}
+\def_new:Npn \int_if_odd_p:n #1 {
+ \if_num_odd:w \int_eval:n{#1}
+ \c_true
+ \else:
+ \c_false
+ \fi:
+}
+\def_test_function_new:npn {int_if_odd:n}#1{\if_num_odd:w \int_eval:n{#1}}
+% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
-% \end{macro}
-%
%
-% Show token usage:
+% \begin{macro}{\int_whiledo:nNnT}
+% \begin{macro}{\int_whiledo:nNnF}
+% \begin{macro}{\int_dowhile:nNnT}
+% \begin{macro}{\int_dowhile:nNnF}
+% These are quite easy given the above functions. The "while" versions
+% test first and then execute the body. The "dowhile" does it the
+% other way round.
% \begin{macrocode}
-%</package>
-%<*showmemory>
-\showMemUsage
-%</showmemory>
+\def_new:Npn \int_whiledo:nNnT #1#2#3#4{
+ \int_compare:nNnT {#1}#2{#3}{#4 \int_whiledo:nNnT {#1}#2{#3}{#4}}
+}
+\def_new:Npn \int_whiledo:nNnF #1#2#3#4{
+ \int_compare:nNnF {#1}#2{#3}{#4 \int_whiledo:nNnF {#1}#2{#3}{#4}}
+}
+\def_new:Npn \int_dowhile:nNnT #1#2#3#4{
+ #4 \int_compare:nNnT {#1}#2{#3}{\int_dowhile:nNnT {#1}#2{#3}{#4}}
+}
+\def_new:Npn \int_dowhile:nNnF #1#2#3#4{
+ #4 \int_compare:nNnF {#1}#2{#3}{\int_dowhile:nNnF {#1}#2{#3}{#4}}
+}
% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
%
%
-% \section{Fake registers}
-%
-% Fake registers are registers which implement \m{counter}s,
-% \m{dimen}s, etc.\ which aren't used often and therefore don't need
-% to run efficiently. One possible way of using them is to prepare certain
-% registers this way, but |\let:NN| the mutator functions to real
-% \m{counter}s as long as we have a sufficient number available. Now
-% if we are making real large formats (by adding Pic\TeX, for example)
-% we can turn them easily into fake registers and everything will work
-% as before (only a bit slower).
-%
-%
-% I haven't implemented anything besides counters so far, but \m{dimen}
-% and \m{skip} present no principal problem and should probably be
-% added.
+% \subsubsection{Scanning and conversion}
%
-% \subsection{Fake counters}
%
-% \begin{macro}{\fint_new:N}
-% A fake counter is internally a \m{muskip} register. A count value
-% \m{x} is saved as \m{x}|mu| (more exactly as \m{x}|.0mu|) in this
-% register. This means that fake counter values are far more
-% restricted then usual counters, the largest value is 16383,
-% i.e.\ the |pt| part of \TeX{}'s largest \m{dimen}. This could be
-% changed by using more complicated conversion routines, but it
-% might be all right in usual applications.
+% Conversion between different numbering schemes requires meticulous
+% work. A number can be preceeded by any number of |+| and/or |-|. We
+% define a generic function which will return the sign and/or the
+% remainder.
%
-% Of course, we should make sure that we don't reach the borders,
-% otherwise the user will be faced by the surprising message that
-% some dimension got to large. (Not done yet).
+% \begin{macro}{\int_get_sign_and_digits:n}
+% \begin{macro}{\int_get_sign:n}
+% \begin{macro}{\int_get_digits:n}
+% \begin{macro}{\int_get_sign_and_digits_aux:nNNN}
+% \begin{macro}{\int_get_sign_and_digits_aux:oNNN}
+% A number may be preceeded by any number of |+|s and |-|s. Start out
+% by assuming we have a positive number.
% \begin{macrocode}
-%<*package>
-\let_new:NN \fint_new:N \newmuskip % nicked from LaTeX
+\def_new:Npn \int_get_sign_and_digits:n #1{
+ \int_get_sign_and_digits_aux:nNNN {#1} \c_true \c_true \c_true
+}
+\def_new:Npn \int_get_sign:n #1{
+ \int_get_sign_and_digits_aux:nNNN {#1} \c_true \c_true \c_false
+}
+\def_new:Npn \int_get_digits:n #1{
+ \int_get_sign_and_digits_aux:nNNN {#1} \c_true \c_false \c_true
+}
% \end{macrocode}
-% \end{macro}
-%
-%
-% \begin{macro}{\fint_use:N}
-% \begin{macro}{\fint_use_aux:w}
-% To use the value of a fake counter we have to get rid of |.0mu| in
-% an expandable way, since we want to allow constructions like
-% \begin{verbatim}
-% \if_num:w\fint_use:N \l_test_fint > 55\scan_stop: ...
-%\end{verbatim}
-% The simplest way I came up with (not much thinking behind) was
-% using parameter matching.
+% Now check the first character in the string. Only a |-| can change
+% if a number is positive or negative, hence we reverse the boolean
+% governing this. Then gobble the |-| and start over.
% \begin{macrocode}
-\def_new:Npn \fint_use:N {\exp_after:NN\fint_use_aux:w\the_internal:D}
+\def_new:Npn \int_get_sign_and_digits_aux:nNNN #1#2#3#4{
+ \tlist_if_head_eq_charcode:fNTF {#1} -
+ {
+ \bool_if:NTF #2
+ { \int_get_sign_and_digits_aux:oNNN {\use_none:n #1} \c_false #3#4 }
+ { \int_get_sign_and_digits_aux:oNNN {\use_none:n #1} \c_true #3#4 }
+ }
% \end{macrocode}
-% In the |\fint_use_aux:w| function we remove the |.0mu| and pass the
-% the result back into the input stream. The only thing we
-% have to think of, is that both |mu| have category code 12 when
-% they are returned by |\the_internal:D|.
+% The other cases are much simpler since we either just have to gobble
+% the |+| or exit immediately and insert the correct sign.
% \begin{macrocode}
-\tex_lccode:D`\!=`\m \tex_lccode:D`\?=`\u
-\tex_lowercase:D{\def_new:Npn \fint_use_aux:w #1.0!?{#1}}
-\tex_lccode:D`\!=0\scan_stop: \tex_lccode:D`\?=0\scan_stop:
+ {
+ \tlist_if_head_eq_charcode:fNTF {#1} +
+ { \int_get_sign_and_digits_aux:oNNN {\use_none:n #1} #2#3#4}
+ {
% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-%
-% \begin{macro}{\fint_set:Nn}
-% \begin{macro}{\fint_gset:Nn}
-% The way both routines are set up, the second argument might be
-% either a \m{normal integer}, or an internal register.
+% The boolean |#3| is for printing the sign while |#4| is for printing
+% the digits.
% \begin{macrocode}
-\def_new:Npn \fint_set:Nn #1#2{#1#2~mu\scan_stop:
-%<*check>
- \chk_local_or_pref_global:N #1
-%</check>
+ \bool_double_if:NNnnnn #3#4
+ { \bool_if:NF #2 - #1 }
+ { \bool_if:NF #2 - }
+ { #1 } { }
+ }
+ }
+}
+\def_new:Npn \int_get_sign_and_digits_aux:oNNN{
+ \exp_args:No\int_get_sign_and_digits_aux:nNNN
}
-\def_new:Npn \fint_gset:Nn{
-%<*check>
- \pref_global_chk:
-%</check>
-%<-check> \pref_global:D
- \fint_set:Nn}
% \end{macrocode}
% \end{macro}
% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
%
%
-% \begin{macro}{\fint_set_eq:NN}
-% \begin{macro}{\fint_gset_eq:NN}
-% We can easily set two fake counters equal to each other, but if
-% fake counters and real counters are used, we have to use the
-% slower |set| functions.
+% \begin{macro}{\int_convert_from_base_ten:nn}
+% \begin{macro}{\int_convert_from_base_ten_aux:nnn}
+% \begin{macro}{\int_convert_from_base_ten_aux:non}
+% \begin{macro}{\int_convert_from_base_ten_aux:fon}
+% |#1| is the base 10 number to be converted to base |#2|. We split
+% off the sign first, print if if there and then convert only the
+% number. Since this is supposedly a base~10 number we can let \TeX\
+% do the reading of |+| and |-|.
% \begin{macrocode}
-\def_new:Npn \fint_set_eq:NN #1#2{#1#2
-%<*check>
- \chk_local_or_pref_global:N #1\chk_var_or_const:N #2
-%</check>
+\def:Npn \int_convert_from_base_ten:nn#1#2{
+ \num_compare:nNnTF {#1}<\c_zero
+ {
+ - \int_convert_from_base_ten_aux:non {}
+ { \int_use:N \int_eval:n {-#1} }
+ }
+ {
+ \int_convert_from_base_ten_aux:non {}
+ { \int_use:N \int_eval:n {#1} }
+ }
+ {#2}
}
-\def_new:Npn \fint_gset_eq:NN {
-%<*check>
- \pref_global_chk:
-%</check>
-%<-check> \pref_global:D
- \fint_set_eq:NN}
% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\fint_add:Nn}
-% \begin{macro}{\fint_gadd:Nn}
-% \begin{macro}{\fint_sub:Nn}
-% \begin{macro}{\fint_gsub:Nn}
-% Adding and substracting; we make use of the fact that internally
-% \TeX{} always use the same primitives to advance a register.
+% The algorithm runs like this:
+% \begin{enumerate}
+% \item If the number \meta{num} is greater than \meta{base},
+% calculate modulus of \meta{num} and \meta{base} and carry that
+% over for next round. The remainder is calculated as a truncated
+% division of \meta{num} and \meta{base}. Start over with these new
+% values.
+% \item If \meta{num} is less than or equal to \meta{base} convert it
+% to the correct symbol, print the previously calculated digits and
+% exit.
+% \end{enumerate}
+% |#1| is the carried over result, |#2| the remainder and |#3| the
+% base number.
% \begin{macrocode}
-\def_new:Npn \fint_add:Nn #1#2{\int_add:Nn#1{#2mu}}
-\def_new:Npn \fint_gadd:Nn {
-%<*check>
- \pref_global_chk:
-%</check>
-%<-check> \pref_global:D
- \fint_add:Nn}
-\def_new:Npn \fint_sub:Nn #1#2{\int_sub:Nn#1{#2mu}}
-\def_new:Npn \fint_gsub:Nn {
-%<*check>
- \pref_global_chk:
-%</check>
-%<-check> \pref_global:D
- \fint_sub:Nn}
+\def_new:Npn \int_convert_from_base_ten_aux:nnn#1#2#3{
+ \num_compare:nNnTF {#2}<{#3}
+ { \int_convert_number_to_letter:n{#2} #1 }
+ {
+ \int_convert_from_base_ten_aux:fon
+ {
+ \int_convert_number_to_letter:n {\int_use:N\int_mod_raw:nn {#2}{#3}}
+ #1
+ }
+ {\int_use:N \int_div_truncate_raw:nn{#2}{#3}}
+ {#3}
+ }
+}
+\def:Npn \int_convert_from_base_ten_aux:non{
+ \exp_args:Nno\int_convert_from_base_ten_aux:nnn
+}
+\def:Npn \int_convert_from_base_ten_aux:fon{
+ \exp_args:Nfo\int_convert_from_base_ten_aux:nnn
+}
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
+% \begin{macro}{\int_convert_number_to_letter:n}
+% Turning a number for a different base into a letter or digit.
+% \begin{macrocode}
+\def:Npn \int_convert_number_to_letter:n #1{ \if_case:w \int_eval:w
+ #1-10\scan_stop: \exp_after:NN A \or: \exp_after:NN B \or:
+ \exp_after:NN C \or: \exp_after:NN D \or: \exp_after:NN E \or:
+ \exp_after:NN F \or: \exp_after:NN G \or: \exp_after:NN H \or:
+ \exp_after:NN I \or: \exp_after:NN J \or: \exp_after:NN K \or:
+ \exp_after:NN L \or: \exp_after:NN M \or: \exp_after:NN N \or:
+ \exp_after:NN O \or: \exp_after:NN P \or: \exp_after:NN Q \or:
+ \exp_after:NN R \or: \exp_after:NN S \or: \exp_after:NN T \or:
+ \exp_after:NN U \or: \exp_after:NN V \or: \exp_after:NN W \or:
+ \exp_after:NN X \or: \exp_after:NN Y \or: \exp_after:NN Z \else:
+ \use_arg_i_after_fi:nw{ #1 }\fi: }
+% \end{macrocode}
+% \end{macro}
%
-% \begin{macro}{\fint_incr:N}
-% \begin{macro}{\fint_gincr:N}
-% \begin{macro}{\fint_decr:N}
-% \begin{macro}{\fint_gdecr:N}
-% Incrementing and decrementing the fake counters:
+% \begin{macro}{\int_convert_to_base_ten:nn}
+% |#1| is the number, |#2| is its base. First we get the sign, then
+% use only the digits/letters from it and pass that onto a new
+% function.
% \begin{macrocode}
-\def_new:Npn \fint_incr:N #1{\advance:D#1\c_one mu\scan_stop:
-%<*check>
- \chk_local_or_pref_global:N #1
-%</check>
+\def:Npn \int_convert_to_base_ten:nn #1#2 {
+ \int_use:N\int_eval:n{
+ \int_get_sign:n{#1}
+ \exp_args:Nf\int_convert_to_base_ten_aux:nn {\int_get_digits:n{#1}}{#2}
+ }
}
-\def_new:Npn \fint_decr:N #1{\advance:D#1\c_minus_one mu\scan_stop:
-%<*check>
- \chk_local_or_pref_global:N #1
-%</check>
+% \end{macrocode}
+% This is an intermediate function to get things started.
+% \begin{macrocode}
+\def_new:Npn \int_convert_to_base_ten_aux:nn #1#2{
+ \int_convert_to_base_ten_auxi:nnN {0}{#2} #1 \q_nil
}
-\def_new:Npn \fint_gincr:N {
-%<*check>
- \pref_global_chk:
-%</check>
-%<-check> \pref_global:D
- \fint_incr:N}
-\def_new:Npn \fint_gdecr:N {
-%<*check>
- \pref_global_chk:
-%</check>
-%<-check> \pref_global:D
- \fint_decr:N}
% \end{macrocode}
-% This can be achieved with less tokens but extra expansions:
+% Here we check each letter/digit and calculate the next number. |#1|
+% is the previously calculated result (to be multiplied by the base),
+% |#2| is the base and |#3| is the next letter/digit to be added.
% \begin{macrocode}
-\def:Npn \fint_incr:N #1{\fint_add:Nn#1\c_one}
-\def:Npn \fint_decr:N #1{\fint_add:Nn#1\c_minus_one}
+\def_new:Npn \int_convert_to_base_ten_auxi:nnN#1#2#3{
+ \quark_if_nil:NTF #3
+ {#1}
+ {\exp_args:No\int_convert_to_base_ten_auxi:nnN
+ {\int_use:N \int_eval:n{ #1*#2+\int_convert_letter_to_number:N #3} }
+ {#2}
+ }
+}
% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\c_fint_max}
-% A constant, denoting the largest possible value for fake counters.
+% This is for turning a letter or digit into a number. This function
+% also takes care of handling lowercase and uppercase letters. Hence
+% |a| is turned into |11| and so is |A|.
% \begin{macrocode}
-\tex_mathchardef:D\c_fint_max=16383 \scan_stop:
+\def:Npn \int_convert_letter_to_number:N #1{
+ \int_compare:nNnTF{`#1}<{58}{#1}
+ {
+ \int_eval:n{ `#1 -
+ \if:w\int_compare_p:nNn{`#1}<{91}
+ 55
+ \else:
+ 87
+ \fi:
+ }
+ }
+}
% \end{macrocode}
% \end{macro}
%
%
-% \subsection{Fake skip registers}
%
-% One has to convert simply from the \m{x}|pt| |plus| \m{y}|pt| |minus|
-% \m{z}|pt| representation produced by |\the_internal:D|, to the
-% corresponding |mu| representation. Complications arise from the
-% possibility that |plus| and/or |minus| is not present,\footnote{This
-% can be catched by adding a suitable constant and removing the
-% corresponding constant in the other representation.} and by the
-% possibility that the stretch or shrink component is a |fil| unit.
%
-% \subsection{Fake dimen registers}
%
-% I suppose this could be viewed as a subcase of the skip registers.
-% See later section for a fake fake version for the moment.
%
%
-% \subsection{Allocation routines}
-%
-% Counters are rare goods in \TeX{} and we are near the limit, if
-% for example \LaTeX{} and Pic\TeX{} are merged. Therefore we should
-% be careful not to throw away counter registers unnecessarily. One
-% place for instance, where we can save some of them are the
-% allocation routines. Instead of using counters we maintain the
-% number of the last allocated register in a fake counter.
-%
-%
+% Show token usage:
% \begin{macrocode}
-%</package>
+%</initex|package>
%<*showmemory>
\showMemUsage
%</showmemory>
% \end{macrocode}
-
+%
+%
+% \endinput
+%
+% $Log$
+% Revision 1.26 2006/06/03 17:17:08 morten
+% Functions for converting between number bases
+%
+% Revision 1.25 2006/03/20 18:26:35 braams
+% Updated the copyright notice (2006) and demoted all implementation
+% sections to subsections and so on to clean up the toc for source3.tex
+%
+% Revision 1.24 2006/01/17 22:47:43 morten
+% Changed \int_while:nNnT to \int_whiledo:nNnT to avoid confusion with
+% the dowhile versions.
+%
+% Revision 1.23 2005/12/27 10:02:37 morten
+% Minor changes plus changed RCS information retrieval
+%
+% Revision 1.22 2005/12/21 20:43:32 morten
+% Fixed silly bugs!
+%
+% Revision 1.21 2005/12/06 17:31:23 morten
+% fixed \int_convert_number_with_rule:nnN
+%
+% Revision 1.20 2005/12/06 14:49:36 morten
+% Fixed primitive names plus a few minor touch-ups
+%
+% Revision 1.19 2005/04/25 15:02:47 morten
+% Added ifodd functions
+%
+% Revision 1.18 2005/04/09 21:07:39 morten
+% Added (extensible) implementations of \int_to_roman:n etc.
+%
+% Revision 1.17 2005/04/06 22:35:43 braams
+% Now we have register allocation fitted
+%
+% Revision 1.16 2005/03/25 23:48:47 braams
+% Added a missing \end{macro}
+%
+% Revision 1.15 2005/03/22 23:22:09 morten
+% Moved definitions of constants to l3num
+%
+% Revision 1.14 2005/03/16 22:36:30 braams
+% Added the tweaks necessary to be able to load with initex
+%
+% Revision 1.13 2005/03/11 21:38:31 braams
+% Fixed the use of RCS information; added \StopEventually
+%