% \iffalse
%% File: l3skip.dtx Copyright (C) 2005-2007 Frank Mittelbach, 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.
%%
%% -----------------------------------------------------------------------
%
%<*driver|package>
\RequirePackage{l3names}
%</driver|package>
%\fi
\GetIdInfo$Id: l3skip.dtx 666 2007-09-27 15:53:26Z mittelba $
       {L3 Experimental skip registers}
%\iffalse
%<*driver>
%\fi
\ProvidesFile{\filename.\filenameext}
  [\filedate\space v\fileversion\space\filedescription]
%\iffalse
\documentclass{l3doc}
\begin{document}
\DocInput{\filename.\filenameext}
\end{document}
%</driver>
% \fi
%
%
% \title{The \textsf{l3skip} package\thanks{This file
%         has version number \fileversion, last
%         revised \filedate.}\\
% Dimension and skip registers}
% \author{\Team}
% \date{\filedate}
% \maketitle
%
%
%  \section{Length registers}
%
%
%  \LaTeX3 knows about two types of length registers for internal use:
%  rubber lengths ("skip"s) and rigid lengths ("dim"s).
%
%  \subsection{Skip registers}
%
%
%
% \subsubsection{Functions}
%
% \begin{function}{%
%                  \skip_new:N |
%                  \skip_new:c |
%                  \skip_new_l:N
% }
% \begin{syntax}
%    "\skip_new:N"   <skip>
% \end{syntax}
% Defines <skip> to be a new variable of type "skip".
% \begin{texnote}
% "\skip_new:N" is the equivalent to plain \TeX{}'s \tn{newskip}.
% However, the internal register allocation is done differently.
% \end{texnote}
% \end{function}
%
% \begin{function}{%
%                  \skip_zero:N |
%                  \skip_zero:c |
%                  \skip_gzero:N |
%                  \skip_gzero:c |
% }
% \begin{syntax}
%   "\skip_zero:N"   <skip>
% \end{syntax}
% Locally or globally reset <skip> to zero.
% For global variables the global versions
% should be used.
% \end{function}
%
%
% \begin{function}{%
%                  \skip_set:Nn |
%                  \skip_set:cn |
%                  \skip_gset:Nn |
%                  \skip_gset:cn |
% }
% \begin{syntax}
%   "\skip_set:Nn"   <skip> "{" <skip value> "}"
% \end{syntax}
% These functions will set the <skip> register to the <length> value.
% \end{function}
%
%
% \begin{function}{%
%                  \skip_add:Nn |
%                  \skip_add:cn |
%                  \skip_gadd:Nn |
%                  \skip_gadd:cn |
% }
% \begin{syntax}
%   "\skip_add:Nn"   <skip> "{" <length> "}"
% \end{syntax}
% These functions will add to the <skip> register the value <length>.  If
% the second argument is a <skip> register too, the surrounding braces
% can be left out.
% \end{function}
%
% \begin{function}{%
%                  \skip_sub:Nn |
%                  \skip_gsub:Nn |
% }
% \begin{syntax}
%   "\skip_gsub:Nn"   <skip> "{" <length> "}"
% \end{syntax}
% These functions will subtract from the <skip> register the value
% <length>.  If the second argument is a <skip> register too, the
% surrounding braces can be left out.
% \end{function}
%
% \begin{function}{%
%                  \skip_use:N |
%                  \skip_use:c |
% }
% \begin{syntax}
%   "\skip_use:N"   <skip>
% \end{syntax}
% This function returns the length value kept in <skip> in a way
% suitable for further processing.
% \begin{texnote}
% The function "\skip_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, dimensions etc.\ to allow checks and to make the code
% more self-explanatory.
% \end{texnote}
% \end{function}
%
%
% \begin{function}{%
%                  \skip_horizontal:N |
%                  \skip_horizontal:c |
%                  \skip_horizontal:n |
%                  \skip_vertical:N |
%                  \skip_vertical:c |
%                  \skip_vertical:n |
% }
% \begin{syntax}
%   "\skip_horizontal:N"   <skip> \\
%   "\skip_horizontal:n" "{" <length> "}"
% \end{syntax}
% The "hor" functions insert <skip> or <length> with the \TeX\
% primitive \tn{hskip}. The "vertical" variants do the same with
% \tn{vskip}. The "n" versions evaluate <length> with "\skip_eval:n".
% \end{function}
%
%
% \begin{function}{%
%                  \skip_infinite_glue:nTF |
% }
% \begin{syntax}
%   "\skip_infinite_glue:nTF" "{"<skip>"}" "{"<true>"}" "{"<false>"}"
% \end{syntax}
% Checks if <skip> contains infinite stretch or shrink components
% and executes either <true> or <false>. Also works on input like
% "3pt plus .5in".
% \end{function}
%
%
%
% \begin{function}{%
%                  \skip_split_finite_else_action:nnNN |
% }
% \begin{syntax}
%   "\skip_split_finite_else_action:nnNN" "{"<skip>"}" "{"<action>"}"
%   <dimen1> <dimen2>
% \end{syntax}
% Checks if <skip> contains finite glue. If it does then it assigns
% <dimen1> the stretch component and <dimen2> the shrink component. If
% it contains infinite glue set <dimen1> and <dimen2> to zero and execute
% "#2" which is usually an error or warning message of some sort.
% \end{function}
%
%
%
% \begin{function}{%
%                  \skip_eval:n |
% }
% \begin{syntax}
%   "\skip_eval:n"   "{"<skip expr>"}"
% \end{syntax}
%  Evaluates the value of <skip expr> so that
%  "\skip_eval:n {5pt plus 3fil + 3pt minus 1fil}" puts
%  "8.0pt plus 3.0fil minus 1.0fil" back into the input stream.
%  Expandable.
% \begin{texnote}
% This is the \eTeX{} primitive \tn{glueexpr} turned into a function
% taking an argument.
% \end{texnote}
% \end{function}
%
%
% \subsubsection{Formatting a skip register value}
%
%
% \subsubsection{Variable and constants}
%
% \begin{variable}{%
%                  \c_max_skip |
% }
% Constant that denotes the maximum value which can be stored in a <skip>
% register.
% \end{variable}
%
% \begin{variable}{%
%                  \c_zero_skip |
% }
% Set of constants denoting useful values.
% \end{variable}
%
% \begin{variable}{%
%                  \l_tmpa_skip |
%                  \l_tmpb_skip |
%                  \l_tmpc_skip |
%                  \g_tmpa_skip |
%                  \g_tmpb_skip |
% }
% Scratch register for immediate use.
% \end{variable}
%
%
%
%
%
% \subsection{Dim registers}
%
%
% \subsubsection{Functions}
%
%
%
%
% \begin{function}{%
%                  \dim_new:N |
%                  \dim_new:c |
%                  \dim_new_l:N
% }
% \begin{syntax}
%    "\dim_new:N"   <dim>
% \end{syntax}
% Defines <dim> to be a new variable of type "dim".
% \begin{texnote}
% "\dim_new:N" is the equivalent to plain \TeX{}'s \tn{newdimen}.
% However, the internal register allocation is done differently.
% \end{texnote}
% \end{function}
%
% \begin{function}{%
%                  \dim_zero:N |
%                  \dim_zero:c |
%                  \dim_gzero:N |
%                  \dim_gzero:c |
% }
% \begin{syntax}
%   "\dim_zero:N"   <dim>
% \end{syntax}
% Locally or globally reset <dim> to zero.
% For global variables the global versions
% should be used.
% \end{function}
%
%
% \begin{function}{%
%                  \dim_set:Nn |
%                  \dim_set:cn |
%                  \dim_gset:Nn |
%                  \dim_gset:cn |
% }
% \begin{syntax}
%   "\dim_set:Nn"   <dim> "{" <dim value> "}"
% \end{syntax}
% These functions will set the <dim> register to the <dim value> value.
% \end{function}
%
%
% \begin{function}{%
%                  \dim_add:Nn |
%                  \dim_add:cn |
%                  \dim_gadd:Nn |
%                  \dim_gadd:cn |
% }
% \begin{syntax}
%   "\dim_add:Nn"   <dim> "{" <length> "}"
% \end{syntax}
% These functions will add to the <dim> register the value <length>.  If
% the second argument is a <dim> register too, the surrounding braces
% can be left out.
% \end{function}
%
% \begin{function}{%
%                  \dim_sub:Nn |
%                  \dim_gsub:Nn |
% }
% \begin{syntax}
%   "\dim_gsub:Nn"   <dim> "{" <length> "}"
% \end{syntax}
% These functions will subtract from the <dim> register the value
% <length>.  If the second argument is a <dim> register too, the
% surrounding braces can be left out.
% \end{function}
%
% \begin{function}{%
%                  \dim_use:N |
%                  \dim_use:c |
% }
% \begin{syntax}
%   "\dim_use:N"   <dim>
% \end{syntax}
% This function returns the length value kept in <dim> in a way
% suitable for further processing.
% \begin{texnote}
% The function "\dim_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, dimensions etc.\ to allow checks and to make the code
% more self-explanatory.
% \end{texnote}
% \end{function}
%
%
%
% \begin{function}{%
%                  \dim_eval:n |
% }
% \begin{syntax}
%   "\dim_eval:n"   "{"<dim expr>"}"
% \end{syntax}
%  Evaluates the value of a dimension expression so that
%  "\dim_eval:n {5pt+3pt}" puts "8pt" back into the input stream.
%  Expandable.
% \begin{texnote}
% This is the \eTeX{} primitive \tn{dimexpr} turned into a function
% taking an argument.
% \end{texnote}
% \end{function}
%
% \begin{function}{%
%                  \if_dim:w |
% }
% \begin{syntax}
%   "\if_dim:w" <dimen1> <rel> <dimen2> <true> "\else:" <false> "\fi:"
% \end{syntax}
% Compare two dimensions. It is recommended to use "\dim_eval:n" to
% correctly evaluate and terminate these numbers. <rel> is one of
% "<", "=" or ">" with catcode 12.
% \begin{texnote}
% This is the \TeX{} primitive \tn{ifdim}.
% \end{texnote}
% \end{function}
%
% \begin{function}{%
%                  \dim_compare:nNnTF |
%                  \dim_compare:nNnT |
%                  \dim_compare:nNnF |
% }
% \begin{syntax}
%   "\dim_compare:nNnTF"   "{"<dim~expr>"}" <rel> "{"<dim~expr>"}"
%                         "{"<true>"}" "{"<false>"}"
% \end{syntax}
% These functions test two dimension expressions against each other. They
% are both evaluated by "\dim_eval:n". Note that if both expressions
% are normal dimension variables as in
% \begin{verbatim}
% \dim_compare:nNnTF \l_temp_dim < \c_zero_skip {negative}{non-negative}
% \end{verbatim}
% you can safely omit the braces.
% \begin{texnote}
% This is the \TeX{} primitive \tn{ifdim} turned into a function.
% \end{texnote}
% \end{function}
%
% \begin{function}{%
%                  \dim_compare_p:nNn |
% }
% \begin{syntax}
%   "\dim_compare_p:nNn"   "{"<dim~expr>"}" <rel> "{"<dim~expr>"}"
% \end{syntax}
% Predicate version of the above functions.
% \end{function}
%
% \begin{function}{%
%                  \dim_while:nNnT |
%                  \dim_while:nNnF |
%                  \dim_dowhile:nNnT |
%                  \dim_dowhile:nNnF |
% }
% \begin{syntax}
%   "\dim_while:nNnT"   <dim expr> <rel> <dim~expr> <true>
% \end{syntax}
%  "\dim_while:nNnT" tests the dimension expressions and if true performs
%  the body "T" until the test fails. "\dim_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.
% \end{function}
%
%
%
% \subsubsection{Variable and constants}
%
% \begin{variable}{%
%                  \c_max_dim |
% }
% Constant that denotes the maximum value which can be stored in a <dim>
% register.
% \end{variable}
%
% \begin{variable}{%
%                  \c_zero_dim |
% }
% Set of constants denoting useful values.
% \end{variable}
%
% \begin{variable}{%
%                  \l_tmpa_dim |
%                  \l_tmpb_dim |
%                  \l_tmpc_dim |
%                  \l_tmpd_dim |
%                  \g_tmpa_dim |
%                  \g_tmpb_dim |
% }
% Scratch register for immediate use.
% \end{variable}
%
% \subsection{Muskips}
%
% \begin{function}{%
%                  \muskip_new:N |
%                  \muskip_new_l:N
% }
% \begin{syntax}
%    "\muskip_new:N"   <muskip>
% \end{syntax}
% Defines <muskip> to be a new variable of type "muskip".
% \begin{texnote}
% "\muskip_new:N" is the equivalent to plain \TeX{}'s \tn{newmuskip}.
% However, the internal register allocation is done differently.
% \end{texnote}
% \end{function}
%
% \begin{function}{%
%                  \muskip_set:Nn |
%                  \muskip_gset:Nn |
% }
% \begin{syntax}
%   "\muskip_set:Nn"   <muskip> "{" <muskip value> "}"
% \end{syntax}
% These functions will set the <muskip> register to the <length>
% value.
% \end{function}
%
%
% \begin{function}{%
%                  \muskip_add:Nn |
%                  \muskip_gadd:Nn |
% }
% \begin{syntax}
%   "\muskip_add:Nn"   <muskip> "{" <length> "}"
% \end{syntax}
% These functions will add to the <muskip> register the value
% <length>.  If the second argument is a <muskip> register too, the
% surrounding braces can be left out.
% \end{function}
%
% \begin{function}{%
%                  \muskip_sub:Nn |
%                  \muskip_gsub:Nn |
% }
% \begin{syntax}
%   "\muskip_gsub:Nn"   <muskip> "{" <length> "}"
% \end{syntax}
% These functions will subtract from the <muskip> register the value
% <length>.  If the second argument is a <muskip> register too, the
% surrounding braces can be left out.
% \end{function}
%
%
% \StopEventually{}
%
% \subsection{The Implementation}
%
%
%    We start by ensuring that the required packages are loaded.
%    \begin{macrocode}
%<package>\ProvidesExplPackage
%<package>  {\filename}{\filedate}{\fileversion}{\filedescription}
%<package&!check>\RequirePackage{l3int}
%<package&!check>\RequirePackage{l3prg}
%<package&check>\RequirePackage{l3chk}
%<*initex|package>
%    \end{macrocode}
%
% \subsubsection{Skip registers}
%
% \begin{macro}{\skip_new:N}
% \begin{macro}{\skip_new:c}
% \begin{macro}{\skip_new_l:N}
%    Allocation of a new internal registers.
%    \begin{macrocode}
%<*initex>
\alloc_setup_type:nnn {skip} \c_zero \c_max_register_num
\def_new:Npn\skip_new:N   #1 {\alloc_reg:NnNN g {skip} \tex_skipdef:D #1 }
\def_new:Npn\skip_new_l:N #1 {\alloc_reg:NnNN l {skip} \tex_skipdef:D #1 }
%</initex>
%<package>\let:NN \skip_new:N \newskip
\def_new:Npn \skip_new:c {\exp_args:Nc \skip_new:N}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
%
% \begin{macro}{\skip_set:Nn}
% \begin{macro}{\skip_set:cn}
% \begin{macro}{\skip_gset:Nn}
% \begin{macro}{\skip_gset:cn}
%    Setting skips is again something that I would like to make
%    uniform at the moment to get a better overview.
%    \begin{macrocode}
\def_new:Npn \skip_set:Nn #1#2{#1\skip_eval:n{#2}
%<*check>
\chk_local_or_pref_global:N #1
%</check>
}
\def_new:Npn \skip_gset:Nn {
%<*check>
   \pref_global_chk:
%</check>
%<-check> \pref_global:D
   \skip_set:Nn }
\def_new:Npn \skip_set:cn {\exp_args:Nc \skip_set:Nn }
\def_new:Npn \skip_gset:cn {\exp_args:Nc \skip_gset:Nn }
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\skip_zero:N}
% \begin{macro}{\skip_gzero:N}
% \begin{macro}{\skip_zero:c}
% \begin{macro}{\skip_gzero:c}
%    Reset the register to zero.
%    \begin{macrocode}
\def_new:Npn \skip_zero:N #1{#1\c_zero_skip \scan_stop:
%<*check>
        \chk_local_or_pref_global:N #1
%</check>
}
\def_new:Npn \skip_gzero: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>
%<-check> \pref_global:D
   \skip_zero:N}
\def_new:Npn \skip_zero:c  {\exp_args:Nc \skip_zero:N}
\def_new:Npn \skip_gzero:c {\exp_args:Nc \skip_gzero:N}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
%
% \begin{macro}{\skip_add:Nn}
% \begin{macro}{\skip_add:cn}
% \begin{macro}{\skip_gadd:Nn}
% \begin{macro}{\skip_sub:Nn}
% \begin{macro}{\skip_gsub:Nn}
%    Adding and subtracting to and from <skip>s
%    \begin{macrocode}
\def_new:Npn \skip_add:Nn #1#2{
%    \end{macrocode}
%    We need to say |by| in case the first argment is a register
%    accessed by its number, e.g., |\skip23|.
%    \begin{macrocode}
    \tex_advance:D#1 by \skip_eval:n{#2}
%<*check>
    \chk_local_or_pref_global:N #1
%</check>
}
\def_new:Npn\skip_add:cn{\exp_args:Nc\skip_add:Nn}
\def_new:Npn \skip_sub:Nn #1#2{
    \tex_advance:D#1-\skip_eval:n{#2}
%<*check>
\chk_local_or_pref_global:N #1
%</check>
}
\def_new:Npn \skip_gadd:Nn {
%<*check>
   \pref_global_chk:
%</check>
%<-check> \pref_global:D
   \skip_add:Nn }
\def_new:Npn \skip_gsub:Nn {
%<*check>
   \pref_global_chk:
%</check>
%<-check> \pref_global:D
   \skip_sub:Nn }
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
%
% \begin{macro}{\skip_horizontal:N}
% \begin{macro}{\skip_horizontal:c}
% \begin{macro}{\skip_horizontal:n}
% \begin{macro}{\skip_vertical:N}
% \begin{macro}{\skip_vertical:c}
% \begin{macro}{\skip_vertical:n}
%    Inserting skips.
%    \begin{macrocode}
\let_new:NN \skip_horizontal:N \tex_hskip:D
\def_new:Npn \skip_horizontal:c {\exp_args:Nc\skip_horizontal:N}
\def_new:Npn \skip_horizontal:n #1{\skip_horizontal:N \skip_eval:n{#1}}
\let_new:NN \skip_vertical:N \tex_vskip:D
\def_new:Npn \skip_vertital:c {\exp_args:Nc\skip_vertical:N}
\def_new:Npn \skip_vertical:n #1{\skip_vertical:N \skip_eval:n{#1}}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\skip_use:N}
% \begin{macro}{\skip_use:c}
%    Here is how skip registers are accessed:
%    \begin{macrocode}
\let_new:NN \skip_use:N \tex_the:D
\def_new:Npn \skip_use:c #1{\exp_args:Nc\skip_use:N}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\skip_eval:n}
% Evaluating a calc expression.
%    \begin{macrocode}
\def_new:Npn \skip_eval:n #1 {\etex_glueexpr:D #1 \scan_stop:}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\l_tmpa_skip}
% \begin{macro}{\l_tmpb_skip}
% \begin{macro}{\l_tmpc_skip}
% \begin{macro}{\g_tmpa_skip}
% \begin{macro}{\g_tmpb_skip}
%    We provide three local and two global scratch registers, maybe we
%    need more or less.
%    \begin{macrocode}
%%\chk_new_cs:N \l_tmpa_skip
%%\tex_skipdef:D\l_tmpa_skip 255  %currently taken up by \skip@
\skip_new:N \l_tmpa_skip
\skip_new:N \l_tmpb_skip
\skip_new:N \l_tmpc_skip
\skip_new:N \g_tmpa_skip
\skip_new:N \g_tmpb_skip
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\c_zero_skip}
% \begin{macro}{\c_max_skip}
%    \begin{macrocode}
%<*!package>
\skip_new:N \c_zero_skip
\skip_set:Nn \c_zero_skip {0pt}
\skip_new:N \c_max_skip
\skip_set:Nn \c_max_skip {16383.99999pt}
%</!package>
%<*!initex>
\let:NN \c_zero_skip \z@
\let:NN \c_max_skip  \maxdimen
%</!initex>
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
%
%
%  \begin{macro}{\skip_infinite_glue:nTF}
%  With \eTeX{} we all of a sudden get access to a lot information we
%  should otherwise consider ourselves lucky to get. One is
%  the stretch and shrink components of a skip register and the order
%  or those components. "\skip_infinite_glue:nTF" tests it directly by
%  looking at the stretch and shrink order. If either of the predicate
%  functions return \m{true} "\prg_logic_or_p:nn" will return \m{true}
%  and the logic test will take the true branch.
%    \begin{macrocode}
\def_new:Npn \skip_infinite_glue:nTF #1{
  \predicate:nTF {
      \int_compare_p:nNn {\etex_gluestretchorder:D #1 } > \c_zero ||
      \int_compare_p:nNn {\etex_glueshrinkorder:D #1 }  > \c_zero 
  }
}
%    \end{macrocode}
%  \end{macro}
%
%
%  \begin{macro}{\skip_split_finite_else_action:nnNN}
%  This macro is useful when performing error checking in certain
%  circumstances. If the \m{skip} register holds finite glue it sets
%  "#3" and "#4" to the stretch and shrink component resp. If it holds
%  infinite glue set "#3" and "#4" to zero and issue the special action
%  "#2" which is probably an error message.
%  Assignments are global.
%    \begin{macrocode}
\def_new:Npn \skip_split_finite_else_action:nnNN #1#2#3#4{
  \skip_infinite_glue:nTF {#1}
  {
    #3 = \c_zero_skip
    #4 = \c_zero_skip
    #2
  }
  {
    #3 = \etex_gluestretch:D #1 \scan_stop:
    #4 = \etex_glueshrink:D  #1 \scan_stop:
  }
}
%    \end{macrocode}
%  \end{macro}
%
%
%
% \subsubsection{Dimen registers}
%
% \begin{macro}{\dim_new:N}
% \begin{macro}{\dim_new:c}
% \begin{macro}{\dim_new_l:N}
%    Allocating \meta{dim} registers...
%    \begin{macrocode}
%<*initex>
\alloc_setup_type:nnn {dimen} \c_zero \c_max_register_num
\def_new:Npn \dim_new:N   #1 {\alloc_reg:NnNN g {dimen} \tex_dimendef:D #1 }
\def_new:Npn \dim_new_l:N #1 {\alloc_reg:NnNN l {dimen} \tex_dimendef:D #1 }
%</initex>
%<package>\let:NN \dim_new:N \newdimen
\def_new:Npn \dim_new:c {\exp_args:Nc \dim_new:N}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\dim_set:Nn}
% \begin{macro}{\dim_gset:Nn}
% \begin{macro}{\dim_set:cn}
% \begin{macro}{\dim_set:Nc}
% \begin{macro}{\dim_gset:cn}
% \begin{macro}{\dim_gset:Nc}
% \begin{macro}{\dim_gset:cc}
% We add |\dim_eval:n| in order to allow simple arithmetic
% and a space just for those using |\dimen1| or alike. See OR!
%    \begin{macrocode}
\def_new:Npn \dim_set:Nn #1#2{#1~ \dim_eval:n{#2}}
\def_new:Npn \dim_gset:Nn {\pref_global:D \dim_set:Nn }
\def_new:Npn \dim_set:cn {\exp_args:Nc \dim_set:Nn }
\def_new:Npn \dim_set:Nc {\exp_args:NNc \dim_set:Nn }
\def_new:Npn \dim_gset:cn {\exp_args:Nc \dim_gset:Nn }
\def_new:Npn \dim_gset:Nc {\exp_args:NNc \dim_gset:Nn }
\def_new:Npn \dim_gset:cc {\exp_args:Ncc \dim_gset:Nn }
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\dim_zero:N}
% \begin{macro}{\dim_gzero:N}
% \begin{macro}{\dim_zero:c}
% \begin{macro}{\dim_gzero:N}
% Resetting.
%    \begin{macrocode}
\def_new:Npn \dim_zero:N #1{#1\c_zero_skip}
\def_new:Npn \dim_gzero:N {\pref_global:D \dim_zero:N}
\def_new:Npn \dim_zero:c  {\exp_args:Nc \dim_zero:N}
\def_new:Npn \dim_gzero:c {\exp_args:Nc \dim_gzero:N}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\dim_add:Nn}
% \begin{macro}{\dim_add:cn}
% \begin{macro}{\dim_add:Nc}
% \begin{macro}{\dim_gadd:Nn}
% \begin{macro}{\dim_gadd:cn}
% Addition.
%    \begin{macrocode}
\def_new:Npn \dim_add:Nn #1#2{
%    \end{macrocode}
%    We need to say |by| in case the first argment is a register
%    accessed by its number, e.g., |\dimen23|.
%    \begin{macrocode}
    \tex_advance:D#1 by \dim_eval:n{#2}\scan_stop:
}
\def_new:Npn\dim_add:cn{\exp_args:Nc\dim_add:Nn}
\def_new:Npn\dim_add:Nc{\exp_args:NNc\dim_add:Nn}
\def_new:Npn \dim_gadd:Nn { \pref_global:D \dim_add:Nn }
\def_new:Npn\dim_gadd:cn{\exp_args:Nc\dim_gadd:Nn}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\dim_sub:Nn}
% \begin{macro}{\dim_sub:cn}
% \begin{macro}{\dim_sub:Nc}
% \begin{macro}{\dim_gsub:Nn}
% \begin{macro}{\dim_gsub:cn}
% Subtracting.
%    \begin{macrocode}
\def_new:Npn \dim_sub:Nn #1#2{\tex_advance:D#1-#2\scan_stop:}
\def_new:Npn\dim_sub:cn{\exp_args:Nc\dim_sub:Nn}
\def_new:Npn\dim_sub:Nc{\exp_args:NNc\dim_sub:Nn}
\def_new:Npn \dim_gsub:Nn {\pref_global:D \dim_sub:Nn }
\def_new:Npn\dim_gsub:cn{\exp_args:Nc\dim_gsub:Nn}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\dim_use:N}
% \begin{macro}{\dim_use:c}
% Accessing a \meta{dim}.
%    \begin{macrocode}
\let_new:NN \dim_use:N \tex_the:D
\def_new:Npn \dim_use:c {\exp_args:Nc\dim_use:N}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\l_tmpa_dim}
% \begin{macro}{\l_tmpb_dim}
% \begin{macro}{\l_tmpc_dim}
% \begin{macro}{\l_tmpd_dim}
% \begin{macro}{\g_tmpa_dim}
% \begin{macro}{\g_tmpb_dim}
% Some scratch registers.
%    \begin{macrocode}
\dim_new:N \l_tmpa_dim
\dim_new:N \l_tmpb_dim
\dim_new:N \l_tmpc_dim
\dim_new:N \l_tmpd_dim
\dim_new:N \g_tmpa_dim
\dim_new:N \g_tmpb_dim
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\c_zero_dim}
% \begin{macro}{\c_max_dim}
% Just aliases.
%    \begin{macrocode}
\let_new:NN \c_zero_dim \c_zero_skip
\let_new:NN \c_max_dim \c_max_skip
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\dim_eval:n}
% Evaluating a calc expression.
%    \begin{macrocode}
\def_new:Npn \dim_eval:n #1 {\etex_dimexpr:D #1 \scan_stop:}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\if_dim:w}
% The comparison primitive.
%    \begin{macrocode}
\let_new:NN \if_dim:w \tex_ifdim:D
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\dim_compare:nNnTF}
% \begin{macro}{\dim_compare:nNnT}
% \begin{macro}{\dim_compare:nNnF}
% Check the expression and choose branch.
%    \begin{macrocode}
\def_new:Npn \dim_compare:nNnTF #1#2#3{
  \if_dim:w \dim_eval:n {#1} #2 \dim_eval:n {#3}
    \exp_after:NN \use_arg_i:nn
  \else:
    \exp_after:NN \use_arg_ii:nn
  \fi:
}
\def_new:Npn \dim_compare:nNnT #1#2#3{
  \if_dim:w \dim_eval:n {#1} #2 \dim_eval:n {#3}
    \exp_after:NN \use_arg_ii:nn
  \fi:
  \use_none:n
}
\def_new:Npn \dim_compare:nNnF #1#2#3{
  \if_dim:w \dim_eval:n {#1} #2 \dim_eval:n {#3}
    \exp_after:NN \use_none:n
  \else:
    \exp_after:NN \use_arg_i:n
  \fi:
}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\dim_compare_p:nNn}
% A predicate function.
%    \begin{macrocode}
\def_new:Npn \dim_compare_p:nNn #1#2#3{
  \if_dim:w \dim_eval:n {#1} #2 \dim_eval:n {#3}
    \c_true
  \else:
    \c_false
  \fi:
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\dim_while:nNnT}
% \begin{macro}{\dim_while:nNnF}
% \begin{macro}{\dim_dowhile:nNnT}
% \begin{macro}{\dim_dowhile:nNnF}
% "while" and "do-while" functions for dimensions. Same as for the
% "int" type only the names have changed.
%    \begin{macrocode}
\def_new:Npn \dim_while:nNnT #1#2#3#4{
  \dim_compare:nNnT {#1}#2{#3}{#4 \dim_while:nNnT {#1}#2{#3}{#4}}
}
\def_new:Npn \dim_while:nNnF #1#2#3#4{
  \dim_compare:nNnF {#1}#2{#3}{#4 \dim_while:nNnF {#1}#2{#3}{#4}}
}
\def_new:Npn \dim_dowhile:nNnT #1#2#3#4{
  #4 \dim_compare:nNnT {#1}#2{#3}{\dim_dowhile:nNnT {#1}#2{#3}{#4}}
}
\def_new:Npn \dim_dowhile:nNnF #1#2#3#4{
  #4 \dim_compare:nNnF {#1}#2{#3}{\dim_dowhile:nNnF {#1}#2{#3}{#4}}
}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
%
% \subsubsection{Muskips}
%
% \begin{macro}{\muskip_new:N}
% \begin{macro}{\muskip_new_l:N}
% And then we add muskips.
%    \begin{macrocode}
%<*initex>
\alloc_setup_type:nnn {muskip} \c_zero \c_max_register_num
\def_new:Npn \muskip_new:N   #1{\alloc_reg:NnNN g {muskip} \tex_muskipdef:D #1}
\def_new:Npn \muskip_new_l:N #1{\alloc_reg:NnNN l {muskip} \tex_muskipdef:D #1}
%</initex>
%<package>\let_new:NN \muskip_new:N \newmuskip     % nicked from LaTeX
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\muskip_set:Nn}
% \begin{macro}{\muskip_gset:Nn}
% \begin{macro}{\muskip_add:Nn}
% \begin{macro}{\muskip_gadd:Nn}
% \begin{macro}{\muskip_sub:Nn}
% \begin{macro}{\muskip_gsub:Nn}
% Simple functions for muskips.
%    \begin{macrocode}
\def_new:Npn \muskip_set:Nn#1#2{#1\etex_muexpr:D#2\scan_stop:}
\def_new:Npn \muskip_gset:Nn{\pref_global:D\muskip_set:Nn}
\def_new:Npn \muskip_add:Nn#1#2{\tex_advance:D#1\etex_muexpr:D#2\scan_stop:}
\def_new:Npn \muskip_gadd:Nn{\pref_global:D\muskip_add:Nn}
\def_new:Npn \muskip_sub:Nn#1#2{\tex_advance:D#1-\etex_muexpr:D#2\scan_stop:}
\def_new:Npn \muskip_gsub:Nn{\pref_global:D\muskip_sub:Nn}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
%    \begin{macrocode}
%</initex|package>
%    \end{macrocode}
%
% \endinput
%
% $Log$
% Revision 1.18  2006/03/20 18:26:40  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.17  2006/01/27 11:22:38  morten
% Added \muskip_set:Nn and friends (since l3calc uses them).
%
% Revision 1.16  2006/01/17 22:46:37  morten
% Moved \skip_eval:n earlier to avoid error.
%
% Revision 1.15  2006/01/17 22:05:35  morten
% Minor updates
%
% Revision 1.14  2006/01/14 19:13:16  morten
% Added operations for \vskip and \hskip
%
% Revision 1.13  2005/12/27 15:54:44  morten
% Changed RCS information retrieval
%
% Revision 1.12  2005/10/27 22:56:15  morten
% Moved \if_dim:w to this module.
%
% Revision 1.11  2005/04/12 12:07:10  morten
% Added muskips
%
% Revision 1.10  2005/04/09 21:09:48  morten
% Both documentation  and implementation cleaned up.
%
% Revision 1.9  2005/04/06 22:35:57  braams
% Now we have register allocation fitted
%
% Revision 1.8  2005/03/26 21:05:42  morten
% Make \c_zero_skip different from \c_zero
%
% Revision 1.7  2005/03/16 22:35:47  braams
% Added the tweaks necessary to be able to load with initex
%
% Revision 1.6  2005/03/11 21:42:48  braams
% Fixed the use of RCS information; added \StopEventually
%
