% \iffalse
%% File: l3skip.dtx Copyright (C) 2005-2010 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/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}
%</driver|package>
%\fi
\GetIdInfo$Id: l3skip.dtx 1933 2010-05-25 00:26:38Z will $
       {L3 Experimental skip registers}
%\iffalse
%<*driver>
%\fi
\ProvidesFile{\filename.\filenameext}
  [\filedate\space v\fileversion\space\filedescription]
%\iffalse
\documentclass[full]{l3doc}
\begin{document}
\DocInput{l3skip.dtx}
\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
%
% \begin{documentation}
%
%  \LaTeX3 knows about two types of length registers for internal use:
%  rubber lengths ("skip"s) and rigid lengths ("dim"s).
%
%  \section{Skip registers}
%
%
%
% \subsection{Functions}
%
% \begin{function}{ \skip_new:N   |
%                   \skip_new:c   }
% \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}.
% \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> \Arg{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> \Arg{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> \Arg{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_show:N |
%                   \skip_show:c }
% \begin{syntax}
%   "\skip_show:N" <skip>
% \end{syntax}
% This function pauses the compilation and displays the length value kept 
% in <skip> in the console output and log file.
% \begin{texnote}
% The function "\skip_show:N" could be implemented directly as the \TeX{}
% primitive "\tex_showthe: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" \Arg{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_if_infinite_glue_p:n |
%                   \skip_if_infinite_glue:n  / (TF) }
% \begin{syntax}
%   "\skip_if_infinite_glue:nTF" \Arg{skip} \Arg{true} \Arg{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" \Arg{skip} \Arg{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 / (EXP) |
% }
% \begin{syntax}
%   "\skip_eval:n"   \Arg{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}
%
%
% \subsection{Formatting a skip register value}
%
%
% \subsection{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 |
% }
% Constants denoting a zero skip.
% \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}
%
%
%
%
%
% \section{Dim registers}
%
%
% \subsection{Functions}
%
%
%
%
% \begin{function}{ \dim_new:N  |
%                   \dim_new:c  }
% \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}.
% \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:Nc |
%                  \dim_set:cn |
%                  \dim_gset:Nn |
%                  \dim_gset:Nc |
%                  \dim_gset:cn |
%                  \dim_gset:cc |
% }
% \begin{syntax}
%   "\dim_set:Nn"   <dim> \Arg{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:Nc |
%                  \dim_add:cn |
%                  \dim_gadd:Nn |
%                  \dim_gadd:cn |
% }
% \begin{syntax}
%   "\dim_add:Nn"   <dim> \Arg{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_sub:Nc |
%                  \dim_sub:cn |
%                  \dim_gsub:Nn |
%                  \dim_gsub:cn |
% }
% \begin{syntax}
%   "\dim_gsub:Nn"   <dim> \Arg{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_show:N |
%                   \dim_show:c }
% \begin{syntax}
%   "\dim_show:N" <dim>
% \end{syntax}
% This function pauses the compilation and displays the length value kept
% in <skip> in the console output and log file.
% \begin{texnote}
% The function "\dim_show:N" could be implemented directly as the \TeX{}
% primitive "\tex_showthe: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"   \Arg{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:nNn / (TF)(EXP) | \dim_compare_p:nNn / (EXP)}
% \begin{syntax}
%   "\dim_compare:nNnTF"   \Arg{dim~expr} <rel> \Arg{dim~expr}
%                         \Arg{true} \Arg{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_while_do:nNnn |
%                  \dim_until_do:nNnn |
%                  \dim_do_while:nNnn |
%                  \dim_do_until:nNnn |
% }
% \begin{syntax}
%   "\dim_while_do:nNnn"   <dim expr> <rel> <dim~expr> <code>
% \end{syntax}
%  "\dim_while_do:nNnn" tests the dimension expressions and if true performs
%  <code> repeatedly while the test remains true. "\dim_do_while:nNnn" is similar
%  but executes the body first and then performs the check, thus
%  ensuring that the body is executed at least once. The `until' versions
%  are similar but continue the loop as long as the test is false.
% \end{function}
%
%
%
% \subsection{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}
%
% \section{Muskips}
%
% \begin{function}{ \muskip_new:N   }
% \begin{syntax}
%    "\muskip_new:N"   <muskip>
% \end{syntax}
% \begin{texnote}
% Defines <muskip> to be a new variable of type "muskip".
% "\muskip_new:N" is the equivalent to plain \TeX{}'s \tn{newmuskip}.
% \end{texnote}
% \end{function}
%
% \begin{function}{%
%                  \muskip_set:Nn |
%                  \muskip_gset:Nn |
% }
% \begin{syntax}
%   "\muskip_set:Nn"   <muskip> \Arg{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> \Arg{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> \Arg{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}
%
% \begin{function}{ \muskip_use:N }
% \begin{syntax}
%   "\muskip_use:N"   <muskip>
% \end{syntax}
% This function returns the length value kept in <muskip> in a way
% suitable for further processing.
% \begin{texnote}
% See note for "\dim_use:N".
% \end{texnote}
% \end{function}
%
% \begin{function}{ \muskip_show:N }
% \begin{syntax}
%   "\muskip_show:N" <muskip>
% \end{syntax}
% This function pauses the compilation and displays the length value kept
% in <muskip> in the console output and log file.
% \end{function}
%
% \end{documentation}
%
% \begin{implementation}
%
% \section{\pkg{l3skip} implementation}
%
%
%    We start by ensuring that the required packages are loaded.
%    \begin{macrocode}
%<*package>
\ProvidesExplPackage
  {\filename}{\filedate}{\fileversion}{\filedescription}
\package_check_loaded_expl:
%</package>
%<*initex|package>
%    \end{macrocode}
%
% \subsection{Skip registers}
%
% \begin{macro}{\skip_new:N,\skip_new:c}
%    Allocation of a new internal registers.
%    \begin{macrocode}
%<*initex>
\alloc_new:nnnN {skip} \c_zero \c_max_register_int \tex_skipdef:D
%</initex>
%<*package>
\cs_new_protected_nopar:Npn \skip_new:N #1 {
  \chk_if_free_cs:N #1
  \newskip #1
}
%</package>
\cs_generate_variant:Nn \skip_new:N {c}
%    \end{macrocode}
% \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}
\cs_new_protected_nopar:Npn \skip_set:Nn #1#2 { 
  #1\skip_eval:n{#2}
%<*check>
\chk_local_or_pref_global:N #1
%</check>
}
\cs_new_protected_nopar:Npn \skip_gset:Nn {
%<*check>
  \pref_global_chk:
%</check>
%<-check> \pref_global:D
  \skip_set:Nn 
}
\cs_generate_variant:Nn \skip_set:Nn  {cn}
\cs_generate_variant:Nn \skip_gset:Nn  {cn}
%    \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}
\cs_new_protected_nopar:Npn \skip_zero:N #1{
  #1\c_zero_skip \scan_stop:
%<*check>
  \chk_local_or_pref_global:N #1
%</check>
}
\cs_new_protected_nopar: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
}
\cs_generate_variant:Nn \skip_zero:N {c}
\cs_generate_variant:Nn \skip_gzero:N {c}
%    \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_gadd:cn}
% \begin{macro}{\skip_sub:Nn}
% \begin{macro}{\skip_gsub:Nn}
%    Adding and subtracting to and from <skip>s
%    \begin{macrocode}
\cs_new_protected_nopar: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>
}
\cs_generate_variant:Nn \skip_add:Nn {cn}
%    \end{macrocode}
% 
%    \begin{macrocode}
\cs_new_protected_nopar:Npn \skip_sub:Nn #1#2{
  \tex_advance:D#1-\skip_eval:n{#2}
%<*check>
  \chk_local_or_pref_global:N #1
%</check>
}
%    \end{macrocode}
% 
%    \begin{macrocode}
\cs_new_protected_nopar:Npn \skip_gadd:Nn {
%<*check>
  \pref_global_chk:
%</check>
%<-check> \pref_global:D
  \skip_add:Nn 
}
\cs_generate_variant:Nn \skip_gadd:Nn {cn}
%    \end{macrocode}
% 
%    \begin{macrocode}
\cs_new_nopar: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}
% \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}
\cs_new_eq:NN  \skip_horizontal:N \tex_hskip:D
\cs_generate_variant:Nn \skip_horizontal:N {c}
%    \end{macrocode}
%    
%    \begin{macrocode}
\cs_new_nopar:Npn \skip_horizontal:n #1 { \skip_horizontal:N \skip_eval:n{#1} }
\cs_new_eq:NN  \skip_vertical:N \tex_vskip:D
\cs_generate_variant:Nn \skip_vertical:N {c}
\cs_new_nopar: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}
\cs_new_eq:NN \skip_use:N \tex_the:D
\cs_generate_variant:Nn \skip_use:N {c} 
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\skip_show:N}
% \begin{macro}{\skip_show:c}
%    Diagnostics.
%    \begin{macrocode}
\cs_new_eq:NN  \skip_show:N \kernel_register_show:N
\cs_generate_variant:Nn \skip_show:N {c}
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
%
% \begin{macro}{\skip_eval:n}
% Evaluating a calc expression.
%    \begin{macrocode}
\cs_new_protected_nopar: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_if_free_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>
\cs_set_eq:NN \c_zero_skip \z@
\cs_set_eq:NN \c_max_skip  \maxdimen
%</!initex>
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
%
%
% \begin{macro}{\skip_if_infinite_glue_p:n}
% \begin{macro}[TF]{\skip_if_infinite_glue:n}
%  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_if_infinite_glue:nTF" tests it directly by
%  looking at the stretch and shrink order. If either of the predicate
%  functions return \m{true} "\bool_if:nTF" will return \m{true}
%  and the logic test will take the true branch.
%    \begin{macrocode}
\prg_new_conditional:Nnn \skip_if_infinite_glue:n {p,TF,T,F} {
  \bool_if:nTF {
      \intexpr_compare_p:nNn {\etex_gluestretchorder:D #1 } > \c_zero ||
      \intexpr_compare_p:nNn {\etex_glueshrinkorder:D  #1 } > \c_zero
  } {\prg_return_true:} {\prg_return_false:}
}
%    \end{macrocode}
%  \end{macro}
%  \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}
\cs_new_nopar:Npn \skip_split_finite_else_action:nnNN #1#2#3#4{
  \skip_if_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}
%
%
%
% \subsection{Dimen registers}
%
% \begin{macro}{\dim_new:N,\dim_new:c}
%    Allocating \meta{dim} registers...
%    \begin{macrocode}
%<*initex>
\alloc_new:nnnN {dim} \c_zero \c_max_register_int \tex_dimendef:D
%</initex>
%<*package>
\cs_new_protected_nopar:Npn \dim_new:N #1 {
  \chk_if_free_cs:N #1
  \newdimen #1
}
%</package>
\cs_generate_variant:Nn \dim_new:N {c}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\dim_set:Nn}
% \begin{macro}{\dim_set:cn}
% \begin{macro}{\dim_set:Nc}
% \begin{macro}{\dim_gset:Nn}
% \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}
\cs_new_protected_nopar:Npn \dim_set:Nn #1#2 { #1~ \dim_eval:n{#2} }
\cs_generate_variant:Nn \dim_set:Nn {cn,Nc}
%    \end{macrocode}
%    
%    \begin{macrocode}
\cs_new_protected_nopar:Npn \dim_gset:Nn { \pref_global:D \dim_set:Nn  }
\cs_generate_variant:Nn \dim_gset:Nn {cn,Nc,cc}
%    \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:c}
% Resetting.
%    \begin{macrocode}
\cs_new_protected_nopar:Npn \dim_zero:N #1 { #1\c_zero_skip }
\cs_generate_variant:Nn \dim_zero:N {c}
%    \end{macrocode}
%    
%    \begin{macrocode}
\cs_new_protected_nopar:Npn \dim_gzero:N { \pref_global:D \dim_zero:N  }
\cs_generate_variant:Nn \dim_gzero:N {c}
%    \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}
\cs_new_protected_nopar: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:
}
\cs_generate_variant:Nn \dim_add:Nn {cn,Nc}
%    \end{macrocode}
%    
%    \begin{macrocode}
\cs_new_protected_nopar:Npn \dim_gadd:Nn { \pref_global:D \dim_add:Nn  }
\cs_generate_variant:Nn \dim_gadd:Nn {cn}
%    \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}
\cs_new_protected_nopar:Npn \dim_sub:Nn #1#2 { \tex_advance:D#1-#2\scan_stop: }
\cs_generate_variant:Nn \dim_sub:Nn {cn,Nc}
%    \end{macrocode}
%    
%    \begin{macrocode}
\cs_new_protected_nopar:Npn \dim_gsub:Nn { \pref_global:D \dim_sub:Nn  }
\cs_generate_variant:Nn \dim_gsub:Nn {cn}
%    \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}
\cs_new_eq:NN \dim_use:N \tex_the:D
\cs_generate_variant:Nn \dim_use:N {c}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\dim_show:N}
% \begin{macro}{\dim_show:c}
%    Diagnostics.
%    \begin{macrocode}
\cs_new_eq:NN  \dim_show:N \kernel_register_show:N
\cs_generate_variant:Nn \dim_show:N {c}
%    \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}
\cs_new_eq:NN \c_zero_dim \c_zero_skip
\cs_new_eq:NN \c_max_dim  \c_max_skip
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\dim_eval:n}
% Evaluating a calc expression.
%    \begin{macrocode}
\cs_new_protected_nopar: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}
\cs_new_eq:NN \if_dim:w \tex_ifdim:D
%    \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\dim_compare_p:nNn}
% \begin{macro}[TF]{\dim_compare:nNn}
%    \begin{macrocode}
\prg_new_conditional:Nnn \dim_compare:nNn {p,TF,T,F} {
  \if_dim:w \dim_eval:n {#1} #2 \dim_eval:n {#3}
    \prg_return_true: \else: \prg_return_false: \fi:
}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\dim_while_do:nNnn}
% \begin{macro}{\dim_until_do:nNnn}
% \begin{macro}{\dim_do_while:nNnn}
% \begin{macro}{\dim_do_until:nNnn}
% "while_do" and "do_while" functions for dimensions. Same as for the
% "int" type only the names have changed.
%    \begin{macrocode}
\cs_new_nopar:Npn \dim_while_do:nNnn #1#2#3#4{
  \dim_compare:nNnT {#1}#2{#3}{#4 \dim_while_do:nNnn {#1}#2{#3}{#4}}
}
\cs_new_nopar:Npn \dim_until_do:nNnn #1#2#3#4{
  \dim_compare:nNnF {#1}#2{#3}{#4 \dim_until_do:nNnn {#1}#2{#3}{#4}}
}
\cs_new_nopar:Npn \dim_do_while:nNnn #1#2#3#4{
  #4 \dim_compare:nNnT {#1}#2{#3}{\dim_do_while:nNnn {#1}#2{#3}{#4}}
}
\cs_new_nopar:Npn \dim_do_until:nNnn #1#2#3#4{
  #4 \dim_compare:nNnF {#1}#2{#3}{\dim_do_until:nNnn {#1}#2{#3}{#4}}
}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
%
% \subsection{Muskips}
%
% \begin{macro}{\muskip_new:N}
% And then we add muskips.
%    \begin{macrocode}
%<*initex>
\alloc_new:nnnN {muskip} \c_zero \c_max_register_int \tex_muskipdef:D
%</initex>
%<*package>
\cs_new_protected_nopar:Npn \muskip_new:N #1 {
  \chk_if_free_cs:N #1
  \newmuskip #1
}
%</package>
%    \end{macrocode}
% \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}
\cs_new_protected_nopar:Npn \muskip_set:Nn#1#2{#1\etex_muexpr:D#2\scan_stop:}
\cs_new_protected_nopar:Npn \muskip_gset:Nn{\pref_global:D\muskip_set:Nn}
\cs_new_protected_nopar:Npn \muskip_add:Nn#1#2{\tex_advance:D#1\etex_muexpr:D#2\scan_stop:}
\cs_new_protected_nopar:Npn \muskip_gadd:Nn{\pref_global:D\muskip_add:Nn}
\cs_new_protected_nopar:Npn \muskip_sub:Nn#1#2{\tex_advance:D#1-\etex_muexpr:D#2\scan_stop:}
\cs_new_protected_nopar: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{macro}{\muskip_use:N}
% Accessing a \meta{muskip}.
%    \begin{macrocode}
\cs_new_eq:NN \muskip_use:N \tex_the:D
%    \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\muskip_show:N}
%    \begin{macrocode}
\cs_new_eq:NN \muskip_show:N \kernel_register_show:N
%    \end{macrocode}
% \end{macro}
%
%
%    \begin{macrocode}
%</initex|package>
%    \end{macrocode}
%
% \end{implementation}
% \PrintIndex
%
% \endinput
