% \iffalse %% File: l3skip.dtx Copyright (C) 2005-2006 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. %% %% ----------------------------------------------------------------------- % %\RequirePackage{l3names} %<*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 % %\fi \GetIdInfo$Id: l3skip.dtx 573 2006-08-21 20:59:37Z morten $ {L3 Experimental skip registers} % % \iffalse %<*driver> \documentclass{l3doc} \begin{document} \DocInput{l3skip.dtx} \end{document} % % \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" % \end{syntax} % Defines 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" % \end{syntax} % Locally or globally reset 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" "{" "}" % \end{syntax} % These functions will set the register to the value. % \end{function} % % % \begin{function}{% % \skip_add:Nn | % \skip_add:cn | % \skip_gadd:Nn | % } % \begin{syntax} % "\skip_add:Nn" "{" "}" % \end{syntax} % These functions will add to the register the value . If % the second argument is a register too, the surrounding braces % can be left out. % \end{function} % % \begin{function}{% % \skip_sub:Nn | % \skip_gsub:Nn | % } % \begin{syntax} % "\skip_gsub:Nn" "{" "}" % \end{syntax} % These functions will subtract from the register the value % . If the second argument is a register too, the % surrounding braces can be left out. % \end{function} % % \begin{function}{% % \skip_use:N | % \skip_use:c | % } % \begin{syntax} % "\skip_use:N" % \end{syntax} % This function returns the length value kept in 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_horizontal:n" "{" "}" % \end{syntax} % The "hor" functions insert or with the \TeX\ % primitive \tn{hskip}. The "vertical" variants do the same with % \tn{vskip}. The "n" versions evaluate with "\skip_eval:n". % \end{function} % % % \begin{function}{% % \skip_infinite_glue:nTF | % } % \begin{syntax} % "\skip_infinite_glue:nTF" "{""}" "{""}" "{""}" % \end{syntax} % Checks if contains infinite stretch or shrink components % and executes either or . 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" "{""}" "{""}" % % \end{syntax} % Checks if contains finite glue. If it does then it assigns % the stretch component and the shrink component. If % it contains infinite glue set and 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" "{""}" % \end{syntax} % Evaluates the value of 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 % 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" % \end{syntax} % Defines 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" % \end{syntax} % Locally or globally reset 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" "{" "}" % \end{syntax} % These functions will set the register to the value. % \end{function} % % % \begin{function}{% % \dim_add:Nn | % \dim_add:cn | % \dim_gadd:Nn | % } % \begin{syntax} % "\dim_add:Nn" "{" "}" % \end{syntax} % These functions will add to the register the value . If % the second argument is a register too, the surrounding braces % can be left out. % \end{function} % % \begin{function}{% % \dim_sub:Nn | % \dim_gsub:Nn | % } % \begin{syntax} % "\dim_gsub:Nn" "{" "}" % \end{syntax} % These functions will subtract from the register the value % . If the second argument is a register too, the % surrounding braces can be left out. % \end{function} % % \begin{function}{% % \dim_use:N | % \dim_use:c | % } % \begin{syntax} % "\dim_use:N" % \end{syntax} % This function returns the length value kept in 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" "{""}" % \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" "\else:" "\fi:" % \end{syntax} % Compare two dimensions. It is recommended to use "\dim_eval:n" to % correctly evaluate and terminate these numbers. 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" "{""}" "{""}" % "{""}" "{""}" % \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" "{""}" "{""}" % \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" % \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 % 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" % \end{syntax} % Defines 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" "{" "}" % \end{syntax} % These functions will set the register to the % value. % \end{function} % % % \begin{function}{% % \muskip_add:Nn | % \muskip_gadd:Nn | % } % \begin{syntax} % "\muskip_add:Nn" "{" "}" % \end{syntax} % These functions will add to the register the value % . If the second argument is a register too, the % surrounding braces can be left out. % \end{function} % % \begin{function}{% % \muskip_sub:Nn | % \muskip_gsub:Nn | % } % \begin{syntax} % "\muskip_gsub:Nn" "{" "}" % \end{syntax} % These functions will subtract from the register the value % . If the second argument is a 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} %\RequirePackage{l3int} %\RequirePackage{l3prg} %\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 } % %\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 % } \def_new:Npn \skip_gset:Nn { %<*check> \pref_global_chk: % %<-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 % } \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> \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 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 % } \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 % } \def_new:Npn \skip_gadd:Nn { %<*check> \pref_global_chk: % %<-check> \pref_global:D \skip_add:Nn } \def_new:Npn \skip_gsub:Nn { %<*check> \pref_global_chk: % %<-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} % %<*!initex> \let:NN \c_zero_skip \z@ \let:NN \c_max_skip \maxdimen % % \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{ \prg_logic_test:nTF { \prg_logic_or_p:nn { \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 } % %\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} % 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 } % \end{macrocode} % \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} % 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 } % \end{macrocode} % \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} % %\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} % % \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 %