diff options
author | Karl Berry <karl@freefriends.org> | 2006-01-11 23:49:19 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2006-01-11 23:49:19 +0000 |
commit | b3e91602f5c5c87db7d26bc4e2422697cbfefdb8 (patch) | |
tree | 727056e7ca8a3fc6e395eae3296e66f4b081eecc /Master/texmf-dist/source/latex3 | |
parent | 23d7c0b36aca6e9b3a074d0382ad9bb24d351bc6 (diff) |
trunk/Master/texmf-dist/source/latex3
git-svn-id: svn://tug.org/texlive/trunk@113 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex3')
31 files changed, 23393 insertions, 0 deletions
diff --git a/Master/texmf-dist/source/latex3/galley/galley2.dtx b/Master/texmf-dist/source/latex3/galley/galley2.dtx new file mode 100644 index 00000000000..a2fd84c8e16 --- /dev/null +++ b/Master/texmf-dist/source/latex3/galley/galley2.dtx @@ -0,0 +1,3780 @@ +% \iffalse +%% +%% $Header: /usr3/users/latex3/design/consolidation/CURRENT/RCS/galley2.dtx,v 1.15 2000/01/27 21:45:56 latex3 Exp $ +%% +%% (C) Copyright 1999-2000 Frank Mittelbach +%% All rights reserved. +%% +%% Not for general distribution. In its present form it is not allowed +%% to put this package onto CD or an archive without consulting the +%% the authors. +%% +%<*dtx> + \ProvidesFile{galley.dtx} +%</dtx> +%<package>\NeedsTeXFormat{LaTeX2e} +%<package>\ProvidesPackage{galley2} +%<driver>\ProvidesFile{galley.drv} +% \fi +% \ProvidesFile{galley2.dtx} + [2000/01/27 v0.2s galley structures] +% +% \iffalse +%<*driver> + \documentclass{ltxdoc} + \typeout{********} + \typeout{* Unpack with:} + \typeout{* \string\generate{% + \string\file{galley2.sty}{\string\from{galley2.dtx}{package,trace}}} + } + \typeout{********} +% \usepackage{ldcdoc} +% \makeatletter +% \let\GAL@typeout\@gobble \let\GAL@show@datastructure\@gobble +% \makeatother + + \newcommand\LaTeXplus{\LaTeXe$*$} + + \CodelineIndex \EnableCrossrefs + \renewcommand\MakePrivateLetters{\makeatletter\catcode`\:11\relax} + \begin{document} + \DocInput{galley2.dtx} + \end{document} +%</driver> +% \fi +% +% \CheckSum{0} +% +% \newcommand\PARM[1]{parameter \textbf{#1}} +% \newcommand\subsubsubsection{\paragraph} +% +% +% \GetFileInfo{galley2.dtx} +% +% \title{The \textsf{galley} package\thanks{This file +% has version number \fileversion, last +% revised \filedate.}} +% \author{FMi} +% \date{\filedate} +% \maketitle +% +% \begin{abstract} +% This module provides the data structure for galleys and contains +% the low-level interfaces for direct manipulation of this data structure. +% Higher-level templates for interfacing with the +% galley mechanism are set up by the module +% \texttt{xhj}. +% The low-level interfaces of the current module are geared +% towards package writers having special needs which are not +% fulfilled by the templates in the \texttt{xhj} module. +% They are not intended to be used directly in class design. +% \end{abstract} +% +% \tableofcontents +% +% \section{Introduction} +% +% In \LaTeXplus{} terminology a galley is a rectangular area which +% receives text and other material filling it from +% top.\footnote{The predominant direction depends on the writing +% system and with extensions to \TeX{} such as Omega there are +% possibilities to define galleys with a different filling direction.} +% The vertically extend of a galley is normally not restricted +% (there are exceptions); instead certain chunks are taken off the top +% of an +% already partially filled galley to form columns or similar areas +% on a page. This process is typically asynchronous but there are ways +% to control or change its behavior. +% +% Examples for galleys are `the main galley', where the continuous +% document data gets formatted into and from which columns and pages are +% constructed, and `vbox galley's, such as the body of a minipage +% environment or the body of a float (in \LaTeXe only---the new float +% mechanism for \LaTeXplus{} will employ horizontally oriented float +% bodies). The latter galleys are typically not being split after +% formatting though there can be exceptions. +% +% The data that is being formatted into a galley can be described as a +% sequence of paragraphs of text separated by vertical material such +% as vertical spaces, penalties, writes, specials, etc. +% +% There are two components that a mechanism for galleys has to provide: +% the framework for manipulating the shape and placement of paragraph +% text (this is provided with higher-level templates in the module +% \texttt{xhj}) and the framework for manipulating the inter-paragraph +% material. +% +% +% +% \subsection{Some problems with \LaTeXe{} galleys} +% +% The handling of inter-paragraph material poses the most difficult +% problems as it is typically influenced by various factors and +% information gained at different stages throughout the document +% processing. \LaTeXe{} provided a certain control over this material, +% e.g., headings would set a |@nobreak| flag to prevent paragraph +% breaking after them and other commands and environments would test +% for it; |\addvspace| and |\addpenalty| could be used several times +% in succession and still provide reasonable results, but all in all +% these have been adhoc solutions to the most pressing problem of that +% area---many others remained unsolved: +% +% The following is a list of document extracts which one can imagine +% to appear in ordinary documents. They all have in common that in +% \LaTeXe{} they produce surprising (and undesired) results: +% \begin{enumerate} +% \item +% \begin{verbatim} +% \end{itemize} \vspace{3pt} \begin{itemize} ... +%\end{verbatim} +% \ldots not three points of extra space but 13 (with +% the \texttt{article} class) +% +% \item +% \begin{verbatim} +% \section{HEAD} {\sc ABC} ... +%\end{verbatim} +% \ldots page breaking restrictions apply to the +% second paragraph after the heading not the first as they +% should +% \item +% \begin{verbatim} +% \usepackage{hyperref} +%\end{verbatim} +% \ldots the danger of completely changed vertical spacing because +% the |\special|s added by \texttt{hyperref} interfere with the +% spacing and penalty mechanisms of \LaTeXe +% +% +% \item +% \begin{verbatim} +% {\section{HEAD}} para text \par \begin{itemize} ... +%\end{verbatim} +% \ldots one gets an indentation after the heading; a page break might +% happen after the first line in the paragraphs; and there will be no +% space above the itemize environment (though there will be space +% below) --- because of this \LaTeXe{} claims this is incorrect input +% --- and then since \LaTeX\,2.09 uses the equivalent of +% |\twocolumn[\chapter{HEAD}]| in certain circumstances in the report +% and book class :-) +% \end{enumerate} +% +% All these pitfalls are due to the fact that \LaTeXe{} typesets the +% inter-paragraph material whenever it receives it and once it is +% typeset \TeX{} has only a limited power to modify the material +% already present on the galley. +% +% Thus to be able to do better one has to defer any typesetting until +% the very last moment (i.e., when the next paragraph starts) and +% instead collect such inter-paragraph material in a suitable data +% structure where it can be manipulated and examined. +% The present code in this module provides such a data structure. Of +% course, to be successful it is important that all functions that +% would normally produce inter-paragraph material (such as user +% commands like |\vspace|) obey the concepts behind the mechanism and +% refrain from directly adding to the galley. +% How this is achieved will be explained in the next sections. +% +% +% \section{The galley data structure} +% +% A galley is a \LaTeX{} object which contains (or receives) +% paragraphs and typesets them vertically below each other intermixed +% with material like vertical spaces and penalties, etc.\ which are +% placed between such paragraphs. +% +% Galleys can be nested and thus data structures associated with them +% need to be provided using a stack structure. +% +% Technical aspects of the implementation of this structure are +% discussed in section~\ref{sec:galley-concept-impl}. +% +% +% \subsection{Writes, marks, specials and inserts} +% +% Writes, marks, specials and inserts are internally represented by +% \TeX{} as invisible objects (nodes) within the horizontal or +% vertical lists of \TeX. The +% problem with this is that they interfere with other nodes, produce +% additional break points, etc. +% +% For this reason they should not appear on their own but need to be +% placed into precisely controlled places. They can either go directly +% after the last line of a paragraph (preceded and followed by +% |\nobreak|) or they can go directly in front of the next +% paragraph. Table~\ref{tab:vthing} lists the different nodes and +% their suggested handling. +% \begin{table} +% \begin{center} +% \begin{tabular}{ll} +% \hline +% vthing & attach to \\ +% \hline +% insert & prev \\ +% write & prev or next (flag) \\ +% mark & prev or next (flag) \\ +% special (hyperref) & prev or next (different command) \\ +% special (others) & next +% \end{tabular} +% \end{center} +% \small ^^A well designed object :-) +% \begin{quote} +% prev := just add to MVL followed by |\nobreak| \\ +% next := store tokens and put in a primitive ``in hmode at start of +% next para'' +% \end{quote} +% \caption{Invisible nodes and their handling}\label{tab:vthing} +% \end{table} +% +% +% \subsection{Individual parameters} +% +% Each parameter related to a galley exists in two incarnation: +% \begin{itemize} +% \item it has one value which is considered to be static for a +% sequence of paragraphs (potentially for all paragraphs typeset on +% this level); any change to it via some mutator command will +% persist until a further change or the end of the level --- called +% static galley parameter value (SGPV) +% \item it has one value which is reset after each use to the +% corresponding static value --- called dynamic galley parameter +% value (DGPV). +% \end{itemize} +% +% The actual processing routines always use the DGPVs. Thus to produce +% a paragraph sequence with a certain uniform setting of parameters +% one would set up (or modify) the SGPVs, and to locally overwrite +% individual values for one paragraph one would modify the relevant DGPVs. +% +% +% \subsubsection{Vertical (pre-paragraph) parameters} +% +% \begin{description} +% \item[nobreak flag (b)] a flag that signals how page breaking should +% be handled +% between the previous and the upcoming paragraph; it takes a number +% between 0 and 3 with the following meaning: 0 means normal +% breaking behavior (value of \PARM{penalty} is used), 1 means +% prevent break between paragraphs (value of \PARM{penalty} is +% discarded and replaced by 10000), 2 is like 1 but additionally +% prevents\footnote{as far as possible with \TeX} a page break +% within the first lines of the upcoming paragraph (by fiddling with +% |\clubpenalty|), 3 is like 1 but also suppresses a page break for +% the whole upcoming paragraph (by setting +% |\interlinepenalty|)\footnote{One can actually implement something +% even better: with e\TeX{} more control is possible and with normal +% \TeX{} one could prevent a break for a minimum of X lines by +% checking on the value of \texttt{\textbackslash prevgraf} and decreasing this for the next +% time around} +% At the moment it also supports negative numbers ($-3$ especially) +% which have the same meaning as the positive counterparts except +% that they only influence the breaking within the paragraph, e.g., +% $-3$ do not break within the next paragraph (which is useful for +% initials etc). However this should probably be redesigned properly! +% \item[vpenalty (p)] penalty between paragraphs unless flag above is set +% \item[vspace (v)] skip between paragraphs as set by class or package +% commands, if -1sp then |\parskip| is used instead.\footnote{This +% -1sp is a speedup measure to avoid the need for an additional flag +% for suppressing or adding \texttt{\textbackslash parskip}, this way +% between normal paragraphs \texttt{\textbackslash parskip} is +% added (as the default for this parameter is -1sp) but any setting +% will result in suppressing it. Of course this means if some +% environment requests some space it does get 1sp less, acceptable? +% Using 0pt instead is not a good idea as it makes it difficult to +% state for some environment that all space should be suppressed.} +% \item[user vpenalty (up)] penalty between paragraphs set by user level +% commands +% \item[user vspace (uv)] additional space between paragraphs set by user level +% commands. This space is always added and never suppressed or subject +% to functions like using the maximum, since it is provided by +% user commands like |\vspace| where we assume that the user intends +% to correct the default result. +% \item[prev whatsits (pw)] whatsits that are supposed to get attached to +% the previous paragraph +% \item[parshape (ps)] structured parameter that sets up a \TeX{} +% |\parshape| declaration or empty; it replaces the next two parameters +% in the current implementation. However for reasons of secure +% programming it might be necessary to have all three. (Right now +% |\linewidth| and |\@totalleftmargin| are locally set when +% modifying the ps parameter and thus are in danger of getting out +% of sync if setting happens not at group boundaries. +% \item[measure (m)] nominal width of the upcoming paragraph lines +% (|\linewidth| is set to this value)\footnote{Not used right now +% see comment on ps parameter.} +% \item[hoffset (h)] offset for the upcoming paragraph lines from the left +% margin (in \LaTeXe{} this was +% |\@totalleftmargin|).\footnote{Not used right now, see comment on +% ps parameter.} +% \end{description} +% +% +% \subsubsection{Paragraph-start parameters} +% +% \begin{description} +% \item[indentation (i)] flag to suppress insertion of indentation +% box. A value of 0 means insert indentation any other value suppresses +% indentation. +% \item[next whatsits (nw)] whatsits that are supposed to get attached to +% the next paragraph +% \item[object (o)] typeset material at the start of the paragraph +% \item[queries (q)] information about previously seen objects/states +% on the galley that can be queried by following code as necessary, +% e.g., the fact that we just have processed an `item', or a +% `heading', or \ldots +% +% This parameter is not yet properly used and perhaps becomes +% obsolete once there is a proper mechanism for handing such data. +% \end{description} +% +% +% \subsubsection{Paragraph-justification parameters} +% +% The following parameter is supposed to define the inner shape of a +% paragraph, e.g., adjusted, centered lines, ragged shapes, etc. It +% is not meant to define the measure (for this see the \PARM{parshape}). +% \begin{description} +% \item[justification (j)] This is a multivalued parameter consisting of +% \begin{itemize} +% \item the counterpart to |\parfillskip| at the +% beginning of a paragraph +% \item the \TeX{} |\leftskip| +% \item the \TeX{} |\rightskip| +% \item the \TeX{} |\parfillskip| +% \item the \TeX{} |\spaceskip| +% \item the \TeX{} |\xspaceskip| +% \item glue specification to be put in front of a forced ``newline'' +% \item the \TeX{} |\parindent|\footnote{This parameter should +% perhaps be taken out, there is some dicussion related to +% this elsewhere.} +% \end{itemize} +% \end{description} +% +% \subsubsection{Line breaking parameters} +% +% Line breaking parameters are considered to be not related to +% individual paragraphs but to paragraphs sequences, i.e., they are +% not reset on each paragraph. Wrong? Instead they are initialized at +% start of galley and are otherwise only settable via templates. One +% could of course make them a multivalued parameter as well. +% +% +% +% \subsubsection{Paragraph-end parameters} +% +% None defined yet (but perhaps should) +% +% +% +% \subsection{Document level (user) commands} +% +% \subsubsection{Penalties} +% +% To give the user a chance to actually overwrite a penalty setting +% produced from environments or commands internally updating the +% galley structure, user level document commands like |\nopagebreak| +% do not modify the internal \PARM{penalty} but instead use a +% \PARM{user penalty}. If that parameter is set (i.e., non-empty) it +% will get used and the internal \PARM{penalty} that is normally +% applied will be ignored. This way, even in situations where the +% user request appears too early in the document (e.g., between +% environments where the following environment would modify +% \PARM{penalty} the desired outcome is ensured. +% +% \subsubsection{Vertical spaces} +% +% In contrast user commands for specifying vertical space will always +% add to the existing space.\footnote{Always? i can image to have the +% desire to explicitly set the space to a fixed value in which case i +% would like to ensure that the internal value for \PARM{vspace} is +% fully ignored. On the other hand this may not been sensible because +% it might be difficult for the user to know how big the space should +% be.} +% +% +% \subsection{Galley structure after lists/displays}\label{sec:endlist} +% +% After lists or a math display the continuation depends on whether +% the following text logically is part of the previous material or +% starts a new paragraph. This difference is coded in the source +% document by leaving or not leaving an empty line (|\par|). +% +% Depending on this the handling of the upcoming paragraph might +% differ in \PARM{penalty}, \PARM{vspace}, \PARM{indent} (and perhaps +% others) +% +% To allow for this a processing mechanism like this should be +% investigated\footnote{There is some concept code for this below but +% it is not finished!}: +% \begin{itemize} +% \item +% The environment that intends to make use of the structure sets a flag +% \item +% The values of parameters for the case of the paragraph continuing +% the previous material are specified by modifying the DGPVs. +% \item +% The values of parameters for the case that the next paragraph is +% to be considered independent are specified in a third structure +% (called XGPV for now) which is a plist like the SGPV (or part of +% it if we don't allow to modify any odd rubbish in that case, +% which is probably sensible) +% \item +% The code for the |\par| command is augmented in a way that if it +% is executed in vertical mode the following happens: +% \begin{itemize} +% \item +% The values in the XGPV are added to the DGPV values to allow +% for user level changes to be preserved. +% \item +% The flag above is reset so that following |\par| does not +% modify the DGPV further. +% \end{itemize} +% \end{itemize} +% The XGPV has to be stored away if a new galley level is initiated! +% +% +% +% +% +% \section{The low-level command interface} +% +% The commands described in this section are used to update the galley +% data structure. Their intended use is a) in kernel code, i.e., in +% parts that are already provided by the \LaTeXplus{} kernel such as +% the basic float mechanism and b) as building blocks for higher-level +% templates such as those defined by the module \texttt{xhj} or the +% module \texttt{xinitials}. +% They are not meant to be used directly when building classes. +% +% Their names are currently very strange and inconsistent and need to +% be normalized. +% +% +% +% \subsection{Manipulating the dynamic galley parameters values} +% +% To manipulate the dynamic parameter values of the galley structure a +% number of commands are available. As explained above changing the +% dynamic parameters effects the only next paragraph (or the next sequence +% of vertical objects between paragraphs) --- afterwards the +% parameters are reset to the values stored in their static counterparts. +% +% \noindent +% \DescribeMacro{\setDGPVthing:nn}\marg{id}\marg{value} \\ +% The |\setDGPVthing:nn| command takes a parameter \meta{id} (or more +% exactly its letter or letter sequence such as `j' or `ps') and +% assigns the \meta{value} to it. No processing of the value is +% undertaken. +% +% \noindent +% \DescribeMacro{\appendtoDGPVthing:nn}\marg{id}\marg{value} \\ +% \DescribeMacro{\appendtoDGPVthing:no} +% The |\appendtoDGPVthing:nn| also leaves the \meta{value} unchanged +% but appends it to the current value of the parameter. This is, for +% example, used to build the list of whatsits nodes in the \PARM{next +% whatsits} parameter. +% +% \noindent +% \DescribeMacro{\setDGPVdimension:nn}\marg{id}\marg{value} \\ +% \DescribeMacro{\addDGPVdimension:nn} +% \DescribeMacro{\maxDGPVdimension:nn} +% In contrast the family of |\...DGPVdimension:nn| commands process the +% \meta{value} by interpreting it as a calc dimension expression. The +% result is then set (|\set...|), or added to the current value +% (|\add...|), or compared with the current value (|\max...|) and the +% maximum assigned. +% +% \noindent +% \DescribeMacro{\setGALpenalty:n}\marg{value} \\ +% \DescribeMacro{\addGALpenalty:n} +% What is available for dimensions is also available for integer +% valued parameters. However, since there is only one such parameter +% (the \PARM{penalty}) at the moment, we provide a family of commands +% which take only a \meta{value} argument. +% +% \noindent +% \DescribeMacro{\setGALobject:n}\marg{value} \\ +% \DescribeMacro{\setGALbreak:n} +% The |\setGALobject:n| and |\setGALbreak:n| are special variants of +% the |\setDGPVthing:nn| command for the \PARM{object} and +% \PARM{nobreak flag} parameters, respectively.\footnote{should +% probably vanish} +% +% \noindent +% \DescribeMacro{\setGALleftparshape:nnn}\marg{\# of normal lines} +% \marg{default width} \marg{delta offset list} \\ +% \DescribeMacro{\setGALrightparshape:nnn} +% Defines a special parshape (that is it sets the \PARM{parshape} +% taking into account its current setting with respect to the galley +% measure) at the left or the right starting with +% a number of normal lines (first arg) followed by a number of special +% lines which are constructed assuming a hole of a certain width +% (second argument). The number of lines this hole exists vertically is +% defined by the number of delta offsets in the in comma separated +% third argument. The width of each delta is added to the nominal +% width of the hole thus allowing for special corrections on a line by +% line basis. +% +% +% +% \subsection{Manipulating the static galley parameters values} +% +% Manipulating the static galley parameters essentially means changing +% the default values to which these parameters are restored to at the +% end of each paragraph. These commands always set the corresponding +% dynamic parameter as well. +% +% \noindent +% \DescribeMacro{\setSGPVthing:nn} \marg{id} \marg{value}\\ +% Like |\setDGPVthing:nn| but for long-term changes, e.g., no +% processing of \meta{value} is undertaken. +% +% \noindent +% \DescribeMacro{\setSGPVdimension:nn} \marg{id} \marg{value} \\ +% Like |\setDGPVdimension:nn| but for long-term changes, e.g., the +% \meta{value} is evaluated using calc prior to assigning it to the +% parameter. +% +% There are no commands for making long-term changes to other parts of +% the interface. Mostly because they seemed to be unnecessary. If +% needed they could be added without much problem. +% +% +% +% \subsection{Manipulating the galley measure} +% +% In the current implementation the galley measure, i.e., the width of +% text lines and their indentation from the left are not represented +% by a galley parameter directly. Instead they are internally stored +% as part of the \PARM{parshape} (see discussion above). For +% this reason that parameter can't be (or rather shouldn't be) +% modified directly but only through the commands below and commands +% like |\setGALleftparshape:nnn| which know baout those dependencies +% and handle the update accordingly. +% +% \noindent +% \DescribeMacro{\setSGPVmeasure:nn} \marg{left-margin} +% \marg{line-width} \\ +% This command make a long-term change to the measure by setting the +% width of +% the line to \meta{line-width} and the width of the left margin to +% \meta{left-margin}. In addition it sets the registers |\linewidth| +% and |\@totalleftmargin| to these values (for inspection). +% +% \noindent +% \DescribeMacro{\addSGPVmeasure:nn} +% \marg{left-margin-increment} \marg{line-width-increment}\\ +% This command make a long-term change to the measure by incrementing the +% width of of the line with \meta{line-width-increment} and the width +% of the left margin with \meta{left-margin-increment}. In addition +% it sets the registers |\linewidth| +% and |\@totalleftmargin| to the resulting values (for inspection). +% +% +% +% +% +% \subsection{Saving and restoring SGPV changes} +% +% \DescribeMacro{\GALsavegalleystate:} \\ +% \DescribeMacro{\GALrestoregalleystate:} This pair of commands stores +% and retrieves the current state of the SGPVs and can be used with +% environments that want to make long term changes and revert to the +% old settings afterwards, i.e. use |\GALsavegalleystate:| at the +% beginning, before doing any modification, and then +% |\GALrestoregalleystate:| at the end. They should be called at the +% same level of grouping (as the saving is done locally) and with the +% current implementation they can't be called several times on the +% same level.\footnote{Or so i think; which is something we may not be +% able to leave as that} +% +% +% \subsection{Manipulating the behavior of \texttt{\textbackslash par}} +% +% The |\par| command in \TeX{} is perhaps the most troublesome item of +% the language for the simple reason that it can't be sucessfully +% trapped by the macro programmer and hidden from (mis)use. +% When \TeX{} sees an empty line it converts it into the token |\par| +% and this name is fixed and can't be changed. It is easy to provide +% special definitions for the action taken when this token is +% processed but there is no way to prevent somebody from overwriting +% those carefully designed interfaces by simply doing something like +% |\let\par\foo|. If this happens anything might go wrong and since +% |\par| is a name that can't be hidden from the user nor from the +% package designer the only thing one can do is to boldly state that +% \begin{center} +% \bfseries Manual changes to |\par| are not supported! +% \end{center} +% +% Having said this we now present the interfaces that can be used to give +% |\par| a special meaning within \LaTeXplus. It should be stressed +% that |\par| always has a special meaning within the galley mechanism +% and that direct changes to it, at best lead to incorrect formatting, +% far more likely however will lead to disaster. +% +% \noindent +% \DescribeMacro{\setGALnormalpar:}\\ +% This command defines |\par| to have its standard definition within +% the galley mechanism, i.e., if a paragraph is currently processed it +% will be finished (including all code necessary, e.g., execute end of +% paragraph hooks) and preparations are undertaken to initialize the +% data structure to be ready to processes inter-paragraph material +% and/or start a new paragraph. +% +% \noindent +% \DescribeMacro{\setGALignoredpar:n} \marg{error text}\\ +% The +% |\setGALignoredpar:n| changes |\par| so that it does nothing for +% a while, outputting the \meta{error text} after 3 successive +% |\par|s.\footnote{That command should probably be replaced in favor +% of the one below as it is quite dangerous if used in horizontal +% mode (see comments in the code section, there may be no way to +% gain control!)} +% +% \noindent +% \DescribeMacro{\setGALendlistpar:} +% A special definition for |\par| at the end of list like +% structures. The code for this is currently not functional, some +% ideas regarding this can be found in section~\ref{sec:endlist} +% and in the code section. +% +% \noindent +% \DescribeMacro{\GALignorepars:n}\marg{error text} \\ +% A sort of |\ignorespaces| but for spaces and |\par|s. Should of +% course only be used as the last command in expansion (and may need +% support within |\end| handling---the latter is not done) +% +% +% \section{Open issues} +% +% In this section unresolved issues or ideas to think about and +% perhaps implement are collected. There is no particular order to +% them. +% +% \begin{itemize} +% \item +% It seems advisable to change the way galleys are set up: don't +% automatically start a new galley with each vbox but instead start +% a galley only in dedicated ``galley-boxes'' such as the internal +% form of |\parbox| etc. The advantage is much less overhead, the +% disadvantage is that non-conforming packages (written without this +% mechanism in mind) will 99\% fall over while with the current setup +% they have a good chance to survive and produce more or less proper +% formatting. +% \item +% |\@totalleftmargin| and |\linewidth| need to be adequately dealt +% with, probably by integrating them properly into the data structure +% somehow at the parshape level. +% \item +% It is quite likely that we need more granularity on the interfaces +% for storing and restoring the galley state. There need to be a +% full store and restore for cases where an unrelated galley is +% started in the middle of some other galley (such as formatting a +% marginal paragraph in the middle of the main galley) but it is not +% appropriate to store and restore the whole galley state when +% formatting a list inside a galley (what is wanted there is to +% store and restore the outer measure, the outer parshape, etc.\ but +% not any registers which deal with penalties, vertical spaces +% between paragraphs and so on. So |\GALsavegalleystate:| needs some +% companion! +% \item +% Not properly integrated into the whole scheme are math displays +% (Michael Downes will hopefully come to rescue me here at some point). +% \end{itemize} +% +% +% +% \StopEventually{} +% +% \section{Implementation} +% +% Set up certain defaults including to ignore white space +% within the body of this package. \LaTeXe{} release needs to be +% recent because of changing some bits of the |\parbox| handling below. +% \begin{macrocode} +%<*package> +\NeedsTeXFormat{LaTeX2e}[1998/12/01] +\RequirePackage{ldcsetup} +% \end{macrocode} +% +% \begin{macrocode} +\RequirePackage{xhj} % taken out of this file +% \end{macrocode} +% +% \begin{macrocode} +\IgnoreWhiteSpace +% \end{macrocode} +% +% The code does use `:' characters in command names (basically +% inherited from expl3 and property list code I took from there for +% the first proto-type implementation). Right now it is a bit of a +% nuisance since using `:' should either be integrated into +% |\IgnoreWhiteSpace| and friends or otherwise probably not be +% used. +% \begin{macrocode} +\catcode`\:=11\relax +% \end{macrocode} +% +% +% \subsection{Tracing} +% +% \begin{macro}{\tracinggalleys} +% A complicated mechanism like the galley interface needs some +% tracing facilities. Here we provide some modeled after +% \TeX's internal low-level tracing functions. +% \begin{macrocode} +\def\tracinggalleys{\afterassignment\@tracinggalleys\count@} +%<-trace>\let\@tracinggalleys\relax +% \end{macrocode} +% +% If we compile this module without tracing than |\tracinggalleys| +% will scan away an integer assignment but otherwise does +% nothing. But if we docstrip with tracing included then depending +% on the integer values the following things happen: +% \begin{description} +% \item[0] No tracing. +% \item[1] All tracing info is written to the log file only. +% \item[2] All tracing info is written to the terminal. +% \item[3 and higher] All tracing info is written to the terminal +% and before it is presented a quick check for other internal +% \TeX{}-tracing is undertaken. If it looks as if |\tracingall| +% is currently used then various tracings are temporarily disable +% to avoid getting the output of the tracing being traced as +% well. This prevents getting many many uninteresting output +% lines which would otherwise appear. +% +% This value can only be used if e\TeX{} in extended mode is used +% as the formatter, as it sets |\tracingassigns|\footnote{Really +% useful that primitive, try it one day if you got stuck while +% macro writing, that alone is worth using e\TeX{} for.} which is +% not a primitive of \TeX. +% \end{description} +% +% \begin{macrocode} +%<*trace> +\def\@tracinggalleys{ + \ifcase \count@ + \let\GAL@typeout\@gobble +% \end{macrocode} +% +% We can't let |\Gal@typout| simply to |\wlog| if we don't want to see +% tracing on the screen since that does expand its argument and +% produces havoc in some cases, so here is a slightly slower variant. +% \begin{macrocode} + \or + \def\GAL@typeout ##1{ + \begingroup + \let\protect\@unexpandable@protect + \wlog {##1} + \endgroup + } +% \end{macrocode} +% If |\tracinggalleys| is set to 2 we show a lot of tracing data. +% \begin{macrocode} + \or + \let\GAL@typeout\typeout +% \end{macrocode} +% And another variant when lowlevel tracing is called for. This +% version does assume that e\TeX{} is being used as it tries to set +% |\tracingassigns|, so it will fail if this assumption is incorrect. +% \begin{macrocode} + \else + \def\GAL@typeout ##1{ + \ifnum\tracingmacros>\z@ + \begingroup + \tracingassigns\z@ + \tracingcommands\z@ + \tracingrestores\z@ + \tracingmacros\z@ + \typeout{##1} + \endgroup + \else + \typeout{##1} + \fi + } + \fi +} +%</trace> +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\GAL@typeout} +% This macro is used below to display some tracing info. By default +% no tracing happens. +% \begin{macrocode} +\let\GAL@typeout\@gobble +% \end{macrocode} +% \end{macro} +% +% +% +% \subsection{Taking away primitives from direct use} +% +% To make this mechanism work we have to shield the primitive \TeX{} +% parameters from direct access by the user or a package writer. We do +% this by giving them internal names of the type +% |\GAL@@|\meta{param-name} and the allocating under the original +% parameter name a suitable register to trap any direct access. +% +% We have to trap |\clubpenalty| and |\interlinepenalty|; both are used +% to prohibit page breaking in paragraphs. +% \begin{macrocode} +\let\GAL@@clubpenalty\clubpenalty +\newcount\clubpenalty +\let\GAL@@interlinepenalty\interlinepenalty +\newcount\interlinepenalty +% \end{macrocode} +% +% See comments below why this is not needed. +% \begin{macrocode} +%\let\GAL@@brokenpenalty\brokenpenalty +%\newcount\brokenpenalty +% \end{macrocode} +% +% And of course we have to trap |\everypar| since this token register +% is one of the central bits of the algorithm. It is used to gain +% control at the start of a new paragraph and actually put the stored +% galley data structure for inter-paragraph material onto the page. +% \begin{macrocode} +\let\GAL@@everypar\everypar +\newtoks\everypar +% \end{macrocode} +% +% Not sure if we really need to trap |\parindent|, anyway here it is: +% \begin{macrocode} +\let\GAL@@parindent\parindent \GAL@@parindent\z@ +\newdimen\parindent +% \end{macrocode} +% +% The |\parskip| parameter is a real nuisance, we really do not want +% it at all as we handle our inter-paragraph spaces ourself. However, +% we can't get rid of it, best we can do is to make it always zero. +% +% Setting the then alocated |\parskip| register will not have any +% effect at all.\footnote{Perhaps it should: i.e., at least produce a +% warning or error message.} +% \begin{macrocode} +\let\GAL@@parskip\parskip \GAL@@parskip\z@ +\newskip\parskip +% \end{macrocode} +% +% The next block is trapping those parameters which are responsible +% for the justification, ie +% \begin{macrocode} +\let\GAL@@leftskip\leftskip +\newskip\leftskip +\let\GAL@@rightskip\rightskip +\newskip\rightskip +\let\GAL@@parfillskip\parfillskip +\newskip\parfillskip \parfillskip\@flushglue +% \end{macrocode} +% +% And while we are at it, we might as well allocate two additional +% skips which are related to justification: |\GAL@@startskip| the +% counterpart to |\GAL@@parfillskip| at the beginning of the paragraph +% and |\GAL@@linefillskip| which will hold the space to be inserted +% before a forced newline (as in |\\|). +% \begin{macrocode} +\newskip\GAL@@startskip +\newskip\GAL@@linefillskip +% \end{macrocode} +% +% |\spaceskip| and |\xspaceskip| are needed when doing proper ragged +% settings so they are part of the interface. +% \begin{macrocode} +\let\GAL@@spaceskip\spaceskip +\newskip\spaceskip +\let\GAL@@xspaceskip\xspaceskip +\newskip\xspaceskip +% \end{macrocode} +% +% The next is not yet (but perhaps it should be as well). +% \begin{macrocode} +\let\GAL@@lineskip\lineskip +\newskip\lineskip +% \end{macrocode} +% +% +% +% \subsection{Some extra scratch registers} +% +% Those registers are needed by the mutator functions and we better +% not rely on general scratch registers (at least not for the +% moment). The box register is for the indentation box. +% \begin{macrocode} +\newcount\GAL@cnta +% \end{macrocode} +% +% \begin{macrocode} +\newskip\GAL@skipa +\newskip\GAL@skipb +% \end{macrocode} +% +% \begin{macrocode} +\newbox\GAL@boxa +% \end{macrocode} +% +% +% +% \subsection{Galley data structure}\label{sec:galley-concept-impl} +% +% \subsubsection{Original concepts} +% +% In earlier implementations of \texttt{galley2.dtx}, galley objects +% have been represented in the following fashion: +% +% \begin{itemize} +% \item the long range values are stored in a within one level in +% global a plist with the name |\GAL@static@hmode@plist| which is a +% property list keeping all individual galley values for hmode. The +% keys in the property list are of the form +% |\GAL@|\meta{letter(s)}|@|. +% \item a copy of this plist is saved away under the name +% |\GAL@static@hmode@|\meta{level-num}|@plist| just before we start +% a new level so that when returning to a level the previous state can +% be reconstructed.\footnote{Instead of doing a global save under a +% name associated with the level number we could probably simply +% save the list locally and use the savestack since each new level +% has to be always associated with a new group anyway!} +% \item the keys in the above plists are also used directly as global +% variables holding the actual current values of the galley object +% parameters which allows fast access. +% \item similar plists exists for vmode and perhaps we want even +% more\footnote{but perhaps not, putting the parameters in different +% plists is mainly a speed thing, we can use flags to reinit only +% things that have changed; the lists are shorter which makes +% property handling faster, etc, but it needs some careful studying +% at a later stage whether this is really beneficial---in principle +% there is no problem with keeping all parameters in a single plist.} +% \end{itemize} +% This means that to make a long-term change to some galley object +% parameter one has to change the property within the +% |\GAL@static@|\meta{h/v}|mode@plist|. Such a change is then +% propagated to both the saved version as well as the global key +% commands. +% +% \subsubsection{Current concepts} +% +% After some evaluation I decided to change this setup in favour of +% the following: +% +% \begin{itemize} +% \item Actual values are represented by global control sequences of +% the form |\GAL@|\meta{letter(s)}|@|. +% \item If they are supposed to be reset after each usage their +% long-term (static) value is recorded globally in +% |\GAL@|\meta{letter(s)}|@s|. +% \item When starting a new galley level saved versions of the +% dynamic parameters are stored locally in |\GAL@|\meta{letter(s)}|@l| +% and those for the static parameters are stored in +% |\GAL@|\meta{letter(s)}|@sl|. When the level is popped those values +% are used to restore the state of the parameters. A consequence of +% this setup is that starting a new galley state should always involve +% a new group level! +% \end{itemize} +% This means that to make a long-term change to some galley object +% parameter one has to change the the |\GAL@|\meta{letter(s)}|@s| +% parameter (if it exists) as well as the |\GAL@|\meta{letter(s)}|@| +% one. +% +% If a new parameter is added to this setup we have to modify the +% following functions below: |\GAL@init@static|, +% |\GAL@save@galleystate|, \\ +% |\GAL@restore@galleystate|, and +% |\GAL@init@dynamic@fully|. +% +% \begin{macro}{\GAL@init@static} +% The |\GAL@init@static| function initialises the static and dynamic +% parameters with fixed defaults. This is, for example, used when +% starting a new level. At a later state one probably want to be able +% to globally set even those defaults for a whole document, but for +% now this is probably okay. +% +% \begin{macrocode} +\def\GAL@init@static { + \gdef\GAL@b@s {\z@} + \gdef\GAL@p@s {\z@} + \gdef\GAL@v@s {-1sp} + \gdef\GAL@uv@s {\z@} + \gdef\GAL@up@s {} + \gdef\GAL@pw@s {} + \gdef\GAL@j@s {\z@\leftskip\rightskip\parfillskip + \spaceskip\xspaceskip\parfillskip\parindent} + \gdef\GAL@o@s {} + \gdef\GAL@ps@s {} + \gdef\GAL@i@s {\z@} + \gdef\GAL@nw@s {} + \gdef\GAL@q@s {} +% \end{macrocode} +% +% The definition of |\par| is kind of static.\footnote{Do we need +% to set the internal version of \texttt{\textbackslash everypar} +% as well?} +% \begin{macrocode} + \setGALnormalpar: +% \end{macrocode} +% +% Having the static parameter updated we have to initialise the +% dynamic ones as well. +% \begin{macrocode} + \GAL@init@dynamic@fully +% \end{macrocode} +% The seldom used parameters for linebreaking and +% hyphenation are not subject to the galley concept but are set for +% the whole galley. For this reason the code below should be moved +% outside this macro. +% +% We interface to a default template instance so that the default +% can be easily overwritten on the class level.\footnote{bad idea? +% good idea?} +% \begin{macrocode} + \UseInstance{hj}{default} +%% alternative +%% \UseInstance{hyphenation}{default} +%% \UseInstance{linebreak}{default} +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\GALsavegalleystate:} +% The |\GALsavegalleystate:| function saves away a copy of the current +% static plists in a way that it can be retrieved when returning to +% the current level. In the new implementation this means locally +% saviing all the dynamic parameters to their local counterparts +% (i.e., |\GAL@|\meta{letter}|@| to |\GAL@|\meta{letter}|@|l) and the +% same for the static parameters. +% \begin{macrocode} +\def\GALsavegalleystate: { + \let\GAL@b@l \GAL@b@ + \let\GAL@p@l \GAL@p@ + \let\GAL@v@l \GAL@v@ + \let\GAL@uv@l \GAL@uv@ + \let\GAL@up@l \GAL@up@ + \let\GAL@pw@l \GAL@pw@ + \let\GAL@j@l \GAL@j@ + \let\GAL@o@l \GAL@o@ + \let\GAL@ps@l \GAL@ps@ + \let\GAL@i@l \GAL@i@ + \let\GAL@nw@l \GAL@nw@ + \let\GAL@q@l \GAL@q@ +% + \let\GAL@b@sl \GAL@b@s + \let\GAL@p@sl \GAL@p@s + \let\GAL@v@sl \GAL@v@s + \let\GAL@uv@sl \GAL@uv@s + \let\GAL@up@sl \GAL@up@s + \let\GAL@pw@sl \GAL@pw@s + \let\GAL@j@sl \GAL@j@s + \let\GAL@o@sl \GAL@o@s + \let\GAL@ps@sl \GAL@ps@s + \let\GAL@i@sl \GAL@i@s + \let\GAL@nw@sl \GAL@nw@s + \let\GAL@q@sl \GAL@q@s +% \end{macrocode} +% The current definition of |\par| is handled manually (really +% manually)\footnote{Now this is pretty dangerous but i'm not sure +% this can be avoided: if \texttt{\textbackslash par} is being +% manually changed outside the control of these macros we might end up +% in deep shit. For example the old definition of tabular does this +% and the result is pretty bad, ie endless loop with +% \texttt{\textbackslash par} being a noop. any ideas?} +% \begin{macrocode} + \let\saved@GAL@par\par +% \end{macrocode} +% We also have to track the state of the |\GAL@reassign@list|: +% \begin{macrocode} + \let\saved@GAL@reassign@list\GAL@reassign@list +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\GALrestoregalleystate:} +% And here we have the reverse operation which is needed when we +% return to a previous level. +% \begin{macrocode} +\def\GALrestoregalleystate: { + \global\let\GAL@b@ \GAL@b@l + \global\let\GAL@p@ \GAL@p@l + \global\let\GAL@v@ \GAL@v@l + \global\let\GAL@uv@ \GAL@uv@l + \global\let\GAL@up@ \GAL@up@l + \global\let\GAL@pw@ \GAL@pw@l + \global\let\GAL@j@ \GAL@j@l + \global\let\GAL@o@ \GAL@o@l + \global\let\GAL@ps@ \GAL@ps@l + \global\let\GAL@i@ \GAL@i@l + \global\let\GAL@nw@ \GAL@nw@l + \global\let\GAL@q@ \GAL@q@l +% + \global\let\GAL@b@s \GAL@b@sl + \global\let\GAL@p@s \GAL@p@sl + \global\let\GAL@v@s \GAL@v@sl + \global\let\GAL@uv@s \GAL@uv@sl + \global\let\GAL@up@s \GAL@up@sl + \global\let\GAL@pw@s \GAL@pw@sl + \global\let\GAL@j@s \GAL@j@sl + \global\let\GAL@o@s \GAL@o@sl + \global\let\GAL@ps@s \GAL@ps@sl + \global\let\GAL@i@s \GAL@i@sl + \global\let\GAL@nw@s \GAL@nw@sl + \global\let\GAL@q@s \GAL@q@sl +% \end{macrocode} +% \begin{macrocode} + \global\let\par\saved@GAL@par + \global\let\GAL@reassign@list\saved@GAL@reassign@list +% \end{macrocode} +% As long as we to not set up the individual paragraph shape +% parameters each time (see comments in +% |\GAL@set@horizontal@objects|) we have to restore them at this +% point as well. +% \begin{macrocode} + \expandafter \setup@paragraph@justification \GAL@j@ +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\saved@GAL@par} +% Recover from confusion: the top-level definition of |\saved@GAL@par| +% should never get assigned to |\par| but in case it is (by getting +% the grouping wrong) we better try to recover +% gracefully\footnote{Gracefully meaning I haven't bothered with +% producing anything other than an undefined csname error :-)}, so +% instead of ending up with a |\par| being an undefined command we do +% the following: +% \begin{macrocode} +\def\saved@GAL@par{\ERROR\GAL@normal@par} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\GAL@init@dynamic@as@necessary} +% Whenever parameters got changed for one paragraph the +% |\GAL@reassign@list| gets extended with an assignment that resets +% the parameter back to its static value. The +% |\GAL@init@dynamic@as@necessary| then executes this list and afterwards +% define it to be empty. +% \begin{macrocode} +\def\GAL@init@dynamic@as@necessary { +%<*trace> + \GAL@typeout{Reinit~ parameters \on@line} + \GAL@typeout{\@spaces \meaning \GAL@reassign@list} +%</trace> + \GAL@reassign@list + \global\let\GAL@reassign@list\@empty +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\GAL@init@dynamic@fully} +% Sometimes we want to ensure that all parameter are set to their +% static values. This is done by the |\GAL@init@dynamic@fully| macro.. +% \begin{macrocode} +\def\GAL@init@dynamic@fully { +%<*trace> + \GAL@typeout{Reinit~ parameters \on@line} +%</trace> + \global\let\GAL@b@ \GAL@b@s + \global\let\GAL@p@ \GAL@p@s + \global\let\GAL@v@ \GAL@v@s + \global\let\GAL@uv@ \GAL@uv@s + \global\let\GAL@up@ \GAL@up@s + \global\let\GAL@pw@ \GAL@pw@s + \global\let\GAL@j@ \GAL@j@s + \global\let\GAL@o@ \GAL@o@s + \global\let\GAL@ps@ \GAL@ps@s + \global\let\GAL@i@ \GAL@i@s + \global\let\GAL@nw@ \GAL@nw@s + \global\let\GAL@q@ \GAL@q@s +% \end{macrocode} +% And since everything is as the static value there is nothing for +% us to reassign so be make this list empty. +% \begin{macrocode} + \global\let\GAL@reassign@list\@empty +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\GAL@reassign@list} +% The |\GAL@reassign@list| holds the parameters that need to be +% reset at the next paragraph or more exactly it holds the +% assignments that do the resetting. So by default this is empty. +% \begin{macrocode} +\let\GAL@reassign@list\@empty +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\GAL@prepare@reassign:NN} +% The |\GAL@prepare@reassign:NN| macro receives the internal names +% of dynamic and and static placeholder for a parameter and extends +% the |\GAL@reassign@list|. +% \begin{macrocode} +\def\GAL@prepare@reassign:NN #1#2{ +% \end{macrocode} +% It might pay off to make a quick check whether or not the value +% of the dynamic parameter really differs from those of the static +% one. If not we can avoid updating the |\GAL@reassign@list| which +% takes some time and further more makes later updates of this list +% slower.\footnote{This needs some empirical testing: if most +% of the time this test results in false then it might be better to +% remove it though. One such test indicated that removal might be +% better but this isn't far from being conclusive.} +% \begin{macrocode} + \ifx#1#2 + \else + \appendtoDGPV@internal:Nn\GAL@reassign@list + {\global \let #1 #2 } + \fi +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\GAL@prepare@reassign:n} +% In contrast |\GAL@prepare@reassign:n| takes only the id for a +% parameter, such as |v| or |up|. It also has some extra code to +% check if the parameter is actually one that has both dynamic and +% static incarnations.\footnote{In the current implementation this +% is probably always the case but if we re-add \texttt{m} and +% \texttt{h} we may not want to reset them on every paragraph but +% handle them always as static for the whole galley.} If not we +% don't need to reassign.\footnote{Furthermore, for speed +% consideration it might be advisable to internally always replaces +% the call to this command by \texttt{GAL@prepare@reassign:NN} +% since this will always saves at least one extra csname parsing.} +% \begin{macrocode} +\def\GAL@prepare@reassign:n #1{ + \expandafter\ifx \csname GAL@#1@s\endcsname \relax +%<*trace> + \GAL@typeout{Not~ reassigning~ for~ #1!} +%</trace> + \else + \expandafter + \GAL@prepare@reassign:NN + \csname GAL@#1@ \expandafter \endcsname + \csname GAL@#1@s \endcsname + \fi +} +% \end{macrocode} +% \end{macro} +% +% +% +% +% +% \subsubsection{Starting and ending a level} +% +% The |\GAL@start@level| command first saves away the current state +% and then starts a new group. This group (|\bgroup|) will be matched +% by the closing brace of the current ``vbox'' either the explicit |}| +% or an |\egroup| equivalent of that. The |\GAL@cleanup@level| which +% then gets into control is supposed to restore the state and finally +% issue and |\egroup| which will then actually end the box. +% +% \begin{macro}{\GAL@start@level} +% \begin{macrocode} +\def\GAL@start@level{ + \GALsavegalleystate: + \bgroup +%<*trace> + \advance\GAL@level@num\@ne + \GAL@typeout{Entering~ galley~ level:~ + \the\GAL@level@num~ \on@line} +%</trace> + \GAL@init@static + \@GAL@if@first@on@leveltrue % temp solution! + % see below + \aftergroup\GAL@cleanup@level} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\GAL@level@num} +% The counter is really only necessary if tracing is compiled in, +% however we define it always just to ensure that the allocation +% doesn't change if tracing is added. +% \begin{macrocode} +\newcount\GAL@level@num +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\if@GAL@if@first@on@level} +% This belongs to some hack which needs some better +% implementation. It signals that we are at the beginning of a galley. +% \begin{macrocode} +\newif\if@GAL@if@first@on@level +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\GAL@cleanup@level} +% \begin{macrocode} +\def\GAL@cleanup@level{ + \par + \GAL@finish@typesetting +%<*trace> + \GAL@typeout{Returning~ to~ galley~ level:~ \the\GAL@level@num~ \on@line} +%</trace> + \GALrestoregalleystate: + \egroup +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\GAL@finish@typesetting} +% At the end of a galley (if in vmode) we have to ensure that we +% don't have any dangling bits in the data structure (like +% untypeset specials or writes that want to make their appearance +% at the beginning of the next paragraph. This is what +% |\GAL@finish@typesetting| is supposed to take care +% of\footnote{one day}. +% \begin{macrocode} +\def\GAL@finish@typesetting {} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\everyvbox} +% We start a new galley with every vbox. +% \begin{macrocode} +\everyvbox{\GAL@start@level} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\insert} +% Interestingly enough |\everyvbox| is not triggered by |\inserts| +% even though those are also vboxes so we have to do it manually +% here (and that is a bit of a pain~\ldots). +% \begin{macrocode} +\let\@@insert\insert +% \end{macrocode} +% There are cases where after the |\insert| we have stuff like +% |\csname ...\endcsname| and to ensure that we don't fall over in +% that case our redefinition has to be a bit elaborate. Of course +% all this is only of interest if we stay with the current +% implementation of always automatically starting a galley. +% \begin{macrocode} +\long\def\insert #1#{\@insert{#1}} +\long\def\@insert #1#2{\@@insert#1{\GAL@start@level#2\par}} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\GAL@ignore@next@galley} +% \begin{macro}{\GAL@ignore@next@galley@vbox} +% We may not need the next two commands at all if we change from +% setting up a galley everywhere to setting up galleys only for +% ``minipage'' like vboxes. And i think we should! +% \begin{macrocode} +\def\GAL@ignore@next@galley{ + \everyvbox{\global\everyvbox{\GAL@start@level}} +} +\def\GAL@ignore@next@galley@vbox{ + \everyvbox{\global\everyvbox{\GAL@start@level}}\vbox +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% \subsubsection{Using the galley data structure} +% +% \begin{macro}{\GAL@show@datastructure} +% Some tracing to show the state of the data structure. +% As some internal params take arbitrary content we have to be a bit careful +% displaying them. Needs (some:-) improvement to be useful. +% \begin{macrocode} +%<*trace> +\def \GAL@show@datastructure #1{ + \GAL@typeout{#1^^J + \@spaces nominal~ width~ =~ \the\hsize ^^J + \@spaces left~ indentation~ =~ \the\@totalleftmargin ^^J + \@spaces break~ switch~ (b)~ =~ \GAL@b@ \space (\GAL@b@s) ^^J + \@spaces v-penalty~ (p)~ =~ \GAL@p@ \space (\GAL@p@s) ^^J + \@spaces v-space~ (v)~ =~ \GAL@v@ \space (\GAL@v@s) ^^J + \@spaces user~ v-penalty~ (up)~ =~ \GAL@up@ ^^J + \@spaces user~v-space~ (uv)~ =~ \GAL@uv@ ^^J + \@spaces prev-whatits~ (pw)~ =~ \meaning \GAL@pw@ ^^J + \@spaces next-whatits~ (nw)~ =~ \meaning \GAL@nw@ ^^J + \@spaces parshape~spec~ (ps)~ =~ \GAL@ps@ \space (\GAL@ps@s) ^^J + \@spaces queries~ (q)~ =~ \meaning \GAL@q@ ^^J + \@spaces indent~ flag~ (i)~ =~ \GAL@i@ \space (\GAL@i@s) ^^J + \@spaces para~ object~ (o)~ =~ \meaning \GAL@o@ ^^J + \@spaces para~ justification~ (j)~ =~ \meaning \GAL@j@ } +} +%</trace> +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\GAL@use@on@para} +% The next function is called when \TeX{} switches to horizontal mode, +% i.e., at the start of a paragraph. +% +% \begin{macrocode} +\def\GAL@use@on@para{ +%<*trace> + \GAL@show@datastructure{Para~ start~ for~ galley~ + level~ \the\GAL@level@num \on@line} +%</trace> +% \end{macrocode} +% At the start of a new galley we do not want to have any vertical +% space being inserted not even a zero |\parskip| since that would +% mess up use of |\vtop| etc. The below is a sort of crude fix for +% the problem ie this is the old minipage switch. +% +% What about a redesign??? +% \begin{macrocode} + \if@GAL@if@first@on@level + \GAL@handle@first@para + \else +% \end{macrocode} +% +% +% We want to return to vmode without leaving too much trace. so we +% remove the indentation box and call |\endgraf|. All this is done +% in a group to keep an already setup |\parshape|, eg in a list. In +% fact we might want to have this parshape setting as part of the +% galley-objects but this is not done so far.\footnote{There is a +% problem with code like this which was the result of a pr in +% \LaTeXe. If the start of a paragraph is triggered by certain very +% special commands (such as encoding-specific accents that involve +% grouping) we might have the case that such a command already +% started a group and then triggers the paragraph mechanism which +% in turn triggers this macro. That may result in those groups to +% overlap in a bad way---needs some clear instruction perhaps +% \texttt{\textbackslash leavevmode} in all potential cases.} +% \begin{macrocode} + \begingroup + \global\setbox\GAL@boxa\lastbox + \endgraf + \GAL@set@vertical@objects +% \end{macrocode} +% Before reentering h-mode we better clear the everypar register or +% we end up in a loop: +% \begin{macrocode} + \GAL@@everypar{} + \noindent + \endgroup + \fi +% \end{macrocode} +% Instead of setting up the measure each time one could probably +% move this to the template setting things up (or not?) +% \begin{macrocode} + \GAL@set@measure + \GAL@set@horizontal@objects +% \end{macrocode} +% At this point during the processing the parameters are all +% reinitialised, i.e., anything not yet used will be +% lost!\footnote{This is important if you think about paragraph +% ending stuff which is not yet implemented} +% \begin{macrocode} + \GAL@init@dynamic@as@necessary +} +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\GAL@handle@first@para} +% Since this part of the code from above is not used that often it was +% placed into a separate command (for faster skipping). +% +% What needs to be done always? +% \begin{macrocode} +\def\GAL@handle@first@para { + \@GAL@if@first@on@levelfalse + \GAL@pw@ +% \end{macrocode} +% \begin{macrocode} + \@tempskipa \GAL@uv@ \relax + \ifdim \@tempskipa =\z@ \else +% \end{macrocode} +% \begin{macrocode} + \ifhmode + \begingroup + \global\setbox\GAL@boxa\lastbox + \endgraf + \vskip \@tempskipa + \GAL@@everypar{} + \noindent + \endgroup + \else + \vskip \@tempskipa + \fi + \fi +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\GAL@use@on@vobject} +% The other case where (part of) the galley data structure is going to +% be used is the case when we are already in vertical mode but want to +% append some vertical mode material (e.g., a rule, an inline float) +% or start some environment that likes to look like a paragraph even +% though it doesn't actually uses \TeX's low-level mechanisms (e.g., +% longtable?, tabbing, \ldots). +% \begin{macrocode} +\def\GAL@use@on@vobject{ +%<*trace> + \GAL@show@datastructure{V-object~ for~ galley~ + level~ \the\GAL@level@num \on@line} +%</trace> + \if@GAL@if@first@on@level + \GAL@handle@first@para + \else + \GAL@set@vertical@objects + \fi + \GAL@init@dynamic@as@necessary +} +% \end{macrocode} +% The use of this command should be followed by a |\nobreak| after the +% v-object or else we introduce an unwanted breakpoint due to the next +% |\parskip| being inserted. +% +% \end{macro} +% +% +% \begin{macro}{\GAL@set@vertical@objects} +% When setting the vertical components of the galley structure the +% following happens: +% \begin{itemize} +% \item First any whatsits for the previous para are +% inserted\footnote{A nobreak is probably not necessary at this +% point as the +% parskip should by now already be inserted so that the next +% thing happening is an explicit penalty anyway.} +% \item +% If a document user command for penalties as been used (i.e., when +% \PARM{user penalty} is none-empty) it take precidence and the internal +% penalty value is ignored. +% \item +% Otherwise the \PARM{break switch} is checked. If this greater +% zero a nobreak penalty is issued and \PARM{penalty} is ignored. +% \item +% Otherwise the \PARM{penalty} value is used. +% \end{itemize} +% +% \begin{macrocode} +\def \GAL@set@vertical@objects { + \GAL@pw@ + \penalty + \ifx \GAL@up@ \@empty + \ifnum \GAL@b@ > \z@ + \@M + \else + \GAL@p@ \relax + \fi + \else + \GAL@up@ \relax + \fi +% \end{macrocode} +% A user skip as supplied by |\vspace| etc.\ is going into a +% separate register to ensure that it will always have the effect +% of adding extra space independent of what surrounding +% environments do. +% +% The |\parskip| below is not the \TeX{} primitive (which is always +% zero) but a user level register which is only applied at this +% point if ever. +% \begin{macrocode} + \GAL@skipa \GAL@v@ \relax + \vskip \ifdim +% \end{macrocode} +% |\parskip| gets applied if we are between two paragraphs without +% any further space requests; this is signalled by |\GAL@v@| having +% a value of |-1sp| (its default). Of course it is in theory +% possible that this value is the result to modification of +% |\GAL@v@| but allowing for this saves us an extra flag or +% register that would otherwise be needed and checked every time. +% \begin{macrocode} + \GAL@skipa = -1sp \parskip +%<*trace> + \GAL@typeout{\parskip=\the\parskip\space applied} +%</trace> + \else + \GAL@skipa + \fi + \vskip \GAL@uv@ \relax +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\GAL@set@measure} +% Some comments on the next macro: +% not sure: do we better set parshape global? (can we?); of course it +% could and perhaps should be run inline, also we might instead add +% |\parshape| to the required content of |\GAL@ps@| so that we avoid +% the test and simply execute it always. +% +% \begin{macrocode} +\def \GAL@set@measure { + \parshape + \ifx\GAL@ps@\@empty + \z@ + \else + \GAL@ps@ + \fi +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\GAL@set@horizontal@objects} +% Once we are back in hmode we first output any waiting whatsits, then +% run any query setups, then +% look at the saved indentation box: if it is void we know that we had +% a paragraph started with \noindent otherwise we typeset some +% indentation then the galley object and finally a horizontal skip +% (might also want a break penalty there or even more stuff). +% +% \begin{macrocode} +\def \GAL@set@horizontal@objects { + \GAL@nw@ + \GAL@q@ +% \end{macrocode} +% The shape is now a multi-valued parameter so we pass it expanded +% and let |\setup@paragraph@justification| do the assignments if necessary. +% +% As a speedup measure we are comparing |\GAL@j@| to the saved +% version |\GAL@j@s|, if they are identical we assume that all +% components of the multi-valued parameter are already properly set +% up. This saves doing 8 assignments at every paragraph. The catch +% is, that a change to the static parameter (via |\setSGPVthing:nn| +% |s|) needs to be manually followed by running +% |\setup@paragraph@justification| (see definition of +% \texttt{justification} template).\footnote{Actually, +% that shortcut does not work correctly! Needs thought! So commented out for the +% moment!} +% \begin{macrocode} +% \ifx \GAL@j@ \GAL@j@s % what is the right test to suppress? +% \GAL@typeout{Not~ setting~ up~ paragraph~ shape} +% \else + \expandafter \setup@paragraph@justification \GAL@j@ +% \fi + \ifnum \GAL@i@ = \z@ + \ifvoid\GAL@boxa \else \hb@xt@ \GAL@@parindent{} \fi + \fi + \GAL@o@ \relax + \hskip \GAL@@startskip \relax + \setup@page@breaking@penalties \GAL@b@ +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\setup@page@breaking@penalties} +% The way the following code is written (at the moment) +% |\clubpenalty|, |\interlinepenalty|, and |\brokenpenalty| are still +% available as user level registers so that setting up, say, the +% broken penalty default for the whole document is done via setting +% that particular register. +% +% Another observation is that we most likely do not have to set +% |\GAL@@brokenpenalty| at all (and if |\GAL@@interlinepenalty| is +% set to `nobreak' we can also leave |\GAL@@clubpenalty| alone) +% since if i read it right these penalties are additive so one +% large one should be sufficient. +% +% \begin{macrocode} +\def \setup@page@breaking@penalties #1{ + \GAL@@clubpenalty \clubpenalty + \GAL@@interlinepenalty \interlinepenalty +% \GAL@@brokenpenalty \brokenpenalty + \ifcase #1 +% 0 + \or +% 1 + \or +%2 + \GAL@@clubpenalty \@M +% \GAL@@brokenpenalty \@M + \or +%3 + \GAL@@interlinepenalty \@M +% \GAL@@brokenpenalty \@M + \else +% assume negative: this loops if called with a value greater than 3! so +% probably can't stay this way. + \setup@page@breaking@penalties {-#1} + \fi +} +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\setup@paragraph@justification} +% Setting up the inner paragraph shape, e.g., the justification is +% done by breaking up the multi-value parameter |s| into its 8 +% components.\footnote{Do one has to make those settings global? Check!} +% \begin{macrocode} +\def \setup@paragraph@justification #1 #2 #3 #4 #5 #6 #7 #8{ + \global \GAL@@startskip #1 \relax + \global \GAL@@leftskip #2 \relax + \global \GAL@@rightskip #3 \relax + \global \GAL@@parfillskip #4 \relax + \global \GAL@@spaceskip #5 \relax + \global \GAL@@xspaceskip #6 \relax + \global \GAL@@linefillskip#7 \relax + \global \GAL@@parindent #8 \relax +} +% \end{macrocode} +% \end{macro} +% +% +% \subsection{Handling of \texttt{\textbackslash par}} +% +% Depending on the state of the machinery |\par| might a get different +% definition. +% +% \begin{macro}{\GAL@normal@par} +% In most cases |\par| will be |\let| to |\GAL@normal@par|. +% \begin{macrocode} +\def \GAL@normal@par { + \begingroup + \ifvmode + \endgraf + \else %% For error-trapping needs + %% \ifinner \ifhmode etc cases +% \end{macrocode} +% At this point we might want to add and end par hook (not done); +% if we are not adding one then this definition can be optimised a lot +% (moving |\endgraf| up and using |\ifhmode| instead of the above. +% \begin{macrocode} + \endgraf + %%%% NOTE: this puts us into vmode with the para on the galley + %%%% AND rignt here we have stuff that has migrated + %%%% (eg vadjust stuff) from the last line!!! + \nobreak + \fi + \endgroup +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\@@par} +% \LaTeX's saved version of the original |\par| primitive now needs +% actually run |\GAL@normal@par| to trick \LaTeX{} into accepting +% this redefinition. This is needed at least as long as if we run +% with a mixture of old and new code. +% \begin{macrocode} +\let\@@par\GAL@normal@par +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\GAL@endlist@par} +% +% Another potential definition of |\par| comes into play when we +% are at the end of a list environment and want to take different +% actions depending on getting a continution of the paragraph or a +% real end. This code is not functional! +% +% ATTENTION: most likely either have to set those locally or have +% to save the state of |\par| as well! And anyway it is not +% finished code yet!!!! +% +% \begin{macrocode} +%<*unfinished> +\def \GAL@endlist@par { + \begingroup + \ifvmode + \addDGPVdimension:nn v \GAL@v@X + \addDGPVdimension:nn i \GAL@i@X + \addGALpenalty:n \GAL@p@X + \setGALnormalpar: + \else + \endgraf + \nobreak + \fi + \endgroup +} +%</unfinished> +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\setGALnormalpar:} +% The |\setGALnormalpar:| states that we are in normal operation. +% \begin{macrocode} +\def\setGALnormalpar:{ + \global\let\par\GAL@normal@par +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\setGALendlistpar:} +% The |\setGALendlistpar:| states that we want to handle the end +% of list case. +% \begin{macrocode} +%<*unfinished> +\def\setGALendlistpar:{ + \global\let\par\GAL@endlist@par +} +%</unfinished> +% \end{macrocode} +% \end{macro} +% +% +% For ignoring |\par| commands we currently have two functions. +% +% \begin{macro}{\setGALignoredpar:n} +% The |\setGALignoredpar:n| command disables |\par| altogether and +% hopes that the beginning of another paragraph shows up soon +% (three |\par|s are allowed). If not it issues an error message +% (arg 1) and redefines |\par| to be |\GAL@normal@par|. +% \begin{macrocode} +\def \setGALignoredpar:n #1 { + \ifvmode + \global \par@deathcycles \z@ + \global\let\par\GAL@ignored@par + \gdef\GAL@ignored@par@error{#1} + \appendtoDGPVthing:nn q \setGALnormalpar: +% \end{macrocode} +% Not sure what should be done if this gets executed in hmode: a) +% ignore the request b) output an error message c) run it and with +% it have the rest of the document being typeset into a single +% paragraph :-)? Since c) isn't really an option we have to take +% some precaution, for the moment i have added an error but perhaps +% this should be restricted to appear really only in hmode as an +% error not in a |\write|, say, so maybe the test should be for +% hmode --- or perhaps the whole commands should be removed in +% favour of the one below. +% \begin{macrocode} + \else + \ERROR \setGALnormalpar: \par + \fi +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\GAL@ignored@par} +% Helper function for |\setGALignoredpar:n|. +% \begin{macrocode} +\def\GAL@ignored@par{ + \global \advance\par@deathcycles \@ne + \ifnum \par@deathcycles > \thr@@ + \PackageError{galley2}\GAL@ignored@par@error\@ehd + \setGALnormalpar: + \par + \fi +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\GALignorepars:n} +% An alternative is to explicitly look out for |\par| and spaces +% (the point being that this immediately set the definition of +% |\par| back to its normal value if anything else is encountered). +% Again up to three |\par|s are accepted otherwise we get an error +% message. +% \begin{macrocode} +\def \GALignorepars:n #1 { + \global \par@deathcycles \z@ + \global\let\par\GAL@ignore@next@pars + \gdef\GAL@ignored@par@error{#1} + \GAL@ignore@next@pars +} +% \end{macrocode} +% \end{macro} +% +% +% +% +% \begin{macro}{\GAL@ignore@next@pars} +% And here is a helper for |\GALignorepars:n|. +% \begin{macrocode} +\def\GAL@ignore@next@pars { + \global \advance\par@deathcycles \@ne + \ifnum \par@deathcycles > \thr@@ + \PackageError{galley2}\GAL@ignored@par@error\@ehd + \setGALnormalpar: + \par + \fi + \@ifnextchar\par{}{\setGALnormalpar:} +} +% \end{macrocode} +% \end{macro} +% +% +% +% +% \subsection{Support for paragraph shapes} +% +% +% \begin{macro}{\GAL@for} +% Next macro is a reimplementation of |\@for| to get rid of the |:| +% \begin{macrocode} +\long\def\GAL@for#1#2\do#3{% + \expandafter\def\expandafter\@fortmp\expandafter{#2}% + \ifx\@fortmp\@empty \else + \expandafter\@forloop#2,\@nil,\@nil\@@#1{#3}\fi} +% \end{macrocode} +% \end{macro} +% +% +% +% +% \begin{macro}{\parshape@setup} +% The |\parshape@setup| macro provides a low-level interface for +% declaring special parshapes for the upcoming paragraph. It is +% especially tuned to deal with the more common cases like +% providing space for an initial or for an inline figure. It takes +% six arguments with the following meaning: +% \begin{itemize} +% \item If a hole is to be cut on the left of the paragraph the +% first argument should be |{\the\parshape@lineindent}| otherwise +% |\@totalleftmargin| (hole on the right). At the moment there is +% no provision for special shapes on both sides of the +% paragraph.\footnote{This is low-level but still more than awkward +% so probably should be replaced by something nicer one day.} +% \item +% The second argument gives the indentation to be used for all +% lines following the last special line. Typical value would be +% |\@totalleftmargin|, or in case of setting up hanging paragraphs, +% |\@totalleftmargin+<amount of hang>|. More exactly this indentation +% is assumed to be what is needed if this would have been a normal +% paragraph. It is therefore also added to the special lines. +% \item +% The third argument gives the line width for all lines following +% the last special line. Typical argument might be |\linewidth| or +% in case of hanging paragraphs +% |\linewidth+<amount of hang>|.\footnote{rewrite +% description of this and previous item} +% \item +% The forth argument gives the number of lines before the first special +% line (in case of an initial this would be 0 typically). +% \item +% The fifth argument gives an initial amount to be left free on all +% special lines. +% \item +% Finally the sixth argument specifies the special lines as a comma +% separated lists of dimensions. These dimensions are deltas to the +% space specified in the forth argument. +% \end{itemize} +% +% Running this command has several effects: +% \begin{itemize} +% \item +% The |\GAL@ps@| parameter is getting updated, ie it receives the +% area parshape spec. +% \item +% In the command |\parshape@firstlineindent| the indent of the +% first special line (not taking into account the standard line +% indentation) is made available for use by an +% application. This can be used to get to the left point on the +% line to insert an initial character or a figure. +% \end{itemize} +% +% \begin{macrocode} +\def \parshape@setup #1 #2 #3 #4 #5 #6{ +% \end{macrocode} +% +% \begin{macrocode} + \setlength\@tempdima{#2} + \setlength\@tempdimb{#3} + \global\let\GAL@ps@\@gobble % remove upcoming space below +% \end{macrocode} +% +% \begin{macrocode} + \parshape@linecnt \z@ + \@whilenum \parshape@linecnt < #4 \do + { \xdef\GAL@ps@{\GAL@ps@\space + \the\@tempdima\space \the\@tempdimb + } + \advance \parshape@linecnt \@ne + } +% \end{macrocode} +% +% \begin{macrocode} + \GAL@for\parshape@next#6\do + { + \advance\parshape@linecnt\@ne + \setlength\parshape@lineindent{\@tempdima+#5+\parshape@next} + \setlength\parshape@linewidth + {\@tempdima+\@tempdimb-\parshape@lineindent} + +% \end{macrocode} +% +% \begin{macrocode} +% \setlength\parshape@linewidth +% {\@tempdimb-#5-(\parshape@next)} +% \setlength\parshape@lineindent +% {\@tempdima+\@tempdimb-\parshape@linewidth} +% \end{macrocode} +% +% If we setting up the first special line we record the indentation +% used compared to a normal paragraph at this point. The +% |\parshape@firstlineindent| is not part of the galley structure +% thus we store it locally. +% \begin{macrocode} + \ifnum\parshape@linecnt=\@ne + \@tempdimc \parshape@lineindent + \advance\@tempdimc -\@tempdima + \edef\parshape@firstlineindent{\the\@tempdimc} + \fi +% \end{macrocode} +% +% \begin{macrocode} + \xdef\GAL@ps@{\GAL@ps@\space + #1\space + \the\parshape@linewidth} + } +% \end{macrocode} +% +% \begin{macrocode} + \advance\parshape@linecnt\@ne + \xdef\GAL@ps@{\the\parshape@linecnt\space + \GAL@ps@\space + \the\@tempdima\space \the\@tempdimb} +%<*trace> + \GAL@typeout{\space\space set~ ps = \GAL@ps@}% +%</trace> +% \end{macrocode} +% +% \begin{macrocode} + \GAL@prepare@reassign:NN \GAL@ps@ \GAL@ps@s +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macrocode} +\newcount\parshape@linecnt +\newlength\parshape@lineindent +\newlength\parshape@linewidth +% \end{macrocode} +% +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% \subsection{Short-term mutators} +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% All these functions only modify the DGPV, i.e., the one that gets +% reset after use. +% +% +% \subsubsection{Dimensions (skips and dimens)} +% +% +% For setting galley parameters of type skip or dimen we provide +% functions which take as their first argument an identifier +% (typically a single character) that identifies the parameter to +% change, e.g., `v' for vertical skip or `i' for indentation and as +% second argument a dimension (for setting the parameter to this +% value or adding this value or using the maximum of the old and the +% new value, etc).\footnote{They currently work using skip registers +% internally which means that it is up to the programmer to ensure +% that a dimen parameter gets passed only dimen values without plus +% or minus parts.} +% +% +% +% \begin{macro}{\setDGPVdimension:nn} +% |\setDGPVdimension:nn| sets the parameter specified by the first +% argument to the value given as the second argument. +% \begin{macrocode} +\def\setDGPVdimension:nn #1#2{% #1=v/h #2=value + \calc@assign@skip\GAL@skipb{#2} +%<*trace> + \GAL@typeout{\space\space set~ #1 = #2 = \the\GAL@skipb}% +%</trace> + \expandafter \xdef + \csname GAL@#1@\endcsname + {\the\GAL@skipb} + \GAL@prepare@reassign:n{#1} +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\addDGPVdimension:nn} +% +% |\addDGPVdimension:nn| add to the parameter specified by the first +% argument the value given as the second argument. +% \begin{macrocode} +\def\addDGPVdimension:nn #1#2{% #1=v/h/... #2=value + \GAL@skipb\csname GAL@#1@ \endcsname\relax +% \end{macrocode} +% Since the value of -1sp is (at least for the v parameter) used as +% a special flag we are a bit careful when adding so that we are +% not off by -1sp: this is not visible but in certain situations +% \TeX{} might be upset even by this tiny amount.\footnote{Really +% necessary?} +% \begin{macrocode} + \ifdim\GAL@skipb=-1sp + \calc@assign@skip\GAL@skipb{#2} + \else + \calc@assign@skip{\advance\GAL@skipb}{#2} + \fi +%<*trace> + \GAL@typeout{\space\space set~ #1 =+ #2 = \the\GAL@skipb} +%</trace> + \expandafter + \xdef + \csname GAL@#1@\endcsname + {\the\GAL@skipb} + \GAL@prepare@reassign:n{#1} +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\maxDGPVdimension:nn} +% |\maxDGPVdimension:nn| compares the current value of the +% parameter specified by the first argument with the value given as +% the second argument and stores the maximum of +% them.\footnote{Current \LaTeX's \texttt{\textbackslash addvspace} +% works quite differently and we may have to provide something else +% here (or in addition)} +% \begin{macrocode} +\def\maxDGPVdimension:nn #1#2{ + \GAL@skipa\csname GAL@#1@\endcsname\relax + \calc@assign@skip\GAL@skipb{#2} + \ifdim\GAL@skipa<\GAL@skipb + \expandafter + \xdef + \csname GAL@#1@\endcsname + {\the\GAL@skipb} + \GAL@prepare@reassign:n{#1} + \fi +%<*trace> + \GAL@typeout{\space\space set~ #1 = + max(\the\GAL@skipa,\the\GAL@skipb) ^^J\@spaces\@spaces + = \csname GAL@#1@\endcsname} +%</trace> +} +% \end{macrocode} +% \end{macro} +% +% +% +% \subsubsection{Integers} +% +% From previous coding we still have things like |\setGALpenalty:n| --- +% i guess one could normalise this to an interface like +% |\setGALinteger| \ldots +% +% \begin{macro}{\setGALpenalty:n} +% we can either set the `penalty' object or add to it. To speed things +% up we use a mixture of calc and low-level \TeX{} conventions +% +% \begin{macrocode} +\def\setGALpenalty:n #1{% + \calc@assign@count\GAL@cnta{#1} + \xdef \GAL@p@ {\the\GAL@cnta} +%<*trace> + \GAL@typeout{\space\space set~ p = #1 = \the\GAL@cnta} +%</trace> + \GAL@prepare@reassign:NN \GAL@p@ \GAL@p@s +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\addGALpenalty:n} +% +% \begin{macrocode} +\def\addGALpenalty:n #1{% + \GAL@cnta \GAL@p@ \relax + \calc@assign@count{\advance\GAL@cnta}{#1} + \xdef \GAL@p@ {\the\GAL@cnta} +%<*trace> + \GAL@typeout{\space\space set~ p += #1 = \the\GAL@cnta} +%</trace> + \GAL@prepare@reassign:NN \GAL@p@ \GAL@p@s +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\setGALbreak:n} +% The |\setGALbreak:n| sets the switch that controls page breaking +% \begin{macrocode} +\def\setGALbreak:n #1{% values 0, 1, 2, or 3 +%<*trace> + \GAL@typeout{\space\space set~ b = #1 } +%</trace> + \gdef \GAL@b@ {#1} + \GAL@prepare@reassign:NN \GAL@b@ \GAL@b@s +} +% \end{macrocode} +% \end{macro} +% +% +% +% +% \subsubsection{Objects and thingies in general} +% +% \begin{macro}{\setGALobject:n} +% +% For the `o' object i've implemented only a `set' command so far +% (have to see what kind of usage this gets first) +% +% \begin{macrocode} +\def\setGALobject:n #1{ + \gdef \GAL@o@ {#1} + \GAL@prepare@reassign:NN \GAL@o@ \GAL@o@s +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\setDGPVthing:nn} +% A generalised version of that is |\setDGPVthing:nn|. +% \begin{macrocode} +\def\setDGPVthing:nn #1 #2{ + \expandafter \gdef \csname GAL@#1@\endcsname {#2} + \GAL@prepare@reassign:n{#1} +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\appendtoDGPVthing:nn} +% \begin{macro}{\appendtoDGPVthing:no} +% And here is another one which appends code to the right of the +% parameter: +% \begin{macrocode} +\def\appendtoDGPVthing:nn #1#2{ + \expandafter\appendtoDGPV@internal:Nn\csname GAL@#1@\endcsname {#2} + \GAL@prepare@reassign:n{#1} +} +\def\appendtoDGPVthing:no #1#2{ + \expandafter\appendtoDGPV@internal:No\csname GAL@#1@\endcsname {#2} + \GAL@prepare@reassign:n{#1} +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\appendtoDGPV@internal:Nn} +% \begin{macro}{\appendtoDGPV@internal:No} +% These are internals which look suspiciently like some macros +% already present a million times in \LaTeX{}. +% \begin{macrocode} +\def\appendtoDGPV@internal:Nn #1 #2{ + \expandafter \gdef \expandafter #1 \expandafter + {#1 #2} +} +\def\appendtoDGPV@internal:No #1 #2{ + \expandafter\appendtoDGPV@internal:Nn\expandafter #1\expandafter {#2} +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \subsubsection{Paragraph shapes} +% +% \begin{macro}{\setGALleftparshape:nnn} +% \begin{macro}{\setGALrightparshape:nnn} +% Setting a parshape on the left or the right for the next +% paragraph, e.g., an initial. Not implemented so far is doing +% something special on both sides. +% \begin{macrocode} +\def \setGALleftparshape:nnn { + \parshape@setup {\the\parshape@lineindent} \@totalleftmargin + \linewidth } +\def \setGALrightparshape:nnn { + \parshape@setup \@totalleftmargin \@totalleftmargin \linewidth +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\GALhangfrom:n} +% And here a reimplementation of |\@hangfrom| but obeying +% |\@totalleftmargin| indentation. +% \begin{macrocode} +\def \GALhangfrom:n #1 { + \setbox\@tempboxa\hbox{{#1}} + \parshape@setup {\the\parshape@lineindent} + {\@totalleftmargin+\wd\@tempboxa} + {\linewidth-\wd\@tempboxa} + \z@ + \z@ + {-\wd\@tempboxa} + \noindent\box\@tempboxa} +\let \@hangfrom \GALhangfrom:n +% \end{macrocode} +% \end{macro} +% +% +% +% +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% \subsection{Long-term mutators} +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% The following functions now modify the SGPV, i.e., modify the +% values that are used as defaults unless overwritten for an +% individual paragraph. Right now I don't see any purpose in providing +% computation support at this level other than something like calc +% expansion; so need one function per parameter type. Otherwise a +% single function would be sufficient. +% +% \subsubsection{Objects and thingies in general} +% +% \begin{macro}{\setSGPVthing:nn} +% So here is one that simply stores away the value in the right plist +% under the right key. In addition we also directly update the key +% command itself to avoid having to run something like +% |\GAL@init@hmode| afterwards. +% \begin{macrocode} +\def\setSGPVthing:nn #1 #2 { + \setDGPVthing:nn {#1} {#2} + \global\expandafter + \let\csname GAL@#1@s \expandafter\endcsname + \csname GAL@#1@ \endcsname +} +% \end{macrocode} +% \end{macro} +% +% +% \subsubsection{Dimensions (skips and dimens)} +% +% \begin{macro}{\setSGPVdimension:nn} +% The |\setSGPVdimension:nn| first sets the dynamic part of the +% parameter (which is done using calc expansion) followed by +% updating the static part of the parameter. +% \begin{macrocode} +\def\setSGPVdimension:nn #1 #2 { + \setDGPVdimension:nn {#1} {#2} + \global\expandafter + \let\csname GAL@#1@s \expandafter\endcsname + \csname GAL@#1@ \endcsname +} +% \end{macrocode} +% \end{macro} +% +% +% \subsubsection{Paragraph shapes} +% +% \begin{macro}{\setSGPVmeasure:nn} +% Dealing with the parshape: the long term modification is essentially +% setting the measure and to support old \LaTeX{} code also sets +% |\linewidth| and |\@totalleftmargin| (but see comments on this somewhere!) +% +% \begin{macrocode} +\def \setSGPVmeasure:nn #1 #2 { + \setlength\@totalleftmargin{#1} + \setlength\linewidth{#2} + \xdef\GAL@ps@s{\@ne\space + \the\@totalleftmargin\space \the\linewidth} + \global\let\GAL@ps@\GAL@ps@s +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\addSGPVmeasure:nn} +% This is a variant modifies the measure (the name is +% horrible) by adding to |\@totalleftmargin| and |\linewidth|. Note +% that you normally need to substract from |\linewidth| if +% |\@totalleftmargin| is enlarged! +% \begin{macrocode} +\def \addSGPVmeasure:nn #1 #2 { + \addtolength\@totalleftmargin{#1} + \addtolength\linewidth{#2} + \xdef\GAL@ps@s{\@ne\space + \the\@totalleftmargin\space \the\linewidth} + \global\let\GAL@ps@\GAL@ps@s +} +% \end{macrocode} +% \end{macro} +% +% +% +% \subsubsection{Integers} +% +% No functions provided. For consistency reasons there probably should +% some in the end. +% +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% \subsection{Higher level commands} +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% +% \begin{macro}{\vspace} +% The |*| of |\vspace| is parsed but not handled in this +% implementation yet! +% \begin{macrocode} +\DeclareDocumentCommand \vspace {s m } + { + \addDGPVdimension:nn{uv}{#2} + } +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\addvspace} +% |\addvspace| is quite a bit different to the latex original, this +% needs changing! +% \begin{macrocode} +\def\addvspace#1{ + \maxDGPVdimension:nn{v}{#1} +} +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\addpenalty} +% \begin{macrocode} +\def\addpenalty#1{ + \addGALpenalty:n{#1} +} +% \end{macrocode} +% \end{macro} +% +% +% +% +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% \subsection{Templates (first ideas)} +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% Code in this section is essentially left over from previous +% versions. Most templates have been moved to different files already. +% +% The endlist template is rubbish and just for testing the concept +% itself! and not finished either! +% +% \begin{macrocode} +\RequirePackage{template} +\RequirePackage{xparse} +% \end{macrocode} +% +% \begin{macrocode} +\DeclareTemplateType{endlist}{0} + +\DeclareTemplate{endlist}{std}{0}{ + penalty =+C \GAL@p@ , + vspace =+L \GAL@v@ , + parindent =+L \GAL@i@ , + par-penalty =+C [0] \GAL@p@X , + par-vspace =+L [\z@] \GAL@v@X , + par-parindent =+L [\z@] \GAL@i@X , + } + {\DoParameterAssignments + \setGALendlistpar:} + +\DeclareInstance{endlist}{list}{std}{ + penalty = 999 , + vspace = 10pt , + parindent = 0pt , + par-penalty = -1000 , + par-vspace = 5pt , + par-parindent = 10pt , + } +% \end{macrocode} +% +% +% +% +% \subsection{Initialisation} +% +% \begin{macrocode} +\GAL@init@static % this is to be after the templates by now + +\GAL@@everypar{\GAL@use@on@para\the\everypar} + +% \end{macrocode} +% +% We need to initialize again at start of document i fear to ensure +% that stuff like the hyphenation is set up properly (this needs some +% further thoughts!) +% \begin{macrocode} +\AtBeginDocument { + \GAL@init@static % this is to be after the templates by now +} +% \end{macrocode} +% +% \section{Updated code from \texttt{latex.ltx}} +% +% There are a bunch of additional code lines which are originally from +% \texttt{latex.ltx} and have been updated (in part) to use the new +% mechanism. This isn't really worth printing as most of that is not +% fully done or obsolete by redefinition of, say, code for lists, +% etc. But one might want to have a look at it at some stage. For this +% reason the code contains an |\end{document}| at this point. which +% you may or may not want to remove. +% +% \PrintIndex +% +% \end{document} +% +% \begin{macrocode} +\def\@@line#1{\GAL@use@on@vobject\hb@xt@\hsize{#1}\nobreak} + +\long\def \@savemarbox #1#2{% + \global\setbox #1% + \color@vbox + \vtop{% + \hsize\marginparwidth + \@parboxrestore + \@marginparreset + #2% + \par % needed nowadays! + \@minipagefalse + \outer@nobreak + }% + \color@endbox +} + +\long\def\@footnotetext#1{\insert\footins{% + \reset@font\footnotesize + \interlinepenalty\interfootnotelinepenalty + \splittopskip\footnotesep + \splitmaxdepth \dp\strutbox \floatingpenalty \@MM + \hsize\columnwidth \@parboxrestore + \protected@edef\@currentlabel{% + \csname p@footnote\endcsname\@thefnmark + }% + \color@begingroup + \@makefntext{% + \rule\z@\footnotesep\ignorespaces#1\@finalstrut\strutbox\par}% %ditto!!! + \color@endgroup}}% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% all latex.ltx commands that involved the @nobreak flag +% +% most of them have been modified to use the new structure but not all +% and not all correctly (see comments within the code + +%<*trace> +\def\showGALcmd#1{\GAL@typeout{In~#1: \the\GAL@level@num~ \on@line}} +%</trace> + +\def\@afterheading{ +%<*trace> + \showGALcmd{@afterheading} +%</trace> + \if@afterindent \else + \setDGPVthing:nn i \@ne + \fi + \setGALbreak:n 2 +} + +\def\nofiles{% +%<*trace> + \showGALcmd{} +%</trace> + \@fileswfalse + \typeout{No auxiliary output files.^^J}% + \long\def\protected@write##1##2##3% + {\write\m@ne{}% +% +% i think that the following code can simply vanish since if we are in +% vmode and the \PARM{break flag} is set then the GAL mechansim will +% automatically add a penalty 10000 at the right point; correct? +% +%\if@nobreak\ifvmode\nobreak\fi\fi}% + } + \let\makeindex\relax + \let\makeglossary\relax} + +\long\def \protected@write#1#2#3{% +%<*trace> + \showGALcmd{protected@write} +%</trace> + \begingroup + \let\thepage\relax + #2% + \let\protect\@unexpandable@protect + \edef\reserved@a{\write#1{#3}}% + \appendtoDGPVthing:no {nw} \reserved@a + \endgroup +% +% see above +% +% \if@nobreak\ifvmode\nobreak\fi\fi +} + +\def\markboth#1#2{\gdef\@themark{{#1}{#2}}{% +%<*trace> + \showGALcmd{} +%</trace> + \let\protect\@unexpandable@protect + \let\label\relax \let\index\relax \let\glossary\relax + \mark{\@themark}}% +% +%\if@nobreak\ifvmode\nobreak\fi\fi +} + +\def\markright#1{{\let\protect\@unexpandable@protect +%<*trace> + \showGALcmd{} +%</trace> + \let\label\relax \let\index\relax \let\glossary\relax + \expandafter\@markright\@themark + {#1}\mark{\@themark}}% +% +%\if@nobreak\ifvmode\nobreak\fi\fi +} + +\def \newpage {% +%<*trace> + \showGALcmd{newpage} +%</trace> + \if@noskipsec + \ifx \@nodocument\relax + \leavevmode + \global \@noskipsecfalse + \fi + \fi + \if@inlabel + \leavevmode + \global \@inlabelfalse + \fi +% +% newpage is supposed to stop any \PARM{nobreak flag}, so the right +% approach is probably something like +% + \ifnum \GAL@b@ > \z@ + \setGALbreak:n 0 + \fi +% +% \if@nobreak \@nobreakfalse \everypar{}\fi +% + \par + \vfil + \penalty -\@M} +% +% +% the |\@arrayparboxrestore| nothing else than initialising a new +% galley level (in the old \LaTeX) so most of what is there needs +% either to vanish or to get integrated into the startup code of a new +% galley (not done yet) +% +\def\@arrayparboxrestore{% +%<*trace> + \showGALcmd{@arrayparboxrestore} +%</trace> +% +% again nothing to do (i think): if used as part of a minipage or +% parbox we are at a new level, otherwise we are probably not supposed +% to change that value +% +% \let\if@nobreak\iffalse + \let\if@noskipsec\iffalse + \let\par\@@par + \let\-\@dischyph + \let\'\@acci\let\`\@accii\let\=\@acciii + \parindent\z@ \parskip\z@skip + \everypar{}% + \linewidth\hsize + \@totalleftmargin\z@ + \leftskip\z@skip \rightskip\z@skip \@rightskip\z@skip + \parfillskip\@flushglue \lineskip\normallineskip + \baselineskip\normalbaselineskip + \sloppy} + +\def\@startsection#1#2#3#4#5#6{% +%<*trace> + \showGALcmd{@startsection} +%</trace> + \if@noskipsec \leavevmode \fi + \par + \@tempskipa #4\relax + \@afterindenttrue + \ifdim \@tempskipa <\z@ + \@tempskipa -\@tempskipa \@afterindentfalse + \fi +% +% the section case is interesting since the @nobreak flag is used for +% two things: a) to suppress a penalty if heading follow each other +% and be to suppress a skip in this case. This works because in latex +% the @nobreak switch is only set in the heading context (so is +% actually something like ``heading just seen flag'' +% +% not sure how to model something like this in general, for the moment +% i look at the \PARM{nobreak flag} but this is not correct! +% +% \if@nobreak +% \everypar{}% +% \else +% \addpenalty\@secpenalty\addvspace\@tempskipa +% \fi + \ifnum \GAL@b@ = \z@ + \addpenalty\@secpenalty\addvspace\@tempskipa + \fi + \@ifstar + {\@ssect{#3}{#4}{#5}{#6}}% + {\@dblarg{\@sect{#1}{#2}{#3}{#4}{#5}{#6}}}} + +\def\@xsect#1{% +%<*trace> + \showGALcmd{@xsect} +%</trace> + \@tempskipa #1\relax + \ifdim \@tempskipa>\z@ + \par \nobreak + \vskip \@tempskipa + \@afterheading + \else + \global\@noskipsectrue +% \@nobreakfalse +% \everypar{% +% \if@noskipsec +% \global\@noskipsecfalse +% {\setbox\z@\lastbox}% +% \clubpenalty\@M +% \begingroup \@svsechd \endgroup +% \unskip +% \@tempskipa #1\relax +% \hskip -\@tempskipa +% \else +% \clubpenalty \@clubpenalty +% \everypar{}% +% \fi}% + \setDGPVthing:nn i \@ne + \setGALbreak:n 2 + \setGALobject:n { \begingroup \@svsechd \endgroup + \unskip } +% obey stupid latex startsection interface with negative numbers ... + \@tempskipa #1\relax + \setDGPVdimension:nn h {-\@tempskipa} +% +% the noskipsec flag is probably needed in interaction with lists as +% long as this is only a partial conversion so i do set it (maybe not) +% + \everypar{% + \if@noskipsec + \global\@noskipsecfalse + \else + \everypar{}% + \fi}% + \fi + \ignorespaces} + +\gdef\@specialoutput{% +%<*trace> + \showGALcmd{@specialoutput} +%</trace> + \ifnum \outputpenalty>-\@Mii + \@doclearpage + \else + \GAL@ignore@next@galley + \ifnum \outputpenalty<-\@Miii + \ifnum \outputpenalty<-\@MM \deadcycles \z@ \fi + \global \setbox\@holdpg \vbox {\unvbox\@cclv}% + \else + \global \setbox\@holdpg \vbox{% + \unvbox\@holdpg + \unvbox\@cclv + \setbox\@tempboxa \lastbox + \unskip + }% + \@pagedp \dp\@holdpg + \@pageht \ht\@holdpg + \unvbox \@holdpg + \@next\@currbox\@currlist{% + \ifnum \count\@currbox>\z@ + \advance \@pageht \@pagedp + \ifvoid\footins \else + \advance \@pageht \ht\footins + \advance \@pageht \skip\footins + \advance \@pageht \dp\footins + \fi + \ifvbox \@kludgeins + \ifdim \wd\@kludgeins=\z@ + \advance \@pageht \ht\@kludgeins + \fi + \fi + \@reinserts + \@addtocurcol + \else + \@reinserts + \@addmarginpar + \fi + }\@latexbug +% +% with the same argument as before we can always add the penalty, right? +% + \ifnum \outputpenalty<\z@ +% \if@nobreak +% \nobreak +% \else + \addpenalty \interlinepenalty +% \fi + \fi + \fi + \fi +} + +\def \@addtocurcol {% +%<*trace> + \showGALcmd{@addtocurcol} +%</trace> + \@insertfalse + \@setfloattypecounts + \ifnum \@fpstype=8 + \else + \ifnum \@fpstype=24 + \else + \@flsettextmin + \advance \@textmin \@textfloatsheight + \@reqcolroom \@pageht + \ifdim \@textmin>\@reqcolroom + \@reqcolroom \@textmin + \fi + \advance \@reqcolroom \ht\@currbox + \ifdim \@colroom>\@reqcolroom + \@flsetnum \@colnum + \ifnum \@colnum>\z@ + \@bitor\@currtype\@deferlist + \if@test + \else + \@bitor\@currtype\@botlist + \if@test + \@addtobot + \else + \ifodd \count\@currbox + \advance \@reqcolroom \intextsep + \ifdim \@colroom>\@reqcolroom + \global \advance \@colnum \m@ne + \global \advance \@textfloatsheight \ht\@currbox + \global \advance \@textfloatsheight 2\intextsep + \@cons \@midlist \@currbox +% +% same argument as before (perhaps incorrect here?) +% +% \if@nobreak +% \nobreak +% \@nobreakfalse +% \everypar{}% +% \else + \addpenalty \interlinepenalty +% \fi +% +% at least it seems to me that we should not use \vskip here +% +% +% however we should then also have a way to trigger the use of the +% GAL structure without actually starting hmode (note done so all +% this is incorrect) +% + \vskip \intextsep + \box\@currbox +% +% and neither here ... +% + \penalty\interlinepenalty + \vskip\intextsep + \ifnum\outputpenalty <-\@Mii \vskip -\parskip\fi + \outputpenalty \z@ + \@inserttrue + \fi + \fi + \if@insert + \else + \@addtotoporbot + \fi + \fi + \fi + \fi + \fi + \fi + \fi + \if@insert + \else + \@resethfps + \@cons\@deferlist\@currbox + \fi +} + +% and the whole item stuff is too complicated for me to really think +% about it tonight ... + +\def\@item[#1]{% +%<*trace> + \showGALcmd{@item} +%</trace> + \if@noparitem + \@donoparitem + \else + \if@inlabel + \indent \par + \fi + \ifhmode + \unskip\unskip \par + \fi + \if@newlist + \if@nobreak + \@nbitem + \else + \addpenalty\@beginparpenalty + \addvspace\@topsep + \addvspace{-\parskip}% + \fi + \else + \addpenalty\@itempenalty + \addvspace\itemsep + \fi + \global\@inlabeltrue + \fi + \everypar{% + \@minipagefalse + \global\@newlistfalse + \if@inlabel + \global\@inlabelfalse + {\setbox\z@\lastbox + \ifvoid\z@ + \kern-\itemindent + \fi}% + \box\@labels + \penalty\z@ + \fi + \if@nobreak + \@nobreakfalse + \clubpenalty \@M + \else + \clubpenalty \@clubpenalty + \everypar{}% + \fi}% + \if@noitemarg + \@noitemargfalse + \if@nmbrlist + \refstepcounter\@listctr + \fi + \fi + \sbox\@tempboxa{\makelabel{#1}}% + \global\setbox\@labels\hbox{% + \unhbox\@labels + \hskip \itemindent + \hskip -\labelwidth + \hskip -\labelsep + \ifdim \wd\@tempboxa >\labelwidth + \box\@tempboxa + \else + \hbox to\labelwidth {\unhbox\@tempboxa}% + \fi + \hskip \labelsep}% + \ignorespaces} + + +% \end{macrocode} +% +% +% \section{Fixing non-galley vboxes} +% +% \begin{macrocode} +\DeclareRobustCommand{\LaTeX}{L\kern-.36em% + {\sbox\z@ T% + \GAL@ignore@next@galley@vbox to\ht\z@{\hbox{\check@mathfonts + \fontsize\sf@size\z@ + \math@fontsfalse\selectfont + A}% + \vss}% + }% + \kern-.15em% + \TeX} +\DeclareTextCommandDefault{\textunderscore}{% + \leavevmode \kern.06em\GAL@ignore@next@galley@vbox{\hrule\@width.3em}} +\DeclareTextCommandDefault{\textvisiblespace}{% + \mbox{\kern.06em\vrule \@height.3ex}% + \GAL@ignore@next@galley@vbox{\hrule \@width.3em}% + \hbox{\vrule \@height.3ex}} +\gdef\showhyphens#1{% + \setbox0\vbox{% + \color@begingroup + \everypar{}% + \parfillskip\z@skip\hsize\maxdimen + \normalfont + \pretolerance\m@ne\tolerance\m@ne\hbadness\z@\showboxdepth\z@\ #1% + \color@endgroup}} +\catcode`\:=12 +\long\def\@imakepicbox(#1,#2)[#3]#4{% + \GAL@ignore@next@galley@vbox to#2\unitlength + {\let\mb@b\vss \let\mb@l\hss\let\mb@r\hss + \let\mb@t\vss + \@tfor\reserved@a :=#3\do{% + \if s\reserved@a + \let\mb@l\relax\let\mb@r\relax + \else + \expandafter\let\csname mb@\reserved@a\endcsname\relax + \fi}% + \mb@t + \hb@xt@ #1\unitlength{\mb@l #4\mb@r}% + \mb@b + \kern\z@}} +\catcode`\:=11 +\long\def\frame#1{% + \leavevmode + \hbox{% + \hskip-\@wholewidth + \GAL@ignore@next@galley@vbox{% + \vskip-\@wholewidth + \hrule \@height\@wholewidth + \hbox{% + \vrule\@width\@wholewidth + #1% + \vrule\@width\@wholewidth}% + \hrule\@height\@wholewidth + \vskip-\@wholewidth}% + \hskip-\@wholewidth}} +\def\@frameb@x#1{% + \@tempdima\fboxrule + \advance\@tempdima\fboxsep + \advance\@tempdima\dp\@tempboxa + \hbox{% + \lower\@tempdima\hbox{% + \GAL@ignore@next@galley@vbox{% + \hrule\@height\fboxrule + \hbox{% + \vrule\@width\fboxrule + #1% + \GAL@ignore@next@galley@vbox{% + \vskip\fboxsep + \box\@tempboxa + \vskip\fboxsep}% + #1% + \vrule\@width\fboxrule}% + \hrule\@height\fboxrule}% + }% + }% +} +\typeout{****~ Careful:~ there~ is~ another~ rewrite~ for~ iiiparbox~ in~ coffins!} + +\long\def\@iiiparbox#1#2[#3]#4#5{% + \leavevmode + \@pboxswfalse + \setlength\@tempdima{#4}% + \@begin@tempboxa\vbox{\hsize\@tempdima\@parboxrestore#5\@@par}% + \ifx\relax#2\else + \setlength\@tempdimb{#2}% + \def\@parboxto{to\@tempdimb}% + \fi + \GAL@ignore@next@galley + \if#1b\vbox + \else\if #1t\vtop + \else\ifmmode\vcenter + \else\@pboxswtrue $\vcenter + \fi\fi\fi + \@parboxto{\let\hss\vss\let\unhbox\unvbox + \csname bm@#3\endcsname}% + \if@pboxsw \m@th$\fi + \@end@tempboxa} +\def\@iiiminipage#1#2[#3]#4{% + \leavevmode + \@pboxswfalse + \setlength\@tempdima{#4}% + \def\@mpargs{{#1}{#2}[#3]{#4}}% + \setbox\@tempboxa\vbox\bgroup + \color@begingroup + \hsize\@tempdima + \textwidth\hsize \columnwidth\hsize + \@parboxrestore + \def\@mpfn{mpfootnote}\def\thempfn{\thempfootnote}\c@mpfootnote\z@ + \let\@footnotetext\@mpfootnotetext + \let\@listdepth\@mplistdepth \@mplistdepth\z@ + \@minipagerestore + \@setminipage} +\long\def\@mpfootnotetext#1{% + \global\setbox\@mpfootins\vbox{% + \unvbox\@mpfootins + \reset@font\footnotesize + \hsize\columnwidth + \@parboxrestore + \protected@edef\@currentlabel + {\csname p@mpfootnote\endcsname\@thefnmark}% + \color@begingroup + \@makefntext{% + \rule\z@\footnotesep\ignorespaces#1\@finalstrut\strutbox}% + \color@endgroup}} +\def\@array[#1]#2{% + \GAL@ignore@next@galley + \if #1t\vtop \else \if#1b\vbox \else \vcenter \fi\fi + \bgroup + \setbox\@arstrutbox\hbox{% + \vrule \@height\arraystretch\ht\strutbox + \@depth\arraystretch \dp\strutbox + \@width\z@}% + \@mkpream{#2}% + \edef\@preamble{% + \ialign \noexpand\@halignto + \bgroup \@arstrut \@preamble \tabskip\z@skip \cr}% + \let\@startpbox\@@startpbox \let\@endpbox\@@endpbox + \let\tabularnewline\\% +% +% we can't allow uncontrolled changes of \par +% +%%%% \let\par\@empty + \let\@sharp##% + \set@typeset@protect + \lineskip\z@skip\baselineskip\z@skip + \ifhmode \@preamerr\z@ \@@par\fi + \@preamble} +\gdef\@shortstack[#1]{% + \leavevmode + \GAL@ignore@next@galley@vbox\bgroup + \baselineskip-\p@\lineskip 3\p@ + \let\mb@l\hss\let\mb@r\hss + \expandafter\let\csname mb@#1\endcsname\relax + \let\\\@stackcr + \@ishortstack} +\gdef\@ishortstack#1{\ialign{\mb@l {##}\unskip\mb@r\cr #1\crcr}\egroup} +\gdef\@stackcr{\@ifstar\@ixstackcr\@ixstackcr} +\gdef\@ixstackcr{\@ifnextchar[\@istackcr{\cr\ignorespaces}} +\gdef\@istackcr[#1]{\cr\noalign{\vskip #1}\ignorespaces} +\newif\if@negarg +\gdef\line(#1,#2)#3{\@xarg #1\relax \@yarg #2\relax + \@linelen #3\unitlength + \ifdim\@linelen<\z@\@badlinearg\else + \ifnum\@xarg =\z@ \@vline + \else \ifnum\@yarg =\z@ \@hline \else \@sline\fi + \fi + \fi} +\gdef\@sline{% + \ifnum\@xarg<\z@ \@negargtrue \@xarg -\@xarg \@yyarg -\@yarg + \else \@negargfalse \@yyarg \@yarg \fi +\ifnum \@yyarg >\z@ \@tempcnta\@yyarg \else \@tempcnta -\@yyarg \fi +\ifnum\@tempcnta>6 \@badlinearg\@tempcnta\z@ \fi +\ifnum\@xarg>6 \@badlinearg\@xarg \@ne \fi +\setbox\@linechar\hbox{\@linefnt\@getlinechar(\@xarg,\@yyarg)}% +\ifnum \@yarg >\z@ \let\@upordown\raise \@clnht\z@ + \else\let\@upordown\lower \@clnht \ht\@linechar\fi +\@clnwd \wd\@linechar +\if@negarg + \hskip -\wd\@linechar \def\reserved@a{\hskip -2\wd\@linechar}% +\else + \let\reserved@a\relax +\fi +\@whiledim \@clnwd <\@linelen \do + {\@upordown\@clnht\copy\@linechar + \reserved@a + \advance\@clnht \ht\@linechar + \advance\@clnwd \wd\@linechar}% +\advance\@clnht -\ht\@linechar +\advance\@clnwd -\wd\@linechar +\@tempdima\@linelen\advance\@tempdima -\@clnwd +\@tempdimb\@tempdima\advance\@tempdimb -\wd\@linechar +\if@negarg \hskip -\@tempdimb \else \hskip \@tempdimb \fi +\multiply\@tempdima \@m +\@tempcnta \@tempdima +\@tempdima \wd\@linechar \divide\@tempcnta \@tempdima +\@tempdima \ht\@linechar \multiply\@tempdima \@tempcnta +\divide\@tempdima \@m +\advance\@clnht \@tempdima +\ifdim \@linelen <\wd\@linechar + \hskip \wd\@linechar + \@picture@warn + \else\@upordown\@clnht\copy\@linechar\fi} +\gdef\@hline{\ifnum \@xarg <\z@ \hskip -\@linelen \fi +\vrule \@height \@halfwidth \@depth \@halfwidth \@width \@linelen +\ifnum \@xarg <\z@ \hskip -\@linelen \fi} +\gdef\@getlinechar(#1,#2){\@tempcnta#1\relax\multiply\@tempcnta 8% + \advance\@tempcnta -9\ifnum #2>\z@ \advance\@tempcnta #2\relax\else + \advance\@tempcnta -#2\relax\advance\@tempcnta 64 \fi + \char\@tempcnta} +\gdef\vector(#1,#2)#3{\@xarg #1\relax \@yarg #2\relax + \@tempcnta \ifnum\@xarg<\z@ -\@xarg\else\@xarg\fi + \ifnum\@tempcnta<5\relax + \@linelen #3\unitlength + \ifdim\@linelen<\z@\@badlinearg\else + \ifnum\@xarg =\z@ \@vvector + \else \ifnum\@yarg =\z@ \@hvector \else \@svector\fi + \fi + \fi + \else\@badlinearg\fi} +\gdef\@hvector{\@hline\hb@xt@\z@{\@linefnt + \ifnum \@xarg <\z@ \@getlarrow(1,0)\hss\else + \hss\@getrarrow(1,0)\fi}} +\gdef\@vvector{\ifnum \@yarg <\z@ \@downvector \else \@upvector \fi} +\gdef\@svector{\@sline + \@tempcnta\@yarg \ifnum\@tempcnta <\z@ \@tempcnta -\@tempcnta\fi + \ifnum\@tempcnta <5% + \hskip -\wd\@linechar + \@upordown\@clnht \hbox{\@linefnt \if@negarg + \@getlarrow(\@xarg,\@yyarg)\else \@getrarrow(\@xarg,\@yyarg)\fi}% + \else\@badlinearg\fi} +\gdef\@getlarrow(#1,#2){\ifnum #2=\z@ \@tempcnta'33 \else + \@tempcnta #1\relax\multiply\@tempcnta \sixt@@n \advance\@tempcnta + -9 \@tempcntb #2\relax\multiply\@tempcntb \tw@ + \ifnum \@tempcntb >\z@ \advance\@tempcnta \@tempcntb + \else\advance\@tempcnta -\@tempcntb\advance\@tempcnta 64 + \fi\fi\char\@tempcnta} +\gdef\@getrarrow(#1,#2){\@tempcntb #2\relax +\ifnum\@tempcntb <\z@ \@tempcntb -\@tempcntb\relax\fi +\ifcase \@tempcntb\relax \@tempcnta'55 \or +\ifnum #1<\thr@@ \@tempcnta #1\relax\multiply\@tempcnta +24\advance\@tempcnta -6 \else \ifnum #1=\thr@@ \@tempcnta 49 +\else\@tempcnta 58 \fi\fi\or +\ifnum #1<\thr@@ \@tempcnta=#1\relax\multiply\@tempcnta +24\advance\@tempcnta -\thr@@ \else \@tempcnta 51 \fi\or +\@tempcnta #1\relax\multiply\@tempcnta +\sixt@@n \advance\@tempcnta -\tw@ \else +\@tempcnta #1\relax\multiply\@tempcnta +\sixt@@n \advance\@tempcnta 7 \fi\ifnum #2<\z@ \advance\@tempcnta 64 \fi +\char\@tempcnta} +\gdef\@vline{\ifnum \@yarg <\z@ \@downline \else \@upline\fi} +\gdef\@upline{% + \hb@xt@\z@{\hskip -\@halfwidth \vrule \@width \@wholewidth + \@height \@linelen \@depth \z@\hss}} +\gdef\@downline{% + \hb@xt@\z@{\hskip -\@halfwidth \vrule \@width \@wholewidth + \@height \z@ \@depth \@linelen \hss}} +\gdef\@upvector{\@upline\setbox\@tempboxa\hbox{\@linefnt\char'66}\raise + \@linelen \hb@xt@\z@{\lower \ht\@tempboxa\box\@tempboxa\hss}} +\gdef\@downvector{\@downline\lower \@linelen + \hb@xt@\z@{\@linefnt\char'77\hss}} +\gdef\dashbox#1(#2,#3){\leavevmode\hb@xt@\z@{\baselineskip \z@skip +\lineskip \z@skip +\@dashdim #2\unitlength +\@dashcnt \@dashdim \advance\@dashcnt 200 +\@dashdim #1\unitlength\divide\@dashcnt \@dashdim +\ifodd\@dashcnt\@dashdim \z@ +\advance\@dashcnt \@ne \divide\@dashcnt \tw@ +\else \divide\@dashdim \tw@ \divide\@dashcnt \tw@ +\advance\@dashcnt \m@ne +\setbox\@dashbox \hbox{\vrule \@height \@halfwidth \@depth \@halfwidth +\@width \@dashdim}\put(0,0){\copy\@dashbox}% +\put(0,#3){\copy\@dashbox}% +\put(#2,0){\hskip-\@dashdim\copy\@dashbox}% +\put(#2,#3){\hskip-\@dashdim\box\@dashbox}% +\multiply\@dashdim \thr@@ +\fi +\setbox\@dashbox \hbox{\vrule \@height \@halfwidth \@depth \@halfwidth +\@width #1\unitlength\hskip #1\unitlength}\@tempcnta\z@ +\put(0,0){\hskip\@dashdim \@whilenum \@tempcnta <\@dashcnt +\do{\copy\@dashbox\advance\@tempcnta \@ne }}\@tempcnta\z@ +\put(0,#3){\hskip\@dashdim \@whilenum \@tempcnta <\@dashcnt +\do{\copy\@dashbox\advance\@tempcnta \@ne }}% +\@dashdim #3\unitlength +\@dashcnt \@dashdim \advance\@dashcnt 200 +\@dashdim #1\unitlength\divide\@dashcnt \@dashdim +\ifodd\@dashcnt \@dashdim \z@ +\advance\@dashcnt \@ne \divide\@dashcnt \tw@ +\else +\divide\@dashdim \tw@ \divide\@dashcnt \tw@ +\advance\@dashcnt \m@ne +\setbox\@dashbox\hbox{\hskip -\@halfwidth +\vrule \@width \@wholewidth +\@height \@dashdim}\put(0,0){\copy\@dashbox}% +\put(#2,0){\copy\@dashbox}% +\put(0,#3){\lower\@dashdim\copy\@dashbox}% +\put(#2,#3){\lower\@dashdim\copy\@dashbox}% +\multiply\@dashdim \thr@@ +\fi +\setbox\@dashbox\hbox{\vrule \@width \@wholewidth +\@height #1\unitlength}\@tempcnta\z@ +\put(0,0){\hskip -\@halfwidth \GAL@ignore@next@galley@vbox{\@whilenum \@tempcnta <\@dashcnt +\do{\vskip #1\unitlength\copy\@dashbox\advance\@tempcnta \@ne }% +\vskip\@dashdim}}\@tempcnta\z@ +\put(#2,0){\hskip -\@halfwidth \GAL@ignore@next@galley@vbox{\@whilenum \@tempcnta<\@dashcnt +\do{\vskip #1\unitlength\copy\@dashbox\advance\@tempcnta \@ne }% +\vskip\@dashdim}}}\@makepicbox(#2,#3)} +\gdef\@ovvert#1#2{\GAL@ignore@next@galley@vbox to\@ovyy{% + \if@ovb \@tempcntb \@tempcnta \advance \@tempcntb #1\relax + \kern -\@ovro \hbox{\char \@tempcntb}\nointerlineskip + \else \kern \@ovri \kern \@ovdy \fi + \leaders\vrule \@width \@wholewidth\vfil \nointerlineskip + \if@ovt \@tempcntb \@tempcnta \advance \@tempcntb #2\relax + \hbox{\char \@tempcntb}% + \else \kern \@ovdy \kern \@ovro \fi}} +\catcode`\:=12 +\def\@xfloat #1[#2]{% + \@nodocument + \def \@captype {#1}% + \def \@fps {#2}% + \@onelevel@sanitize \@fps + \def \reserved@b {!}% + \ifx \reserved@b \@fps + \@fpsadddefault + \else + \ifx \@fps \@empty + \@fpsadddefault + \fi + \fi + \ifhmode + \@bsphack + \@floatpenalty -\@Mii + \else + \@floatpenalty-\@Miii + \fi + \ifinner + \@parmoderr\@floatpenalty\z@ + \else + \@next\@currbox\@freelist + {% + \@tempcnta \sixt@@n + \expandafter \@tfor \expandafter \reserved@a + \expandafter :\expandafter =\@fps + \do + {% + \if \reserved@a h% + \ifodd \@tempcnta + \else + \advance \@tempcnta \@ne + \fi + \fi + \if \reserved@a t% + \@setfpsbit \tw@ + \fi + \if \reserved@a b% + \@setfpsbit 4% + \fi + \if \reserved@a p% + \@setfpsbit 8% + \fi + \if \reserved@a !% + \ifnum \@tempcnta>15 + \advance\@tempcnta -\sixt@@n\relax + \fi + \fi + }% + \@tempcntb \csname ftype@\@captype \endcsname + \multiply \@tempcntb \@xxxii + \advance \@tempcnta \@tempcntb + \global \count\@currbox \@tempcnta + }% + \@fltovf + \fi + \global \setbox\@currbox + \color@vbox + \normalcolor + \vbox \bgroup + \hsize\columnwidth + \@parboxrestore + \@floatboxreset +} +\catcode`\:=11 +\def\end@float{% + \@endfloatbox + \ifnum\@floatpenalty <\z@ + \@largefloatcheck + \@cons\@currlist\@currbox + \ifnum\@floatpenalty <-\@Mii + \penalty -\@Miv + \@tempdima\prevdepth + \GAL@ignore@next@galley@vbox{}% + \prevdepth\@tempdima + \penalty\@floatpenalty + \else + \vadjust{\penalty -\@Miv \GAL@ignore@next@galley@vbox{}\penalty\@floatpenalty}\@Esphack + \fi + \fi +} +\def \@xympar{% + \ifnum\@floatpenalty <\z@\@cons\@currlist\@marbox\fi + \setbox\@tempboxa + \color@vbox + \vbox \bgroup + \end@float + \@ignorefalse + \@esphack +} +\def \AtBeginDvi #1{% + \global \setbox \@begindvibox + \vbox{\unvbox \@begindvibox #1}% +} +\def\clearpage{% + \ifvmode + \ifnum \@dbltopnum =\m@ne + \ifdim \pagetotal <\topskip + \hbox{}% + \fi + \fi + \fi + \newpage + \write\m@ne{}% + \GAL@ignore@next@galley@vbox{}% + \penalty -\@Mi +} +\def \@emptycol {\GAL@ignore@next@galley@vbox{}\penalty -\@M} +\long\def \@topnewpage [#1]{% + \@nodocument + \@next\@currbox\@freelist{}{}% + \global \setbox\@currbox + \color@vbox + \normalcolor + \vbox {% + \hsize\textwidth + \@parboxrestore + \col@number \@ne + #1% + \vskip -\dbltextfloatsep + }% + \color@endbox + \ifdim \ht\@currbox>\textheight + \ht\@currbox \textheight + \fi + \global \count\@currbox \tw@ + \@tempdima -\ht\@currbox + \advance \@tempdima -\dbltextfloatsep + \global \advance \@colht \@tempdima + \ifx \@dbltoplist \@empty + \else + \@latexerr{Float(s) lost}\@ehb + \let \@dbltoplist \@empty + \fi + \@cons \@dbltoplist \@currbox + \global \@dbltopnum \m@ne + \ifdim \@colht<2.5\baselineskip + \@latex@warning@no@line {Optional argument of \noexpand\twocolumn + too tall on page \thepage}% + \@emptycol + \if@firstcolumn + \else + \@emptycol + \fi + \else + \global \vsize \@colht + \global \@colroom \@colht + \@floatplacement + \fi +} +\gdef\@specialoutput{% + \ifnum \outputpenalty>-\@Mii + \@doclearpage + \else + \ifnum \outputpenalty<-\@Miii + \ifnum \outputpenalty<-\@MM \deadcycles \z@ \fi + \global \setbox\@holdpg \vbox {\unvbox\@cclv}% + \else + \global \setbox\@holdpg \vbox{% + \unvbox\@holdpg + \unvbox\@cclv + \setbox\@tempboxa \lastbox + \unskip + }% + \@pagedp \dp\@holdpg + \@pageht \ht\@holdpg + \unvbox \@holdpg + \@next\@currbox\@currlist{% + \ifnum \count\@currbox>\z@ + \advance \@pageht \@pagedp + \ifvoid\footins \else + \advance \@pageht \ht\footins + \advance \@pageht \skip\footins + \advance \@pageht \dp\footins + \fi + \ifvbox \@kludgeins + \ifdim \wd\@kludgeins=\z@ + \advance \@pageht \ht\@kludgeins + \fi + \fi + \@reinserts + \@addtocurcol + \else + \@reinserts + \@addmarginpar + \fi + }\@latexbug + \ifnum \outputpenalty<\z@ + \if@nobreak + \nobreak + \else + \addpenalty \interlinepenalty + \fi + \fi + \fi + \fi +} +\def \@doclearpage {% + \ifvoid\footins + \setbox\@tempboxa\vsplit\@cclv to\z@ \unvbox\@tempboxa + \setbox\@tempboxa\box\@cclv + \xdef\@deferlist{\@toplist\@botlist\@deferlist}% + \global \let \@toplist \@empty + \global \let \@botlist \@empty + \global \@colroom \@colht + \ifx \@currlist\@empty + \else + \@latexerr{Float(s) lost}\@ehb + \global \let \@currlist \@empty + \fi + \@makefcolumn\@deferlist + \@whilesw\if@fcolmade \fi{\@opcol\@makefcolumn\@deferlist}% + \if@twocolumn + \if@firstcolumn + \xdef\@dbldeferlist{\@dbltoplist\@dbldeferlist}% + \global \let \@dbltoplist \@empty + \global \@colht \textheight + \begingroup + \@dblfloatplacement + \@makefcolumn\@dbldeferlist + \@whilesw\if@fcolmade \fi{\@outputpage + \@makefcolumn\@dbldeferlist}% + \endgroup + \else + \GAL@ignore@next@galley@vbox{}\clearpage + \fi + \fi + \else + \setbox\@cclv\vbox{\box\@cclv\vfil}% + \@makecol\@opcol + \clearpage + \fi +} +\gdef \@makecol {% + \ifvoid\footins + \setbox\@outputbox \box\@cclv + \else + \setbox\@outputbox \vbox {% + \boxmaxdepth \@maxdepth + \@tempdima\dp\@cclv + \unvbox \@cclv + \vskip-\@tempdima + \vskip \skip\footins + \color@begingroup + \normalcolor + \footnoterule + \unvbox \footins + \color@endgroup + }% + \fi + \xdef\@freelist{\@freelist\@midlist}% + \global \let \@midlist \@empty + \@combinefloats + \ifvbox\@kludgeins + \@makespecialcolbox + \else + \setbox\@outputbox \vbox to\@colht {% + \@texttop + \dimen@ \dp\@outputbox + \unvbox \@outputbox + \vskip -\dimen@ + \@textbottom + }% + \fi + \global \maxdepth \@maxdepth +} +\gdef \@makespecialcolbox {% + \setbox\@outputbox \vbox {% + \@texttop + \dimen@ \dp\@outputbox + \unvbox\@outputbox + \vskip-\dimen@ + }% + \@tempdima \@colht + \ifdim \wd\@kludgeins>\z@ + \advance \@tempdima -\ht\@outputbox + \advance \@tempdima \pageshrink + \setbox\@outputbox \vbox to \@colht {% + \unvbox\@outputbox + \vskip \@tempdima + \@textbottom + }% + \else + \advance \@tempdima -\ht\@kludgeins + \setbox \@outputbox \vbox to \@colht {% + \GAL@ignore@next@galley@vbox to \@tempdima {% + \unvbox\@outputbox + \@textbottom}% + \vss}% + \fi + {\setbox \@tempboxa \box \@kludgeins}% +} +\def\@outputpage{% +\begingroup % the \endgroup is put in by \aftergroup + \@resetactivechars + \@parboxrestore + \let \protect \noexpand % <- this moved after parboxrestore!!!! + \shipout \vbox{% + \set@typeset@protect + \aftergroup \endgroup + \aftergroup \set@typeset@protect + % correct? or just restore by ending + % the group? + \if@specialpage + \global\@specialpagefalse\@nameuse{ps@\@specialstyle}% + \fi + \if@twoside + \ifodd\count\z@ \let\@thehead\@oddhead \let\@thefoot\@oddfoot + \let\@themargin\oddsidemargin + \else \let\@thehead\@evenhead + \let\@thefoot\@evenfoot \let\@themargin\evensidemargin + \fi + \fi + \reset@font + \normalsize + \normalsfcodes + \let\label\@gobble + \let\index\@gobble + \let\glossary\@gobble + \baselineskip\z@skip \lineskip\z@skip \lineskiplimit\z@ + \@begindvi + \vskip \topmargin + \moveright\@themargin \vbox {% + \setbox\@tempboxa \vbox to\headheight{% + \vfil + \color@hbox + \normalcolor + \hb@xt@\textwidth{\@thehead}% + \color@endbox + }% %% 22 Feb 87 + \dp\@tempboxa \z@ + \box\@tempboxa + \vskip \headsep + \box\@outputbox + \baselineskip \footskip + \color@hbox + \normalcolor + \hb@xt@\textwidth{\@thefoot}% + \color@endbox + }% + }% + \global \@colht \textheight + \stepcounter{page}% + \let\firstmark\botmark +} +\def \@cflt{% + \let \@elt \@comflelt + \setbox\@tempboxa \vbox{}% + \@toplist + \setbox\@outputbox \vbox{% + \boxmaxdepth \maxdepth + \unvbox\@tempboxa + \vskip -\floatsep + \topfigrule + \vskip \textfloatsep + \unvbox\@outputbox + }% + \let\@elt\relax + \xdef\@freelist{\@freelist\@toplist}% + \global\let\@toplist\@empty +} +\def\@comflelt#1{\setbox\@tempboxa + \vbox{\unvbox\@tempboxa\box #1\vskip\floatsep}} +\def \@combinedblfloats{% + \ifx \@dbltoplist \@empty + \else + \setbox\@tempboxa \vbox{}% + \let \@elt \@comdblflelt + \@dbltoplist + \let \@elt \relax + \xdef \@freelist {\@freelist\@dbltoplist}% + \global\let \@dbltoplist \@empty + \setbox\@outputbox \vbox to\textheight + {%\boxmaxdepth\maxdepth %% probably not needed, CAR + \unvbox\@tempboxa\vskip-\dblfloatsep + \ifnum \@dbltopnum>\m@ne + \dblfigrule + \fi + \vskip \dbltextfloatsep + \box\@outputbox + }% + \fi +} +\def\@vtryfc #1{% + \global\setbox\@outputbox\vbox{}% + \let\@elt\@wtryfc + \@flsucceed + \global\setbox\@outputbox \vbox to\@colht{% + \vskip \@fptop + \vskip -\@fpsep + \unvbox \@outputbox + \vskip \@fpbot}% + \let\@elt\relax + \xdef #1{\@failedlist\@flfail}% + \xdef\@freelist{\@freelist\@flsucceed}} +\def\@wtryfc #1{% + \global\setbox\@outputbox\vbox{% + \unvbox\@outputbox + \vskip\@fpsep + \box #1}} +\def\@addmarginpar{\@next\@marbox\@currlist{\@cons\@freelist\@marbox + \@cons\@freelist\@currbox}\@latexbug\@tempcnta\@ne + \if@twocolumn + \if@firstcolumn \@tempcnta\m@ne \fi + \else + \if@mparswitch + \ifodd\c@page \else\@tempcnta\m@ne \fi + \fi + \if@reversemargin \@tempcnta -\@tempcnta \fi + \fi + \ifnum\@tempcnta <\z@ \global\setbox\@marbox\box\@currbox \fi + \@tempdima\@mparbottom + \advance\@tempdima -\@pageht + \advance\@tempdima\ht\@marbox + \ifdim\@tempdima >\z@ + \@latex@warning@no@line {Marginpar on page \thepage\space moved}% + \else + \@tempdima\z@ + \fi + \global\@mparbottom\@pageht + \global\advance\@mparbottom\@tempdima + \global\advance\@mparbottom\dp\@marbox + \global\advance\@mparbottom\marginparpush + \advance\@tempdima -\ht\@marbox + \global\setbox \@marbox + \vbox {\vskip \@tempdima + \box \@marbox}% + \global \ht\@marbox \z@ + \global \dp\@marbox \z@ + \kern -\@pagedp + \nointerlineskip + \hb@xt@\columnwidth + {\ifnum \@tempcnta >\z@ + \hskip\columnwidth \hskip\marginparsep + \else + \hskip -\marginparsep \hskip -\marginparwidth + \fi + \box\@marbox \hss}% + \nointerlineskip + \hbox{\vrule \@height\z@ \@width\z@ \@depth\@pagedp}} +\def\@outputdblcol{% + \if@firstcolumn + \global \@firstcolumnfalse + \global \setbox\@leftcolumn \box\@outputbox + \else + \global \@firstcolumntrue + \setbox\@outputbox \vbox {% + \hb@xt@\textwidth {% + \hb@xt@\columnwidth {% + \box\@leftcolumn \hss}% + \hfil + \vrule \@width\columnseprule + \hfil + \hb@xt@\columnwidth {% + \box\@outputbox \hss}% + }% + }% + \@combinedblfloats + \@outputpage + \begingroup + \@dblfloatplacement + \@startdblcolumn + \@whilesw\if@fcolmade \fi + {\@outputpage + \@startdblcolumn}% + \endgroup + \fi +} + + + +% \end{macrocode} +% +% \begin{macrocode} +\catcode`\:=12\relax +\endinput +% \end{macrocode} +% +% \begin{macrocode} +%</package> +% \end{macrocode} +% +% +% \Finale +% diff --git a/Master/texmf-dist/source/latex3/galley/galley2.ins b/Master/texmf-dist/source/latex3/galley/galley2.ins new file mode 100644 index 00000000000..f44ac61196b --- /dev/null +++ b/Master/texmf-dist/source/latex3/galley/galley2.ins @@ -0,0 +1,14 @@ +\input docstrip +\keepsilent +\askforoverwritefalse + +\preamble + +\endpreamble + +\generate{% + \file{galley2.sty}{\from{galley2.dtx}{package,trace}} + \file{xhj.sty}{\from{xhj.dtx}{package,trace}} + } + +\endbatchfile diff --git a/Master/texmf-dist/source/latex3/galley/xhj.dtx b/Master/texmf-dist/source/latex3/galley/xhj.dtx new file mode 100644 index 00000000000..56f245782c9 --- /dev/null +++ b/Master/texmf-dist/source/latex3/galley/xhj.dtx @@ -0,0 +1,1924 @@ +% \iffalse +%% +%% $Header: /usr3/users/latex3/design/consolidation/CURRENT/RCS/xhj.dtx,v 1.8 2000/01/14 15:24:24 latex3 Exp $ +%% +%% (C) Copyright 1999-2000 Frank Mittelbach +%% All rights reserved. +%% +%% Not for general distribution. In its present form it is not allowed +%% to put this package onto CD or an archive without consulting the +%% the authors. +%% +%% This module only works in conjunction with the galley2 module. +%% +%<*dtx> + \ProvidesFile{xhj.dtx} +%</dtx> +%<package>\NeedsTeXFormat{LaTeX2e} +%<package>\ProvidesPackage{xhj} +%<driver>\ProvidesFile{xhj.drv} +% \fi +% \ProvidesFile{xhj.dtx} + [2000/01/14 v0.3c hyphenation & justification] +% +% \iffalse +%<*driver> + \documentclass{ltxdoc} +%\usepackage{xlists-samples} +%\makeatletter \let\GAL@typeout\@gobble \let\GAL@show@datastructure\@gobble +% \usepackage{ldcdoc} + +\newcommand\LaTeXplus{\LaTeXe$*$} + +\newcommand\DelayEvaluation{\texttt{\textbackslash DelayEvalution} + \ignorespaces} +\newcommand\fontwordspace{\texttt{\textbackslash fontwordspace}} +\newcommand\fontextraspace{\texttt{\textbackslash fontextraspace}} + + +% next three definitions are big hacks to run the file +% without the above packages +% +\newcommand\NoValue{\texttt{\textbackslash NoValue}} + +\makeatletter +\newenvironment{TemplateInterfaceDescription}[1] + {\subsection{The Template Type `#1'}% + \begingroup + \@beginparpenalty\@M + \description + \def\TemplateArgument##1##2{\item[Arg: ##1]##2\par}% + \def\TemplateSemantics{\enddescription\endgroup + \subsubsection*{Semantics:}}% + } + {\par\bigskip} + +\newenvironment{TemplateDescription}[2] + {\subsection{The Template `#2' (type #1)}% + \subsubsection*{Attributes:}% + \begingroup + \@beginparpenalty\@M + \description + \def\TemplateKey##1##2##3##4{\item[##1 (##2)]##3% + \ifx\TemplateKey##4\TemplateKey\else +% \hskip0ptplus3em\penalty-500\hskip 0pt plus 1filll Default:~##4% + \hfill\penalty500\hbox{}\hfill Default:~##4% + \nobreak\hskip-\parfillskip\hskip0pt\relax + \fi + \par}% + \def\TemplateSemantics{\enddescription\endgroup + \subsubsection*{Semantics \& Comments:}}% + } + {\par\bigskip} + +\newenvironment{InstanceDescription}[4][xxxxxxxxxxxxxxx] + {\subsubsection{The Instance `#3' (template #2/#4)}% + \subsubsection*{Attribute values:}% + \begingroup + \@beginparpenalty\@M + \def\InstanceKey##1##2{\>\textbf{##1}\>##2\\}% + \def\InstanceSemantics{\endtabbing\endgroup + \vskip-30pt\vskip0pt + \subsubsection*{Layout description \& Comments:}}% + \tabbing + xxxx\=#1\=\kill + } + {\par\bigskip} + +\makeatother + +\newcommand\key[1]{\textbf{#1}} + + \begin{document} + \DocInput{xhj.dtx} + \end{document} +%</driver> +% \fi +% +% \CheckSum{298} +% +% \newcommand\subsubsubsection{\paragraph} +% +% \GetFileInfo{xhj.dtx} +% +% \title{The \textsf{h\&j} package\thanks{This file +% has version number \fileversion, last +% revised \filedate.}} +% \author{FMi} +% \date{\filedate} +% \maketitle +% +% \tableofcontents +% +% \bigskip +% +% \begin{abstract} +% This module contains basic templates for interfacing with the +% galley mechanism as set up by the module +% \texttt{galley2}. These templates are intended for class +% designers and are mostly usable out of the box (i.e., this is one +% of the modules where providing a suitable number of default +% instances is probably sensible since they would cover 98\% of all +% usage. In contrast the \texttt{galley2} module contains only +% low-level interfaces for +% direct manipulation of the galley mechanism which are geared +% towards package writers having special needs which are not +% fulfilled by the templates in this module. +% \end{abstract} +% +% +% +% +% \section{Introduction} +% +% In \LaTeXplus{} terminology a galley is a rectangular area which +% receives text and other material filling it from +% top.\footnote{The predominant direction depends on the writing +% system and with extensions to \TeX{} such as Omega there are +% possibilities to define galleys with a different filling direction.} +% The vertically extend of a galley is normally not restricted +% (there are exceptions); instead certain chunks are taken off the top +% of an +% already partially filled galley to form columns or similar areas +% on a page. This process is typically asynchronous but there are ways +% to control or change its behavior. +% +% Examples for galleys are `the main galley', where the continuous +% document data gets formatted into and from which columns and pages are +% constructed, and `vbox galley's, such as the body of a minipage +% environment or the body of a float (in \LaTeXe only---the new float +% mechanism for \LaTeXplus{} will employ horizontally oriented float +% bodies). The latter galleys are typically not being split after +% formatting though there can be exceptions. +% +% Low-level interfaces for setting up such galleys and the way objects +% are formatted into them are provided by the module +% \texttt{galley2}. +% +% \subsection{Formatting layers} +% +% The present module is mainly concerned with the +% formatting of text in such galleys. +% The galley mechanism provides interfaces at four different layers +% some of which can be manipulated through the templates provided by +% this module. +% +% \subsubsection{Outer galley dimensions} +% +% In the bottom layer the external dimensions of a galley are +% fixed. In most cases only the horizontal dimension is defined while +% the vertical dimension (i.e., the filling direction) remains +% unspecified. These dimensions are fixed when initiating a new galley, +% using low-level functions, and are not modifiable. The horizontal +% overall width of the current galley is available for inspection in +% the register |\hsize|.\footnote{This is going to change once there +% is a final concept for handling this part of the interface, e.g., +% the relation of \texttt{\textbackslash hsize}, +% \texttt{\textbackslash columnwidth}, and \texttt{\textbackslash +% textwidth}. The latter are actually parameters of the text-page and +% should probably not be handled as it is done in \LaTeXe{}, i.e., by +% also using \texttt{\textbackslash columnwidth} as a measure for the +% current galley width. Perhaps one should introduce a +% \texttt{\textbackslash galleywidth} parameter instead of using +% \texttt{\textbackslash hsize}.} +% There are no templates that only set variable of this layer, though +% higher level +% templates (e.g., a template for providing minipage functionality) +% will of course address this part of the galley mechanism. +% +% +% \subsubsection{Inner galley dimensions} +% +% The second layer defines the inner horizontal galley dimensions of +% the galley, i.e., the measure used for paragraph text and its +% positioning within the galley. The current measure of the galley is +% available for inspection in the register |\linewidth| and the +% indentation from the left outer margin is available in the register +% |\@totalleftmargin|.\footnote{The two registers are already +% available in \LaTeXe{} and their names have been retained to make +% it easier to use a mixture of old and new code. However at some +% point the interface should be made more uniform by either providing +% two user accessible or two user inaccessible names.} +% +% This layer can (and should) be manipulated by higher-level templates +% through template instances of the type `measure'. These templates +% make long-term changes. +% +% +% +% +% \subsubsection{Paragraph shapes} +% +% The third layer defines the paragraph shape within the measure as +% provided by the second layer. In the absence of any specification +% for that layer the paragraph shape used will be that of a +% rectangular area of the width of the current measure. +% +% For this layer we are restricted by the mechanisms offered by +% \TeX{}. This means that it is possible to define particular +% paragraph shapes such as cutouts only from the top of a paragraph +% but not relative to its bottom. +% +% This layer can (and should) be manipulated by higher-level templates +% through template instances of the type `pshape'. Templates in this +% layer typically make short-term changes only (i.e. applicable only +% to the upcoming paragraph), however templates for long-term changes +% are also permissable though none are provided right now. +% +% A future implementation of the \texttt{galley2} module is probably +% going to support pshapes spanning several paragraphs, however at the +% moment pshapes apply per paragraph only. +% +% +% \subsubsection{Text formatting within the paragraph shape} +% +% The forth (and currently final) layer deals with the paragraph +% formatting aspects such as hyphenation and justification (h\&j which +% gave the current module its name). +% +% There are several template types in this layer: `hj' is a type that +% sets all aspects of h\&j in a single template whereas the types +% `justification', `linebreak', and `hyphenation' deal with individual +% aspects. +% +% \subsection{Open issues} +% +% Several but right now most of them are discussed when describing the +% interfaces in more details below. +% +% \begin{itemize} +% \item +% The model attempts a proper separation between paragraph shapes +% (layer three) and justification (part of layer four). However, due +% to the way \TeX{} works certain paragraph shapes can only be +% accomplished by using the parameters that are normally reserved +% for justification (an example would be the famous shape used by +% |\@dottedcontentsline|, i.e., a rectangular shape with the first +% line sticking out to the left and the last line sticking out to +% the right). How to integrate such shapes on layer three needs some +% more thought. +% \item +% What does the argument to the `measure' type really signal? Always +% a relative value (to current |\@totalleftmargin|), always an +% absolute value, or a value depending on what the template makes +% out of it? Perhaps this is not that important as one can't expect +% any such document supplied value be correct for different +% designs---or is this the wrong idea? At the moment I make +% it always be a relative change to |\@totalleftmargin| independent +% of the type of template being used. +% \end{itemize} +% +% +% \section{Interfaces} +% +% \begin{TemplateInterfaceDescription}{measure} +% +% \TemplateArgument{1} +% {Indentation of the left margin overwriting the default change +% or \NoValue{} in which case the value from the template +% is used. If provide the value is \emph{always} interpreted as +% being relative to the current indentation in the galley.} +% +% \TemplateSemantics +% This template type defines the basic measure of the galley, +% i.e., the width of the lines (|\linewidth|) and their +% indentation from the left (|\@totalleftmargin|). +% +% Each template of this type has to set the above parameters +% locally to their correct value.\footnote{That part of the +% implementation in \texttt{galley2.dtx} probably needs changing.} +% +% The templates can (and in most cases do) refer to an +% external\footnote{Again that is something which may not survive +% for long. It might very well be the case that all these +% parameters need to be added to the main galley data structures.} +% parameter holding the overall nominal width of the current +% galley (|\hsize|). However it is perfectly admissible that the +% template parameters are set in a way that |\@totalleftmargin| + +% |\linewidth| exceeds this nominal width (the galley mechanism +% provides low-level calls that allow for this without producing +% an error. This way paragraphs in a galley may stick out on +% either side if desired. +% +% One could think of making also the right margin being user +% over-writable or providing something like a boolean to modify the +% meaning of the template argument---suggestions/applications +% needed.\footnote{Think!} +% +% Templates of this type make long-term changes, i.e., their +% settings remain until the next occurence of an instance of this +% type or until the galley ends or its previous settings are +% restored. As remarked in the introduction +% there is a need for saving and restoring the settings of this +% particular part of the mechanism individually. +% +% \end{TemplateInterfaceDescription} +% +% +% \begin{TemplateDescription}{measure}{relative} +% +% \TemplateKey{leftmargin}{l} +% {Additional indentation on the left for all lines} +% {none} +% +% \TemplateKey{rightmargin}{l} +% {Additional indentation on the right for all lines} +% {none} +% +% \TemplateSemantics +% This is the main template needed for defining vertically oriented +% lists and the like (at least if they are supposed to allow for +% nesting). +% +% \end{TemplateDescription} +% +% +% +% \begin{TemplateDescription}{measure}{absolute} +% +% \TemplateKey{leftmargin}{l} +% {Indentation on the left for all lines} +% {none} +% +% \TemplateKey{rightmargin}{l} +% {Indentation on the right for all lines measured from the +% nominal width of the galley (i.e., \texttt{\textbackslash +% hsize})} +% {none} +% +% \TemplateSemantics +% This template can be used in cases where one wishes to ignore +% any already existing indentations. Whether or not this has real +% applications remains to be seen. +% +% \end{TemplateDescription} +% +% +% +% +% +% \begin{TemplateInterfaceDescription}{pshape} +% +% \TemplateArgument{none} +% {---} +% +% \TemplateSemantics +% Templates of this type define the shape of the paragraph within +% the given measure of the galley, e.g., whether it has some +% special form such as a cutout one or the other side. +% +% Typically they define a shape only for the next paragraph, +% however templates that provide long term changes are also allowed. +% +% Since such special forms often require that all lines of a +% paragraph are kept together on a page these templates typically +% also define whether or not pages breaks within a paragraph are +% allowed. +% +% An interesting question is whether or not such templates should +% set (or inhibit) paragraph indentations via a template key. After +% all with cutouts on the top left such indentations are usually +% not desired.\footnote{Right now only justification templates set +% indentation but perhaps they should not, or both should, or what?} +% +% \end{TemplateInterfaceDescription} +% +% +% +% \begin{TemplateDescription}{pshape}{cutout} +% +% \TemplateKey{no-page-break-boolean}{s} +% {If true the upcoming paragraph will not be broken across a +% page. If false the breakability of the upcoming paragraph +% depends on other elements in the galley, i.e., it might still +% be forbidden to break.} +% {false} +% +% \TemplateKey{left-side-boolean}{s} +% {If true, the cutout will appear on the left otherwise it will +% appear on the right.} +% {true} +% +% \TemplateKey{normal-lines-num}{c} +% {Number of lines before the cutoff starts.} +% {0} +% +% \TemplateKey{parshape-list}{f0} +% {Comma separated list of dimensions denoting the horizontal +% size of the cutout for successive lines. If the paragraph +% contains more lines than the sum of \key{normal-lines-num} and +% the number of elements in this list then the remaining lines +% are all normal lines (i.e., cutout width 0pt) again.} +% {none} +% +% \TemplateSemantics +% This template is used to define a fixed cutout on one or the +% other side of a paragraph. It applies to the next paragraph +% only. +% +% The \key{normal-lines-num} is for convenience +% only. Alternatively one could prepend a suitable number of +% `\texttt{0pt,}'s to \key{parshape-list}. +% +% \end{TemplateDescription} +% +% +% \begin{InstanceDescription}[\textbf{no-page-break-boolean}xx] +% {pshape}{staggered}{cutout} +% +% \InstanceKey{no-page-break-boolean}{true} +% +% \InstanceKey{left-side-boolean}{true} +% +% \InstanceKey{normal-lines-num}{1} +% +% \InstanceKey{parshape-list}{20pt,40pt,60pt} +% +% \InstanceSemantics +% This instance will indent each line by an additional 20pt (up to +% the fourth line). A possible application would be a heading text +% (with a maximum number of four lines). +% This should then perhaps be combined with a special justification +% instance which does ragged right except for the last line which is +% set to full measure. +% +% \end{InstanceDescription} +% +% +% \begin{InstanceDescription}[\textbf{no-page-break-boolean}xx] +% {pshape}{ltriangle}{cutout} +% +% \InstanceKey{no-page-break-boolean}{true} +% +% \InstanceKey{left-side-boolean}{true} +% +% \InstanceKey{normal-lines-num}{0} +% +% \InstanceKey{parshape-list}{60pt,40pt,20pt} +% +% \InstanceSemantics +% This instance will produce a triangle cutout on the left upper +% corner of a paragraph. Could, for example, used together with an +% unusual heading layout~\ldots +% +% \end{InstanceDescription} +% +% +% \begin{InstanceDescription}[\textbf{no-page-break-boolean}xx] +% {pshape}{rectangle}{cutout} +% +% \InstanceKey{no-page-break-boolean}{false} +% +% \InstanceKey{left-side-boolean}{true} +% +% \InstanceKey{normal-lines-num}{0} +% +% \InstanceKey{parshape-list}{} +% +% \InstanceSemantics +% This instance can be used when a pshape is required but one just +% wants a standard regular paragraph area.\footnote{Using the cutoff +% template for this is overkill; at some point in the future this +% instance should be reimplemented.} +% +% \end{InstanceDescription} +% +% +% +% +% \begin{TemplateInterfaceDescription}{justification} +% +% \TemplateArgument{none} +% {---} +% +% \TemplateSemantics +% Templates of this type define how a paragraph text is formatted +% within the boundaries of a general paragraph shape (as defined +% through a measure (and perhaps additionally a pshape) +% template). More exactly they define whether or +% not the text should be justified at both sides or only at one +% side and in the latter case how much raggedness is desired, +% etc. See the instance examples for more details. +% +% The \key{linefillskip} in the templates below is worth +% mentioning. It defines a stretchable space that is used by +% commands that end a line prematurely in the middle of a +% paragraph, e.g., |\\| or |\newline|. In most cases what is +% needed is to fill the line with white space in exactly the same +% way as \TeX's |\parfillskip| parameter works (which is also the +% reason for the chosen default). However, for special instances +% this is not appropriate. Important is that any template of this +% type provides this key or rather provides a mechanism to +% correctly feeds the underlying data structure. +% +% Originally there have been different template types for setting +% the paragraph specs for all following paragraphs and for only +% the next one but this was combined into a single type. Whether +% or not this is the right approach remains to be seen. +% +% \end{TemplateInterfaceDescription} +% +% +% \begin{TemplateDescription}{justification}{std} +% +% \TemplateKey{startskip}{l} +% {Stretchable space added to the left of the first line in a +% paragraph (in addition to \key{leftskip}).} +% {0pt} +% +% \TemplateKey{leftskip}{l} +% {Stretchable space added to the left of every line in a +% paragraph.} +% {\texttt{\textbackslash leftskip}} +% +% \TemplateKey{rightskip}{l} +% {Stretchable space added to the right of every line in a +% paragraph.} +% {\texttt{\textbackslash rightskip}} +% +% \TemplateKey{parfillskip}{l} +% {Stretchable space added to the right of the last line in a +% paragraph (in addition to \key{rightskip}).} +% {\texttt{\textbackslash parfillskip}} +% +% \TemplateKey{spaceskip}{l} +% {Stretchable space to use between words if non-zero. Otherwise +% size for space between words is taken from the current font +% metrics.} +% {\texttt{\textbackslash spaceskip}} +% +% \TemplateKey{xspaceskip}{l} +% {Extra space to use after periods etc.~(in certain situations)} +% {\texttt{\textbackslash xspaceskip}} +% +% \TemplateKey{linefillskip}{l} +% {Space to add at the point where some command requests a +% ``carriage-return line-feed'' in the middle of a paragraph, +% e.g., the \LaTeX{} command \texttt{\textbackslash newline}.} +% {value of \key{parfillskip}} +% +% \TemplateKey{parindent}{l} +% {Non-stretchable space to be added at the beginning of a +% paragraph.} +% {\texttt{\textbackslash parindent}} +% +% \TemplateSemantics +% +% This template sets the paragraph justification for all following +% paragraph (within the normal scope, i.e., until the end of the +% galley or a new specification). +% +% The key names for this template are derived from the original +% \TeX{} primitives whenever applicable. Perhaps this is a bad +% idea as \key{startskip} and \key{parfillskip} do not go well +% together. +% +% The defaults for most keys are actually the command names of the +% original \TeX{} primitives. The intention is that something like +% \key{parindent} could be externally provided by setting +% |\parindent| for all instances which do not explicitly set it to +% some value (e.g., to 0pt in instances where paragraph +% indentation is not really appropriate). Whether this is a good +% idea remains to be seen, this probably need some radically +% different default concept. +% +% \end{TemplateDescription} +% +% +% +% +% \begin{InstanceDescription}{justification}{default}{std} +% +% \InstanceKey{leftskip}{0pt} +% +% \InstanceKey{rightskip}{0pt} +% +% \InstanceKey{parfillskip}{0pt plus 1fil} +% +% \InstanceSemantics +% +% This instance is slightly special as it is internally called +% whenever a new galley is instantiated, e.g., in a minipage. Thus +% it must be defined by class. The setting above is the same as for +% the adjust instance, but of course a class might wish to change +% this, e.g., if the desired layout requires ragged right setting by +% default. +% +% \end{InstanceDescription} +% +% +% +% +% +% +% \begin{InstanceDescription}{justification}{adjust}{std} +% +% \InstanceKey{leftskip}{0pt} +% +% \InstanceKey{rightskip}{0pt} +% +% \InstanceKey{parfillskip}{0pt plus 1fil} +% +% \InstanceSemantics +% +% This instance provides the standard justified paragraph setting, +% i.e., every line is justified at both sides and the final line +% is set flush left. Paragraph indentation is not set, i.e. will +% be whatever the value of |\parindent| is. +% +% \end{InstanceDescription} +% +% +% +% +% +% \begin{InstanceDescription}{justification}{adjust2}{std} +% +% \InstanceKey{leftskip}{0pt} +% +% \InstanceKey{rightskip}{0pt} +% +% \InstanceKey{parfillskip}{20pt plus 1fil} +% +% \InstanceSemantics +% +% This is a variation of the previous instance: the difference is +% that the last line of a paragraph can never be completely +% filled. In some sense this defines a paragraph indent at the +% end. +% +% Further variations are possible, e.g., one can ensure that the +% last line always contains at least a certain amount of space. +% +% \end{InstanceDescription} +% +% +% +% +% +% \begin{InstanceDescription}{justification}{center}{std} +% +% \InstanceKey{parindent}{0pt} +% +% \InstanceKey{leftskip}{0pt} +% +% \InstanceKey{rightskip}{0pt} +% +% \InstanceKey{parfillskip}{0pt} +% +% \InstanceSemantics +% +% This instance is an example of a layout where the paragraph +% indent is explicitly set to zero to ensure that all lines are +% properly centered. Of course even with centered lines somebody +% could think of having a paragraph indentation: if so define a +% variation of the this instance. +% +% \end{InstanceDescription} +% +% +% +% +% \begin{InstanceDescription}{justification}{centermiddle}{std} +% +% \InstanceKey{parindent}{0pt} +% +% \InstanceKey{startskip}{-36pt plus -1fill} +% +% \InstanceKey{leftskip}{36pt plus 1fill} +% +% \InstanceKey{rightskip}{36pt plus 1fill} +% +% \InstanceKey{parfillskip}{-36pt plus -1fill} +% +% \InstanceSemantics +% +% A specialized instance that sets the first line of the paragraph +% flush left, the last line flush right and the intermediate lines +% centered with at least one centimeter space at each +% side. Possible application could be two or three line headings. +% +% \end{InstanceDescription} +% +% +% +% +% +% \begin{InstanceDescription}{justification}{raggedright}{std} +% +% \InstanceKey{startskip}{0pt} +% +% \InstanceKey{leftskip}{0pt} +% +% \InstanceKey{rightskip}{\DelayEvaluation 0pt plus 2em} +% +% \InstanceKey{parfillskip}{0pt plus 1fil} +% +% \InstanceKey{spaceskip}{\DelayEvaluation \fontwordspace} +% +% \InstanceKey{xspaceskip}{\DelayEvaluation +% \fontwordspace + \fontextraspace} +% +% \InstanceSemantics +% +% This interesting instance defines a ragged right setting which +% allows for hyphenation in case the raggedness would otherwise be +% too extreme (2em in the current font are considered okay anything +% in addition will start making the line bad as far as \TeX's +% paragraph algorithm is concerned so \TeX{} will consider +% hyphenation in such cases. +% +% An unjustified setting should always contain identical word +% spaces. Since we restrict the stretchability at the right end (it is +% of the same strength as the default word space stretchability), we +% have to ensure that the word spaces to not stretch or shrink at +% all. This is achieved by forcing the \key{spaceskip} to the +% normal font word space (without any stretch). +% +% \end{InstanceDescription} +% +% +% +% +% +% +% \begin{InstanceDescription}{justification}{flushleft}{std} +% +% \InstanceKey{startskip}{0pt} +% +% \InstanceKey{leftskip}{0pt} +% +% \InstanceKey{rightskip}{0pt plus 1fill} +% +% \InstanceKey{parfillskip}{0pt plus 1fill} +% +% \InstanceSemantics +% +% In contrast to the previous instance, this instance allows for +% arbitrary short lines, i.e., a paragraph set using this instance +% will never get hyphenated unless it contains words longer than +% the line measure. +% +% As all the stretchable space will appear at the right margin +% there in no point in artifically modify the word spaces as they +% will be set at their natural size anyway. +% +% \end{InstanceDescription} +% +% +% +% +% +% \begin{InstanceDescription}{justification}{raggedleft}{std} +% +% \InstanceKey{startskip}{0pt} +% +% \InstanceKey{leftskip}{\DelayEvaluation 0pt plus 2em} +% +% \InstanceKey{rightskip}{0pt} +% +% \InstanceKey{parfillskip}{0pt} +% +% \InstanceKey{spaceskip}{\DelayEvaluation \fontwordspace} +% +% \InstanceKey{xspaceskip}{\DelayEvaluation +% \fontwordspace + \fontextraspace} +% +% \InstanceSemantics +% +% This instance is the raggedleft counter part to the raggedright +% instance above. +% +% \end{InstanceDescription} +% +% +% +% +% +% \begin{InstanceDescription}{justification}{flushright}{std} +% +% \InstanceKey{startskip}{0pt} +% +% \InstanceKey{leftskip}{0pt plus 1fill} +% +% \InstanceKey{rightskip}{0pt} +% +% \InstanceKey{parfillskip}{0pt} +% +% \InstanceSemantics +% +% And here is the variation which is not using hyphenation unless +% there is absolutely no other alternative. +% +% \end{InstanceDescription} +% +% +% +% \begin{TemplateDescription}{justification}{single} +% +% \TemplateKey{startskip}{l} +% {Stretchable space added to the left of the first line in a +% paragraph (in addition to \key{leftskip}).} +% {0pt} +% +% \TemplateKey{leftskip}{l} +% {Stretchable space added to the left of every line in a +% paragraph.} +% {\texttt{\textbackslash leftskip}} +% +% \TemplateKey{rightskip}{l} +% {Stretchable space added to the right of every line in a +% paragraph.} +% {\texttt{\textbackslash rightskip}} +% +% \TemplateKey{parfillskip}{l} +% {Stretchable space added to the right of the last line in a +% paragraph (in addition to \key{rightskip}).} +% {\texttt{\textbackslash parfillskip}} +% +% \TemplateKey{spaceskip}{l} +% {Stretchable space to use between words if non-zero. Otherwise +% size for space between words is taken from the current font +% metrics.} +% {\texttt{\textbackslash spaceskip}} +% +% \TemplateKey{xspaceskip}{l} +% {Extra space to use after periods etc.~(in certain situations)} +% {\texttt{\textbackslash xspaceskip}} +% +% \TemplateKey{linefillskip}{l} +% {Space to add at the point where some command requests a +% ``carriage-return line-feed'' in the middle of a paragraph, +% e.g., the \LaTeX{} command \texttt{\textbackslash newline}.} +% {value of \key{parfillskip}} +% +% \TemplateKey{parindent}{l} +% {Non-stretchable space to be added at the beginning of a +% paragraph.} +% {\texttt{\textbackslash parindent}} +% +% \TemplateSemantics +% +% This template is exactly the same as the std one, except that it +% applies only to the next paragraph after which the previous +% setting will become active again. For an explanation of the keys +% see the std template description. +% +% It is not clear whether this approach makes much +% sense. See comments below. +% +% \end{TemplateDescription} +% +% +% +% +% +% \begin{InstanceDescription}{justification}{centerfirst}{single} +% +% \InstanceKey{startskip}{0pt plus 2fill} +% +% \InstanceKey{leftskip}{0pt plus -1fill} +% +% \InstanceKey{rightskip}{0pt plus 1fill} +% +% \InstanceKey{parfillskip}{0pt} +% +% \InstanceKey{linefillskip}{0pt} +% +% \InstanceSemantics +% +% This instance centers the first line of a paragraph and sets all +% remaining lines as a solid block (including the last line). This +% is a rather specialized justification method which relies on some +% peculiar features of the \TeX's internal handling of stretchable +% space. It is not possible to control the amount of white space on +% the first line (other than forcing it to be centered) with the +% controls available. Anything further needs manual intervention by +% the user. +% +% In a similar fashion centering of the last line could be achieved +% (by setting \key{parfillskip} rather than \key{startskip}. +% +% \end{InstanceDescription} +% +% +% +% +% +% +% +% \begin{TemplateDescription}{justification}{complex} +% +% \TemplateKey{first-para-justification-setup}{i} +% {Justification setup for the first paragraph of a sequence.} +% {none} +% +% \TemplateKey{other-para-justification-setup}{i} +% {Justification setup for the remaining paragraphs in the sequence} +% {none} +% +% \TemplateSemantics +% +% This template allows to specify a different justification setup +% for the first paragraph of a sequence and its remaining +% paragraphs. Due to the implementation it is currently required +% that the key \key{first-para-justification-setup} receives an +% instance defined through the template `single' or more exactly +% through a template that modifies the justification setup only for +% a single paragraph. Otherwise all paragraphs in the sequence will +% be formatted in the same way (i.e., the second key would have no +% effect). +% +% This is largely due to the fact that the implementation previously +% contained different template types for local and `global' changes +% to the justification.\footnote{Better concept needed! Perhaps the +% coding in galley2 needs changing in this area.} +% +% +% \end{TemplateDescription} +% +% +% +% +% \begin{InstanceDescription}[\textbf{other-para-justification-setup}xx] +% {justification}{centerfirst-adjust}{complex} +% +% \InstanceKey{first-para-justification-setup}{centerfirst} +% +% \InstanceKey{other-para-justification-setup}{adjust} +% +% \InstanceSemantics +% +% This instance is an example for a paragraph justification where +% the first and the remaining paragraphs are handled differently: +% the first paragraph will get a centered first line (with the +% remaining lines being set as a squared block and any additional +% paragraph will be justified. A common use for such a +% layout would be table captions. +% +% \end{InstanceDescription} +% +% +% +% +% +% +% +% +% +% +% \begin{TemplateInterfaceDescription}{hyphenation} +% +% \TemplateArgument{none} +% {---} +% +% \TemplateSemantics +% +% Templates of this type define whether or not hyphenation is +% attempted for upcoming paragraphs in the galley and if hyphenation +% is allowed whether it should be encouraged (to support better +% justification) or whether it should be only used if justification +% would get too bad without it.\footnote{There are a few conceptual +% questions: should templates of this type set anything like +% \key{hyphenpenalty} or would this be better handled in the +% linebreak template type and this template type only be used to set +% hyphenation on/off? In case of the latter is it needed as a +% separate type or should it be added to some other type?} +% +% \end{TemplateInterfaceDescription} +% +% +% \begin{TemplateDescription}{hyphenation}{TeX} +% +% \TemplateKey{uchyph}{c} +% {If positive allow hyphenation of words starting with an +% uppercase letter.} +% {1} +% +% \TemplateKey{hyphenpenalty}{c} +% {} +% {50} +% +% \TemplateKey{exhyphenpenalty}{c} +% {} +% {50} +% +% \TemplateKey{lefthyphenmin}{c} +% {} +% {leave unchanged} +% +% \TemplateKey{righthyphenmin}{c} +% {} +% {leave unchanged} +% +% \TemplateSemantics +% +% Keys are named like the \TeX{} primitives. As I remarked +% earlier, perhaps \key{hyphenpenalty} and \key{exhyphenpenalty} +% should be moved to the linebreak templates. +% +% Also an open question is the keys +% \key{left/righthyphenmin}. Their minimum values are actually a +% feature of the current language or more exactly a feature of the +% hyphenation patterns in force, but on the other hand one can +% increase their values without harm and especially by setting +% them to extremely high values one can disable hyphenation +% altogether. So how should this be handled? +% +% \end{TemplateDescription} +% +% +% +% \begin{TemplateDescription}{hyphenation}{std} +% +% \TemplateKey{hyphen-enable-boolean}{s} +% {If false disables hyphenation} +% {none} +% +% \TemplateKey{hyphen-uppercase-boolean}{s} +% {If positive allows hyphenation of words starting with an +% uppercase letter.} +% {none} +% +% \TemplateKey{hyphen-discourage-boolean}{s} +% {Sets penalties for breaking a line at a discretionary to a +% higher value. Only relevant if \key{hyphen-enable-boolean} is +% set to true.} +% {none} +% +% \TemplateKey{hyphen-encourage-boolean}{s} +% {Sets penalties for breaking a line at a discretionary to a +% higher value. Only relevant if \key{hyphen-enable-boolean} is +% set to true.} +% {none} +% +% \TemplateSemantics +% +% Better or worse than the TeX version? In any case it remains a +% question of whether the line breaking parts should be set in a +% template like this. +% +% \end{TemplateDescription} +% +% +% +% +% +% +% \begin{TemplateInterfaceDescription}{linebreak} +% +% \TemplateArgument{none} +% {---} +% +% \TemplateSemantics +% +% This template type determines the line breaking behavior of the +% \TeX{} machinery, with the exception of whether or not to +% hyphenate (certain) words. It could be considered to moved the +% parameters related to breaking up math formulas to a separate +% type. +% +% \end{TemplateInterfaceDescription} +% +% +% \begin{TemplateDescription}{linebreak}{TeX} +% +% \TemplateKey{pretolerance}{c} +% {Maximum tolerance allowed for individual lines to break the +% paragraph without attempting hyphenation.} +% {100} +% +% \TemplateKey{tolerance}{c} +% {Maximum tolerance allowed for individual lines when breaking a +% paragraph while attempting hyphenation (if this limit can't be +% met \key{emergencystretch} comes into play.} +% {200} +% +% \TemplateKey{linepenalty}{c} +% {Extra penalty charged per line in the paragraph. By making +% this penalty higher \TeX{} will try harder to produce compact +% paragraphs.} +% {10} +% +% \TemplateKey{binoppenalty}{c} +% {Penalty charged if an inline math formula is broken at a +% binary operator.} +% {700} +% +% \TemplateKey{relpenalty}{c} +% {Penalty charged if an inline math formula is broken at a +% relational symbol.} +% {500} +% +% \TemplateKey{hbadness}{c} +% {Boundary that if exceeded will cause \TeX{} to report an +% underfull line.} +% {1000} +% +% \TemplateKey{adjdemerits}{c} +% {Extra demerit charge if two visually incompatible lines follow +% each other.} +% {10000} +% +% \TemplateKey{doublehyphendemerits}{c} +% {Extra demerit charge of two (or more) lines in succession end +% in a hyphen.} +% {10000} +% +% \TemplateKey{finalhyphendemerits}{c} +% {Extra demerit charge if the second last line is hyphenated.} +% {5000} +% +% \TemplateKey{hfuzz}{l} +% {Boundary below overfull lines are not reported.} +% {.1pt} +% +% \TemplateKey{emergencystretch}{l} +% {Complicated --- I write up the explanation at some other day :-)} +% {0pt} +% +% \TemplateSemantics +% Keys are named like the \TeX{} primitives. As I remarked +% earlier, perhaps \key{hyphenpenalty} and \key{exhyphenpenalty} +% from the hyphenation template +% should be moved to the linebreak templates. +% +% +% \end{TemplateDescription} +% +% +% +% +% +% +% \begin{TemplateInterfaceDescription}{hj} +% +% \TemplateArgument{none} +% {---} +% +% \TemplateSemantics +% Often certain combinations of justification, line breaking and +% hyphenation settings are used together. For those case it might +% be desirable to be able to identify these settings with a single +% name. The hj type provides for this. It is supposed to set the +% complete ``micro typography'' setting concerning paragraphs, +% i.e., everything that happens within the outer form as defined by +% the measure and/or pshape templates. +% +% Whether this template type is actually needed remains to be +% seen. Clearly everywhere where it gets applied one could apply +% individually templates of type justification, linebreak, and +% hyphenation. +% +% Right now the low-level galley interface uses an instance of this +% type (with the name ``default'') to initialize a new +% galley. +% +% \end{TemplateInterfaceDescription} +% +% +% \begin{TemplateDescription}{hj}{std} +% +% \TemplateKey{justification-setup}{i} +% {Instance specifying the justification used.} +% {\texttt{default}} +% +% \TemplateKey{linebreak-setup}{i} +% {Instance specifying the line breaking parameters} +% {\texttt{default}} +% +% \TemplateKey{hyphenation-setup}{i} +% {Instance specifying the hyphenation parameter used.} +% {\texttt{default}} +% +% \TemplateSemantics +% This is the shortcut template as discussed before. One could +% think of other templates that do set the parameters using a large +% number keys (\TeX{} style, for example) --- whether this +% makes sense~\ldots +% +% \end{TemplateDescription} +% +% + +% \begin{InstanceDescription}[\textbf{justification-setup}xx] +% {hj}{default}{std} +% +% \InstanceKey{justification-setup}{default} +% +% \InstanceKey{linebreak-setup}{default} +% +% \InstanceKey{hyphenation-setup}{default} +% +% \InstanceSemantics +% +% This instance is used when initializing new galleys. It is in +% fact slightly faster to run |\UseInstance{hj}{default}| compared +% to three calls to |\UseInstance| for the individual template +% instances.\footnote{This is because we avoid the overhead of +% \texttt{\textbackslash UseInstance} (the keys of type \texttt{i} +% are optimized in this respect.} +% +% \end{InstanceDescription} +%% +% +% +% +% \StopEventually{} +% +% \section{Implementation} +% +% Set up certain defaults including to ignore white space +% within the body of this package. \LaTeXe{} release needs to be +% recent because of changing some bits of the |\parbox| handling below. +% \begin{macrocode} +%<*package> +\NeedsTeXFormat{LaTeX2e}[1998/12/01] +% \end{macrocode} +% +% \begin{macrocode} +\RequirePackage{template,xparse} +% \RequirePackage{galley2} % this is required but needs to + % be loaded afterwards !!!! +% \end{macrocode} +% +% The primitives of the galley mechanism currently have ``:'' in their +% names so\ldots +% \begin{macrocode} +\IgnoreWhiteSpace +\catcode`\:=11\relax +% \end{macrocode} +% +% +% \subsection{Using Font Dimensions} +% +% Some helper functions to access information in a tfm file. +% They do not really belong here but right now we don't have a place +% for them. +% \begin{macro}{\@usefontdimen} +% A shorthand: +% \begin{macrocode} +\def\@usefontdimen#1{\fontdimen#1\font} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\fontslant} +% \begin{macro}{\fontwordspace} +% \begin{macro}{\fontwordspacestretch} +% \begin{macro}{\fontwordspaceshrink} +% \begin{macro}{\fontex} +% \begin{macro}{\fontem} +% \begin{macro}{\fontextraspace} +% The following commands access dimension of the current font, +% e.g., |\fontwordspace| gives the width of a space between words +% in the current font. Typically these commands have to be used +% together with |\DelayEvaluation| so that they are applied at +% runtime rather than during the declaration of template +% instances. +% \begin{macrocode} +\def\fontslant {\@usefontdimen1} +\def\fontwordspace {\@usefontdimen2} +\def\fontwordspacestretch {\@usefontdimen3} +\def\fontwordspaceshrink {\@usefontdimen4} +\def\fontex {\@usefontdimen5} +\def\fontem {\@usefontdimen6} +\def\fontextraspace {\@usefontdimen7} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \subsection{Templates for the second layer} +% +% \subsubsection{The template type `measure'} +% +% The `measure' type takes one argument (left margin or +% |\NoValue|), see discussion above. +% \begin{macrocode} +\DeclareTemplateType{measure}{1} +% \end{macrocode} +% +% \begin{macrocode} +\DeclareTemplate{measure}{absolute}{1}{ + leftmargin =l \leftmargin, + rightmargin =l \rightmargin, + }{ + \DoParameterAssignments +% \end{macrocode} +% +% User provided left margin is always relative to current +% indentation even if template does provide absolute values. +% \begin{macrocode} + \IfNoValueF{#1} { \setlength\leftmargin{ #1 + \@totalleftmargin } } + \setSGPVmeasure:nn \leftmargin {\hsize -\leftmargin -\rightmargin } +} +% \end{macrocode} +% +% +% \begin{macrocode} +\DeclareTemplate{measure}{relative}{1}{ + leftmargin =l \leftmargin, + rightmargin =l \rightmargin, + }{ + \DoParameterAssignments + \IfNoValueF{#1} { \setlength\leftmargin{#1} } + \addSGPVmeasure:nn \leftmargin { -\leftmargin -\rightmargin } +} +% \end{macrocode} +% +% +% +% \subsection{Templates for the third layer} +% +% \subsubsection{The template type `pshape'} +% +% The template type `pshape' right now is mostly an interface to +% \TeX's |\parshape| primitive. This is probably going to be extended. +% +% \begin{macrocode} +\DeclareTemplateType{pshape}{0} +% \end{macrocode} +% +% +% \begin{macrocode} +\DeclareTemplate{pshape}{cutout}{0}{ + no-page-break-boolean =s {\setGALbreak:n {-3}}{}, + left-side-boolean =s {}{\let\shape@side\setGALrightparshape:nnn}, + normal-lines-num =C \pshape@normalines, + parshape-list =f0 \pshape@parshape, + }{ + \let\pshape@normalines\z@ + \let\shape@side\setGALleftparshape:nnn + \DoParameterAssignments + \shape@side \pshape@normalines \z@ \pshape@parshape + } +% \end{macrocode} +% +% +% \begin{macrocode} +\DeclareInstance{pshape}{staggered}{cutout}{ + no-page-break-boolean = true, + normal-lines-num = 1, + parshape-list = { 20pt, 40pt, 60pt }, +} +% \end{macrocode} +% +% +% +% \begin{macrocode} +\DeclareInstance{pshape}{ltriangle}{cutout}{ + no-page-break-boolean = true, + normal-lines-num = 0, + parshape-list = { 60pt, 40pt, 20pt }, +} +% \end{macrocode} +% +% The next instance provides a ``noop'' or ``regular'' pshape instance, +% i.e., one +% that can be applied when a template requests to set up a pshape but +% the standard rectangular is desired (of course using using the +% cutout template for this task is very very inefficient so at some +% point this should be done differently). +% +% \begin{macrocode} +\DeclareInstance{pshape}{rectangle}{cutout}{ + no-page-break-boolean = false, + normal-lines-num = 0, + parshape-list = { }, +} +% \end{macrocode} +% +% +% \subsection{Templates for the forth layer} +% +% \subsubsection{The template type `justification'} +% +% How we justify the text within the measure: +% \begin{macrocode} +\DeclareTemplateType{justification}{0} +% \end{macrocode} +% +% +% \begin{macrocode} +\DeclareTemplate{justification}{single}{0}{ + startskip =L \justification@a , + leftskip =L \justification@b , + rightskip =L \justification@c , + parfillskip =L \justification@d , + spaceskip =L \justification@e , + xspaceskip =L \justification@f , + linefillskip =L \justification@g , + parindent =L \justification@h , + }{ + \def\justification@a{\z@} + \def\justification@b{\leftskip} + \def\justification@c{\rightskip} + \def\justification@d{\parfillskip} + \def\justification@e{\spaceskip} + \def\justification@f{\xspaceskip} + \def\justification@g{\justification@d} + \def\justification@h{\parindent} +% + \DoParameterAssignments +% \end{macrocode} +% Next is a written out form of |\appendtoDGPVthing:nx| (more or less) +% \begin{macrocode} + \xdef \GAL@j@ + {{\justification@a} + {\justification@b} + {\justification@c} + {\justification@d} + {\justification@e} + {\justification@f} + {\justification@g} + {\justification@h} + } + \GAL@prepare@reassign:NN \GAL@j@ \GAL@j@s + } +% \end{macrocode} +% +% +% \begin{macrocode} +\DeclareTemplate{justification}{std}{0}{ + startskip =L \justification@a , + leftskip =L \justification@b , + rightskip =L \justification@c , + parfillskip =L \justification@d , + spaceskip =L \justification@e , + xspaceskip =L \justification@f , + linefillskip =L \justification@g , + parindent =L \justification@h , + } + { + \def\justification@a{\z@} + \def\justification@b{\leftskip} + \def\justification@c{\rightskip} + \def\justification@d{\parfillskip} + \def\justification@e{\spaceskip} + \def\justification@f{\xspaceskip} + \def\justification@g{\justification@d} +% + \def\justification@h{\parindent} + \DoParameterAssignments + \edef \@tempa {\noexpand \setSGPVthing:nn j + {{\justification@a} + {\justification@b} + {\justification@c} + {\justification@d} + {\justification@e} + {\justification@f} + {\justification@g} + {\justification@h} + } + } + \@tempa +% \end{macrocode} +% \begin{macrocode} + \expandafter \setup@paragraph@justification \GAL@j@ +} +% \end{macrocode} +% +% +% \begin{macrocode} +\DeclareTemplate{justification}{complex}{0}{ + first-para-justification-setup =i {justification} + \justification@first, + other-para-justification-setup =i {justification} + \justification@other, + } + { + \DoParameterAssignments +% long term changes first! + \justification@other + \justification@first + } +% \end{macrocode} +% +% +% +% And some instances for testing \ldots +% \begin{macrocode} +\DeclareInstance{justification}{adjust}{std} + {rightskip =0pt, + leftskip =0pt, + startskip =0pt, + parfillskip=\fill +} +% \end{macrocode} +% +% +% +% Another name for the above: +% \begin{macrocode} +\DeclareInstance{justification}{default}{std} + {rightskip =0pt, + leftskip =0pt, + startskip =0pt, + parfillskip=\fill +} +% \end{macrocode} +% +% +% \begin{macrocode} +\DeclareInstance{justification}{adjust2}{std} + {parindent = 0pt, + rightskip = 0pt, + leftskip = 0pt, + startskip = 0pt, + parfillskip= 20pt plus 1fil +} +% \end{macrocode} +% +% +% \begin{macrocode} +\DeclareInstance{justification}{center}{std} + {parindent =0pt, + rightskip =\fill, + leftskip =\fill, + startskip =0pt, + parfillskip=0pt +} +% \end{macrocode} +% +% +% \begin{macrocode} +\DeclareInstance{justification}{centermiddle}{std} + {parindent =0pt, + rightskip =36pt plus 1fill, + leftskip =36pt plus 1fill, + startskip =-36pt plus -1fill, + parfillskip=-36pt plus -1fill, + linefillskip= 0pt, +} +% \end{macrocode} +% +% +% \begin{macrocode} +\DeclareInstance{justification}{raggedright}{std} + {rightskip = \DelayEvaluation 0pt plus 2em, + leftskip = 0pt, + startskip = 0pt, + parfillskip= \fill, + spaceskip = \DelayEvaluation \fontwordspace, + xspaceskip = \DelayEvaluation \fontwordspace + \fontextraspace, +} +% \end{macrocode} +% +% +% \begin{macrocode} +\DeclareInstance{justification}{flushleft}{std} + {rightskip =\fill, + leftskip =0pt, + startskip =0pt, + parfillskip=\fill, +} +% \end{macrocode} +% +% +% \begin{macrocode} +\DeclareInstance{justification}{raggedleft}{std} + {leftskip = \DelayEvaluation 0pt plus 2em, + rightskip = 0pt, + startskip = 0pt, + parfillskip= 0pt, + spaceskip = \DelayEvaluation \fontwordspace, + xspaceskip = \DelayEvaluation \fontwordspace + \fontextraspace, +} +% \end{macrocode} +% +% +% \begin{macrocode} +\DeclareInstance{justification}{flushright}{std} + {leftskip = \fill, + rightskip = 0pt, + startskip = 0pt, + parfillskip= 0pt, +} +% \end{macrocode} +% +% +% \begin{macrocode} +% this does now work: +\DeclareInstance{justification}{centerfirst}{single} + {parindent = 0pt, + rightskip = \fill, + leftskip = -\fill, + parfillskip= 0pt, + startskip = 0pt plus 2fill, + linefillskip= 0pt, +} +% \end{macrocode} +% +% +% \begin{macrocode} +\DeclareInstance{justification}{centerfirst-adjust}{complex} + { first-para-justification-setup = centerfirst, + other-para-justification-setup = adjust + } +% \end{macrocode} +% +% +% +% \subsubsection{The template `linebreak'} +% +% How we attempt to break the paragraph into lines: +% \begin{macrocode} +\DeclareTemplateType{linebreak}{0} +% \end{macrocode} +% +% +% \begin{macrocode} +\DeclareTemplate{linebreak}{TeX}{0}{ + pretolerance =c [100] \pretolerance, + tolerance =c [200] \tolerance, + linepenalty =c [10] \linepenalty, + binoppenalty =c [700] \binoppenalty, + relpenalty =c [500] \relpenalty, + hbadness =c [1000] \hbadness, + adjdemerits =c [10000] \adjdemerits, + doublehyphendemerits =c [10000] \doublehyphendemerits, + finalhyphendemerits =c [5000] \finalhyphendemerits, +% + hfuzz =l [.1pt] \hfuzz, + emergencystretch =l [0pt] \emergencystretch, +% +} + {\DoParameterAssignments +%<*trace> + \GAL@typeout{Now~ changing~ linebreaking} +%</trace> + } +% \end{macrocode} +% +% +% +% +% +% \begin{macrocode} +\DeclareInstance{linebreak}{default}{TeX}{} +\DeclareInstance{linebreak}{fussy}{TeX}{} +\DeclareInstance{linebreak}{sloppy}{TeX} + { + tolerance = 9999, + hfuzz = .5pt, + emergencystretch = \DelayEvaluation 3em, + } +% \end{macrocode} +% +% +% \begin{macro}{\fussy} +% \begin{macro}{\sloppy} +% Two old friends from \LaTeX: +% \begin{macrocode} +\def\fussy {\UseInstance{linebreak}{fussy}} +\def\sloppy{\UseInstance{linebreak}{sloppy}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% +% \subsubsection{The template type `hyphenation'} +% +% How do we handle the question of hyphenation: +% \begin{macrocode} +\DeclareTemplateType{hyphenation}{0} + +\DeclareTemplate{hyphenation}{TeX}{0}{ + uchyph =c [1] \uchyph, + hyphenpenalty =c [50] \hyphenpenalty, + exhyphenpenalty =c [50] \exhyphenpenalty, + lefthyphenmin =c \lefthyphenmin, + righthyphenmin =c \righthyphenmin, +} + {\DoParameterAssignments +%<*trace> + \GAL@typeout{Now~ changing~ hyphenation} +%</trace> + } +% \end{macrocode} +% +% +% +% +% +% \begin{macrocode} +\newcount\@@lefthyphenmin +% \end{macrocode} +% +% +% \begin{macrocode} +\DeclareTemplate{hyphenation}{std}{0}{ + hyphen-enable-boolean =s {\ifnum\@@lefthyphenmin>\z@ + \lefthyphenmin\@@lefthyphenmin + \fi} + {\@@lefthyphenmin\lefthyphenmin + \lefthyphenmin\@M}, + hyphen-uppercase-boolean =s {\uchyph\@ne}{\uchyph\z@}, + hyphen-discourage-boolean=s {\hyphenpenalty\@highpenalty + \exhyphenpenalty\@highpenalty}{}, + hyphen-encourage-boolean =s {\hyphenpenalty\@lowpenalty + \exhyphenpenalty\@lowpenalty}{}, +} + {\DoParameterAssignments +%<*trace> + \GAL@typeout{Now~ changing~ hyphenation} +%</trace> + } +% \end{macrocode} +% +% +% +% +% +% \begin{macrocode} +\DeclareInstance{hyphenation}{default}{TeX} + {} +% \end{macrocode} +% +% +% \begin{macrocode} +\DeclareInstance{hyphenation}{off}{std} + {hyphen-enable-boolean = false} +% \end{macrocode} +% +% +% \begin{macrocode} +\DeclareInstance{hyphenation}{on}{std} + {hyphen-enable-boolean = true} +% \end{macrocode} +% +% +% \begin{macrocode} +\DeclareInstance{hyphenation}{discourage}{std} + {hyphen-enable-boolean = true, + hyphen-discourage-boolean = true} +% +%\ShowInstance{hyphenation}{off} +%\ShowInstance{hyphenation}{discourage} +% \end{macrocode} +% +% +% +% \subsubsection{The template type `hj'} +% +% \begin{macrocode} +\DeclareTemplateType{hj}{0} +% \end{macrocode} +% +% +% \begin{macrocode} +\DeclareTemplate{hj}{std}{0}{ + justification-setup =i {justification} [default] \hj@justification, + linebreak-setup =i {linebreak} [default] \hj@linebreak, + hyphenation-setup =i {hyphenation} [default] \hj@hyphenation, +} + {\DoParameterAssignments + \hj@justification + \hj@linebreak + \hj@hyphenation + } +% \end{macrocode} +% +% +% \begin{macrocode} +\DeclareInstance{hj}{default}{std}{} +% \end{macrocode} +% +% +% \begin{macrocode} +%\ShowInstance{hj}{default} +% \end{macrocode} +% +% +% \begin{macrocode} +\catcode`\:=12\relax +\endinput +% \end{macrocode} +% +% \begin{macrocode} +%</package> +% \end{macrocode} +% +% +% \Finale +% +% \endinput +% +% +% +% \subsection{The template `pagebreak'} +% +% +% +% The rest doesn't belong here but i've already set it up I have to +% keep it somewhere until work on the page builder actually +% starts---so why not in this place. +% +% \begin{TemplateInterfaceDescription}{pagebreak} +% +% \TemplateArgument{1} +% {none} +% +% \TemplateSemantics +% +% \end{TemplateInterfaceDescription} +% +% +% \begin{TemplateDescription}{pagebreak}{TeX} +% +% \TemplateKey{clubpenalty}{c} +% {} +% {150} +% +% \TemplateKey{widowpenalty}{c} +% {} +% {150} +% +% \TemplateKey{displaywidowpenalty}{c} +% {} +% {50} +% +% \TemplateKey{predisplaypenalty}{c} +% {} +% {10000} +% +% \TemplateKey{postdisplaypenalty}{c} +% {} +% {0} +% +% \TemplateKey{brokenpenalty}{c} +% {} +% {100} +% +% \TemplateKey{interlinepenalty}{c} +% {} +% {0} +% +% \TemplateKey{vbadness}{c} +% {} +% {1000} +% +% \TemplateKey{vfuzz}{l} +% {} +% {.1pt} +% +% \TemplateSemantics +% +% \end{TemplateDescription} +% +% +% +% +% \begin{macrocode} +\DeclareTemplateType{pagebreak}{0} +% \end{macrocode} +% +% +% \begin{macrocode} +\DeclareTemplate{pagebreak}{TeX}{0}{ + clubpenalty =c [150] \clubpenalty, + widowpenalty =c [150] \widowpenalty, + displaywidowpenalty =c [50] \displaywidowpenalty, + predisplaypenalty =c [10000] \predisplaypenalty, + postdisplaypenalty =c [0] \postdisplaypenalty, + brokenpenalty =c [100] \brokenpenalty, + interlinepenalty =c [0] \interlinepenalty, +% + vbadness =c [1000] \vbadness, + vfuzz =l [.1pt] \vfuzz, +} + {\DoParameterAssignments +%<*trace> + \GAL@typeout{Now~ changing~ pagebreaking} +%</trace> + } +% \end{macrocode} +% +% +% \begin{macrocode} +\DeclareInstance{pagebreak}{default}{TeX}{} +% \end{macrocode} +% +% +% +% +% +% +% +% +% \begin{TemplateInterfaceDescription}{} +% +% \TemplateArgument{1} +% {} +% +% \TemplateSemantics +% +% \end{TemplateInterfaceDescription} +% +% diff --git a/Master/texmf-dist/source/latex3/template/template.dtx b/Master/texmf-dist/source/latex3/template/template.dtx new file mode 100644 index 00000000000..286449af968 --- /dev/null +++ b/Master/texmf-dist/source/latex3/template/template.dtx @@ -0,0 +1,2053 @@ +% \iffalse +%% +%% (C) Copyright 1999 David Carlisle, Frank Mittelbach +%% All rights reserved. +%% +%% Not for general distribution. In its present form it is not allowed +%% to put this package onto CD or an archive without consulting the +%% the authors. +%% +%<*dtx> + \ProvidesFile{template.dtx} +%</dtx> +%<package>\NeedsTeXFormat{LaTeX2e} +%<package>\ProvidesPackage{template} +%<driver>\ProvidesFile{template.drv} +% \fi +% \ProvidesFile{template.dtx} + [1999/09/28 v0.14 template parsing (DPC,FMi)] +% +% \iffalse +%<*driver> + \documentclass{ltxdoc} +\makeatletter + \newenvironment{decl}[1][]% + {\par\small\addvspace{4.5ex plus 1ex}% + \vskip -\parskip + \ifx\relax#1\relax + \def\@decl@date{}% + \else + \def\@decl@date{\NEWfeature{#1}}% + \fi + \noindent\hspace{-\leftmargini}% + \begin{tabular}{|l|}\hline\ignorespaces}% + {\\\hline\end{tabular}\nobreak\@decl@date\par\nobreak + \vspace{2.3ex}\vskip -\parskip\@afterheading} +\makeatother + + \begin{document} + \DocInput{template.dtx} + \end{document} +%</driver> +% \fi +% +% +% \CheckSum{864} +% +% \GetFileInfo{template.dtx} +% +% \title{The \textsf{template} package\thanks{This file +% has version number \fileversion, last +% revised \filedate.}} +% \author{DPC, FMi} +% \date{\filedate} +% \maketitle +% +% \changes{0.06}{1998/12/17}{generic functions reborn as templates} +% +% \tableofcontents +% +% \section{Introduction} +% A \emph{Template} is a named `function' that has a fixed number +% of \emph{mandatory arguments} and an additional set of \emph{keys} +% or `named attributes' that are set in a `key value list'. That is, +% a comma separated set of assignments of the form:\\ +% \meta{key$_1$} |=| \meta{value$_1$} |,| +% \meta{key$_2$} |=| \meta{value$_2$} \ldots +% +% More specific instances of the template may be declared by +% specifying settings of the parameters. The key value list is parsed +% at the time the instance is declared, and an `internal' set of +% parameter assignments is passed to the template code. It is normally +% not parsed at run-time, though it is possible to enforce this +% behaviour. +% +% Templates have a \emph{type} and a \emph{name}. Templates +% of the same type have the same argument and parameter +% structure. That is, templates of the same type are expected to be +% exchangeable semantically. (However, except for checking that +% templates of the same type always have the same number of arguments +% this is not enforced by the code.) +% +% A template type is declared via the |\DeclareTemplateType| +% declaration which takes two arguments: the name for the type and the +% number of arguments a template of this type requires. +% +% Templates are declared via the |\DeclareTemplate| +% command which takes five arguments +% \begin{itemize} +% \item The \emph{type} of the template (no |\|). +% \item The \emph{name} of the template (no |\|). +% \item The number of arguments for the template (same as on type +% declaration). +% \item A list declaring the keys accepted by the template, +% with information about the action to take when the key is specified +% with a value. +% \item The code for the template. This may be arbitrary \TeX\ +% code. At some point it should execute |\DoParameterAssignments| +% to run the parameter assigments. +% +% The mandatory arguments are accessed via |#1|, |#2|, \ldots +% \end{itemize} +% +% +% Each element of the key specification list is of the form: +% \begin{flushleft} +% \meta{key name} |=| +% \meta{key type} \meta{optional default} \meta{internal code} +% \end{flushleft} +% +% The \meta{key types} are essentially specified by giving a symbolic +% representation of the assignment function to be used by \TeX. +% +% Currently the possibilities are +% +% \begin{center}\catcode`|=12 +% \begin{tabular}{l|ll|l} +% key type& letter& internal code& argument form\\\hline +% Command & f\emph{n}&command name & command definition\\ +% name & n & command name & command definition\\ +% length & l & length register& calc length syntax\\ +% fake length & L & command name & calc length syntax\\ +% count & c & count register& calc count syntax\\ +% fake count & C & command name & calc count syntax\\ +% boolean & b & name of \verb|\newif| switch& true or false\\ +% switch & s & \marg{true code}\marg{false code}& true or false\\ +% instance& i\marg{type}& command name& instance of this \emph{type}\\ +% direct & x & Internal code& any\\ +% general & g & general code & any +% \end{tabular} +% \end{center} +% +% In addition, any of these types may be prefixed by |+| to +% denote a global assignment (described below). +% |f| takes a digit from 0--9 to denote the number of arguments. +% |n| is in fact the same as |f0|. When an instance is declared +% The value assigned to the key should be the definition of +% the command, using |#1|\ldots|#9| to denote the specified arguments. +% +% |c| takes an internal form a count register, +% not a \LaTeX\ counter name. +% +% For |f|, |n|, |l|, and |c|, the assignment is done twice, once +% at the time an instance is \emph{declared}. (This may involve +% using \textsf{calc} expresions. Then the `primitive assignment' +% of the value (not using calc) is copied to the internal parameter +% list, to be executed when an instance is run. Sometimes you need the +% expression to be evaluated at the time an instance is run rather +% than the time it is declared. For example it may be an expression +% involving some values that are not fixed throughout a document. +% In this case the instance declaration may give a value in the +% form |\DelayedEvaluation|\marg{calc expression}. In this case +% the value is not evaluated when the instance is declared, and +% instead the entire expression is copied to the `internal parameter +% list' and is evaluated whenever the instance is used. +% +% |L| and |C| take the same value types as |l| and |c| but the internal +% assignments are to macros not registers. +% +% Keys declared with |b| and |s| each take values either \emph{true} or +% \emph{false}. if the key zzz is declared with |b| then specifying +% |zzz=true| will essentially pass |\zzztrue| to the internal parameter +% list (although in fact |\zzztrue| need not be defined) . If instead +% zzz had been declared via |s|, then |zzz=true| would pass the tokens +% of the \marg{true code} to the internal parameter list. +% +% If a key is specified as |x|, then when used the \emph{internal code} +% will be copied to the internal parameter lists. This code may use |#1| +% to denote the value supplied to the key in the instance declaration. +% Note that this code is \emph{only} copied at the time the instance is +% declared. It is not executed at this time. It is executed when the +% instance is executed.\footnote{Despite the question of whether or +% not x and g are still necessary these days, they have the wrong +% `names' since x is the one that is not executed during delcaration +% while g is.} +% +% If a key is declared with |g| then the code is run at the time the +% instance is declared. By default \emph{nothing} is passed to the +% internal parameter list. This code may use |#1| to denote the +% value that will be supplied when an instance is declared. +% Any code that should be run when an instance is executed should +% be explicitly passed to the internal parameter list using +% |\addto@hook\TP@toks{|\ldots|}| +% +% A key declared with |i|\marg{type} takes as value the name of a +% declared instance of that type. The command token associated with +% the key will store a command essentially equivalent to a call +% to |\UseInstance|\marg{type}\marg{name}, but in a slightly optimised +% internal form. +% As an exception to this rule the replacement code may be of the form +% |\UseTemplate| followed by the key settings for the template +% but without the mandatory arguments. In this case the `inner' +% instance declaration is `pre compiled' and the token assigned to +% the store the value assigned to this key will execute an instance +% of the template directly, it will not re-parse the keyword settings +% each time the instance is used. +% +% \section{Commands} +% +% +% \subsection{Template declaration commands} +% +% \begin{decl} +% |\DeclareTemplateType| \marg{type}\marg{num} +% \end{decl} +% Declare a template type. +% +% \begin{decl} +% |\DeclareTemplate| +% \marg{type}\marg{tname}\marg{num}\marg{keyspec}\marg{code} +% \end{decl} +% Declare a template \meta{tname} of type \meta{type} with the set of +% keys as defined by \meta{keyspec}. From this template instances can +% be declared using |\DeclareInstance| At runtime such instances will run +% \meta{code} and expect \meta{num} mandatory arguments (same number +% for all templates of one type).\footnote{The \meta{num} argument is +% redundent as it can be deduced from the type. However, for practical +% reasons it seems better to keep that information with each +% individual template declaration.} +% +% \begin{decl} +% |\DeclareRestrictedTemplate| +% \marg{type}\marg{new-tname}\marg{old-tname}\marg{keyvals} +% \end{decl} +% Declare as new template \meta{new-tname} for type \meta{type} by +% taking template \meta{old-tname} as the basis and setting one or +% more of its keys to specific values. +% +% \begin{decl} +% |\DoParameterAssignments| +% \end{decl} +% The list of key value assignments made (and saved) during template +% declaration is evaluated at this point in the template code. +% +% +% \subsection{Instance declaration commands} +% +% \begin{decl} +% |\DeclareInstance| \marg{type}\marg{iname}\marg{tname}\marg{keyvals} +% \end{decl} +% Declare an instance of type \meta{type} named \meta{iname} build +% from using template \meta{tname} with key settings as given by +% \meta{keyvals}. +% +% \begin{decl} +% |\DeclareCollectionInstance| +% \marg{collection}\marg{type}\marg{iname}\marg{tname}\marg{keyvals} +% \end{decl} +% Same as |\DeclareInstance| except that this instance is only active +% when for the type \meta{type} the collection \meta{collection} was +% selected via |\UseCollection|. E.g., within the frontmatter one +% could make all headings behave differently by defining collection +% instances for template type `head'. +% +% \subsection{Key value commands} +% +% \begin{decl} +% |\DelayEvaluation|\marg{code} +% \end{decl} +% Used in the value spec for an instance to declare that the value +% \meta{code} should not be evaluated at declaration time but at +% run-time. Can also be used in the defaults for keys (given in square +% brackets) in the declaration of templates. +% +% \begin{decl} +% |\MultiSelection| \meta{counter} \marg{cases} \marg{else} +% \end{decl} +% Used in the value spec for an instance key to declare that the value of +% this key depends on the current setting of \meta{counter} at run-time. +% The \meta{cases} argument is a comma-separated list of ``values'', +% the \meta{else} argument a single ``value''. If at run-time +% \meta{counter} has the value $i$ then the $i$-th element of the +% \meta{cases} list is selected. If that does not exist the +% \meta{else} case is returned. +% +% +% \subsection{Processing commands} +% +% \begin{decl} +% |\UseTemplate| \marg{type}\marg{tname}\marg{keyval} +% \end{decl} +% Execute a template \meta{tname} of type \meta{type} at run-time +% using \meta{keyvals} as the value assignments for its keys. In this +% case the keys are evaluated at run-time thus this method is far +% slower than using a predeclared instance of this template (see +% below). This command can also appear as the value for a key of type +% `i' in which case the evaluation happens at declaration time of the +% template that contains this key! +% +% +% \begin{decl} +% |\UseInstance| \marg{type}\marg{iname} +% \end{decl} +% Run the instance \meta{iname} of template type \meta{type}. If a +% collection is in force see if there is a collection instance of name +% \meta{iname} and if so run that instead. +% +% \begin{decl} +% |\UseCollection| \marg{type}\marg{collection} +% \end{decl} +% Declare that from now on (normal scoping rules) the collection +% \meta{collection} for template type \meta{type} is in force. This +% means that a call to |\UseInstance| will first check if there is a +% collection instance defined, and if so use that instance, otherwise +% use the normal instance. +% +% +% \subsection{Test commands} +% +% \begin{decl} +% |\IfExistsInstanceTF| \marg{type}\marg{iname}\marg{true}\marg{false} +% \end{decl} +% Test if for template type \meta{type} an instance with name +% \meta{iname} exists. Select \meta{true} or \meta{false} code +% accordingly. +% +% +% +% \section{Examples of template key types} +% +% The general syntax for key specification in templates (fourth argument +% of the command |\DeclareTemplate|) is: +%\begin{flushleft} +%| {| \\ +%| | \meta{key-name$_1$} |=|\meta{key-type$_1$} +% \meta{optional-default$_1$} \meta{storage-bin$_1$}|,|\\ +%| | \meta{key-name$_2$} |=|\meta{key-type$_2$} +% \meta{optional-default$_2$} \meta{storage-bin$_2$}|,|\\ +%| ...|\\ +%| }| +%\end{flushleft} +% In this section we look at all possible key types and give examples +% for them. +% +% +% \subsection{Attributes that receive names as values} +% +% The type |n| expects to receive a \LaTeX{} name as a value. Used, +% for example, to specify the name of a \LaTeX{} counter to use. +%\begin{verbatim} +% heading-id =n \heading@id, +% counter-id =n [\DelayEvaluation{\heading@id}] \heading@counter, +%\end{verbatim} +% Notice the use of |\DelayEvaluation| in the default of +% |counter-id|. It is necessary to make the default the token +% |\heading@id| if we want to inherit the value from the |heading-id| +% key. Otherwise it gets value of |\heading@id| at the time the +% instance is declared. +% +% +% \subsection{Attributes that receive functions as values} +% +% +% The type |f|\meta{num} expects a function with \meta{num} arguments +% as a value. The arguments are denoted by |#1|, |#2|, etc. In most +% cases either |f0| (for declarations) or |f1| (to format one argument) are +% needed. +%\begin{verbatim} +% initial-font =f0 \initial@font, +% initial-format =f1 [#1] \initial@boxhandling, +%\end{verbatim} +% +% \subsection{Attributes that receive dimensions as values} +% +% As far as specifying instances the |l| and |L| type behave +% identically. They differ only in the type of internal storage-bin +% they need: |l| expects a length register while |L| expects an +% ordinary macro name and assigns its value via |\def|. +%\begin{verbatim} +% pre-sep =l \topsep, +% post-sep =L \botsep, +%\end{verbatim} +% +% +% +% \subsection{Attributes that receive integers as values} +% +% The |c| and |C| type receive integers as values. Again either of +% them can be transparently used. In case of |c| the +% \meta{storage-bin} has to be a \TeX{} count register not a \LaTeX{} +% counter name, i.e., set up via |\newcount|. (\LaTeX{} counters can +% be used as well if they are accessed via their internal name, i.e., +% via |\c@|\meta{\LaTeX-counter}) +%\begin{verbatim} +% pre-penalty =c \@beginparpenalty, +% penalty =C \hmaterial@penalty, +%\end{verbatim} +% +% +% +% \subsection{Attributes that receive template instances as values} +% +% The type |i|\marg{type} takes as value the name of a declared +% instance of that type. The \meta{storage-bin} associated with the +% key will store a command essentially equivalent to a call to +% |\UseInstance|\marg{type}\marg{name}, but in a slightly optimised +% internal form. +% +% As an exception to this rule the replacement code may be of the form +% |\UseTemplate| followed by the key settings for the template but +% without the mandatory arguments. In this case the `inner' instance +% declaration is `pre compiled' and the token assigned to the store +% the value assigned to this key will execute an instance of the +% template directly, it will not re-parse the keyword settings each +% time the instance is used. +%\begin{verbatim} +% justification-setup =i{justification} \list@justification, +%\end{verbatim} +% +% Usage within an instance declaration is either +%\begin{verbatim} +% justification-setup = raggedright, +%\end{verbatim} +% i.e., name of a declared instance or a call to |\UseTemplate| +%\begin{verbatim} +% justification-setup = \UseTemplate{justification}{TeX} +% { startskip = 0pt, ... }, +%\end{verbatim} +% +% +% +% \subsection{Attributes that receive true or false values} +% +% The type |s| expects the strings |true| or |false| as values. In +% this case the declaration has no \meta{storage-bin}. Instead the +% declaration consists of two brace groups containing code. Depending +% on the value one of the groups gets copied verbatim into the +% internal parameter list of the instance and gets executed at +% run-time at the point where |\DoParameterAssignments| is seen. +%\begin{verbatim} +% item-implicit-boolean =s +% { \def\item@implicit@code{\item\relax} }{}, +% numbered-boolean =b [true] @heading@nums, +%\end{verbatim} +% +% +% \subsection{Attributes that accept any value} +% +% The type |g| is a low-level specification which contains arbitrary +% code in place of the \meta{storage-bin}. This code is evaluated at +% declaration time of the instance and by default \emph{nothing} is +% passed to the internal parameter list (this has to happen explicitly +% from within the code). |#1| may be used to access the value +% specified. + +% The main purpose for this type is of historical nature (originally +% most of the other types have been implemented internally using |g|). +% +% The type |x| also requires code in place of the \meta{storage-bin}. +% However with this type all of the code is copied unevaluated to the +% internal parameter list. There are some applications for this type +% when implementing customisable defaults. However, it is likely that +% it will not survive a final release. +%\begin{verbatim} +% generic-key =g \typeout{#1}, +% extra-assigns =x \typeout{#1}, +%\end{verbatim} +% +% +% +% +% +% +% \section{A complete example} +% +% The following example shows a sketch of a template for typesetting +% captions to be used as part of a larger mechanism setting whole +% floats.\footnote{I made it up while I went along so if you spot the +% ``missing brace'' or some other blunder tell me, FMi.} +% +% We declare a template type \texttt{caption} then define an example +% template for that type and finally produce some instances from that. +% +% \subsection{Declaring the template type} +% +% To define the template type we first have to ask ourselves what +% information would be varying each time such a template is used? A +% potential answer could be the following: +% \begin{itemize} +% \item +% The float name, e.g., `Table' or `Fig.' etc. +% \item +% The float +% number e.g., `10' or `3--c' etc. +% \item +% The actual caption text as specified in the document. +% \end{itemize} +% Since the above items would be differed in each instantiation of +% such a template we would pass them as mandatory argument to the +% template. +% +% Are there others? Possibly. Here are two more that seem to be +% useful, at least in a number of cases: +% \begin{itemize} +% \item +% The text of the legend in document classes that distinguish +% between caption text (heading to the figure/table) and legend +% (explanatory material) +% \item +% Measure to which the caption should be typeset. +% \end{itemize} +% The last one of these might need some extra explanation. Suppose a +% design requires that the caption width is decided depending on the +% width of the table of figure, e.g., the caption is supposed to +% typeset below some illustration and should not be wider than that +% illustration, or the caption is typeset aside to the illustration +% using the remaining space. In that case the process that formats the +% whole float needs to communicate with the current template to pass +% that (varying) information along. Of course, that could happen by +% using global variables, e.g., the outer process sets the measure as +% desired before calling the caption formatting template. What makes +% more sense is likely to be a matter of taste but it also has to do +% with the precise semantics of the template type. Staying with our +% example: if the the semantics of the template type \texttt{caption} +% is supposed to produce a formatted box (in \TeX{} terms) then we +% should pass the measure as an argument if we ever intend to allow +% for variations. If on the other hand the semantics are to format a +% certain set of text into the current galley (which has measure of +% its own) then a measure argument would not belong to this template +% type. +% +% Are there other variations sensible? Yes, for example, instead of +% passing a fixed string like ``Fig.'' as the first argument one could +% pass an abstract float type identifier and let the template worry to +% deduce from that information what fixed string to produce. +% +% Another question: why should we pass the fixed text (or an abstract +% identifier from which it can be deduced) and the number as separate +% arguments to the template instead of passing a combined string (like +% it is done in the |\@makecaption| command of \LaTeXe{})? Answer: +% because this allows to build templates that can individually +% manipulate both bits of information, e.g., to format the number in a +% different font, etc. +% +% So what are the conclusions of this discussion? Defining the +% semantics of a template type is difficult and often needs several +% trials to come up with something that is covering the anticipated +% use. There is clearly not a cardinal way for defining template +% types; how the overall separation into smaller units is done is +% partly a matter of taste and partly a matter of the major layout +% characteristics that one tries to support. +% +% Returning to our example: let's assume we settle for the first four +% arguments, i.e., the calling template is responsible for setting the +% measure for the caption text if necessary. +% +% What we also have to do is to define (at least for ourselves) what +% data the arguments accept and what their semantics are. An informal +% summary of that could be the following: +% \begin{center} +% \begin{tabular}{rrl} +% \textit{Arg} & \textit{Data Type} & \textit{Description} \\[3pt] +% 1 & text & fixed float description +% \\ +% 2 & text/|\NoValue| & float number +% \\ +% 3 & text & caption text +% \\ +% 4 & text/|\NoValue| & legend text +% \\ +% \end{tabular} +% \end{center} +% The second and the fourth argument are allowed to be missing (i.e., +% can get |\NoValue| passed as a value). Note that the empty string in +% case of a text argument is different from |\NoValue|. +% +% We further declare that it is permissible for a template of this +% type to ignore the information provided by all arguments except 3, +% i.e., the caption text. +% +% Finally the result of the template formatting should is to typeset +% text into a current galley (paragraph mode in \LaTeX{} lingua). +% +% All the above is semantic information that (at least right now) is +% not being enforced by declaring a template type (except for the +% number of arguments) but each template of a certain type is supposed +% to conform to this specification nonetheless.\footnote{To make this +% even clearer we are thinking of extending the template type +% declaration with another argument in which one has to formally or +% informally (?) specifies information like the one in the table +% above.} +% +% This finally leads to the following declaration: +%\begin{verbatim} +%\DeclareTemplateType{caption}{4} +%\end{verbatim} +% +% \subsection{Defining a first template} +% +% We start by defining a simple template of type \texttt{caption} +% which roughly formats a caption like those being presented in +% \LaTeXe{}'s article class, i.e., the caption is typeset as a +% paragraph if it is longer than a single line, otherwise it is +% centered. The legend even if present is ignored. Above and below we +% give the designer the possibility to add some space. +% +% In fact the examples is more or less identical in code to +% |\@makecaption| except that if the second argument (i.e., the +% number) is |\NoValue| it and its preceding space\footnote{For those +% who wonder: spaces are by default ignored within definitions when +% the new packages are used due to a command \texttt{\textbackslash +% IgnoreWhiteSpace}, do get a normal space one has to use +% \texttt{\textasciitilde} and to obtain an unbreakable space +% \texttt{\textbackslash nobreakspace}.} gets ignored. +% +% We start by declaring the template \texttt{toosimple} of type +% \texttt{caption} having four mandatory arguments (as described in +% the discussion of the template type). +%\begin{verbatim} +%\DeclareTemplate{caption}{toosimple}{4} +%\end{verbatim} +% The next argument of |\DeclareTemplate| lists all keys for the +% template. In this case we have keys for the vertical spaces above +% and below. We make them type |L| to save on registers but with a bit +% of care we could also have used scratch registers like |\@tempskipa| +% etc. Their default values are both zero. +%\begin{verbatim} +% { +% above-skip =L [0pt] \caption@above@skip , +% below-skip =L [0pt] \caption@below@skip , +% } +%\end{verbatim} +% The final argument of |\DeclareTemplate| contains the actual +% processing code. We start with looking at the second mandatory +% argument (caption number) to find out if it is |\NoValue| and +% depending on the result define a helper command |\caption@start|. +%\begin{verbatim} +% { +% \IfNoValueTF{#2} +% { \def\caption@start{#1:~} } +% { \def\caption@start{#1~#2:~} } +%\end{verbatim} +% Having dealt with the prelims we now run |\DoParameterAssigments| at +% which point the keys of the template are made available, e.g., at +% this point all those right hand containers such as +% |\caption@above@skip| get assigned the value specified in an +% instantiation of the template. (That scheme allows to do preliminary +% processing up front, e.g., defaults for the keys could be assigned +% prior to that point in which case they are overwritten if the +% template instance specifies a different value. the use of specifying +% defaults via the |[..]| syntax as done above is slightly faster at +% run-time but needs more memory.) +%\begin{verbatim} +% \DoParameterAssigments +%\end{verbatim} +% The rest of the code should look familiar to anybody who ever looked +% at \texttt{article.cls}. The only point worth mentioning are the +% |\relax| commands after |\caption@above@skip| and +% |\caption@below@skip|. Since we have decided to use |L| as key type +% these commands are macros and not registers containing the +% dimensions as strings. This means that we have to be careful to +% ensure that \TeX{} knows where the dimension ends. In certain cases +% text following such a command might be mistaken as being part of the +% dimension (e.g., if followed by the word \texttt{plus}, etc.). In +% the code below this could only happen for the second |\vskip| but it +% is good practice to always add a terminating |\relax| to avoid such +% hidden traps. +%\begin{verbatim} +% \vskip \caption@above@skip \relax +% \sbox \@tempboxa {\caption@start #3} +% \ifdim \wd\@tempboxa >\hsize +% \caption@start #3\par +% \else +% \global \@minipagefalse +% \hb@xt@\hsize{\hfil\box\@tempboxa\hfil} +% \fi +% \vskip \caption@below@skip \relax +% } +%\end{verbatim} +% +% Why is the above template of not much use? Simply because it doesn't +% offer any flexibility to declare different designs. The only +% alteration offered to the designer is to modify the space above and +% below the caption, e.g., the following declaration would mimic the +% definition within the \texttt{article.cls} class of \LaTeXe: +%\begin{verbatim} +%\DeclareInstance{caption}{article}{toosimple} +% { +% above-skip = 0pt, +% below-skip = 10pt, +% } +%\end{verbatim} +% And that's all that can be manipulated. All items that people asking +% to change, e.g., not having a colon after the number, using +% different fonts and font sizes, etc.\ are still hard-wired and thus +% inaccessible. So we have to do better if we want to make use of the +% power the template mechanism offers. +% +% +% +% \subsection{Defining a better template} +% +% First step in defining better templates is to ask ourselves a couple +% of questions: +% \begin{itemize} +% \item What are the main characteristics of the layout the template +% is supposed to support? +% \item What are the elements that we want to allow (or can allow) the +% designer to modify? +% \end{itemize} +% +% Take the first question first: the layout supported by the template +% of the previous section had as its main characteristics that it +% would center the caption if it would fit in a single line in the +% current measure. We could consider this being an unchangable +% characteristic of the layout this template produces (and a designer +% would need to use a different template of type \texttt{caption} if a +% design compatible with this restriction is desired) or we could try +% to make our template smarter by adding bells and wistles that allow +% the designer to say stuff like: +%\begin{verbatim} +% one-line-format = \hfil #1 \hfil, +%\end{verbatim} +% or +%\begin{verbatim} +% one-line-action = center, +%\end{verbatim} +% depending on how we intend to offer changing the behavior of the +% template. Like when trying to define sensible template types we have +% no single road to heaven (and probably as many to hell) --- it has a +% lot to do with how we think about design. +% +% My advice, after having tried to work with these concepts for a +% while, is to keep templates simple in so far as that most of not all +% attribute for a template should be relevant for the design. In other +% words, if you have attributes that, depending on their setting, make +% half of the other attributes not applicable then it may be +% appropriate to think about providing several templates instead. To +% give an example from \LaTeXe: instead of having |\@startsection| +% deal with both vertical heads and run-in heads provide individual +% templates. (|\@startsection| is this famous command where design +% switches are build in by making dimensions negative to signal +% something and afterwards use the absolute value.) +% Another way to look at this is to say that a template should +% normally not contain large amounts of code which is only selected in +% a subset of attribute settings. +% +% As said before there are no golden rules, it is perfectly possible +% to make hugely complicated templates that solve every possible +% aspect of layout one could think of in one go --- it is just that +% with keeping it more simple one can get the same functionality with +% less headaches for the template writer as well as the template user +% later on. +% +% Returning to our example: allowing to handle the case of a single +% line caption specially could well be considered part of the +% template. In contrast: layouts that would put the caption number +% sideways, i.e., which would need totally different internal coding +% should probably be coded as a separate template of type +% \texttt{caption}. +% +% So for our next example template we settle for the fixed caption +% text plus number (if any) being at the beginning of the variable +% caption text (coming from the document) and being together formatted +% as some sort of a pargraph. In case of the whole caption being a +% single line we allow the designer to specify how to lay it out +% (e.g., centered, flush left, etc.). If there is a legend it will get +% formatted by a vertical space followed by the legend formatted as +% another paragraph. +% +% More precisely we allow for the following bells and wistles: +%\begin{verbatim} +%\DeclareTemplate{caption}{lesssimple}{4} +% { +%\end{verbatim} +% The designer can specify the space above and below the caption like +% we did in our first example. +%\begin{verbatim} +% above-skip =L [0pt] \caption@above@skip , +% below-skip =L [0pt] \caption@below@skip , +%\end{verbatim} +% Regarding the caption number we support the case where no number is +% present (the value being |\NoValue|) as well as the number being +% present. For both cases the designer has to specify what formatting +% should be attached. By default all is being typeset in the font the +% whole caption is presented but if there is a need for it the +% designer can use the following keys to attach special formatting +% devices to each particular item beside specifying special spacing +% information or replacing the default colon after the number with +% something else. +%\begin{verbatim} +% number-format =f2 [#1~#2:~] \caption@number@format, +% nonumber-format =f1 [#1:~] \caption@nonumber@format, +%\end{verbatim} +% If the caption is fitting onto a single line we make it possible +% for the designer to specify how this single line should be +% positioned (the default is to center the line). +%\begin{verbatim} +% single-line-format =f1 [\hfil#1\hfil] \caption@single@line@format, +%\end{verbatim} +% The font for the caption (including the fixed text and the number +% unless specified differently above) is going to be the one decided +% by the next key. +%\begin{verbatim} +% caption-font =f0 [\normalfont] \caption@font, +%\end{verbatim} +% The next attribute deserves some extra explanation: here we make use +% of an interface which is explained in more detail when we reveil the +% support for galley formatting.\footnote{Guess I have to apologize +% for the fact that i partly make use of that interface in this +% example while on other occasions (like the use of vertical spacing) +% within the example I do not---consistency around midnight is not my +% strength I fear (FMi).} In a nutshell the template type \texttt{hj} +% (hyphenation \& justification) allows one to define a) the +% justification concepts applied to the upcoming paragraphs, e.g., +% whether they should be set flush left, adjusted, first line +% centered, etc.\ b) the linebreaking strategy used and c) the +% hyphenation rules which should apply. All this is done by selecting +% an appropriate (predefined) instance of this type as will hopefully +% become somewhat clearer in the example instances shown below. +%\begin{verbatim} +% caption-hj-setup =i {hj} [default] \caption@hj@instance, +%\end{verbatim} +% In case there is a legend to format we give the designer the +% possibility to specify by how much vertical space it should be +% separated from the preceding paragraph (i.e., the caption text). The +% attributes for font and hj setup are comparable to those for the +% caption text itself (except that they will only apply to the +% legend). The only addition is the key \texttt{legend-text} which is +% allowed to take a fixed text (plus any formating and spacing for it) +% which will be added to the front of the legend in case it is +% provided at all (by default it is empty). +%\begin{verbatim} +% legend-sep =L [0pt] \caption@legend@sep , +% legend-text =f0 [] \caption@legend@text, +% legend-font =f0 [\normalfont] \caption@legend@font, +% legend-hj-setup =i {hj} [default] \caption@legend@hj@instance, +% } +%\end{verbatim} +% The actual code for the template should hold few if any +% surprises. In fact it is more or less identical to the one of the +% first template example, except that now we have now taken out some +% of the hardwired decisions and placed them into attributes. +%\begin{verbatim} +% { +% \IfNoValueTF{#2} +% { \def\caption@start{\caption@number@format{#1}{#2}} } +% { \def\caption@start{\caption@nonumber@format{#1}} } +% \DoParameterAssigments +% \vskip \caption@above@skip \relax +%\end{verbatim} +% To properly measure the caption to determine if it fits a single +% line we have to set it in the right font, so here as well as below +% we have to apply |\caption@font|. +%\begin{verbatim} +% \sbox \@tempboxa {\caption@font \caption@start #3} +% \ifdim \wd\@tempboxa >\hsize +% \begingroup +% \caption@font \caption@hj@instance +% \caption@start #3\par +% \endgroup +% \else +% \global \@minipagefalse +% \hb@xt@\hsize{\caption@single@line@format{\box\@tempboxa}} +% \fi +%\end{verbatim} +% To decide whether or not we have to set any legend we have to test +% |#4| for being |\NoValue|. This part of the code was not present in +% the previous example but otherwise should be straight forward. +%\begin{verbatim} +% \IfNoValueF{#4} +% { +% \vskip \caption@legend@sep \relax +% \begingroup +% \caption@legend@font \caption@legend@hj@instance +% \caption@legend@text +% #4\par +% \endgroup +% } +% \vskip \caption@below@skip \relax +% } +%\end{verbatim} +% +% I wouldn't claim the the above template is good or contains +% everything that would be desired and I'm sure that in the end we +% will have several such template for typesetting the caption part and +% perhaps decide on a different template type in the first place. So +% this is only to give a glimpse of how the template interface could +% be applied and I hope that reading it can see a) how they can apply +% it to other areas as well as see what is wrong with the example +% itself. +% +% To just note one point that i thought of being wrong after writing +% the above paragraphs: the key \texttt{single-line-format} was +% declared to be a function with one argument with the idea that +% besides specifying the single line should be centered (|\hfil|) on +% both sides, or flush left, or flush right (|\hfil| on one side) one +% could also specify something like +%\begin{verbatim} +% single-line-format = \hspace{10pt}#1\hfil, +%\end{verbatim} +% that is a fixed indentation on the left in case where the caption is +% a single line. However, of course one can't. Or at least it is not +% safe to do so since our test in the code tests the width of the line +% without taking into account such a finite fixed space and guess what +% might happen? So in summary, flexibility needs some thought and +% often some afterthoughts as well --- happy thinking :-) +% +% +% +% \subsection{Defining a few instances} +% +% So let us conclude this example with a few sample instances. We +% start with one that repeats what current \LaTeXe{} provides in the +% article class. It shows all keys with values. However in fact only +% the first key is actually needed since all others are the same as +% the default values in the template (and of course a legend is not +% specifiable in standard \LaTeX{} coding so those settings simply do +% not apply anyway). +%\begin{verbatim} +%\DeclareInstance{caption}{article}{lesssimple} +% { +% above-skip = 10pt, +% below-skip = 0pt, +% number-format = #1~#2:~, +% nonumber-format = #1:~, +% single-line-format = \hfil#1\hfil, +% caption-font = \normalfont, +% caption-hj-setup = default, +% legend-sep = 0pt, +% legend-text = , +% legend-font = \normalfont, +% legend-hj-setup = default, +% } +%\end{verbatim} +% +% The next examples are taken from books on the shelf essentially a +% random selection I fear. This one is from \emph{Introduction to +% Database Design} by C.~J.~Date and it uses Helvetica for the caption +% text with the caption flush left, with the figure and the fixed +% string (e.g., `Fig.' in bold face) separated by a quad of space. No +% legend either so this is not set up. The \texttt{hj} instance +% \texttt{noindentflushleft} is supposed to produce a ragged right paragraph +% without any indentation. It would have to be set up elsewhere +% (instance to the template of type \texttt{hj}). +%\begin{verbatim} +%\DeclareInstance{caption}{DATE}{lesssimple} +% { +% above-skip = 10pt, +% below-skip = 0pt, +% number-format = \textbf{#1~#2}\quad, +% nonumber-format = \textbf{#1}\quad, +% single-line-format = #1\hfil, +% caption-font = \fontfamily{phv} \normalfont, +% caption-hj-setup = noindentflushleft, +% } +%\end{verbatim} +% +% The final example is from the book ``Methods of Book Design'' by +% H.~Williamson which sets the caption centered if it fits a single +% line but adjusted as a paragraph without any indentation if longer +% than a single line. It uses old style numerals followed by a period +% for the number (though the example isn't quite right as i guess the +% text font used already has oldstyle numerals as default, so +% |\oldstylenums| is in fact not necessary). +%\begin{verbatim} +%\DeclareInstance{caption}{WILLIAMSON}{lesssimple} +% { +% above-skip = 10pt, +% below-skip = 0pt, +% number-format = #1~\oldstylenums{#2}.~, +% nonumber-format = #1~, +% single-line-format = \hfil#1\hfil, +% caption-font = \normalfont, +% caption-hj-setup = noindentadjusted, +% } +%\end{verbatim} +% +% +% +% \section{Notes} +% +% \subsection{Note on multi-valued parameters} +% +% +% The following code\footnote{docu taken from trial implementation in +% xlists.dtx, FMi} implements for registers (ie L,l,C,c keys) and +% for names (ie n key) a multi-selection mechanism of the following +% form: +% \begin{verbatim} +% key = \MultiSelection \@listdepth { +% \DelayEvaluation {2.5em}, +% 20pt + 34pt } +% { \DelayEvaluation {1em} }, +% \end{verbatim} +% where the first argument to |\MultiSelection| is a counter, the +% second argument is a comma separated list of values denoting the +% values for the cases 1, 2,\ldots, and the third argument contains +% the value for all other cases. +% +% The values are evaluated at declaration time in case of registers +% and therefore can contain calc expressions as well as +% |\DelayEvaluation|. +% +% Due to the implementation the case list is not allowed to have a +% trailing comma! And of course no checks are made whatsoever :-( +% +% A probably much nicer syntax would be something like this: +% \begin{verbatim} +% key = \MultiSelection { +% selector = \@listdepth, +% 1 = \DelayEvaluation {2.5em}, +% 2 = 20pt + 34pt, +% else = \DelayEvaluation {1em} +% }, +% \end{verbatim} +% but i found that too difficult to implement right now. +% +% I think it should also be considered if this kind of thing should be +% a generally available feature on all key types especially on the +% f\meta{number} ones. +% +% Anyway it is what i need for lists right now and as such it is +% sufficient. +% +% +% \subsection{Notes on template restriction} +% +% Possible semantics: +% +% a: just:-) changes the defaults ie the new template has as +% defaults those of its source as modified by the supplied +% keyvals; +% +% b: similar to a: but also removes some keywords ie the new template +% will not accept the keywods whose values are set by the suppied +% keyvals; +% +% c: plan C. +% +% +% Towards an implementation of b: but without a restriction on what +% keys appear where. +% +% +% +% +% \subsection{Open issues} +% +% In this section unresolved issues or ideas to think about and +% perhaps implement are collected. There is no particular order to +% them. +% +% \begin{itemize} +% \item The order of arguments in |\UseCollection| is illogical in my +% eyes! A collection typically modifies the behavior of several +% types and thus should perhaps be first (as it is in the +% |\DeclareCollectionInstance| case). Or not, or what? +% +% \item How should |\IfExistsInstanceTF| behave for Collection +% instances? Do we need a special check for those or a default +% action? Or do we need an additional test for the existence of +% collection instances? +% +% \item It was suggested that the template type declaration should get +% another argument in which (in?)formally the semantics for the +% template types are described, e.g., data type of arguments, +% resulting output, \ldots{} (somewhat like the description arguments +% for functions and variables in Emacs-Lisp). The advantage being +% that this helps employing the templates better as well as perhaps +% guiding context sensitive editors to support the work with such +% templates (e.g., providing help texts). +% +% \item The same might be of interest for the keys of individual +% templates though here syntax support is already available to some +% extend by the declaration of key types. +% +% \item There might be a need to distinguish between \TeX's dimen and +% skip registers. Right now this is not done and both |l| and |L| +% accepts what \LaTeX{} calls ``rubber length'' specifications. +% +% \item The type |b| can probably vanish. It is equivalent to +% specifying the mutators of a |\newif| command in the brace groups, +% e.g. +%\begin{verbatim} +% numbered-boolean =b [true] @heading@nums, +% numbered-boolean =s [true] {\@heading@numstrue} +% {\@heading@numsfalse}, +%\end{verbatim} +% +% \item See issue raised about syntax (and semantics) for +% |\Multiselection|. +% +% \end{itemize} +% +% \StopEventually{} +% +% \section{Implementation} +% \begin{macrocode} +%<*package> +% \end{macrocode} +% +% \begin{macrocode} +\RequirePackage{ldcsetup} +% \end{macrocode} +% +% Ignore white space in this package. +% \begin{macrocode} +\IgnoreWhiteSpace +% \end{macrocode} +% +% Declare a private token register for building parameter lists. +% Having the number saves a few expandafters +% (probably not needed in the end). +% \begin{macrocode} +\newtoks\TP@toks +\newtoks\TP@toksb +\newtoks\TP@toksc +% \end{macrocode} +% +% +% \begin{macro}{\functiondefine} +% |\def| setup with a latex style `number of arguments' argument. +% definition setup left in toksb for possible future use. +% \begin{macrocode} +\def\functiondefine#1#2#3{% + \def\@tempa##1#1##2##{% + \TP@toksb\expandafter{\expandafter\def\expandafter#2\@gobble##1#1} + \the\TP@toksb}% + \@tempa0##1##2##3##4##5##6##7##8##9{#3}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TP@DCI} +% Declare a command name to be an instance of a template +% ie with a particular setting of the parameters.\\ +% |#1| internal command name for instance to be (globally) declared\\ +% |#2| template type/template name\\ +% |#3| key value assignments for parameters of |#2| +% \begin{macrocode} +\def\TP@DCI#1#2#3{ + \begingroup + \TP@get@restrictions {#2} % puts stuff in \TP@toks + \toks@\expandafter\expandafter\expandafter + {\csname TPD>/#2\endcsname\relax\relax} + \setkeys{\the\TP@toksc} % temp OK? + {#3} % adds stuff to \TP@toks + \expandafter\TP@add@default \the\toks@ % prepends stuff to \TP@toks + \xdef#1{ + \expandafter\ifx\csname TP>/#2\endcsname\TP@dpa + \the\TP@toks + \else + \noexpand\TP@assignments{\the\TP@toks} + \expandafter\noexpand\csname TP>/#2\endcsname + \fi} + \endgroup} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TP@dpa} +% \begin{macrocode} +\long\def\TP@dpa{\DoParameterAssignments} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TP@add@default} +% \begin{macrocode} +\def\TP@add@default#1#2{ + \ifx#1\relax + \else + \@temptokena{#2} + \edef\@tempa{{\the\@temptokena\the\TP@toks}} + \TP@toks\@tempa + \expandafter\TP@add@default + \fi} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\UseTemplate} +% |{type}{templatename}{keyval}| +% Directly use a template with a particular parameter setting. +% This is also picked up if used in a nested fashion inside a parameter +% list.\\ +% |#1| type of a template.\\ +% |#2| name of a template.\\ +% |#3| key value assignments for parameters of |#1|. +% \begin{macrocode} +\def\UseTemplate#1#2#3{ + \TP@get@restrictions {#1/#2} % from here ... + \toks@\expandafter\expandafter\expandafter + {\csname TPD>/#1/#2\endcsname\relax\relax} + \setkeys{\the\TP@toksc}{#3} + \expandafter \TP@add@default \the\toks@ % to here is : + % Shared with \def\DeclareCommandInstance + \TP@push + \csname TP>/#1/#2\endcsname} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\DoParameterAssignments} +% Acces the list stored in |\TP@toks|. +% \begin{macrocode} +\def\DoParameterAssignments{ + \expandafter\TP@pop\the\TP@stack\@@} +% \end{macrocode} +% +% \end{macro} +% +% \begin{macro}{\TP@pop} +% \begin{macrocode} +\def\TP@pop#1#2\@@{ + \global\TP@stack{#2} + #1} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TP@stack} +% \begin{macrocode} +\newtoks\TP@stack +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TP@stack} +% \begin{macrocode} +\global\TP@stack{\relax}% avoid brace loss +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TP@assignments} +% Access the list stored in |\TP@toks|. +% \begin{macrocode} +\def\TP@assignments{ + \afterassignment\TP@push\TP@toks} +% \end{macrocode} +% +% \end{macro} +% +% \begin{macro}{\TP@push} +% \begin{macrocode} +\def\TP@push{ + \global\TP@stack\expandafter + {\expandafter{\the\expandafter\TP@toks\expandafter} + \the\TP@stack}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\DeclareTemplateType} +% |{type}{nofarg}| +% \begin{macrocode} +\def\DeclareTemplateType#1#2{ + \expandafter\def\csname TP@<#1>\endcsname{{}#2}} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\TP@prefix} +% |{type}| returns prefix for csnames for type, based on current collection. +% \begin{macrocode} +\def\TP@prefix#1{ + <\expandafter\expandafter\expandafter + \@firstoftwo\csname TP@<#1>\endcsname>#1/} +% \end{macrocode} +% +% \end{macro} +% +% \begin{macro}{\TP@args} +% |{type}| returns arg count for type, +% \begin{macrocode} +\def\TP@args#1{ + \expandafter\expandafter\expandafter + \@secondoftwo\csname TP@<#1>\endcsname} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\DeclareTemplate} +% |{type}{templatename}{nofarg}{keywordspec}{code}| +% \begin{macrocode} +\long\def\DeclareTemplate#1#2#3#4#5{ + \@ifundefined{TP@<#1>} + {\undefinedtype\DeclareTemplateType{#1}#3} + {\ifnum#3=\TP@args{#1}\relax\else + \BadArgCount\fi} +% \end{macrocode} +% Parse the key declaration, and execute the list with a suitable +% definition of |\KV@elt|. +% \begin{macrocode} + \let\KV@elt\TP@elt + \def\KV@default@elt##1{ + \PackageError{template}{Missing = after ##1}\@ehd} + \def\TP@name{#1/#2} + \toks@{} + \KV@parse{#4} +% \end{macrocode} +% +% Define the defaults +% \begin{macrocode} + \expandafter\edef\csname TPD>/\TP@name\endcsname{\the\toks@} +% \end{macrocode} +% +% Define the template +% \begin{macrocode} + \expandafter\newcommand\csname TP>/\TP@name\endcsname[#3]{#5}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TP@elt} +% The list of undefined keys and values is put in the list of the form\\ +% |\KV@elt|\marg{key}\marg{val}%^^A +% |\KV@elt|\marg{key}\marg{val}\ldots\\ +% So just need to give this macro a suitable definition. We just need +% to look at the first token of the value, to see what sort of key +% it is, so call a helper function to split that off. +% \begin{macrocode} +\def\TP@elt#1#2{% + \let\TP@global\@empty + \TP@do{#1}#2\TP@do} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TP@f@shift} +% Helper for |\TP@do|. +% \begin{macrocode} +\def\TP@f@shift#1#2{% + \TP@testopt{#1}{\TPkeycommand{#1}{#2}}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TP@i@shift} +% Helper for |\TP@do|. +% \begin{macrocode} +\def\TP@i@shift#1#2{% + \TP@testopt{#1}{\TP@instance{#1}{#2}}} +% \end{macrocode} +% +% declaration |hd =i{head} \fooo| \\ +% use |hd = mine|\\ +% makes |\fooo| shorthand for |\UseInstance{head}{mine}| +% +% also allowed: |hd = \UseTemplate{head}{...}{...}|\\ +% in case you want to use an unnamed instance of type |head| +% in this place. +% \end{macro} +% +% \begin{macro}{\TP@instance} +% \begin{macrocode} +\def\TP@instance#1#2#3{ + \TP@define@key{#1}{ + \TPinstance#3{#2}{##1}}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TPinstance} +% \begin{macrocode} +\def\TPinstance#1#2#3{ + \expandafter\ifx\@car#3.\@nil\UseTemplate + \typeout{\string\UseTemplate\space seen} +% \end{macrocode} +% +% code below from |\TPkeycommand| (should be combined and cleaned up) +% at this point one should also check if first arg of |\UseTemplate| +% corresponds to |#2| and if not complain (not done) +% +% \begin{macrocode} + {\TP@fudge#3} + \expandafter\addto@hook\expandafter\TP@toks\expandafter{ + \expandafter\KV@toks\expandafter{\TP@gtemp} + \edef#1{\the\KV@toks}} + \else + \@letinstance#1{#2}{#3} + \expandafter\expandafter\expandafter\addto@hook + \expandafter\expandafter\expandafter\TP@toks + \expandafter\expandafter\expandafter{ + \@letinstance#1{#2}{#3}} + \fi} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\TP@do} +% Case switch on the possible key types. +% \begin{macrocode} +\def\TP@do#1#2#3\TP@do{ + \ifx#2f + \TP@f@shift{#1}#3\@@ + \else\ifx#2n + \TP@testopt{#1}{\TPnamecommand{#1}}#3\@@ + \else\ifx#2l + \TP@testopt{#1}{\TP@register\setlength{#1}}#3\@@ + \else\ifx#2L + \TP@testopt{#1}{\TP@fakeregister\setlength\fake@length + {#1}}#3\@@ + \else\ifx#2c + \TP@testopt{#1}{\TP@register\SetInternalCounter{#1}}#3\@@ + \else\ifx#2C + \TP@testopt{#1}{\TP@fakeregister\SetInternalCounter\@tempcnta + {#1}}#3\@@ + \else\ifx#2b + \TP@testopt{#1}{\TP@setboolean{#1}}#3\@@ + \else\ifx#2s + \TP@testopt{#1}{\TP@booltest{#1}}#3\@@ + \else\ifx#2g + \TP@testopt{#1}{\TP@setgeneral{#1}}#3\@@ + \else\ifx#2x + \TP@testopt{#1}{\TP@setx{#1}}#3\@@ + \else\ifx#2i + \TP@i@shift{#1}#3\@@ + \else\ifx#2+ + \def\TP@global{\addto@hook\TP@toks{\global}} + \TP@do{#1}#3\TP@do + \else + \PackageError{template}{Unknown~key~type~ (#2)~for~#1}\@eha + \fi + \fi + \fi + \fi + \fi + \fi + \fi + \fi + \fi + \fi + \fi + \fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TP@testopt} +% \begin{macrocode} +\def\TP@testopt#1#2{ + \@ifnextchar[%] + {\TP@test@pt{#1}{#2}} + {\TP@zap@@{#2}}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TP@zap@@} +% \begin{macrocode} +\def\TP@zap@@#1#2\@@{ + #1{#2}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TP@test@pt} +% \begin{macrocode} +\def\TP@test@pt#1#2[#3]#4\@@{ + #2 + {#4} + \begingroup + \TP@toks{} + \let\TP@remove\@gobble + \csname KV@\TP@name @#1\endcsname{#3} + \expandafter + \endgroup + \expandafter + \toks@\expandafter{ + \csname KV@\TP@name @#1\expandafter\endcsname\expandafter + {\the\expandafter\TP@toks\expandafter}\the\toks@}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TP@setgeneral} +% \begin{macrocode} +\def\TP@setx#1#2{ + \TP@define@key{#1}{\addto@hook\TP@toks{#2}}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TP@setgeneral} +% \begin{macrocode} +\def\TP@setgeneral#1#2{ + \TP@define@key{#1}{#2}} +% \end{macrocode} +% +% \end{macro} +% +% \begin{macro}{\TP@setboolean} +% \begin{macrocode} +\def\TP@setboolean#1#2{ + \expandafter\let\csname if#2\endcsname\iftrue + \TP@define@key{#1}{ + \TPsetboolean{#2}{##1}} +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TPsetboolean} +% Modify so the boolean does not need to have been +% declared with |\newif| +% \begin{macrocode} +\def\TPsetboolean#1#2{ + \expandafter\ifx\csname if#2\endcsname\relax + \PackageError{template}{Bad~boolean~setting~#1=#2}\@eha + \else + \expandafter\let\csname if#1\expandafter\endcsname + \csname if#2\endcsname + \expandafter\addto@hook\expandafter\TP@toks\expandafter{ + \expandafter\let + \csname if#1\expandafter\endcsname\csname if#2\endcsname} + \fi} +% \end{macrocode} +% +% \end{macro} +% +% \begin{macro}{\TP@booltest} +% \begin{macrocode} +\def\TP@booltest#1#2{ + \TP@define@key{#1}{ + \TPbooltest{##1}#2}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TP@true} +% \begin{macrocode} +\def\TP@true{true} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TPbooltest} +% \begin{macrocode} +\def\TPbooltest#1#2#3{ +% no error check on this yet. + \def\@tempa{#1} + \ifx\@tempa\TP@true + \addto@hook\TP@toks{#2} + \else + \addto@hook\TP@toks{#3} + \fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TP@register} +% This is normally called automatically by |\DeclareTemplate|. +% +% Command for setting a template attribute whose name +% corresponds directly to a tex count or length register\\ +% |#1| the fuction to set the value eg \setlength.\\ +% |#2| key name.\\ +% |#3| the register to set. +% +% This command \emph{fully evaluates} the argument at declare time, +% and assigns the value to the register. It also passes an assignment +% of the register to the final value into the parameter list for the +% template. +% +% If the value is a call to |\DelayEvaluation|, don't evaluate it now, +% just pass the whole assignment to the template. +% +% [Note that the code below contains some : being used in csnames in other files +% this is currently being allowed by default but in this one it is right now +% manually added --- need fixing either way] +% \begin{macrocode} +\catcode`\:=11\relax +\def\TP@register#1#2#3{ + \TP@define@key{#2}{ + \expandafter\ifx\@car##1\@nil\DelayEvaluation + \addto@hook\TP@toks{#1#3{##1}} + \else +% \end{macrocode} +% +% +% check for |\MultiSelection| creeping up and if so add something like +% +% \begin{verbatim} +% \setlength\register{\ifcase\selector \or value1 \or value2 +% ... \else valueotherwise \fi} +% \end{verbatim} +% to |\TP@toks|. +% +% \begin{macrocode} + \expandafter\ifx\@car##1..\@nil\MultiSelection + \begingroup + \TP@multi#1#3##1 + \endgroup +% \end{macrocode} +% +% +% there are probably better ways to do this :-) +% +% \begin{macrocode} + \expandafter\in@\expandafter\DelayEvaluation + \expandafter{\the\TP@multi@toks} + \ifin@ + \addto@hook:No\TP@toks + {\expandafter#1\expandafter#3\expandafter + {\the\TP@multi@toks}} + \else + \addto@hook:No\TP@toks + {\expandafter #3 + \expandafter= \the\TP@multi@toks\relax} + \fi +% \end{macrocode} +% +% +% otherwise do as before +% +% \begin{macrocode} + \else + #1#3{##1} + \addto@hook:No\TP@toks + {\expandafter #3 + \expandafter= \the#3\relax} + \fi\fi}} +% \end{macrocode} +% \end{macro} +% +% +% +% +% \begin{macro}{\addto@hook:No} +% \begin{macrocode} +\def\addto@hook:No#1#2 { + \expandafter\addto@hook\expandafter#1\expandafter{#2}} +\catcode`\:=12\relax +% \end{macrocode} +% \end{macro} +% +% +% +% +% \begin{macro}{\DelayEvaluation} +% \begin{macrocode} +\let\DelayEvaluation\@firstofone +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TPkeycommand} +% Same for macro names. Again usually called automatically when +% declaring a new template.\\ +% |#1| the key.\\ +% |#2| Determines how many arguments the function should have.\\ +% |#3| The macro to be defined. +% +% If the `|##1|`, the value passed as the argument of the key |#1| +% to the macro |#3| is invoked starts with |\FunctionInstance|, then a +% special procedure is taken. Instead of defining a macro with the +% specified number of arguments, the paramater list of the nested +% function instance is parsed, and |#3| is defined to be a macro +% expanding to that instance. In this case the specified template +% is responsible for picking up the requested number of +% arguments. (This is \emph{not} checked.) +% \begin{macrocode} +\def\TP@define@key#1#2{% + \expandafter\def + \csname KV@\TP@name @#1\expandafter\endcsname + \expandafter##\expandafter1 + \expandafter{ + \expandafter\TP@remove + \csname KV@\TP@name @#1\expandafter\endcsname + \TP@global + #2}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TP@remove} +% \begin{macrocode} +\def\TP@remove#1{ + \def\@tempa##1#1##2##3#1##4\@@{ + \toks@{##1##3}} + \expandafter\@tempa\the\toks@#1\relax#1\@@} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TPkeycommand} +% \begin{macrocode} +\def\TPkeycommand#1#2#3{ + \TP@define@key{#1}{ +% \end{macrocode} +% +% |##1| can either be arbitrary inline code, in which case it will be +% defined with |\newcommand[val]| so it needs to use |#1| -- |#val|. +% +% define it locally here +% \begin{macrocode} + \functiondefine#2#3{##1} +% \end{macrocode} +% +% \begin{macrocode} + \expandafter\addto@hook\expandafter\TP@toks\expandafter{ + \the\TP@toksb{##1}} + } + } +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\TPnamecommand} +% Here is the extended version that tries to deal with +% |\MultiSelection|. +% +% In case of `n' keys there is no evaluation at declaration time so it +% is not sensible to look for |\DelayEvaluation|. For this reason as +% well as for the fact that |\TP@multi| above assumes that it deals +% with registers that can be accessed via |\the| we have to use a +% different command to handle the |\MultiSelection| args but +% it is essentially doing the same. +% +% \begin{macrocode} +\catcode`\:=11\relax +\def\TPnamecommand#1#2{ + \TP@define@key{#1}{ + \expandafter\ifx\@car##1..\@nil\MultiSelection + \begingroup + \TP@multi@name##1 + \endgroup + \addto@hook:No\TP@toks + {\expandafter\def\expandafter#2\expandafter + {\the\TP@multi@toks}} + \else + \def#2{##1} % setting it? + \addto@hook\TP@toks{\def#2{##1}} + \fi + } + } +\catcode`\:=12\relax +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TP@multi@name} +% \begin{macrocode} +%\catcode`\:=12\relax +\def\TP@multi@name #1#2#3#4{ + \global\TP@multi@toks{\ifcase #2} + \@for\next:=\@empty #3\do{ + \TP@do@multi\next +} + \global\addto@hook\TP@multi@toks{\else #4\fi} + } +%\catcode`\:=11\relax +% \end{macrocode} +% \end{macro} +% +% +% +% +% +% +% +% +% \begin{macro}{\DeclareInstance} +% |{type}{instname}{templatename}{keyval}| +% \begin{macrocode} +\def\DeclareInstance{\DeclareCollectionInstance{}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\DeclareCollectionInstance} +% |{collection}{type}{instname}{templatename}{keyval}| +% \begin{macrocode} +\long\def\DeclareCollectionInstance#1#2#3#4{ + \expandafter\TP@DCI\csname<#1>#2/#3\endcsname{#2/#4}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\UseCollection} +% |{type}{collection}| +% \begin{macrocode} +\def\UseCollection#1#2{ + \expandafter\edef\csname TP@<#1>\endcsname{ + {#2} + \TP@args{#1}}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@letinstance} +% |\internalcommand{type}{instname}| +% \begin{macrocode} +\def\@letinstance#1#2#3{ + \expandafter\let\expandafter#1\csname + \@ifundefined{\TP@prefix{#2}#3} + {<>#2/} + {\TP@prefix{#2}} + #3 + \endcsname} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\UseInstance} +% |{type}{instname}| +% \begin{macrocode} +\def\UseInstance#1#2{ + \@letinstance\@tempa{#1}{#2} + \ifx\@tempa\relax + \INSTANCEundefined + \else + \expandafter\@tempa + \fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TP@fudge} +% \begin{macrocode} +\long\def\TP@fudge#1#2#3{% + \TP@DCI\TP@gtemp{#2/#3}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\ShowTemplate} +% Some extension to |\ShowTemplate| so that we also get to see the +% restrictions if any +% \begin{macrocode} +\def\ShowTemplate#1#2{ + \typeout{*******~ Template:~ #1/#2~ *******} + \typeout{*} + \typeout{*~ Defaults:} + \typeout{*} + \typeout{\string\TPD>/#1/#2= + \expandafter\meaning\csname TPD>/#1/#2\endcsname} + \typeout{*} + \typeout{*~ Restrictions:} + \typeout{*} + \typeout{\string\TPR>/#1/#2= + \expandafter\meaning\csname TPR>/#1/#2\endcsname} + \typeout{*} + \typeout{*~ Body:} + \typeout{*} + \expandafter\show\csname TP>/#1/#2\endcsname} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\ShowCollectionInstance} +% \begin{macrocode} +\def\ShowCollectionInstance#1#2#3{ + \typeout{*******~ Instance:~ <#1>#2/#3~ *******} + \typeout{*} + \expandafter\show\csname <#1>#2/#3\endcsname} +\def\ShowInstance{\ShowCollectionInstance{}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TP@fakeregister} +% |{setcomand}{privateregister}{key}{internalcode}| +% \begin{macrocode} +\catcode`\:=11\relax +\def\TP@fakeregister#1#2#3#4{ + \TP@define@key{#3}{ + \expandafter\ifx\@car##1..\@nil\DelayEvaluation +% \end{macrocode} +% In the v0.08 version of \texttt{template.dtx} a +% |\DelayEvaluation| for a faked register would simply be equiv to +% a |\def| (code is below commented out). The negative side effect +% of this is that something like |=L| used with |\DelayEvaluation| +% would not allow for calc syntax since it would end up as +% |\def|\allowbreak|\foo|\allowbreak|{a+b}|. The code below changes +% this to first assign to a scratch register (at runtime) and then +% do an |\edef|. Could be coded differently to save space (at cost +% of time) +% \begin{macrocode} +% \addto@hook\TP@toks{\def#4{##1}} + \addto@hook\TP@toks{#1#2{##1}\edef#4{\the#2}} + \else +% \end{macrocode} +% +% +% Otherwise same game for fake registers except that instead of +% passing the register to |\TP@multi| we pass a temp fake one and +% doing a def instead of using |\setlength| or |\setcounter| +% +% and i haven't done the |\DelayEvaluation| bit for that case! as +% i'm not sure what the best approach is for those +% things\footnote{we might disallow it for that case in general --- +% not a nice rule but an explainable one} +% +% \begin{macrocode} + \expandafter\ifx\@car##1..\@nil\MultiSelection + \begingroup + \TP@multi#1#2##1 + \endgroup + \addto@hook:No\TP@toks + {\expandafter\def\expandafter#4\expandafter + {\the\TP@multi@toks}} + \else + #1#2{##1} + \addto@hook:No\TP@toks + {\expandafter + \def + \expandafter + #4 + \expandafter + {\the#2}} + \fi\fi}} +\catcode`\:=12\relax +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\TP@multi@toks} +% \begin{macrocode} +\newtoks\TP@multi@toks +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TP@multi} +% \marg{operation} \marg{register} |\MultiSelection| +% \marg{selector} \marg{case-list} \marg{else-case} +% +% This command builds up the |\ifcase| code from the three arguments +% of |\MultiSelection| and stores it in |\TP@multi@toks|. This code is +% supposed to be run in a group so a) we don't have to initialise +% |\TP@multi@toks| and b) all changes to the used registers not +% affecting the outside. +% +% Warning: this code uses |\@for| which will not work if put into files where +% ``:'' was made a letter! +% +% \begin{macrocode} +%\catcode`\:=12\relax +\def\TP@multi #1#2#3#4#5#6{ + \global\TP@multi@toks{\ifcase #4} + \@for\next:=\@empty #5\do{ + \expandafter \expandafter\expandafter\ifx\expandafter + \@car\next..\@nil\DelayEvaluation + \TP@do@multi\next + \else + #1#2{\next} + \TP@do@multi{\the#2} + \fi + } + \global\addto@hook\TP@multi@toks{\else #6\fi} + } +%\catcode`\:=11\relax +% \end{macrocode} +% +% Since we intend to add |\or| to |\TP@multi@toks| within the |\@for| +% loop we have to hide it carefully or else we will get some unmatched +% conditionals. +% \end{macro} +% +% \begin{macro}{\TP@do@multi} +% \begin{macrocode} +\def\TP@do@multi#1{ + \global\expandafter\addto@hook\expandafter\TP@multi@toks + \expandafter{\expandafter\or #1 } +} +% \end{macrocode} +% \end{macro} +% +% Since i like to set things like |item-label-text| using this +% mechanism i need to handle the `n' key specially. +% +% Actually i could have probably extended |\TPkeycommand| thus making +% this generally available to all f\meta{number} keys but was too lazy +% (or too stupid) to get it right first time so settled for the simple +% solution. +% +% So |\TP@do| now calls |\TPnamecommand| for the `n' key. looks like +% this thus be fixed some time soon +% +% +% +% +% +% +% \begin{macro}{\fake@length} +% \begin{macrocode} +\newlength\fake@length +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\IfExistsInstanceTF} +% tests that there is a \emph{default} definition +% taken from xinitials.dtx: +% \begin{macrocode} +\def\IfExistsInstanceTF#1#2{ + \expandafter\ifx\csname <>#1/#2\endcsname\relax + \expandafter\@secondoftwo + \else + \expandafter\@firstoftwo + \fi} +% \end{macrocode} +% +% FMi: what happens if we are in collection FOO and there exists an +% instance I for type T within this collection but there doesn't exist +% an instance in the empty collection? +% +% What would happen if \ldots\ --- not clear to me what the sematics +% really should be. The code below is not better only different( and +% slower).\footnote{fix semantics} +% \begin{macrocode} +\def\IfExistsInstanceTF#1#2{ + \@letinstance\@tempa{#1}{#2} + \ifx\@tempa\relax + \expandafter\@secondoftwo + \else + \expandafter\@firstoftwo + \fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\DeclareRestrictedTemplate} +% Setting it up: +% +%| \DeclareRestrictedTemplate|\\ +% |{T-type} {new-T-name} {source-T-name} {keyvals}| +% +% This uses the same code as {T-type} {source-T-name} but adds +% settings from {keyvals} +% \begin{macrocode} +\def\DeclareRestrictedTemplate#1#2#3#4{ + % CCC do we need a group here?? + \letcc { TPD>/#1/#2 } { TPD>/#1/#3 } + \letcc { TP>/#1/#2 } { TP>/#1/#3 } + \TP@get@restrictions {#1/#3} % puts stuff in \TP@toks + \setkeys{\the\TP@toksc} % temp OK? + {#4} % adds stuff to \TP@toks + \TP@store@restrictions {#1/#2}{#1/#3}} % stores the contents of + % \TP@toks +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\letcc} +% \begin{macrocode} +\def\letcc#1#2{ + \expandafter \let + \csname #1 \expandafter \endcsname + \csname #2 \endcsname} +% \end{macrocode} +% \end{macro} +% +% Internals: +% +% \begin{macro}{\TP@get@restrictions} +% These could probably be inlined, even when they do something! +% \begin{macrocode} +\def\TP@get@restrictions#1{ % Returns to \TP@toks the restrictions + % stored in the TP-structure (at present + % in YAM) of the template #1 + \@ifundefined {TPR>/#1} + {\TP@toks {}} + {\TP@toks \expandafter\expandafter\expandafter + {\csname TPR>/#1\endcsname}} + \@ifundefined {TPO>/#1} + {\@namedef {TPO>/#1} {#1} + \TP@toksc {#1} } % temp OK? + {\TP@toksc \expandafter\expandafter\expandafter + {\csname TPO>/#1\endcsname} }} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\TP@store@restrictions} +% \begin{macrocode} +\def\TP@store@restrictions#1#2{ % Stores the contents of \TP@toks + % in the TP-structure (at present + % in YAM) of the template #1 + \expandafter\edef\csname TPR>/#1\endcsname{\the\TP@toks} + \@ifundefined{TPO>/#2} + {\@namedef{TPO>/#1}{#2}} + {\letcc{TPO>/#1}{TPO>/#2}}} +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +%</package> +% \end{macrocode} +% +% \Finale +% + + + diff --git a/Master/texmf-dist/source/latex3/template/template.ins b/Master/texmf-dist/source/latex3/template/template.ins new file mode 100644 index 00000000000..b8fe0900dc8 --- /dev/null +++ b/Master/texmf-dist/source/latex3/template/template.ins @@ -0,0 +1,12 @@ +\input docstrip +\keepsilent +\askforoverwritefalse + +\preamble +\endpreamble + +\generate{% + \file{template.sty}{\from{template.dtx}{package}} + } + +\endbatchfile diff --git a/Master/texmf-dist/source/latex3/xinitials/xinitials.dtx b/Master/texmf-dist/source/latex3/xinitials/xinitials.dtx new file mode 100644 index 00000000000..1bc00c320ea --- /dev/null +++ b/Master/texmf-dist/source/latex3/xinitials/xinitials.dtx @@ -0,0 +1,553 @@ +% \iffalse +%% +%% $Header: /usr3/users/latex3/design/consolidation/CURRENT/RCS/xinitials.dtx,v 1.7 2000/01/28 13:39:56 latex3 Exp $ +%% +%% (C) Copyright 1999-2000 Frank Mittelbach +%% All rights reserved. +%% +%% Not for general distribution. In its present form it is not allowed +%% to put this package onto CD or an archive without consulting the +%% the authors. +%% +%<*dtx> + \ProvidesFile{xinitials.dtx} +%</dtx> +%<package>\NeedsTeXFormat{LaTeX2e} +%<package>\ProvidesPackage{xinitials} +%<signature>\ProvidesFile{xinitials.sig} +%<driver>\ProvidesFile{xinitials.drv} +% \fi +% \ProvidesFile{xinitials.dtx} + [2000/01/28 v0.1h templates for initials] +% +% \iffalse +%<*driver> + \documentclass{ltxdoc} + \usepackage{textcomp} +% \usepackage{ldcdoc} + +% next three definitions are big hacks to run the file +% without the above packages +% +\newcommand\NoValue{\texttt{\textbackslash NoValue}} + +\makeatletter +\newenvironment{TemplateInterfaceDescription}[1] + {\subsection{The Template Type `#1'}% + \begingroup + \@beginparpenalty\@M + \description + \def\TemplateArgument##1##2{\item[Arg: ##1]##2\par}% + \def\TemplateSemantics{\enddescription\endgroup + \subsubsection*{Semantics:}}% + } + {\par\bigskip} + +\newenvironment{TemplateDescription}[2] + {\subsection{The Template `#2' (type #1)}% + \subsubsection*{Attributes:}% + \begingroup + \@beginparpenalty\@M + \description + \def\TemplateKey##1##2##3##4{\item[##1 (##2)]##3% + \ifx\TemplateKey##4\TemplateKey\else +% \hskip0ptplus3em\penalty-500\hskip 0pt plus 1filll Default:~##4% + \hfill\penalty500\relax\qquad \hbox{}\hfill Default:~##4% + \nobreak\hskip-\parfillskip\hskip0pt\relax + \fi + \par}% + \def\TemplateSemantics{\enddescription\endgroup + \subsubsection*{Semantics \& Comments:}}% + } + {\par\bigskip} + +\makeatother + +\newcommand\LaTeXplus{\LaTeXe$*$} +\newcommand\key[1]{\textbf{#1}} + + \EnableCrossrefs + \CodelineIndex + \begin{document} + \DocInput{xinitials.dtx} + \PrintIndex + \end{document} +%</driver> +% \fi +% +% \CheckSum{125} +% +% \GetFileInfo{xinitials.dtx} +% +% \title{The \textsf{xinitials} package\thanks{This file +% has version number \fileversion, last +% revised \filedate.}} +% \author{FMi} +% \date{\filedate} +% \maketitle +% +% \tableofcontents +% +% \section{Introduction} +% +% This module implements an interface for producing initial +% characters. It was originally written as an exercise for working +% with the template interface of \LaTeXplus{} and survived many +% internal changes of the new methods. +% +% +% \section{Interfaces} +% +% The template implemented by this module uses absolute dimensions to +% produce the initials, something which I found being a natural way to +% achieve the desired results. There are other ways to specify how +% such initials should look; for example there exists a \LaTeXe{} +% package called \texttt{lettrine} by Daniel Flippo which makes the +% specifications relative to the current font used for the initials. +% It would be interesting to see his approach being reimplemented as +% an alternative template to the one I called \texttt{std}. +% +% +% \begin{TemplateInterfaceDescription}{initial} +% +% \TemplateArgument{1} +% {Quote to the left of the initial (if any) or \NoValue} +% +% \TemplateArgument{2} +% {Initial character} +% +% \TemplateArgument{3} +% {Text following the initial that is handled specially, e.g., +% set in small capitals (if any) or \NoValue } +% +% \TemplateSemantics +% Typesets argument 2 as an initial character with argument 1 being +% any special material typeset to the left of the initial (e.g., a +% quote) and argument 3 being all material that is typeset in a +% special fashion to the right of the initial. +% +% In typical document commands arguments 1 and 3 are most likely +% implemented as optional, if implemented at all. +% +% \end{TemplateInterfaceDescription} +% +% +% \begin{TemplateDescription}{initial}{std} +% +% \TemplateKey{initial-font}{f0} +% {Font specification to use for the initial glyph itself.} +% {None} +% +% \TemplateKey{initial-format}{f1} +% {Action to be taken on the initial. +% This action takes one argument: the initial glyph formated +% using \key{initial-font} but not including +% the left and right separation spaces from \key{quote-sep} and +% \key{text-sep}. The result if this action is further +% manipulated by other keys.} +% {Process argument unchanged} +% +% \TemplateKey{text-format}{f1} +% {Action to be take on the special text following +% the initial. This action takes one argument: argument 3 of the +% template if not \NoValue.} +% {Produce Caps\&SmallCaps} +% +% \TemplateKey{quote-format}{f1} +% {Action to be taken on a quotation glyph to the left of the +% initial (i.e., argument 1 of the template, if not \NoValue). +% This action takes one argument: the quote glyph.} +% {Process argument unchanged} +% +% \TemplateKey{parshape-list}{f0} +% {List of dimensions (separated by comma) specifying two things: +% For how many lines the paragraph needs indentation due do the +% initial, i.e., how far does it drop into the paragraph +% (number of dimensions) and how much each line should +% be indented in addition to the actual width of the initial +% including its offsets from \key{text-sep} and \key{h-adjust} +% (value of the individual dimension which +% could be negative) --- because of the commas in the list the +% whole list has to be surrounded by braces.} +% {Initial does not drop: \texttt{0pt}} +% +% \TemplateKey{v-adjust}{l} +% {Dimension used to adjust the initial (see above) +% vertically (positive values raise it). Default value places +% the initial at the baseline of the +% last indented paragraph line.} +% {\texttt{0pt}} +% +% \TemplateKey{h-adjust}{l} +% {Dimension used to adjust the initial horizontally (positive +% values move it to the right). Default value places the initial +% flush left with the text margin.} +% {\texttt{0pt}} +% +% \TemplateKey{quote-sep}{l} +% {Dimension specifying the space between the initial +% and any ``quote material'' on its left (see also +% \key{initial-format}).} +% {\texttt{0pt}} +% +% \TemplateKey{text-sep}{l} +% {Dimension specifying the space between the initial +% and the paragraph lines on the right (see also +% \key{parshape-list}). This key is available for convenience, it +% is equivalent of extending all values in \key{parshape-list} +% by this amount.} +% {\texttt{0pt}} +% +% \TemplateKey{nominal-height}{l} +% {Dimension specifying the height of the initial as seen by +% \TeX. If not specified, the height is calculated as the actual +% dimension of the initial (after applying \key{initial-format}) +% plus the value of \key{top-sep}.} +% {Unspecified} +% +% \TemplateKey{top-sep}{l} +% {Dimension specifying an extra separation from preceding +% material by pretending that the initial larger (or smaller) +% than it actually is (see also \key{nominal-height} for special +% effects).} +% {\texttt{0pt}} +% +% \TemplateSemantics +% The template will raise an error if used in horizontal mode. It +% will also complain if it finds that it is used with a special +% |\parshape| in force (other than the one produced from list environments. +% +% \end{TemplateDescription} +% +% +% +% +% \subsection{The Document Interface} +% +% The following two commands should be viewed as examples on how one +% could set up a document interface for initials. +% +% \DescribeMacro\Initial +% The |\Initial| command takes one mandatory argument which is the +% initial character. It may be followed by an optional argument, +% which, if present, denotes the portion of text following the initial +% character that should be handled somewhat special (for example being +% set in caps \& smallcaps). It can also take an optional argument +% before the mandatory one, which, if present, contains material that +% should be placed to the left of the initial (in the margin). It can +% be used, for example, for placing quotes at this point. +% +% The mandatory argument can only contain a straight \textsc{ascii} +% letter and not something like an accented character. The reason is +% that the |\Initial| command tries to find a template instance using +% the the argument as the potential name.\footnote{This is for +% convenience only, if one often needs special initial one would better +% define a different interface.} If it find such an instance it will +% use it, otherwise it will use the instance with name +% \texttt{default}. This scheme makes it possible to declare one +% instance (\texttt{default}) with values being suitable for most +% characters and define overwriting instances for those character +% which need special treatment. +% +% +% \DescribeMacro\ExtendedInitial +% The |\ExtendedInitial| is an extension of the interface provided by +% the |\Initial| command. It accepts a star in which case a following +% optional argument is interpreted as the key/value specification for +% the template \texttt{std} of type \texttt{initial} which is then +% constructed on the fly. The remaining three arguments (optional, +% mandatory, optional) are as in the case of |\Initial|. If no star is +% present the first optional argument is interpreted as the name of +% the template instance. If it is defined then it is used; if not the +% instance with name \texttt{default} is used. This way the mandatory +% argument is allowed to contain any \TeX{} code including accents and +% the like. For example, +%\begin{verbatim} +% \ExtendedInitial [Uumlaut][``]{\"U}[ber den sieben Bergen] bei ... +%\end{verbatim} +% would use the instance with name \texttt{Uumlaut} (which would need +% to be defined) to typeset the `\"U' as initial with a left double +% quote on the left and the text `ber den sieben Bergen' handled +% specially. +% +% \StopEventually{} +% +% \section{Implementation} +% +% \subsection{The template implementation} +% +% \begin{macrocode} +%<*package> +% \end{macrocode} +% +% For this module we need the galley support and of course the +% template module. +% \begin{macrocode} +\RequirePackage{template,galley2} +% \end{macrocode} +% +% Getting our private coding environment ready\ldots +% \begin{macrocode} +\IgnoreWhiteSpace +\catcode`\:=11\relax +% \end{macrocode} +% +% At some point below we need a register to do some calculations. We +% could probably get away with a scratch one but here I allocated a +% private one to avoid having to think about the implications :-) +% \begin{macrocode} +\newlength\initial@raise +% \end{macrocode} +% +% We also need a box register to be able to measure the size of the +% initial and its frills, again this could probably be done with a +% general purpose register but\ldots +% \begin{macrocode} +\newbox\initial@box +% \end{macrocode} +% +% +% +% \bigskip +% +% The \texttt{initial} template type has three arguments: +% \begin{macrocode} +\DeclareTemplateType{initial}{3} +% \end{macrocode} +% +% +% +% \bigskip +% +% \begin{macrocode} +\DeclareTemplate{initial}{std}{3}{ +% \end{macrocode} +% The font to be used for the initial does not have any default +% value: it must be specified. +% \begin{macrocode} + initial-font =f0 \initial@font, +% \end{macrocode} +% All other keys have default values but we do not specify the here. +% \begin{macrocode} + h-adjust =L \initial@hadjust, + initial-format =f1 \initial@charformat, + nominal-height =L \initial@height, + parshape-list =f0 \initial@parshape, + quote-format =f1 \initial@quoteformat, + quote-sep =L \initial@leftsep, + text-format =f1 \initial@textformat, + text-sep =L \initial@rightsep, + top-sep =L \initial@topsep, + v-adjust =L \initial@vadjust, +} +{ +% \end{macrocode} +% Specifying the defaults here saves space, otherwise each instance would +% contain them. +% \begin{macrocode} + \let\initial@vadjust\z@ + \let\initial@hadjust\z@ + \let\initial@leftsep\z@ + \let\initial@rightsep\z@ + \let\initial@height\maxdimen + \let\initial@topsep\z@ + \let\initial@parshape\z@ + \let\initial@quoteformat\@firstofone + \let\initial@charformat\@firstofone + \let\initial@textformat\textsc + \DoParameterAssignments +% \end{macrocode} +% +% We first check if we are in vertical mode and if not raise an error. +% \begin{macrocode} + \ifvmode \else + \PackageError{xinitials}{Initial~ inside~ paragraph} + {Initials~ can~ only~ be~ used~ at~ the~ beginning~ + of~ a~ paragraph} + \par + \fi +% \end{macrocode} +% We then typeset the initial character in a box to be able to +% measure it. The purpose of this measurement is to determine the +% width of the cutout, thus we have to include the specified +% horizontal adjustments on the left and the right. +% \begin{macrocode} + \sbox\initial@box{ + \kern\initial@hadjust + \initial@charformat{ + \initial@font #2 + } + \kern\initial@rightsep + } +% \end{macrocode} +% We then prepare the cutout using |\setGALleftparshape:nnn| (see +% the module \texttt{galley2} for an explanation of this command). +% \begin{macrocode} + \setGALleftparshape:nnn \z@ {\wd\initial@box} + \initial@parshape +% \end{macrocode} +% It would be a problem if the paragraph containing the initial +% would be split across the page, so we forbid paragraph splits +% for the next paragraph. (We use the value |-3| which indicates +% that it is allowed to break before the paragraph). +% \begin{macrocode} + \setGALbreak:n {-3} + \noindent +% \end{macrocode} +% Next lines of code calculate the vertical dimension by which we +% have to raise (normally lower in fact) the . The value of +% |\parshape@linecnt| which is used in the formula was calculated +% by |\setGALleftparshape:nnn|. +% \begin{macrocode} + \setlength\initial@raise{-\baselineskip*(\parshape@linecnt-2) + -\initial@vadjust} +% \end{macrocode} +% +% We then calculate the vertical space that the initial should +% occupy (with respect to the first baseline of the paragraph). +% If |\initial@height| is |\maxdimen|, i.e., was not set then the +% effective height of the initial should be its real height +% (|\height| reduced by the amount we drop (|\initial@raise|) plus +% the extra space requested (|\initial@topsep|). If however the +% value of |\initial@height| differs from |\maxdimen| we use that +% value directly.\footnote{Writing the documentation for this I +% notice that it might be better to change the logic here +% completely: assume that the initial sticks out of the +% paragraph. Now we have to account for this sticking out to avoid +% that the initial bumps into the previous paragraph. However, if +% we do it as it is currently implemented then this vertical extend +% is actually a property of the initial character box. This means +% that if we have a page break before the paragraph containing the +% initial we do get a paragraph whose first line is far lower on +% the page than in the care there would be a normal paragraph (in +% other words the initial would not stick into the top margin but +% be confined to the body text area). This may be what is intended, +% on the other hand it may be not. So perhaps one need to allow to +% contribute this vertical space to the inter-paragraph material.} +% \begin{macrocode} + \ifdim\initial@height=\maxdimen + \def\initial@height{\height+\initial@raise+\initial@topsep} + \fi +% \end{macrocode} +% +% Now we about ready to typeset the initial. We put the whole thing +% into an |\llap|. If we do have some material to the left of the +% initial we set it in a way that its height and its width has no +% influence. To prevent the width of the material effecting the +% placement of the actual initial character we set the material in +% an |\llap|. The right corner of this |\llap| will be at the left +% paragraph boundary. But the initial might have been moved +% horizontally so that we have to account for this space +% (|-\initial@hadjust|). In addition there should be a separation +% between the material and the initial of width +% |\initial@leftsep|. Both spaces are added as |\kern|s to the +% |\llap| box to provide the necessary separation. +% \begin{macrocode} + \llap{ + \llap{\IfValueT{#1}{\smash{\initial@quoteformat{#1}}} + \kern-\initial@hadjust + \kern\initial@leftsep} +% \end{macrocode} +% Now we typeset the initial using |\raisebox| and the values we +% have calculated above. We are as far as typesetting is concerned +% at the place where the text following the initial would +% start. Thus to be able to typeset the initial character we have +% to first back off to the left margin. We do this by placing the +% whole thing inside an |\rlap| so that we do not occupy any +% horizontal space and add a kern of width +% |\parshape@firstlineindent| inside it after the |\raisebox|. This +% will push the initial to the left by the right amount and +% afterwards we are still at the correct point to typeset the text +% following the initial.\footnote{For those who find this +% mysterious, please have a look at the implementation of +% \texttt{\textbackslash parshape@setup} in \texttt{galley2}.} +% \begin{macrocode} + \rlap{ + \raisebox{\initial@raise} + [\initial@height] + [\z@] + {\box\initial@box} + } + \kern\parshape@firstlineindent + } +% \end{macrocode} +% If there is any text that should be treated specially (in +% argument \#3) then we typeset that now otherwise we are done. +% \begin{macrocode} + \IfValueT{#3} + { \initial@textformat{#3} } +} +% \end{macrocode} +% +% \begin{macrocode} +\catcode`\:=12\relax +%</package> +% \end{macrocode} +% +% +% +% +% \subsection{The document commands} +% +% \begin{macrocode} +%<*signature> +\RequirePackage{xinitials} +\RequirePackage{xparse} +\IgnoreWhiteSpace +% \end{macrocode} +% +% +% \begin{macro}{\Initial} +% Default document command which takes one mandatory argument (the +% initial) and two optional arguments (any ``quote material'' and +% any text handled specially). +% +% It runs the instance \texttt{initial}/\meta{initial-char} (i.e., +% a different instance per character) if defined or otherwise runs +% the instance \texttt{initial/default}. Thus a class providing +% this command has to define at least the latter instance. +% \begin{macrocode} +\DeclareDocumentCommand \Initial {omo} + { + \IfExistsInstanceTF{initial}{#2} + {\UseInstance{initial}{#2}} + {\UseInstance{initial}{default}} + {#1}{#2}{#3} + } +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\ExtendedInitial} +% An extension of the above document command is the following +% version. This form of |\ExtendedInitial| will support a star +% form, which, if used, expects an optional argument that contains +% key value settings for the \texttt{std} template of type +% \texttt{initial}. It is then followed by three more arguments +% like in the case if the |\Initial| command. If no star is present +% then the optional second argument is interpreted as an instance +% name of type \texttt{initial}. If that instance exist it will be +% used otherwise the instance with name \texttt{default} will be +% used. This way it is possible to place into the mandatory +% argument (argument 4) any character specification including +% accents. +% \begin{macrocode} +\DeclareDocumentCommand \ExtendedInitial {so omo} + { + \IfBooleanTF{#1} + {\UseTemplate{initial}{std}{#2}{#3}{#4}{#5}} + {\IfExistsInstanceTF{initial}{#2} + {\UseInstance{initial}{#2}} + {\UseInstance{initial}{default}} + {#3}{#4}{#5} + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +%</signature> +% \end{macrocode} +% +% \Finale +% diff --git a/Master/texmf-dist/source/latex3/xinitials/xinitials.ins b/Master/texmf-dist/source/latex3/xinitials/xinitials.ins new file mode 100644 index 00000000000..71ab2559e3e --- /dev/null +++ b/Master/texmf-dist/source/latex3/xinitials/xinitials.ins @@ -0,0 +1,13 @@ +\input docstrip +\keepsilent +\askforoverwritefalse + +\preamble +\endpreamble + +\generate{% + \file{xinitials.sty}{\from{xinitials.dtx}{package}} + \file{xinitials.sig}{\from{xinitials.dtx}{signature}} + } + +\endbatchfile diff --git a/Master/texmf-dist/source/latex3/xinitials/xinitials.sig b/Master/texmf-dist/source/latex3/xinitials/xinitials.sig new file mode 100644 index 00000000000..4962f090cb6 --- /dev/null +++ b/Master/texmf-dist/source/latex3/xinitials/xinitials.sig @@ -0,0 +1,43 @@ +%% +%% This is file `xinitials.sig', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% xinitials.dtx (with options: `signature') +%% +%% +%% $Header: /usr3/users/latex3/design/consolidation/CURRENT/RCS/xinitials.dtx,v 1.7 2000/01/28 13:39:56 latex3 Exp $ +%% +%% (C) Copyright 1999-2000 Frank Mittelbach +%% All rights reserved. +%% +%% Not for general distribution. In its present form it is not allowed +%% to put this package onto CD or an archive without consulting the +%% the authors. +%% +\ProvidesFile{xinitials.sig} + [2000/01/28 v0.1h templates for initials] +\RequirePackage{xinitials} +\RequirePackage{xparse} +\IgnoreWhiteSpace +\DeclareDocumentCommand \Initial {omo} + { + \IfExistsInstanceTF{initial}{#2} + {\UseInstance{initial}{#2}} + {\UseInstance{initial}{default}} + {#1}{#2}{#3} + } +\DeclareDocumentCommand \ExtendedInitial {so omo} + { + \IfBooleanTF{#1} + {\UseTemplate{initial}{std}{#2}{#3}{#4}{#5}} + {\IfExistsInstanceTF{initial}{#2} + {\UseInstance{initial}{#2}} + {\UseInstance{initial}{default}} + {#3}{#4}{#5} + } + } +\endinput +%% +%% End of file `xinitials.sig'. diff --git a/Master/texmf-dist/source/latex3/xor/xmarks.dtx b/Master/texmf-dist/source/latex3/xor/xmarks.dtx new file mode 100644 index 00000000000..c8286827ec0 --- /dev/null +++ b/Master/texmf-dist/source/latex3/xor/xmarks.dtx @@ -0,0 +1,956 @@ +% \iffalse +%% +%% (C) Copyright 1999 Frank Mittelbach +%% All rights reserved. +%% +%% Not for general distribution. In its present form it is not allowed +%% to put this package onto CD or an archive without consulting the +%% the authors. +%% +% \begin{macrocode} +\def\next#1: #2.dtx,v #3 #4 #5 #6 #7$#8{ +%<*dtx> + \ProvidesFile{#2.dtx} +%</dtx> +%<package>\ProvidesPackage{#2} +%<driver>\ProvidesFile{#2.drv} + [#4 #3 #8 (#6)]} +\next$Id: xmarks.dtx,v 1.6 2000/06/13 20:47:23 latex3 Exp $ + {multiple marks} +% \end{macrocode} +% +%<*driver> + \documentclass{ltxdoc} +% + \begin{document} + \DocInput{xmarks.dtx} + \end{document} +%</driver> +% +% \fi +% +% +% \GetFileInfo{xmarks.dtx} +% +% \title{The \textsf{xmarks} package\thanks{This file +% has version number \fileversion, last +% revised \filedate.}} +% \author{FMi} +% \date{\filedate} +% +% \maketitle +% +% \tableofcontents +% +% +% +% \section{Mark algorithm} +% +% To allow for completely independent marks we use the following +% procedure: +% \begin{itemize} +% \item +% For every mark of type \meta{type} we have a queue that holds every mark +% info found in memory. Every info is associated with a unique number, +% i.e., we simply count them. The queue always holds at least one item +% which is the previous mark info, i.e., the last mark for that type on +% the previous page. +% +% \item +% We use \TeX's internal mark mechanism only to record the associated +% numbers for marks for every type on the current page. +% +% \item +% For every \meta{type} we record the info-number that belongs to the last +% mark of the previous page. +% +% \item +% By looking at \TeX's internal |\botmark| we can determine the +% info-number of the last mark for every \meta{type} that is on the current +% page. +% +% \item +% The difference between this number and the info-number from the last +% page gives us the number of marks for every \meta{type} on the current page. +% +% \item +% That way we are able to decide how to extract items from the queue so +% that first, last, and previous mark for every type can be accessed. +% \begin{itemize} +% \item +% If the difference is zero, no new marks have been added on the +% current page, therefore the only item on the corresponding mark type +% queue holds the info that should be previous, first, and last mark of +% this type for the current page. +% \item +% If the difference is one, then the first item in the queue represents +% the info that should become the previous mark (it will be popped off) +% and the second item (which will be kept, since it will become the +% previous mark for the next page) should become first and last mark for +% the current page. +% \item +% Otherwise we had at least two marks for this type on the current page. +% Therefore, the first item in the queue will become previous mark (popped +% off), the second will become first mark (popped off), then we pop off +% all but the last item in the queue, which will become last mark, by only +% looking at it. +% \end{itemize} +% In other words every queue should hold only one item after this part of +% the algorithm has acted. +% After this is done we save the info-numbers given by |\botmark| +% as the info-numbers of the last page, so that they are available next time. +% +% \item +% Putting a mark into the galley therefore means to put its info to the +% right of the corresponding queue, increment the current info-number for +% \meta{type} by one and putting a \TeX{} mark into the galley holding the +% current info-numbers for all \meta{types}. +% +% \end{itemize} +% +% +% \subsection{Restrictions} +% +% One restriction in using this algorithm without further refinements +% is that for every \meta{type} there will be an upper limit of marks allowed +% within one document. This upper limit is given by |\maxdimen| which is +% probably high enough to ignore it, but it could be improved by resetting +% the info numbers whenever all marks have found their way onto the +% current page. +% +% Another restriction is that one better not changes from linearily +% processing the data for the main galley, or, if one modifies that +% processing one needs to carefully adjust the data structures for the +% marks as well. The problem being that the individual marks within a +% preprocessed galley will stay there forever (and thus can be parsed +% several times), the external data structures, e.g., the plists and +% the sequences however need manual corrections in that case. +% +% \subsection{Implementation} +% +% The original implementation was done on a portable PC in a train +% sometime in 1992/93 and is just a straight implementation of the +% above algorithm using plists to hold the current and the last +% info-numbers. The whole stuff could be done much better by analysing +% the algorithm combining common parts (a lot of thing have be done +% twice, etc.) and recoding the rest in a better way. +% +% The implementation below is more or less a straight adaption +% of that code, so it still needs a rewrite one day. It is based on +% modules implementing ``queues'', ``property lists'', and ``quarks'' +% most of which have been published as experimental code with a +% slightly different surface syntax, i.e., as \texttt{l3seq.sty}, +% \texttt{l3prop.sty}, and \texttt{l3quark.sty}. +% +% New stuff: +% \begin{macrocode} +\RequirePackage{ldcsetup} +\IgnoreWhiteSpace +% \end{macrocode} +% +% \begin{macrocode} +\long\def\@firstofthree#1#2#3{#1} +\long\def\@secondofthree#1#2#3{#2} +\long\def\@thirdofthree#1#2#3{#3} +% \end{macrocode} +% +% \begin{macrocode} +\def \tlp@to@str@N {\expandafter \tlp@to@str@aux \meaning} +\def \tlp@to@str@aux #1>{} +\def \tlp@to@str@c #1 {\expandafter \tlp@to@str@N \csname#1\endcsname} +% \end{macrocode} +% +% +% +% +% +% \subsection{Commands for manipulating queues} +% +% \begin{macro}{\trace@queue} +% \begin{macro}{\trace@queue@internal} +% \begin{macro}{\tracingqueues} +% \begin{macrocode} +%<*trace> +\def\trace@queue#1{\ifnum \tracingqueues > \z@ + \typeout{Queues:~ #1~ \on@line}\fi} +\def\trace@queue@internal#1{\ifnum\tracingqueues>\@ne + \typeout{Queues:~ #1~ \on@line}\fi} +\newcount\tracingqueues +%</trace> +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\queue@new@c} +% \begin{macrocode} +\def\queue@new@c#1{\@namedef{#1}{}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\queue@gadd@Nn} +% \begin{macrocode} +\def\queue@gadd@Nn#1#2{\expandafter\gdef\expandafter#1\expandafter + {#1\queue@elt#2\queue@eelt} +%<*trace> + \trace@queue@internal{add~ `#2'~ to~ queue~ \string#1} +%</trace> +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\queue@gadd@cn} +% \begin{macrocode} +\def\queue@gadd@cn#1{\expandafter\queue@gadd@Nn\csname#1\endcsname} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\queue@top@NN} +% \begin{macrocode} +\def\queue@top@NN#1#2{ + \queue@empty@err@N#1 + \expandafter\queue@top@split@w#1\q@stop{\def#2} +%<*trace> + \trace@queue@internal{top~ of~ queue~\string#1:~`\tlp@to@str@N#2'} +%</trace> +} +% \end{macro} +% +% \begin{macro}{\queue@top@split@w} +\def\queue@top@split@w\queue@elt#1\queue@eelt#2\q@stop#3{#3{#1}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\queue@top@cN} +% \begin{macrocode} +\def\queue@top@cN#1{\expandafter\queue@top@NN\csname#1\endcsname} +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\queue@pop@aux@nnNN} +% \begin{macro}{\queue@pop@aux@w} +% \begin{macrocode} +\def \queue@pop@aux@nnNN #1#2#3{ + \queue@empty@err@N #3 + \expandafter\queue@pop@aux@w #3\q@stop #1#2#3} +\def \queue@pop@aux@w \queue@elt#1\queue@eelt + #2\q@stop #3#4#5#6{#3#5{#2}#4#6{#1}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\queue@gpop@NN} +% \begin{macrocode} +\def \queue@gpop@NN #1#2{\queue@pop@aux@nnNN \gdef \def #1 #2 +%<*trace> + \trace@queue@internal{pop~ of~ queue~\string#1:~`\tlp@to@str@N #2'} +%</trace> +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\queue@gpop@cN} +% \begin{macrocode} +\def \queue@gpop@cN #1{\expandafter\queue@gpop@NN\csname#1\endcsname} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\queue@empty@err@N} +% \begin{macrocode} +\def\queue@empty@err@N #1{\ifx#1\@empty \ERROR \fi} +% \end{macrocode} +% \end{macro} +% +% +% +% +% +% +% +% +% +% \subsection {Quarks} +% +% A quark is a control sequence that expands into itself@ |\def| +% |\foo{\foo}|. Quarks provide a cheap way of generating distinct +% constants. Also, they permit the following ingenious trick: when +% you pick up a token in a temporary, and you want to know whether you +% have picked up a particular quark, all you have to do is compare the +% temporary to the quark using |\ifx|. +% +% \begin{macro}{\quark@new@N} +% Allocate a new quark. +% \begin{macrocode} +\def \quark@new@N #1{\def #1{#1}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\q@stop} +% \begin{macro}{\q@no@value} +% \begin{macro}{\q@nil} +% |\q@stop| is often used as a marker in parameter text, +% |\q@no@value| is the canonical missing value, and |\q@nil| +% represents a nil pointer in some data structures. +% \begin{macrocode} +\quark@new@N \q@stop +\quark@new@N \q@no@value +\quark@new@N \q@nil +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\q@error} +% \begin{macro}{\q@mark} +% We need two additional quarks. |\q@error| delimits the end of +% the computation for purposes of error recovery. |\q@mark| is +% used in parameter text when we need a scanning boundary that is +% distinct from |\q@stop|. +% \begin{macrocode} +\quark@new@N\q@error +\quark@new@N\q@mark +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\quark@if@no@value@NTF} +% \begin{macro}{\quark@if@no@value@NF} +% \begin{macro}{\quark@if@no@value@nTF} +% \begin{macro}{\quark@if@no@value@nT} +% \begin{macro}{\quark@if@no@value@nF} +% Here we test if we found a special quark as the first argument. +% The argument might contain an arbitrary list of tokens, therefore +% we have to wrap it up in a token list pointer. +% \begin{macrocode} +\def \quark@if@no@value@NTF #1{ +% \end{macrocode} +% We better start with |\q@no@value| as the first argument since +% the whole thing may otherwise loop if |#1| is wrongly given +% a string like |aabc| instead of a single token.\footnote{It may +% still loop in special circumstances however!} +% \begin{macrocode} + \ifx\q@no@value#1 + \expandafter\@firstoftwo + \else \expandafter\@secondoftwo \fi} +% \end{macrocode} +% It would be possible to speed up the following commands by +% providing individual implementations similar to the one above. +% Should perhaps be done if they are used often! +% \begin{macrocode} +\def \quark@if@no@value@NF #1{\quark@if@no@value@NTF {#1}\@empty} +\def \quark@if@no@value@nTF #1{\gdef \@gtempa {#1} + \quark@if@no@value@NTF\@gtempa} +\def \quark@if@no@value@nF #1{\quark@if@no@value@nTF {#1}\@empty} +\def \quark@if@no@value@nT #1#2{\quark@if@no@value@nTF {#1} + {#2}\@empty} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\quark@if@nil@NTF} +% A function to check for the presence of |\q@nil|. +% \begin{macrocode} +\def\quark@if@nil@NTF#1{ + \ifx#1\q@nil + \expandafter\@firstoftwo + \else + \expandafter\@secondoftwo\fi} +% \end{macrocode} +% \end{macro} +% +% +% +% +% \subsection{Commands for manipulating property lists} +% +% +% \begin{macro}{\prop@new@N} +% \begin{macrocode} +\def \prop@new@N #1{\def #1{}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\prop@put@NNn} +% \begin{macro}{\prop@gput@NNn} +% \begin{macro}{\prop@gput@NNo} +% \begin{macro}{\prop@gput@cco} +% \begin{macro}{\prop@gput@ccn} +% \begin{macrocode} +\long\def \prop@put@NNn #1#2{\prop@split@aux@NNn + #1#2{\prop@put@aux@w {\def #1}#2}} +\long\def \prop@gput@NNn #1#2{\prop@split@aux@NNn + #1#2{\prop@put@aux@w {\gdef #1}#2}} +% missing commands for galley stuff... +\def \prop@gput@NNo #1#2#3{ + \expandafter\prop@gput@NNn \expandafter #1 \expandafter + #2 \expandafter { #3 } } +\def \prop@gput@cco #1#2#3{ + \expandafter\prop@gput@NNn \csname #1\expandafter\endcsname + \csname #2\expandafter\endcsname + \expandafter { #3 } } +\def \prop@gput@ccn #1#2{ + \expandafter\prop@gput@NNn \csname #1\expandafter\endcsname + \csname #2\endcsname + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\prop@put@aux@w} +% \begin{macrocode} +\long\def \prop@put@aux@w #1#2#3#4#5#6{ + \quark@if@no@value@nTF {#4} + {#1{#2{#6}#3}} + {\def\tmp@w ##1#2\q@no@value {#1{#3#2{#6}##1}} + \tmp@w #5}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\prop@split@aux@NNn} +% \begin{macrocode} +\long\def \prop@split@aux@NNn #1#2#3{ + \def\tmp@w ##1#2##2##3\q@stop {#3{##1}{##2}{##3}} +% ^ ^ needed! + \expandafter\tmp@w #1#2\q@no@value \q@stop} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\prop@get@NNN} +% \begin{macrocode} +\long\def \prop@get@NNN #1#2{\prop@split@aux@NNn + #1#2\prop@get@aux@w} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\prop@get@aux@w} +% \begin{macrocode} +\long\def \prop@get@aux@w #1#2#3#4{\def#4{#2}} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\prop@map@funct@Nn} +% \begin{macrocode} +\let \prop@map@funct@Nn \@gobbletwo +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\prop@map@NN} +% \begin{macrocode} +\def \prop@map@NN #1#2{ + \let \prop@map@funct@Nn #2 + \expandafter\prop@map@aux@w #1\q@stop \q@stop} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\prop@map@aux@w} +% \begin{macrocode} +\def \prop@map@aux@w #1#2{ + \ifx #1\q@stop \else + \prop@map@funct@Nn #1{#2} + \expandafter\prop@map@aux@w + \fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\prop@map@cN} +% \begin{macrocode} +\def \prop@map@cN #1{ + \expandafter \prop@map@NN \csname #1\endcsname } +% \end{macrocode} +% \end{macro} +% +% +% +% +% +% +% +% \subsection{Commands for manipulating marks} +% +% +% +% \begin{macro}{\trace@mark} +% \begin{macro}{\trace@mark@internal} +% \begin{macro}{\tracingmarks} +% Tracing is done when |\tracingmarks| is positive. +% \begin{macrocode} +%<*trace> +\def\trace@mark#1{\ifnum \tracingmarks > \z@ + \typeout{Marks:~ #1~ \on@line}\fi} +\def\trace@mark@internal#1{\ifnum\tracingmarks>\@ne + \typeout{Marks:~ #1}\fi} +\newcount\tracingmarks +%</trace> +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\mark@new} +% Defines a new mark label and retrieval token list pointer. +% \begin{macrocode} +\def\mark@new#1{ +%<*trace> + \trace@mark + {new~mark:~\string#1} +%</trace> +% \end{macrocode} +% We make sure that the argument is still free and allocate the +% corresponding queue. To avoid problems with the use of such tlp's +% when they are used before the first |\mark@update@structure| we initialize +% them in a way that |\mark@previous| and the like will accept them even +% then. +% \begin{macrocode} + \newcommand* #1 {{}{}{}} + \queue@new@c{\string#1@seq} +% \end{macrocode} +% The last info-number for this type will be set to |1| This value +% is actually arbitrary and we could use |-\maxdimen+1| to get the +% range doubled. +% \begin{macrocode} + \prop@gput@NNn\mark@last@plist#1{1} +% \end{macrocode} +% More important is that the starting value for the current +% info-number is one less then the one used above. +% \begin{macrocode} + \prop@gput@NNn\mark@curr@plist#1{0} +% \end{macrocode} +% We now put the very first mark of this type in. This mark will be +% empty. This will initialize the queue (now holding the empty previous +% mark) increment the current info number, so that last and current are +% now equal and also puts a \TeX{} mark into the galley will the +% additional type present. +% \begin{macrocode} + \mark@put@Nn#1{}% +% \end{macrocode} +% \begin{macrocode} + \expandafter\g@addto@macro\expandafter\mark@save@state\expandafter{% + \expandafter\global\expandafter\let + \csname saved\string#1@seq\expandafter\endcsname + \csname\string#1@seq\endcsname} + \expandafter\g@addto@macro\expandafter\mark@restore@state@internal\expandafter{% + \expandafter\global\expandafter\let + \csname\string#1@seq\expandafter\endcsname + \csname saved\string#1@seq\endcsname} +} +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\mark@save@state} +% \begin{macro}{\mark@restore@state@internal} +% Save and restore the current state of the mark data +% structure. The commands will be extended by |\mark@new|. They are +% needed if part of the main galley is being reused or several +% times parsed. +% \begin{macrocode} +\def\mark@save@state{% + \global\let\saved@mark@curr@plist\mark@curr@plist + \global\let\saved@mark@last@plist\mark@last@plist} +\def\mark@restore@state@internal{% + \global\let\mark@curr@plist\saved@mark@curr@plist + \global\let\mark@last@plist\saved@mark@last@plist} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\mark@restore@state} +% |\mark@restore@state| will restore the state of the mark +% mechanism to the one saved by |\mark@save@state|. It has to be +% called inside an output routine and as it needs an output routine +% of its own to restore the |\mark| status of the bottom mark (so +% that \TeX{} correctly updates the mark registers in case it +% doesn't find a mark in box 255) it has an argument which is +% executed inside that output routine to regain control. +% +% The code in the argument has to set |\output| to a new output +% routine! If not you are in trouble. +% +% \begin{macrocode} +\def\mark@restore@state#1{% +%<*trace> + \@tracepush{mark@restore@state} +%</trace> +% \end{macrocode} +% We first restore the external data structures by calling +% |\mark@restore@sate@internal|. Then we have to ensure that \TeX's +% idea of what the current |\botmark| is, corresponds to what it +% was when we saved the state. Back then it was the contents of +% |\mark@last@plist| so we are now adding an empty box and then +% mark with is contents +% onto the MVL followed by a penalty that ensures we trigger the +% output routine and then specify a tiny little output routine +% whose sole purpose is to get that mark processed. +% \begin{macrocode} + \mark@restore@state@internal + \hbox{}% +% \end{macrocode} +% We have to protect |\mark@last@plist| from expanding too far +% inside the |\mark| so we first put it into a token register +% before applying |\mark|. +% \begin{macrocode} + \@temptokena\expandafter{\mark@last@plist}% +%<*trace> + \trace@mark@internal{restoring~ botmark~ \the\@temptokena}% +%</trace> + \mark + {\the\@temptokena} + \penalty-20203\relax +% \end{macrocode} +% We are not setting |\vsize| assuming its positive. So the moment +% we return from the current output routine (we are hopefully in +% right now) we should very very soon find the above penalty and +% then trigger the output routine we are about to define now. +% +% In that output routine we have a quick test for the +% |\outputpenalty| just to ensure that we really grabbed what we +% are supposed to grab. Then we throw away the contents of box 255 +% since all we wanted todo is to get |\botmark| set back to the +% value of our mark above. Finally we execute whatever got passed +% along as argument one to regain control. Since current |\output| +% has a rather funny definition the code in that argument better +% change that back to something that does a little bit more +% typesetting. +% \begin{macrocode} + \global\output{% +%<*trace> + \@tracepush{mark@restore@state@or} +%</trace> + \ifnum-20203=\outputpenalty\else \ERROR \fi + \global\setbox\@cclv\box\voidb@x + #1% +%<*trace> + \@tracepop{mark@restore@state@or} +%</trace> + }% +%<*trace> + \@tracepop{mark@restore@state} +%</trace> +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\mark@put@Nn} +% To put a mark into the current horizontal or vertical \TeX{} list +% we first update |\mark@curr@plist| and then put its value into the +% mark without any further expansion. (The code could be +% optimized!) +% \begin{macrocode} +%<-trace>\def\mark@put@Nn#1{% % wtest hack } +%<*trace> +\def\mark@put@Nn#1#2{ + \def\l@tmpa@tlp{#2} + \trace@mark + {set~\string#1~<-~\tlp@to@str@N\l@tmpa@tlp} +%</trace> +% \end{macrocode} +% First we have to update the current info number for this type. The +% code is a bit complicated because we have to get the number from the +% the plist update it and then put it back. If we would keep the numbers +% differently this could be improved, probably at the cost of more macro +% names. +% \begin{macrocode} + \@temptokena\expandafter{\mark@curr@plist} + \prop@get@NNN\mark@curr@plist#1\@tempa +%<*debug> + \ifx\q@no@value\@tempa + \ERROR + \fi +%</debug> + \@tempcnta\@tempa + \advance\@tempcnta\@ne + \expandafter + \prop@gput@NNn\expandafter\mark@curr@plist\expandafter#1\expandafter + {\the\@tempcnta} +% \end{macrocode} +% Now we want to put this plist into a \TeX{} mark. We need a +% one-level expansion, otherwise our pkeys would expand which would +% produce chaos. So we save it in a toks register. +% \begin{macrocode} + \@temptokena\expandafter{\mark@curr@plist} + \mark + {\the\@temptokena} +% \end{macrocode} +% Finally we shouldn't forget to put the info at the right of the +% corresponding queue. +% Without tracing we can omit the second argument to +% this function. +% \begin{macrocode} +%<*trace> + \queue@gadd@cn{\string#1@seq}{#2} +%</trace> +%<-trace> \queue@gadd@cn{\string#1@seq}% +} +% \end{macrocode} +% \end{macro} +% +% +% +% +% \begin{macro}{\mark@put@Nnn} +% \begin{macrocode} +\def\mark@put@Nnn#1#2#3{ + \mark@put@Nn#1{#2#3}} +% \end{macrocode} +% \end{macro} +% +% +% +% +% \begin{macro}{\mark@update@structure} +% This function is for use in output routines to initialize the marks +% at the beginning. It is only useful after \TeX{} internally has +% updated |\botmark|. +% \begin{macrocode} +\def\mark@update@structure{ +% \end{macrocode} +% We map a function over all keys in |\mark@last@plist|, in other +% words over all types of marks. This routine will set the marks for +% all types. Finally we set the plist |\mark@last@plist| to the +% plist that was stored in |\botmark|, i.e., to the +% info-numbers from this page. +% \begin{macrocode} + \prop@map@NN\mark@last@plist\mark@retrieve@single@Nn + \expandafter\gdef\expandafter\mark@last@plist\expandafter{\botmark} +} +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\mark@retrieve@single@Nn} +% This function will be mapped over the plist containing the info-numbers +% from the last page. This means that |#1| will be the key (which is +% simply our type token list pointer and |#2| is the value, i.e. the +% info-number from the last page for this type. +% \begin{macrocode} +\def\mark@retrieve@single@Nn#1#2{ +%<*trace> + \trace@mark@internal + {queue~for~\string#1~ before:~`\tlp@to@str@c{\string#1@seq}'} +%</trace> +% \end{macrocode} +% We retrieve the info number for this type from |\botmark| +% and store the difference in |\@tempcnta|. +% \begin{macrocode} + \@temptokena\expandafter{\botmark}% +%<*trace> + \trace@mark@internal{picking~ up~ from~ output~ \the\@temptokena}% +%</trace> + \prop@get@NNN\botmark#1\@tempa +%<*debug> + \ifx\q@no@value\@tempa + \ERROR + \fi +%</debug> + \@tempcnta\@tempa + \advance\@tempcnta-#2\relax +%<*trace> + \trace@mark@internal + {found~\the\@tempcnta\space entries~ for~ \string#1~ + (new~\@tempa;~old~#2)} +%</trace> +% \end{macrocode} +% Then we decide what to do depending on its value. +% We use |\@tempa|, |\@tempb|, and |\@tempc| to +% temporarily hold the previous, first and last mark for this type. +% \begin{macrocode} + \ifcase\@tempcnta +% \end{macrocode} +% If there haven't been any new marks we leave the queue alone, +% peeking only at its top element and using it for all three marks. +% \begin{macrocode} + \queue@top@cN{\string#1@seq}\@tempa + \let\@tempb\@tempa + \let\@tempc\@tempa + \or +% \end{macrocode} +% When there was one mark of this type, we pop one item for the +% previous mark of this type, and use the remaining item for first +% and last mark. +% \begin{macrocode} + \queue@gpop@cN{\string#1@seq}\@tempa + \queue@top@cN{\string#1@seq}\@tempb + \let\@tempc\@tempb + \else +% \end{macrocode} +% If we had more than one mark for this type we pop one mark for the +% previous mark of this type, then pop another mark for the first +% mark of this type, then pop all but the last item and use the last +% item as the last mark of this type, keeping it as before on the +% queue. +% \begin{macrocode} + \queue@gpop@cN{\string#1@seq}\@tempa + \queue@top@cN{\string#1@seq}\@tempb + \@whilenum \@tempcnta>\@ne\do + {\advance\@tempcnta\m@ne + \queue@gpop@cN{\string#1@seq} + \@tempc + } + \queue@top@cN{\string#1@seq}\@tempc + \fi +% \end{macrocode} +% After this process all values for previous, first and last mark for +% this type are found so that we can store them in the tlp +% representing this type for further processing. +% \begin{macrocode} + \@temptokena\expandafter{\@tempa} + \@temptokenb\expandafter{\@tempb} + \@temptokenc\expandafter{\@tempc} + \edef#1{{\the\@temptokena}{\the\@temptokenb}{\the\@temptokenc}} +%<*trace> + \trace@mark + {in~output:~\string#1~->~\tlp@to@str@N#1} +% \end{macrocode} +% At this point the queue should show only one item. +% \begin{macrocode} + \trace@mark@internal + {queue~ for~\string#1~after:~`\tlp@to@str@c{\string#1@seq}'} +%</trace> +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@temptokenb} +% \begin{macro}{\@temptokenc} +% \begin{macrocode} +\newtoks\@temptokenb +\newtoks\@temptokenc +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\mark@curr@plist} +% \begin{macro}{\mark@last@plist} +% Here are the allocations for the two plists used. +% \begin{macrocode} +\prop@new@N\mark@curr@plist +\prop@new@N\mark@last@plist +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% +% +% +% +% \begin{macro}{\mark@get@first@N} +% \begin{macro}{\mark@get@last@N} +% \begin{macro}{\mark@get@previous@N} +% To retrieve the first, last or previous page mark, we +% grap the appropriate value stored in the tlp. The marks are stored +% in the tlp in the order previous, first, last mark. These functions +% should be used only in output routines after |\mark@retrieve| has +% acted, otherwise their value will be wrong. They are all fully +% expandable. +% +% Actually, they may bomb when tracing is included and we have +% material that doesn't work corretly within a write. +% \begin{macrocode} +%<*trace> +\def\mark@get@first@N#1{ + \expandafter\@secondofthree#1 + \trace@mark@internal{use~first~\string#1~=~ + `\expandafter\@secondofthree#1'} +} +\def\mark@get@last@N#1{ + \expandafter\@thirdofthree#1 + \trace@mark@internal{use~ last~ \string#1~ =~ + `\expandafter\@thirdofthree#1'} +} +\def\mark@get@previous@N#1{ + \expandafter\@firstofthree#1 + \trace@mark@internal{use~prev~\string#1~ =~ + `\expandafter\@firstofthree#1'} +} +%</trace> +%<-trace>\def\mark@get@first@N{% +%<-trace> \expandafter\@secondofthree} +%<-trace>\def\mark@get@last@N{% +%<-trace> \expandafter\@thirdofthree} +%<-trace>\def\mark@get@previous@N{% +%<-trace> \expandafter\@firstofthree} +% \end{macrocode} +% above version in trace case doesn't work alway! +% \begin{macrocode} +\def\mark@get@first@N{% + \expandafter\@secondofthree} +\def\mark@get@last@N{% + \expandafter\@thirdofthree} +\def\mark@get@previous@N{% + \expandafter\@firstofthree} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\DeclareMarkType} +% \begin{macrocode} +\def\DeclareMarkType#1{ + \expandafter\mark@new\csname mark@#1\endcsname} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\PutMark} +% \begin{macrocode} +\def\PutMark#1{ + \@ifundefined{mark@#1}{\ERROR}{} + \expandafter\mark@put@Nn\csname mark@#1\endcsname} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\PreviousMark} +% \begin{macrocode} +\def\PreviousMark#1{ + \expandafter\mark@get@previous@N\csname mark@#1\endcsname} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\FirstMark} +% \begin{macrocode} +\def\FirstMark#1{ + \expandafter\mark@get@first@N\csname mark@#1\endcsname} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\LastMark} +% \begin{macrocode} +\def\LastMark#1{ + \expandafter\mark@get@last@N\csname mark@#1\endcsname} +% \end{macrocode} +% \end{macro} +% +% \Finale +% +\endinput +% +% $Log: xmarks.dtx,v $ +% Revision 1.6 2000/06/13 20:47:23 latex3 +% docu update +% inlined quarks code +% diff --git a/Master/texmf-dist/source/latex3/xor/xo-alloc.dtx b/Master/texmf-dist/source/latex3/xor/xo-alloc.dtx new file mode 100644 index 00000000000..05250715ccb --- /dev/null +++ b/Master/texmf-dist/source/latex3/xor/xo-alloc.dtx @@ -0,0 +1,125 @@ +% \iffalse +%% +%% (C) Copyright 1999-2000 Frank Mittelbach, David Carlisle, Chris Rowley +%% All rights reserved. +%% +%% Not for general distribution. In its present form it is not allowed +%% to put this package onto CD or an archive without consulting the +%% the authors. +%% +% \fi +% +% \begin{macrocode} +\def\@tempa#1: #2.dtx,v #3 #4 #5 #6 #7${ + \ProvidesPackage{#2}[#4 #3 #5 #6]} +\@tempa$Id: xo-alloc.dtx,v 1.4 2000/08/11 07:13:34 latex3 Exp $ +% \end{macrocode} +% +% +% Ignore white space in this package. +% \begin{macrocode} +\IgnoreWhiteSpace +% \end{macrocode} +% +% |\footins| is FD, should probably move to FE +% +% |\@footins| is FE, should probably go and be replaced by a box and skip allocation +% they don't need to be same number, except for compatibility reasons. +% +% |\@kludgeins| was EA maybe can go, depending on how enlargethispage to be implemented. +% for now, move to FC (which was bx@A +% \begin{macrocode} +\chardef\@kludgeins="FC\relax +\global\dimen\@kludgeins \maxdimen +\global\count\@kludgeins 1000 +\global\dimen\@kludgeins\z@ +\global\skip\@kludgeins\z@ +\global\setbox\@kludgeins\box\voidb@x +% \end{macrocode} +% +% \begin{macrocode} +\insc@unt"FC\relax +% \end{macrocode} +% +% count dimen skip no longer bounded by insertion allocation. +% toks now bounded by insertions. +% \begin{macrocode} +\def\newcount{\alloc@0\count\countdef\@kludgeins} +\def\newdimen{\alloc@1\dimen\dimendef\@kludgeins} +\def\newskip{\alloc@2\skip\skipdef\@kludgeins} +\def\newtoks{\alloc@5\toks\toksdef\insc@unt} +% \end{macrocode} +% +% \begin{macrocode} +\def\newinsert#1{\global\advance\insc@unt \m@ne + \ch@ck4\insc@unt\box + \ch@ck5\insc@unt\toks + \allocationnumber\insc@unt + \global\chardef#1\allocationnumber + \wlog{\string#1=\string\insert\the\allocationnumber}} +% \end{macrocode} +% +% \begin{macrocode} +\newinsert\bx@A +\newinsert\bx@B +\newinsert\bx@C +\newinsert\bx@D +\newinsert\bx@E +\newinsert\bx@F +\newinsert\bx@G +\newinsert\bx@H +\newinsert\bx@I +\newinsert\bx@J +\newinsert\bx@K +\newinsert\bx@L +\newinsert\bx@M +\newinsert\bx@N +\newinsert\bx@O +\newinsert\bx@P +\newinsert\bx@Q +\newinsert\bx@R +% \end{macrocode} +% +% like |\@next| but allocates to list if empty (so doesn't have the +% 4th argument) There is a hidden 3rd argument, picked up by |\@xnext|. +% \begin{macrocode} +\def\@allocating@next#1#2{ + \ifx#2\@empty + \xdef#2{\noexpand\@elt\csname bx@\the\insc@unt\endcsname} + \expandafter\newinsert\csname bx@\the\insc@unt\endcsname + \fi + \expandafter\@xnext #2\@@#1#2} +% \end{macrocode} +% +% \begin{macrocode} +% \end{macrocode} +% +% \begin{macrocode} +% \end{macrocode} +% +% \begin{macrocode} +% \end{macrocode} +% +% \begin{macrocode} +% \end{macrocode} +% +% \begin{macrocode} +% \end{macrocode} + +% +% \endinput +\endinput +% +% $Log: xo-alloc.dtx,v $ +% Revision 1.4 2000/08/11 07:13:34 latex3 +% added header +% +% Revision 1.3 2000/06/13 20:54:46 latex3 +% made this a dtx file +% +% Revision 1.2 2000/02/22 01:03:55 david +% *** empty log message *** +% +% Revision 1.1 2000/02/22 00:52:52 david +% Initial revision +% diff --git a/Master/texmf-dist/source/latex3/xor/xo-capt.dtx b/Master/texmf-dist/source/latex3/xor/xo-capt.dtx new file mode 100644 index 00000000000..618e22f94d7 --- /dev/null +++ b/Master/texmf-dist/source/latex3/xor/xo-capt.dtx @@ -0,0 +1,306 @@ +% \iffalse +%% +%% (C) Copyright 1999-2000 Frank Mittelbach, David Carlisle, Chris Rowley +%% All rights reserved. +%% +%% Not for general distribution. In its present form it is not allowed +%% to put this package onto CD or an archive without consulting the +%% the authors. +%% +% \fi +% + +% \begin{macrocode} +\def\@tempa#1: #2.dtx,v #3 #4 #5 #6 #7${ + \ProvidesPackage{#2}[#4 #3 #5 #6]} +\@tempa$Id: xo-capt.dtx,v 1.13 2000/08/11 07:14:03 latex3 Exp $ +% \end{macrocode} +% +% Ignore white space in this package. +% \begin{macrocode} +\IgnoreWhiteSpace +% \end{macrocode} +% +% +% \subsection{Modifying the caption command} +% +% \begin{macro}{\@caption} +% |\caption| just saves its main argument in a token register. It also +% has |\unskip| and |\ignorespaces| to cope with hmode. +% The format of the token register is:\\ +% \marg{type}\marg{number}\marg{caption text}\marg{extra info}\\ +% The \meta{type} is something like `figure', used to generate the +% relevant command names. \meta{number} is the fully expanded version of +% |\the|\ldots. The last group is unused by the current definition +% but extended packages may use it to pass extra information to the +% float handler, as required. +% \begin{macrocode} +\def\caption{\@dblarg{\@caption\float@type}} + +\long\def\@caption#1[#2]#3{% + \unskip +% \end{macrocode} +% We use the old \LaTeX{} interface with |\addcontentsline| for the +% moment.\footnote{FIX!!} +% \begin{macrocode} + \addcontentsline{\csname toc@extension@#1\endcsname}{#1} +% \end{macrocode} +% The counter used is not |#1| but given by (|\foat@counter|) which +% should perhaps be passed along but isn't: +% \begin{macrocode} + {\protect\numberline{\csname the\float@counter\endcsname} + {\ignorespaces #2}} + \global\toks\@currbox{#3} + \ignorespaces + } +% \end{macrocode} +% \end{macro} +% +% +% \subsection{Adding captions to float boxes} +% +% This should really be a template instance. +% Must \emph{copy} the float body in |\this@float@box| +% into |\this@captioned@float| adding the caption text. +% May use |\this@area|, |\this@area@col@number| and other information, to be +% determined \ldots +% +% \begin{macro}{\append@caption@to@float} +% Combine float body and caption of the current float (``this +% float'') and store it in |\this@captioned@float|. +% \begin{macrocode} +\def\append@caption@to@float{ + \typeset@some@floatbox + \this@type\this@area + \this@float@box{\csname caption@\this@type\endcsname} + \this@usercnt\this@caption\this@span@number +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\append@here@caption@to@float} +% Combine float body and caption of the current here float and +% store it in |\this@captioned@float|. +% \begin{macrocode} +\def\append@here@caption@to@float{ + \typeset@some@floatbox + \here@type{h\the\curr@col@count 1} + \here@float@box{\csname caption@\here@type\endcsname} + \here@usercnt\here@caption\here@span@number +} +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\typeset@this@float@and@caption} +% Combine float body and caption of the current float (``this +% float'') and output it into the current list. +% \begin{macrocode} +\def\typeset@this@float@and@caption{ + \append@caption@to@float + \box\this@captioned@float +} +% \end{macrocode} +% \end{macro} +% +% +% +% \section{Some primitive templates for testing} +% +% prove of concept only --- not even prototype +% +% +% \begin{macro}{\typeset@some@floatbox} +% The macro |\typeset@some@floatbox| take 7 arguments as follows: +% \begin{description} +% \item[type] type of the float to be typeset +% \item[area] area in which to format the float +% \item[floatbody box] box register in which the body of the float +% is stored +% \item[caption heading] fixed text like ``Figure'' +% \item[caption number] caption number of the float +% \item[caption text] caption text of the float +% \item[span count] span count (normally deducable from the area +% but\ldots +% \end{description} +% The first two arguments are used to decide which formatting +% instance to call, the remaining arguments are passed to that +% instance. +% +% The logic is (at the moment) as follows: if a template instance +% (type \texttt{buildfloat}) with the name +% \meta{type}|-|\meta{area}\footnote{The ``here'' areas are +% denoted as \texttt{h}\meta{col}\texttt{1}.} +% is defined then this instance is used, +% otherwise we look if there is an instance with just the name of +% the \meta{area}, otherwise we try an instance with the name +% \meta{type} and if this isn't defined either we try the instance +% named |default|. +% \begin{macrocode} +\def\typeset@some@floatbox#1#2{ % type area + + \IfExistsInstanceTF{buildfloat} + { #1 - #2 } + {\def\use@instance@named{#1 - #2}} + { + \IfExistsInstanceTF{buildfloat} + { #2 } + {\def\use@instance@named{#2}} + { + \IfExistsInstanceTF{buildfloat} + { #1 } + {\let\use@instance@named#1 } % we know this is a token + {\def\use@instance@named{default}} + } + } + \UseInstance{buildfloat}\use@instance@named +} +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macrocode} +% #1 body box +% #2 fixed text +% #3 counter value +% #4 caption +% #5 span number +\DeclareTemplateType{buildfloat}{5} +% \end{macrocode} +% +% \begin{macrocode} +\DeclareTemplate{buildfloat}{centeredabove}{5} + { + body-caption-sep =l [10pt] \belowcaptionskip, + } + { + \DoParameterAssignments + + \@parboxrestore + + \hsize=#5\columnwidth + + \global\setbox\this@captioned@float\vbox{ + \sbox\@tempboxb{#2~ #3:~ #4} + \ifdim \wd\@tempboxb >\hsize + #2~ #3:~ #4\par + \else + \hb@xt@\hsize{\hfil\box\@tempboxb\hfil}% + \fi + \vskip\belowcaptionskip + \centerline{ + \copy#1 + } + \kern\z@ + } + } +% \end{macrocode} +% +% \begin{macrocode} +\newbox\@tempboxb +% \end{macrocode} +% +% \begin{macrocode} +\DeclareTemplate{buildfloat}{centeredbelow}{5} + { + body-caption-sep =l [10pt] \abovecaptionskip, + } + { + \DoParameterAssignments + + \@parboxrestore + + \hsize=#5\columnwidth + + \global\setbox\this@captioned@float\vbox{ + \centerline{\copy#1} + \vskip\abovecaptionskip + \sbox\@tempboxb{#2~ #3:~ #4} + \ifdim \wd\@tempboxb >\hsize + #2~ #3:~ #4\par + \else + \hb@xt@\hsize{\hfil\box\@tempboxb\hfil}% + \fi + } + } +% \end{macrocode} +% +% \begin{macrocode} +\DeclareTemplate{buildfloat}{bottomright}{5} + { + body-caption-sep =l [10pt] \abovecaptionskip, + } + { + \DoParameterAssignments + + \@parboxrestore + + \hsize=#5\columnwidth + + \global\setbox\this@captioned@float\vbox{ + \@@line{\hss\vbox{\copy#1\kern0pt} + \rlap{ + \hskip\abovecaptionskip +% \end{macrocode} +% rubbish as far as it goes: this should be turned into a real +% template probably using coffins +% \begin{macrocode} + \parbox[b]{\marginparwidth + +(#5\columnwidth-\wd#1)/2}{ + \raggedright + #2~ #3:~ #4 + } + }\hss + } + \kern0pt + } + } +% \end{macrocode} +% +% +% +% \subsection{Some test instances} +% +% \begin{macrocode} +\DeclareInstance{buildfloat}{default}{centeredabove}{} + +\DeclareInstance{buildfloat}{figure}{centeredbelow}{} + +\DeclareInstance{buildfloat}{t31}{bottomright}{} +\DeclareInstance{buildfloat}{t22}{bottomright}{} +\DeclareInstance{buildfloat}{t13}{bottomright}{} +% \end{macrocode} +% +% \endinput +\endinput +% +% $Log: xo-capt.dtx,v $ +% Revision 1.13 2000/08/11 07:14:03 latex3 +% added header +% +% Revision 1.12 2000/08/11 06:47:53 latex3 +% untabify +% +% Revision 1.11 2000/07/19 15:55:53 latex3 +% used \float@type rather than \@captype +% extended buildfloat template to 5 arguments +% +% Revision 1.10 2000/07/10 18:45:23 latex3 +% some normalisation of caption attachment code -- needs more work +% +% Revision 1.9 2000/06/13 20:53:55 latex3 +% docu update +% renamed template type builtfloat to buildfloat +% +% Revision 1.8 2000/05/03 20:16:59 latex3 +% added more arguments to the caption template +% +% Revision 1.7 2000/05/03 20:03:59 latex3 +% fixed typo in macro name +% +% Revision 1.6 2000/05/03 18:52:44 latex3 +% enabling write of toc entries +% adding a prove of concept for caption templates +% diff --git a/Master/texmf-dist/source/latex3/xor/xo-final.dtx b/Master/texmf-dist/source/latex3/xor/xo-final.dtx new file mode 100644 index 00000000000..ad4216ea7a3 --- /dev/null +++ b/Master/texmf-dist/source/latex3/xor/xo-final.dtx @@ -0,0 +1,1094 @@ +% \iffalse +%% +%% (C) Copyright 1999-2000 Frank Mittelbach, David Carlisle, Chris Rowley +%% All rights reserved. +%% +%% Not for general distribution. In its present form it is not allowed +%% to put this package onto CD or an archive without consulting the +%% the authors. +%% +% \fi +% +% +% \begin{macrocode} +\def\@tempa#1: #2.dtx,v #3 #4 #5 #6 #7${ + \ProvidesPackage{#2}[#4 #3 #5 #6]} +\@tempa$Id: xo-final.dtx,v 1.20 2000/08/11 07:14:09 latex3 Exp $ +% \end{macrocode} +% +% \begin{macrocode} +\IgnoreWhiteSpace +% \end{macrocode} +% +% Update: as of April 3 this now does something reasonable with +% top and bottom floats. The text in between still needs lots of +% attention. No headers/footers/margins/overlays etc etc yet. +% +% There is still a lot of inefficient indirection; this shows where we +% may be able to support more general page-makeup systems. +% +% And not much tracing yet. +% +% \subsection{Text columns} +% +% \begin{macro}{\produce@final@column} +% \begin{macro}{\final@column@with@floats} +% \begin{macro}{\final@column} +% +% This version puts column floats in columns; see below for +% an alternative. It simulates current \LaTeX{} so should not be +% taken as a model for anything useful. +% +% When we remove or modernise this a lot more code from below can go +% too. +% +% \begin{macrocode} +\def\final@column@with@floats { +%<*trace> + \@tracepush{produce@final@column} +%</trace> + \setbox\@outputbox \box\@cclv + + \expandafter + \add@floats@top + \csname area@t1\the\curr@col@count\endcsname + + \ifvoid\footins + \else + \setbox\@outputbox \vbox { + \boxmaxdepth \@maxdepth + \dimen@\dp\@outputbox + \unvbox \@outputbox + \vskip-\dimen@ + \vskip \skip\footins + \color@begingroup + \normalcolor + \footnoterule + \unvbox \footins + \color@endgroup + } + \fi + + \expandafter + \add@floats@bottom + \csname area@b1\the\curr@col@count\endcsname + + \global\setbox\csname col@box@\the\curr@col@count\endcsname + % \vbox { % this should one day become \@colht + \vbox { % this should one day become \@colht + % or else + \@texttop + \dimen@ \dp\@outputbox + \unvbox \@outputbox + \vskip -\dimen@ + \@textbottom + }% + \global \maxdepth \@maxdepth +%<*trace> + \@tracepop{produce@final@column} +%</trace> +} +% \end{macrocode} +% This version does not give special treatment to column floats; it +% simply attachs footnotes and tops/tails. +% +% Probably this should just stuff the main text and footnotes into +% boxes (or a box?) with no extra formatting; all aesthetic handling would +% be done later, when the page is being made-up. +% +% The formatting details are clearly temporary. +% +% \begin{macrocode} +\def\final@column { +%<*trace> + \@tracepush{produce@final@column} +%</trace> + \setbox\@outputbox \box\@cclv + + \ifvoid\footins + \else + \setbox\@outputbox \vbox { + \boxmaxdepth \@maxdepth + \dimen@\dp\@outputbox + \unvbox \@outputbox + \vskip-\dimen@ + \vskip \skip\footins + \color@begingroup + \normalcolor + \footnoterule + \unvbox \footins + \color@endgroup + } + \fi + +% \end{macrocode} +% +% I am not sure if texttop/bottom should survive for long: something +% more spohisictaed is needed these days. This may mean that +% footnotes need better handling too: what makes a complex column +% look good? +% +% \begin{macrocode} + \global\setbox\csname col@box@\the\curr@col@count\endcsname + \vbox { % this should one day become \@colht + % or else + \@texttop + \dimen@ \dp\@outputbox + \unvbox \@outputbox + \vskip -\dimen@ + \@textbottom + }% + \global \maxdepth \@maxdepth +%<*trace> + \@tracepop{produce@final@column} +%</trace> +} +\let \produce@final@column \final@column +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\add@floats@top} +% \begin{macro}{\add@floats@bottom} +% These are now used (if at all) +% only within columns (maybe not best even there). +% +% \begin{macrocode} +\def\add@floats@top #1{ + \ifx#1\@empty + \else + \setbox\@tempboxa \vbox{} + \let \@elt \@comflelt #1 + \setbox\@outputbox \vbox{ + \boxmaxdepth \maxdepth + \unvbox\@tempboxa + \vskip -\pagesetup@float@float@sep + \topfigrule + \vskip \pagesetup@float@text@sep + \unvbox\@outputbox + } + \let\@elt\relax + \release@floats#1 + \fi +} +% \end{macrocode} +% +% \begin{macrocode} +\def\add@floats@bottom#1{ + \ifx#1\@empty + \else + \setbox\@tempboxa \vbox{} + \let\@elt\@comflelt + #1 + \setbox\@outputbox \vbox{ + \unvbox\@outputbox + \vskip \pagesetup@float@text@sep + \botfigrule + \unvbox\@tempboxa + \vskip -\pagesetup@float@float@sep + } + \let\@elt\relax + \release@floats#1 + \fi +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% +% +% \subsection{Shipout and housekeeping} +% +% +% \begin{macro}{\absolute@page@number} +% \begin{macrocode} +\mathchardef\absolute@page@number\c@page +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} + +% \end{macrocode} +% +% \begin{macro}{\produce@final@page} +% +% This puts everything to be shipped out into the hbox +% |\page@box| and then ships this out (not quite, see below!). +% +% Probably these two processes should be separated. +% +% At present it does the page-makeup within the shipped out box; +% this should proably be done earlier. +% +% Should the box (or the box-name) be a global +% fixed object (bad;-) or a local parameter (good;-)? +% +% The shipping out is surrounded by considerable housekeeping: +% this version sets up to do the writes and fixes the +% numbering. +% +% \begin{macrocode} +\def\produce@final@page{ +%<*trace> + \@tracepush{produce@final@page} + \tr@ce{final~ page~ output:~ Chris'~ version} +%</trace> + \begingroup % the \endgroup is put in by \aftergroup +% \end{macrocode} +% +% \begin{macrocode} + \@resetactivechars + \@parboxrestore + \let \protect \noexpand +% \end{macrocode}% +% Temp: just puts stuff into lists (which could have been built up +% as floats are placed?). +% \begin{macrocode} + \do@floats + \shipout \hbox { % NOTE: an hbox now! +% \end{macrocode} +% +% \begin{macrocode} + \set@typeset@protect + \aftergroup \endgroup + \aftergroup \set@typeset@protect +% \end{macrocode} +% Making the box can be done outside the shipout. +% \begin{macrocode} + \make@page@box + \box \page@box + } +% \endgroup %% This is _implicitly_ here. +% \end{macrocode} +% +% \begin{macrocode} + \count@\absolute@page@number +%<*trace> + \tr@ce{absolute~page:~\the\absolute@page@number} +%</trace> + \advance\count@\@ne + \global\advance\c@page\@ne + \global\mathchardef\absolute@page@number\count@ +%<*trace> + \@tracepop{produce@final@page} +%</trace> +} + +% \end{macrocode} +% \end{macro} +% +% \subsection{The page box} +% +% \begin{macro}{\mbox@addtopage} +% \begin{macro}{\box@addtopage} +% \begin{macro}{\page@box} +% This should be generalised to add a box to any box (without overcrowding). +% \begin{macrocode} +\newbox \page@box +\def\mbox@addtopage (#1,#2)#3{% +%<*trace> + \tr@ce{box~being~added~to~page:~at~(#1,~#2) + } +%</trace> + \global \setbox\page@box + \hbox { + \unhbox \page@box + \mbox@put (#1,#2) {#3} + } +} +\def\box@addtopage (#1,#2)#3{% + \mbox@addtopage (#1,#2){\box #3} +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\make@page@box} +% +% This adds stuff to a globallly named box; maybe it should be more +% generic. +% +% This is some kind of default example. +% It should be templated. +% +% \begin{macrocode} +\def \make@page@box { +%<*trace> + \@tracepush{make@page@box} + \tr@ce{new style page nake-up} +%</trace> +% \end{macrocode} +% Temp for current header: +% \begin{macrocode} + \mbox@addtopage (\pagebodylefthpos, \headheight) + {page:~\thepage} +% \end{macrocode} +% Then add the float areas, using a list of boxes and positions. +% Probably, the whole thing should be done this way but this may +% not be sensible for simple cases. +% +% Also, some alignments (eg text) may be better handled by the +% use of coffins (which are a very similar, but more complex, +% technology). +% +% First set-up starting point for main text body. +% \begin{macrocode} + \forall@columns { + \expandafter \xdef + \csname stack@level@\the\curr@col@count \endcsname + {\pagebodytopvpos} + } + \stack@top@areas + \add@columns + \stack@bot@areas +%<*trace> + \@tracepop{make@page@box} +%</trace> +} +% \end{macrocode} +% \end{macro} +% +% +% \subsection{The page box: text columns} +% +% This needs to be a lot more sophisticated in order to make these +% look anything but dreadful. +% +% \begin{macro}{\add@columns} +% \begin{macro}{\add@columns@topstacked} +% \begin{macro}{\add@columns@botaligned} +% +% Several possibilities here: choose one. +% +% One way to do bottom-aligned columns (probably will not +% generalise well): +% \begin{macrocode} +\def \add@columns@botaligned { +%<*trace> + \@tracepush{add@columns@botaligned} +%</trace> + \setlength \@tempdima {\pagebodylefthpos} + \forall@columns { +%<*trace> + \tr@ce{bot~aligned~column~\the\curr@col@count :~% + ht=\expandafter\the\expandafter\ht + \csname col@box@\the\curr@col@count \endcsname,~ + dp=\expandafter\the\expandafter\dp + \csname col@box@\the\curr@col@count \endcsname} +%</trace> +% \end{macrocode} +% Rules will need to be handled separately: where do they go in +% general with spanning floats? +% \begin{macrocode} +% \vrule + \box@addtopage ( \@tempdima, \pagebodybotvpos ) + {\csname col@box@\the\curr@col@count \endcsname} + \setlength \@tempdima {\@tempdima + \columnwidth + \columnsep} +% \vrule + } +%<*trace> + \@tracepop{add@columns@botaligned} +%</trace> +} +% \end{macrocode} +% +% Stacking them at the top: this must be dome immediately after +% stacking the top areas. They are aligned, if possible, at the +% top (the actual top, not necessarily the top text line). +% +% \begin{macrocode} +\def \add@columns@topstacked { +%<*trace> + \@tracepush{add@columns@topstacked} +%</trace> + \gsetmlength \cuur@col@pos {\pagebodylefthpos} + \forall@columns { +%<*trace> + \tr@ce{top~stacked~column~\the\curr@col@count :~% + ht=\expandafter\the\expandafter\ht + \csname col@box@\the\curr@col@count \endcsname,~ + dp=\expandafter\the\expandafter\dp + \csname col@box@\the\curr@col@count \endcsname} + \tr@ce{vsize~for~column~\the\curr@col@count~was:~% + \csname col@ht@ \the\curr@col@count\endcsname} + \tr@ce{lowered~column~\the\curr@col@count~:~% + \csname stack@level@\the\curr@col@count \endcsname + } +%</trace> + \gsetmlength@c {stack@level@\the\curr@col@count} + { \csname stack@level@\the\curr@col@count \endcsname + + \expandafter + \ht \csname col@box@\the\curr@col@count \endcsname + } +% \end{macrocode} +% Vertical rules will need to be handled differentlyy: +% where do they go in general with spanning floats? +% \begin{macrocode} +% \vrule + \box@addtopage ( \cuur@col@pos, + \csname stack@level@\the\curr@col@count \endcsname ) + {\csname col@box@\the\curr@col@count \endcsname} + \gsetmlength \cuur@col@pos { \cuur@col@pos + \columnwidth + \columnsep} +% \vrule + } +%<*trace> + \@tracepop{add@columns@topstacked} +%</trace> +} +\let \add@columns \add@columns@topstacked +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \subsection{The page box: float areas} +% +% \begin{macro}{\t@stack@area} +% \begin{macro}{\b@stack@area} +% +% The 4th argument must be a procedure that fills a box whose number +% is its last argument. This rather bizarre code merely avoids +% a box-register-per-area. +% +% \begin{macrocode} +\def\t@stack@area #1#2#3#4{ +%<*trace> + \@tracepush{t@stack@area} +%</trace> + #4 \@tempboxa +% \end{macrocode} +% First update stacking position for these columns. +% \begin{macrocode} + \@tempcnta #2 + \@tempcntb #3 \relax + \setlength \@tempdimb {\ht\@tempboxa + \dp\@tempboxa} + \loop + \@tempdima \csname stack@level@\the\@tempcntb \endcsname + \advance \@tempdima \@tempdimb + \expandafter + \xdef \csname stack@level@\the\@tempcntb \endcsname + { \the\@tempdima } + \advance \@tempcntb \@ne + \advance \@tempcnta \m@ne + \ifnum \@tempcnta > \z@ + \repeat +% \end{macrocode} +% Calculate horizontal displacement. +% \begin{macrocode} + \setlength \@tempdima + {\pagebodylefthpos - \columndisplacement + \columndisplacement * #3} +% \end{macrocode} +% Add box. +% \begin{macrocode} +%<*trace> + \tr@ce{float~area~box~#1#2#3~~lowered~:~% + \csname stack@level@#3 \endcsname + } +%</trace> + \box@addtopage (\@tempdima,\csname stack@level@#3\endcsname) + \@tempboxa +%<*trace> + \@tracepop{t@stack@area} +%</trace> +} +% \end{macrocode} +% Different order for co-stacking. +% \begin{macrocode} +\def\b@stack@area #1#2#3#4{ +%<*trace> + \@tracepush{b@stack@area} +%</trace> + #4 \@tempboxa +% \end{macrocode} +% Calculate horizontal displacement. +% \begin{macrocode} + \setlength \@tempdima + {\pagebodylefthpos - \columndisplacement + \columndisplacement * #3} +% \end{macrocode} +% Add box. +% \begin{macrocode} + \box@addtopage (\@tempdima,\csname stack@level@#3\endcsname) + \@tempboxa +% \end{macrocode} +% Then update stacking position for these columns. +% \begin{macrocode} + \@tempcnta #2 + \@tempcntb #3 \relax + \setlength \@tempdimb {\ht\@tempboxa + \dp\@tempboxa} + \loop + \@tempdima \csname stack@level@\the\@tempcntb \endcsname + \advance \@tempdima -\@tempdimb + \expandafter + \xdef \csname stack@level@\the\@tempcntb \endcsname + { \the\@tempdima } + \advance \@tempcntb \@ne + \advance \@tempcnta \m@ne + \ifnum \@tempcnta > \@ne + \repeat +%<*trace> + \@tracepop{b@stack@area} +%</trace> +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\stack@top@areas} +% \begin{macro}{\stack@bot@areas} +% +% Use of these is all a bit ad hoc for a particular stacking system. +% +% \begin{macrocode} +\def \stack@bot@areas { + \stack@areas@list b \pagebodybotvpos \pagebox@list@b +} +\def \stack@top@areas { + \stack@areas@list t \pagebodytopvpos \pagebox@list@t +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\stack@areas@list} +% +% |#1| : stacking type (t, b or c at present)\\ +% |#2| : starting position\\ +% |#3| : list name +% +% \begin{macrocode} +\def \stack@areas@list #1#2#3 { +%<*trace> + \@tracepush{stack@areas@list} +%</trace> + \ifx #3 \@empty + \else + \forall@columns { +% \end{macrocode} +% Starting point: +% \begin{macrocode} +% \vrule + \expandafter \xdef + \csname stack@level@\the\curr@col@count \endcsname + {#2} + } +% \end{macrocode} +% Stacking or co-stacking: bottom-up or top-down. +% \begin{macrocode} + \expandafter + \let \expandafter + \p@elt \csname #1@stack@area \endcsname + #3 + \fi +%<*trace> + \@tracepop{stack@areas@list} +%</trace> +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\make@area@floats@box} +% +% Format all the floats in a list and store the result in a box register. +% This should be templated. +% +% This could do the file-writing too. +% +% |#1| : area-name\\ +% |#2| : box to be filled +% +% \begin{macrocode} +\def\make@area@floats@box #1#2 { +%<*trace> + \@tracepush{make@area@floats@box} +%</trace> + \setbox #2 \vbox{} +% \let \@elt \@comflelt % Big aaah! + \def \@elt { \typeset@float@in@box {#2} } + \csname area@#1\endcsname +% \end{macrocode} +% Not very pretty yet! But better when decoration +% stuff is used. +% \begin{macrocode} + \let \@elt \relax + \expandafter + \release@floats + \csname area@#1\endcsname +%<*trace> + \@tracepop{make@area@floats@box} +%</trace> +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{DECORATIONS} +% Not used at present but something like this is probably needed. +% +% \begin{macrocode} + +\def \box@decorate@bot #1 { + \setbox #1 \vbox{ + \vskip \pagesetup@float@text@sep + \botfigrule + \unvbox #1 + \vskip -\pagesetup@float@float@sep + } +} +\def \box@decorate@top #1 { + \setbox #1 \vbox{ + \unvbox #1 + \vskip -\pagesetup@float@float@sep + \topfigrule + \vskip \pagesetup@float@text@sep + } +} + + +% \end{macrocode} +% \end{macro} +% +% +% \subsection{The page box: margins} +% +% Needed? +% +% \subsection{The page box: headers and footers} +% +% Nothing worth puting here yet. +% +% \subsection{The page box: other} +% +% Maybe should be many subsections: eg overlays. +% +% \subsection{Typesetting captions and float boxes} +% +% All more or less temporary. +% +% \begin{macro}{\@comflelt} +% \begin{macro}{\typeset@float@in@box} +% +% Maybe a bad name but this is probably as generic as it can be at +% present (and one would hate to see the name's demise). +% +% \begin{macrocode} +\def\@comflelt #1 { + \global \let \this@float@box #1 + \expandafter + \extract@this@float@actual@structure \the\toks #1 + \setbox\@tempboxa \vbox { + \unvbox\@tempboxa + \typeset@this@float@and@caption + } + } +% \end{macrocode} +% +% Thus sadly we maybe should move to this, avoiding the use of a +% global variable for parameter passing. +% +% \begin{macrocode} +\def\typeset@float@in@box #1 #2 { + \global \let \this@float@box #2 + \expandafter + \extract@this@float@actual@structure \the\toks #2 + \setbox #1 \vbox { + \unvbox #1 + \typeset@this@float@and@caption + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% +% \begin{macro}{\typeset@this@float@and@caption} +% +% This should really be a template instance. +% +% It must be integrated with the generic version of +% |\append@caption@to@float| since they must both do the same thing. +% +% May use |\this@area|, |\this@area@col@number| and other information, +% to be determined \ldots even |\this@caption@action|. +% +% First we disable premature captioning (fascist or what?). +% +% \begin{macrocode} +%<*obsolete> +\let\add@caption@to@float@box \relax +%</obsolete> + +%<*obsolete> +\def \typeset@this@float@and@caption { + \box\this@float@box + \nobreak + \smallskip + \hsize\columnwidth + \this@caption \par + \bigskip + \hrule + \vskip\pagesetup@float@float@sep + } +% Reminder ABOVE ONLY WORKS WITH THIS: +% \def\append@caption@to@float{ +% \global\setbox\this@captioned@float\vbox{ +% \copy\this@float@box +% \smallskip +% \hsize\columnwidth +% \this@caption +% \par\bigskip\hrule} +% } +%</obsolete> +% \end{macrocode} +% \end{macro} +% +% \subsection{Page box lists} +% +% \begin{macro}{\pagebox@area} +% \begin{macro}{\@addto@pagebox@list} +% +% Bad names? +% +% Add the float areas to a page-box list, and specify how to +% process them. This should be templated. The columns could be added +% to this list. +% +% The 2nd argument must at present be a procedure that has two +% arguments and it is expected to fill a box whose number +% is its last argument. This rather bizarre code merely avoids +% a box-register-per-area. +% +% |#1| : area-name +% |#2| : action for each float in area +% |#3| : area-position +% +% \begin{macrocode} +\def\pagebox@area #1#2#3 { +%<*trace> + \@tracepush {pagebox@area} +%</trace> + \expandafter + \let \expandafter + \this@list \csname area@#1\endcsname +%<*trace> + \tr@ce{adding~ floats~ (if any)~ #1~ ==~ `\this@list'~ + to~page~list:~#3 } +%</trace> + \ifx \this@list \@empty + \else + \let \p@elt \relax + \@addto@pagebox@list {#3} + { \p@elt #1 { #2 {#1}} } + \fi +%<*trace> + \@tracepop {pagebox@area} +%</trace> +} +% \end{macrocode} +% Ugh!! Improve? +% \begin{macrocode} +\def \@addto@pagebox@list #1#2 { + \@temptokena \expandafter\expandafter\expandafter + { \csname pagebox@list@#1 \endcsname + #2 + } + \expandafter + \xdef + \csname pagebox@list@#1 \endcsname + { \the\@temptokena } +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% \subsection{Magic boxes} +% +% \begin{macro}{\mbox@put} +% \begin{macro}{\box@put} +% \begin{macro}{\copy@put} +% +% Probably move sometime.\footnote{Move?} +% +% These add boxes with the specified visual relative position +% but all-zero dimensions (unlike picture mode where the inner +% boxes have non-zero vertical size). A highly generalised lap-box! +% +% At present these use Don Knuth's left-handed DVI co-ordinate +% system. They could (should?) be changed to a saner system as used +% by \LaTeX{}, Postscript and the rest of the known civilised world +% since Descartes. +% +% \begin{macrocode} +\def\mbox@put (#1,#2)#3{% + \setbox\@tempboxa \hbox { +% \raise #2 % Ugh! Zany y-direction--- + \lower #2 % thanks Don! + \hbox {\kern#1 #3\hss} + } +% \end{macrocode} +% For this application we must zero everything. +% \begin{macrocode} + \wd \@tempboxa \z@ + \ht \@tempboxa \z@ + \dp \@tempboxa \z@ + \box\@tempboxa + } +% \end{macrocode} +% +% \begin{macrocode} +\def\box@put (#1,#2)#3{% + \mbox@put (#1,#2) {\box #3} +} +% \end{macrocode} +% +% \begin{macrocode} +\def\copy@put (#1,#2)#3{ + \mbox@put (#1,#2) {\copy #3} +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \subsection{Move me!} +% +% Stuff for elsewhere; maybe to xo-new right now? +% +% \begin{macro}{\forall@areas} +% \begin{macro}{\def \make@useful@list@aux} +% \begin{macro}{\def \make@useful@list} +% Area list stuff\footnote{Probably move.}. +% +% These should be more generally used/available whatever area lists, +% however impemnted, we end up with. +% +% This list manipulation stuff works only for lists whose elements are +% unexpandable; this could be extended. +% \begin{macrocode} +\def \forall@areas #1 { + \def \area@elt ##1##2##3 { + \def \curr@area {##1##2##3} + \def \curr@pos {##1} + \def \curr@col {##3} + \def \curr@span {##2} + #1 + } + \used@areas@exec +} + +\def \make@useful@list@aux #1#2#3 { + \ifx #1 \relax + \else + \expandafter + \xdef \csname \temp@list@name @exec \endcsname + {\csname \temp@list@name @exec \endcsname \temp@list@elt #1#2#3 } + \expandafter + \make@useful@list@aux + \fi +} +\def \make@useful@list #1 #2 { + \edef \temp@list@name + {\expandafter \@gobble \string #1} + \def \temp@list@elt {#2} + \let #2 \relax + \expandafter + \let \csname \temp@list@name @exec \endcsname \@empty + \expandafter + \make@useful@list@aux #1\relax\relax\relax +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\release@floats} +% +% \begin{macrocode} +\def\release@floats#1{ +% \show #1 + \xdef \@freelist {\@freelist#1} + \global\let#1\@empty +} +% \end{macrocode} +% \end{macro} +% +% More helper functions (some not yet used)\footnote{To be moved}. +% +% Lettings. +% +% \begin{macro}{\let@nc} +% \begin{macro}{\let@cn} +% \begin{macro}{\let@cc} +% \begin{macrocode} +\def \let@nc #1 #2 { + \expandafter + \let \expandafter + #1 \csname #2\endcsname +} +\def \let@cn #1 { + \expandafter + \let \csname #1\endcsname +} +\def \let@cc #1 { + \expandafter + \let@nc \csname #1\endcsname +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% Macrised lengths etc. +% +% \begin{macro}{\setmlength} +% \begin{macro}{\gsetmlength} +% \begin{macrocode} +\def \gsetmlength #1#2 { + \setlength \@tempdima {#2} + \xdef #1 {\the\@tempdima} +} +\def \gsetmlength@c #1#2 { + \setlength \@tempdima {#2} + \expandafter + \xdef \csname #1\endcsname + {\the\@tempdima} +} +\def \setmlength #1#2 { + \setlength \@tempdima {#2} + \edef #1 {\the\@tempdima} +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \subsection{Really temp stuff} +% +% \begin{macro}{TEMP@KLUDGES} +% Some very temporary (very bad) examples and kludges: +% \begin{macrocode} +\def \do@floats { +%<*trace> + \@tracepush{do@floats} +%</trace> + \make@useful@list \used@areas \area@elt + \let \pagebox@list@t \@empty + \let \pagebox@list@b \@empty + \forall@areas { + \expandafter + \pagebox@area + \expandafter + {\curr@area} \make@area@floats@box {\curr@pos} + } +%<*trace> + \tr@ce{ + pagebox~list:~t~ is~\meaning \pagebox@list@t} + \tr@ce{ + pagebox~list:~b~ is~\meaning \pagebox@list@t} + \@tracepop{do@floats} +%</trace> +} + +% \end{macrocode} +% +% Temp place for these calcs. They should be part of the page layout +% set-up.\footnote{Move?} +% Temp positioning stuff: +% \begin{macrocode} +\AtBeginDocument { +%% vert + \setlength \@tempdima {\headheight + \headsep} + \xdef \pagebodytopvpos {\the\@tempdima} + + \setlength \@tempdima {\@tempdima + \textheight} + \xdef \pagebodybotvpos {\the\@tempdima} + +%% horiz + \setlength \@tempdima {\columnwidth + \columnsep} + \xdef \columndisplacement {\the\@tempdima} + + \def \pagebodylefthpos {\z@} % or whatever?) + +% \show \pagebodytopvpos +% \show \pagebodybotvpos +% +% \showthe \headheight +% \showthe \headsep +% \showthe \textheight +% \showthe \textwidth +% \showthe \columnwidth +} + +% \end{macrocode} +% \end{macro} +% +% \endinput +\endinput +% +% $Log: xo-final.dtx,v $ +% Revision 1.20 2000/08/11 07:14:09 latex3 +% added header +% +% Revision 1.19 2000/07/19 15:56:46 latex3 +% removed \extract@this@float@actual@structure (is now in xo-or awaiting +% normalisation with similar commands) +% +% Revision 1.18 2000/07/10 18:46:11 latex3 +% mainly macro renamings +% +% Revision 1.17 2000/06/16 11:20:40 latex3 +% rename \construct@and@test@col@height to \construct@and@test@col@ht +% rename \construct@and@test@col@heights to \construct@and@test@col@hts +% rename \cl@height1 to \@col@ht@1 (etc) +% +% Revision 1.16 2000/06/13 21:17:32 latex3 +% move setting of \protect so that it works +% +% Revision 1.15 2000/04/12 20:52:39 car2 +% Much tidyng: farewell comflelt! +% +% Revision 1.14 2000/04/06 22:14:00 car2 +% added caption setting +% +% Revision 1.13 2000/04/03 12:09:28 car2 +% alpha version +% +% Revision 1.12 2000/04/03 10:59:31 car2 +% Untidy alpha +% +% Revision 1.11 2000/03/30 21:06:28 car2 +% Chris' alpha-minus version +% +% Revision 1.10 2000/03/24 15:34:27 latex3 +% version that starts supporting spans (still a hack yet) +% +% Revision 1.9 2000/03/22 15:29:42 latex3 +% some normalisations of names +% +% Revision 1.8 2000/03/09 14:44:31 latex3 +% *** empty log message *** +% +% Revision 1.7 2000/03/05 19:38:12 latex3 +% support multiple columns (6 max right now) +% +% Revision 1.6 2000/02/26 18:25:10 david +% release floats changes +% +% Revision 1.5 2000/02/16 17:34:31 latex3 +% bit of extra tracing to find why columns do not align (no good :-) +% +% Revision 1.4 2000/02/16 13:39:47 latex3 +% added 3col support +% +% Revision 1.3 2000/02/16 10:19:03 latex3 +% better code for adding floats to column (using \pagesetup@float@text@sep and friends) +% +% Revision 1.2 2000/02/13 22:28:10 latex3 +% moved some stuff from xo-or.sty to this file +% diff --git a/Master/texmf-dist/source/latex3/xor/xo-float.dtx b/Master/texmf-dist/source/latex3/xor/xo-float.dtx new file mode 100644 index 00000000000..cc552fe25b0 --- /dev/null +++ b/Master/texmf-dist/source/latex3/xor/xo-float.dtx @@ -0,0 +1,950 @@ +% \iffalse +%% +%% (C) Copyright 1999-2000 Frank Mittelbach, David Carlisle, Chris Rowley +%% All rights reserved. +%% +%% Not for general distribution. In its present form it is not allowed +%% to put this package onto CD or an archive without consulting the +%% the authors. +%% +% \fi +% + +% \begin{macrocode} +\def\@tempa#1: #2.dtx,v #3 #4 #5 #6 #7${ + \ProvidesPackage{#2}[#4 #3 #5 #6]} +\@tempa$Id: xo-float.dtx,v 1.32 2000/08/11 07:14:11 latex3 Exp $ +% \end{macrocode} +% +% Ignore white space in this package. +% \begin{macrocode} +\IgnoreWhiteSpace +% \end{macrocode} +% +% +% +% \begin{macro}{\@xfloat} +% The start of a float environment. +% Unlike \LaTeXe, now save the float as a horizontal list. +% \begin{macrocode} +\def\@xfloat #1[#2]{% +%<*trace> +\@tracepush{float~environment} +%</trace> + \@nodocument +% #2 is either user suplied or \fps@#1 (from 2e again) + \def \@fps {#2} + \def \float@type {#1} +% \end{macrocode} +% Next line could be inline since it is used only once +% now.\footnote{Change?} +% \begin{macrocode} + \expandafter \let \expandafter + \float@sequence@class \csname sequence@class@#1 \endcsname +% \end{macrocode} +% +% \begin{macrocode} + \expandafter \let \expandafter + \float@counter \csname counter@#1 \endcsname +% \end{macrocode} +% Floats (not caption) increment counter: +% \begin{macrocode} + \refstepcounter\float@counter + \ifhmode + \@bsphack + \fi + \ifinner + \@parmoderr\@floatpenalty\z@ + \else + \@allocating@next\@currbox\@freelist + { +% +% not used any longer: +% +% \global\expandafter\let\csname fps@\the\@currbox\endcsname +% \@fps +% \global\expandafter\let\csname ftype@\the\@currbox\endcsname +% \@captype +% + \global\advance\float@sequence@count\@ne + \expandafter\PutMark\expandafter\float@sequence@class\expandafter{ + \the\float@sequence@count} + \global\toks\@currbox{} + } + \fi +% \end{macrocode} +% +% Save |\@currbox| as an |\hbox|. +% \begin{macrocode} + \global\let\@saved@label\@empty + \global \setbox\@currbox +% \end{macrocode} +% The float body is typeset in a normalised environment, i.e.., we +% reset colour and font. This is followed by a call to +% |\body@|\meta{type} to allow the designer to set up special +% conventions for each float type, e.g., a special font or font +% size or a special colour, etc. +% \begin{macrocode} + \hbox \bgroup\color@begingroup + \normalcolor + \normalfont + \normalsize + \csname body@\float@type \endcsname + \ignorespaces} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@endfloatbox} +% The end of a float environment. +% First finish off the box assignment. Then make a copy in a second box. +% The current code makes use of the fact that the allocated boxes +% are in two continuous runs, |\sbx@offset| apart. +% \begin{macrocode} +\def \@endfloatbox{% + \unskip + \outer@nobreak + \color@endgroup + \egroup + \edef\@tempa{ + \global\toks\@currbox{ + {\the\toks\@currbox}{\SPANCNT} + {\@saved@label} + {\csname the\float@counter \endcsname} + {\@fps} + {\float@type} + {\the\float@sequence@count} + }} + \@tempa +%<*trace> +\tr@ce{\the\toks\@currbox} +%</trace> +% \end{macrocode} +% Simple temporary interface to get here floats for testing. Needs +% replacment!\footnote{FIX!!!} +% \begin{macrocode} + \def\@tempa{h} + \ifx\@fps\@tempa + \setup@here@float + \else + \@cons\@activelist\@currbox + \fi +%<*trace> +\@tracepop{float~environment} +%</trace> +} + +\def\SPANCNT{} %%% do properly one day: David + + +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\float@sequence@count} +% |\float@sequence@count| is the counter used to uniquely refer +% to the floats, it is incremented whenever we encounter a new float. +% \begin{macrocode} +\newcount\float@sequence@count +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\label} +% Modify to save the label string. +% \begin{macrocode} +\def\label#1{\@bsphack + \gdef\@saved@label{#1} + \protected@write\@auxout{}% + {\string\newlabel{#1}{{\@currentlabel}{\thepage}}}% + \@esphack} +% \end{macrocode} +% \end{macro} +% +% +% +% +% +% +% \begin{macro}{\DeclareFloatType} +% A float type is an identifier like ``figure'' the defines a class +% (?) of floats of floats which have certain attributes in common, +% e.g., they have the same fixed caption text (e.g. \texttt{Fig}), +% they use the same counter to number the floats, etc. +% +% Setting up a float type is done by declaring an instance of type +% \texttt{floattypesetup} and then executing it. +% \begin{macrocode} +\def\DeclareFloatType#1#2{ + \DeclareInstance{floattypesetup}{#1}{std} + { type-id = #1, #2 } + \UseInstance{floattypesetup}{#1} +} +% \end{macrocode} +% +% For each float type \texttt{TYPE} the following utility macros +% hold important static data. +% +% \DescribeMacro\sequence@class@TYPE +% The |\sequence@class@TYPE| holds the name of the float sequence +% class the float type |TYPE| belongs to. A sequence class contains +% all types which should be placed in order of their call-outs, +% e.g., if type ``figure'' and ``table'' are in the same sequence +% class a table whose call-out is later than that of a figure will +% not be placed before it. If on the other hand these types are in +% different sequence classes such reordering will be undertaken by +% the placement algorithm if feasible. +% +% +% \DescribeMacro\toc@extension@TYPE +% The |\toc@extension@TYPE| holds the file extension to which +% caption information for this type is written, e.g., |lot| for +% tables, or |lof| for figures. If there is the desire to produce +% combined listing one can use the same extension for different +% float types.\footnote{This functionality can alternatively be +% provided by putting all captions into a single external file and +% then ignore certain entries when reading the data back, so it +% might vanish again.} +% +% +% \DescribeMacro\fps@TYPE +% The |\fps@TYPE| holds the default float areas in which this float +% type is allowed to go. By default this is the full list of all +% known areas. By restricting it to a subset of areas it is +% possible to provide special placement arrangements, e.g., tables +% always at the bottom only. +% +% +% \DescribeMacro\caption@TYPE +% The |\caption@TYPE| holds the fixed caption text which is +% displayed together with the caption number, e.g., |Figure|, +% etc. This is passed to the caption formatting instances. +% +% +% \DescribeMacro\counter@TYPE +% The |\counter@TYPE| holds the name of the counter to use for +% numbering the floats of type |TYPE|. It is possible that +% different types share the same counter, i.e., are numbered as a +% single sequence. However in that case one should probably ensure +% that the types belong to a single float sequence class since +% otherwise the numbers within the document might get out of +% sequence. On the other hand it is not required to have floats in +% the same sequence class share a counter; they can be numbered +% independently without problems. +% +% \DescribeMacro\body@TYPE +% The |\body@TYPE| holds the formatting instructions that should be +% applied to the body of each float of type |TYPE|. +% +% \begin{macrocode} +\DeclareTemplateType{floattypesetup}{0} + +\DeclareTemplate{floattypesetup}{std}{0}{ + type-id =n \floattypesetup@id, + sequence-class-id =n \floattypesetup@class@id, + toc-extension =n \floattypesetup@toc@ext, + default-area-list =n \floattypesetup@area@list, + caption-text =n \floattypesetup@caption@text, + numbered-boolean =b @test, + numbered-id =n \floattypesetup@numbered@id, + numbered-within-id =n \floattypesetup@numbered@within@id, + numbered-action =f0 \floattypesetup@numbered@action, + body-decls =f0 \floattypesetup@body@decls, + + } + { +% \end{macrocode} +% Setting up defaults is done (at least in parts) in two steps: +% first we set certain key commands to |\relax| then we run +% |\DoParameterAssignments| and then check if they are still +% |\relax|. If so we set the commands that we really want to +% set. This is necessary because several of them have names that +% contain the float type as part of the name and this type name is +% one of the keys. +% \begin{macrocode} + \let\floattypesetup@class@id\relax + \let\floattypesetup@numbered@id\relax + \let\floattypesetup@numbered@action\relax + \let\floattypesetup@body@decls\relax +% \end{macrocode} +% Now for the defaults we can set directly: +% the |@test| switch is locally used to denote that we want to +% number the floats. +% \begin{macrocode} + \@testtrue % number by default +% \end{macrocode} +% The areas which should be tried for the current type are by +% default all areas, i.e., |\known@areas|; we use |\def| not |\let| +% to allow this list to grow afterwards. +% \begin{macrocode} + \def\floattypesetup@area@list{\known@areas} +% \end{macrocode} +% Default for the fixed caption text is |\@empty|. +% \begin{macrocode} + \let\floattypesetup@caption@text\@empty +% \end{macrocode} +% By default we don't run the float counter within another +% counter. We use |\@empty| to denote this since this is also what +% would be returned from |numbered-within-id=,| which might be +% specified by a user. +% \begin{macrocode} + \let\floattypesetup@numbered@within@id\@empty +% \end{macrocode} +% Everything goes by default to the |.toc| file (which isn't too +% bad if the extended \texttt{xcontents} package is used. +% \begin{macrocode} + \def\floattypesetup@toc@ext{toc} % everything in here by default +% \end{macrocode} +% Now we are ready to look at the designer specifications: +% \begin{macrocode} + \DoParameterAssignments +% \end{macrocode} +% Now for the second step: evaluate what we have: If the +% |sequence-class-id| is not set up, we try to default it to the +% |type-id|: +% \begin{macrocode} + \ifx\floattypesetup@class@id\relax + \let\floattypesetup@class@id\floattypesetup@id + \fi +% \end{macrocode} +% Float numbers are only set up if requested (which is the default). +% \begin{macrocode} + \if@test +% \end{macrocode} +% If the |numbered-id| is not set up, we try to default it to +% the |type-id|:\footnote{This needs fixing since part of the float +% handling assumes there is some counter to step etc. FIX!} +% \begin{macrocode} + \ifx\floattypesetup@numbered@id\relax + \let\floattypesetup@numbered@id\floattypesetup@id + \fi +% \end{macrocode} +% Set up the new counter, if it already exists skip this part: +% \begin{macrocode} + \expandafter\ifx\csname c@\floattypesetup@numbered@id \endcsname + \relax + \ifx\floattypesetup@numbered@within@id\@empty + \newcounter\floattypesetup@numbered@id + \else + \newcounter\floattypesetup@numbered@id + [\floattypesetup@numbered@within@id] + \fi +% \end{macrocode} +% The default display for the float number is ``arabic'', we +% overwrite this only if requested: +% \begin{macrocode} + \ifx\floattypesetup@numbered@action\relax + \else + \global\expandafter\let + \csname the\floattypesetup@numbered@id \endcsname + \floattypesetup@numbered@action + \fi + \fi + \fi +% \end{macrocode} +% +% Low-level environment declaration (allows overwriting since +% figure etc already exists)\footnote{Handle better?} +% \begin{macrocode} + \expandafter + \xdef\csname \floattypesetup@id \endcsname + {\noexpand\@float{\floattypesetup@id}} + \global\expandafter \let \csname end\floattypesetup@id \endcsname + \end@float +% \end{macrocode} +% The remaining bits of the code set up the data structures that +% belong to each float type by linking the macro name containing +% the type in its name (i.e., |\floattypesetup@id|) to the +% corresponding key macro. Theay are otherwise straight forward +% |\let|s. +% +% First for |\sequence@class@|\meta{type}: +% \begin{macrocode} + \global\expandafter\let + \csname sequence@class@\floattypesetup@id \endcsname + \floattypesetup@class@id +% \end{macrocode} +% Then |\toc@extension@|\meta{type}: +% \begin{macrocode} + \global\expandafter\let + \csname toc@extension@\floattypesetup@id \endcsname + \floattypesetup@toc@ext +% \end{macrocode} +% Then |\fps@|\meta{type}: +% \begin{macrocode} + \global\expandafter\let + \csname fps@\floattypesetup@id \endcsname + \floattypesetup@area@list +% \end{macrocode} +% Then |\caption@|\meta{type}: +% \begin{macrocode} + \global\expandafter\let + \csname caption@\floattypesetup@id \endcsname + \floattypesetup@caption@text +% \end{macrocode} +% Then |\counter@|\meta{type}: +% \begin{macrocode} + \global\expandafter\let + \csname counter@\floattypesetup@id \endcsname + \floattypesetup@numbered@id +% \end{macrocode} +% Then |\body@|\meta{type}: +% \begin{macrocode} + \global\expandafter\let + \csname body@\floattypesetup@id \endcsname + \floattypesetup@body@decls + } +% +% +% +% +% \begin{macro}{\DeclareFloatSequenceClass} +% A float sequence class is a list of float types for which the +% placement algorithm should preserve call-out order even between +% objects with different float type. +% +% For each class we need a corresponding ``mark'' (needed by the +% algorithm) and we need to record the class name in an |\@elt| +% list. +% +% Perhaps this declaration should be implicitly handled by +% |\DeclareFloatType|. It would mean a bit more work for the latter +% but less declarations in the document design!\footnote{Change one +% day!} +% \begin{macrocode} +\def\DeclareFloatSequenceClass#1{ +% \end{macrocode} +% We probably have to check if that class is already +% declared since in that case we have to leave out a couple of +% actions. We assume that this is the case if a mark class is +% already defined for it.\footnote{Do it properly!} +% \begin{macrocode} + \@ifundefined{mark@#1} + { + \DeclareMarkType{#1} +% \end{macrocode} +% Add this to the list of known classes. +% \begin{macrocode} + \@cons\float@classes@list{{#1}} + } + \ErrorAlreadyDefined +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\float@classes@list} +% The list of float classes known in the system. +% \begin{macrocode} +\let\float@classes@list\@empty +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\c@figure} +% \begin{macro}{\c@table} +% Throw away good registers\ldots this is only for testing to allow +% us using the OR together with classes like article that sets up +% figure and table already\footnote{Clean up!} +% \begin{macrocode} +\expandafter\ifx\csname c@figure \endcsname \relax +\else + \let\c@figure\relax % thus new counter will be defined + \let\c@table \relax +\fi +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% +% +% +% +% +% +% \subsection{Float Placement Control Files} +% +% \begin{macro}{\perhaps@write@placements@to@fpl@file} +% |\perhaps@write@placements@to@fpl@file| writes all float +% placements (except for ``here'' floats) into the |fpl| in case we +% are writing to this file. +% +% By default, don't write fpl files. +% \begin{macrocode} +\let\perhaps@write@placements@to@fpl@file\relax +\let\perhaps@write@to@fpl@file\@gobble +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\perhaps@write@to@fpl@file} +% |\perhaps@write@to@fpl@file| writes its first argument to the +% |fpl| in case we are writing to it. +% +% By default, don't write fpl files. +% \begin{macrocode} +\let\perhaps@write@to@fpl@file\@gobble +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\perhaps@write@placements@to@fpl@file@aux} +% The format for a Float: line in an |fpl| file. Only the sequence +% number (|#7|) is currently used, the rest just helps a human +% reader identify the float. +% \begin{macrocode} +\def\perhaps@write@placements@to@fpl@file@aux#1#2#3#4#5#6#7{ + \@spaces\@spaces Float:~#7~(#6~#4)~[#3]^^J} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\savefloatplacements} +% Declaration to turn on writing of FPL files. +% \begin{macrocode} +\def\savefloatplacements{ + \newwrite\fpl@file + \immediate\openout\fpl@file\jobname.fpl + \def\perhaps@write@to@fpl@file{ + \immediate\write\fpl@file + } + \def\perhaps@write@placements@to@fpl@file{ + \def\@elt{\expandafter + \perhaps@write@placements@to@fpl@file@aux\the\toks} + \perhaps@write@to@fpl@file{ + ^^JPage:~\the\absolute@page@number\space (\the\c@page)^^J +% \end{macrocode} +% +% \begin{macrocode} + \expandafter\@write@areas\used@areas\relax\relax\relax + } + \let\@elt\relax}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@write@areas} +% |\@write@areas| loops through an area list (like |\used@areas|) +% and writes lines for every float, provided that |\@elt| is +% properly set up before. It is used inside a |\write| so needs to +% be expandable! +% \begin{macrocode} +\def\@write@areas#1#2#3{ + \ifx\relax#1 + \else + \expandafter\ifx\csname area@#1#2#3\endcsname\@empty + \else + \@spaces Area:~#1#2#3^^J\csname area@#1#2#3\endcsname + \fi + \expandafter\@write@areas + \fi} +% \end{macrocode} +% Alternate version that writes out all areas even if they don't +% contain any floats. +% \begin{macrocode} +\def\@write@areas#1#2#3{ + \ifx\relax#1 + \else + \@spaces Area:~#1#2#3^^J\csname area@#1#2#3\endcsname + \expandafter\@write@areas + \fi} +% \end{macrocode} +% \end{macro} +% +% +% +% +% \begin{macro}{\readfloatplacements} +% Similar declaration to read FPC files. The file is read at this +% point up to th efirst Page: line. and the output routine command +% |\float@placement@loop| is redefined to read the FPC info for each page. +% \begin{macrocode} +\def\readfloatplacements{ + \newread\fpc@file + \openin\fpc@file\jobname.fpc\relax + \ifeof\fpc@file + \PackageWarningNoLine{xo} + {No~\jobname.fpc:~using~automatic~float~placement} + \else + \let\get@fpc@page@data\get@fpc@page@data@fpc + \get@fpc@page@data + \let\try@float@pages\relax +% \end{macrocode} +% Next line should go once we implement moving floats in and out of +% ``here'' as then we need to read the file at a different +% place!\footnote{Reimplement!} +% \begin{macrocode} + \let\float@placement@loop\fpc@float@placement@loop + \fi +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\fpc@float@placement@loop} +% Version of |\try@float@pages| to use with float placement control file. +% Should be moved to xo-or once it works. +% \begin{macrocode} +\def\fpc@float@placement@loop{ +%<*trace> + \@tracepush{fpc@float@placement@loop} +%</trace> +% \end{macrocode} +% Don't think the the next line has any meaning, so +% removed.\footnote{Old command only did set up best@trial, which +% is later on set to relax anyway. Correct to remove?} +% \begin{macrocode} +% \initialise@best@trial + \get@fpc@page@data + \global\let\best@trial\relax +% \end{macrocode} +% +% \footnote{Do we have to set run@with@floats? Check!} +% \begin{macrocode} + \mark@restore@state{ + \unvcopy\@holdpg + \setup@best@column@or + } +%<*trace> + \@tracepop{fpc@float@placement@loop} +%</trace> +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\next@fpc@page} +% The next page for which there is FPC data. Initial value has to be +% a number to |\ifnum|. +% \begin{macrocode} +\let\next@fpc@page\m@ne +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\get@fpc@page@data} +% +% \begin{macrocode} +\let\get@fpc@page@data\relax +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\get@fpc@page@data@fpc} +% get one line of data from an FPC file, calls itself recursively +% so the effect of a call is to get all the lines for the current page +% up to and including the Page: line for the next page for which there +% is data. +% \begin{macrocode} +\def\get@fpc@page@data@fpc{ +%<*trace> +\@tracepush{get@fpc@page@data@fpc} +%</trace> + \let\@nextfpc\relax + \ifnum\next@fpc@page>\absolute@page@number +%<*trace> + \tr@ce{No~ float~ control~ on~ page:~ \the\absolute@page@number} +%</trace> + \else + \ifeof\fpc@file +%<*trace> + \tr@ce{fpc~ file~ended} +%</trace> + \global\let\next@fpc@page\maxdimen + \else + \begingroup + \endlinechar`\ % + \catcode`\ 10\relax + \global\read\fpc@file~to~\@gtempa + \endgroup + \let\@nextfpc\get@fpc@page@data + \ifx\@gtempa\@empty + \else + \expandafter\parse@fpc\@gtempa\relax + \fi + \fi + \fi +%<*trace> +\@tracepop{get@fpc@page@data@fpc} +%</trace> + \@nextfpc +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{parse@fpc} +% If float control files are being read, +% Read the section of the fpc file for this page +% and directly assign floats to the specified areas +% with no trials or checks. +% \begin{macrocode} +\def\parse@fpc#1#2~#3~#4\relax{ + \ifx P#1 +%<*trace> +\tr@ce{Next~page~control:~#3} +%</trace> + \global\mathchardef\next@fpc@page#3\relax + \let\@nextfpc\relax + \else\ifx A#1 +%<*trace> +\tr@ce{Area:~#3} +%</trace> + \setup@this@area{#3} + \let\@nextfpc\get@fpc@page@data + \else\ifx F#1 + \ifx\this@area\fpc@here +% \end{macrocode} +% Should allow moving floats into and out of here status means +% reading before the collecton OR, not after.\footnote{FIX, update, +% extend --- whatever you want to call it.} +% \begin{macrocode} +%<*trace> +\tr@ce{here~float} +%</trace> + \else +%<*trace> +\tr@ce{not~here~float} +%</trace> + \begingroup + \count@#3\relax + \global\let\this@float@box\relax + \let\@elt\extract@float@by@number + \@activelist + \endgroup +% \end{macrocode} +% If a float number is specified and there is not a float of that +% number in the active list, something has gone wrong, either we +% haven't reached the float yet (possible if the new arrangement +% results in the callout being on a later page than specified) or +% we have already assigned this float (which is a bug, either in +% this code, or in the fpc file.) Currently this condition is not +% handled other than by |\ERROR|. If the float is found, assign it +% to the current area (as set by an Area: line in the fpc file. +% \begin{macrocode} + \ifx\this@float@box\relax +%<*trace> + \tr@ce{Float:~#3~not~found} +%</trace> + \edef\fpc@list{\fpc@list#3,\this@area\relax} + \show\fpc@list + \else +%<*trace> + \tr@ce{Float:~#3~is~\this@float@box} +%</trace> +% \end{macrocode} +% Before we add the float, let's do some sanity checks. We allow to +% place a float into an area which is bigger than the float (spans +% more columns) but we complain if the area is smaller. +% \begin{macrocode} + \ifnum \this@area@span@number < + \if!\this@span@number! 1\else % big hack + \this@span@number \fi + \relax + \PackageError{xo} + {Float~ bigger~ than~ target~ area} + {Float~\this@sequence@number\space spans ~ + \this@span@number\space columns,~ + but~ target~ area~ \this@area\space + spans~ only~ \this@area@span@number\space + columns.\MessageBreak + Correct~ the~ data~ in~ file~ \jobname.fpc! + } + \fi +% \end{macrocode} +% We also check if the target area is allowed on the current page +% (it could be the case that the page setup for that page doesn't +% list it in its |area-list| key! +% \begin{macrocode} + \xin@\this@area + \used@areas + \ifin@\else + \PackageError{xo} + {Target~ area~ not~ available~ on~ current~ page} + {Float~ \this@sequence@number\space was~ requested~ to~ + be~ placed~ into~ area~ \this@area,\MessageBreak + but~ this~ + area~ is~ not~ available~ on~ page~ \thepage. + \MessageBreak + Correct~ the~ data~ in~ file~ \jobname.fpc! + } +% \end{macrocode} +% If we can't put it into the requested area we have to put it +% somewhere else. Otherwise a lot of code might break. So we simply +% chose the first area in |\used@area|\footnote{Need a solution if +% the page doesn't allow ``any'' floats! FIX!} +% \begin{macrocode} + \ifx\used@areas\@empty % we have a problem + \RESOLVE + \else + \setup@this@area{\expandafter\@carcube\used@areas\@nil} + \fi + \fi +% \end{macrocode} +% Typeset and attach the caption and adjust the text size for the +% current column. +% \begin{macrocode} + \append@caption@to@float + \construct@and@test@col@hts + \if@test + \ERRORFloatAreaToLarge + \fi +% \end{macrocode} +% We append the float to the area after the above column updates, +% otherwise |\construct@and@test@col@hts| would incorrectly think +% there is already a float present even if we add the first float +% to an area. +% \begin{macrocode} + \let\@elt\relax + \xdef\@freelist{\@freelist\@elt\this@float@box} + \expandafter\@cons\csname area@\this@area\expandafter\endcsname + \this@float@box + \fi + \fi +% \end{macrocode} +% +% Loop to next line. +% \begin{macrocode} + \let\@nextfpc\get@fpc@page@data +% \end{macrocode} +% end of case on type of fpc line. +% \begin{macrocode} + \fi\fi\fi +} +% \end{macrocode} +% \end{macro} +% +% +% +% +% \begin{macro}{\fpc@here} +% +% \begin{macrocode} +\def\fpc@here{hhh} +% \end{macrocode} +% \end{macro} + +% \begin{macro}{\fpc@list} +% +% \begin{macrocode} +\def\fpc@list{\relax} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\get@float@number} +% could be known as |\@seventhofseven|. +% \begin{macrocode} +\def\get@float@number#1#2#3#4#5#6#7{#7} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\extract@float@by@number} +% Find the float box that has the float with sequence number |\count@|. +% \begin{macrocode} +\def\extract@float@by@number#1{ + \ifnum\expandafter\get@float@number\the\toks#1=\count@ + \def\@currbox{#1} + \expandafter\update@this@float@structure\the\toks#1 + \fi} +% \end{macrocode} +% \end{macro} +% +% +% +% +% +% \endinput +\endinput +% +% $Log: xo-float.dtx,v $ +% Revision 1.32 2000/08/11 07:14:11 latex3 +% added header +% +% Revision 1.31 2000/08/11 06:48:24 latex3 +% untabify +% +% Revision 1.30 2000/08/11 06:44:00 latex3 +% fix typo in initialization +% +% Revision 1.29 2000/08/04 10:17:28 latex3 +% separate out initialisation of here float +% +% Revision 1.28 2000/07/19 17:14:01 latex3 +% deduce \this@class from \this@type instead of storing it on a per +% float basis +% +% Revision 1.27 2000/07/19 15:53:46 latex3 +% introduced float sequence classes +% cleaned up parts of the code +% added further documentation +% +% Revision 1.26 2000/07/10 18:47:12 latex3 +% macro name renaming +% +% Revision 1.25 2000/06/29 17:16:30 latex3 +% introduced \setup@this@area +% +% Revision 1.24 2000/06/26 15:00:59 latex3 +% docu update +% +% Revision 1.23 2000/06/22 20:07:00 latex3 +% renamed some macros to get them more uniform +% +% Revision 1.22 2000/06/22 10:55:59 latex3 +% Includeed part of David's code (formerly in xo-dpc.sty) for writing +% and reading fpl/fpc files. Not done is moving floats in and out of hhh +% +% Revision 1.21 2000/06/16 11:20:50 latex3 +% rename \construct@and@test@col@height to \construct@and@test@col@ht +% rename \construct@and@test@col@heights to \construct@and@test@col@hts +% rename \cl@height1 to \@col@ht@1 (etc) +% +% Revision 1.20 2000/06/15 15:24:25 latex3 +% implemented new semantics for area names +% +% Revision 1.19 2000/06/13 21:18:02 latex3 +% add some trace guards +% +% Revision 1.18 2000/05/03 18:55:34 latex3 +% pass \theCNT instead of \value{CNT} in the float data structure (we +% might need both one day) +% +% Revision 1.17 2000/04/21 19:11:39 latex3 +% updated here float interface (needs fixing) +% +% Revision 1.16 2000/04/08 10:49:39 latex3 +% first draft support for here floats +% +% Revision 1.15 2000/03/24 15:34:27 latex3 +% version that starts supporting spans (still a hack yet) +% +% Revision 1.14 2000/03/22 15:30:28 latex3 +% some normalisations of names +% started on spans (tmp version) +% +% Revision 1.13 2000/03/16 10:28:29 latex3 +% partial and full flush working for the first time +% +% Revision 1.12 2000/03/05 19:40:07 latex3 +% support multiple columns (6 max right now) +% moved some float init code into page setup +% +% Revision 1.11 2000/02/26 18:22:59 david +% interface to x-alloc and make changes due to +% deferred float pre-allocation +% +% Revision 1.10 2000/02/21 01:45:23 david +% documentation improvements +% +% Revision 1.9 2000/02/20 00:05:08 david +% use galley, don't discard it (get more pages that way) +% +% Revision 1.8 2000/02/19 23:16:19 david +% Use \construct@and@test@col@height before destroying +% \this@captioned@float, not after... +% +% Revision 1.7 2000/02/19 18:55:44 david +% reading fpc files +% +% Revision 1.6 2000/02/17 22:47:07 david +% *** empty log message *** +% +% Revision 1.5.1.1 2000/02/16 10:39:42 latex3 +% 3cols support added +% diff --git a/Master/texmf-dist/source/latex3/xor/xo-flow-chart.dtx b/Master/texmf-dist/source/latex3/xor/xo-flow-chart.dtx new file mode 100644 index 00000000000..5565a5aa6ad --- /dev/null +++ b/Master/texmf-dist/source/latex3/xor/xo-flow-chart.dtx @@ -0,0 +1,153 @@ + +% \iffalse +% $Id: xo-flow-chart.dtx,v 1.5 2000/03/22 15:31:14 latex3 Exp $ +% \fi + +\begin{footnotesize} +\begin{verbatim} + (1) + | + V + \setup@collection@or + | + V + New OR: \collection@or + | + V + \setup@float@placement + + + + \setup@float@placement + | + V +(2)--> \float@placement@loop + | + V + \trial@inner@loop + | + V + <current float successfully placed in previous trial?> + | | + no yes + | | + | | + | V + | \try@next@float <--------------------- + | | | + | | | + | <\@activelist empty?> | + | | | | + | no yes | + | | | | + | | V | + | (get it) \@activelist@empty@action | + | | (= \setup@best@column@or) | + -------------v---------------- | + | | + | | + -----> \select@and@test@next@area | + | | | + | | | + | <still open areas for current float type?> | + | | | | + | yes no---------------(defer float)---------------- + | | | + | (do some tests and perhaps | + | close area this way) | + | | | + | <float allowed on this page/column (according to tests)?> | + | | | | + | yes no---------------(defer float)---------------- + | | + | <current area got closed by any test?> + | | | + | yes no + | | | + -------- V + \pretests@success@action (\setup@grabcolumn@or) + + + + + \setup@grabcolumn@or + | + V + \grabcolumn@loop <-------- + | | + V | + New OR: \grabcolumn@or | + | | + | | + <all cols produced?> | + | | | + yes no------------ + | + (store results of trial) + | + V + \setup@cleanup@or + | + V + New OR: \cleanup@or + | + V + <special outputpenalty reached?> --> (reenter 2) + + + + \setup@best@column@or + | + V + \best@column@loop <------- + | | + V | + New OR: \best@column@or | + | | + <all cols produced?> | + | | | + yes no---------- + | + (produce final page) + | + V + \initialise@next@page + | + V + (try to make float pages) + | + V + \setup@collection@or (reenter 1) + + + +\end{verbatim} +\end{footnotesize} + +\endinput + +% +% $Log: xo-flow-chart.dtx,v $ +% Revision 1.5 2000/03/22 15:31:14 latex3 +% some normalisations of names +% some corrections +% +% Revision 1.4 2000/03/05 19:38:51 latex3 +% more updates -- still wrong +% +% Revision 1.3 2000/02/26 18:27:52 david +% updates (not finished) +% +% Revision 1.4 2000/02/18 19:08:47 car2 +% oops, something else changed! +% +% Revision 1.3 2000/02/18 19:05:04 car2 +% correction: removed a defer +% +% Revision 1.2 2000/02/16 10:20:14 latex3 +% small updates +% +% Revision 1.1 2000/02/16 07:35:47 latex3 +% Initial revision +% + diff --git a/Master/texmf-dist/source/latex3/xor/xo-grid.dtx b/Master/texmf-dist/source/latex3/xor/xo-grid.dtx new file mode 100644 index 00000000000..b1d737358a7 --- /dev/null +++ b/Master/texmf-dist/source/latex3/xor/xo-grid.dtx @@ -0,0 +1,345 @@ +% \iffalse +%% +%% (C) Copyright 1999-2000 Frank Mittelbach, David Carlisle, Chris Rowley +%% All rights reserved. +%% +%% Not for general distribution. In its present form it is not allowed +%% to put this package onto CD or an archive without consulting the +%% the authors. +%% +% \fi +% + +% \begin{macrocode} +\def\@tempa#1: #2.dtx,v #3 #4 #5 #6 #7${ + \ProvidesPackage{#2}[#4 #3 #5 #6]} +\@tempa$Id: xo-grid.dtx,v 1.3 2000/08/11 07:14:20 latex3 Exp $ +% \end{macrocode} +% +% Ignore white space in this package. +% \begin{macrocode} +\IgnoreWhiteSpace +% \end{macrocode} +% +% This package implements grid design on top of \LaTeXe{} by adding +% |\AlignToGrid| in various macros. Nothing else is really needed (or +% so I hope :-) +% +% So far this probably doesn't cover all structures that should, or +% could be handled automatically. +% +% \subsection{Headings} +% +% +% \begin{macro}{\headingsinkage} +% This is a temporary register used to specify the amount of +% sinkage a |\@startsection| heading is allowed if it falls at the +% a column break. In a proper reimplementation of |\@startsection| +% as a template, this should be individually specifiable rather +% than being the same for all headings! +% \begin{macrocode} +\newskip\headingsinkage +\headingsinkage=5pt plus 3pt minus 5pt +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@startsection} +% \begin{macrocode} +\def\@startsection#1#2#3#4#5#6{% + \if@noskipsec \leavevmode \fi + \par + \@tempskipa #4\relax + \@afterindenttrue + \ifdim \@tempskipa <\z@ + \@tempskipa -\@tempskipa \@afterindentfalse + \fi + \if@nobreak + \everypar{}% + \else + \addpenalty\@secpenalty + \addvspace\@tempskipa +% \end{macrocode} +% next lines are pretty horrible but we need something like this +% here (only it could be be done better) +% \begin{macrocode} + \vskip-\headingsinkage + \vskip\saved@topskip + \vskip-\prevdepth + \nointerlineskip + \null + \nobreak + \vskip-\saved@topskip + \vskip\headingsinkage + \fi + \@ifstar + {\@ssect{#3}{#4}{#5}{#6}}% + {\@dblarg{\@sect{#1}{#2}{#3}{#4}{#5}{#6}}}} +% \end{macrocode} +% \end{macro} +% +% +% +% +% \begin{macro}{\@sect} +% Have to ensure that we don't get the heading itself aligned due +% to a dangling |\AlignToGrid| from a previous structure, so we +% issue a |\IgnoreAlignToGrid| early on. That's the only change for +% this command. +% \begin{macrocode} +\def\@sect#1#2#3#4#5#6[#7]#8{% + \ifnum #2>\c@secnumdepth + \let\@svsec\@empty + \else + \refstepcounter{#1}% + \protected@edef\@svsec{\@seccntformat{#1}\relax}% + \fi + \@tempskipa #5\relax + \IgnoreAlignToGrid + \ifdim \@tempskipa>\z@ + \begingroup + #6{% + \@hangfrom{\hskip #3\relax\@svsec}% + \interlinepenalty \@M #8\@@par}% + \endgroup + \csname #1mark\endcsname{#7}% + \addcontentsline{toc}{#1}{% + \ifnum #2>\c@secnumdepth \else + \protect\numberline{\csname the#1\endcsname}% + \fi + #7}% + \else + \def\@svsechd{% + #6{\hskip #3\relax + \@svsec #8}% + \csname #1mark\endcsname{#7}% + \addcontentsline{toc}{#1}{% + \ifnum #2>\c@secnumdepth \else + \protect\numberline{\csname the#1\endcsname}% + \fi + #7}}% + \fi + \@xsect{#5}} +% \end{macrocode} +% \end{macro} +% +% +% +% +% \begin{macro}{\@xsect} +% Now after having typeset the heading we need to issue +% |\ObeyAlignToGrid| and make sure that the first line of text gets +% aligned again. And in addition we issue a |\AlignToGrid| inside +% the |\everypar| to align the first text after the heading. Of +% course that mean that we will generate a break point after this +% line and thus might end up up with a heading and only a single +% line afterwards. +% +% This could be fixed by using a ``rspace'' structure as +% implemented in \texttt{xo-or.sty} but this is not added at the +% moment! +% \begin{macrocode} +\def\@xsect#1{% + \ObeyAlignToGrid + \@tempskipa #1\relax + \ifdim \@tempskipa>\z@ + \par \nobreak + \vskip \@tempskipa + \@afterheading + \else + \@nobreakfalse + \global\@noskipsectrue + \everypar{% + \if@noskipsec + \global\@noskipsecfalse + {\setbox\z@\lastbox}% + \clubpenalty\@M + \AlignToGrid + \begingroup \@svsechd \endgroup + \unskip + \@tempskipa #1\relax + \hskip -\@tempskipa + \else + \clubpenalty \@clubpenalty + \everypar{}% + \fi}% + \fi + \ignorespaces} +% \end{macrocode} +% \end{macro} +% +% +% +% +% +% \begin{macro}{\@afterheading} +% The other case where we have to add |\AlignToGrid| to the +% |\everypar|. +% \begin{macrocode} +\def\@afterheading{% + \@nobreaktrue + \everypar{% + \if@nobreak + \@nobreakfalse + \clubpenalty \@M + \if@afterindent \else + {\setbox\z@\lastbox}% + \fi + \AlignToGrid + \else + \clubpenalty \@clubpenalty + \everypar{}% + \fi}} +% \end{macrocode} +% \end{macro} +% +% +% \subsection{List structures} +% +% \begin{macro}{\@doendpe} +% Handling of |\everypar| after a list strcture is already strange +% and complicated; here we complicate it even more by adding +% |\AlignToGrid| into its definition(s). +% \begin{macrocode} +\def\@doendpe{\@endpetrue + \def\par{\@restorepar + \everypar{\everypar{}\AlignToGrid}\par\@endpefalse}% + \everypar{{\setbox\z@\lastbox}\everypar{}\AlignToGrid\@endpefalse}% +} +% \end{macrocode} +% \end{macro} +% +% +% +% +% +% \begin{macro}{\endtrivlist} +% And there is one case in |\endtrivlist| in which |\@doendpe| +% is skipped so we have to set |\everypar| manually +% here.\footnote{Perhaps done in a wrong way, CHECK!} +% \begin{macrocode} +\def\endtrivlist{% + \if@inlabel + \leavevmode + \global \@inlabelfalse + \fi + \if@newlist + \@noitemerr + \global \@newlistfalse + \fi + \ifhmode\unskip \par\fi + \if@noparlist + \everypar{\everypar{}\AlignToGrid} + \else + \ifdim\lastskip >\z@ + \@tempskipa\lastskip \vskip -\lastskip + \advance\@tempskipa\parskip \advance\@tempskipa -\@outerparskip + \vskip\@tempskipa + \fi + \@endparenv + \fi +} +% \end{macrocode} +% \end{macro} +% +% +% \subsection{Math} +% +% \begin{macro}{\displaymath} +% \begin{macro}{\enddisplaymath} +% \begin{macro}{\[} +% \begin{macro}{\]} +% Math is a bit more complicated as with the standard definitions +% we don't regain control after the display. So we change all the +% definitions to use the |\@doendpe| method. This means we have to +% redefine |\[| at al to be a ref to |\displaymath| not the other +% way around as it was done in \texttt{latex.ltx}. +% \begin{macrocode} +\def \displaymath { + \relax\ifmmode + \@badmath + \else + \ifvmode + \nointerlineskip + \makebox[.6\linewidth]% + \fi + $$%%$$ BRACE MATCH HACK + \fi +} +\def \enddisplaymath { + \relax\ifmmode + \ifinner + \@badmath + \else + $$%%$$ BRACE MATCH HACK + \fi + \else + \@badmath + \fi +% \end{macrocode} +% To gain control we end the paragraph and then invoke the |\end| +% mechanism for dealing with par. This gives in certain situations +% slightly different results compared working only with |$$|'s but +% that's life. +% \begin{macrocode} + \par + \@endpetrue % kill parindent if current paragraph continues + \@ignoretrue +} +\def\[{\begin{displaymath}} +\def\]{\end{displaymath}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% +% +% \begin{macro}{\endequation} +% Same change for the end of an equation. +% \begin{macrocode} +\def\endequation{\eqno \hbox{\@eqnnum}$$\par\@ignoretrue + \@endpetrue % kill parindent if current paragraph continues +} +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\endeqnarray} +% And again the same for the equation array structure. +% \begin{macrocode} +\def\endeqnarray{% + \@@eqncr + \egroup + \global\advance\c@equation\m@ne + $$\par\@ignoretrue + \@endpetrue % kill parindent if current paragraph continues +} +% \end{macrocode} +% \end{macro} +% +% \endinput +\endinput +% +% $Log: xo-grid.dtx,v $ +% Revision 1.3 2000/08/11 07:14:20 latex3 +% added header +% +% Revision 1.2 2000/08/06 19:01:12 latex3 +% fix \prevdepth situation before \@startsection +% +% Revision 1.1 2000/07/30 18:07:22 latex3 +% Initial revision +% +% +% +% +% +% +% +% \begin{macro}{} +% \begin{macrocode} +% \end{macrocode} +% \end{macro} diff --git a/Master/texmf-dist/source/latex3/xor/xo-here.dtx b/Master/texmf-dist/source/latex3/xor/xo-here.dtx new file mode 100644 index 00000000000..189aa2259ae --- /dev/null +++ b/Master/texmf-dist/source/latex3/xor/xo-here.dtx @@ -0,0 +1,454 @@ +% \iffalse +%% +%% (C) Copyright 1999-2000 Frank Mittelbach, David Carlisle, Chris Rowley +%% All rights reserved. +%% +%% Not for general distribution. In its present form it is not allowed +%% to put this package onto CD or an archive without consulting the +%% the authors. +%% +% \fi +% +% \begin{macrocode} +\def\@tempa#1: #2.dtx,v #3 #4 #5 #6 #7${ + \ProvidesPackage{#2}[#4 #3 #5 #6]} +\@tempa$Id: xo-here.dtx,v 1.12 2000/08/11 07:14:21 latex3 Exp $ +% \end{macrocode} +% +% Ignore white space in this package. +% \begin{macrocode} +\IgnoreWhiteSpace +% \end{macrocode} +% +% +% Most of the code in this file is temporary in the sense that the +% interfaces are not fixed or the intended functionality is not fully +% implemented. It is sort of the proof of concept stuff. +% +% +% +% \begin{macro}{\requirespace} +% The |\requirespace| command is an interface function for other +% parts of a a class file. It issues a here point which ensures +% that there is at least |#1| amount of space still available in +% the current column. If not it results in carrying the here point, +% including the previous line(s), to the next column. This could, +% for example, be used by a heading to ensure that there is a +% certain amount of minimal space following it. +% +% The precise (?) definition of ``previous line(s)'' is as follows: +% the internal algorithm will split the so far collected column material +% trying reach the latest possible break point before the here +% point. It is theoretically possible to construct examples where +% \TeX{} decides to take an earlier split point but it is +% guaranteed the the here point is not losing contact with the +% material directly preceeding it (unless a legal breakpoint was +% added in front of it). +% If the here point was added via |\vadjust| in horizontal mode, +% this means that the line immediately before it will be after the +% split (since there will be no other legal break point inbetween). +% \begin{macrocode} +\def\requirespace #1 { + \ifhmode + \@bsphack + \fi + \@next\@currbox\@freelist{}{} +% \end{macrocode} +% We are only interested in the type really: +% \begin{macrocode} + \global\toks\@currbox{{}{} + {} + {} + {} + {rspace} + {} + } + \here@point\@currbox{#1} + \@ignorefalse + \@esphack +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\marginpar} +% The current implementation of the document command |\marginpar| +% is only a proof of concept draft. It doesn't cover the full +% flexibility of the \LaTeXe{} version yet (and perhaps one wants +% even an extension of that). +% \begin{macrocode} +\def\marginpar #1 { + \ifhmode + \@bsphack + \fi + \@next\@currbox\@freelist{}{} + \@savemarbox\@currbox{#1} +% \end{macrocode} +% We are only interested in the type really: +% \begin{macrocode} + \global\toks\@currbox{{}{} + {} + {} + {} + {mpar} + {} + } +% \end{macrocode} +% How far is a marginpar allowed to move past the bottom of the +% text area? Or say it differently: how much space does a marginpar +% need to reserve on the page? +% +% The code below works differently than the \LaTeXe{} one: it will +% move the marginpar including the line it was issued on to the +% next column if its text will otherwise fall more than a +% baselineskip below the page bottom. +% \begin{macrocode} + \@tempdima\ht\@currbox + \advance\@tempdima\dp\@currbox + \advance\@tempdima -\baselineskip % allow to run long + \ifdim\@tempdima< \z@ \@tempdima\z@ \fi + \here@point\@currbox{\the\@tempdima} + \@ignorefalse + \@esphack +} +% \end{macrocode} +% \end{macro} +% +% +% +% +% +% +% +% +% \begin{macro}{\typeset@a@marginpar} +% The |\typeset@a@marginpar| code is called when a marginpar is +% finally added to the current page (either in a trial or in the +% final run). +% +% It should be templated! +% +% Current code is only working for two column setup (!) and lacks +% any modification possibilities depending on the final position +% for the marginpar. +% +% \begin{macrocode} +\def \typeset@a@marginpar{ + \kern-\pagedepth + \vtop to\pagedepth{\baselineskip\pagedepth + \lineskip\z@ + \vss + \dimen@\dp\@currbox + \ifnum \curr@col@count = \@ne +% \end{macrocode} +% Since this perhaps only a trial setting we have to |\copy| and +% not to |\box|!\footnote{FIX: Should clear those boxes somewhere +% else to save space!} +% \begin{macrocode} + \llap{\copy\@currbox\kern\marginparsep} + \else + \ifnum \curr@col@count = \col@count + \rlap{\kern\columnwidth\kern\marginparsep\copy\@currbox} + \else + \ERROR-NOT-SUPPORTED + \fi + \fi + \kern-\dimen@ + \null} +} +% \end{macrocode} +% \end{macro} +% +% +% +% +% +% \begin{macro}{\check@and@typeset@a@here@float} +% +% When we reach |\check@and@typeset@a@here@float| we are trying to +% place a float from the active list into some area and have +% encountered a here point while grabbing the column text for this +% trial placement. In |\check@and@typeset@a@here@float| we check if +% the type of the here point is the same as the current float and +% if so whether or not it would conflict with that trial +% placement. This is the case if +% \begin{itemize} +% \item +% the here float and the float under trial have the same type +% \item +% and their ordering gets out of sync. +% \end{itemize} +% \begin{macrocode} +\def\check@and@typeset@a@here@float{ +%<*trace> + \@tracepush{check@and@typeset@a@here@float} +%</trace> +% \end{macrocode} +% If we don't run with floats then no check are necessary (in fact, +% the checks would produce incorrect results), so we skip them and +% immediately typeset the here float. +% \begin{macrocode} + \ifrun@with@floats +% \end{macrocode} +% If the current float under trial has the same sequence class as the here +% object we have to look at the spatial relationship in more detail. +% \begin{macrocode} + \ifx\here@class\this@class +%<*trace> + \tr@ce{here:~ here@class~ =~ this@class~ =~ \this@class} +%</trace> +% \end{macrocode} +% If the float under trial has a larger sequence number than the +% here float we have to ensure that the area we place it in follows +% the here point, i.e., is either a later column or if it is in the +% same column comes at the bottom. +% \begin{macrocode} + \ifnum \this@sequence@number > \here@sequence@number \relax +%<*trace> + \tr@ce{here:~ target~ area~ should~ be~ after~ here~ point!} +%</trace> +% \end{macrocode} +% Like in the case of checking call-out relations we use the column +% number returned in |\count@| by |calculate@target@fl@column| +% rather than always using the start column of the area. +% \begin{macrocode} + \calculate@target@fl@column + \ifnum \count@ > \curr@col@count +%<*trace> + \tr@ce{OK:~ target~ area column~ later} +%</trace> + \else + \ifnum \count@ = \curr@col@count +%<*trace> + \tr@ce{??:~ target~ area~ target~ column~ identical} +%</trace> +% \end{macrocode} +% So in case we are in the same column at the top we fail the trial. +% \begin{macrocode} + \if t \this@area@type +%<*trace> + \tr@ce{Fail:~ target~ area~ is~ before~ here~ point} +%</trace> + \@failtrue +%<*trace> + \else + \tr@ce{OK:~ target~ area~ is~ after~ here~ point} +%</trace> + \fi + \else +% \end{macrocode} +% And we fail the trial if we tried to place the float into an +% earlier column. +% \begin{macrocode} +%<*trace> + \tr@ce{Fail:~ target~ area~ column~ earlier~ + (\the\count@ < \the\curr@col@count)} +%</trace> + \@failtrue + \fi + \fi +% \end{macrocode} +% If the float sequence number of the current float is smaller than +% the one of the here float then we should always handle it via +% flushing the float out. So the |\else| case is really only there +% for debugging +% \begin{macrocode} +%<*debug> + \else + \tr@ce{here:~ target~ area~ should~ be~ before~ here~ point!} + \ifnum \this@area@col@number > \curr@col@count + \tr@ce{Problem:~ target~ area~ column~ after~ here~ point + (\this@area@col@number > \the\curr@col@count)} + \else + \ifnum \this@area@col@number = \curr@col@count + \tr@ce{??:~ target~ area~ target~ column~ identical} + \if t \this@area@type + \tr@ce{OK:~ target~ area~ is~ before~ here~ point} + \else + \tr@ce{Problem:~ target~ area~ is~ after~ here~ point} + \fi + \else + \tr@ce{OK:~ target~ area~ is~ before~ here~ point} + \fi + \fi +%</debug> + \fi + \fi + \fi + \if@fail +% \end{macrocode} +% If the test above failed we report progress claiming that the +% reason is due to the current float being placed before the here +% float. As mentioned above this should be the only possibility why +% things fail. +% \begin{macrocode} +%<*progress> + \progress@failed{\this@area\space before~here~float~ + (\here@type\space \here@sequence@number)~ + in~ column~ \the\curr@col@count} +%</progress> + \global\curr@col@count\col@count +%<*trace> + \tr@ce{Failed:~ here~ float~ out~ of~ sync} +%</trace> + \else + \typeset@a@here@float + \fi +%<*trace> + \@tracepop{check@and@typeset@a@here@float} +%</trace> +} +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\typeset@a@here@float} +% The |\typeset@a@here@float| is called when a here float is +% finally added to the current page (either in a trial or in the +% final run). +% +% The caption is attached by the usual method where the here +% area is denoted by |h|\meta{col}|1|. This allows to have +% different caption placements depending, for example, on the +% column being near the one of outer margins. +% +% The float is separated from preceeding and following text by the +% current value of |\pagesetup@float@inline@sep| as defined in the +% page setup template plus or minus a certain amount to allow +% grid-based typesetting if desired. +% \begin{macrocode} +\def \typeset@a@here@float{ +% \end{macrocode} +% Attach the caption to the float body and store the result in +% |\this@captioned@float|. +% \begin{macrocode} + \append@here@caption@to@float +% \end{macrocode} +% If we are not doing grid typesetting we simply put +% |\pagesetup@float@inline@sep| before and after the formatted +% float. +% \begin{macrocode} + \ifdim \pagesetup@grid@point@sep = \z@ + \@tempskipa\pagesetup@float@inline@sep + \else +% \end{macrocode} +% Otherwise we have to work a little harder since now we need to +% put exactly the right amount of space before and after the float +% to stay within the grid. So we measure the size of the formatted +% float and store the value in |\@tempdima|. +% \begin{macrocode} + \@tempdima\ht\this@captioned@float + \advance\@tempdima\dp\this@captioned@float +% \end{macrocode} +% To this we add twice |\pagesetup@float@inline@sep| which gives us +% the target size for whole object including surrounding space. +% \begin{macrocode} + \advance\@tempdima\tw@\pagesetup@float@inline@sep +% \end{macrocode} +% Calculate the difference to the nearest grid point\ldots +% \begin{macrocode} + \snap@to@grid \@tempdima \pagesetup@grid@point@sep +% \end{macrocode} +% \ldots and decide which grid point is closest. If the smaller one +% is closer use it if we are allowed to shrink the white space by +% the necessary amount. +% \begin{macrocode} + \ifdim \returned@lower@delta@size < \returned@delta@size \relax + \ifdim \returned@lower@delta@size < 2\pagesetup@float@inline@shrink +% \end{macrocode} +% Note that for the lower delta size we have to use the +% negation since we want to backup by this amount and delta sizes +% are always given in absolute values. +% \begin{macrocode} + \xdef \returned@delta@size {-\returned@lower@delta@size } + \fi + \fi +% \end{macrocode} +% Now set up the amount of white space we need around the float by +% starting with the |\returned@delta@size| divided by two (i.e., +% equal amount contributed to both sides of the float and then add +% |\pagesetup@float@inline@sep|. Notice, that we used a skip +% register for the calculation so that any minus or plus parts will +% survive. This is useful in case we are not doing grid typesetting +% and want to allow for some flexibility.\footnote{This needs perhaps +% rethinking it the light of extended grid implementation concept!} +% \begin{macrocode} + \@tempskipa \returned@delta@size \relax + \divide \@tempskipa \tw@ + \advance \@tempskipa \pagesetup@float@inline@sep +%<*trace> + \tr@ce{GRID:~ here~float:~ use~ \the\@tempskipa \space above~ and~ below} +%</trace> + \fi +% \end{macrocode} +% Finally typeset the float and its surrounding space which is by +% now stored in |\@tempskipa|.\footnote{Perhaps make the space +% above and below specifiable individually. One day, perhaps!} +% \begin{macrocode} + \vskip\@tempskipa + \box\this@captioned@float + \vskip\@tempskipa +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\setup@here@float} +% Absolutely temp!!!!!\footnote{FIX!!!!} +% \begin{macrocode} +\def \setup@here@float { + \@tempskipa 2\pagesetup@float@inline@sep %FMi arbitrary value TMP + \advance\@tempskipa\ht\@currbox %FMi arbitrary value TMP + \advance\@tempskipa\dp\@currbox %FMi arbitrary value TMP + \advance\@tempskipa5\baselineskip %FMi arbitrary value TMP + \here@point\@currbox{\the\@tempskipa} +} +% \end{macrocode} +% \end{macro} +% +% +% +% +% \endinput +\endinput +% +% $Log: xo-here.dtx,v $ +% Revision 1.12 2000/08/11 07:14:21 latex3 +% added header +% +% Revision 1.11 2000/08/04 10:19:09 latex3 +% added init of here floats (temp version) +% +% Revision 1.10 2000/07/19 16:05:41 latex3 +% introduced float sequence class concept +% +% Revision 1.9 2000/07/10 19:13:34 latex3 +% template here floats and support grid typesetting for them. +% +% Revision 1.8 2000/06/29 17:18:44 latex3 +% introduced \setup@this@area +% +% Revision 1.7 2000/06/18 14:58:32 latex3 +% use \calculate@target@fl@column to determine the target column ti +% check if here float and current float are in sync +% +% Revision 1.6 2000/06/15 15:23:05 latex3 +% untabify +% +% Revision 1.5 2000/06/13 20:45:47 latex3 +% docu updates +% +% Revision 1.4 2000/05/03 18:58:56 latex3 +% provide caption template support +% +% Revision 1.3 2000/04/27 19:51:45 latex3 +% bug fix: need to copy boxes in trials :-) +% moved \check@and@typeset@a@here@float to this file +% +% Revision 1.2 2000/04/21 19:01:13 latex3 +% added documentation +% +% Revision 1.1 2000/04/21 10:19:07 latex3 +% Initial revision +% diff --git a/Master/texmf-dist/source/latex3/xor/xo-new.dtx b/Master/texmf-dist/source/latex3/xor/xo-new.dtx new file mode 100644 index 00000000000..acbeda1bf83 --- /dev/null +++ b/Master/texmf-dist/source/latex3/xor/xo-new.dtx @@ -0,0 +1,701 @@ +% \iffalse +%% +%% (C) Copyright 1999-2000 Frank Mittelbach, David Carlisle, Chris Rowley +%% All rights reserved. +%% +%% Not for general distribution. In its present form it is not allowed +%% to put this package onto CD or an archive without consulting the +%% the authors. +%% +% \fi +% +% \begin{macrocode} +\def\@tempa#1: #2.dtx,v #3 #4 #5 #6 #7${ + \ProvidesPackage{#2}[#4 #3 #5 #6]} +\@tempa$Id: xo-new.dtx,v 1.25 2000/08/11 07:14:23 latex3 Exp $ +% \end{macrocode} +% +% This package is available for test overwrites that need integration +% into the main packages at some point +% +% Ignore white space in this package. +% \begin{macrocode} +\IgnoreWhiteSpace +% \end{macrocode} +% + +% +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% +% STUFF THAT CHANGES CHRIS' xo-final +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% +% +% +% \begin{macrocode} + +\flushbottom + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%changes to xo-final +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\iftrue % using Frank's changes built on 1.15 + +%<*obsolete> +\def\typeset@this@float@and@caption{ + \append@caption@to@float + \box\this@captioned@float +} +%</obsolete> + + + +\def\final@column { +%<*trace> + \@tracepush{produce@final@column} +%</trace> + \setbox\@outputbox \box\@cclv + + \ifvoid\footins + \else + \setbox\@outputbox \vbox { + \boxmaxdepth \@maxdepth +% \end{macrocode} +% \TeX\ calculates page breaks expecting the depth of the main text +% to extend below the page baseline, not contributing to the page height, +% and it assumes the entire height plus depth of footnotes will contribute +% to the page height. When the page is assembled, the footnote depth +% is below the baseline and the main text depth appears mid-page. To +% make the contents fit the page precisely, we (locally) adjust the +% footnote spacing \cs{skip}\cs{footins} by the \emph{difference} in +% the two depths.\footnote{This part of the code was suggested by +% Donald Arseneau in bug report pr3189.} +% \begin{macrocode} + \advance\skip\footins -\dp\@outputbox % already limited to \@maxdepth + \unvbox \@outputbox + \advance\skip\footins + \ifdim\dp\footins>\@maxdepth \@maxdepth \else \dp\footins \fi + \vskip \skip\footins +% \end{macrocode} +% If we are doing grid typesetting we put all excess space between +% the text and the footnote(s). +% \begin{macrocode} + \ifdim \pagesetup@grid@point@sep > \z@ + \vfil + \fi + \color@begingroup + \normalcolor + \footnoterule + \unvbox \footins + \color@endgroup + } + \fi +% \end{macrocode} +% +% I am not sure if texttop/bottom should survive for long: something +% more spohisictaed is needed these days. This may mean that +% footnotes need better handling too: what makes a complex column +% look good? +% +% \begin{macrocode} + \global\setbox\csname col@box@\the\curr@col@count\endcsname + \vbox to \csname col@ht@ \the\curr@col@count\endcsname %<----- + { % this should one day become \@colht + % or else + \@texttop + \dimen@ \dp\@outputbox + \unvbox \@outputbox + \vskip -\dimen@ + \@textbottom + }% + \global \maxdepth \@maxdepth +%<*trace> + \@tracepop{produce@final@column} +%</trace> +} +\let \produce@final@column \final@column + + + +\def\make@area@floats@box #1#2 { +%<*trace> + \@tracepush{make@area@floats@box} + \tr@ce{Area:~ #1} +%</trace> + \@ifundefined{area@#1} % test only needed because of missing integration + { +%<*trace> + \tr@ce{Area:~ not~ set~ up} +%</trace> + } + { + \setup@this@area{#1} % needed below when typesetting floats + + \setbox #2 \box\voidb@x % <-------- FMi +% \let \@elt \@comflelt % Big aaah! + \def \@elt { \typeset@float@in@box {#2} } + \csname area@#1\endcsname +% \end{macrocode} +% Not very pretty yet! But better when decoration +% stuff is used. +% \begin{macrocode} + \let \@elt \relax + + \expandafter + \release@floats + \csname area@#1\endcsname + } +%<*trace> + \@tracepop{make@area@floats@box} +%</trace> +} + + +\def\typeset@float@in@box #1 #2 { +%<*trace> + \@tracepush{typeset@float@in@box} +%</trace> + \gdef\this@float@box {#2} % <------------- FMi + \expandafter + \extract@this@float@actual@structure \the\toks #2 + + \update@this@area@columns + { + \expandafter + \gdecrement@num + \csname col@ \this@area@type + @floats@ \the\count@ @number\endcsname +%<*trace> + \tr@ce{col@ \this@area@type + @floats@ \the\count@ @number~ <-~ + \csname col@ \this@area@type + @floats@ \the\count@ @number\endcsname} +%</trace> + } + + \setbox #1 \vbox { + \ifvoid #1 +%<*trace> +\tr@ce{add~to~#1:~float~ #2} +%</trace> + \else % experimental FMi +%<*trace> +\tr@ce{add~to~#1:~float~ #2~ plus~ \pagesetup@float@float@sep} +%</trace> + \unvbox #1 % experimental FMi + \vskip \pagesetup@float@float@sep % experimental FMi + \fi % experimental FMi + \typeset@this@float@and@caption + } +%<*trace> + \@tracepop{typeset@float@in@box} +%</trace> + } + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% my new xo-final stuff +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + +\def \myfinalpage { + \mbox@addtopage (\pagebodylefthpos, -\headsep) + {page:~\thepage} +% \end{macrocode} +% +% \begin{macrocode} +% Init |\dimen|1,2,3,\ldots as vertical current point per column +% (don't forget in Chris's (sorry, Don's) universum zero is at the +% top). +% \end{macrocode} +% +% \begin{macrocode} + \forall@columns{ + \dimen \the\curr@col@count + \z@ + } +% \end{macrocode} +% Now mount all top areas looping through an ordered list of top +% areas. +% \begin{macrocode} + \expandafter\mount@top@areas@loop + \top@areas + \relax\relax\relax +% \end{macrocode} +% Next mount the text columns. +% \begin{macrocode} + \forall@columns{ + +%<*trace> + \tr@ce{GRID (delta):~ column~\the\curr@col@count t:~ + \csname col@t@delta@ \the\curr@col@count + \endcsname\space used} +%</trace> + \advance \dimen \the\curr@col@count + by %NEEDED!!!!! + \csname col@t@delta@ \the\curr@col@count \endcsname + + \advance \dimen \the\curr@col@count + \csname col@ht@ \the\curr@col@count \endcsname + + \setlength \@tempdima + {\pagebodylefthpos - \columndisplacement + + \columndisplacement * \curr@col@count } + + \mbox@addtopage ( \the\@tempdima ,\the\dimen\curr@col@count ) + { \box \csname col@box@ \the\curr@col@count \endcsname } + +%<*trace> + \tr@ce{GRID (delta):~ column~\the\curr@col@count b:~ + \csname col@b@delta@ \the\curr@col@count + \endcsname\space used} +%</trace> + \advance \dimen \the\curr@col@count + by %NEEDED!!!!! + \csname col@b@delta@ \the\curr@col@count \endcsname + } +% \end{macrocode} +% Then mount the bottom floats. +% \begin{macrocode} + \def\col@of@focus{0} % temp solution see below + \expandafter\mount@bot@areas@loop + \bot@areas + \relax\relax\relax +% \end{macrocode} +% +% Next thing is absolutely temp: mount a marginal area on the right +% (bottom) to allow footnotes there (this is just for testing). +% \begin{macrocode} + \setlength \@tempdima + {\pagebodylefthpos + \columndisplacement * \col@count } + \mbox@addtopage ( \the\@tempdima , \textheight ) + { \box \saved@footins } % TEMP FMi +% +% Next thing is absolutely temp: mount a marginal area on the right +% (bottom) to allow marginal floats there (this is just for testing). +% \begin{macrocode} + \expandafter + \ifx\csname area@m1\the\curr@col@count\endcsname\relax + \else + \curr@col@count\col@count + \advance\curr@col@count\@ne + \make@area@floats@box {m\the\curr@col@count1}\@tempboxa + \setlength \@tempdima + {\pagebodylefthpos + \columndisplacement * \col@count } + \mbox@addtopage ( \the\@tempdima , \textheight ) + { \vbox to\textheight{\vfil \unvbox \@tempboxa \vfil }} + \fi +% + \ifShowGrid + \ifdim \pagesetup@grid@point@sep > \z@ + \@tempcnta\textheight + \@tempcntb\topskip + \advance\@tempcnta -\@tempcntb + \@tempdimb\pagesetup@grid@point@sep + \@tempcntb\@tempdimb + \divide\@tempcnta\@tempcntb + \advance\@tempcnta\@ne + + \setlength \@tempdimb + {\pagebodylefthpos + \columndisplacement * \col@count + - \columnsep } + \count@\@tempdimb + + \sbox\grid@box{ + \setlength\unitlength{1sp} + \begin{picture}(0,0) + \multiput(0,0)(0,\@tempcntb){\@tempcnta} + {\line(1,0){\count@}} + \end{picture} + } + + \mbox@addtopage ( 0pt ,\textheight ) + { \box\grid@box } + + \fi + \fi +} + +\newbox\grid@box + +\newif\ifShowGrid +\ShowGridtrue + +% for tracing only (unchanged) + + +\def\mbox@addtopage (#1,#2)#3{% +% \tr@ce{box~being~added~to~page:~at~(#1,~#2) } + \global \setbox\page@box + \hbox { + \unhbox \page@box + \mbox@put (#1,#2) {#3} + } +} + + + + +\def\mount@top@areas@loop#1#2#3{ + \ifx#1\relax + \else + \mount@top@area#1#2#3 + \expandafter\mount@top@areas@loop + \fi} + + +\def\mount@top@area#1#2#3 { + \make@area@floats@box {#1#2#3}\@tempboxa + + \ifvoid \@tempboxa + \else + + \setlength \@tempdimb + { \dimen#2 + \ht\@tempboxa + \dp\@tempboxa } + + \setlength \@tempdima + {\pagebodylefthpos - \columndisplacement + \columndisplacement * #2 } + + \mbox@addtopage ( \the\@tempdima ,\the\@tempdimb ) + { \box \@tempboxa } + + \count@ #2\relax + \advance\count@ #3\relax + \loop + \advance\count@\m@ne + \dimen \count@ = \@tempdimb + \advance\dimen \count@ + \ifnum \csname col@t@floats@ \the\count@ @number\endcsname > \z@ + \pagesetup@float@area@sep + \else + \pagesetup@float@text@sep + \fi + \ifnum #2 < \count@ + \repeat + + \fi +} + +\def\mount@bot@areas@loop#1#2#3{ + \ifx#1\relax + \else + \mount@bot@area#1#2#3 + \expandafter\mount@bot@areas@loop + \fi} + +\def\mount@bot@area#1#2#3 { + \make@area@floats@box {#1#2#3}\@tempboxa + + \ifvoid \@tempboxa + \else + + \setlength \@tempdimb + { \dimen#2 + \ht\@tempboxa + \dp\@tempboxa } + +% \end{macrocode} +% There are probably much better ways to get the spacing right, the +% one below is really only a temporary fix: in |\col@of@focus| we +% remember the last column in which already applied +% |\pagesetup@float@text@sep|, any additional float area will +% contribute another |\pagesetup@float@area@sep| +% instead.\footnote{To make this work it is absolutely necessary +% that the floats in bot@areas are ordered by column!!! No-good. FIX!!} +% \begin{macrocode} + \ifnum \col@of@focus < #2 \relax + \def\col@of@focus{#2} + \advance\@tempdimb + \pagesetup@float@text@sep + \else + \advance\@tempdimb + \pagesetup@float@area@sep + \fi + + \setlength \@tempdima + {\pagebodylefthpos - \columndisplacement + \columndisplacement * #2 } + + \mbox@addtopage ( \the\@tempdima ,\the\@tempdimb ) + { \box \@tempboxa } + +% \end{macrocode} +% Next loop is actually not necessary as long we keep the +% restriction that we don't allow partial overlapping float areas, ie we +% will never mount another float area in the columns that are +% spanned by the current float area (other than potentially the +% first and we set this one explicitly). +% \begin{macrocode} + \dimen #2 = \@tempdimb +% \count@ #2\relax +% \advance\count@ #3\relax +% \loop +% \advance\count@\m@ne +% \dimen \count@ = \@tempdimb +% \ifnum #2 < \count@ +% \repeat + + \fi +} + + +% of course \top@areas and \bot@areas should be constructed +% automatically when preparing the \use@areas or from the \known@areas +% but for now i simply define them here: + +\def\top@areas{t13 t12 t22 t32 t11 t21 t31} + +\def\bot@areas{b11 b12 b13 b21 b22 b31 b32} + + +%%%%%%%%%%%%%%%%%%%%%%%%%%% +% next line activates my version (well some of it is activated already +% above) +%%%%%%%%%%%%%%%%%%%%%%%%%%% +\let\make@page@box\myfinalpage + +\fi % end of stuff modifying xo-final 1.15 + +% \end{macrocode} +% + +\endinput + + + +% \begin{macro}{\savecolumnsizes} +% Declaration to turn on writing of CSL (column size list) files. +% \begin{macrocode} +\def\savecolumnsizes{ + \newwrite\csl@file + \immediate\openout\csl@file\jobname.csl + \def\perhaps@write@to@csl@file{ + \immediate\write\csl@file + } + \def\perhaps@write@placements@to@csl@file{ + \def\@elt{\expandafter + \perhaps@write@placements@to@csl@file@aux\the\toks} + \perhaps@write@to@csl@file{ + ^^JPage:~\the\absolute@page@number\space (\the\c@page)^^J +% \end{macrocode} +% +% \begin{macrocode} + \expandafter\@write@areas\used@areas\relax\relax\relax + } + \let\@elt\relax}} +% \end{macrocode} +% \end{macro} +% + + + + + + +\endinput + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% an attempt to use column 0 and n+1 as marginal areas +% not active +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% \begin{macro}{\forall@columns@and@margins} +% \begin{macrocode} +\def\forall@columns@and@margins#1{ + \edef\saved@curr@col@count{\the\curr@col@count} + \global\curr@col@count\col@count + \global\advance\curr@col@count\@ne + \@whilenum \curr@col@count>\m@ne \do + { + #1 + \global\advance\curr@col@count\m@ne + } + \global\curr@col@count\saved@curr@col@count\relax +} +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macrocode} +% original macro no longer used +\def\initialise@best@trial{ +%<*trace> + \@tracepush{initialise@best@trial} +%</trace> +% \end{macrocode} +% +% \begin{macrocode} + \global\let\best@trial\@empty + \forall@columns@and@margins{ + \expandafter + \g@addto@macro\expandafter\best@trial\expandafter + { + \expandafter + \global + \csname col@ht@ \the\curr@col@count\endcsname + \textheight + } + } +%<*trace> + \tr@ce{\meaning\best@trial} + \@tracepop{initialise@best@trial} +%</trace> +} +% \end{macrocode} +% + +% \begin{macrocode} +\expandafter\newdimen\csname col@ht@ 0\endcsname +% \end{macrocode} +% + + +% \begin{macro}{\initialise@next@page} +% Initialises the column heights to text height. Clear the float +% area lists, zero holdinginserts to allow footnote texts to arrive +% in the insertion box. +% \begin{macrocode} +\def\initialise@next@page{ +%<*trace> + \@tracepush{initialise@next@page} +%</trace> +% + \forall@columns@and@margins + {\global\csname col@ht@ \the\curr@col@count\endcsname\textheight} +% + \initialise@areas +% + \global\page@float@count\z@ +% + \initialise@best@trial +% \end{macrocode} +% +% \begin{macrocode} + \initialise@flush@data +% \end{macrocode} +% +% \begin{macrocode} + \initialise@here@data +% \end{macrocode} +% +% \begin{macrocode} + \initialise@footins@action +% \end{macrocode} +% +% Nothing is closed when we are at the start of a page. +% \begin{macrocode} + \global\let\this@page@closed\@empty +% \end{macrocode} +% +% \begin{macrocode} + \let\@elt\initialise@float@class + \float@classes@list + \let\@elt\relax +% +%\showfloatlists +%\show\area@ddd\show\@activelist +% for safety + \global\let\this@float@box\@undefined +%<*trace> + \@tracepop{initialise@next@page} +%</trace> + } +% \end{macrocode} +% \end{macro} +% +% +% + +% +% \endinput +\endinput +% +% $Log: xo-new.dtx,v $ +% Revision 1.25 2000/08/11 07:14:23 latex3 +% added header +% +% Revision 1.24 2000/08/11 06:49:09 latex3 +% untabify +% +% Revision 1.23 2000/08/05 10:01:26 latex3 +% ensure that \make@area@floats@box doesn't do any harm to areas not set +% up via \DeclareFloatArea +% +% Revision 1.22 2000/08/04 15:50:31 latex3 +% \flushbottom default again +% +% Revision 1.21 2000/08/04 13:58:58 latex3 +% \bot@areas need to be ordered by column at the moment!!!! +% +% Revision 1.20 2000/08/04 10:20:09 latex3 +% removed old experimental code for grid layout +% +% Revision 1.19 2000/07/22 06:30:50 latex3 +% fixed bug in positioning bottom floats +% +% Revision 1.18 2000/07/19 17:12:53 latex3 +% introduced float sequence list +% +% Revision 1.17 2000/07/10 19:22:12 latex3 +% more grid support +% +% Revision 1.16 2000/07/04 19:48:55 latex3 +% experimental stuff for GRIDs +% start writing out columnsizes (unused) +% use \update@this@area@columns +% +% Revision 1.15 2000/06/29 17:16:59 latex3 +% introduced \setup@this@area +% +% Revision 1.14 2000/06/26 15:17:26 latex3 +% prototype support for \pagesetup@float@area@sep +% +% Revision 1.13 2000/06/16 11:21:07 latex3 +% rename \construct@and@test@col@height to \construct@and@test@col@ht +% rename \construct@and@test@col@heights to \construct@and@test@col@hts +% rename \cl@height1 to \@col@ht@1 (etc) +% +% Revision 1.12 2000/06/15 15:22:36 latex3 +% implemented new semantics for area names +% +% Revision 1.11 2000/06/13 21:23:03 latex3 +% *** empty log message *** +% +% Revision 1.10 2000/05/04 09:21:27 latex3 +% urg: \this@area undefined inside the output routine, so captions got +% typeset with whatever was the last \this@area. +% +% Revision 1.9 2000/05/03 18:41:52 latex3 +% still overwriting code for xo-final 1.15 ! (not 1.16) +% enabling support for caption templates +% +% Revision 1.8 2000/04/21 19:16:32 latex3 +% activate my version of xo-final +% +% Revision 1.7 2000/04/21 19:05:21 latex3 +% my version of xo-final mainly +% +% Revision 1.6 2000/04/09 20:02:42 latex3 +% first draft of marginpar support +% +% Revision 1.5 2000/03/24 15:34:27 latex3 +% version that starts supporting spans (still a hack yet) +% +% Revision 1.4 2000/02/26 18:26:08 david +% code moved to xo-* +% +% Revision 1.3 2000/02/13 21:37:20 latex3 +% ooops, my ultrix rcs is too old to guess the comment char correctly +% so we better add explicit \endinput +% +% Revision 1.2 2000/02/13 21:35:25 latex3 +% wording +% +% Revision 1.1 2000/02/13 21:34:51 latex3 +% Initial revision +% diff --git a/Master/texmf-dist/source/latex3/xor/xo-or.dtx b/Master/texmf-dist/source/latex3/xor/xo-or.dtx new file mode 100644 index 00000000000..6aef48254b1 --- /dev/null +++ b/Master/texmf-dist/source/latex3/xor/xo-or.dtx @@ -0,0 +1,5188 @@ +% \iffalse +%% +%% (C) Copyright 1999-2000 Frank Mittelbach, David Carlisle, Chris Rowley +%% All rights reserved. +%% +%% Not for general distribution. In its present form it is not allowed +%% to put this package onto CD or an archive without consulting the +%% the authors. +%% +% \fi +% + +% \begin{macrocode} +\def\@tempa#1: #2.dtx,v #3 #4 #5 #6 #7${ + \ProvidesPackage{#2}[#4 #3 #5 #6]} +\@tempa$Id: xo-or.dtx,v 1.53 2000/08/11 07:14:25 latex3 Exp $ +% \end{macrocode} +% +% \subsection{A flowchart of the algorithm} +% +% Several output routines are employed. Output routines (that is, +% macros to be used as the sole content of the primitive |\output| +% register) are named xxx@or. Typically a companion macro named +% setup@xxx is called to initialise the state (typically setting +% vsize) and to assign |\output|. +% +% +% [The flow chart has be cut into pieces and individual pieces are +% shown below.] +% +% ^^A \input{xo-flow-chart.sty} ^^A .sty to ease updating +% +% +% +% Ignore white space in this package. +% \begin{macrocode} +\IgnoreWhiteSpace +% \end{macrocode} +% +% +% +% +% \subsection{General helper Routines} +% +% \begin{macro}{\@gobblethree} +% Get rid of three tokens or brace groups. +% \begin{macrocode} +\long\def\@gobblethree#1#2#3{} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\xin@} +% Like |\in@| but with both args (which have to be single tokens!) +% expanded. Should be replaced by a proper interface. +% \begin{macrocode} +\def\xin@#1#2{% +% expanded once: + \expandafter\def\expandafter\in@@\expandafter##\expandafter1#1##2##3\in@@{% + \ifx\in@##2\in@false\else\in@true\fi}% + \expandafter\expandafter\expandafter\in@@\expandafter#2#1\in@\in@@} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\gincrement@num} +% Globally increment a ``number macro'' by one. +% \begin{macrocode} +\def\gincrement@num#1 { +% \end{macrocode} +% We don't want to modify |\count@| here as it might hold some +% important data so we do everything in a group. +% \begin{macrocode} + \begingroup + \count@#1 + \advance\count@\@ne + \xdef#1{\the\count@} + \endgroup +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\gdecrement@num} +% Globally decrement a ``number macro'' by one. +% \begin{macrocode} +\def\gdecrement@num#1 { + \begingroup + \count@#1 + \advance\count@\m@ne + \xdef#1{\the\count@} + \endgroup +} +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\split@skip} +% \begin{macro}{\check@for@fil} +% \begin{macro}{\get@plus@part} +% \begin{macro}{\get@minus@part} +% |\split@skip| takes four aguments: a template key name (for error +% recovery), a skip specification (e.g., either the value of a skip +% register via |\the|\meta{register}, or a macro holding the +% information, or the specification directly), and two dimen +% registers. The skip specification is taken apart and the first +% dimen register receives ``plus'' part and the second the +% ``minus'' part. If the specification contains any |fil| parts an +% error is generated since these values can't be assigned to a +% dimen register. +% \begin{macrocode} +\begingroup +% \end{macrocode} +% We employ the |\lowercase| trick to get certain letters with +% |\catcode| 12 since we have to scan for them (they are what +% |\the| outputs. So if we say |MINUS| below we get |minus| but all +% |\catcode|d 12. +% \begin{macrocode} +\catcode`\M=12 +\catcode`\I=12 +\catcode`\N=12 +\catcode`\U=12 +\catcode`\S=12 +% \end{macrocode} +% We need |p| with |\catcode| 12 to scan for |pt| but we also need +% |P| with |\catcode| 11 to be able to say |\PackageError|. So we +% claim lowecase of |Z| is |p| and then say |ZT| and |ZLUS| below. +% \begin{macrocode} +\catcode`\Z=12 +\lccode`\Z=`\p +\catcode`\T=12 +% \end{macrocode} +% And we need to scan for |FIL|: +% \begin{macrocode} +\catcode`\L=12 +\catcode`\F=12 +% \end{macrocode} +% And the error message contains uppercase |V| and |O| and we want +% to retain those. +% \begin{macrocode} +\lccode`\V=`\V +\lccode`\O=`\O +% \end{macrocode} +% With the above prelims we now apply |\lowercase| to all the +% definitions below, which will put the correctly |\catcode|d +% strings in the parsing part of the macros. +% \begin{macrocode} +\lowercase{ +\gdef\split@skip #1#2#3#4{ +% \end{macrocode} +% |#2| is the skip specification. To be sure that the strings +% ``plus'', ``minus'', ``pt'' are always having |\catcode| 12 we +% assign it to a register first. Otherwise a user supplied string +% like |1in plus .5in| wouldn't be parsable since we are only +% looking for |pt| and also because in this case the |\catcode|s of +% |plus| would be 11. +% \begin{macrocode} + \@tempskipa#2\relax +% \end{macrocode} +% Then we pass this on to |\check@for@fil| which will make sure +% that there isn't any |fil| present and if not does the rest of +% the processing. +% \begin{macrocode} + \expandafter\check@for@fil \the\@tempskipa FIL\relax\check@for@fil + {\the\@tempskipa}{#3}{#4}{#1} + } +% \end{macrocode} +% +% \begin{macrocode} +\gdef\check@for@fil #1FIL#2\check@for@fil#3#4#5#6{ + \ifx\relax#2 + \expandafter + \get@minus@part #3MINUS 0ZT \get@minus@part{#4}{#5} + \else + #4\z@ + #5\z@ + \PackageError{template}{Value~ for~ key~ #6~ contains~ `fil(ll)'} + {Only~ finite~ minus~ or~ plus~ parts~ are~ allowed~ for~ this~ key.} + \fi + } +% \end{macrocode} +% +% \begin{macrocode} +\gdef\get@plus@part #1ZLUS#2ZT#3\get@plus@part#4{ + #4=#2pt\relax + } +% \end{macrocode} +% +% \begin{macrocode} +\gdef\get@minus@part #1MINUS#2ZT#3\get@minus@part#4#5{ + \get@plus@part #1ZLUS 0ZT\get@plus@part{#4} + #5=#2pt\relax + } +} +\endgroup +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% +% +% +% +% +% +% \subsection{Special Output Routine Penalties} +% +% +% \begin{macro}{\output@collect@penalty} +% Special penalty marking the point at which the collection OR ended. +% \begin{macrocode} +\mathchardef\output@collect@penalty=20202 +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\output@balance@penalty} +% Special penalty marking the point at which the collection OR +% should end collection because we want to balance the material. +% \begin{macrocode} +\mathchardef\output@balance@penalty=10010 +% \end{macrocode} +% \end{macro} +% +% +% Other special penalties are inbetween -10000 and -10010. Those will +% not stop the collection OR but are instead recorded along the way. +% +% \begin{macro}{\output@columnbreak@penalty} +% Special penalty marking the point a forced column break was +% requested by the user. +% \begin{macrocode} +\mathchardef\output@columnbreak@penalty=10005 +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\output@flush@float@penalty} +% Special penalty to trigger float flushing for one or more types. +% \begin{macrocode} +\mathchardef\output@flush@float@penalty=10006 +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\output@here@float@penalty} +% Special penalty for floats that should stay with their callout. +% \begin{macrocode} +\mathchardef\output@here@float@penalty=10007 +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\output@grid@align@penalty} +% Special penalty for places that should fall on the page grid. +% \begin{macrocode} +\mathchardef\output@grid@align@penalty=10008 +% \end{macrocode} +% \end{macro} +% +% +% +% +% +% +% \subsubsection{Utilities for Special Output Routine Penalties} +% +% +% \begin{macro}{\add@badly@guarded@penalty} +% Put a special penalty into the output and guard it with a +% box. The reason this macro is called |\add@badly@guarded@penalty| +% is that such a box of size zero is still messing up spacing +% caluclations. Why? Because when the penalty is reached on the MVL +% the preceeding line has already be fully added (i.e., including +% its depth). This means that \TeX{} might not reach it at all in +% time! For example, if the preceeding line would be the last line +% of the page the depth would not be taken into account yet, but by +% the time we reach the special penalty it has been added to +% |\pagetotal| and that may result in not fitting anymore onto the +% page. +% +% A solution would be to use a box that has the same depth as its +% preceeding box and a negative height so that it effectively +% doesn't modify the galley length. Easy, right? The only problem +% is that in case of |\vadjust| (and that is unfortunately the more +% important case) we just don't know what the preceeding depth is, +% since |\prevdepth| will always give us a friendly |-1000pt| in +% that case (start of a vertical sub-list\ldots). +% +% So not so easy after all. The way out of this dilemma turned out +% to be complicated and involves a lot of strange corrective +% actions in the collection process, see there for a replacement of +% that box and what else can go wrong if one delves into messing +% around with that part of \TeX. +% \begin{macrocode} +\def\add@badly@guarded@penalty#1 { + \ifvmode + \nointerlineskip + \vbox to\z@{\vss\the#1}\penalty-#1\relax + \else + \@bsphack + \vadjust{\vbox to\z@{\vss\the#1}\penalty-#1\relax} + \@esphack + \fi +} +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\add@guarded@penalty} +% Put a special penalty into the output. To ensure that it doesn't +% get mistakenly removed during breaking preceed it with a ``guard +% box'' which is later removed again. --- Actually no longer used +% but replacement isn't yet finalised.\footnote{CLEANUP!} +% \begin{macrocode} +\def\add@guarded@penalty#1 + {\guard@box{BUG:~\string#1}\penalty-#1\relax} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\guard@box} +% Could be moved into the previous macro. +% +% The way it is written (using |\prevdepth|) this can only be used +% in vertical mode! We have to carry over the |\prevdepth| and +% append the box without adding any additional interline +% space. Without it one gets nasty extra glue blobs of height +% |\baselineskip| somewhere in the output. +% \begin{macrocode} +\def\guard@box#1{ + \dimen@\prevdepth + \nointerlineskip + \vbox to0pt{\vss \rlap{#1}\kern\z@} + \prevdepth\dimen@ +} +% \end{macrocode} +% Better implementation? The above is wrong!\footnote{FIX!} +% \begin{macrocode} +\def\guard@box#1{ + \dimen@\prevdepth + \nointerlineskip + \begingroup + \setbox\z@\vbox to\z@{\vss \rlap{#1}} + \dp\z@\dimen@ + \box\z@ + \endgroup +} +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\remove@guard@box@from@cclv} +% Remove a guard box again. This always happens in the OR and so we +% hard code the box number for speed. +% +% Chris thinks this needs a maxdepth setting. +% \begin{macrocode} +\def\remove@guard@box@from@cclv{ + \global\setbox\@cclv \vbox{\boxmaxdepth\@maxdepth \unvbox\@cclv + \global\setbox\removed@guard@box\lastbox} +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\readd@guarded@penalty} +% Readding a guared penalty including the box that was removed +% earlier. Probably not needed in the end either since the way it +% is used at the moment we have a |\topskip| problem this +% way.\footnote{FIX!!!!} +% \begin{macrocode} +\def\readd@guarded@penalty#1 { + \box\removed@guard@box +%FMi what about topskip? + \penalty-#1\relax} +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\removed@guard@box} +% \begin{macrocode} +\newbox\removed@guard@box +% \end{macrocode} +% \end{macro} +% +% +% +% +% +% \subsection{Columns and their Data Structures} +% +% \begin{macro}{\col@count} +% We are collecting stuff for a given number of columns. This +% number of column is available in a count register. +% \begin{macrocode} +\let\col@count \col@number % reuse a register from LaTeX + % which is named differently there +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\curr@col@count} +% Register denoting the column number of the current column while +% we cut the galley etc. Should always be modified globally since +% it is used within output routines. +% \begin{macrocode} +\newcount\curr@col@count +% \end{macrocode} +% \end{macro} +% +% +% +% \DescribeMacro\col@box@FOO +% Per column number FOO we have one box register allocated in which +% the column text from the galley is stored during trials and page +% makeup. +% +% \DescribeMacro\col@ht@FOO +% Per column number FOO we have dimen register allocated which +% holds the vertical target size for the column during the trials. +% +% \DescribeMacro\col@t@floats@FOO@number +% Per column number FOO we have a macro number in which we count +% the number of top floats we have seen so far in this column. This +% is used to implement |\pagesetup@float@area@sep| handling. +% +% \DescribeMacro\col@b@floats@FOO@number +% Per column number FOO we have a macro number in which we count +% the number of bottom floats we have seen so far in this column. This +% is used to implement |\pagesetup@float@area@sep| handling. +% +% +% \DescribeMacro\col@t@delta@FOO +% Per column number foo we have a macro in which we record the +% difference between the real size of all top floats (including +% there separation spaces) and the nominal size which is used to +% determine the vertical size of the remaining text column. The two +% may differ if we do grid typesetting. +% +% \DescribeMacro\col@b@delta@FOO +% Same kind of delta is recorded per column for the bottom floats. +% +% \DescribeMacro\fl@FOO@BAR +% For each float type BAR (e.g., |figure|, |table|, etc.) and each +% column number FOO we have a macro which holds the highest float +% sequence number for floats of type BAR allocated to column FOO or +% zero if no float has been allocated so far. +% +% \DescribeMacro{\fl@0@BAR} +% For each float type BAR (e.g., |figure|, |table|, etc.) +% |\fl@0@BAR| holds the highest sequence number in columns of the +% previous page. +% +% \DescribeMacro\tfl@FOO@BAR +% |\tfl@FOO@BAR| is like |\fl@FOO@BAR| but only stores information +% about floats allocated to top areas. +% +% + +% \begin{macro}{\col@box@1} +% \begin{macro}{\col@box@2} +% \begin{macro}{\col@box@3} +% \begin{macro}{\col@box@4} +% \begin{macro}{\col@box@5} +% \begin{macro}{\col@box@6} +% Need a box per column (currently fixed at six) to hold material +% from the galley for this column. +% \begin{macrocode} +\expandafter\newbox\csname col@box@1\endcsname +\expandafter\newbox\csname col@box@2\endcsname +\expandafter\newbox\csname col@box@3\endcsname +\expandafter\newbox\csname col@box@4\endcsname +\expandafter\newbox\csname col@box@5\endcsname +\expandafter\newbox\csname col@box@6\endcsname +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\col@ht@ 1} +% \begin{macro}{\col@ht@ 2} +% \begin{macro}{\col@ht@ 3} +% \begin{macro}{\col@ht@ 4} +% \begin{macro}{\col@ht@ 5} +% \begin{macro}{\col@ht@ 6} +% Need a dimen\footnote{Could be a macro if we find ourselves to +% use up too many dimens.} per column to hold its current vertical +% target size. +% \begin{macrocode} +\expandafter\newdimen\csname col@ht@ 1\endcsname +\expandafter\newdimen\csname col@ht@ 2\endcsname +\expandafter\newdimen\csname col@ht@ 3\endcsname +\expandafter\newdimen\csname col@ht@ 4\endcsname +\expandafter\newdimen\csname col@ht@ 5\endcsname +\expandafter\newdimen\csname col@ht@ 6\endcsname +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% +% +% +% \subsubsection{Utilities for Columns and their Data Structures} +% +% \begin{macro}{\forall@columns} +% If we want to do something to data structures for all column we +% can use the macro |\forall@columns|. Within its argument the +% current column is available in the register +% |\curr@col@count|. The macro takes some pains to restore the +% original value of |\curr@col@count| afterwards. +% \begin{macrocode} +\def\forall@columns#1{ + \edef\saved@curr@col@count{\the\curr@col@count} + \global\curr@col@count\z@ + \@whilenum \curr@col@count<\col@count \do + {\global\advance\curr@col@count\@ne + #1 + } + \global\curr@col@count\saved@curr@col@count\relax +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\initialise@column@data} +% \begin{macrocode} +\def\initialise@column@data{ +%<*trace> + \@tracepush{initialise@column@data} +%</trace> +% \end{macrocode} +% +% \begin{macrocode} + \global\let\best@trial\@empty + + \forall@columns + { + + \global\csname col@ht@ \the\curr@col@count\endcsname\textheight + +% \end{macrocode} +% +% \begin{macrocode} + \expandafter + \g@addto@macro\expandafter\best@trial\expandafter + { + \expandafter + \global + \csname col@ht@ \the\curr@col@count\endcsname + \textheight + } +% \end{macrocode} +% We haven't seen any top or bottom floats yet. +% \begin{macrocode} + \global\@namedef{col@t@floats@ \the\curr@col@count + @number}{0} + \global\@namedef{col@b@floats@ \the\curr@col@count + @number}{0} +% \end{macrocode} +% For the same reason the delta values for top and bottom areas are +% zeroed.\footnote{Using \texttt{\string\let} and +% \texttt{\string\z@} in places like this would be more faster and +% shorter, but it wouldn't work nicely in tracing as it would make +% unexpandable macros. Perhaps the tracing versions should be made +% specially.} +% \begin{macrocode} + \global\@namedef{col@t@delta@ \the\curr@col@count}{0pt} + \global\@namedef{col@b@delta@ \the\curr@col@count}{0pt} + } + +%<*trace> + \tr@ce{\meaning\best@trial} + \@tracepop{initialise@column@data} +%</trace> +} +% \end{macrocode} +% \end{macro} +% +% +% +% +% +% +% \subsubsection{User Commands for Columns} +% +% +% \begin{macro}{\columnbreak} +% And here is the user command formaking a column +% break:\footnote{All this is stolen from \texttt{multicol.sty} and +% there is still code that doesn't belong here.} |\columnbreak| is +% modelled after |\pagebreak| except that we generate a penalty +% |-\output@columnbreak@penalty|. +% \begin{macrocode} +\def\columnbreak{ +% \end{macrocode} +% We have to ensure that it is only used within a multicolumn +% environment since if that penalty would be seen by the unmodified +% \LaTeX{} output routine strange things would happen. +% \begin{macrocode} + \ifnum\col@count<\tw@ + \PackageError{xoutput} + {\noexpand\columnbreak~ in~ one-column~ mode} + {???} + \else + \ifvmode + \penalty -\output@columnbreak@penalty + \else + \@bsphack + \vadjust{\penalty -\output@columnbreak@penalty} + \@esphack + \fi + \fi} +% \end{macrocode} +% \end{macro} +% +% +% +% +% +% +% +% +% +% +% \subsection{Float Areas and their Data Structures} +% +% Naming conventions for float areas is as follows: +% \begin{quote} +% \meta{identifier}\meta{start-column}\meta{span-count}. +% \end{quote} +% The \meta{identifier} is a single letter denoting the type of area, +% e.g., |t| for top, |b| for bottom. The \meta{span-count} is a single +% digit denoting the number of columns to span. The +% \meta{start-column} is a single digit\footnote{with a bit of care in +% the code this could be extended to allow more than one digit.} +% denoting the start column of the area. Thus |t32| is a top area +% starting at column three and spanning two columns ie three and four. +% A restriction due to the naming scheme is that currently no more than +% 9 columns are possible. +% +% Only a subset of the float areas is allowed to be popolated on a +% page. In essense the current algorithm does not support placements +% that result in splitting the text of a column due to a float (other +% than column `here' floats).\footnote{Perhaps this restriction is +% lifted one day.} This means that if $pcs$ ($p=\textrm{pos}$, +% $c=\textrm{column}$, $s=\textrm{span}$) is a float area that is +% being populated then it must prevent populating all float areas that +% satisfy either +% \[ +% pij \textrm{ with } i < c \leq i+j < c+s +% \] +% or +% \[ +% pij \textrm{ with } i \leq c+s < i+j \leq \verb=\col@count= +% \] +% The first formula describes the areas which partly overlap from the +% left, the second formula describes those that partly overlap from +% the right. Areas which are sub- or super-areas, e.g., \texttt{t13} +% and \texttt{t22} do not affect each other. The above restriction is +% necessary to prevent situations like +%\begin{verbatim} +%aaaaaaaaaaa 444 +%aaaaaaaaaaa 444 +%aaaaaaaaaaa 444 +%111 222 bbbbbbb +%111 222 bbbbbbb +%111 222 bbbbbbb +%111 222 333 444 +%111 222 333 444 +%\end{verbatim} +% +% +% For each area |FOO| (e.g., |t13|) we keep a number of global +% variables to store relevant data. These are the following +% variables\footnote{Not a consistent lot}: +% +% \DescribeMacro\area@FOO +% Floats allocated to the area |FOO| by the page building process +% are stored as an |\@elt| list in the macro |\area@FOO|. +% +% \DescribeMacro\pagesetup@FOO@float@num +% The maximum number of floats allowed in area |FOO| is stored in +% the macro |\pagesetup@FOO@float@num|. +% +% \DescribeMacro\FOO@@float@count +% +% The number of floats currently allocated to area |FOO| is stored +% in the count register |\FOO@@float@count|.\footnote{This is a +% waste of registers!} +% +% \DescribeMacro\pagesetup@FOO@class@close +% The areas that should be closed for floats of the same sequence class the +% moment a float is placed into area |FOO|. This is a comma +% separated list. +% +% \DescribeMacro\pagesetup@FOO@all@close +% The areas that should be closed for all float sequence classes the +% moment a float is placed into area |FOO|. This is a comma +% separated list. +% +% +% +% \begin{macro}{\known@areas} +% |\known@areas| are the areas known to the system.\footnote{or +% something else, the semantics are still changing} Initialisation +% is done when declaring individual areas. +% \begin{macrocode} +\def\known@areas{} +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\used@areas} +% |\used@areas| are the areas used by the current page setup. +% Initialisation is done in the page setup template so the +% definition below is arbitrary. +% \begin{macrocode} +\def\used@areas{ t11 b11 } +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\@activelist} +% \begin{macrocode} +\let\@activelist\@empty +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@mvllist} +% \begin{macrocode} +\let\@mvllist\@empty +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\area@ddd} +% The list of deferred floats (which we consider being an area in +% some respects). +% \begin{macrocode} +\let\area@ddd\@empty +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\pagesetup@ddd@class@close} +% \begin{macro}{\pagesetup@ddd@all@close} +% \begin{macrocode} +\def\pagesetup@ddd@class@close{\pagesetup@area@list} +\let\pagesetup@ddd@all@close\@empty +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% +% \begin{macro}{\this@open@areas} +% \begin{macro}{\saved@this@open@areas} +% In |\this@open@areas| we store the float areas which we will try +% to place a float onto the current page. These areas are tried one +% after another until the float is successfully placed or we run +% out of areas. The list does not have any separator (as we assume +% that all areas are denoted by a letter followed by two digits). +% +% |\saved@this@open@areas| is the seved version needed for +% backtracking if we encounter a flush point that can't be resolved. +% \begin{macrocode} +\let\this@open@areas\@empty +\let\saved@this@open@areas\@empty +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% +% \begin{macro}{\this@closed@areas} +% In |\this@closed@areas| we store the float areas which have been +% closed for the current float while trying to place it. In this +% list each area name is followed by a comma (to avoid spurious +% matches). It is initialised with |closed@\this@class @areas| when +% we fetch a new float to try. Once the float is placed we write +% the then current value back. +% \begin{macrocode} +\let\this@closed@areas\@empty +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\this@page@closed} +% In |\this@page@closed| we store the float areas which have been +% closed for all float types. In this list each area name is +% followed by a comma (to avoid spurious matches). +% \begin{macrocode} +\let\this@page@closed\@empty +% \end{macrocode} +% \end{macro} +% +% +% +% +% \begin{macro}{\t11@float@count} +% \begin{macro}{\t21@float@count} +% \begin{macro}{\b11@float@count} +% \begin{macro}{\b21@float@count} +% The float counts are allocated dynamically when an area is +% declared if they are not defined, but we have a few registers +% left over from \LaTeX{}'s old OR so we might as well use them. +% \begin{macrocode} +%\expandafter\newcount\csname t11@float@count\endcsname +\expandafter\let\csname t11@float@count\endcsname \@topnum +%\expandafter\newcount\csname b11@float@count\endcsname +\expandafter\let\csname b11@float@count\endcsname \@botnum +%\expandafter\newcount\csname t12@float@count\endcsname +\expandafter\let\csname t12@float@count\endcsname \@dbltopnum +%\expandafter\newcount\csname b12@float@count\endcsname +\expandafter\let\csname b12@float@count\endcsname \@dblbotnum +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\ddd@float@count} +% And we need to declare the one for the defer area is that isn't +% going through the normal initialisation process. +% \begin{macrocode} +\newcount\ddd@float@count +% \end{macrocode} +% \end{macro} +% +% +% +% +% \begin{macro}{\pagesetup@float@area@sep} +% |\pagesetup@float@area@sep| is the separation to use between two +% adjacent float areas. +% \begin{macrocode} +\newskip\pagesetup@float@area@sep +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\pagesetup@float@text@sep} +% |\pagesetup@float@text@sep| is the separation to use between +% column text and adjacent float areas. +% \begin{macrocode} +%\newskip\pagesetup@float@text@sep +\let\pagesetup@float@text@sep\textfloatsep % reuse register +\let\textfloatsep\@undefined +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\pagesetup@float@float@sep} +% |\pagesetup@float@float@sep| is the separation to use between +% two floats in the same float area. +% \begin{macrocode} +%\newskip\pagesetup@float@float@sep +\let\pagesetup@float@float@sep\floatsep % reuse register +\let\floatsep\@undefined +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\pagesetup@float@text@shrink} +% |\pagesetup@float@text@shrink| is the allowed shrinkability of +% |\pagesetup@float@text@sep|. This is used if we are doing grid +% typesetting and have to adjust the vertical size of the column. +% \begin{macrocode} +\newdimen\pagesetup@float@text@shrink +% \end{macrocode} +% \end{macro} +% +% +% +% +% \begin{macro}{\pagesetup@float@inline@sep} +% |\pagesetup@float@inline@sep| is the separation to use between +% two floats in the same float area. +% \begin{macrocode} +%\newskip\pagesetup@inline@float@sep +\let\pagesetup@float@inline@sep\intextsep % reuse register +\let\intextsep\@undefined +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\pagesetup@float@inline@shrink} +% |\pagesetup@float@inline@shrink| is the allowed shrinkability of +% |\pagesetup@float@inline@sep|. This is used if we are doing grid +% typesetting and have to adjust the vertical size of object to be +% added, e.g., an inline float with its caption. +% \begin{macrocode} +\newdimen\pagesetup@float@inline@shrink +% \end{macrocode} +% \end{macro} +% +% +% +% +% +% +% \subsubsection{Utilities for Float Areas and their Data Structures} +% +% +% \begin{macro}{\initialise@areas} +% Initialise all float areas used within the current page setup. +% \begin{macrocode} +\def\initialise@areas{ + \expandafter\initialise@areas@loop + \used@areas + \relax\relax\relax +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\initialise@areas@loop} +% The |\initialise@areas@loop| picks up the next three tokens and +% interprets them as the component of an area name. +% \begin{macrocode} +\def\initialise@areas@loop#1#2#3{ + \ifx#1\relax + \else + \global\csname #1#2#3@float@count\endcsname\z@ + \global\expandafter\let\csname area@#1#2#3\endcsname\@empty + \expandafter\initialise@areas@loop + \fi} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\first@of@type} +% The macro |\first@of@type| takes a \meta{type} name as its first +% argument and an \meta{area} area name as its second argument and +% will return in the macro |\returned@sequence@number| the sequence +% number of the first float of type \meta{type} currently in +% \meta{area}. If there is no float of type \meta{type} in this +% area it will return |-1| (impossible sequence number). +% \begin{macrocode} +\def\first@of@type#1#2{ + \begingroup + \def\@tempb{#1} + \gdef\returned@sequence@number{-1} + \def\@elt{\expandafter\first@of@type@aux\the\toks} + \csname area@#2\endcsname + \endgroup +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\first@of@type@aux} +% This macro picks up the type definition in the data structure of +% a float and compares it with the name started in |\@tempb|. If +% they agree |\returned@sequence@number| will get updated to +% contain the sequence number of the float. +% \begin{macrocode} +\def\first@of@type@aux#1#2#3#4#5#6#7{ + \def\@tempa{#6} + \ifx\@tempa\@tempb + \gdef\returned@sequence@number{#7} + \let\@elt\@gobble + \fi} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\last@of@type} +% The macro |\last@of@type| takes a \meta{type} name as its firat +% argument and an \meta{area} area name as its second argument and +% will return in the macro |\returned@sequence@number| the sequence +% number of the last float of type \meta{type} currently in +% \meta{area}. If there is no float of type \meta{type} in this +% area it will return |-1| (impossible sequence number). +% \begin{macrocode} +\def\last@of@type#1#2{ + \begingroup + \def\@tempb{#1} + \gdef\returned@sequence@number{-1} + \def\@elt{\expandafter\last@of@type@aux\the\toks} + \csname area@#2\endcsname + \endgroup +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\last@of@type@aux} +% \begin{macrocode} +\def\last@of@type@aux#1#2#3#4#5#6#7{ + \def\@tempa{#6} + \ifx\@tempa\@tempb + \gdef\returned@sequence@number{#7} + \fi} +% \end{macrocode} +% \end{macro} +% +% +% +% +% \begin{macro}{\setup@this@area} +% +% Whenever the algorithm works with some area as the current +% candidate for putting a float into it uses the following commands +% to reference this area: +% +% \DescribeMacro\this@area +% The macro |\this@area| holds the name of the candidate area, e.g., +% it would expand to something like |t13|. +% +% \DescribeMacro\this@area@type +% The macro |\this@area@type| holds the ``type'' of the area, e.g., |t| +% in the above example. +% +% \DescribeMacro\this@area@col@number +% The macro |\this@area@col@number| holds the starting column of the +% area, e.g., |1| in the above example. +% +% +% \DescribeMacro\this@area@span@number +% The macro |\this@area@span@number| holds the number of columns +% spanned by the area, e.g., |3| in the above example. +% +% All the above macros are globally assigned when calling +% |\setup@this@area|. The argument is fully expanded (!) since one +% typical usage to pick up the first area from an area like +% |\this@open@areas| which can then be done within the argument. +% +% \begin{macrocode} +\def\setup@this@area #1 { + \xdef\this@area{#1} +% \end{macrocode} +% This really relies on |\this@area| containing exactly three +% tokens (no error recovery if not). +% \begin{macrocode} + \expandafter\gassign@area@type@col@and@span@aux\this@area +} +\def\gassign@area@type@col@and@span@aux #1#2#3{ + \gdef \this@area@type {#1} % type + \gdef \this@area@col@number {#2} % col + \gdef \this@area@span@number {#3} % span +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\update@this@area@columns} +% +% If we have to do updates for all columns that are spanned by the +% current target area we can call |\update@this@area@columns|. It +% loops through the columns with |\count@| referring to the current +% column. Data structure updates have to be global as everything +% happens within a group. +% \begin{macrocode} +\def\update@this@area@columns #1 { + \begingroup + \count@\this@area@col@number\relax + \advance\count@\this@area@span@number\relax + \loop + \ifnum \this@area@col@number < \count@ + \advance\count@\m@ne +%<*trace> + \tr@ce{looking~ at~ column:~ \the\count@} +%</trace> + #1 + \repeat + \endgroup +} +% \end{macrocode} +% \end{macro} +% +% +% +% +% +% +% \newpage +% \subsection{Collection Output Routine} +% +% \begin{description} +% \item[Entry:] |\setup@collection@or| +% \item[Exit:] |\setup@float@placement| +% \item[Prereq:] |\initialise@next@page| should have been called before. +% \item[Description:] Grab enough text (and float call-outs) to obtain +% a galley big enough to form the next text page. The page goal is +% set to a value high enough to ensure that in normal cases text +% for all columns of the page is collected, i.e, we have a safety +% margin of 5 extra lines per column.\footnote{This should be made +% customisable for unusual jobs!} +% +% If the output routine is triggered with a special penalty (in the +% range of $-10000>p>-10010=|\output@balance@penalty|$) the penalty +% is moved into the collection box |\partial@galley@box| without +% further processing; otherwise the collection is ended and all +% collected material is moved to |\@holdpg| for use in page +% production. +% +% \item[Flow:] +%\begin{footnotesize} +%\begin{verbatim} +% \setup@collection@or +% | +% V +% New OR: \collection@or +% | +% |<----------------------------------------- +% | | +% (natural end of collection reached?) | +% | | | +% yes no | +% | | | +% | (record special penalty and carry on)---- +% | +% V +% \setup@float@placement +%\end{verbatim} +%\end{footnotesize} +% \end{description} +% +% Chris noted that |\@holdpg| never gets emptied. This could be +% done when the Collection OR is started for a new page (in this +% next macro).\footnote{FIX} +% +% \begin{macro}{\setup@collection@or} +% \begin{macrocode} +\def\setup@collection@or{ +%<*trace> + \@tracepush{setup@collection@or} +%</trace> + \global\holdinginserts\@ne +% \end{macrocode} +% We set the |\vsize| for collection to the height of a single +% column (plus a safety margin of currently five lines to allow for +% vanishing space at margins) multiplied by the number of columns. +% \begin{macrocode} + \global\vsize\textheight + \global\advance\vsize 5\baselineskip + \global\multiply\vsize \col@count +%<*trace> + \tr@ce{collection~vsize:~\the\vsize } +%</trace> +% \end{macrocode} +% Initialising the flush point handling: +% \begin{macrocode} + \@flushseenfalse + \@flushfailfalse +% \end{macrocode} +% We may have to restart the collection (whenever we find a here or +% a flush point) and we don't want to get extra space added via +% |\topskip|. So we can either make |\topskip| zero during +% collection (current strategy) or back it out whenever we restart. +% +% We can't set topskip to zero now since a) we want a proper +% |\topskip| for the first column and b) due to a bloody fix for the +% old \LaTeX{} OR, a value of |0pt| is set to |1sp| in +% |\begin{document}| and this results in adding |1sp| at every +% special point\ldots no, we definitely do not want this! It took +% me ages to find out why the grid design macros didn't work. +% \begin{macrocode} + \xdef\saved@topskip{\the\topskip} +% \end{macrocode} +% +% \begin{macrocode} + \global\output{\collection@or} +%<*trace> + \@tracepop{setup@collection@or} +%</trace> +} +% \end{macrocode} +% \end{macro} +% +% +% +% +% \begin{macro}{\if@collecting@new@material} +% There are actually two collecting modes: one when the recent +% contributions are empty and we are really collecting material +% that we haven't seen before and one where we collect material +% that has been collected on a previous collection pass and has been +% placed again on to the main vertical list. The reason why we need +% to differentiate between the two is that in the second case we +% have to handle the special penalties differently since by now +% they are already surrounded by the proper guard boxes before and +% after and we better do not disturb this fragile setup. +% \begin{macrocode} +\newif\if@collecting@new@material +\def\@collecting@new@materialfalse + {\global\let\if@collecting@new@material\iffalse} +\def\@collecting@new@materialtrue + {\global\let\if@collecting@new@material\iftrue} +% \end{macrocode} +% \end{macro} +% +% +% +% +% \begin{macro}{\collection@or} +% The output routine during the collection phase assembles the +% material until enough has been gathered to be sure to fill a +% page. +% \begin{macrocode} +\def\collection@or{ +%<*trace> + \@tracepush{collection@or} + \tr@ce{output~pen:~ \the\outputpenalty} +%{\x\showoutput\showbox255} +%</trace> +% \end{macrocode} +% We first look if the call to the OR is due to a special penalty. +% \begin{macrocode} + \@testfalse + \ifnum\outputpenalty < -\@M + \ifnum\outputpenalty > -\output@balance@penalty + \@testtrue + \fi + \fi + \if@test +%<*trace> + \tr@ce{Forced~ break~(\the\outputpenalty)~ seen\on@line} +%</trace> +% \end{macrocode} +% Whenever a special penalty, i.e., one between $-10000 > p > +% -10010$ is encountered we need some magic: +% \begin{itemize} +% \item We want to keep the the penalty in the collected material but +% nevertheless carry on with the collection. Simply moving the +% collected material to a separate box is not enough since then +% we will restart the collection with an empty page and thus +% receive a |\topskip| glue as well as probably losing material +% if there is anything discardable after the special penalty. +% \item But putting a zero box back and doing something to fix the +% problem with the |\topskip| glue isn't good either in case we +% later actually want to break after the line with special +% penalty, since then we would start a page with our inserted +% box, and in this case we would like to get a proper |\topskip| +% and we would like to get rid of discardable stuff. +% \item And there is another problem, we need a guard box in front of +% that special penalty, but this guard box should not be simply a +% |\null| box (as it is right now added by +% |\add@badly@guarded@penalty|) since that will result in wrong +% page calculations because it will make \TeX{} add the depth of +% the precious line to the page total which it shouldn't. +% \end{itemize} +% So what to do? First of all we remove the guard box in front of +% the special penalty (which is now at the end of box 255) since we +% want to replace that with something better, then we +% store away the depth of box 255 since we need that in a minute. +% \begin{macrocode} + \remove@guard@box@from@cclv +% \end{macrocode} +% We really have to say |\dp\@cclv| not |\pagedepth|. The latter is +% always zero in the OR which looks suspiciously like a bug or at +% least an inconsistency when Don implemented the change from \TeX2 +% to \TeX3 (in \TeX2 |\page...| registers were useless in the OR, +% now only |\pagedepth| seems to be left). +% \begin{macrocode} + \dimen@\dp\@cclv +% \end{macrocode} +% Then we subtract the size of the collected material from +% |\vsize| since we will store it away in a separate box for a +% while. Note that we have to use |\ht\@cclv| here not |\pagetotal| +% since the latter might be to large because of that |\null| +% box. The height of 255 on the other hand is, after the removal of +% that box the natural height of the material. +% \begin{macrocode} + \global\advance\vsize-\ht\@cclv +% \end{macrocode} +% Now we append the material to |\partial@galley@box|, this is +% straight forward. +% \begin{macrocode} + \global\setbox\partial@galley@box + \vbox{\ifvoid\partial@galley@box + \else + \unvbox\partial@galley@box + \fi + \unvbox\@cclv +% \end{macrocode} +% But how to add the penalty and how to guard it? We need a box or +% something to ensure the penalty doesn't get lost at a column +% break but we also want to avoid that \TeX{} adds the depth of the +% preceding line to |\pagetotal|. Fortunately we know this depth by +% now (we have just stored it in |\dimen@|), something we didn't +% know at the time the we added the penalty with +% |\add@badly@guarded@penalty|. So we could back up and then add a +% box with zero height and that depth. This way a break directly +% after this line would have the same |\pagetotal| as a break at +% the special penalty. In fact, instead of backing up using a +% |\kern| or a |\vskip| we can simply make the height of the box +% negative. The advantage is that this way we don't generate a +% break point between the box and a preceding box and thus don't +% have to use special precautions to prevent \TeX{} from breaking in +% front of the guard box.\footnote{This statement is only true for +% special penalties added using \texttt{\string\vadjust}, i.e., in +% hmode. If the penalty was added between paragraphs then there +% might be vertical space in front of the box. This might need +% special handling too. CHECK!} +% \begin{macrocode} + \setbox\z@\vbox to-\dimen@{} + \dp\z@\dimen@ + \box\z@ + \penalty\outputpenalty + } +%{\showoutput\batchmode\showbox\partial@galley@box\errorstopmode} +% \end{macrocode} +% So now we have put everthing we need into the +% |\partial@galley@box|, but how do we restart our collection +% process without running into the problems outlined above? +% +% Well, right now on the recent contributions there will be a +% penalty node (from our special penalty) which gets set to 10000 +% by \TeX{} followed perhaps by another penalty from the line +% breaking followed probably by interline glue calculated to make +% the next line of text fit vertically with the preceding one --- +% and we don't want to loose that that glue if we are ending up in +% the middle of a column. But we want to make it vanish if we +% happen to finally break at the special penalty place. +% +% So the trick is that we a) disable |\topskip| by setting it to +% |-\maxdimen| (not zero this might be too large still) and b) we +% add another of those funny boxes followed by a penalty of zero to +% allow for a break after it. +% +% If later on all this is put together again into a single box (in +% |\@holdpg|) we will have the following sequence there: +% \begin{itemize} +% \item text line (box) preceding the special penalty with depth $d$ +% or some other vertical material in which case $d=0\texttt{pt}$ +% \item special box with height $-d$ and depth $d$ +% \item special penalty, e.g. $-10008$ +% \item |\topskip| glue of 0pt +% \item special box with height $-d$ and depth $d$ +% \item |\penalty| 0 +% \item |\penalty| 10000 +% \item perhaps a |\penalty| and/or interline glue +% \item perhaps the next text line (box) +% \end{itemize} +% Now if during later processing we hit the special penalty +% |\pagetotal| has the same value as if we would have broken the +% galley directly after the text line, in other words we do not see +% the penalty too late (assume this happens to be the last line of +% the column then if |\pagetotal| would also have the extra depth +% added to it it might have been overfull and the penalty not being +% considered at all for this column). +% +% After the OR's have dealt with the special penalty, e.g., by +% flushing some floats, etc. the penalty will be replaced by 10000 +% and thus the next time the galley is processed there is no +% breakpoint between the two special boxes any more. As a result +% the next potential breakpoint is the penalty 0 which again +% results in exactly the same |\pagetotal| as before, i.e., if the +% text line was the last line to fit in the column then this +% breakpoint will still fit there. Thus if we break the column +% there then the interline glue etc will vanish and \TeX{} will +% insert |\topskip| glue (which has be set back to a normal value +% by then). If on the other hand, this break point is not chosen +% the interline glue will stay and thus the two text lines, before +% and after the special penalty will sit one |\baselineskip| apart +% just as they should. +% +% Woah. What did Don said on page 125 of \textit{The \TeX{}book}? +% (Deep breath.) You got that?\footnote{There are probably still +% cases that aren't covered I fear and the need for an explicit +% penalty 0 at the end is kind of toublesome, so we have to see if +% this needs further refinements.} +% +% And here is already the first case where the above method is not +% appropriate: if we stumble across a |\output@columnbreak@penalty| +% we need to discard any following glue, so we don't want a box +% intervene here.\footnote{Once this is interfaced with the galley +% code problems like this should vanish since then we can ensure +% that all such penalties are added to the galley on at save +% places. REDO THEN!} +% \begin{macrocode} + \global\topskip-\maxdimen % okay here? + \if@collecting@new@material + \ifnum \outputpenalty = -\output@columnbreak@penalty + \else + \setbox\z@\vbox to-\dimen@{} + \dp\z@\dimen@ + \box\z@ + \penalty\z@ + \fi + \fi +% \end{macrocode} +% +% \begin{macrocode} + \ifnum\outputpenalty=-\output@flush@float@penalty +%<*trace> + \tr@ce{Forced~ break~ =~ flush~ float~ point} +%</trace> + \@flushseentrue + \fi +% \end{macrocode} +% Otherwise either the we reached the natural end of the +% collection, or the point where we have been before (in case we +% are recollecting previously seen material) or we reached an +% |\output@balance@penalty|. +% \begin{macrocode} + \else + \ifnum\outputpenalty = -\output@collect@penalty +% \end{macrocode} +% If we got an |-\output@collect@penalty| then we are at the point +% to which the previous collection pass got. So, away with the +% guard box, then everything back onto the MVL and as a penalty we +% try to put what we have found in the previous collection pass. +% \begin{macrocode} + \remove@guard@box@from@cclv + \unvbox\@cclv +%<*trace> + \tr@ce{reinsert~penalty:~ \saved@outputpenalty\space + (unless~ 10000~ or~ <~ -9999)} +%</trace> + \ifnum\saved@outputpenalty > -\@M + \penalty + \ifnum\saved@outputpenalty=\@M + \z@ + \else + \saved@outputpenalty\relax + \fi +% \end{macrocode} +% We have a special situation to account for here: if we have a +% |\pagebreak| that ended the collection last time then it might +% still be the case that we haven't got to this point due to +% floats. So we would need to put that penalty back. But only then, +% and therese the catch! The alternative is to not stop a +% collection as such a point so that this problem doesn't arise in +% the first place. Right now we lose the +% penalty.\footnote{Unresolved situation. FIX!} +% \begin{macrocode} + \else + \fi +% \end{macrocode} +% Finally we change the |@collecting@new@material| switch since we +% are from now on looking at really new material. +% \begin{macrocode} + \@collecting@new@materialtrue + \else +% \end{macrocode} +% Next case is not functional right now\ldots +% \begin{macrocode} + \ifnum\outputpenalty = -\output@balance@penalty + \@balancetrue +%<*trace> + \tr@ce{BALANCE:~ break~ seen\on@line} +%</trace> + \xdef\saved@outputpenalty{0} +% \end{macrocode} +% This is now the point where the collection ended naturally: we +% save the penalty that triggered it and combine the +% |\partial@galley@box| if it contains material with the stuff now +% in 255 and put everything into |\@holdpg|. +% \begin{macrocode} + \else + \xdef\saved@outputpenalty{\the\outputpenalty} + \fi + \ifvoid\partial@galley@box + \global \setbox\@holdpg\box\@cclv + \else +%<*trace> + \tr@ce{Re-adding~ forced~ break(s)~ for~ splitting} +%</trace> + \global\setbox\@holdpg\vbox{ + \unvbox\partial@galley@box + \unvbox\@cclv} + \fi + +%\showbox\@holdpg + + \if@balance + \global\setbox\@holdpg\vbox{ + \unvbox\@holdpg + \penalty\outputpenalty % short for "-\output@balance@penalty" + } + \fi + + \mark@save@state + \mark@update@structure +% + \global\holdinginserts\z@ + + \global\topskip\saved@topskip + + \setup@float@placement + + \@collecting@new@materialfalse + \fi + \fi +%<*trace> + \@tracepop{collection@or} +%</trace> + } +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\partial@galley@box} +% Need a box to store the partially collected galley. +% \begin{macrocode} +\newbox\partial@galley@box +% \end{macrocode} +% \end{macro} +% +% +% +% +% +% \begin{macro}{\initialise@float@class} +% +% \begin{macrocode} +\def\initialise@float@class#1{ +%<*trace> + \@tracepush{initialise@float@class} +%</trace> + \count@0\LastMark{#1} +% +% next line no longer used +% \global\expandafter\mathchardef\csname count@#1\endcsname\count@ +% +%<*trace> + \tr@ce{count~ (#1) = \the\count@} +%</trace> +% \end{macrocode} +% +% At some point the set of open areas at page start (for a +% given type of floats) should be specifiable through some +% templates. Using |\used@areas| is not really the right thing +% to do.\footnote{Code should vanish one day}. +% \begin{macrocode} + \global\expandafter\let\csname open@#1@areas\endcsname\used@areas + \global\expandafter\let\csname closed@#1@areas\endcsname\@empty +% \end{macrocode} +% +% \begin{macrocode} +%<*trace> + \tr@ce{open~ (#1) = \csname open@#1@areas\endcsname} + \tr@ce{closed~ (#1) = \csname closed@#1@areas\endcsname} +%</trace> +% \end{macrocode} +% +% |\fl@1@figure| are macros that expands to the highest numbered +% figure callout in this column (or zero if there is none). +% |\fl@0@figure| is the highest value from previous pages (or zero +% if there was never any float of this type). +% \begin{macrocode} + \forall@columns { + \ifnum \csname fl@ \the\curr@col@count @#1\endcsname>\z@ + \global\expandafter\let\csname fl@0@#1\expandafter\endcsname + \csname fl@ \the\curr@col@count @#1\endcsname + \expandafter\xdef + \csname fl@ \the\curr@col@count @#1\endcsname{0} + \fi +% \end{macrocode} +% |\tfl@1@figure| is like |\fl@1@figure| but only stores +% information about floats allocated to top areas. +% \begin{macrocode} + \expandafter\xdef + \csname tfl@ \the\curr@col@count @#1\endcsname{0} + } +%<*trace> + \@tracepop{initialise@float@class} +%</trace> + } +% \end{macrocode} +% \end{macro} +% +% +% +% +% \newpage +% +% \subsection{Placing Floats} +% +% +% \begin{description} +% \item[Entry:] |\setup@float@placement| +% \item[Exit:] |\setup@grab@column@or| or |\setup@best@column@or| +% \item[Prereq:] +% \item[Description:] +% \item[Flow:] +%\begin{footnotesize} +%\begin{verbatim} +% \setup@float@placement +% | +% V +%(2)--> \float@placement@loop +% | +% <run with floats?> +% | | +% yes no----------> \setup@grab@column@or +% | +% V +% \trial@inner@loop +% | +% V +% <current float successfully placed in previous trial?> +% | | +% no yes +% | | +% (means we now try V +% again using different \try@next@float <------------------- +% placement rules below ) | | +% | | | +% | <\@activelist empty?> | +% | | | | +% | no yes | +% | | | | +% | | V | +% | (get it) \@activelist@empty@action | +% | | (= \setup@best@column@or) | +% -------------v---------------- | +% | | +% -----> \try@this@area (= \std@try@this@area, or | +% | | \relaxed@try@this@area) | +% | | | +% | <still open areas for current float type?> | +% | | | | +% | yes no---------------(defer float)-------------- +% | | | +% | (do some tests and perhaps | +% | close area this way) | +% | | | +% | <float allowed on this page/column (according to tests)?> | +% | | | | +% | yes no---------------(defer float)-------------- +% | | +% | <current area got closed by any test?> +% | | | +% | yes no +% | | | +% | (select next area) | +% | | | +% -------- V +% \pretests@success@action (\setup@grab@column@or) +%\end{verbatim} +%\end{footnotesize} +% \end{description} +% +% +% +% +% +% \begin{macro}{\if@fail} +% \begin{macrocode} +\newif\if@fail +\def\@failfalse{\global\let\if@fail\iffalse} +\def\@failtrue{\global\let\if@fail\iftrue} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\setup@float@placement} +% +% \begin{macrocode} +\def\setup@float@placement { +% initialise before trial loop (needs work) +%<*trace> + \@tracepush{setup@float@placement} +%</trace> +% \end{macrocode} +% A bit statistics: how many floats do we have on the +% |\@activelist|? +% \begin{macrocode} +%<*progress> + \def\@elt{\global\advance\trial@count\@ne\@gobble} + \@activelist + \let\@elt\relax + \progress@separator + \progress@nl{STATS:~ floats~ waiting~ =~ \the\trial@count + \space on~ page~ \the\absolute@page@number} + \progress@separator + \global\trial@count\z@ +%</progress> +% \end{macrocode} +% We need the list of here floats during all trials. They are +% therefore saved in |\saved@herelist| at this point which is then +% used to initialise |\@herelist| at the beginning of each trial. +% \begin{macrocode} + \global\let\saved@herelist\@herelist +% \end{macrocode} +% +% \begin{macrocode} + \tighten@float@placement@conditions +% \end{macrocode} +% First time we run the |\float@placement@loop| we run it without +% actually trying any floats (i.e., we are just cutting the +% galley).\footnote{Could be improved: if there are no floats then +% we run it once too often this way (per page) so\ldots} +% \begin{macrocode} + \run@with@floatsfalse + \float@placement@loop +%<*trace> + \@tracepop{setup@float@placement} +%</trace> +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\float@placement@loop} +% Place the galley box back on the MVL. Needs to be done via the +% special output routine call |\mark@restore@state| to ensure that +% \TeX's primitive marks reflect the `logical' previous page rather +% than the previous actual output routine call. +% \begin{macrocode} +\def\float@placement@loop{ +%<*trace> + \@tracepush{float@placement@loop} +%</trace> +% \end{macrocode} +% +% \begin{macrocode} + \deadcycles\z@ + \global\let\@activelist@empty@action\setup@best@column@or + \global\let\pretests@success@action\setup@grab@column@or +% \end{macrocode} +% +% If we are doing trials we have to place a special penalty at the +% end of the MVL but if we are cutting up the galley for +% typesetting we don't want this penalty. Since at this point it is +% not clear in which case we are we defer this action until +% later.\footnote{This part of the documentation is no longer true, +% we now add it below. CORRECT DOCU} +% +% |\mark@restore@state| state is a special output routine those +% only purpose is to reinitialise the state of the mark +% mechanism. Its argument is executed at the of that OR. +% \begin{macrocode} + \mark@restore@state{ +% \end{macrocode} +% Initialising the grabbing trials means putting the saved material +% back onto the MVL and reinitialising the here float list. +% \begin{macrocode} + \unvcopy\@holdpg + \ifnum\saved@outputpenalty > -1073741824\relax + \add@badly@guarded@penalty\output@collect@penalty + \fi + \global\let\@herelist\saved@herelist +% \end{macrocode} +% +% The we can start the actual loop: if we run with floats we go to +% |\trial@inner@loop| otherwise we immediately setup the grap +% column OR. +% \begin{macrocode} + \ifrun@with@floats + \trial@inner@loop + \else + \setup@grab@column@or + \fi + } +%<*trace> + \@tracepop{float@placement@loop} +%</trace> + } +% \end{macrocode} +% \end{macro} +% +% +% +% +% \begin{macro}{\trial@inner@loop} +% Alternative entry into the float placement trial loop. This can +% be used by setting |\@activelist@empty@action| and +% |\pretests@success@action| to different values, e.g., for trying +% float pages without the overhead of the grabcolumn output +% routine, etc. +% \begin{macrocode} +\def\trial@inner@loop{ +%<*trace> + \@tracepush{trial@inner@loop} +%</trace> +% \end{macrocode} +% If |\if@fail| is true we have already tried the current float +% before. This means we either do a retry with relaxed conditions +% (in which case the current area to try was suitably modified +% beforhand) or else we have just started with a new float and +% should try the first area of |\this@open@areas|. +% \begin{macrocode} + \if@fail + \@failfalse + \@flushfailfalse +% \end{macrocode} +% +% \begin{macrocode} +%<*progress> + \global\advance\trial@count\@ne +%</progress> +% \end{macrocode} +% +% \begin{macrocode} + \do@next\try@this@area + \else + \do@next\try@next@float + \fi +%<*trace> + \@tracepop{trial@inner@loop} +%</trace> + \do@continue + } +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\trial@count} +% To gather statistics we count the number of trials per page. +% \begin{macrocode} +%<*progress> +\newcount\trial@count +%</progress> +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\try@this@area} +% |\try@this@area| is |\let| to the right definition before it is +% called so on top-level it is defined to be an error. +% \begin{macrocode} +\let\try@this@area\ERROR +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\try@next@area} +% |\try@next@area| first updates |\this@open@areas| by removing the +% first area in this list and then calls |\try@this@area|. Thus it +% should never be called if |\this@open@areas| is already empty. +% \begin{macrocode} +\def\try@next@area{ + \xdef\this@open@areas{\expandafter\@gobblethree\this@open@areas} +%<*progress> + \global\advance\trial@count\@ne +%</progress> + \try@this@area +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\try@next@float} +% If there is still a float on the active list take it and try to +% place it in the next open float area (which will be the same as +% the current area after a successful trial). If there are no +% floats left execute |\best@trial| to return to that state then +% switch to the bestcolumn output routine to begin typesetting +% columns. +% \begin{macrocode} +\def\try@next@float{ +%<*trace> + \@tracepush{try@next@float} +%</trace> + \@next\@currbox\@activelist{ +%<*trace> + \tr@ce{currbox:~ \@currbox} +%</trace> +%<*progress> + \progress{Float:~ \@currbox} +%</progress> + \expandafter\update@this@float@structure\the\toks\@currbox +%<*trace> + \tr@ce{saved@this@open@areas~(init):~ + \saved@this@open@areas\space :=~\this@open@areas} +%</trace> + \global\let\saved@this@open@areas\this@open@areas +%<*progress> + \global\advance\trial@count\@ne +%</progress> + \try@this@area + } +% \end{macrocode} +% no floats left\ldots +% \begin{macrocode} + { +%<*progress> + \progress@nl{STATS:~ trials~ =~ \the\trial@count} + \global\trial@count\z@ +%</progress> + \@activelist@empty@action + } +%<*trace> + \@tracepop{try@next@float} +%</trace> +} +% \end{macrocode} +% \end{macro} +% +% +% +% +% +% \begin{macro}{\update@this@float@structure} +% Each float box has an associated token register storing several +% information fields. +% \begin{enumerate} +% \item[1] float caption (set by caption command) +% \item[2] Currently unused (could have callout page number, set by +% |\best@column@or|). +% \item[3] saved label string +% \item[4] `user counter' number (per-type count) set by float environment. +% \item[5] Allowed float areas (from default or optional arg.) +% \item[6] float type (currently this is the long name, eg figure) should +% probably be the single token name, to allow quicker testing. +% \item[7] float sequence number. +% \end{enumerate} +% +% This macro assumes that |\@currbox| is the box number for this structure +% \begin{macrocode} +\def\update@this@float@structure#1#2#3#4#5#6#7{ + \gdef\this@caption{#1} + \gdef\this@span@number{#2} + \gdef\this@usercnt{#4} + \gdef\this@fps{#5} + \gdef\this@type{#6} +% \end{macrocode} +% From the type we infer the class: +% \begin{macrocode} + \global\expandafter\let\expandafter + \this@class\csname sequence@class@#6\endcsname + \gdef\this@sequence@number{#7} +% \end{macrocode} +% If we want to consider all areas for each float (and storing +% closed areas via |\closed@|\meta{type}|@areas| we have to +% initialise |\this@open@areas| to |\used@areas| (which is +% derived from the |area-list| key. +% \begin{macrocode} + \global\let\this@open@areas\used@areas +% \end{macrocode} +% +% \begin{macrocode} + \global\expandafter\let\expandafter\this@closed@areas + \csname closed@\this@class @areas\endcsname % FMi tmp + \global\let\this@float@box\@currbox +%<*trace> +\tr@ce{This~float~structure:} +\toks@{#1}\tr@ce{~{\the\toks@}} +\tr@ce{~{#2}} +\tr@ce{~{#3}} +\tr@ce{~{#4}} +\tr@ce{~{#5}} +\tr@ce{~{#6}} +\tr@ce{~{#7}} +\tr@ce{~this@open@areas~ <-~ \this@open@areas} +\tr@ce{~this@closed@areas~ <-~ \this@closed@areas} +%</trace> +%<*progress> +\progress{~{#7}} +\progress{~{#6}~(\this@class)} +\progress{~{#4}} +%\progress{~{#2}} +%\progress{~{#3}} +%\progress{~{#5}} +\toks@{#1}\progress@nl{~{\the\toks@}} +%</progress> +} +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\extract@this@float@actual@structure} +% As used by Chris in xo-final. Should probably be replaced by the +% one above or combined with the one above!\footnote{FIX!!} +% \begin{macrocode} +\def \extract@this@float@actual@structure #1#2#3#4#5#6#7 { + \gdef\this@caption{#1} + \gdef\this@span@number{#2} + \gdef\this@loglabel{#3} + \gdef\this@usercnt{#4} + \gdef\this@fps{#5} + \gdef\this@type{#6} + \global\expandafter\let\expandafter + \this@class\csname sequence@class@#6\endcsname + \gdef\this@sequence@number{#7} + } +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\update@here@float@structure} +% +% Similar to |\update@this@float@structure| but filling different +% macros.\footnote{We only need some of those macros, so this +% should be cleaned up at some stage.} +% +% This macro assumes that |\@currbox| is the box number for this +% structure. +% +% \begin{macrocode} +\def\update@here@float@structure#1#2#3#4#5#6#7{ + \gdef\here@span@number{#2} + \gdef\here@type{#6} + \global\expandafter\let\expandafter + \here@class\csname sequence@class@#6\endcsname + \gdef\here@sequence@number{#7} + \gdef\here@usercnt{#4} +% \gdef\here@fps{#5} + \gdef\here@caption{#1} + \global\let\here@float@box\@currbox +%<*trace> +\tr@ce{Here~object~structure:} +\toks@{#1}\tr@ce~{~{\the\toks@}} +\tr@ce{~{#2}} +\tr@ce{~{#3}} +\tr@ce{~{#4}} +\tr@ce{~{#5}} +\tr@ce{~{#6}} +\tr@ce{~{#7}} +%</trace> +} +% \end{macrocode} +% \end{macro} +% +% +% +% +% +% +% \begin{macro}{\page@float@count} +% \begin{macrocode} +%\newcount\page@float@count +\let\page@float@count\@colnum +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\this@captioned@float} +% \begin{macrocode} +\newbox\this@captioned@float +% \end{macrocode} +% \end{macro} +% +% +% +% \newpage +% +% \subsection{Grab Column Output Routine} +% +% \begin{description} +% \item[Entry:] |\setup@grab@column@or| +% \item[Exit:] |\setup@cleanup@or| +% \item[Prereq:] +% \item[Description:] +% \item[Flow:] +%\begin{footnotesize} +%\begin{verbatim} +% \setup@grab@column@or +% | +% New OR: \grab@column@or +% | +% V +% \grab@column@loop <------- +% | +% (when entering OR...) +% | +% <end of collection reached?> +% | | +% yes no +% | | +% | <col break requested?> +% | | | +% | yes no +% | | | +% | | <flush point encountered?> +% | | | | +% | | yes no +% | | | | +% | | <flush point <here point encountered?> +% | | too early?> | | +% | | | | yes no +% | | yes no | | +% | | | | ? ? +% | | | (ignore break) +% | | | | +% | | | | +% (end column now) <------- | +% | | +% V | +% <all cols produced?> | +% | | V +% yes no--------------------> (reenter \grab@column@loop) +% | +% (store results of trial) +% | +% V +% \setup@cleanup@or +%\end{verbatim} +%\end{footnotesize} +% \end{description} +% +% +% +% \begin{macro}{\setup@grab@column@or} +% +% \begin{macrocode} +\def\setup@grab@column@or{ +%<*trace> + \@tracepush{setup@grab@column@or} +%</trace> +% \end{macrocode} +% +% We just returned to the MVL the current galley. We now add a +% special penalty to mark the point that we need to reach in order +% to remove everything after the trial run. +% This penalty has to be guarded against premature removal, e.g., +% if the algorithm would break exactly before it it would then be +% discarded which we can't allow.\footnote{Penalty now added +% earlier (normally). CORRECT DOCU} +% \begin{macrocode} + \ifnum\saved@outputpenalty = -1073741824\relax + \add@badly@guarded@penalty\output@collect@penalty + \fi +% \end{macrocode} +% +% \begin{macrocode} + \@failfalse + \global\curr@col@count\z@ +% \end{macrocode} +% In case there is a flush penalty in the collection we have to +% find out if we see it again during the trial. So we record the +% number of flush points we see during the trial. Same happens for +% here points. +% \begin{macrocode} + \gdef\trial@flush@seen@num{0} + \gdef\trial@here@seen@num{0} +% \end{macrocode} +% +% Moved from |\try@this@area| as it should be executed +% only if we really do a trial and thus back it out if +% unsuccessful---this was a bug as it changed +% |\fl@|\meta{col}|@|\meta{type} in cases we never came to this +% point here but recursed) +% \begin{macrocode} + \ifrun@with@floats +% \end{macrocode} +% Depending on the policy a spanning float can be considered belong +% to different columns. This influences the behaviour of the +% call-out contraint tests and is determined by the code stored in +% |\calculate@target@fl@column|. +% \begin{macrocode} + \calculate@target@fl@column +% \end{macrocode} +% |\calculate@target@fl@column| returns its calculated column +% number in |\count@|. +% \begin{macrocode} + \global\expandafter\let\expandafter\saved@fl@ + \csname fl@\the\count@ @\this@class\endcsname + \global\expandafter\let + \csname fl@\the\count@ @\this@class\endcsname + \this@sequence@number +%<*trace> + \tr@ce{~fl@\the\count@ @\this@class\space <-~ + \csname fl@\the\count@ @\this@class\endcsname} +%</trace> +% \end{macrocode} +% If we are adding to a top area we also have to update the +% corresponding |tfl@| commands: +% \begin{macrocode} + \if t\this@area@type + \global\expandafter\let\expandafter\saved@tfl@ + \csname tfl@\the\count@ @\this@class\endcsname + \global\expandafter\let + \csname tfl@\the\count@ @\this@class\endcsname + \this@sequence@number +%<*trace> + \tr@ce{~tfl@\the\count@ @\this@class\space <-~ + \csname tfl@\the\count@ @\this@class\endcsname} +%</trace> + \fi + \fi +% \end{macrocode} +% +% If we have seen any flush points during collection we need to +% save their current |min@col| positions in case we have to throw +% away the current trial. +% \begin{macrocode} + \if@flushseen + \count@\z@ + \@whilenum \flush@seq@num>\count@ \do + { \advance\count@\@ne + \global\expandafter\let + \csname saved@flush@min@col@\the\count@ \expandafter\endcsname + \csname flush@min@col@\the\count@\endcsname +%<*trace> + \tr@ce{saved@flush@min@col@\the\count@ \space <-~ + \csname flush@min@col@\the\count@\endcsname} +%</trace> + } + \fi +% \end{macrocode} +% +% \begin{macrocode} + \initialise@footins@action +% \end{macrocode} +% +% \begin{macrocode} + \global\output{\grab@column@or} + \grab@column@loop +% \end{macrocode} +% +% \begin{macrocode} +%<*trace> + \@tracepop{setup@grab@column@or} +%</trace> +} +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\calculate@target@fl@column} +% \begin{macro}{\calculate@target@fl@column@flexible} +% \begin{macro}{\calculate@target@fl@column@strict} +% The purpose of |\calculate@target@fl@column| is to calculate +% the column number for which the |\fl@|\meta{col}|@number| has to +% be updated in case we place the current float into the area with +% start column |\this@area@col@number| and span-number +% |\this@area@span@number|. It returns the calculated number in +% |\count@|. +% +% For non-spanning floats it is simply returning +% |\this@area@col@number|. If we return this value also in case of +% spanning floats then this means that we claim that the float has +% be placed the first of its spanned columns. Alternatively we +% could return the last of the spanned columns which would if the +% |column| policy is in force, allow to place a float into |t12| +% even if its call-out is in the second column. +% +% The real value for |\calculate@target@fl@column| will be assigned +% in the page setup template. +% \begin{macrocode} +\let\calculate@target@fl@column \ERROR +% \end{macrocode} +% +% And here are the two possibilities. +% \begin{macrocode} +\def\calculate@target@fl@column@flexible { + \count@\this@area@col@number\relax + \advance\count@\this@area@span@number\relax + \advance\count@\m@ne +} +% \end{macrocode} +% +% \begin{macrocode} +\def\calculate@target@fl@column@strict { + \count@\this@area@col@number\relax +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\ifrun@with@floats} +% \begin{macro}{\run@with@floatstrue} +% \begin{macro}{\run@with@floatsfalse} +% +% \begin{macrocode} +\newif\ifrun@with@floats +\def\run@with@floatsfalse{\global\let\ifrun@with@floats\iffalse} +\def\run@with@floatstrue{\global\let\ifrun@with@floats\iftrue} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% +% \begin{macro}{\grab@column@loop} +% The |\grab@column@or| output routine is responsible for +% constructing one column of a layout trial. The loop command +% increments the column count and sets vsize to the target height +% for the current column (which has already been set based on the +% size and position of the floats in this trial layout. +% \begin{macrocode} +\def\grab@column@loop{ +%<*trace> + \@tracepush{grab@column@loop} +%</trace> + \global\advance\curr@col@count\@ne + \global\vsize\csname col@ht@ \the\curr@col@count\endcsname +%<*trace> + \@tracepop{grab@column@loop} +%</trace> +} +% \end{macrocode} +% \end{macro} +% +% +% +% +% +% +% \begin{macro}{\some@column@or} +% |\grab@column@or| and |\best@column@or| are sharing most of their +% code which is therefore placed into a separate macro. At the +% moment it takes 4 arguments: the name (``grab'' or ``best''), +% what to do when we actually finish the column +% (``|\grab@column@or@finish|'' or ``|\best@column@or@finish|''), +% what to do for a flush point, and what to do when we encounter a +% here float.\footnote{This code needs a bit of redesign to deal +% properly with the case that we have stumbled upon one of the +% special penalties. In this case we need to ensure that we also +% remove the special box after the penalty in case we are at a +% column break. This is not done right now so that in this case we +% will not dicard material at the top of the column properly. FIX!!!!} +% \begin{macrocode} +\def\some@column@or #1#2#3#4{ +%<*trace> + \@tracepush{#1@column@or} + \tr@ce{output~pen:~ \the\outputpenalty} + \tr@ce{#1~ col:~ \the\curr@col@count\space of~ \the\col@count} +%</trace> + \handle@case@of@premature@ending + \handle@case@of@forced@pagebreak +% \end{macrocode} +% If the |\outputpenalty| is |-\output@flush@float@penalty| we +% have reached a float flush point in the galley. +% \begin{macrocode} + \ifnum\outputpenalty=-\output@flush@float@penalty + \gincrement@num\trial@flush@seen@num +%<*trace> + \tr@ce{flush~ point~(\trial@flush@seen@num,~ + affects:~ \csname flush@classes@list@\trial@flush@seen@num\endcsname,~ + mincol:~ \csname flush@min@col@\trial@flush@seen@num\endcsname,~ + lastfloat:~ \csname flush@last@float@\trial@flush@seen@num\endcsname + )~ reached} +%</trace> +% \end{macrocode} +% We then remove the guard box from the output (which is at the end +% of box |\@cclv|. +% \begin{macrocode} + \remove@guard@box@from@cclv +% \end{macrocode} +% If the flush penalty moved to an earlier column than in the last +% trial we end the current column (by calling +% |\#1@column@or@finish|) and reinsert the penalty so that it will +% be seen again if we do the next column. +% \begin{macrocode} + \ifnum\csname flush@min@col@\trial@flush@seen@num\endcsname + > \curr@col@count +%<*trace> + \tr@ce{flush@min@col@\trial@flush@seen@num\space >~ + curr@col@count~ + (\csname flush@min@col@\trial@flush@seen@num\endcsname + \space >~ \the\curr@col@count)~ ->~ ending~ column} +%</trace> + \gdecrement@num\trial@flush@seen@num + \readd@guarded@penalty\output@flush@float@penalty + #2 + \else +% \end{macrocode} +% Otherwise the flush point is in an acceptable position which +% means we ignore it and carry on collecting material for the +% current column. This is done be putting everything back onto the +% MVL except the guard box and the penalty.\footnote{We lose a +% potential break point here (acceptable?) See comments in +% best@column@or!!} +% \begin{macrocode} +%<*trace> + \tr@ce{flush@min@col@\trial@flush@seen@num\space + <=~ curr@col@count~ + (\csname flush@min@col@\trial@flush@seen@num\endcsname + \space <=~ \the\curr@col@count)} +%</trace> +% \end{macrocode} +% What exactly happens here (beside the above) depends on the +% calling macro. +% \begin{macrocode} + #3 + \fi + \else +% \end{macrocode} +% If it was not a flush point we might have a here point to take +% care of. This is more or less like the code above. +% \begin{macrocode} + \ifnum\outputpenalty=-\output@here@float@penalty + \gincrement@num\trial@here@seen@num +%<*trace> + \tr@ce{here~ penalty~(\trial@here@seen@num)~ reached} +%</trace> + \remove@guard@box@from@cclv + \ifnum\csname here@min@col@\trial@here@seen@num\endcsname + > \curr@col@count +%<*trace> + \tr@ce{here@min@col@\trial@here@seen@num\space >~curr@col@count~ + (\csname here@min@col@\trial@here@seen@num\endcsname + \space >~ \the\curr@col@count)~ ->~ ending~ column} +%</trace> + \split@off@last@line + \gdecrement@num\trial@here@seen@num + \readd@guarded@penalty\output@here@float@penalty + #2 + \else + \@tempdima \pagegoal + \advance\@tempdima -\pagetotal + \ifdim \@tempdima < + \csname + here@required@space@\trial@here@seen@num + \endcsname \relax +%<*trace> + \tr@ce{here@required@space@\trial@here@seen@num\space >~ + \pagegoal-\pagetotal \space + (\csname here@required@space@\trial@here@seen@num\endcsname + \space >~ \the\pagegoal\space + -~ \the\pagetotal\space =~ + \the\@tempdima)~ + ->~ ending~ column} +%</trace> + \split@off@last@line + \gdecrement@num\trial@here@seen@num + \readd@guarded@penalty\output@here@float@penalty + #2 + \else +%<*trace> + \tr@ce{here@required@space@\trial@here@seen@num\space <=~ + \pagegoal-\pagetotal \space + (\csname here@required@space@\trial@here@seen@num\endcsname + \space <=~ \the\pagegoal\space + -~ \the\pagetotal\space =~ + \the\@tempdima)~ + ->~ accepting~ here~ point} +%</trace> + \@reinserts + \unvbox\@cclv + \@next\@currbox\@herelist{ +%<*trace> + \tr@ce{@currbox:~ \@currbox} +%</trace> + \expandafter\update@here@float@structure\the\toks\@currbox +% \end{macrocode} +% Different things need to be done depending on the type of the +% here point: +% \begin{macrocode} + \def\@tempa{mpar} + \ifx\@tempa\here@type + \typeset@a@marginpar + \else + \def\@tempa{rspace} + \ifx\@tempa\here@type + % do nothing + \else + #4 + \fi + \fi + } +% \end{macrocode} +% If there is no here object left the algorithm has screwed up +% (i.e., a ``this can't happen'' situation). +% \begin{macrocode} + \ERROR + \fi + \fi + \else +% \end{macrocode} +% If it is neither a flush nor a here point it might be a grid point: +% \begin{macrocode} + \ifnum\outputpenalty=-\output@grid@align@penalty + \align@collected@galley@and@restart +% \end{macrocode} +% So we now know that it wasn't one of our special points so this +% must have been a normal end of the galley: +% \begin{macrocode} + \else + #2 + \fi + \fi + \fi +%<*trace> + \@tracepop{#1@column@or} +%</trace> +} +% \end{macrocode} +% \end{macro} +% +% +% +% +% \begin{macro}{\grab@column@or} +% Here is the output routine used during trials, an instantiation +% of |\some@column@or|. +% \begin{macrocode} +\def\grab@column@or{\some@column@or{grab} + \grab@column@or@finish + \grab@column@or@flushcheck + \check@and@typeset@a@here@float +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\grab@column@or@flushcheck} +% +% The |\grab@column@or@flushcheck| code checks for restrictions +% regarding the placement of the current float. It is called when +% we just have encountered a flush float penalty while grabbing the +% text for a column and now have to see which floats (if any) need +% to be positioned before that flush point. +% \begin{macrocode} +\def\grab@column@or@flushcheck{ +%<*trace> + \@tracepush{grab@column@or@flushcheck} +%</trace> +% \end{macrocode} +% If we are making a dry-run without floats then there is no need to +% do much, so we skip all testing that involves flush points and +% only do the cleanup actions at the end. +% \begin{macrocode} + \ifrun@with@floats + \expandafter\xin@\expandafter\this@class + \csname flush@classes@list@\trial@flush@seen@num\endcsname + \ifin@ +%<*trace> + \tr@ce{flush:~ class~ \this@class\space in~ + {\csname flush@classes@list@\trial@flush@seen@num\endcsname}} +%</trace> +% \end{macrocode} +% We store in |\count@| the float sequence number of the last float +% that would be affected by the current flush penalty. This value +% is then used in the tests below. +% \begin{macrocode} + \count@\csname flush@last@float@\trial@flush@seen@num\endcsname\relax +% \end{macrocode} +% +% If the current float number is higher than float number stored in +% |\flush@last@float@|\meta{num} with the flush penalty, we are +% dealing with a float whose call-out is after the flush penalty +% and thus we have no restriction. +% \begin{macrocode} + \ifnum\this@sequence@number>\count@ +%<*trace> + \tr@ce{???:\this@sequence@number>\the\count@} + \tr@ce{this~float~ past~flush~point} +%</trace> + \else +% \end{macrocode} +% Otherwise check if this float is placed in an acceptable position +% with respect to the current flush point. For this we run +% different code depending on the ``fuzziness'' of the flush point +% under check: +% \begin{macrocode} + \csname flush@fuzziness@\trial@flush@seen@num \endcsname + \fi +%<*trace> + \else + \tr@ce{flush:~ class~ \this@class\space not~ in~ + {\csname flush@classes@list@\trial@flush@seen@num\endcsname}} +%</trace> + \fi + \fi +% \end{macrocode} +% If we failed above we additionally record that the failure is +% due to violating restrictions for a flush point. +% \begin{macrocode} + \if@fail + \@flushfailtrue +% \end{macrocode} +% +% \begin{macrocode} + \global\setbox\@cclv\box\voidb@x + \global\setbox\footins\box\voidb@x +% \end{macrocode} +% We have to immediately abort the current trial otherwise a +% flush point following in the galley might be encountered and +% processed before we reach |\evaluate@results@of@trial|. That +% would result in updating the wrong data structure there (due to +% the fact that there it assumes that |\trial@flush@seen@num| +% refers to the flush point that is the reason for +% failure).\footnote{Implementation could be improved!} +% \begin{macrocode} + \global\curr@col@count\col@count + \grab@column@or@finish + \else +% \end{macrocode} +% If we haven't failed we might have to update the +% |\flush@min@col|\meta{num} for the current flush point in case it +% moved to a new column. +% \begin{macrocode} + \ifnum\csname flush@min@col@\trial@flush@seen@num\endcsname<\curr@col@count + \expandafter\xdef + \csname flush@min@col@\trial@flush@seen@num\endcsname + {\the\curr@col@count} +%<*trace> + \tr@ce{set~ flush@min@col@\trial@flush@seen@num:~ + \csname flush@min@col@\trial@flush@seen@num\endcsname} +%</trace> + \fi +% \end{macrocode} +% We have to return the collected footnotes first or else \TeX{} +% might decide that it is better to break before +% them.\footnote{Quite likely that this needs some refinement as it +% might mess up vertical spacing in other respects. Look out for +% other places where \texttt{\string\@reinserts} is used, if this +% needs fixing.} +% \begin{macrocode} + \@reinserts + \unvbox\@cclv +% \end{macrocode} +% What penalty to return???\footnote{FIX!!!} +% \begin{macrocode} +% \penalty\z@ % none i think now (in the current version) but this + % will change again + \fi +%<*trace> + \@tracepop{grab@column@or@flushcheck} +%</trace> +} +% \end{macrocode} +% \end{macro} +% +% +% +% +% +% \begin{macro}{\flushcheck@page} +% \begin{macrocode} +\def\flushcheck@page { +%<*trace> + \tr@ce{OK:~flush~check~ (same~page)} +%</trace> +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\flushcheck@spread} +% +% This is actually a dummy definition. There is more to do if we +% want to provide support for spreads!\footnote{Finish implementation} +% \begin{macrocode} +\def\flushcheck@spread { +%<*trace> + \tr@ce{OK:~flush~check~ (using~page~not~ spread)} +%</trace> +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\flushcheck@strict} +% \begin{macrocode} +\def\flushcheck@strict { +%<*trace> + \@tracepush{flushcheck@strict} +%</trace> +% \end{macrocode} +% If strict flushing is required we look where the current float is +% being placed. If it +% is placed in a column which is earlier than the current column +% then it is definitely before the flush point and thus we are okay. +% \begin{macrocode} + \ifnum\this@area@col@number<\curr@col@count +%<*trace> + \tr@ce{OK:~flush~check~ + (\this@area@col@number<\the\curr@col@count,~\this@area)} +%</trace> + \else +% \end{macrocode} +% Otherwise we test if the float is placed into the current +% column. If this is the case it might be okay, but only if it is +% not placed into the bottom area. +% \begin{macrocode} + \ifnum\this@area@col@number=\curr@col@count +% \end{macrocode} +% To test for the bottom area(s) means looking at the first token +% in the area identifier. If it is |b| we are past the flush +% point.\footnote{It might be an interesting extension to allow +% relaxing the flush situation to allow the floats to appear +% anywhere on the current column (on which the flush point ends up), +% or even allowing that it only has to appear on the current page +% or page spread.} +% \begin{macrocode} + \if b \this@area@type + \@failtrue +%<*progress> + \progress@failed{area~ below~ flush~ point~ + (\this@area@col@number=\the\curr@col@count,~\this@area)} +%</progress> +%<*trace> + \tr@ce{Fail:~flush~check~ + (\this@area@col@number=\the\curr@col@count,~\this@area)} +% \end{macrocode} +% Otherwise the float was placed into an area that is still before +% the flush point. +% \begin{macrocode} + \else + \tr@ce{OK:~flush~check~ + (\this@area@col@number=\the\curr@col@count,~\this@area)} +%</trace> + \fi +% \end{macrocode} +% If the float was neither placed before nor into the current +% column we have to conclude that it was placed into a later column +% which means it was placed after the flush point --- thus we fail. +% \begin{macrocode} + \else + \@failtrue +%<*progress> + \progress@failed{area~ after~ flush~ point~ + (\this@area@col@number>\the\curr@col@count,~\this@area)} +%</progress> +%<*trace> + \tr@ce{Fail:~flush~check~ + (\this@area@col@number>\the\curr@col@count,~\this@area)} +%</trace> + \fi + \fi +%<*trace> + \@tracepop{flushcheck@strict} +%</trace> +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\flushcheck@column} +% \begin{macrocode} +\def\flushcheck@column { + \ifnum\this@area@col@number>\curr@col@count + \@failtrue +%<*progress> + \progress@failed{area~ after~ flush~ point~ column~ + (\this@area@col@number>\the\curr@col@count,~\this@area)} +%</progress> +%<*trace> + \tr@ce{Fail:~flush~check~ + (\this@area@col@number>\the\curr@col@count,~\this@area)} + \else + \tr@ce{OK:~flush~check~ + (\this@area@col@number<=\the\curr@col@count,~\this@area)} +%</trace> + \fi +} +% \end{macrocode} +% \end{macro} +% +% +% +% +% \begin{macro}{\grab@column@or@finish} +% \begin{macrocode} +\def\grab@column@or@finish{ +%<*trace> + \@tracepush{grab@column@or@finish} +%</trace> +% \end{macrocode} +% +% \begin{macrocode} + \mark@update@structure +% \end{macrocode} +% +% \begin{macrocode} + \deal@with@footins@action +% \end{macrocode} +% +% First check if there are some special constraints that should be +% met (this is, for example, used to check if there are both bottom +% floats and footnotes). If the constraints are not met don't +% bother to check the callout/float constraints. +% \begin{macrocode} + \if@fail\else + \ifrun@with@floats + \check@some@constraints + \fi + \fi + \if@fail\else +% \end{macrocode} +% For each float sequence class, call |\check@callout@constraints| +% this will be set via a call to a pagesetup template to do an +% appropriate check on the float placement relative to float +% call-out. +% \begin{macrocode} + \ifrun@with@floats + \let\@elt\check@callout@constraints + \float@classes@list + \fi + \fi +% \end{macrocode} +% +% Throw the text away (it will be reset later if this trial is +% in fact chosen). +% \begin{macrocode} + \global\setbox\@cclv\box\voidb@x + \global\setbox\footins\box\voidb@x +% \end{macrocode} +% After the last column we evaluate the results of the trial (and +% if the result looks ok remember it as a candidate for the final +% solution). We then switch to the `clean up' OR which will +% collect up the main vertical list as far as the special penalty +% marking the end of the collection pass, to clear the MVL for the +% next trial. If this isn't the last column, set up the next +% column. +% \begin{macrocode} + \ifnum\curr@col@count=\col@count + \evaluate@results@of@trial + \setup@cleanup@or + \else + \grab@column@loop + \fi +%<*trace> + \@tracepop{grab@column@or@finish} +%</trace> +} +% \end{macrocode} +% \end{macro} +% +% +% +% +% \begin{macro}{\handle@case@of@premature@ending} +% Next |\ifnum| is a fix that needs rethinking: what is the best +% approach if we hit the penalty which denotes the end of the +% collected galley too early, e.g., in the middle of a trial using +% |\grab@column@or| or when producing the final columns with +% |\best@column@or|? Current solution gets the stuff out, but is it +% probably not the best solution. +% correct? +% \begin{macrocode} +\def\handle@case@of@premature@ending{ + \ifnum\outputpenalty=-\output@collect@penalty + \remove@guard@box@from@cclv + \readd@guarded@penalty\output@collect@penalty + \fi +} +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\check@some@constraints} +% By default there are no additional constraints to check for. +% \begin{macrocode} +\let\check@some@constraints\relax +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\evaluate@results@of@trial} +% +% The purpose of |\evaluate@results@of@trial| is to determine if +% the current trial is a potential candiate for the final solution +% and if so store it away. We can determine if the trial failed by +% looking at the switch |@fail|. +% \begin{macrocode} +\def\evaluate@results@of@trial{ +%<*trace> + \@tracepush{evaluate@results@of@trial} +%</trace> +% \end{macrocode} +% +% \begin{macrocode} + \ifrun@with@floats + \ifx\try@this@area\std@try@this@area + \count@\trial@here@seen@num\relax + \advance\count@\page@float@count + \ifnum \pagesetup@max@float@num < \count@ +%<*trace> + \tr@ce{Failed:~ area~ +~ here~ floats~ exceed~ max~ floats} +%</trace> +%<*progress> + \progress@failed{area~ +~ here~ floats~ exceed~ max~ floats} +%</progress> + \@failtrue + \fi + \fi + \fi +% \end{macrocode} +% +% \begin{macrocode} + \if@fail +%<*trace> + \tr@ce{fail:~true} +%</trace> +% \end{macrocode} +% If the trial has failed we have to distinguish two cases: +% \begin{itemize} +% \item +% There has been a request for flushing out floats up to a +% certain float somewhere +% and the current float belongs to the list of floats to flush. +% \item +% There has been no such request. +% \end{itemize} +% +% If there have been flush points we need to restore their +% |min@col| values since we might have updated them. +% \begin{macrocode} + \if@flushseen + \count@\z@ + \@whilenum \flush@seq@num>\count@ \do + { \advance\count@\@ne + \global\expandafter\let + \csname flush@min@col@\the\count@ \expandafter\endcsname + \csname saved@flush@min@col@\the\count@\endcsname +%<*trace> + \tr@ce{flush@min@col@\the\count@ \space <-~ + \csname flush@min@col@\the\count@\endcsname \space + (restore) } +%</trace> + } + \fi + + \if@flushfail +%<*trace> + \tr@ce{flushfail:~true} +%</trace> +% \end{macrocode} +% If we have failed and |\try@this@area| is already the ``relaxed'' +% version we have to artificially move the offending flush point to +% the next column and hope that this way we get ourselves some new +% options (worst case is that eventually the flush point is removed +% from the page in which case we can as a last resort defer the +% float). +% \begin{macrocode} + \ifx\try@this@area\relaxed@try@this@area + + \expandafter\gincrement@num + \csname flush@min@col@\trial@flush@seen@num\endcsname +%<*trace> + \tr@ce{flush@min@col@\trial@flush@seen@num~ <-~ + \csname flush@min@col@\trial@flush@seen@num\endcsname} +%</trace> +%<*progress> + \progress@failed{flush~ point~ \trial@flush@seen@num\space + moved~ to~ column~ + \csname flush@min@col@\trial@flush@seen@num\endcsname} +%</progress> + \else + + \ifx\saved@this@open@areas\@empty +%<*debug> + \tr@ce{saved@this@open@areas:~empty ????????} +%</debug> + \ERROR + \else + \global\let\this@open@areas\saved@this@open@areas +%<*trace> + \tr@ce{~this@open@areas~ <-~ \this@open@areas \space (reopen)} +%</trace> + \fi + \relax@float@placement@conditions + \fi + \else +%<*trace> + \tr@ce{flushfail:~false} +%</trace> + \xdef\this@open@areas{\expandafter\@gobblethree\this@open@areas} + \fi + +%<*trace> + \tr@ce{open:~\this@open@areas} + + \tr@ce{restore:~last~allocated:~\saved@fl@} +%</trace> +% \end{macrocode} +% To restore the previous state we have to recalculate the target +% |fl@| column. +% \begin{macrocode} + \calculate@target@fl@column + \global\expandafter\let + \csname fl@\the\count@ @\this@class\endcsname + \saved@fl@ +%<*trace> + \tr@ce{~fl@\the\count@ @\this@class\space <-~ + \saved@fl@ \space (restored)} +%</trace> +% \end{macrocode} +% And if we tried a top area we also have to restored the +% corresponding |tfl@| macro. +% \begin{macrocode} + \if t\this@area@type + \global\expandafter\let + \csname tfl@\the\count@ @\this@class\endcsname + \saved@tfl@ +%<*trace> + \tr@ce{~tfl@\the\count@ @\this@class\space <-~ + \saved@tfl@ \space (restored)} +%</trace> + \fi +% \end{macrocode} +% And we better don't forget to restore the heights.\footnote{This +% is most likely buggy: I seem to restore all column values but i think +% i don't save all of them! FIX!!!!} +% \begin{macrocode} + \update@this@area@columns + { +%<*trace> + \tr@ce{restore:~saved@col@ht@ \the\count@:~ + \csname saved@col@ht@ \the\count@\endcsname} +%</trace> + \global\csname col@ht@ \the\count@\endcsname + \csname saved@col@ht@ \the\count@\endcsname\relax + \global\expandafter\let + \csname col@ \this@area@type @delta@ \the\count@ + \expandafter \endcsname + \csname saved@col@ \this@area@type @delta@ \the\count@ \endcsname +%<*trace> + \tr@ce{GRID (delta):~ column~\the\count@\this@area@type:~ + \csname saved@col@ \this@area@type @delta@ \the\count@ + \endcsname\space (restore) } +%</trace> + } + \else +%<*trace> + \tr@ce{fail:~false} +%</trace> +% \end{macrocode} +% +% \begin{macrocode} +%<*progress> + \let\progress@inform@later\@empty +%</progress> +% \end{macrocode} +% If this trial is valid and we haven't seen all flush penalties +% again we must have pushed them to the next page. We record +% this fact by setting |flush@min@col@...| to |\maxdimen|. +% \begin{macrocode} + \if@flushseen + \count@\flush@seq@num\relax + \loop + \ifnum \trial@flush@seen@num < \count@ + \global\@namedef{flush@min@col@\the\count@}{\maxdimen} +%<*trace> + \tr@ce{flush@min@col@\the\count@\space <-~ maxdimen} +%</trace> + \advance\count@\m@ne + \repeat +% \end{macrocode} +% If there has been a flush point (ie if |\trial@flush@seen@num| und +% thus |\count@| is greater than 0) we test whether or not the +% float recently placed was the last one affected by the last flush +% point on the current page and if so tighten the float placement +% setting again.\footnote{correct logic?} +% \begin{macrocode} +%<*progress> + \let\progress@inform@later\@empty +%</progress> + \ifrun@with@floats + \ifnum \count@ > \z@ + \ifnum \csname flush@last@float@\trial@flush@seen@num\endcsname = + \this@sequence@number \relax +%<*trace> + \tr@ce{flush:~ last~float~affected~ by~ flush~ point~ + \trial@flush@seen@num\space placed~ ->~ + use~ partly~ normal~ placement~ conditions~ again} +%</trace> +%<*progress> + \def\progress@inform@later{ + \progress@nl{->~ past~ flush~ point:~ -->~ + tighten~ conditions~ again} + \progress@nl{} + } +%</progress> + \partly@tighten@float@placement@conditions + \fi + \fi + \fi +% \end{macrocode} +% Having placed a float we need to update |\flush@classes@list@max| to +% reflect which float types are affected by the flush points +% currently on the page as this might be needed when trying to +% place or rather defer the next float. +% +% So we loop and concatenate all |\flush@classes@list@|\meta{num} that +% belong to flush points on the current page. This might result in +% the list containing types several times but for the test we need +% to do this doesn't make any difference (and it is far faster than +% unifying the list). +% \begin{macrocode} + \count@\z@ + \global\let\flush@classes@list@max\@empty + \loop + \ifnum \trial@flush@seen@num > \count@ + \advance\count@\@ne + \xdef\flush@classes@list@max{ + \flush@classes@list@max; + \csname flush@classes@list@\the\count@\endcsname + } +%<*trace> + \tr@ce{flush@classes@list@max~ <-~ \flush@classes@list@max} +%</trace> + \repeat + \fi +% \end{macrocode} +% +% With this algorithm a trial which passed so far is always +% considered to be better than previous trials (meaning more floats +% on the page are better). So we always update the best trial data +% (unless this was the run without adding floats in which case we +% only change the |run@with@floats| switch. +% \begin{macrocode} + \ifrun@with@floats + \update@best@trial +%<*progress> + \progress@inform@later +%</progress> + \else + \run@with@floatstrue + \fi + \fi +%<*trace> + \@tracepop{evaluate@results@of@trial} +%</trace> + } +% \end{macrocode} +% \end{macro} +% +% +% +% +% \subsection{Best Trial Data} +% +% +% \begin{macro}{\best@trial} +% \begin{macrocode} +\let\best@trial\@empty +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\update@best@trial} +% Not all of this belongs into this macro!\footnote{redistribute} +% \begin{macrocode} +\def\update@best@trial{ +%<*trace> + \@tracepush{update@best@trial} +%</trace> +%<*progress> + \progress@nl{->~ accepted} +%</progress> + \global\let\best@trial\@empty + \forall@columns{ + \expandafter + \g@addto@macro\expandafter\best@trial\expandafter + { + \expandafter + \global + \csname col@ht@ \the\curr@col@count\expandafter\endcsname + \the\csname col@ht@ \the\curr@col@count\endcsname + } + } +% \end{macrocode} +% +% Frank says this needs to be documented (the rest of the code is self evident) +% |\this@float@box| is |\let| to |\@currbox| which is defed to a chardefed +% token from newinsert. so this is OK. honest. +% \begin{macrocode} + \expandafter\@cons\csname area@\this@area\expandafter\endcsname + \this@float@box +% \end{macrocode} +% +% \begin{macrocode} +%<*trace> + \tr@ce{this@page@closed~ \this@page@closed\space +~ + "\csname pagesetup@\this@area @all@close\endcsname"} + \tr@ce{this@closed@areas~ \this@closed@areas\space +~ + "\csname pagesetup@\this@area @class@close\endcsname"} +%</trace> + \xdef\this@page@closed{\this@page@closed, + \csname pagesetup@\this@area @all@close\endcsname} + \xdef\this@closed@areas{\this@closed@areas, + \csname pagesetup@\this@area @class@close\endcsname} +% \end{macrocode} +% +% \begin{macrocode} + \global\expandafter\let\csname open@\this@class + @areas\endcsname % FMi tmp + \this@open@areas + \global\expandafter\let\csname closed@\this@class + @areas\endcsname % FMi tmp + \this@closed@areas +% \end{macrocode} +% moving the captioned float to the main float box is put into a +% separate macro so that we can suppress this in cases where we +% potentially want to revert to a previous stage.\footnote{FIX} +% \begin{macrocode} +%<*obsolete> + \add@caption@to@float@box +%</obsolete> +% \end{macrocode} +% +% \begin{macrocode} + \global\advance\page@float@count\@ne + \global\advance\csname \this@area @float@count\endcsname\@ne +% \end{macrocode} +% +% Since the trial was successful, we have to update the the macros +% that hold the number of top or bottom floats we have seen so far +% in each column.\footnote{Code for this is similar to the one in +% construct@and@test@col@ht and elsewhere; perhaps there should be +% a subroutine for it!} +% \begin{macrocode} + \update@this@area@columns + { + \expandafter + \gincrement@num + \csname col@ \this@area@type + @floats@ \the\count@ @number\endcsname +%<*trace> + \tr@ce{col@ \this@area@type + @floats@ \the\count@ @number <-~ + \csname col@ \this@area@type + @floats@ \the\count@ @number\endcsname} +%</trace> + } +% \end{macrocode} +% +% \begin{macrocode} +%<*trace> + \tr@ce{\meaning\best@trial} + \tr@ce{area:~\this@area\space\csname area@\this@area\endcsname} + \@tracepop{update@best@trial} +%</trace> +} +% \end{macrocode} +% \end{macro} +% + +% \begin{macro}{\add@caption@to@float@box} +% This is a hook really to be able to prevent moving the caption +% back into |\this@float@box| (by making this macro |\relax| and +% this is what happens later on in xo-final). Yes we know the +% coding here needs changing!\footnote{David FIX!!!} +% \begin{macrocode} +%<*obsolete> +\def\add@caption@to@float@box{ + \global\setbox\this@float@box\box\this@captioned@float +} +%</obsolete> +% \end{macrocode} +% \end{macro} +% +% +% \newpage +% +% \subsection{Best Column Output Routine} +% +% \begin{description} +% \item[Entry:] |\setup@best@column@or| +% \item[Exit:] |\setup@collection@or| +% \item[Prereq:] +% \item[Description:] +% \item[Flow:] +%\begin{footnotesize} +%\begin{verbatim} +% \setup@best@column@or +% | +% New OR: \best@column@or +% | +% V +% \best@column@loop <------- +% | +% (when entering OR...) +% | +% <end of collection reached?> +% | | +% yes no +% | | +% | <col break requested?> +% | | | +% | yes no +% | | | +% | | <flush point encountered?> +% | | | | +% | | yes no +% | | | | +% | | <flush point <here point encountered?> +% | | too early?> | | +% | | | | yes no +% | | yes no | | +% | | | | ? ? +% | | | (ignore break) +% | | | | +% | | | | +% | | | | +% | | | | +% | | | | +% | | | | +% | | | | +% | | | | +% | | | | +% (end column now) <------- | +% | | +% V | +% <all cols produced?> | +% | | V +% yes no--------------------> (reenter \best@column@loop) +% | +% (produce final page) +% | +% V +% \initialise@next@page +% | +% V +% (try to make float pages) +% | +% V +% \setup@collection@or +%\end{verbatim} +%\end{footnotesize} +% \end{description} +% +% +% After the best trial is chosen the `best@column@or' output routines +% are executed. Structurally this is similar to the grab column output +% routines used during the trials, but this time information +% about the float placements is recorded in the float area lists +% and also optionally in float placement control files. +% +% \begin{macro}{\setup@best@column@or} +% This is the initialisation code for producing the final best set +% of columns (via the @best@column@or output routine). +% \begin{macrocode} +\def\setup@best@column@or{ +%<*trace> + \@tracepush{setup@best@column@or} +% Elsewhere now: +% \tr@ce{reinsert~penalty:~ \saved@outputpenalty\space (unless~ 10000)} +%</trace> +% \penalty +% \ifnum\saved@outputpenalty=\@M +% \z@ +% \else +% \saved@outputpenalty\relax +% \fi + \global\curr@col@count\z@ + \gdef\trial@flush@seen@num{0} + \gdef\trial@here@seen@num{0} + \perhaps@write@placements@to@fpl@file + \best@trial +% \end{macrocode} +% +% \begin{macrocode} + \initialise@footins@action +% \end{macrocode} +% +% \begin{macrocode} + \global\output{\best@column@or} + \best@column@loop +%<*trace> + \@tracepop{setup@best@column@or} +%</trace> +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\best@column@loop} +% \begin{macrocode} +\def\best@column@loop{ +%<*trace> + \@tracepush{best@column@loop} +%</trace> + \global\advance\curr@col@count\@ne + \global\vsize\csname col@ht@ \the\curr@col@count\endcsname +%<*trace> + \tr@ce{vsize~ <-~ \the\vsize } + \@tracepop{best@column@loop} +%</trace> +} +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\best@column@or} +% Here is the output routine used when preparing the final columns, +% an instantiation of |\some@column@or|. In contrast to the version +% used for |\grab@column@or| it doesn't do the tests. +% \begin{macrocode} +\def\best@column@or{\some@column@or{best} + \best@column@or@finish + { + \@reinserts + \unvbox\@cclv +% \end{macrocode} +% Next line not okay! we need to add a penalty here but which one? +% Or we need a different mechanism using either |\holdinginserts| +% or a partial box line in collection OR.\footnote{FIX!!! there is +% also another place like this!} +% \begin{macrocode} +% \penalty\z@ %FMi? + } + { + \perhaps@write@to@fpl@file{ + \@spaces Area:~hhh^^J + \expandafter\perhaps@write@placements@to@fpl@file@aux\the\toks\@currbox} + \typeset@a@here@float + } +} +% \end{macrocode} +% \end{macro} +% +% +% +% +% +% +% \begin{macro}{\best@column@or@finish} +% +% \begin{macrocode} +\def\best@column@or@finish{ +%<*trace> + \@tracepush{best@column@or@finish} +%</trace> + \mark@update@structure +% \end{macrocode} +% +% \begin{macrocode} + \deal@with@footins@action +% \end{macrocode} +% +% save all marks here\footnote{not done yet!} +% +% add floats and footnotes etc to collected column +% +% \begin{macrocode} + \produce@final@column +% \end{macrocode} +% +% \begin{macrocode} + \ifnum\curr@col@count=\col@count + \produce@final@page + \initialise@next@page + \try@float@pages + \place@deferred@floats + \setup@collection@or +%{\showoutput\showlists} + \else + \best@column@loop + \fi +%<*trace> + \@tracepop{best@column@or@finish} +%</trace> +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\initialise@next@page} +% Initialises the column heights to text height. Clear the float +% area lists, zero holdinginserts to allow footnote texts to arrive +% in the insertion box. +% \begin{macrocode} +\def\initialise@next@page{ +%<*trace> + \@tracepush{initialise@next@page} +%</trace> +% +% \end{macrocode} +% +% \begin{macrocode} + \initialise@column@data +% \end{macrocode} +% +% \begin{macrocode} + \initialise@areas +% \end{macrocode} +% +% \begin{macrocode} + \global\page@float@count\z@ +% \end{macrocode} +% +% \begin{macrocode} + \initialise@flush@data +% \end{macrocode} +% +% \begin{macrocode} + \initialise@here@data +% \end{macrocode} +% +% \begin{macrocode} + \initialise@footins@action +% \end{macrocode} +% +% Nothing is closed when we are at the start of a page. +% \begin{macrocode} + \global\let\this@page@closed\@empty +% \end{macrocode} +% +% \begin{macrocode} + \let\@elt\initialise@float@class + \float@classes@list + \let\@elt\relax +% +%\showfloatlists +%\show\area@ddd\show\@activelist +% for safety + \global\let\this@float@box\@undefined +%<*trace> + \@tracepop{initialise@next@page} +%</trace> + } +% \end{macrocode} +% \end{macro} +% +% +% +% +% \begin{macro}{\handle@case@of@forced@pagebreak} +% This is related to |\handle@case@of@premature@ending| but we have +% to return the penalty only if we haven't reached the last column. +% If we don't do this we would start collecting material in the +% middle of final page generation! +% \begin{macrocode} +\def \handle@case@of@forced@pagebreak{ + \ifnum\curr@col@count<\col@count + \ifnum\outputpenalty=-\@M + \@emptycol + \fi + \fi + + \ifnum\outputpenalty=-\output@balance@penalty +%<*trace> + \tr@ce{BALANCE:~ end~ point~ seen~ again} +%</trace> + \remove@guard@box@from@cclv + \ifnum\curr@col@count<\col@count + \@emptycol + \fi + \fi +} +% \end{macrocode} +% \end{macro} +% +% +% +% \newpage +% +% \subsection{Cleanup Output Routine} +% +% \begin{description} +% \item[Entry:] |\setup@cleanup@or| +% \item[Exit:] |\float@placement@loop| +% \item[Prereq:] +% \item[Description:] +% Responsible for discarding unused text still on Main Vertical +% List After the end of a trial. It eats everything until it sees +% the special penalty marking the end of the last collection output +% routine. This output routine may need to be called several times +% in succession due to forced penalties in the galley. +% \item[Flow:] +%\begin{footnotesize} +%\begin{verbatim} +% \setup@cleanup@or +% | +% V +% New OR: \cleanup@or +% | +% V +% <special outputpenalty reached?> --> \float@placement@loop +%\end{verbatim} +%\end{footnotesize} +% \end{description} +% +% +% \begin{macro}{\setup@cleanup@or} +% \begin{macrocode} +\def\setup@cleanup@or{ + \global\vsize\maxdimen + \global\output{\cleanup@or} + } +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\cleanup@or} +% In the actual output routine we grab text and throw it away until +% we see the special output penalty. Then we prepare for the trials +% to place the floats properly. +% \begin{macrocode} +\def\cleanup@or{ +%<*trace> + \@tracepush{cleanup@or} + \tr@ce{output~pen:~ \the\outputpenalty} +%</trace> +% \end{macrocode} +% Throw everything away \ldots +% \begin{macrocode} + \global\setbox\@cclv\box\voidb@x + \global\setbox\footins\box\voidb@x +% \end{macrocode} +% \ldots\ until we see the special output penalty again. +% \begin{macrocode} + \ifnum\outputpenalty=-\output@collect@penalty + \float@placement@loop + \fi +%<*trace> + \@tracepop{cleanup@or} +%</trace> +} +% \end{macrocode} +% \end{macro} +% +% +% \newpage +% +% \subsection{Making float pages} +% +% +% \begin{description} +% \item[Entry:] |\try@float@pages| +% \item[Exit:] --- (this happens within the OR)\\ +% On exit |\area@ddd| will be empty and the floats not being put +% onto float pages are moved to |\@activelist| (those that have +% their call outs on previous pages) and |\@mvllist| (those that +% have their call outs still on the MVL). +% \item[Prereq:] |\area@ddd| contains the float to work on; all other +% areas are empty. +% \item[Description:] +% \item[Flow:] +%\begin{footnotesize} +%\begin{verbatim} +% \try@float@pages +% | +% V +% <\area@ddd has floats?> +% | | +% ----no yes +% | | +% | V +% | (split \area@ddd into \@activelist and \@mvllist; +% | setup trial conditions) +% | | +% | V +% | \try@float@page <------------- +% | | | +% | <float page produced?> | +% | | | | +% | no yes | +% | | | | +% | | (output page) | +% | | | | +% | | (move new \area@ddd | +% | | to \@activelist) | +% | | | | +% | | ------------------ +% | | +% | | +% | (restore float conditions before last trial) +% | | +% | (restore trial condition to normal) +% | | +% ------------->| +% | +% V +%\end{verbatim} +%\end{footnotesize} +% \end{description} +% +% +% +% \begin{macro}{\try@float@pages} +% +% \begin{macrocode} +\def\try@float@pages { +%<*trace> + \@tracepush{try@float@pages} +%</trace> + \ifx\area@ddd\@empty +%<*trace> + \tr@ce{no~ deferred~ floats} +%</trace> + \else + \global\let\@activelist@empty@action\relax + \global\let\pretests@success@action\floatpage@pretests@success@action +% \end{macrocode} +% this is only a tmp: we just use |\relaxed@try@this@area| but of +% course there should be different rules for float pages (and +% different float areas and \ldots) +% \begin{macrocode} + \global\let\try@this@area\relaxed@try@this@area +% \end{macrocode} +% +% First thing to do is to split the list of deferred floats into +% those that have ther callouts already typeset (on previous pages) +% and those that we have only seen because we looked a bit +% ahead. For making float pages we can only use the former. +% \begin{macrocode} + \let\@elt\split@defer@list + \area@ddd + \let\@elt\relax + \global\let\area@ddd\@empty +% \end{macrocode} +% Now we loop until we fail to make float pages. The actual work is +% done in the macro |\try@float@page|. +% \begin{macrocode} + \@floatpagetrue + \loop + \if@floatpage + \begingroup % no nesting of \loop without grouping ... +% \end{macrocode} +% Next line prevents adding the caption to the float box. Of course +% the float page does come out even worse this way, but we don't +% get multiple captions if float page generation +% fails.\footnote{FIX by redesigning caption handling!} +% \begin{macrocode} +%<*obsolete> + \let\add@caption@to@float@box\relax %tmp!! +%</obsolete> +% \end{macrocode} +% +% A bit statistics: how many floats do we have on the +% |\@activelist|? +% \begin{macrocode} +%<*progress> + \def\@elt{\global\advance\trial@count\@ne\@gobble} + \@activelist + \let\@elt\relax + \progress@nl{} + \progress@separator + \progress@nl{STATS:~ floats~ waiting~ =~ \the\trial@count + \space on~ page~ \the\absolute@page@number\space (float~ page)} + \progress@separator + \global\trial@count\z@ +%</progress> +% \end{macrocode} +% \begin{macrocode} + \try@float@page + \endgroup + \repeat +% \end{macrocode} +% Once we are finished we have to return to normal trial +% conditions, so\ldots +% \begin{macrocode} + \global\let\try@this@area\std@try@this@area + \fi +%<*trace> + \@tracepop{try@float@pages} +%</trace> +} +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\try@float@page} +% This macro tries to build a single float page from the floats in +% |\@activelist|. If it fails it (tries to) restores the state of +% the floats. If it succeeds it will output a float page and returns. +% \begin{macrocode} +\def\try@float@page { +%<*trace> + \@tracepush{try@float@page} +%</trace> +% \end{macrocode} +% Save the current state in case of failure then run the float +% placement loop (setup for this loop should have happened +% earlier). +% \begin{macrocode} + \save@current@float@state + \trial@inner@loop +% +%\typeout{float.list.after.trial} +%\showfloatlists +% +% \end{macrocode} +% Loop through all ``text columns'' and add up their heights. This +% is again only done to have some sort of measure for float pages +% and should be removed once some real code gets into this part. +% \begin{macrocode} + \dimen@\z@ + \forall@columns{ +%<*trace> + \tr@ce{\ht\the\curr@col@count=\the \csname + col@ht@ \the\curr@col@count \endcsname} +%</trace> + \advance\dimen@ \csname + col@ht@ \the\curr@col@count \endcsname + } +% \end{macrocode} +% +% If the sum of all white space is more than 300pt :-) +% \begin{macrocode} + \ifdim \dimen@ > 300pt \relax +% \end{macrocode} +% we fail +% \begin{macrocode} + \@floatpagefalse +%<*trace> + \tr@ce{float~page~failed} +%</trace> +%<*progress> + \progress@failed{no~ float~ page~ made} + \progress@nl{} +%</progress> +% \end{macrocode} +% Return to the previous state (and as can be seen by using +% |\initialise@next@page|) this needs some work; the latter might +% in fact do too much like calling +% |\initialise@flush@num|!\footnote{FIX} +% \begin{macrocode} + \saved@float@state +% \end{macrocode} +% To avoid having |\initialise@flush@num| do anything harmful we +% set |\trial@flush@seen@num| to zero at this point.\footnote{This +% needs fixing properly!} And the same is necessary for +% |\initialise@here@num|. +% \begin{macrocode} + \gdef\trial@flush@seen@num{0} + \gdef\trial@here@seen@num{0} + \initialise@next@page + \else +% \end{macrocode} +% Otherwise we claim we have a good float page. +% \begin{macrocode} +%<*trace> + \tr@ce{float~page~succeeded} + \tr@ce{We~ better~ output~ something~ now~ ...} +%</trace> +%<*progress> + \progress@nl{succeeded} + \progress@nl{} +%</progress> +% \end{macrocode} +% producing this page is rubbish as well but it can't be written +% before we have parameters and rules for making float pages. +% \begin{macrocode} + \forall@columns{ + \global\setbox\csname col@box@\the\curr@col@count\endcsname + \vbox to \csname col@ht@ \the\curr@col@count\endcsname{} + \produce@final@column + } + \perhaps@write@placements@to@fpl@file + \produce@final@page + \initialise@next@page +% \end{macrocode} +% But the final lines are for real: if we did succeed we need to +% provide a new |\@activelist| for the next potential float page. +% It should be the floats we deferred while trying to make the +% current float page followed by the floats that are still on the +% active list (i.e., those we haven't even tried for the current +% page). +% \begin{macrocode} + \xdef\@activelist{\area@ddd\@activelist} + \global\let\area@ddd\@empty + \fi +% +%\typeout{float.list.after.shipout.float.page.or.fail} +%\showfloatlists +% +%<*trace> + \@tracepop{try@float@page} +%</trace> +} +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\if@floatpage} +% \begin{macro}{\@floatpagefalse} +% \begin{macro}{\@floatpagetrue} +% Switch which is set to true while we are in the process of making +% float pages and haven't failed. +% \begin{macrocode} +\newif\if@floatpage +\def\@floatpagefalse{\global\let\if@floatpage\iffalse} +\def\@floatpagetrue{\global\let\if@floatpage\iftrue} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% +% \begin{macro}{\save@current@float@state} +% +% Save the current state of affairs concerning +% floats\footnote{Needs more work, there are now other data +% structures that should be saved if this is every going to be of +% much use. (its current usage actually could be achieved with +% simpler means). FIX or fold!}. In case of failure return to +% this state by executing |\saved@float@state|. +% \begin{macrocode} +\def\save@current@float@state { +%<*trace> + \@tracepush{save@current@float@state} +%</trace> + \xdef\saved@float@state{\gdef\noexpand\@activelist{\@activelist}} + \forall@columns { + \expandafter + \g@addto@macro + \expandafter \saved@float@state + \expandafter { \expandafter \global + \csname col@ht@ \the\curr@col@count\expandafter\endcsname + \the \csname col@ht@ \the\curr@col@count\endcsname +% \end{macrocode} +% No final |\relax| needed since this is followed by area data. And +% if there are no areas we wouldn't call this code, would we? +% \begin{macrocode} + } + } +% \end{macrocode} +% Save current state of all used float areas by looping though them. +% \begin{macrocode} + \expandafter\save@area@info\used@areas ddd\relax\relax\relax +%<*trace> + \tr@ce{saved:~ \meaning\saved@float@state} + \@tracepop{save@current@float@state} +%</trace> +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\save@area@info} +% Save information about area and recourse. +% \begin{macrocode} +\def\save@area@info#1#2#3{ + \ifx#1\relax + \else + \edef\@tempa { + \global\csname #1#2#3@float@count\endcsname + \the\csname #1#2#3@float@count\endcsname +% \end{macrocode} +% No |\relax| needed since followed by a |\gdef|. +% \begin{macrocode} + \gdef \expandafter\noexpand \csname area@#1#2#3\endcsname + {\csname area@#1#2#3\endcsname} + } + \expandafter + \g@addto@macro + \expandafter \saved@float@state + \expandafter { \@tempa } + + \expandafter\save@area@info + \fi} +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\saved@float@state} +% To return to the saved float state execute |\saved@float@state|. +% \begin{macrocode} +\let\saved@float@state\@empty +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\split@defer@list} +% +% Split |\area@ddd| list, moving those floats whose callouts have +% been typeset to |\@activelist| for consideration for (one day) +% float pages, and for allocating to text page float areas. +% +% Floats whose callouts are still on MVL are placed on |\@mvllist|. +% \begin{macrocode} +\def\split@defer@list #1 { + \def\@currbox{#1} + \expandafter\extract@this@float@actual@structure\the\toks #1 +%<*trace> + \tr@ce { #1:~\LastMark{\this@class}~ ???~\this@sequence@number } +%</trace> + \ifnum 0\LastMark{\this@class} < \this@sequence@number +%<*trace> + \tr@ce {#1:~ not~ really~ defered } +%</trace> + \@cons \@mvllist #1 + \else +%<*trace> + \tr@ce {#1:~ callout~ has~ been~ typeset} +%</trace> + \@cons \@activelist #1 + \fi +} +% \end{macrocode} +% \end{macro} +% +% +% +% +% +% \subsection{Preassign deferred floats} +% +% +% +% \begin{macro}{\place@deferred@floats} +% +% The |\place@deferred@floats| is supposed to distribute from +% previous pages (i.e., from the top of |\area@ddd| or more exactly +% those currently on the |\@activelist| since the |\area@ddd| was +% already split when trying to build float pages) into the areas +% of the page to be build. After all we know that for those floats +% the call outs are on previous pages so testing for them +% is unnecessary and we could save time by bypassing this stuff. +% +% On the other hand if we have flush points in the upcoming text +% all our placements might be wrong, so perhaps this doesn't really +% save so much time after all and the extra complication might not +% be worth the effort. +% +% Perhaps a compromise is to make a first column grab without any +% floats to see if we end up with a flush point (not implemented). +% +% So if we don't do this then the only thing we need to do at this +% point is to move the floats from the |\@mvllist| to the end of +% the |\@activelist|. +% \begin{macrocode} +\def\place@deferred@floats { +%<*trace> + \@tracepush{place@deferred@floats} +%</trace> + \xdef\@activelist{\@activelist\@mvllist} + \global\let\@mvllist\@empty +%\showfloatlists +%<*trace> + \@tracepop{place@deferred@floats} +%</trace> +} +% \end{macrocode} +% +% +% Here is an alternate definition which does the preassigning but +% it would need to be extended by checking for flush points or by a +% flag that ensures that if we later encounter a flush point that +% we know we could backtrack if necessary (e.g., the preassignment +% might have already deferred some floats past the flush +% point).\footnote{Extend, fix, or get rid of.} +% \begin{macrocode} +\iffalse % we don't do it right now +\def\place@deferred@floats { +%<*trace> + \@tracepush{place@deferred@floats} +%</trace> +%\showfloatlists +% \let\@elt\split@defer@list +% \area@ddd +% \let\@elt\relax +% \global\let\area@ddd\@empty + \global\let\@activelist@empty@action\relax + \global\let\pretests@success@action\floatpage@pretests@success@action +\showfloatlists + \trial@inner@loop + \xdef\@activelist{\area@ddd\@mvllist} + \global\let\area@ddd\@empty + \global\let\@mvllist\@empty +%\showfloatlists +%<*trace> + \@tracepop{place@deferred@floats} +%</trace> +} +\fi +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\floatpage@pretests@success@action} +% Version of |\pretests@success@action| for use in initial phase +% when previously deferred floats are being allocated to float areas. +% \begin{macrocode} +\def\floatpage@pretests@success@action{ +%<*trace> + \@tracepush{floatpage@pretests@success@action} +%</trace> + \update@best@trial + \trial@inner@loop +%<*trace> + \@tracepop{floatpage@pretests@success@action} +%</trace> + } +% \end{macrocode} +% \end{macro} +% +% +% +% \newpage +% +% \subsection{Support for Balancing} +% +% Code in this section (and related code in other sections) is not +% used at the moment and will most likely be replaced with something +% completely different. +% +% \begin{macro}{\if@balance} +% |@balance| is set to true if we encounter a balance penalty +% during collection. +% \begin{macrocode} +\newif\if@balance +\def\@balancefalse{\global\let\if@balance\iffalse} +\def\@balancetrue{\global\let\if@balance\iftrue} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\balancecolumns} +% +% \begin{macrocode} +\def\balancecolumns { + \add@badly@guarded@penalty\output@balance@penalty +} +% \end{macrocode} +% \end{macro} +% +% +% +% +% +% +% \newpage +% +% \subsection{Support for Flush Points} +% +% +% \begin{macro}{\if@flushseen} +% \begin{macro}{\if@flushfail} +% +% |@flushseen| is set to true if we encounter a flush penalty +% during collection. +% +% |@flushfail| is set to true if we fail a trial due to placing the +% float after the flush penalty. +% \begin{macrocode} +\newif\if@flushseen +\def\@flushseenfalse{\global\let\if@flushseen\iffalse} +\def\@flushseentrue{\global\let\if@flushseen\iftrue} +\newif\if@flushfail +\def\@flushfailfalse{\global\let\if@flushfail\iffalse} +\def\@flushfailtrue{\global\let\if@flushfail\iftrue} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% +% \begin{macro}{\flushfloats} +% +% Possible variants: +% +% Flush only one (some) types. +% +% Fuzzyflush or, more precisely, flush-to-this-column +% or -page or -spread.\footnote{Right now "spread" is not implemented.} +% +% Parts of the flushpenalty (all types) data structure: +% +% |\flush@min@col@|\meta{num} +% |\saved@flush@min@col@|\meta{num} +% |\flush@prev@float@num@|\meta{num}\footnote{what is this Chris?} +% +% |\flush@seq@num| is the number of these so that +% \meta{num} has range [1, |\flush@seq@num|] +% +% In addition, whilst doing an fp trial we need |\trial@flush@seen@num| +% to record that we have, in this trial so far, seen the +% flush points [1, |\trial@flush@seen@num|]. +% +% +% \begin{macrocode} +\DeclareDocumentCommand\flushfloats { o O{strict} } + { \flush@floats {#1} {#2} } +% \end{macrocode} +% +% \begin{macrocode} +\def\flush@floats #1 #2 { + \add@badly@guarded@penalty\output@flush@float@penalty +% \end{macrocode} +% +% \begin{macrocode} + \gincrement@num\flush@seq@num +% \end{macrocode} +% +% \begin{macrocode} + \global\@namedef{flush@min@col@\flush@seq@num}{1} +% \end{macrocode} +% +% \begin{macrocode} + \expandafter\xdef + \csname flush@last@float@\flush@seq@num \endcsname + {\the\float@sequence@count} +% \end{macrocode} +% If |#1| is |\NoValue| the current flush point affects all float +% sequence classes, thus we store in +% |\flush@classes@list@|\meta{num} a list of all float sequence +% classes separated by semicolons. Otherwise we assume that we got +% a single float type(!) as argument and flush the corresponding +% class. +% \begin{macrocode} + \IfNoValueTF{#1}{ + \def\@elt##1{##1;} + \expandafter\xdef + \csname flush@classes@list@\flush@seq@num \endcsname + {\float@classes@list} + \let\@elt\relax + } + {\expandafter\ifx\csname sequence@class@#1\endcsname + \relax + \ErrorArgumentNotAFloatType + \else + \global\expandafter\let + \csname flush@classes@list@\flush@seq@num + \expandafter\endcsname + \csname sequence@class@#1\endcsname + \fi + } +% \end{macrocode} +% The argument |#2| holds the fuzziness of the flush point which +% currently can be either |strict|, |column| or |page|. +% We link |\flush@fuzziness@|\meta{num} to the code stored in +% |\flushcheck@#2| after making sure that such code +% exists.\footnote{Improve error handling (as elsewhere)} +% \begin{macrocode} + \@ifundefined {flushcheck@#2} + \userinputERROR + {\global\expandafter\let + \csname flush@fuzziness@\flush@seq@num \expandafter \endcsname + \csname flushcheck@#2\endcsname +%<*trace> + \tr@ce{flush@fuzziness@\flush@seq@num \space + =:~ \expandafter\noexpand\csname flushcheck@#2\endcsname + } +%</trace> + } +} +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\clearpage} +% \LaTeX's |\clearpage| command now looks like this: +% \begin{macrocode} +\def\clearpage{ \flushfloats \newpage } +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\doubleclearpage} +% \LaTeX's |\doubleclearpage| command also needs a new +% definition:\footnote{But not this one :-) FIX!} +% \begin{macrocode} +\def\doubleclearpage{ \clearpage } +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\flush@seq@num} +% The number |\flush@seq@num| records the number of flush +% points we have have seen during collection. +% \begin{macrocode} +\def\flush@seq@num{0} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\trial@flush@seen@num} +% The number |\trial@flush@seen@num| records the number of flush +% points we have seen so far during a trial, i.e., it will be +% initialised to zero at the beginning of the trial and advanced by +% one for each flush point encountered. +% \begin{macrocode} +\def\trial@flush@seen@num{0} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\flush@last@float@xxx} +% \begin{macro}{\flush@min@col@xxx} +% \begin{macro}{\flush@classes@list@xxx} +% \begin{macro}{\flush@fuzziness@xxx} +% +% For each flush point we have a data structure in which we store +% relevant information. This data structure is provided by a set of +% macros which can be accessed by using the number of the current +% flush point and constructing |\csname|s from it, e.g., to get at +% the ``flush min col'' for the flush point with number 3 would be +% |\csname flush@min@col@3\endcsname|. + +% |\flush@min@col@|\meta{num} holds the column number in which we +% last seen the flush penalty while trying to find a solution for +% the current page. This is initialised to 1 in collection@or when +% a flush penalty is encountered during collection (since 1 is the +% earliest column in which the flush penalty finally may fall). By +% adding additional floats to the page the penalty might move to a +% later column but normally not back to an earlier +% one\footnote{There is a possibility that this happens if there is +% enough space vanishing at the new break.} If we end up with the +% flush penalty moving backwards we force a break at this point +% until we reach the column where it was before. The reason for +% this action is that we might have allocated floats to later +% columns that would otherwise end after after the flush penalty. +% +% If by adding floats to the trials the flush penalty is moved to +% the next page we set |\flush@min@col@|\meta{num} to +% |\maxdimen|. The actual test to see if a flush penalty still +% belongs to the current page is to check against |\curr@col@count| +% (so |\curr@col@count+1| would be sufficient, but using +% |\maxdimen| avoids calculations. +% +% |\flush@classes@list@|\meta{num} holds a list of float types which +% are affected by the current flush point. +% +% |\flush@fuzziness@|\meta{num} holds the fuzziness associated with +% the flushpoint, valid values are |strict| and |page|. +% +% By defining (some of) them on top-level we avoid unnecessary +% entries on the savestack since they would otherwise be +% constructed (locally) first within the output routine (when doing +% |\ifx| testing), resulting in |\relax| being stored on the +% savestack. +% \begin{macrocode} +\expandafter\let\csname flush@last@float@1 \endcsname\ERROR +\expandafter\let\csname flush@classes@list@1 \endcsname\ERROR +\expandafter\let\csname flush@min@col@1 \endcsname\ERROR +\expandafter\let\csname flush@fuzziness@1 \endcsname\ERROR +\expandafter\let\csname flush@last@float@2 \endcsname\ERROR +\expandafter\let\csname flush@classes@list@2 \endcsname\ERROR +\expandafter\let\csname flush@min@col@2 \endcsname\ERROR +\expandafter\let\csname flush@fuzziness@2 \endcsname\ERROR +\expandafter\let\csname flush@last@float@3 \endcsname\ERROR +\expandafter\let\csname flush@classes@list@3 \endcsname\ERROR +\expandafter\let\csname flush@min@col@3 \endcsname\ERROR +\expandafter\let\csname flush@fuzziness@3 \endcsname\ERROR +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\flush@classes@list@max} +% |\flush@classes@list@max| holds the concatenation of all +% |\flush@classes@list@|\meta{num} on the page currently +% constructed. This information is needed in case we get to a new +% float and the preliminary tests suggests that it needs to be +% deferred. In that case we need to know which flush points have +% been seen previously to decide whether or not we can defer the +% new float. +% \begin{macrocode} +\let\flush@classes@list@max\@empty +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\initialise@flush@data} +% \begin{macrocode} +\def \initialise@flush@data{ +%<*trace> + \@tracepush{initialise@flush@data} +%</trace> +% \end{macrocode} +% Does this need any documentation? +% +% Well, we have to get rid of all information relating to flush +% float penalties that have been typeset on the previous page and +% move the remaining ones (if any) to the front. +% \begin{macrocode} + \count@\flush@seq@num\relax + \advance\count@ -\trial@flush@seen@num +%<*trace> + \tr@ce{flush@seq@num~ + =~ \flush@seq@num\space <-~ + \the\count@ } +%</trace> +% \end{macrocode} +% Something wrong here if we get negative values! +% \begin{macrocode} +%<*debug> + \ifnum\count@<\z@ \ERROR \fi +%</debug> +% \end{macrocode} +% +% \begin{macrocode} + \xdef\flush@seq@num{\the\count@} +% \end{macrocode} +% +% \begin{macrocode} + \@tempcnta\trial@flush@seen@num + \@tempcntb\z@ + \loop + \ifnum \@tempcntb < \count@ + + \advance\@tempcnta\@ne + \advance\@tempcntb\@ne +%<*trace> + \tr@ce{flush@fuzziness@\the\@tempcntb\space + =~ \expandafter \noexpand + \csname flush@fuzziness@\the\@tempcntb\endcsname\space + <-~ \expandafter \noexpand + \csname flush@fuzziness@\the\@tempcnta \endcsname + } + \tr@ce{flush@last@float@\the\@tempcntb\space + =~ \csname flush@last@float@\the\@tempcntb\endcsname\space <-~ + \csname flush@last@float@\the\@tempcnta \endcsname + } + \tr@ce{flush@classes@list@\the\@tempcntb\space + =~ \csname flush@classes@list@\the\@tempcntb\endcsname\space <-~ + \csname flush@classes@list@\the\@tempcnta \endcsname + } + \tr@ce{flush@min@col@\the\@tempcntb\space <-~ 1} +%</trace> + \global\expandafter\let + \csname flush@fuzziness@\the\@tempcntb \expandafter\endcsname + \csname flush@fuzziness@\the\@tempcnta \endcsname + + \global\expandafter\let + \csname flush@last@float@\the\@tempcntb \expandafter\endcsname + \csname flush@last@float@\the\@tempcnta \endcsname + + \global\expandafter\let + \csname flush@classes@list@\the\@tempcntb \expandafter\endcsname + \csname flush@classes@list@\the\@tempcnta \endcsname + + \global\@namedef{flush@min@col@\the\@tempcntb}{1} + \repeat +% \end{macrocode} +% +% \begin{macrocode} + \global\let\flush@classes@list@max\@empty +% \end{macrocode} +% Need to reset |\trial@flush@seen@num| in case the current macro +% is called again too early, e.g., if it is called to initialize a +% float page and then again to initialize a text page. +% \begin{macrocode} + \gdef\trial@flush@seen@num{0} +%<*trace> + \@tracepop{initialise@flush@data} +%</trace> +} +% \end{macrocode} +% \end{macro} +% +% +% +% +% +% \subsection{Support for Here Points} +% +% A ``Here Point'' is a place in the galley at which something is +% supposed to happen. For example, a marginal note needs to be +% attached to the column, or a float needs to be inserted into the +% column (here float), or it needs to be made sure that from that +% point on there is still a certain amount of space available in the +% column. +% +% With each here point there is associated a float structure (i.e. a +% box and its corresponding |\toks| register) although in most cases +% only parts of that structure is used. In addition each here point +% has an associated dimension which denotes the amount of available +% space which is required after the here point in the column to allow +% to place the here point into this column. If this requirement is not +% met the here point is moved to the next column (or page) by ending +% the current column prematurely at the last legal breakpoint before +% the here point (not at the here point itself\footnote{It should be +% considered to allow breaking directly at the here point in special +% cases, i.e., specified at the here point declaration.}). This +% behaviour will ensure that a line of text preceding the here point +% will also be moved to the next column or page which is important in +% case of marginals and similar situations. In case of here floats it +% might not be a requirements so perhaps this should be made +% customisable. +% +% At the moment the ``type'' in the float structure is used to define +% the type of here point. E.g., +% \begin{description} +% \item[mpar] denotes a marginal +% \item[rspace] denotes a requested space +% \item[figure,table,\ldots] all normal float types identify the here +% point as belonging to a here float. +% \end{description} +% The down side of this approach is that ``mpar'' can't be used as a +% float type any longer and the whole approach might be too difficult +% to extend this way. This needs certainly needs a cleanup. +% +% It is quite likely that there will be additional values that need +% storing on a per here point basis. For this reason the code below +% provides the requiredspace as a data structure external to the float +% structure. Otherwise it could probably be integrated therein. +% +% When a here point is encountered while making columns for a trial or +% for the final page, its requirements are checked. If they are +% fulfilled then a here-point-type specific function will update the +% column material (e.g. by adding a here float or a marginal). +% +% Here points are in many aspects like flush points. So most of the +% code below should not be very surprising. +% +% \begin{macro}{\here@seq@num} +% The number |\here@seq@num| records the number of here +% points we have have seen during collection. +% \begin{macrocode} +\def\here@seq@num{0} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\trial@here@seen@num} +% The number |\trial@here@seen@num| records the number of here +% points we have seen so far during a trial, i.e., it will be +% initialised to zero at the beginning of the trial and advanced by +% one for each here point encountered. +% \begin{macrocode} +\def\trial@here@seen@num{0} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\@herelist} +% |\@elt| list of floats that should appear at a here point. +% \begin{macrocode} +\let\@herelist\@empty +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\saved@herelist} +% Saved version of the |\@herelist| while we run a through the +% float placement trial since we need the full |\@herelist| again in +% the next trial. +% \begin{macrocode} +\let\saved@herelist\@empty +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\here@point} +% |\here@point| adds a here point to the MVL. It takes two +% arguments: the box reference associated with the here point and +% the vertical space that needs to be reserved for the material +% added. +% \begin{macrocode} +\def\here@point #1#2{ +% \end{macrocode} +% +% \begin{macrocode} + \@cons\@herelist#1 +% \end{macrocode} +% +% \begin{macrocode} + \gincrement@num\here@seq@num +% \end{macrocode} +% +% \begin{macrocode} + \global\@namedef{here@min@col@\here@seq@num}{1} +% \end{macrocode} +% +% \begin{macrocode} + \setlength\dimen@{#2} + \expandafter\xdef + \csname here@required@space@\here@seq@num \endcsname + {\the\dimen@} +% \end{macrocode} +% +% \begin{macrocode} + \add@badly@guarded@penalty\output@here@float@penalty +} +% \end{macrocode} +% \end{macro} +% +% +% +% +% \begin{macro}{\initialise@here@data} +% \begin{macrocode} +\def \initialise@here@data{ +%<*trace> + \@tracepush{initialise@here@data} +%</trace> +% Does this need any documentation? +% +% Well, we have to get rid of all information relating to here +% float penalties that have been typeset on the previous page and +% move the remaining ones (if any) to the front. +% \begin{macrocode} + \count@\here@seq@num\relax + \advance\count@ -\trial@here@seen@num +%<*trace> + \tr@ce{here@seq@num~ + =~ \here@seq@num\space <-~ + \the\count@ } +%</trace> +% \end{macrocode} +% Something wrong hereif we get negative values! +% \begin{macrocode} +%<*debug> + \ifnum\count@<\z@ \ERROR \fi +%</debug> +% \end{macrocode} +% +% \begin{macrocode} + \xdef\here@seq@num{\the\count@} +% \end{macrocode} +% +% \begin{macrocode} + \@tempcnta\trial@here@seen@num + \@tempcntb\z@ + \loop + \ifnum \@tempcntb < \count@ + + \advance\@tempcnta\@ne + \advance\@tempcntb\@ne +%<*trace> + \tr@ce{here@required@space@\the\@tempcntb\space + =~ \csname here@required@space@\the\@tempcntb\endcsname\space <-~ + \csname here@required@space@\the\@tempcnta \endcsname + } + \tr@ce{here@min@col@\the\@tempcntb\space <-~ 1} +%</trace> + \global\expandafter\let + \csname here@required@space@\the\@tempcntb \expandafter\endcsname + \csname here@required@space@\the\@tempcnta \endcsname + + \global\@namedef{here@min@col@\the\@tempcntb}{1} + \repeat +%<*trace> + \@tracepop{initialise@here@data} +%</trace> +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\split@off@last@line} +% +% When a here point doesn't fit onto the current page or column for +% some reason it will be moved into the next column. In some cases, +% e.g., when the here point is associated with the line before it +% (as, for example, in marginals) it is necessary to move the line +% also to the later column. +% +% The purpose of |\split@off@last@line| (to be called inside the +% OR) is to split box 255 at the latest possible breakpoint before +% the end and return the material following this breakpoint to the +% MVL. +% +% The idea is as follows: if we subtract 1sp from the height of +% box 255 and also subtract all of its internal shrinkability and +% then split it to this height it can't any longer reach the final +% breakpoint (by 1sp). Thus it will settle with some earlier +% breakpoint and chances are very very good that this will be the +% prefinal one. +% \begin{macrocode} +\def \split@off@last@line{ +%<*trace> + \@tracepush{split@off@last@line} + \tr@ce{goal:~ \the\pagegoal;~ total:~ \the\pagetotal;~ shrink:~ + \the\pageshrink} + \tr@ce{ht255:~ \the\ht255;~ dp255:~ \the\dp255} +%</trace> +% \end{macrocode} +% +% +% \begin{macrocode} + \dimen@\ht\@cclv +% \end{macrocode} +% Looking at |\ht255| should be the same as |\pagetotal-\pagedepth| +% or not?\footnote{Doesn't seem to be the case, bug in the code, +% the program, or in my thinking? (seems to be a bug in \TeX: +% pagedepth is always zero in the OR!)} +% \begin{macrocode} + \advance\dimen@-\pageshrink + \advance\dimen@-1sp +%{\showoutput\showbox\@cclv} +% \end{macrocode} +% Before splitting we have to ensure that the maximum depth is not +% larger than the maximum depth allowed on the MVL. +% \begin{macrocode} + \splitmaxdepth\@maxdepth + \setbox\z@\vsplit\@cclv to\dimen@ +%{\showoutput\showbox\z@} +%{\showoutput\showbox\@cclv} +% \end{macrocode} +% +% Before we now |\unvbox| 255 back onto the MVL we have to make sure +% that the sum of its vertical dimensions plus the requested space +% for the current here point is smaller than a full column height. +% +% If we don't do that we might end up with a situation where we are +% pushing the two from column to columns since they will never fit. +% \begin{macrocode} + \dimen@\csname + here@required@space@\trial@here@seen@num + \endcsname + \advance\dimen@\ht\@cclv + \advance\dimen@\dp\@cclv +% \end{macrocode} +% If the sum is too large we reduce the required space for the here +% point and complain (not really done yet the latter). +% \begin{macrocode} + \ifdim \dimen@ > \textheight + \ERROR-HERE-TOO-LARGE + \dimen@\textheight + \advance\dimen@-\ht\@cclv + \advance\dimen@-\dp\@cclv + \expandafter\xdef\csname + here@required@space@\trial@here@seen@num + \endcsname{\the\dimen@} + \fi +% \end{macrocode} +% So now we can |\unvbox| and then move the top from the split back +% into 255 (essentially to have it taken out of that register by +% the code following, but such is life). +% \begin{macrocode} + \unvbox\@cclv + \global\setbox\@cclv\box\z@ +%<*trace> + \@tracepop{split@off@last@line} +%</trace> +} +% \end{macrocode} +% \end{macro} +% +% +% +% +% \subsection{Support for Grid Points} +% +% +% +% +% \begin{macro}{\align@collected@galley@and@restart} +% |\align@collected@galley@and@restart| is called inside +% |\some@column@or| when we have encountered a grid point. It is +% supposed to align the current line with the text grid and then +% restarts the galley processing. +% +% We do this by putting the material gathered so far into a box of +% appropriate size, and then push this pack onto the recent +% contributions for reconsideration. +% \begin{macrocode} +\def \align@collected@galley@and@restart { +%<*trace> + \@tracepush{align@collected@galley@and@restart} + \tr@ce{GRID:~ page~ goal~\space\space\space =~ \the\pagegoal} + \tr@ce{GRID:~ page~ total~\space\space =~ \the\pagetotal} + \tr@ce{GRID:~ page~ depth~\space\space =~ \the\pagedepth} + \tr@ce{GRID:~ page~ shrink~\space =~ \the\pageshrink} + \tr@ce{GRID:~ page~ stretch~ =~ \the\pagestretch} + \tr@ce{GRID:~ page~ fil~ stretch~ =~ \the\pagefilstretch} + \tr@ce{GRID:~ page~ fill~ stretch~ =~ \the\pagefillstretch} + \tr@ce{GRID:~ page~ filll~ stretch~ =~ \the\pagefillstretch} + \tr@ce{GRID:~ ht~ 255~\space =~ \the\ht\@cclv} + \tr@ce{GRID:~ dp~ 255~\space =~ \the\dp\@cclv} +%</trace> +% \end{macrocode} +% As a first step we remove the guard box since it has now served +% its purpose. +% \begin{macrocode} + \remove@guard@box@from@cclv +% \end{macrocode} +% Then we calculate the distance to nearby grid points. +% \begin{macrocode} + \snap@to@grid{\ht\@cclv}\pagesetup@grid@point@sep +% \end{macrocode} +% So the next step is to make a decision which grid point to +% use. The strategy used below can probably be refined +% further\ldots +% +% First we test if the next grid point down makes us fall off the +% page\footnote{We should use \texttt{\string\pagegoal} for the +% test I think, not the commented out construct below, since in +% case of footnotes the available space for text might has be +% reduced!}, if so\ldots +% \begin{macrocode} + \ifdim \returned@size > \pagegoal + % \csname col@ht@ \the\curr@col@count\endcsname % not! +% \end{macrocode} +% \ldots we better try using the previous grid point. +% \begin{macrocode} + \ifdim \returned@lower@delta@size < \pageshrink +% \end{macrocode} +% If the |\pageshrink| allows us to reach the previous point then +% use it. +% \begin{macrocode} +% can use it: do so +%<*trace> + \tr@ce{GRID:~ outside~ page,~ choosing~ lower~ grid~ point} +%</trace> + \global\let \returned@size \returned@lower@size + \xdef \returned@delta@size {-\returned@lower@delta@size } + \else +% \end{macrocode} +% Otherwise, ouch \ldots{} what now? Can this happen? Unfortunately +% yes, it seems to happen, for example, when we are trying to place +% floats.\footnote{Analyse this situation and decide on a course of +% action if necessary.} +% \begin{macrocode} + \OuchERROR + \fi +% \end{macrocode} +% Otherwise we are in the normal case, i.e., somewhere in the +% middle of the page. +% \begin{macrocode} + \else +% \end{macrocode} +% So now we can in principle choose either grid point. The code +% below makes the decision based on which grid point is closer but +% chooses the previous point only if |\pageshink| allows +% it.\footnote{One could also have a look at the available +% stretchability and base the decision on the resulting badness, +% this might in fact be the more appropriate way!} +% \begin{macrocode} + \ifdim \returned@lower@delta@size < \returned@delta@size \relax + \ifdim \returned@lower@delta@size < \pageshrink +%<*trace> + \tr@ce{GRID:~ choosing~ lower~ grid~ point} +%</trace> + \global\let \returned@size \returned@lower@size + \xdef \returned@delta@size {-\returned@lower@delta@size } + \fi + \fi + \fi +%<*trace> + \tr@ce{GRID:~ adjustment:~ \the\ht\@cclv\space ->~ \returned@size} +%</trace> +% \end{macrocode} +% Whatever the decision was, we finally bundle up all material in a +% box with the vertical size being that of the chosen grid point +% (no |\maxdepth| setting in this case) and return this box to the +% MVL followed by any footnotes found in that process. These +% footnotes are reinserted so that they will be reconsidered but +% since we have no break point between the box and them they will +% be considered as a unit. +% \begin{macrocode} + \vbox to\returned@size{\unvbox\@cclv} + \@reinserts +% \end{macrocode} +% We know that the material returned to the MVL is followered +% immediately by a box of size zero followed by a penalty thus +% there will be a breakpoint in the right place (or so we hope) so +% that the box plus the following footnotes will still fit into the +% column when reprocessed. +% \begin{macrocode} +%<*trace> + \@tracepop{align@collected@galley@and@restart} +%</trace> +} +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\OuchERROR} +% This part of the code (as far as I can see right now) will be +% executed if there is some larger display object (ie off grid) +% which will just fit onto the page unaligned but not if we align +% to the next grid point. The reason for this is that somewhere on +% the column there are also footnotes for example, which result in +% the column not being an integral number of grid lines. +% \begin{macrocode} +\def\OuchERROR{ +%<*trace> + \tr@ce{Failed:~grid~ overflowing~ column~ \the\curr@col@count} +%</trace> +%<*progress> + \progress@failed{next~ possible~ grid~ point~ in~ column~ + \the\curr@col@count\space outside~ page} +%</progress> +% \end{macrocode} +% I think essentially what is needed here is to split the column +% just before the current line, ie, using something like +% |\split@off@last@line| (except that this only works for here +% points right now) and this move the grid align penalty to the +% next column.\footnote{Not done! FIX} +% \begin{macrocode} +% \split@off@last@line +% \(re)???add@guarded@penalty\output@grid@align@penalty +} +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\std@AlignToGrid} +% This is the definition for |\AlignToGrid| if we are really doing +% grid based layout. +% \begin{macrocode} +\def\std@AlignToGrid{ + \add@badly@guarded@penalty\output@grid@align@penalty +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\IgnoreAlignToGrid} +% \begin{macro}{\ObeyAlignToGrid} +% |\IgnoreAlignToGrid| will turn off automatic grid alignment for a +% while, while |\ObeyAlignToGrid| will turn it on again. This is +% needed in commands that want to set something outside the grid +% and then realign afterwards, e.g., a heading. If that heading +% would follow, say, a list that issued a |\AlignToGrid| to be +% executed on the next paragraph, that |\AlignToGrid| would +% effectively appear on the heading title thus forcing that to be +% on a grid line, which is typically not intended. So the heading +% macro first says |\IgnoreAlignToGrid| then typesets the material +% which should be not aligned, then says |\ObeyAlignToGrid| and +% prepares to install its own |\AlignToGrid| (typically after the +% first line of text via |\everypar|). +% \begin{macrocode} +\def\IgnoreAlignToGrid{ + \global\let\AlignToGrid\relax +} +\def\ObeyAlignToGrid{ + \global\let\AlignToGrid\std@AlignToGrid +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% +% \begin{macro}{\AlignToGrid} +% |\AlignToGrid| is the command that inserts a grid point which +% triggers alignment to the text grid for the current line (if we +% are doing grid based design). It should be set in the page setup +% so the default is an error. +% \begin{macrocode} +\let\AlignToGrid\ERROR +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\TextAlignToGrid} +% In nearly all cases the alignment should be done for a text line, +% so we provide this abbreviation which starts horizontal mode if +% necessary. +% \begin{macrocode} +\def\TextAlignToGrid{ \leavevmode \AlignToGrid } +% \end{macrocode} +% \end{macro} +% +% +% +% +% +% +% \subsection{Initialisations} +% +% The initialisation at begin document isn't properly done +% yet. Some bits are done unnecessarily here (by calling +% initialisation commands that do too much and some bits are +% problably still in the wrong place. Furthermore the column data +% initialisation needs to be resolved properly. Right now we +% hardwire a maximum of 6 columns down there and initialise the +% data structures for all the potential columns independently of +% whether or not they are ever being used.\footnote{SORT OUT!} +% \begin{macrocode} +\AtBeginDocument{ + \begingroup + \col@count6\relax + \initialise@column@data +% \end{macrocode} +% More column data stuff which needs to be set only the very first +% time! +% \begin{macrocode} + \forall@columns { +% \end{macrocode} +% +% \begin{macrocode} + \def\@elt#1{ + \global\@namedef{fl@\the\curr@col@count @#1}{0} + \global\@namedef{tfl@\the\curr@col@count @#1}{0} + } + \float@classes@list +% \end{macrocode} +% Setting |\@elt| back to |\relax| is done below. +% \begin{macrocode} + } +% \end{macrocode} +% +% The default for fps should be all areas known (not only those +% currently used!) +% \begin{macrocode} + \def\@elt#1{ + \global\expandafter\let\csname fps@#1\endcsname\known@areas + \global\@namedef{fl@0@#1}{0} + } + \float@classes@list + \endgroup +% \end{macrocode} +% +% \begin{macrocode} +% \initialise@next@page +% \end{macrocode} +% Start the document by collecting text. +% \begin{macrocode} + \@collecting@new@materialtrue + \setup@collection@or +} +% \end{macrocode} +% +% +% \endinput +\endinput +% +% $Log: xo-or.dtx,v $ +% Revision 1.53 2000/08/11 07:14:25 latex3 +% added header +% +% Revision 1.52 2000/08/11 06:49:21 latex3 +% untabify +% +% Revision 1.51 2000/08/11 06:46:48 latex3 +% change logic for handling special penalties once more (and still not +% okay) +% +% Revision 1.50 2000/08/06 19:03:44 latex3 +% change initialisation at \begin{document} +% fix \columnbreak +% +% Revision 1.49 2000/08/04 13:58:16 latex3 +% documented issue when grid point overflows column +% +% Revision 1.48 2000/08/04 10:22:31 latex3 +% added \split@skip (probably not final version) +% +% Revision 1.47 2000/07/26 20:37:03 latex3 +% working version of grid points (text grids) +% +% Revision 1.46 2000/07/21 13:52:13 latex3 +% more renaming for float sequence class concept +% +% Revision 1.45 2000/07/19 17:12:08 latex3 +% introduced float sequence class concept +% added variables for float area separation +% +% Revision 1.44 2000/07/10 19:24:59 latex3 +% some start at supporting "balance points" (unfinished). +% added \initialise@column@data. +% getting rid of extra empty page at end due to old defnition of +% \clearpage. +% +% Revision 1.43 2000/07/04 19:45:40 latex3 +% fix GRID stuff (restore all values as needed) +% +% Revision 1.42 2000/07/01 16:07:26 latex3 +% use \update@this@area@columns +% integrate code to support grid design (first draft) +% +% Revision 1.41 2000/06/29 17:40:44 latex3 +% introduced \setup@this@area +% +% Revision 1.40 2000/06/26 15:16:15 latex3 +% prototype support for \pagesetup@float@area@sep +% +% Revision 1.39 2000/06/22 20:07:51 latex3 +% renamed some macros to get them more uniform +% +% Revision 1.38 2000/06/22 10:59:57 latex3 +% Included support for writing fpl files +% +% Revision 1.37 2000/06/21 09:55:41 latex3 +% fix typo +% +% Revision 1.36 2000/06/19 19:03:56 latex3 +% make \gincrement@num and \gdecrement@num behave (not update \count@) +% cleanup flushing (if fail only move flush point one column) +% +% Revision 1.35 2000/06/18 14:59:50 latex3 +% docu updates (and a bug fix due to typo) +% +% Revision 1.34 2000/06/16 11:21:14 latex3 +% rename \construct@and@test@col@height to \construct@and@test@col@ht +% rename \construct@and@test@col@heights to \construct@and@test@col@hts +% rename \cl@height1 to \@col@ht@1 (etc) +% +% Revision 1.33 2000/06/16 11:05:25 latex3 +% implemented tfl@ support (top area float sequences) +% support float-callout-span-constraint +% more documentation +% +% Revision 1.32 2000/06/15 15:20:16 latex3 +% implemented new semantics for area names +% +% Revision 1.31 2000/06/15 09:32:18 latex3 +% added mising \end{macro}'s +% +% Revision 1.30 2000/06/13 20:44:25 latex3 +% guard the output@collect@penalty +% implemented fuzzy flushing (except for spreads) +% +% Revision 1.29 2000/06/06 11:03:21 latex3 +% before attempting fuzzyflush +% +% Revision 1.28 2000/05/03 20:17:31 latex3 +% need more info about here floats +% +% Revision 1.27 2000/05/03 18:45:40 latex3 +% fix bugs: always have a trial run wihtout floats to initialise here +% and flush points; reset \trial@flush@seen@num after using it to update +% the data structures on a new pages; have adding to the defer area +% close other areas :-) +% more documentation +% +% Revision 1.26 2000/04/27 19:50:11 latex3 +% some stats gathered now +% combine \grab@column@or and \best@column@or as far as possible +% some bug fixes and additional documentation +% +% Revision 1.25 2000/04/21 19:08:43 latex3 +% code cleanup +% additional documentation +% fixes for here points +% support for footnote setup +% +% Revision 1.24 2000/04/11 21:06:06 latex3 +% basically Chris's 1.24 plus my changes +% +% Revision 1.24 2000/04/10 16:41:14 car2 +% typos, comments and guardbox removal +% +% Revision 1.23 2000/04/09 20:02:00 latex3 +% fix topskip problem in collection +% added first draft of marginpar support +% +% Revision 1.22 2000/04/08 09:47:06 latex3 +% first draft of here point implementation +% code cleanup +% further documentation +% +% Revision 1.21 2000/03/31 17:12:41 latex3 +% disable preplacing deferred floats (until caption handling is fixed) +% fix float page handling +% ensure that float pages don't add additional captions (don't mind that +% the float page comes out even worse) +% +% Revision 1.20 2000/03/26 21:05:11 latex3 +% work on float pages +% some renaming in particular \try@this@area +% and \try@next@area +% some more documentation +% +% Revision 1.19 2000/03/24 15:34:27 latex3 +% version that starts supporting spans (still a hack yet) +% +% Revision 1.18 2000/03/22 15:51:11 latex3 +% some normalisations of names +% moved code around +% lot of updates +% +% Revision 1.17 2000/03/17 20:26:40 latex3 +% more fixes to flushing (looks good now) +% +% Revision 1.16 2000/03/16 10:28:29 latex3 +% partial and full flush working for the first time +% +% Revision 1.15 2000/03/05 19:36:53 latex3 +% some renaming +% support multiple columns (6 max right now) +% fix flush float logic (hopefully) +% +% Revision 1.14 2000/02/28 23:41:14 david +% deadcycles +% +% Revision 1.13 2000/02/27 15:39:53 david +% *** empty log message *** +% +% Revision 1.12 2000/02/27 15:12:00 david +% 2nd attempt at flush floats (working as far as implemented) +% +% Revision 1.11 2000/02/27 11:26:35 david +% first attempt at flush floats +% +% Revision 1.10 2000/02/26 18:20:09 david +% added pre-allocation of deferred floats to float areas +% +% Revision 1.9 2000/02/21 23:25:11 david +% t11|t22 support in optional argument +% +% Revision 1.8 2000/02/19 23:14:58 david +% chris' doc fix +% +% Revision 1.7 2000/02/16 13:40:40 latex3 +% added 3col support +% +% Revision 1.6 2000/02/16 10:07:13 latex3 +% added further documentation +% fixed bug by removing code from \try@this@area to +% \pretests@success@action +% handle case of hitting special output penalty during trial or +% page production +% handle case of \newpage ie penalty -10000 +% +% Revision 1.5 2000/02/15 01:08:25 david +% dead code +% +% Revision 1.4 2000/02/13 22:40:13 latex3 +% moved some stuff around and added macro environments +% diff --git a/Master/texmf-dist/source/latex3/xor/xo-page.dtx b/Master/texmf-dist/source/latex3/xor/xo-page.dtx new file mode 100644 index 00000000000..7dff99b8119 --- /dev/null +++ b/Master/texmf-dist/source/latex3/xor/xo-page.dtx @@ -0,0 +1,694 @@ +% \iffalse +%% +%% (C) Copyright 1999-2000 Frank Mittelbach, David Carlisle, Chris Rowley +%% All rights reserved. +%% +%% Not for general distribution. In its present form it is not allowed +%% to put this package onto CD or an archive without consulting the +%% the authors. +%% +% \fi +% + +% \begin{macrocode} +\def\@tempa#1: #2.dtx,v #3 #4 #5 #6 #7${ + \ProvidesPackage{#2}[#4 #3 #5 #6]} +\@tempa$Id: xo-page.dtx,v 1.34 2000/08/11 07:14:27 latex3 Exp $ +% \end{macrocode} +% +% +% Ignore white space in this package. +% \begin{macrocode} +\IgnoreWhiteSpace +% \end{macrocode} +% +% +% +% \subsection{Footnote setup} +% +% \begin{macro}{\initialise@footins@action} +% The |\initialise@footins@action| is a hook to add code to the +% page initialisation phase related to the footnote insertions. For +% example, when all footnotes are accumulated in the last column we +% need to make footnote insertions invisible when gathering +% material for the first columns. +% \begin{macrocode} +\let\initialise@footins@action\relax +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\deal@with@footins@action} +% The |\deal@with@footins@action| hook is called in the +% |\grab@column@or| and the |best@column@or| output routine to do +% something to the accumulated footnote insertions if +% necessary. I.e., it is called for every column. +% \begin{macrocode} +\let\deal@with@footins@action\relax +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macrocode} +\DeclareTemplateType{footnotesetup}{0} +% \end{macrocode} +% +% +% +% +% \begin{macrocode} +\DeclareTemplate{footnotesetup}{std}{0}{ + text-sep =+l \skip\footins, + max-height =+l \dimen\footins, + } + { + + \global\skip\footins 10pt plus 5pt + \global\dimen\footins.7\textheight + + \DoParameterAssignments + + \let\initialise@footins@action\relax + \let\deal@with@footins@action\relax + + \global\count\footins\@m + + } +% \end{macrocode} +% +% \begin{macrocode} +\DeclareTemplate{footnotesetup}{ftnright}{0}{ + text-sep =+l \rcol@footinsskip, + max-height =+l \dimen\footins, + } + { + + \global\rcol@footinsskip 10pt plus 5pt + \global\dimen\footins\textheight + + \DoParameterAssignments + + \let\initialise@footins@action\initialise@footins@ftnright + \let\deal@with@footins@action\deal@with@footins@ftnright + + } +% \end{macrocode} +% +% +% Setting |max-height| as done below has not the desired effect and +% needs investigation.\footnote{FIX!} +% +% \begin{macrocode} +\DeclareTemplate{footnotesetup}{margin}{0}{ + max-height =+l \dimen\footins, + } + { + + \global\dimen\footins.7\textheight + + \DoParameterAssignments + + \let\initialise@footins@action\initialise@footins@margin + \let\deal@with@footins@action\deal@with@footins@margin + +% \end{macrocode} +% If the footnote do not appear within the columns we have to +% ensure that the |\insert| does not change the page +% calculations. This needs changes in two places: +% \begin{macrocode} + \global\count\footins\z@ + \global\skip\footins \z@ + + } +% \end{macrocode} +% +% +% +% +% \subsubsection{Footnote setup ftnright} +% +% In this section we provide the code for running all footnotes in the +% last column. +% +% \begin{macro}{\saved@footins} +% +% \begin{macrocode} +\newbox\saved@footins +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\rcol@footinsskip} +% \begin{macrocode} +\newskip\rcol@footinsskip +% \end{macrocode} +% \end{macro} +% +% +% +% +% +% \begin{macro}{\initialise@footins@ftnright} +% \begin{macrocode} +\def \initialise@footins@ftnright { + \global\setbox\saved@footins\box\voidb@x + \global\skip\footins\z@ + \global\count\footins\z@ + \global\dimen\footins\textheight +} +% \end{macrocode} +% \end{macro} +% +% +% +% +% +% \begin{macro}{\deal@with@footins@ftnright} +% \begin{macrocode} +\def \deal@with@footins@ftnright { +%<*trace> + \@tracepush{deal@with@footins@ftnright} +%</trace> +% \end{macrocode} +% If we are not in the last column we save any footnote accumulated +% in |\footins| in a separate |\saved@footins| box. This way any +% later code that checks |\footins| for constraints will not fire +% incorrectly. +% \begin{macrocode} + \ifnum\curr@col@count<\col@count +%<*trace> + \tr@ce{not~ last~ col} +%</trace> + \ifvoid\footins + \else + \global\setbox\saved@footins + \vbox{\unvbox\saved@footins + \unvbox\footins} + \fi +% \end{macrocode} +% If we are in the second last column we have to change the +% procedure: we now have to return all saved footnotes to the MVL +% and modify the insertion register values so that from now on +% footnotes need space in the column.\footnote{Not correctly +% handled is the case that we have accumulated more than a full +% column of footnotes before!} +% \begin{macrocode} + \count@\col@count + \advance\count@\m@ne + \ifnum\curr@col@count=\count@ % cur col = second last col +%<*trace> + \tr@ce{second~ last~ col} +%</trace> + \global\count\footins\@m + \global\skip\footins\rcol@footinsskip + \ifvoid\saved@footins + \else + \insert\footins{\unvbox\saved@footins} + \fi + \fi + \fi +%<*trace> + \@tracepop{deal@with@footins@ftnright} +%</trace> +} +% \end{macrocode} +% \end{macro} +% +% +% +% +% \begin{macro}{\deal@with@footins@margin} +% \begin{macrocode} +\def \deal@with@footins@margin { +%<*trace> + \@tracepush{deal@with@footins@margin} +%</trace> + \ifvoid\footins + \else + \global\setbox\saved@footins + \vbox{\unvbox\saved@footins + \unvbox\footins} + \fi +%<*trace> + \@tracepop{deal@with@footins@margin} +%</trace> +} +% \end{macrocode} +% \end{macro} +% +% +% +% +% \begin{macro}{\deal@with@footins@margin} +% \begin{macrocode} +\def \initialise@footins@margin { + \global\setbox\saved@footins\box\voidb@x +} +% \end{macrocode} +% \end{macro} +% +% +% +% +% \subsection{A basic page setup template} +% +% +% \begin{macro}{\test@named@key} +% This should perhaps be made more general +% \begin{macrocode} +\def\test@named@key #1#2#3#4 { + \global\expandafter\let \expandafter #1 + \csname #2 \endcsname + \ifx #1 \relax + \PackageError{template}{#3~ unknown} + {#3~ can~ be~ either~ #4} + \fi +} +% \end{macrocode} +% \end{macro} +% +% +% +% +% \begin{macro}{\DeclareFloatArea} +% We declare new float areas and (for the moment) internally use the +% template mechanism. But this is more or less overkill and should +% probably be replaced in the end. +% \begin{macrocode} +\def\DeclareFloatArea#1#2{ + \xdef\known@areas{\known@areas#1} + \DeclareInstance{floatareasetup}{#1}{std} + { name = #1, #2 } +% \end{macrocode} +% We need to do some intialisation here in case the area isn't +% really used. (Since it is added to |\known@areas| it will be +% considered and that will die if the initialisation isn't done) +% \begin{macrocode} + \UseInstance{floatareasetup}{#1} +} +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macrocode} +\DeclareTemplateType{floatareasetup}{0} +% \end{macrocode} +% +% \begin{macrocode} +\DeclareTemplate{floatareasetup}{std}{0}{ + name =n \floatareasetup@name, + class-close-list=n \floatareasetup@class@close, + all-close-list =n \floatareasetup@all@close, + max-float-num =C \floatareasetup@maxfloats, + } + { + + \DoParameterAssignments +% \end{macrocode} +% +% Declare area data structures if necessary\ldots +% \begin{macrocode} + \@ifundefined{\floatareasetup@name @float@count} + {\expandafter\newcount\csname \floatareasetup@name + @float@count\endcsname} + {} +% \end{macrocode} +% \ldots and initialise them +% \begin{macrocode} + \global\expandafter\let + \csname pagesetup@ \floatareasetup@name @float@num\endcsname + \floatareasetup@maxfloats + \global\expandafter\let + \csname pagesetup@ \floatareasetup@name @class@close\endcsname + \floatareasetup@class@close + \global\expandafter\let + \csname pagesetup@ \floatareasetup@name @all@close\endcsname + \floatareasetup@all@close +% \end{macrocode} +% Let's not forget that area itself (some macros wouldn't like if +% this is |\relax| rather than |\@empty|. +% \begin{macrocode} + \global\expandafter\let + \csname area@\floatareasetup@name\endcsname + \@empty +} +% \end{macrocode} +% +% +% \begin{macrocode} +\DeclareTemplateType{pagesetup2}{0} +% \end{macrocode} +% +% \begin{macrocode} +\DeclareTemplate{pagesetup2}{std}{0}{ + column-num =+c \col@count, + column-width =+l \columnwidth, + column-height =+l \textheight, % FMi tmp + column-sep =+l \columnsep, + max-float-num =C \pagesetup@max@float@num, + float-callout-constraint =n \pagesetup@float@callout, + float-callout-span-constraint =n \pagesetup@float@callout@span, + bottom-float-footnote-constraint =n \pagesetup@float@footnote, + flush-float-callout-constraint =n \pagesetup@flush@float@callout, + flush-float-callout-span-constraint =n \pagesetup@flush@float@callout@span, + flush-bottom-float-footnote-constraint =n + \pagesetup@flush@float@footnote, +% +% \end{macrocode} +% +% \begin{macrocode} + area-list =n \pagesetup@area@list, +% \end{macrocode} +% \begin{macrocode} + defer-class-close-list=n \pagesetup@ddd@class@close, + defer-all-close-list =n \pagesetup@ddd@all@close, +% \end{macrocode} +% +% \begin{macrocode} + footnote-setup =i {footnotesetup} \pagesetup@footnote@setup, +% \end{macrocode} +% +% \begin{macrocode} + float-float-sep =+l \pagesetup@float@float@sep, + float-area-sep =+l \pagesetup@float@area@sep, + float-text-sep =+l \pagesetup@float@text@sep, + float-inline-sep =+l \pagesetup@float@inline@sep, +% \end{macrocode} +% +% \begin{macrocode} + grid-point-sep =+L \pagesetup@grid@point@sep, + } + { +% \end{macrocode} +% We start off with ensuring that we are at the top of a page. This +% is a temporary solution until after pagesetup is more settled and +% those bits which are only possible if there is nothing left on +% recent contributions are properly separated from those things +% which can be changed midway. +% \begin{macrocode} + \newpage + + \global\col@count\@ne + \def\pagesetup@max@float@num{3} + \def\pagesetup@float@callout{column} + \def\pagesetup@float@footnote{none} + \def\pagesetup@flush@float@callout{\pagesetup@float@callout} + \def\pagesetup@flush@float@footnote{\pagesetup@float@footnote} + \def\pagesetup@float@callout@span{flexible} + \def\pagesetup@flush@float@callout@span{\pagesetup@float@callout@span} +% \end{macrocode} +% +% \begin{macrocode} + \let\pagesetup@ddd@class@close\maxdimen %impossible value + \let\pagesetup@ddd@all@close\@empty +% \end{macrocode} +% +% \begin{macrocode} +% tmp: + \def\pagesetup@footnote@setup{\UseTemplate{footnotesetup}{std}{}} +% \end{macrocode} +% +% \begin{macrocode} + \global\let\pagesetup@grid@point@sep\z@ % no grid points by default + + \DoParameterAssignments +% \end{macrocode} +% +% \begin{macrocode} + \ifdim \pagesetup@grid@point@sep = \z@ + \global\let\snap@to@grid\dummy@snap@to@grid +% \end{macrocode} +% Next two lines need some refinement, we need some mechanism to +% fully disable those grid points. |\IgnoreAlignToGrid| doesn't do +% the trick.\footnote{FIX!} +% \begin{macrocode} + \IgnoreAlignToGrid + \global\let\std@AlignToGrid\relax + \else + \global\let\snap@to@grid\std@snap@to@grid + \ObeyAlignToGrid + \fi +% \end{macrocode} +% Split the |\pagesetup@float@text@sep| specification and store the +% minus part in |\pagesetup@float@text@shrink|. Right now the plus +% part is not used. Actually this is only really necessary if we do +% grid typesetting but we do it anyway so that the spec is always +% checked for offending infinite stretch. +% \begin{macrocode} + \split@skip{float-text-sep} + \pagesetup@float@text@sep + \dimen@ + {\global\pagesetup@float@text@shrink} +% \end{macrocode} +% +% \begin{macrocode} + \split@skip{float-inline-sep} + \pagesetup@float@inline@sep + \dimen@ + {\global\pagesetup@float@inline@shrink} + \global\pagesetup@float@inline@sep \@ne\pagesetup@float@inline@sep +% \end{macrocode} +% +% \begin{macrocode} + \global\hsize\columnwidth + \global\linewidth\columnwidth + +% all taken away from AtBeginDocument (where it is was added in xo-final) + \setlength \@tempdima {\headheight + \headsep} + \xdef \pagebodytopvpos {\the\@tempdima} + + \setlength \@tempdima {\@tempdima + \textheight} + \xdef \pagebodybotvpos {\the\@tempdima} + +%% horiz + \setlength \@tempdima {\columnwidth + \columnsep} + \xdef \columndisplacement {\the\@tempdima} + +% \end{macrocode} +% +% Perhaps we could use |\known@areas| instead and save the +% test (would need a change in xo-place as well!).\footnote{Check!} +% \begin{macrocode} + \ifx\pagesetup@ddd@class@close\maxdimen % not set? + \let\pagesetup@ddd@class@close\pagesetup@area@list + \fi +% \end{macrocode} +% +% \begin{macrocode} + \test@named@key + \std@check@callout@constraints + {check@callout@\pagesetup@float@callout} + {float-callout-constraint} + {`none',~ `page',~ `column',~ or~ `after'} +% \end{macrocode} +% +% \begin{macrocode} + \test@named@key + \relaxed@check@callout@constraints + {check@callout@\pagesetup@flush@float@callout} + {flush-float-callout-constraint} + {`none',~ `page',~ `column',~ or~ `after'} +% \end{macrocode} +% +% \begin{macrocode} + \test@named@key + \std@check@some@constraints + {check@float@footnote@\pagesetup@float@footnote} + {bottom-float-footnote-constraint} + {`none'~ or~ `forbidden'} +% \end{macrocode} +% +% \begin{macrocode} + \test@named@key + \relaxed@check@some@constraints + {check@float@footnote@\pagesetup@flush@float@footnote} + {flush-bottom-float-footnote-constraint} + {`none'~ or~ `forbidden'} +% \end{macrocode} +% +% \begin{macrocode} + \test@named@key + \std@calculate@target@fl@column + {calculate@target@fl@column@\pagesetup@float@callout@span} + {float-callout-span-constraint} + {`strict'~ or~ `flexible'} +% \end{macrocode} +% +% \begin{macrocode} + \test@named@key + \relaxed@calculate@target@fl@column + {calculate@target@fl@column@\pagesetup@flush@float@callout@span} + {flush-float-callout-span-constraint} + {`strict'~ or~ `flexible'} +% \end{macrocode} +% +% \begin{macrocode} + \global\let\check@some@constraints\std@check@some@constraints + \global\let\check@callout@constraints\std@check@callout@constraints + \global\let\calculate@target@fl@column\std@calculate@target@fl@column +% \end{macrocode} +% +% \begin{macrocode} + \global\let\used@areas\@empty +% \end{macrocode} +% +% \begin{macrocode} + \expandafter + \@for \expandafter \@tempa \expandafter:\expandafter= + \pagesetup@area@list \do + { +% \end{macrocode} +% Perhaps the instance should be called the moment we declare the +% area. on the other hand calling it within the page setup would +% allow to use collections!\footnote{Think and decide} +% \begin{macrocode} + \xdef\used@areas{\used@areas\@tempa} +% after next line \@tempa is gone ... David, template.sty needs a cleanup + \UseInstance{floatareasetup}{\@tempa} +%\show\@tempa + } + +% \end{macrocode} +% +% \begin{macrocode} + \pagesetup@footnote@setup +% \end{macrocode} +% +% Finally another bit of the initalisation that we have to redo at +% this point since now some of the values may have +% changed.\footnote{Temporary solution until the initialisation bit +% and the pagesetup is properly sorted out.} +% \begin{macrocode} + \initialise@next@page + \setup@collection@or + } +% +% \end{macrocode} +% +% \begin{macrocode} +\endinput +% \end{macrocode} +% +% \endinput +% +% $Log: xo-page.dtx,v $ +% Revision 1.34 2000/08/11 07:14:27 latex3 +% added header +% +% Revision 1.33 2000/08/07 19:50:48 latex3 +% setup the collection@or again when a pagesetup is selected since its +% parameter might have changed. +% +% Revision 1.32 2000/08/06 19:02:51 latex3 +% move parts initialisation to \begin{document} +% move \newpage in pagesetup template first to ensure that previous page +% is finished with old values +% +% Revision 1.31 2000/08/06 09:02:57 latex3 +% documented that footnotehandling needs fixing +% +% Revision 1.30 2000/08/04 10:23:24 latex3 +% removed float-text-shrink and float-inline-shrink keys and instead +% used \split@skip +% +% Revision 1.29 2000/07/26 20:45:51 latex3 +% first implementation of grid point support +% +% Revision 1.28 2000/07/21 13:52:53 latex3 +% more renaming for float sequence class concept +% +% Revision 1.27 2000/07/18 21:07:03 latex3 +% introduced float sequence classes +% +% Revision 1.26 2000/07/12 16:47:44 latex3 +% use grid points properly in template +% +% Revision 1.25 2000/07/10 21:04:30 latex3 +% integration of float specing parameters in page setup +% support for grid typesetting in page setup +% +% Revision 1.24 2000/07/04 19:44:58 latex3 +% fix marginal footnote template (did change column calculations) +% +% Revision 1.23 2000/06/26 15:01:29 latex3 +% docu update +% +% Revision 1.22 2000/06/21 09:56:09 latex3 +% update docu +% +% Revision 1.21 2000/06/18 15:00:35 latex3 +% move "Bottom float footnote relation" to xo-place file +% +% Revision 1.20 2000/06/16 11:06:05 latex3 +% support float-callout-span-constraint +% +% Revision 1.19 2000/06/15 17:49:55 latex3 +% moved macros about placment checking to xo-place since they don't +% belong here +% +% Revision 1.18 2000/06/15 15:21:33 latex3 +% implemented new semantics for area names +% +% Revision 1.17 2000/06/13 21:21:08 latex3 +% added support for columnheight (tmp) +% define \pagebodytopvpos etc inside template so that it can change +% +% Revision 1.16 2000/05/03 18:48:42 latex3 +% initialise float area data structure the moment the float area is +% declared (otherwise you can't declare areas if they are not used!) +% +% add keys defer-type-close-list and defer-all-close-list to pagesetup2 +% template +% +% Revision 1.15 2000/04/21 19:03:58 latex3 +% added footnote setup +% cleanup pagesetup code +% +% Revision 1.14 2000/04/08 10:48:42 latex3 +% code cleanup +% +% Revision 1.13 2000/04/08 08:16:53 latex3 +% default for \pagesetup@flush@float@callout changed +% +% Revision 1.12 2000/03/31 17:07:24 latex3 +% don't fail in footnote/float test if there isn't any bottom area at +% all! +% +% Revision 1.11 2000/03/24 15:34:27 latex3 +% version that starts supporting spans (still a hack yet) +% +% Revision 1.10 2000/03/22 15:51:51 latex3 +% some normalisations of names +% +% Revision 1.9 2000/03/17 20:25:02 latex3 +% initialise fl@0 +% support relaxing constraints when flushing +% +% Revision 1.8 2000/03/15 19:58:00 latex3 +% assigning values to \column@number should always be done globally +% +% Revision 1.7 2000/03/05 19:41:21 latex3 +% support multiple columns (6 max right now) +% +% Revision 1.6 2000/02/26 18:21:16 david +% fixed footnote bottom constraint code +% +% Revision 1.5 2000/02/26 16:52:25 david +% *** empty log message *** +% +% Revision 1.4 2000/02/17 22:41:38 david +% *** empty log message *** +% +% Revision 1.4 2000/02/16 13:41:06 latex3 +% added 3col support +% +% Revision 1.3 2000/02/13 14:38:53 latex3 +% was 1.2.1.2 +% +% Revision 1.2.1.2 2000/02/13 11:51:27 latex3 +% fixed \check@callout@after (hopefully correct now) +% added \check@some@constraints logic +% diff --git a/Master/texmf-dist/source/latex3/xor/xo-place.dtx b/Master/texmf-dist/source/latex3/xor/xo-place.dtx new file mode 100644 index 00000000000..0a208459540 --- /dev/null +++ b/Master/texmf-dist/source/latex3/xor/xo-place.dtx @@ -0,0 +1,1537 @@ +% \iffalse +%% +%% (C) Copyright 1999-2000 Frank Mittelbach, David Carlisle, Chris Rowley +%% All rights reserved. +%% +%% Not for general distribution. In its present form it is not allowed +%% to put this package onto CD or an archive without consulting the +%% the authors. +%% +% \fi +% + +% \begin{macrocode} +\def\@tempa#1: #2.dtx,v #3 #4 #5 #6 #7${ + \ProvidesPackage{#2}[#4 #3 #5 #6]} +\@tempa$Id: xo-place.dtx,v 1.37 2000/08/11 07:14:28 latex3 Exp $ +% \end{macrocode} +% +% +% +% Ignore white space in this package. +% \begin{macrocode} +\IgnoreWhiteSpace +% \end{macrocode} +% +% +% +% \subsection{Selecting the next area to try} +% +% +% \begin{macro}{\std@try@this@area} +% The |\std@try@this@area| command is called when we have +% selected a float from the |\@activelist| and want to place it +% in one of the open areas to see if it fits there. If we succeed +% in finding a potential candidate place we will exit using +% |\contruct@trial| which will run a trial cutting the galley to +% see if each column gets the right kind of text and contains the +% right kind of callouts. +% The areas are tried in a defined order. +% +% If we don't find any open areas we return putting the current +% float onto the |\area@ddd| and then calling |\@trynextfloat|. +% +% If we find an open area but for some reason the float is not +% allowed to go there we close that area for floats of this type +% and recurse (i.e. try to use the next open area for this type). +% +% The reasons for failure to place the float into the first open +% area are numerous. First there are restrictions on the number of +% floats on a page (if we reach this all areas get closed) there +% there are similar restrictions for each individual float area. +% +% If those tests are passed we trial typeset the float with its +% caption (or rather typeset and attach its caption) to determine +% the size needed by the float. That will give us a dimension to +% test against restrictions for the amount of space floats are +% allowed to occupy etc. +% +% \begin{macrocode} +\def\std@try@this@area{ +%<*trace> + \@tracepush{std@try@this@area} +%</trace> +% \end{macrocode} +% If all areas for the float type are closed we have to defer this float. +% \begin{macrocode} + \ifx\this@open@areas\@empty +%<*trace> + \tr@ce{defer:~no~open~area~ available} +%</trace> + \do@next\defer@and@try@next@float + \else +% \end{macrocode} +% Otherwise the next area to try is the first of |\this@open@areas|: +% \begin{macrocode} + \setup@this@area{\expandafter\@carcube\this@open@areas\@nil} +%<*trace> + \tr@ce{area~trial:~ \this@area} +%</trace> +%<*progress> + \progress{~ area~trial:~ \this@area} +%</progress> +% \end{macrocode} +% Next test needs cleanup once the span has a decent data +% structure.\footnote{FIX!!} +% \begin{macrocode} + \ifnum \this@area@span@number = \if!\this@span@number! 1\else % big hack + \this@span@number \fi + \relax +%<*trace> + \tr@ce{span~ count~ okay:~ \this@area \space =~ + \if!\this@span@number! 1\else % big hack + \this@span@number \fi} +%</trace> +% \end{macrocode} +% +% \begin{macrocode} + \ifnum \pagesetup@max@float@num > \page@float@count +% \end{macrocode} +% +% \begin{macrocode} + \ifnum\csname pagesetup@\this@area @float@num\endcsname = + \csname \this@area @float@count \endcsname +% +% \end{macrocode} +% Current area doesn't accept any more floats, so try next one (if any) +% \begin{macrocode} +%<*trace> + \tr@ce{close~area:~\this@area\space float~num~reached ~ + (\csname pagesetup@\this@area @float@num\endcsname)} +%</trace> +%<*progress> + \progress@failed{\this@area\space float~num~reached ~ + (\csname pagesetup@\this@area @float@num\endcsname)} +%</progress> + \do@next\try@next@area +% \end{macrocode} +% +% \begin{macrocode} + \else + \xin@\this@area + \this@page@closed + \ifin@ +%<*trace> + \tr@ce{area~ closed~ for~ all~ types;~ member~ of~ + (\this@page@closed)} +%</trace> +%<*progress> + \progress@failed{area~ closed~ for~ all~ types} +%</progress> + \do@next\try@next@area + \else +%<*trace> + \tr@ce{area~ not~ closed~ for~ all~ types:~ not~ member~ of~ + (\this@page@closed)} +%</trace> + \xin@\this@area + \this@closed@areas + \ifin@ +%<*trace> + \tr@ce{area~ closed~ for~ class~ \this@class;~ member~ of~ + (\this@closed@areas)} +%</trace> +%<*progress> + \progress@failed + {area~ closed~ for~ class~ \this@class} +%</progress> + \do@next\try@next@area + \else +%<*trace> + \tr@ce{area~ open~ for~ class~ \this@class;~ not~ member~ of~ + (\this@closed@areas)} +%</trace> + \xin@\this@area\this@fps + \ifin@ +% + \append@caption@to@float + \construct@and@test@col@hts + \if@test + \do@next\try@next@area + \else + \do@next\pretests@success@action + \fi + + \else +%<*trace> + \tr@ce{close~area:~\this@area\space float~not~allowed~ + by~ user~ control~ (\this@fps)} +%</trace> +%<*progress> + \progress@failed{\this@area\space float~not~allowed~ + by~ user~ control~ (\this@fps)} +%</progress> + \do@next\try@next@area + \fi + \fi + \fi + \fi + \else +% defer + \global\let\this@open@areas\@empty +%<*trace> + \tr@ce{defer:~max~float~num~reached ~(\pagesetup@max@float@num)} +%</trace> +%<*progress> + \progress@failed{max~float~num~reached ~(\pagesetup@max@float@num)} +%</progress> + \do@next\defer@and@try@next@float + \fi + \else +%<*trace> + \tr@ce{span~ count~ unsuitable:~ \this@area \space /=~ + \if!\this@span@number! 1\else % big hack + \this@span@number \fi} +%</trace> +%<*progress> + \progress@failed{span~ count~ \this@area \space /=~ + \if!\this@span@number! 1\else % big hack + \this@span@number \fi} +%</progress> + \do@next\try@next@area + \fi + \fi +%<*trace> + \@tracepop{std@try@this@area} +%</trace> + \do@continue +} +% \end{macrocode} +% \end{macro} +% +% +% +% +% \begin{macro}{\do@next} +% Emergency macro to reduce the number of input levels (as the code +% got past the internal default of 300). This is because we have a +% lot of recursion going on without being tail +% recursion. Essentially this means some of the code needs slightly +% different implementation.\footnote{fix} +% \begin{macrocode} +\def\do@next{\let\do@continue} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\relaxed@try@this@area} +% \begin{macrocode} +\def\relaxed@try@this@area{ +%<*trace> + \@tracepush{relaxed@try@this@area} +%</trace> +% \end{macrocode} +% If all areas for the float type are closed we have to defer this float. +% \begin{macrocode} + \ifx\this@open@areas\@empty +%<*trace> + \tr@ce{defer:~no~open~area~ available} +%</trace> + \do@next\defer@and@try@next@float + \else +% \end{macrocode} +% Otherwise the next area to try is the first of |\this@open@areas|: +% \begin{macrocode} + \setup@this@area{\expandafter\@carcube\this@open@areas\@nil} +%<*trace> + \tr@ce{area~trial:~ \this@area} +%</trace> +%<*progress> + \progress{~ area~trial:~ \this@area} +%</progress> +% \end{macrocode} +% Next test needs cleanup once the span has a decent data +% structure.\footnote{FIX!!} +% \begin{macrocode} + \ifnum \this@area@span@number = \if!\this@span@number! 1\else % big hack + \this@span@number \fi + \relax +%<*trace> + \tr@ce{span~ count~ okay:~ \this@area \space =~ + \if!\this@span@number! 1\else % big hack + \this@span@number \fi} +%</trace> +% \end{macrocode} +% +% \begin{macrocode} + \xin@\this@area\this@page@closed + \ifin@ +%<*trace> + \tr@ce{area~ closed~ for~ all~ types;~ member~ of~ + (\this@page@closed)} +%</trace> +%<*progress> + \progress@failed{area~ closed~ for~ all~ types} +%</progress> + \do@next\try@next@area + \else +%<*trace> + \tr@ce{area~ not~ closed~ for~ all~ types:~ not~ member~ of~ + (\this@page@closed)} +%</trace> + \xin@\this@area + \this@closed@areas + \ifin@ +%<*trace> + \tr@ce{area~ closed~ for~ class~ \this@class;~ member~ of~ + (\this@closed@areas)} +%</trace> +%<*progress> + \progress@failed + {area~ closed~ for~ class~ \this@class} +%</progress> + \do@next\try@next@area + \else +%<*trace> + \tr@ce{area~ open~ for~ class~ \this@class;~ not~ member~ of~ + (\this@closed@areas)} +%</trace> + \append@caption@to@float + \construct@and@test@col@hts + \if@test + \do@next\try@next@area + \else + \do@next\pretests@success@action + \fi + \fi + \fi + \else +%<*trace> + \tr@ce{span~ count~ unsuitable:~ \this@area \space /=~ + \if!\this@span@number! 1\else % big hack + \this@span@number \fi} +%</trace> +%<*progress> + \progress@failed{span~ count~ \this@area \space /=~ + \if!\this@span@number! 1\else % big hack + \this@span@number \fi} +%</progress> + \do@next\try@next@area + \fi + \fi +%<*trace> + \@tracepop{relaxed@try@this@area} +%</trace> + \do@continue +} +% \end{macrocode} +% \end{macro} +% +% +% +% +% \begin{macro}{\construct@and@test@col@hts} +% The |\construct@and@test@col@hts| loops over all columns +% affected by the float area we want to place our float into +% and reduces the column size as +% needed. It sets the switch |@test| to true in case the float +% doesn't fit into area for some reason. It is up to the calling +% macro to take proper action in this case (including resetting +% column heights to their former values). +% \begin{macrocode} +\def\construct@and@test@col@hts { +% \end{macrocode} +% We use the information from the area not from the float (which +% allows us to put small floats into larger areas. +% \begin{macrocode} + \update@this@area@columns + { + \expandafter + \construct@and@test@col@ht + \csname col@ht@ \the\count@ \endcsname + {\the\count@} +% \end{macrocode} +% We need to break out of the updating loop if we found a column that +% doesn't work, a) to save time and b) since the +% |\construct@and@test@col@ht| resets the switch again to false +% (in the current implementation). +% \begin{macrocode} + \if@test + \count@\z@ % break out of loop + \fi + } +} +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\construct@and@test@col@ht} +% The |\construct@and@test@col@ht| reduces the height of one column +% by the size of the current float (plus some suitable extra space) +% and tests if this reduction is possible/allowed. It sets the +% switch |@test| to true if it encounters a problem. +% \begin{macrocode} +\def\construct@and@test@col@ht#1#2{ +%<*trace> + \tr@ce{col height~before:~ \the#1 (\string#1)} +%</trace> +% \end{macrocode} +% In |\@tempdima| we calculate the amount of space we need if we +% place the float. This is the size of the float, i.e., its height +% and depth, plus either |\pagesetup@float@text@sep| if this is the +% very first float in this column (on top or on bottom), or +% |\pagesetup@float@area@sep| if it is the first float in the +% current area, or |\pagesetup@float@float@sep| if we already have +% floats in this area. +% \begin{macrocode} + \@tempdima \ht\this@captioned@float + \advance \@tempdima \dp\this@captioned@float + \ifnum \csname col@ \this@area@type + @floats@#2@number\endcsname + = \z@ +%<*trace> + \tr@ce{first~ float~ in~ any~ \this@area@type\space + in~ column~ #2:~ + adding~ \string\pagesetup@float@text@sep + =\the\pagesetup@float@text@sep} +%</trace> + \advance \@tempdima \pagesetup@float@text@sep + \else + \advance \@tempdima + \expandafter + \ifx \csname area@\this@area\endcsname\@empty + \pagesetup@float@area@sep +%<*trace> + \tr@ce{first~ float~ in~ \this@area :~ + adding~ \string\pagesetup@float@area@sep + =\the\pagesetup@float@area@sep} +%</trace> + \else + \pagesetup@float@float@sep +%<*trace> + \tr@ce{additional~ float~ in~ \this@area :~ + adding~ \string\pagesetup@float@float@sep + = \the\pagesetup@float@float@sep} +%</trace> + \fi + \fi +% \end{macrocode} +% Now we make the area size fully fall into the page grid (if there +% is one). To do this we first substract any delta that has been +% accumulated for the column (to get back to the real size) and +% then run |\snap@to@grid| to get the next grid point. +% \begin{macrocode} + \advance \@tempdima + -\csname col@ \this@area@type @delta@ #2 \endcsname \relax +% \end{macrocode} +% The |\col@|\meta{area-type}|@delta@|\meta{col} are macros but +% fortunately low-level \TeX{} supports register assignments of the +% form |--3pt| so the above will work even if the macro contains a +% negative value. +% \begin{macrocode} + \snap@to@grid \@tempdima \pagesetup@grid@point@sep +% \end{macrocode} +% +% If the distance to the next grid point is larger than the +% distance to the previous one, and if the space between floats and +% text is allowed to shrink by the needed amount we will use the +% previous grid point. +% \begin{macrocode} + \ifdim \returned@lower@delta@size < \returned@delta@size \relax + \ifdim \returned@lower@delta@size < \pagesetup@float@text@shrink +%<*trace> + \tr@ce{GRID:~ column~#2:~ choosing~ lower~ grid~ point} +%</trace> +% \end{macrocode} +% We do this by copying the |\returned@lower@...| to the macros +% used below. Note that for the delta size we have to use the +% negation since we want to backup by this amount and delta sizes +% are always given in absolute values. +% \begin{macrocode} + \global\let \returned@size \returned@lower@size + \xdef \returned@delta@size {-\returned@lower@delta@size } + \fi + \fi +%<*trace> + \tr@ce{GRID:~ column~#2:~ \the\@tempdima\space ->~ \returned@size} +%</trace> + \@tempdima \returned@size +% \end{macrocode} +% +% After updating |\@tempdima| in this way we now have to check if +% the space remaining for the text column is large enough. +% \begin{macrocode} + \@tempdimb#1 + \advance \@tempdimb -\@tempdima + \@testfalse + \ifdim \textminlines\baselineskip > \@tempdimb +% \end{macrocode} +% If not we bail out +% \begin{macrocode} + \@testtrue +%<*trace> + \tr@ce{close~area:~\this@area\space not~ enough~ text~ lines~ + left~ + (\textminlines x\the\baselineskip> \the\@tempdimb)} +%</trace> +%<*progress> + \progress@failed{not~ enough~ text~ space~ + (\textminlines x\the\baselineskip\space + >~ \the\@tempdimb)} +%</progress> + \else +% \end{macrocode} +% Otherwise we have to update the column heights (and their saved +% version in case we back out later) as well as storing the new +% delta (which is still in |\returned@delta@size|). +% \begin{macrocode} +%<*trace> + \tr@ce{saved@col@ht@ #2~ <-~\the#1} +%</trace> + \expandafter\xdef + \csname saved@col@ht@ #2\endcsname{\the#1} + \global#1\@tempdimb + \global\expandafter\let + \csname saved@col@ \this@area@type @delta@ #2 \expandafter \endcsname + \csname col@ \this@area@type @delta@ #2 \endcsname + \global\expandafter\let + \csname col@ \this@area@type @delta@ #2 \endcsname + \returned@delta@size +%<*trace> + \tr@ce{GRID (delta):~ column~#2\this@area@type:~ + \csname saved@col@ \this@area@type @delta@ #2 + \endcsname\space ->~ \returned@delta@size} +%</trace> + \fi +%<*trace> + \tr@ce{col height~after:~ \the#1} +%</trace> +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\textminlines} +% Tmp definition; should be interfaced to pagesetup. +% \begin{macrocode} +\def\textminlines{4} +% \end{macrocode} +% \end{macro} +% +% +% +% \subsection{Supporting grid based designs} +% +% +% +% \begin{macro}{\pagesetup@grid@point@sep} +% |\pagesetup@grid@point@sep| is the distance between grid points +% for page design or 0pt if we are not doing grid design. +% \begin{macrocode} +\let\pagesetup@grid@point@sep\ERROR +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\snap@to@grid} +% |\snap@to@grid| takes a dimension as first argument and a +% ``grid-size'' as second argument and from those two values +% calculates a new dimension which is a multiple of the grid-size +% and equal or larger than the first argument. +% +% It returns this calculated value globally in |\returned@size|. In +% addition it will return in |\returned@delta@size| the delta +% between the original and the new dimension. +% +% It also returns a lower or equal grid point in +% |\returned@lower@size| and the delta to it (absolute value) in +% |\returned@lower@delta@size|. +% +% Thus the first argument lies on a grid point if and only if +% |\returned@size| equals |\returned@lower@size|. +% +% If we are not doing grid typesetting then |\snap@to@grid| is +% actually a dummy which will return always the first argument in +% |\returned@size| and |\returned@lower@size|, and |0pt| in the +% deltas. +% +% The actual definition is assigned within the page setup. +% \begin{macrocode} +\let\snap@to@grid\ERROR +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\dummy@snap@to@grid} +% In case we don't do grids we simply pretend that all sizes lie on +% grid points. +% \begin{macrocode} +\def \dummy@snap@to@grid #1#2{ + \begingroup +% \end{macrocode} +% Definitions below can be optimised for speed but the ones used +% give better tracing. +% \begin{macrocode} + \@tempdima #1 \relax + \xdef \returned@size { \the\@tempdima } + \global\let \returned@lower@size \returned@size + \gdef \returned@delta@size {0pt} + \global\let \returned@lower@delta@size \returned@delta@size + \endgroup +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\std@snap@to@grid} +% But if we do grid typesetting we have to do a bit more work +% here. +% \begin{macrocode} +\def \std@snap@to@grid #1#2{ +% \end{macrocode} +% Everything is done in a group so that the register change do not +% affect other parts of the code. +% \begin{macrocode} + \begingroup +% \end{macrocode} +% First we calculate in |\@tempdimc| the nearest grid point which +% is smaller or equal to the given size in |#1| by using scaled +% point arithmetic. +% \begin{macrocode} + \@tempdima #1\relax + \@tempdimb #2\relax + \@tempcnta \@tempdima % orig size in sp + \@tempcntb \@tempdimb % grid size in sp + \divide \@tempcnta \@tempcntb + \@tempdimc \@tempcnta\@tempdimb +% \end{macrocode} +% If the calculated grid point is smaller than the original +% dimension use the next larger one. But record the other in +% |\returned@lower@size|. +% \begin{macrocode} + \ifdim \@tempdimc < \@tempdima + \xdef \returned@lower@size { \the\@tempdimc } + \advance\@tempdimc \@tempdimb + \fi +% \end{macrocode} +% The |\returned@size| will be whatever the result of the above is +% and |\returned@delta@size| the difference to the given value in +% |#1|. Note that |\returned@size| will always be larger or equal +% to this value so the difference computed below will also be +% non-negative! +% \begin{macrocode} + \xdef \returned@size { \the\@tempdimc } + \advance \@tempdimc -\@tempdima + \xdef \returned@delta@size { \the\@tempdimc } +% \end{macrocode} +% Now if this difference turns out to be zero then we actually +% started with a dimension exactly on a grid point. In this case we +% better define both |\returned@lower@size| and +% |\returned@lower@delta@size| to equal their counterparts. +% \begin{macrocode} + \ifdim \@tempdimc = \z@ + \global \let \returned@lower@size \returned@size + \global \let \returned@lower@delta@size \returned@delta@size +% \end{macrocode} +% Otherwise we only have to compute |\returned@lower@delta@size| +% since in that case we already recorded |\returned@lower@size| +% above (and we better had since by now we lost this information as +% we reused |\@tempdimc|). Now the value for this macro should be +% the difference between |\returned@delta@size| and our grid size +% both of which are already stored in some temp registers, +% thus\ldots +% \begin{macrocode} + \else + \advance\@tempdimb-\@tempdimc + \xdef \returned@lower@delta@size { \the\@tempdimb } + \fi + \endgroup +%<*trace> + \tr@ce{GRID:~ \string\returned@lower@size=\returned@lower@size} + \tr@ce{GRID:~ \string\returned@lower@delta@size=\returned@lower@delta@size} + \tr@ce{GRID:~ \string\returned@size=\returned@size} + \tr@ce{GRID:~ \string\returned@delta@size=\returned@delta@size} +%</trace> +} +% \end{macrocode} +% \end{macro} +% +% +% +% +% +% \subsection{Deferring a float} +% +% +% +% \begin{macro}{\really@defer@and@try@next@float} +% \begin{macrocode} +\def\really@defer@and@try@next@float{ +%<*progress> + \progress@failed{-->~ defer} + \progress@nl{} +%</progress> + \@cons\area@ddd\this@float@box +%<*trace> + \tr@ce{this@page@closed~ <-~ "\this@page@closed"~ +~ + "\pagesetup@ddd@all@close"} +%</trace> + \xdef\this@page@closed{\this@page@closed, + \pagesetup@ddd@all@close} + + \ifx\pagesetup@ddd@class@close\pagesetup@area@list +%<*trace> + \tr@ce{this@closed@areas~ <-~ + "\pagesetup@ddd@class@close"~ (all~ closed)} +%</trace> + \global\let\this@closed@areas\pagesetup@ddd@class@close + \else +%<*trace> + \tr@ce{this@closed@areas~ <-~ "\this@closed@areas"~ +~ + "\pagesetup@ddd@class@close"} +%</trace> + \xdef\this@closed@areas{\this@closed@areas, + \pagesetup@ddd@class@close} + \fi + + \global\expandafter\let\csname closed@\this@class + @areas\endcsname % FMi tmp + \this@closed@areas + \try@next@float +} +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\defer@and@try@next@float} +% +% This code either defers the current float and restarts by calling +% |\try@next@float| or recurses after relaxing the placement +% conditions (in case the current float should be flushed). +% +% If the placement conditions are already relaxed we move the first +% flush point that affects the current float one column forward and +% then retry. This might result in succeding to place the float, if +% not it will ultiamtely result in the flush point being moved from +% the page at which point the float can be deferred. +% +% \begin{macrocode} +\def\defer@and@try@next@float{ +%<*trace> + \@tracepush{defer@and@try@next@float} +%</trace> +% \end{macrocode} +% If there have been no flush points or if the flush points seen do +% not affect the current float we can immediately defer it. +% \begin{macrocode} + \if@flushseen + \xin@\this@class\flush@classes@list@max + \ifin@ +%<*trace> + \tr@ce{flush:~ class~ \this@class\space in~ + \flush@classes@list@max} +%</trace> +% \end{macrocode} +% First test is just there to avoid doing any of the loops +% (might not be worth having) +% \begin{macrocode} + \ifnum \csname flush@min@col@1\endcsname > \curr@col@count +%<*trace> + \tr@ce{flush:~ no~ flush~ points~ on~ page;~ defer} +%</trace> + \do@next\really@defer@and@try@next@float + \else +% \end{macrocode} +% +% The code is often invoked before there is an attempt to split the +% galley; this means we don't know which flush point affects the +% current float and thus have to manually get at it. +% +% So we loop through the |\flush@last@float@|\meta{num} values to +% find the first one that a) affects the current float type and b) +% holds a sequence number that is higher or equal to the sequence +% number of the current float. +% \begin{macrocode} + \count@ \@ne + \loop +% \end{macrocode} +% If |\count@| is greater than |\flush@seq@num| we have exhausted +% all possible flush points without finding a candidate. +% \begin{macrocode} + \ifnum \flush@seq@num < \count@ + \in@false + \else +% \end{macrocode} +% Otherwise, if |\this@sequence@number| is greater than +% |\flush@last@float@|\meta{num} the current flush point is before +% the call-out to the current float. +% \begin{macrocode} +%<*trace> + \tr@ce{flush:~ \this@sequence@number \space ???~ + \csname flush@last@float@ \the\count@ \endcsname} +%</trace> + \ifnum \this@sequence@number > + \csname flush@last@float@ \the\count@ \endcsname + \relax +% \end{macrocode} +% We set |\in@true| to get a repeat below with a new value of +% |\count@|. +% \begin{macrocode} + \in@true + \else +% \end{macrocode} +% Otherwise we have a flush point that is later in the galley in +% comparison to the call-out of the current float thus potentially +% affects it. Therefore we now have to check if the sequence class +% of the current float is affected by the flush point found: +% \begin{macrocode} + \expandafter\xin@\expandafter\this@class + \csname flush@classes@list@ \the\count@ \endcsname +% \end{macrocode} +% Now we could make good use of the |\unless| primitive of +% e\TeX. But since we want to run with standard \TeX{} and don't +% have |\xnotin@| available we invert the result. +% \begin{macrocode} + \ifin@ + \in@false + \else + \in@true +%<*trace> + \tr@ce{flush:~ class~ \this@class\space not~ in~ + \csname flush@classes@list@ \the\count@ \endcsname + \space (ignored) + } +%</trace> + \fi + \fi + \fi + \ifin@ + \advance\count@\@ne + \repeat +%<*trace> + \tr@ce{flush:~ first~ float~ point~ after~ float~ =~ + \the\count@} +%</trace> + \ifnum \flush@seq@num < \count@ +%<*trace> + \tr@ce{flush:~ this~ float~ past~all~flush~ points;~ defer} +%</trace> + \do@next\really@defer@and@try@next@float + \else +% \end{macrocode} +% Once a |flush@min@col| is larger than |\curr@col@count| it has +% moved to the next page. In particular this is true for the +% artificial value |\maxdimen| to which it is sometimes set to +% denote this fact. If so we can defer our float. +% \begin{macrocode} + \ifnum \csname flush@min@col@\the\count@\endcsname + > \curr@col@count +%<*trace> + \tr@ce{flush:~ float~ past~ all~ flush~ points~ + on~ current~ page;~ defer} +%</trace> + \do@next\really@defer@and@try@next@float + \else +% \end{macrocode} +% If we have already relaxed the conditions and we are still in +% conflict with a flush point on the current page we nearly ran out +% of options. In this case we are forced to move the flush point, +% but rather than moving it to the next page and defering the float +% we can move it one column further (which might make it fall off +% the page though) and then retry to place the float since we have +% now more space available. +% \begin{macrocode} + \ifx\try@this@area\relaxed@try@this@area +%<*trace> + \tr@ce{flush:~ defer~ forced;~ move~ + flush~ point~ columns} +%</trace> +%<*progress> + \progress@nl{} + \progress@nl{Flushing~ impossible~ -->~ breaking~ + before~ flush~ point~ and~ retry} +%</progress> +% \end{macrocode} +% We should only increment the |flush@min@col@| value of the first +% flush point that affects our float (this will automatically move +% later flush points if necessary). Incrementing the later ones is +% incorrect as they might not need moving! +% \begin{macrocode} + \expandafter \gincrement@num + \csname flush@min@col@ \the\count@ \endcsname +%<*trace> + \tr@ce{flush@min@col@\the\count@ \space <-~ + \csname flush@min@col@ \the\count@ \endcsname + } +%</trace> +%<*progress> + \progress@nl{} + \progress@nl{Defer~ impossible~ -->~ moving~ + flush~ point~ to~ column~ + \csname flush@min@col@ \the\count@\endcsname + \space + and~ retry} +%</progress> +% \end{macrocode} +% Not clear that it is really necessary to check all areas again, +% but it is late (after midnight) and it is definitely not +% wrong.\footnote{Check!} +% \begin{macrocode} + \relax@float@placement@conditions % needed to reset open areas + \do@next\try@this@area + + \else +% \end{macrocode} +% +% \begin{macrocode} + \relax@float@placement@conditions + \do@next\try@this@area + \fi + \fi + \fi + \fi + \else +%<*trace> + \tr@ce{flush:~ class~ \this@class\space not~ in~ + \flush@classes@list@max;~ defer} +%</trace> + \do@next\really@defer@and@try@next@float + \fi + + \else +%<*trace> + \tr@ce{flush:~ no~ flush~ point~ seen; defer} +%</trace> + \do@next\really@defer@and@try@next@float + \fi + +%<*trace> + \@tracepop{defer@and@try@next@float} +%</trace> + \do@continue +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\relax@float@placement@conditions} +% \begin{macrocode} +\def \relax@float@placement@conditions { +%<*progress> + \progress@failed{-->~ retry~ with~ relaxed~ conditions} + \progress@nl{} +%</progress> +%<*trace> + \tr@ce{flush:~relax~placement~conditions} +%</trace> + \global\let\try@this@area\relaxed@try@this@area +% next line perhaps external? + \global\let\this@open@areas\saved@this@open@areas + + \global\let\check@some@constraints\relaxed@check@some@constraints + \global\let\check@callout@constraints\relaxed@check@callout@constraints + \global\let\calculate@target@fl@column\relaxed@calculate@target@fl@column +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\tighten@float@placement@conditions} +% \begin{macrocode} +\def\tighten@float@placement@conditions { +%<*trace> + \tr@ce{flush:~tighten~placement~conditions} +%</trace> + \global\let\try@this@area\std@try@this@area + + \global\let\check@some@constraints\std@check@some@constraints + \global\let\check@callout@constraints\std@check@callout@constraints + \global\let\calculate@target@fl@column\std@calculate@target@fl@column +} +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\partly@tighten@float@placement@conditions} +% This is used when we have placed the last float that is affected +% by a certain flush point. We don't want to tighten up completely +% since this would essentially mean that we can't place any further +% floats since callout relationships etc might be violated for +% them. Good question is whether or not the last restriction should +% be used again since this too might prevent any further placements. +% \begin{macrocode} +\def\partly@tighten@float@placement@conditions { +%<*trace> + \tr@ce{flush:~partly~tighten~placement~conditions} +%</trace> + \global\let\try@this@area\std@try@this@area + +% \global\let\check@some@constraints\std@check@some@constraints +% \global\let\check@callout@constraints\std@check@callout@constraints + \global\let\calculate@target@fl@column\std@calculate@target@fl@column +} +% \end{macrocode} +% \end{macro} +% +% +% +% \subsection{Checking float placement during trial} +% +% The interface to checking float placement in relation to its callout +% is the following piece of code in |\grab@column@or|: +%\begin{verbatim} +% \let\@elt\check@callout@constraints +% \float@classes@list +%\end{verbatim} +% This loops through all float types and executes +% |\check@callout@constraints| with the float type as an argument. The output +% routine |\grab@column@or| itself is called for each column of a trial +% configuration, thus the above loop is called for each column +% individually (|\curr@col@count| can be used to determine the current +% column number). +% +% By giving |\check@callout@constraints| an appropriate definition a +% pagesetup template can implement different relationships between +% callout and float. +% +% Possible tests (getting stronger): +% \begin{itemize} +% +% \item +% Don't check, i.e., add the float when you find it and it fits +% according to other criteria (like number of floats in the area, +% etc.). This is implemented in |\check@callout@none|. +% +% +% \item +% Check if callouts for all floats on the page (not column) are +% either on the same page or on an earlier page; i.e., callout can be +% late as long as the float is visible from the callout. +% +% Fail if for last column and all float types: +% last callout number for float type is smaller than maximum last float +% of type put into any column.\footnote{This description is +% probably wrong} +% +% This is implemented in |\check@callout@page|. +% +% \item +% Check if callouts for all floats in the column are either on the +% same column or on an earlier column. +% +% Fail if for any column and any float type: +% last callout number for float type is smaller last float sequence +% number for type recorded for this column. +% +% This case consists in fact of two subcases depending on how we +% interpret to which column a spanning float belongs. If we claim +% that a spanning float is placed into its starting column, then we +% fail if its call-out is in a later column even though this column +% might still be spanned by the float area. +% +% This is implemented in |\check@callout@column|. +% +% \item +% Check if callouts for all floats in the column are on an earlier +% column or if on the same column the float was added to the bottom +% (or marginal) area; i.e. strict float/callout order +% +% Fail if for each type and for any column: +% `top' callout number less than `top' float number +% (at top of text column) +%\begin{verbatim} +% [Corectness proof: +% TRUE => first callout's float comes before bottom +% and so comes too early +% => FAIL +% FALSE => first callout's float comes in bottom and all other +% callouts come later and so are in bottom or beyond +% => OK +% ] +%\end{verbatim} +% The proof above is in fact only valid if you look at the whole +% document and not only at a single page since a float in the bottom +% area of the last column with its callout on the next page will +% only be detected when testing the next page. Therefore one needs +% an additional check of type |\check@callout@column|. +% +% This is implemented in |\check@callout@after|. +% +% +% \end{itemize} +% +% +% \begin{macro}{\check@callout@none} +% This test is an easy one: just do nothing, i.e., gobble the argument. +% \begin{macrocode} +\let\check@callout@none\@gobble +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\check@callout@page} +% We are are only interested in the callout/float relation per page +% we only have to do a check when producing the last column, i.e., +% when |\curr@col@count| is |\col@count|. +% \begin{macrocode} +\def\check@callout@page#1{ +%<*trace> + \@tracepush{check@callout@page} +%</trace> + \ifnum\curr@col@count=\col@count +% \end{macrocode} +% We store in |\fl@max| the highest sequence number for floats of +% the current type up to the end of the page. For this we have to +% find the maximum of |\fl@0@|\meta{type} (highest float number on +% previous pages) and those for the columns, e.g., +% |\fl@|\meta{colnum}|@|\meta{type}; this is done by the following +% code: +% \begin{macrocode} + \global\expandafter\let\expandafter\fl@max + \csname fl@0@#1\endcsname + \forall@columns { + \ifnum\csname fl@\the\curr@col@count @#1\endcsname>\fl@max\relax + \xdef\fl@max{\csname fl@\the\curr@col@count @#1\endcsname} + \fi + } +% \end{macrocode} +% We then store the number of the last callout in |\count@|; the +% |0| will take care of the potential problem that there was never any +% callout so far. And we better have a |\relax| afterwards since +% otherwise we will expand the |\ifnum| before we have finished +% assigning the |\count@|. +% \begin{macrocode} + \count@0\LastMark{#1}\relax +%<*trace> + \tr@ce{Last~callout~ (#1)~ =~ \the\count@} +%</trace> +% \end{macrocode} +% Now we have to compare those two numbers to find out if that +% trial has failed: +% \begin{macrocode} + \ifnum\count@<\fl@max\relax + \@failtrue +%<*progress> + \progress@failed{last~callout~ + \the\count@\space~<~\fl@max + \space last~float~put~on~page~or~ earlier} +%</progress> +%<*trace> + \tr@ce{Failed:~(#1)~ last~callout~ + \the\count@\space~<~\fl@max + \space last~float~put~on~page~or~ earlier} + \else + \tr@ce{OK:~(#1)~ last~callout~ + \the\count@\space~>=~\fl@max + \space last~float~put~on~page~or~ earlier} +%</trace> + \fi + \fi +%<*trace> + \@tracepop{check@callout@page} +%</trace> +} +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\fl@max} +% The macro |\fl@max| is used within |\check@callout@page| to hold +% the highest sequence number of any allocated float on the current +% page for the type under testing. It will be recalculated on +% each pass.\footnote{One could generate this value while running through +% the trials --- this would perhaps be a bit more time efficient.} +% \begin{macrocode} +\let\fl@max\ERROR +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\check@callout@column} +% Checking each column separately means we have to compare for each +% type the last callout on this or previous columns (i.e., as +% returned by |\LastMark|) with the highest sequence number for +% floats of this type in the current column (as stored in +% |fl@|\meta{col}|@|\meta{type}). So we first store the callout +% info in |\count@|. +% \begin{macrocode} +\def\check@callout@column#1{ +%<*trace> + \@tracepush{check@callout@column} +%</trace> + \count@0\LastMark{#1}\relax +% \end{macrocode} +% Then we do the test. If there are no floats of the current type +% in the current column |\fl@|\meta{col}|@|\meta{type} will be zero +% and thus the following test will come out true. This is the +% correct behaviour as any callouts that might be present will be +% correctly evaluated in tests on neighboring columns with floats. +% \begin{macrocode} + \ifnum\count@<\csname fl@\the\curr@col@count @#1\endcsname\relax +%<*progress> + \progress@failed{last~ callout~ + \the\count@\space <~ + \csname fl@\the\curr@col@count @#1\endcsname + \space last~ float~ placed~ in~ column~ \the\curr@col@count} +%</progress> +%<*trace> + \tr@ce{Failed:~(#1)~ last~ callout~ + \the\count@\space <~ + \csname fl@\the\curr@col@count @#1\endcsname + \space last~float~placed} +%</trace> +% \end{macrocode} +% If the test fails we abort this trial by setting the switch +% |@fail| to true. We also set +% |\curr@col@count| to |\col@count| which will save us any further +% iteration (in case this wasn't the last column). Finally we +% locally set |\@elt| to |\@gobble| which will essentially about +% the current loop through the |\float@classes@list|. +% \begin{macrocode} + \@failtrue + \global\curr@col@count\col@count + \let\@elt\@gobble +% \end{macrocode} +% Otherwise the constraints for callout of current float type are +% met so we report this fact if we do tracing. +% \begin{macrocode} +%<*trace> + \else + \tr@ce{OK:~(#1)~ last~ callout~ + \the\count@\space >=~ + \csname fl@\the\curr@col@count @#1\endcsname + \space last~float~placed} +%</trace> + \fi +%<*trace> + \@tracepop{check@callout@column} +%</trace> +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\check@callout@after} +% +% \begin{macrocode} +\def\check@callout@after#1{ +%<*trace> + \@tracepush{check@callout@after} +%</trace> +% \end{macrocode} +% +% We first check if all floats are either on the same column than +% their callout or on an later column by calling +% |\check@callout@column|. If this returns |@fail| we immediately +% abort any further processing. +% \begin{macrocode} + \check@callout@column{#1} + \if@fail\else +% \end{macrocode} +% +% If the above check found no violation we have to check for top +% area floats that might preceed their callouts. +% +% For this we look at the value of the +% |\tfl@|\meta{col}|@|\meta{float-type} macro which holds the +% highest float sequence number for floats of this type allocated +% in that column. +% \begin{macrocode} + \global\expandafter\let\expandafter + \returned@sequence@number + \csname tfl@\the\curr@col@count @#1\endcsname +% \end{macrocode} +% +% If there was no float in the top area we get |0| back and in +% that case we are done since all our constraints are met. +% \begin{macrocode} + \ifnum \returned@sequence@number = \z@ +%<*trace> + \tr@ce{OK:~(#1)~ top~ areas~ have~ no~ floats} +%</trace> + \else +% \end{macrocode} +% +% Otherwise we have to look at the top callout number and compare +% it to the last float number of the top area. +% \begin{macrocode} + \count@ 0\PreviousMark{#1}\relax +% \end{macrocode} +% If that callout number is less than the last float number we +% failed since this means that there is a float in the top area +% which callout has not yet been seem. So we abort the +% trial. Otherwise our constraints are met. +% \begin{macrocode} + \ifnum \count@ < \returned@sequence@number \relax +% \end{macrocode} +% But before aborting we give some information on why we +% failed. This has to come first since we change |\curr@col@count| +% below. +% \begin{macrocode} +%<*progress> + \progress@failed{top~ callout~ + \the\count@\space <~ \returned@sequence@number + \space last~ float~ put~ in~ top~ + of~ column~ \the\curr@col@count} +%</progress> + \@failtrue + \global\curr@col@count\col@count + \let\@elt\@gobble +%<*trace> + \tr@ce{Failed:~(#1)~ top~ callout~ + \the\count@\space <~ \returned@sequence@number + \space last~float~put~in~top} + \else + \tr@ce{OK:~(#1)~ top~ callout~ + \the\count@\space >=~ \returned@sequence@number + \space last~float~put~in~top} +%</trace> + \fi + \fi + \fi +%<*trace> + \@tracepop{check@callout@after} +%</trace> +} +% \end{macrocode} +% \end{macro} +% +% +% +% +% \subsection{Checking bottom float footnote constraints} +% +% In |\grab@column@or|, the output routine that grabs a single column +% during a trial, we have the command |\check@some@constraints| which +% allows to check some constraints and if they aren't met is supposed +% to set the switch |@fail|. +% +% This can, for example be used to implement a constraint that bottom +% floats are only allowed if there are no footnotes in the current +% column.\footnote{At the moment this is restricted to single column +% floats. Spanning floats are always allowed.} +% +% \begin{macro}{\check@float@footnote@forbidden} +% The command |\check@float@footnote@forbidden| is the +% implementation for |\check@some@constraints| that prevents bottom +% floats if the current column contains footnotes. +% \begin{macrocode} +\def\check@float@footnote@forbidden{ +%<*trace> + \@tracepush{check@float@footnote@forbidden} +%</trace> + \ifvoid\footins + \else +% \end{macrocode} +% If the current column contains footnotes and we have bottom +% floats we fail. First we check if there is a bottom area for this +% column defined if not we pretend there is an empty one. +% \begin{macrocode} + \expandafter + \ifx \csname area@b\the\curr@col@count1\endcsname + \relax + \global\expandafter\let + \csname area@b\the\curr@col@count1\endcsname + \@empty + \fi +% \end{macrocode} +% Then we check if the bottom area is empty and fail otherwise +% \begin{macrocode} + \expandafter + \ifx \csname area@b\the\curr@col@count1\endcsname + \@empty +%<*trace> + \tr@ce{OK:~ no~ old~ bottom~ floats} +%</trace> + \else +%<*progress> + \progress@failed{old~bottom~floats:~ \expandafter\meaning + \csname area@b\the\curr@col@count1\endcsname} +%</progress> +%<*trace> + \tr@ce{Failed:~ old~bottom~floats:~ \expandafter\meaning + \csname area@b1\the\curr@col@count\endcsname} +%</trace> + \@failtrue + \fi +% \end{macrocode} +% Finally we test if the float we are try to place is going onto a +% bottom area. +% +% However we only do this if the float doesn't span.\footnote{Extend?} +% \begin{macrocode} + \ifnum \this@area@span@number = \@ne +%<*trace> + \tr@ce{this@area,column:~ \this@area,~\the\curr@col@count} +%</trace> + \if b \this@area@type + \ifnum \this@area@col@number = \curr@col@count + \@failtrue + \fi + \fi + \fi + \if@fail +%<*progress> + \progress@failed{column~ \the\curr@col@count\space + contains~ footnotes~ and~ bottom~ floats} +%</progress> +%<*trace> + \tr@ce{Failed:~ column~ \the\curr@col@count\space + contains~ footnotes~ and~ bottom~ floats} +%</trace> + \global\curr@col@count\col@count + \fi + \fi +%<*trace> + \@tracepop{check@float@footnote@forbidden} +%</trace> +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\check@float@footnote@none} +% +% This is the implementation for |\check@some@constraints| if we +% don't care about mixing footnotes and bottom floats. The reason +% |\@empty| rather than |\relax| is used is that otherwise the +% |\ifx| test in the template would fail. +% \begin{macrocode} +\let\check@float@footnote@none\@empty +% \end{macrocode} +% \end{macro} +% +% +% +% +% +% +% \endinput +\endinput +% +% $Log: xo-place.dtx,v $ +% Revision 1.37 2000/08/11 07:14:28 latex3 +% added header +% +% Revision 1.36 2000/08/11 06:49:47 latex3 +% untabify +% +% Revision 1.35 2000/08/11 06:45:03 latex3 +% only partially tighten float constraints after passing a flush point +% +% Revision 1.34 2000/07/23 21:03:19 latex3 +% removed obsolete commentary +% +% Revision 1.33 2000/07/21 13:53:17 latex3 +% more renaming for float sequence class concept +% +% Revision 1.32 2000/07/18 21:06:36 latex3 +% introduced float sequence classes +% +% Revision 1.31 2000/07/12 17:24:53 latex3 +% more support for grids +% +% Revision 1.30 2000/07/10 21:00:57 latex3 +% support for grid typesetting +% +% Revision 1.29 2000/07/04 19:42:05 latex3 +% fix tracing for GRID stuff +% +% Revision 1.28 2000/07/01 15:57:25 latex3 +% use \update@this@area@columns +% integrate code to support grid design (first draft) +% +% Revision 1.27 2000/06/29 17:18:14 latex3 +% introduced \setup@this@area +% +% Revision 1.26 2000/06/26 15:03:40 latex3 +% making prototype for \pagesetup@float@area@sep +% +% Revision 1.25 2000/06/22 20:08:09 latex3 +% renamed some macros to get them more uniform +% +% Revision 1.24 2000/06/22 11:01:24 latex3 +% When substracting heights from columns do this for the columns spanned +% by the area. Don't use the span number from the float (in the future +% this might be smaller than the span number of the area) +% +% Revision 1.23 2000/06/19 21:38:04 latex3 +% fixed flush point handling when deferring +% +% Revision 1.22 2000/06/18 19:03:53 latex3 +% added "Checking bottom float footnote constraints" from xo-page +% +% Revision 1.21 2000/06/16 11:20:15 latex3 +% rename \construct@and@test@col@height to \construct@and@test@col@ht +% rename \construct@and@test@col@heights to \construct@and@test@col@hts +% rename \cl@height1 to \@col@ht@1 (etc) +% +% Revision 1.20 2000/06/16 11:06:37 latex3 +% support float-callout-span-constraint +% +% Revision 1.19 2000/06/16 07:49:49 latex3 +% improve progress info +% +% Revision 1.18 2000/06/15 17:49:02 latex3 +% moved macros from xo-page into here since they deal with placement +% +% Revision 1.17 2000/06/15 15:23:32 latex3 +% implemented new semantics for area names +% +% Revision 1.16 2000/06/13 20:48:18 latex3 +% docu update +% +% Revision 1.15 2000/06/06 12:50:40 latex3 +% before attempting fuzzy flushpoints +% +% Revision 1.14 2000/05/03 18:57:56 latex3 +% provide \construct@and@test@col@heights subroutine +% +% fix problem that deferred floats would not stop other floats going +% into earlier areas +% +% Revision 1.13 2000/03/31 17:08:50 latex3 +% avoid using up too much input stack by using tail recursion in +% strategic places (tmp fix) +% +% Revision 1.12 2000/03/26 21:04:03 latex3 +% some renaming of macros +% +% Revision 1.11 2000/03/24 15:34:27 latex3 +% version that starts supporting spans (still a hack yet) +% +% Revision 1.10 2000/03/22 15:52:37 latex3 +% some normalisations of names +% first go at spans (tmp version) +% +% Revision 1.9 2000/03/17 20:23:11 latex3 +% more fixes to flushing (looks good now) +% +% Revision 1.8 2000/03/16 10:28:29 latex3 +% partial and full flush working for the first time +% +% Revision 1.7 2000/03/05 19:31:56 latex3 +% some renaming +% extend to multiple columns (6 max right now) +% fix defer logic: when flushseen don't defer immediately +% +% Revision 1.6 2000/02/27 15:12:45 david +% *** empty log message *** +% +% Revision 1.5 2000/02/27 11:27:45 david +% first attempt at flush floats +% +% Revision 1.4 2000/02/26 18:24:21 david +% renaming, and using \initialise@areas +% +% Revision 1.3 2000/02/16 13:40:09 latex3 +% added 3col support +% +% Revision 1.2 2000/02/16 10:10:43 latex3 +% added documentation +% added test for float area size after adding float +% +% Revision 1.1 2000/02/13 22:27:39 latex3 +% Initial revision +% diff --git a/Master/texmf-dist/source/latex3/xor/xo-trace.dtx b/Master/texmf-dist/source/latex3/xor/xo-trace.dtx new file mode 100644 index 00000000000..435994f1682 --- /dev/null +++ b/Master/texmf-dist/source/latex3/xor/xo-trace.dtx @@ -0,0 +1,140 @@ +% \iffalse +%% +%% (C) Copyright 1999-2000 Frank Mittelbach, David Carlisle, Chris Rowley +%% All rights reserved. +%% +%% Not for general distribution. In its present form it is not allowed +%% to put this package onto CD or an archive without consulting the +%% the authors. +%% +% \fi +% + +% \begin{macrocode} +\def\@tempa#1: #2.dtx,v #3 #4 #5 #6 #7${ + \ProvidesPackage{#2}[#4 #3 #5 #6]} +\@tempa$Id: xo-trace.dtx,v 1.9 2000/08/11 07:14:29 latex3 Exp $ +% \end{macrocode} +% +% Ignore white space in this package. +% \begin{macrocode} +\IgnoreWhiteSpace +% \end{macrocode} +% +% +% \begin{macrocode} +\def\showmarks{ + \toks@\expandafter{\topmark}\typeout{topmark:\the\toks@} + \toks@\expandafter{\firstmark}\typeout{firstmark:\the\toks@} + \toks@\expandafter{\botmark}\typeout{botmark:\the\toks@} +} +% \end{macrocode} +% +% \begin{macrocode} +\def\showfloatlists{{ + \let\@elt\@empty + \typeout{free:~\@freelist} + \typeout{active:~\@activelist} + \typeout{mvl:~\@mvllist} + \typeout{defer:~\area@ddd} + \typeout{assigned:} + \showfloatarea{t13} + \showfloatarea{t12} + \showfloatarea{t22} + \showfloatarea{t11} + \showfloatarea{t21} + \showfloatarea{t31} + \showfloatarea{b11} + \showfloatarea{b21} + \showfloatarea{b31} + \edef\@tempa{currbox\expandafter\strip@prefix\meaning\@currbox>\space + this@float\expandafter\strip@prefix\meaning\this@float@box>} + \show\@tempa}} + +\def\showfloatarea#1{ + \@ifundefined{area@#1}{} + {\expandafter + \ifx\csname area@#1\endcsname\@empty + \else + \typeout{~\space\space #1:~\csname area@#1\endcsname} + \fi + } +} +% \end{macrocode} +% +% \begin{macrocode} +%<*trace> +\def \@tracemessage #1{% + \begingroup\let\@elt\space\typeout{:~\tf@indent~#1}\endgroup} +% \end{macrocode} +% +% \begin{macrocode} +\let\tf@indent\@empty +% \end{macrocode} +% +% \begin{macrocode} +\def\@tracepush#1{% + \tr@ce{entering~#1} + \xdef\tf@indent{-\tf@indent}} +% \end{macrocode} +% +% \begin{macrocode} +\def\@tracepop#1{% + \tr@ce{leaving~#1} + \xdef\tf@indent{\expandafter\@gobble\tf@indent}} +% \end{macrocode} +% +% \begin{macrocode} +\def \tracefloats{\global\let \tr@ce \@tracemessage} +% \end{macrocode} +% +% \begin{macrocode} +\def \notrace {\global\let \tr@ce \@gobble} +%\notrace +% \end{macrocode} +% +% \begin{macrocode} +% \end{macrocode} +% +% \begin{macrocode} +\def\traceonly#1{ + \notrace + \def\@trace@command{#1} + \gdef\@tracepush##1{ + \def\@trace@this{##1} + \ifx\@trace@this\@trace@command + \global\let\@this@tf@indent\tf@indent + \tracefloats + \tr@ce{entering~##1} + \fi + \xdef\tf@indent{-\tf@indent}} + \def\@tracepop##1{ + \tr@ce{leaving~##1} + \xdef\tf@indent{\expandafter\@gobble\tf@indent} + \ifx\@this@tf@indent\tf@indent + \global\let\@this@tf@indent\relax + \notrace + \fi} +} +% \end{macrocode} +% +% \begin{macrocode} +\tracefloats +% \end{macrocode} +% +% \begin{macrocode} +\def \@traceval #1{\tr@ce{\string #1~=~\the #1}} +%</trace> +%<-trace>\let\tr@ce\@gobble +% \end{macrocode} +% +% \begin{macrocode} +%<*progress> +\def \progress #1{\message{#1}} +\def \progress@separator{ + \progress{=============================== + ========================================^^J}} +\def \progress@nl #1{\progress{~ #1^^J}} +\def \progress@failed #1{\progress@nl{ ->~ failed:~ #1}} +%</progress> +% \end{macrocode} diff --git a/Master/texmf-dist/source/latex3/xor/xo.ins b/Master/texmf-dist/source/latex3/xor/xo.ins new file mode 100644 index 00000000000..be726b76dfa --- /dev/null +++ b/Master/texmf-dist/source/latex3/xor/xo.ins @@ -0,0 +1,40 @@ +% +% $Id: xo.ins,v 1.4 2000/08/05 09:43:49 latex3 Exp $ + +\input docstrip +\keepsilent +\askforoverwritefalse + +\preamble + +Not for distribution + +(C) Copyright 1999-2000 Frank Mittelbach, David Carlisle, Chris Rowley +All rights reserved. + +Not for general distribution. In its present form it is not allowed +to put this package onto CD or an archive without consulting the +the authors. +\endpreamble + + + +\generate{% + \file{xmarks.sty}{\from{xmarks.dtx}{package}} + \file{xo-alloc.sty}{\from{xo-alloc.dtx}{package}} + \file{xo-capt.sty}{\from{xo-capt.dtx}{package}} + \file{xo-final.sty}{\from{xo-final.dtx}{package}} + \file{xo-float.sty}{\from{xo-float.dtx}{package}} + \file{xo-grid.sty}{\from{xo-grid.dtx}{package}} + \file{xo-here.sty}{\from{xo-here.dtx}{package}} + \file{xo-new.sty}{\from{xo-new.dtx}{package}} + \file{xo-or.sty}{\from{xo-or.dtx}{package}} + \file{xo-page.sty}{\from{xo-page.dtx}{package}} + \file{xo-place.sty}{\from{xo-place.dtx}{package}} + \file{xo-trace.sty}{\from{xo-trace.dtx}{package,trace}} + \file{xoutput.sty}{\from{xoutput.dtx}{package}} +} + +\endbatchfile + +% \file{xo-implement.sty}{\from{xo-implement-generic-algorithm.dtx}{package}} diff --git a/Master/texmf-dist/source/latex3/xor/xoprogress.ins b/Master/texmf-dist/source/latex3/xor/xoprogress.ins new file mode 100644 index 00000000000..307853273dd --- /dev/null +++ b/Master/texmf-dist/source/latex3/xor/xoprogress.ins @@ -0,0 +1,40 @@ +% +% $Id: xoprogress.ins,v 1.3 2000/08/04 15:54:51 latex3 Exp $ + +\input docstrip +\keepsilent +\askforoverwritefalse + +\preamble + +Not for distribution + +(C) Copyright 1999-2000 Frank Mittelbach, David Carlisle, Chris Rowley +All rights reserved. + +Not for general distribution. In its present form it is not allowed +to put this package onto CD or an archive without consulting the +the authors. +\endpreamble + + + +\generate{% + \file{xmarks.sty}{\from{xmarks.dtx}{package}} + \file{xo-alloc.sty}{\from{xo-alloc.dtx}{package,progress}} + \file{xo-capt.sty}{\from{xo-capt.dtx}{package,progress}} + \file{xo-final.sty}{\from{xo-final.dtx}{package,progress}} + \file{xo-float.sty}{\from{xo-float.dtx}{package,progress}} + \file{xo-grid.sty}{\from{xo-grid.dtx}{package,progress}} + \file{xo-here.sty}{\from{xo-here.dtx}{package,progress}} + \file{xo-new.sty}{\from{xo-new.dtx}{package,progress}} + \file{xo-or.sty}{\from{xo-or.dtx}{package,progress}} + \file{xo-page.sty}{\from{xo-page.dtx}{package,progress}} + \file{xo-place.sty}{\from{xo-place.dtx}{package,progress}} + \file{xo-trace.sty}{\from{xo-trace.dtx}{package,progress,trace}} + \file{xoutput.sty}{\from{xoutput.dtx}{package,progress}} +} + +\endbatchfile + +% \file{xo-implement.sty}{\from{xo-implement-generic-algorithm.dtx}{package,progress}} diff --git a/Master/texmf-dist/source/latex3/xor/xotrace.ins b/Master/texmf-dist/source/latex3/xor/xotrace.ins new file mode 100644 index 00000000000..7c5f971dcce --- /dev/null +++ b/Master/texmf-dist/source/latex3/xor/xotrace.ins @@ -0,0 +1,40 @@ +% +% $Id: xotrace.ins,v 1.4 2000/08/04 15:47:48 latex3 Exp $ + +\input docstrip +\keepsilent +\askforoverwritefalse + +\preamble + +Not for distribution + +(C) Copyright 1999-2000 Frank Mittelbach, David Carlisle, Chris Rowley +All rights reserved. + +Not for general distribution. In its present form it is not allowed +to put this package onto CD or an archive without consulting the +the authors. +\endpreamble + + + +\generate{% + \file{xmarks.sty}{\from{xmarks.dtx}{package,trace}} + \file{xo-alloc.sty}{\from{xo-alloc.dtx}{package,trace}} + \file{xo-capt.sty}{\from{xo-capt.dtx}{package,trace}} + \file{xo-final.sty}{\from{xo-final.dtx}{package,trace}} + \file{xo-float.sty}{\from{xo-float.dtx}{package,trace}} + \file{xo-grid.sty}{\from{xo-grid.dtx}{package,trace}} + \file{xo-here.sty}{\from{xo-here.dtx}{package,trace}} + \file{xo-new.sty}{\from{xo-new.dtx}{package,trace}} + \file{xo-or.sty}{\from{xo-or.dtx}{package,trace}} + \file{xo-page.sty}{\from{xo-page.dtx}{package,trace}} + \file{xo-place.sty}{\from{xo-place.dtx}{package,trace}} + \file{xo-trace.sty}{\from{xo-trace.dtx}{package,trace}} + \file{xoutput.sty}{\from{xoutput.dtx}{package,trace}} +} + +\endbatchfile + +% \file{xo-implement.sty}{\from{xo-implement-generic-algorithm.dtx}{package,trace}} diff --git a/Master/texmf-dist/source/latex3/xor/xoutput.drv b/Master/texmf-dist/source/latex3/xor/xoutput.drv new file mode 100644 index 00000000000..ee33688cd25 --- /dev/null +++ b/Master/texmf-dist/source/latex3/xor/xoutput.drv @@ -0,0 +1,144 @@ +\def\rcsdata#1: #2,v #3${ + \def\rcsdata{#2 #3}} +\rcsdata$Id: xoutput.drv,v 1.11 2000/08/04 16:42:11 latex3 Exp $ + +\documentclass[a4paper]{ltxdoc} + +\usepackage{hyperref} + +%\usepackage{trace,xoutput} + +\CodelineIndex +\EnableCrossrefs + +\setcounter{IndexColumns}{2} + +\DoNotIndex{\@elt,\@ne,\@tracepush,\@tracepop,\@empty,\@namedef} +\DoNotIndex{\@spaces} +\DoNotIndex{\advance,\aftergroup,\begingroup,\bgroup,\box,\chardef,\copy,\count,\countdef} +\DoNotIndex{\count@,\csname,\def,\do,\dimen,\dimendef\endgroup,\egroup,\else,\endcsname,\expandafter} +\DoNotIndex{\fi,\gdef,\global,\if,\ifdim,\ifeof,\ifnum,\iftrue,\ifx} +\DoNotIndex{\immediate,\let,\long,\m@ne,\mathchardef,\meaning,\message,\multiply} +\DoNotIndex{\noexpand,\read,\relax,\repeat,\setbox,\space,\string\the} +\DoNotIndex{\toks,\tr@ce,\tw@,\unskip,\unvbox,\unvcopy,\vadjust} +\DoNotIndex{\value,\vbox,\voidb@x,\vrule,\vskip,\vss,\wlog,\write,\z@} +\DoNotIndex{\hbox,\hrule,\ht,\dp,\wd,\ifinner} +\DoNotIndex{\RequirePackage,\typeout,\xdef,\tracingall} + + +\begin{document} + +\title{A new output routine for \LaTeX\thanks{\rcsdata}} +\author{\copyright\ Frank Mittelbach, David Carlisle and Chris Rowley} +\date{Started in 1996--7; first real implementation in Feb 2000 +} + +\maketitle +\tableofcontents + + +\iffalse + +\section{What has been done} + +To get a rough estimate of the work involved (and make me feel good) +look at the rcs change lines per file of the output routine +(as of June 21 2000) using: +\begin{verbatim} + for f in xo*dtx xo*tex ; do rlog $f ; done | \ + awk -f get-changes.awk |sort +\end{verbatim} + +\begin{scriptsize} +\begin{verbatim} +author: # changes # total lines # added lines # plus lines # minus lines +car2; 4 1.84332% 1907 7.21065% 773 7.97977% 1340 7.41684% -567 6.76611% +david; 51 23.5023% 3181 12.0278% 1935 19.9752% 2558 14.1584% -623 7.43437% +frank; 162 74.6544% 21359 80.7615% 6979 72.045% 14169 78.4248% +-7190 85.7995% +\end{verbatim} +\end{scriptsize} + +\fi + +\section{xoutput} +\DocInput{xoutput.dtx} + +\section{Output Routine Tracing} +\DocInput{xo-trace.dtx} + +\newpage +\section{Output Routines} +\DocInput{xo-or.dtx} + +\newpage +\section{Interfacing Here Points} +\DocInput{xo-here.dtx} + +\newpage +\section{Float Placement Algorithm} +\DocInput{xo-place.dtx} + +\newpage +\section{Page Makeup} +\DocInput{xo-final.dtx} + +\newpage +\section{Page Setup Templates} +\DocInput{xo-page.dtx} + +\newpage +\section{Float Environments} +\DocInput{xo-float.dtx} + +\section{Captions} +\DocInput{xo-capt.dtx} + +\section{Allocations} +\DocInput{xo-alloc.dtx} + +\section{Redefinitions for Grid Design} +\DocInput{xo-grid.dtx} + +\section{New stuff that needs merging (or cleanup)} +\DocInput{xo-new.dtx} + +\newpage + +\PrintIndex + +\typeout{=====================================================================} +\typeout{} +\typeout{To get proper index run the document using:} +\typeout{} +\typeout{latex xoutput.drv ; makeindex -s gind.ist xoutput ; latex xoutput.drv} +\typeout{} +\typeout{=====================================================================} + +\end{document} + +% $Log: xoutput.drv,v $ +% Revision 1.11 2000/08/04 16:42:11 latex3 +% *** empty log message *** +% +% Revision 1.10 2000/07/30 18:06:52 latex3 +% added xo-grid.dtx +% +% Revision 1.9 2000/06/15 09:34:37 latex3 +% use .dtx not .sty +% +% Revision 1.8 2000/04/21 19:09:14 latex3 +% added xo-here +% +% Revision 1.7 2000/04/07 07:29:56 latex3 +% added index +% +% Revision 1.6 2000/03/16 10:28:29 latex3 +% adding index +% +% Revision 1.5 2000/03/09 14:44:31 latex3 +% *** empty log message *** +% +% Revision 1.4 2000/03/05 19:42:59 latex3 +% new sections +% diff --git a/Master/texmf-dist/source/latex3/xor/xoutput.dtx b/Master/texmf-dist/source/latex3/xor/xoutput.dtx new file mode 100644 index 00000000000..6f0467022cc --- /dev/null +++ b/Master/texmf-dist/source/latex3/xor/xoutput.dtx @@ -0,0 +1,78 @@ +% \iffalse +%% +%% (C) Copyright 1999-2000 Frank Mittelbach, David Carlisle, Chris Rowley +%% All rights reserved. +%% +%% Not for general distribution. In its present form it is not allowed +%% to put this package onto CD or an archive without consulting the +%% the authors. +%% +% \fi +% + +% \begin{macrocode} +\def\@tempa#1: #2.dtx,v #3 #4 #5 #6 #7${ + \ProvidesPackage{#2}[#4 #3 #5 #6]} +\@tempa$Id: xoutput.dtx,v 1.13 2000/08/11 07:14:49 latex3 Exp $ +% \end{macrocode} +% +% \begin{macrocode} +\RequirePackage{ + ldcsetup, + template, + xmarks, + xparse, + xo-trace,xo-or, + xo-here, + xo-place,xo-page,xo-float,xo-capt,xo-final, + xo-alloc, + xo-new +} +% \end{macrocode} +% + + +% Ignore white space in this package. +% \begin{macrocode} +\IgnoreWhiteSpace +% \end{macrocode} +% +% +% +% +% \endinput +\endinput +% +% $Log: xoutput.dtx,v $ +% Revision 1.13 2000/08/11 07:14:49 latex3 +% added header +% +% Revision 1.12 2000/07/18 21:05:43 latex3 +% removed initialisations +% +% Revision 1.11 2000/07/12 19:44:58 latex3 +% removed some commented out code +% +% Revision 1.10 2000/06/13 21:22:29 latex3 +% turned into a dtx file +% +% Revision 1.9 2000/04/21 19:06:01 latex3 +% removed old initialisation +% added xo-here +% +% Revision 1.8 2000/03/31 17:00:18 latex3 +% fixed rcs log +% +% Revision 1.7 2000/03/22 15:53:39 latex3 +% added xparse +% +% Revision 1.6 2000/02/26 18:26:26 david +% xo-alloc and xo-new added +% +% Revision 1.5 2000/02/13 21:58:07 latex3 +% oops, my rcs again (probably something that will only show up here +% but to ensure that everything is fine I add an \endinput) +% +% Revision 1.4 2000/02/13 21:33:05 latex3 +% added xo-place (float trial placement tests) +% diff --git a/Master/texmf-dist/source/latex3/xparse/ldcsetup.dtx b/Master/texmf-dist/source/latex3/xparse/ldcsetup.dtx new file mode 100644 index 00000000000..c280221b7e5 --- /dev/null +++ b/Master/texmf-dist/source/latex3/xparse/ldcsetup.dtx @@ -0,0 +1,264 @@ +% \iffalse +%% +%% (C) Copyright 1999 Frank Mittelbach, Chris Rowley, David Carlisle +%% All rights reserved. +%% +%% Not for general distribution. In its present form it is not allowed +%% to put this package onto CD or an archive without consulting the +%% the authors. +%% +%<*dtx> + \ProvidesFile{ldcsetup.dtx} +%</dtx> +%<package>\NeedsTeXFormat{LaTeX2e} +%<package>\ProvidesPackage{ldcsetup} +%<driver>\ProvidesFile{ldcsetup.drv} +% \fi +% \ProvidesFile{ldcsetup.dtx} + [1999/09/10 v0.04 coding conventions and stuff] +% +% \iffalse +%<*driver> +\documentclass{ltxdoc} +\begin{document} +\DocInput{ldcsetup.dtx} +\end{document} +%</driver> +% \fi +% +% \CheckSum{249} +% +% \GetFileInfo{ldcsetup.dtx} +% +% \title{The \textsf{ldcsetup} package\thanks{This file +% has version number \fileversion, last +% revised \filedate.}} +% \author{DPC, FMi} +% \date{\filedate} +% \maketitle +% +% \begin{abstract} +% Basic code shared by several other packages currently under development. +% \end{abstract} +% +% \StopEventually{} +% +% \begin{macrocode} +%<*package> +% \end{macrocode} +% +% \begin{macrocode} +\RequirePackage{keyval,calc} +% \end{macrocode} +% +% \section{Ignoring White Space} +% Within a package, or in a document preamble, you can use +% |\IgnoreWhiteSpace| this makes white space ignored, and |@| +% a letter, and |~| a space character. It lasts until the end of the +% current package or preamble. +% +%% Puts an ignored space at the end of the line, so `|\ |' does the right +% thing. (Perhaps should instead just change catcode of |^^M|) +% \begin{macrocode} +\def\IgnoreWhiteSpace{% + \edef\@tempa{% + \catcode`\noexpand\~=\the\catcode`\~\relax + \catcode`\noexpand\ =\the\catcode`\ \relax + \catcode`\noexpand\^^I=\the\catcode`\^^I\relax + \catcode`\noexpand\@=\the\catcode`\@\relax + \endlinechar=\the\endlinechar\relax + }% + \ifx\@currname\@empty + \expandafter\AtBeginDocument\expandafter{\@tempa}% + \else + \expandafter\AtEndOfPackage\expandafter{\@tempa}% + \fi + \catcode`\~=10\relax + \catcode`\ =9\relax + \catcode`\^^I=9\relax + \makeatletter +% \endlinechar=\m@ne + \endlinechar=` % +} +% \end{macrocode} +% +% Do it for this package. +% \begin{macrocode} +\IgnoreWhiteSpace +% \end{macrocode} +% +% \section{KV fixes} +% Allow\footnote{Not needed now?} key names to start with |\|. +% \begin{macrocode} +\def\define@key#1#2{% + \@ifnextchar[ + {\KV@def{#1}{\string#2}} + {\@namedef{KV@#1@\string#2}####1}} +\def\setkeys#1#2{% + \def\KV@prefix{KV@#1@\expandafter\string}% + \KV@do#2,\relax,} +% \end{macrocode} +% +% Make KV |#| safe. +% \begin{macrocode} +% \end{macrocode} +% +% \begin{macrocode} +\newtoks\KV@toks +% \end{macrocode} +% +% \begin{macrocode} +\def\KV@@sp@c#1\@nil#2\relax#3{\KV@toks{#1}\edef#3{\the\KV@toks}} +% \end{macrocode} +% +% Generate error messages on missing `,'. +% +% More exactly if two `=' appear after a key generate an error. +% The current KV just silently ignores everything after the second `='. +% \begin{macrocode} +\def\KV@equal{=} +% \end{macrocode} +% +% \begin{macrocode} +\def\KV@split#1=#2=#3\relax{% + \KV@@sp@def\@tempa{#1}% + \def\@tempd{#3}% + \ifx\@tempa\@empty\else + \expandafter\let\expandafter\@tempc + \csname\KV@prefix\@tempa\endcsname + \ifx\@tempc\relax + \KV@error{\@tempa\space \expandafter\@gobbletwo\string\@undefined}\@eha + \else + \ifx\@tempd\@empty + \KV@default + \else + \KV@@sp@def\@tempb{#2}% + \ifx\@tempd\KV@equal + \expandafter\@tempc\expandafter{\@tempb}\relax + \else + \KV@error{Extra~=~ sign~ after~ `#1'}\KV@erry + \fi + \fi + \fi + \fi} +% \end{macrocode} +% +% \begin{macrocode} +\def\KV@erry{\expandafter\KV@errx\meaning\@tempd\relax ignored\MessageBreak + missing~comma~in~`\expandafter\strip@prefix\meaning\@tempb'~?} +% \end{macrocode} +% +% \begin{macrocode} +\def\KV@errx#1>#2==\relax{% + `#2' } +% \end{macrocode} +% +% \begin{macrocode} +\def\KV@default{% + \expandafter\let\expandafter\@tempb + \csname\KV@prefix\@tempa @default\endcsname + \ifx\@tempb\relax + \KV@error{No value specified for \@tempa}\@eha + \else + \@tempb\relax + \fi} +% \end{macrocode} +% +% \LaTeX\ style error message. +% \begin{macrocode} +\def\KV@error#1#2{\PackageError{keyval}{#1}{#2}} +% \end{macrocode} +% +% Instead of doing a full KV parse, and evaluating all the keys, +% you might want to parse a parameter list, even for undefined keys, +% removing spaces, splitting up the `,` and `=' and resolving cases +% where no value is supplied. This is used in |\DeclareGenericFunction| +% which \emph{defines} a set of keys via such a KV parse. +% +% A setting of |, key = value ,| will result in |\KV@elt{key}{value}| +% being added to the list, a seting of |, key ,| will result in +% |\KV@default@elt{key}| being added. At the end of the parse the list +% is executed. No keys are checked at this stage (so no csnames are used +% up) the two |\KV|\ldots|@elt| commands must be defined as appropriate. +% +% \begin{macrocode} +\def\KV@parse#1{ + \begingroup +% \end{macrocode} +% +% Locally fudge |\KV@@def| to just add to a token register +% rather than make a definition. +% \begin{macrocode} +\def\KV@@sp@c##1\@nil##2\relax##3{\addto@hook##3{{##1}}} +% \end{macrocode} +% +% Locally fudge |\KV@split| to just add to a token register +% rather than execute the code for the found keys. +% \begin{macrocode} +\def\KV@split##1=##2=##3\relax{% + \def\@tempd{##3}% + \expandafter\ifx\expandafter=\@firstofone##1=\else + \ifx\@tempd\@empty + \addto@hook\KV@toks\KV@default@elt + \KV@@sp@def\KV@toks{##1}% + \else + \ifx\@tempd\KV@equal + \addto@hook\KV@toks\KV@elt + \KV@@sp@def\KV@toks{##1}% + \KV@@sp@def\KV@toks{##2}% + \else + \KV@err{Extra `=' after `##1'}\@ehd + \fi + \fi + \fi} +% \end{macrocode} +% +% Initialise +% \begin{macrocode} + \KV@toks{} +% \end{macrocode} +% Do the parse +% \begin{macrocode} + \KV@do#1,\relax, +% \end{macrocode} +% Evaluate the token register outside the group. +% \begin{macrocode} + \expandafter + \endgroup + \the\KV@toks} +% \end{macrocode} +% +% \section{Calc fixes} +% +% Count Register assignments via calc. +% \begin{macrocode} +\let\SetInternalCounter\calc@assign@count +% \end{macrocode} +% +% +% \section{Misc code that is best collected in one place} +% +% This section will receive odd code that would be of potential use to +% other packages and should eventually made it to the kernel +% (perhaps). +% +% \begin{macro}{\UndeclareRobustCommand} +% Remove a robust command from memory if it isn't used any +% longer. Of course this doesn't free the hash table but at least +% the space gets reclaimed. +% \begin{macrocode} +\def\UndeclareRobustCommand#1{% + \global\let#1\undefined + \global\expandafter + \let\csname\expandafter\@gobble\string#1~\endcsname\undefined +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macrocode} +%</package> +% \end{macrocode} +% +% \Finale +% diff --git a/Master/texmf-dist/source/latex3/xparse/xparse.dtx b/Master/texmf-dist/source/latex3/xparse/xparse.dtx new file mode 100644 index 00000000000..1bee47bb059 --- /dev/null +++ b/Master/texmf-dist/source/latex3/xparse/xparse.dtx @@ -0,0 +1,1339 @@ +% \iffalse +%% +%% (C) Copyright 1999 Frank Mittelbach, Chris Rowley, David Carlisle +%% All rights reserved. +%% +%% Not for general distribution. In its present form it is not allowed +%% to put this package onto CD or an archive without consulting the +%% the authors. +%% +%<*dtx> + \ProvidesFile{xparse.dtx} +%</dtx> +%<package>\NeedsTeXFormat{LaTeX2e} +%<package>\ProvidesPackage{xparse} +%<driver>\ProvidesFile{xparse.drv} +% \fi +% \ProvidesFile{xparse.dtx} + [1999/09/10 v0.17 generic document command parser] +% +% \iffalse +%<*driver> + \documentclass{ltxdoc} + \usepackage{textcomp} +% \usepackage{ldcdoc} + \begin{document} + \DocInput{xparse.dtx} + \end{document} +%</driver> +% \fi +% +% \CheckSum{667} +% +% \GetFileInfo{xparse.dtx} +% +% \title{The \textsf{xparse} package\thanks{This file +% has version number \fileversion, last +% revised \filedate.}} +% \author{FMi, CAR, DPC} +% \date{\copyright~\filedate} +% \maketitle +% +% \begin{abstract} +% The interfaces described in this document are not meant to be final +% but only as a basis for discussion. Building productive applications +% using the current code is discouraged. +% \end{abstract} +% +% \section{Interface} +% +% This package implements high-level interface commands for class file +% writers which allows the separation of formatting commands +% (typically instances of so-called `templates') and their arguments +% from the signature of document-level commands. +% +% This works by declaration commands that provide a general +% specification method for the typical \LaTeX{} syntax, e.g., +% star-form, optional arguments, and mandatory arguments. A command +% (or environment) declared in this way parses the input according to +% its spec and presents its findings in a normalized way for further +% processing. +% +% \subsection{Argument spec} +% +% An argument specification is a list of letters each representing a +% type of argument, i.e., |m| is a mandatory argument (surrounded by +% braces), |o| an optional argument (surrounded by brackets if +% present), and |s| represents a star (which might be present or +% not).\footnote{Other argument types such as \texttt{c} for picture +% coordinates could be integrated in principle --- the last prototype +% now contains support for\texttt{c}.} Thus the argument +% spec for headings as implemented by |\@startsection| in standard +% \LaTeX{} would be represented by the three letters |som|. +% +% With the new proof of concept implementation there is also +% |O{default}| which acts like |o| which also scans for an optional +% argument but allows to specify a default value if the optional +% argument is not present. I.e., it can be used to turn mandatory +% arguments of a template (that is those that do not check for +% |\NoValue|) into optional ones by supplying a default on the +% document command level. +% +% We also have |C{{x-default}{y-default}}| to allow for optional +% coordinate pairs which is, for example, needed to provide something +% like the picture environment in current \LaTeX. +% +% \subsection{Parsing results} +% +% To normalise the result of parsing the input according to an +% argument specification it is important to uniquely identify all +% arguments found. For this reason each parsing operation initiated by +% one of the argument spec letters will result in an identifiable +% output as follows: +% \begin{description} +% \item[m] will return the parsed argument surrounded by a brace pair, +% i.e., will normally be the identity; +% \item[o] will return the parsed argument surrounded by a brace pair +% if present. Otherwise it will return the token |\NoValue|; +% \item[O\textbraceleft default\textbraceright] will return the parsed +% argument surrounded by a brace pair +% if present. Otherwise it will return the |{default}| as specified above. +% \item[s] will return either the token |\BooleanTrue| or +% |\BooleanFalse| depending on whether or not a star was parsed. +% \item[c] will parse the syntax |(|\meta{x}|,|\meta{y}|)|, i.e., a +% coordinate pair and will return |{{|\meta{x}|}{|\meta{y}|}}| as +% the result. If no open parentheses is scanned an error is signalled. +% \item[C\textbraceleft\textbraceleft x-default\textbraceright\textbraceleft +% y-default\textbraceright\textbraceright] behaves like |c|, i.e., parses a +% coordinate pair if present. If the coordinate pair is missing it +% returns the default values instead. +% \end{description} +% For example, given the spec |soomO{default}| the input |*[Foo]{Bar}| would be +% parsed as |\BooleanTrue{Foo}\NoValue{Bar}{default}|. In other words +% there will be always exactly the same number of brace groups or +% tokens as the number of letters in the argument spec. +% +% \subsection{Applying the parsing results} +% +% Since the result of the parsing is a well defined number of tokens or +% brace groups it is easy to pass them on in any order to any +% processing function. To this end the tokens or brace groups are +% associated with the standard argument specifiers in \TeX{} macros, +% i.e., |#1|, |#2|, and so forth. This limits the argument +% specification to a maximum number of 9 letters, but for practical +% applications this should be sufficient. +% +% \subsection{The class designer interface} +% +% This package provides two commands for declaring commands +% and environments to be used within the document body. +% +% \DescribeMacro\DeclareDocumentCommand +% The |\DeclareDocumentCommand| declaration takes three arguments. The +% first argument is the name of the command to be declared, the second +% is the argument specification in the syntax described above, and the +% third is the action to be carried out once the arguments are +% parsed. Within the third argument |#1|, |#2|, etc.\ denote the +% result of the parsing, e.g., +%\begin{verbatim} +% \DeclareDocumentCommand{\chapter}{som} +% { \IfBooleanTF {#1} +% { \typesetnormalchapter {#2}{#3} } +% { \typesetstarchapter {#3} } +% } +%\end{verbatim} +% would be a way to define a |\chapter| command which would +% essentially behave like the current \LaTeX{} command (except that it +% would accept an optional argument even when a |*| was parsed). The +% |\typesetnormalchapter| could test its first argument for being +% |\NoValue| to see if an optional argument was present. +% +% Of course something like the |\IfNoValueTF| test could also be +% placed inside a function that would process all three arguments, thus +% using the templates and their instances as provided by the +% \texttt{template} package such a declaration would probably look +% more like the following example: +%\begin{verbatim} +% \DeclareDocumentCommand{\chapter}{som} +% { \UseInstance {head} {A-head-main} {#1} {#2} {#3} } +%\end{verbatim} +% +% Using the |\DeclareDocumentCommand| interface it is easy to modify +% the document-level syntax while still applying the same +% layout-generating functions, e.g., a class that would not support +% optional arguments or star forms for the heading commands could +% define |\chapter| like this: +%\begin{verbatim} +% \DeclareDocumentCommand{\chapter}{m} +% { \UseInstance {head} {A-head-main} \BooleanFalse \NoValue {#1} } +%\end{verbatim} +% while a class that would allow for an additional optional argument +% (for whatever reason) could define it like that: +%\begin{verbatim} +% \DeclareDocumentCommand{\chapter}{somo} +% { \doSomethingWithTheExtraOptionalArg {#4} +% \UseInstance {head} {A-head-main} {#1} {#2} {#3} } +%\end{verbatim} +% +% Commands declared in this way are automatically robust (in David's +% implementation). +% +% \DescribeMacro\DeclareDocumentEnvironment +% The |\DeclareDocumentEnvironment| declaration is similar to +% |\DeclareDocumentCommand| except that it takes four arguments: the +% first being the environment name (without a backslash), the second +% again the argument-spec, and the third and forth are the actions +% taken at start end end of the environment. The parsed arguments are +% available to both the start and the finish as |#1|, |#2|, +% etc.\footnote{It is wishful thinking that the args can be made available +% to the end of the environment. In the current implementation this +% was buggy and has been taken out again below.} +% +% +% \subsubsection{Comparing tokens in a quarky way} +% +% Something like |\NoValue| would perhaps be best implemented as a +% ltx3 quark, i.e. a token which expands to itself as this is +% can be easily tested even if hidden inside a macro. The unfortunate +% side effect however is that it will result in a tight loop if it ever +% gets executed by mistake. +% +% \DescribeMacro\NoValue +% For this reason |\NoValue| is defined to expand to the string +% |-NoValue-| which would get typeset if ever executed thus clearly +% indicating the type of error the writer made. +% +% However this makes testing for this token slightly complicated as in +% that case the test +%\begin{verbatim} +% \def\seen{#1} +% \def\containsNoValue{\NoValue} +% \ifx\seen\containsNoValue +%\end{verbatim} +% will be true if |#1| was |\NoValue| but false if if |#1| itself +% contains a macro which contains |\NoValue|; a case that happens +% unfortunately very often in practice. Using unguarded |\edef| to +% define |\seen| is out of question as |#1| typically is either +% |\NoValue| or arbitrary user input (which is likely to die horribly +% even in a |\protected@edef|. +% +% \DescribeMacro\IfSomethingTF +% \DescribeMacro\IfSomethingT +% \DescribeMacro\IfSomethingF +% Therefore the |\IfSomethingTF| test uses a slower recursive +% procedure: it tests if |#1| and |#2| are equal. If they are testing +% stops and the true-case (argument |#3|) will be executed. If not, it +% expands the first token of |#2| and checks if the resulting +% token-list is identical to |#2| (this would happen if this first +% token is unexpandable or |#2| is empty). In the latter case testing +% terminates and the false-case (argument |#4|) will be +% executed. However if the token-list created this way differs from +% |#2| the macro recurses using this token-list in place of |#2|. +% +% \DescribeMacro\IfNoValueTF +% \DescribeMacro\IfNoValueT +% \DescribeMacro\IfNoValueF +% \DescribeMacro\IfValueTF +% \DescribeMacro\IfValueT +% \DescribeMacro\IfValueF +% The test |\IfNoValueTF| is implemented as an application of +% |\IfSomethingTF|, i.e., +%\begin{verbatim} +% \def\IfNoValueTF{\IfSomethingTF\NoValue} +%\end{verbatim} +% where the three arguments (test token, true and false case) are +% picked up by |\IfSomethingTF|. Similar tests for other quark-like +% tokens could be defined similarly. |\IfValueTF| is the same test +% with the true/false case exchanged. +% +% +% \subsection{Some comments on the need for the \texttt{O} specifier} +% +% With |\newcommand| there is the possibility of specifying a default +% for an optional argument which is stored away in a more or less +% efficient manner. For example below is the old definition of +% |\linebreak| as can be found in the \LaTeX2e kernel: +%\begin{verbatim} +%\def\linebreak{\@testopt{\@no@lnbk-}4} +%\def\@no@lnbk #1[#2]{% +% \ifvmode +% \@nolnerr +% \else +% \@tempskipa\lastskip +% \unskip +% \penalty #1\@getpen{#2}% +% \ifdim\@tempskipa>\z@ +% \hskip\@tempskipa +% \ignorespaces +% \fi +% \fi} +%\end{verbatim} +% Ignoring for the moment that the above is slightly optimised an +% expansion of this code under |\tracingall| will result in about 90 +% lines of tracing output. +% If we reimplement this using |\DeclarDocumentCommand\linebreak{o}| +% we have to use |\IfNoValueTF| to find out if an argument was present +% which (because of the somewhat slow expansion of |\IfSomethingTF|) +% results in about twice as much of tracing lines. In contrast using +% |O{4}| as below we end up with 110 lines, which seems roughly the +% price we have to pay for the extra generality available (though this +% could perhaps even be reduced by a better implementation of the +% parsing machine as originally done by David, before i talked him +% into adding support for arguments in the end code of an environment). +% +%\begin{verbatim} +%\DeclareDocumentCommand\linebreak { O{4} } +% { +% \ifvmode +% \@nolnerr +% \else +% \@tempskipa\lastskip +% \unskip +% % \IfNoValueTF{#1} +% % {\break} +% % {\penalty -\@getpen{#1}} +% \penalty -\@getpen{#1} +% \ifdim\@tempskipa>\z@ +% \hskip\@tempskipa +% \ignorespaces +% \fi +% \fi +% } +%\end{verbatim} +% +% \subsubsection{A boolean data type} +% +% \DescribeMacro\BooleanTrue +% \DescribeMacro\BooleanFalse +% The parsing result for a star etc is presented as the token +% |\BooleanTrue| or |\BooleanFalse| respectively! +% +% \DescribeMacro\IfBooleanTF +% \DescribeMacro\IfBooleanT +% \DescribeMacro\IfBooleanF +% To test for these values the macro |\IfBooleanTF| can be used. It +% expects as its first argument either |\BooleanTrue| or +% |\BooleanFalse| and executes its second or third argument depending +% on this value. |\IfBooleanT| and |\IfBooleanF| are obvious +% shortcuts. +% +% At one point in time i thought that one can represent everything +% using |\NoValue|, e.g., for the star case either return |*| or +% |\NoValue|. However, this slows down processing of commands like +% |\\*| considerably since they would then have to use the slow +% |\IfSomethingTF| internally instead of a fast two-way switch. So now +% this data type is back in. +% +% \subsection{A somewhat complicated example} +% +% This example reimplements the |\makebox| and |\framebox| interface +% of \LaTeX{} both of which are unfortunately quite overloaded +% syntactically. For this reason the example isn't meant to show good +% coding practice but to show the power of the interface even though +% applied in a somewhat bad way. +% +% |\makebox| and |\framebox| support the following different document +% syntax forms: +% \begin{itemize} +% \item +% |\makebox{A}|: only a single mandatory argument. +% +% \item +% |\makebox[20pt]{B}|: one optional argument specify the box width. +% +% +% \item +% |\makebox[30pt][r]{C}|: two optional arguments the second specifying +% the text position within the box being made (l,c,r being allowed +% with c being the default). +% +% \item +% |\makebox(20,30){D}|: within picture mode the width is specified not +% as an optional argument in brackets but as a coordinate pair. +% +% \item +% |\makebox(0,0)[lt]{E}|: in that case an optional argument following +% coordinate pair denotes the placement within the box which can have +% different values compared to case C above. +% \end{itemize} +% +% To cater for this overloaded structure we can define |\makebox| to +% be something like the following: +%\begin{verbatim} +%\DeclareDocumentCommand \makebox { C{\NoValue} o O{c} m} +% { \IfNoValueTF{#1} +% { \ltx@maketextbox{#2}{#3}{#4} } +% { \ltx@makepicbox #1 {#2}{#4} } } +%\end{verbatim} +% In other words: if we do not see a coordinate pair first (i.e., +% first argument is |\NoValue| then we expect up to two optional +% arguments (the width of the box or |\NoValue| if not given and the +% placement specifier with a default of |c| if not given) and one +% mandatory one which is the text. In that case we pass argument 2 to +% 4 to an internal function |\ltx@maketextbox| which builds the text +% box. +% +% Otherwise, if the first argument is a coordinate pair we parse an +% optional argument denoting the placement specifier. Since +% \texttt{xparse} doesn't support variant syntax we actually parse for +% another optional argument (which has no meaning in that case and is +% in fact ignored if present) followed by a mandatory one containing +% the box text. In that case we pass the coordinate pair (|#1|), the +% specifier (|#2|), and the text (|#4|) to the function +% |\ltx@makepicbox| which builds the picture box. Note the special +% handling of the coordinatesD: which are passed without surrounding +% braces to |\ltx@makepicbox|: since the coordinate argument looks +% like |{x-val}{y-val}| the receiving function |\ltx@makepicbox| gets +% the |x-val| as argument one and the |y-val| as argument two. +% +% A definition for |\framebox| would look more or less identical +% except that we would need to pass the arguments to slightly +% different internal functions. The alternative is to give the +% internal functions an extra argument that controls whether or not a +% frame is bying built. +% +% \begin{macro}{\ltx@makepicbox} +% So here is a possible implementation of |\ltx@makepicbox| that +% builds a picture box with or without frame. It takes the following +% mandatory arguments: +% \begin{enumerate} +% \item x-part of coordinate +% \item y-part of coordinate +% \item placement specifier, e.g., |lt| or |\NoValue| +% \item text of box +% \item the token |\frame| (if a frame should surround the box) or the +% token |\@firstofone| --- not pretty i agree +% \end{enumerate} +%\begin{verbatim} +%\def\ltx@makepicbox#1#2#3#4#5 +% { +% #5{ +% \vbox to#2\unitlength +% {\let\mb@b\vss \let\mb@l\hss\let\mb@r\hss +% \let\mb@t\vss +% \IfNoValueF{#3} +% { +% \@tfor\reserved@a :=#3\do{ +% \if s\reserved@a +% \let\mb@l\relax\let\mb@r\relax +% \else +% \expandafter\let\csname mb@\reserved@a\endcsname\relax +% \fi}% +% } +% \mb@t +% \hb@xt@ #1\unitlength{\mb@l #4\mb@r} +% \mb@b +% \kern\z@} +% } +% } +%\end{verbatim} +% \end{macro} +% +% +% +% \begin{macro}{\ltx@maketextbox} +% For the text case the internal function could take the following +% mandatory arguments: +% \begin{enumerate} +% \item width of the box or |\NoValue| (denoting to build the box at +% natural width) +% \item placement specifier, e.g., |l|. (No test for |\NoValue| being undertaken) +% \item text of box +% \item the token |\fbox| (if a frame should surround the box) or the +% token |\mbox| +% \end{enumerate} +% The actual code is taken straight from the current \LaTeX{} kernel +% and looks kind of scary. +%\begin{verbatim} +%\def\ltx@maketextbox#1#2#3#4 +% { +% \IfNoValueTF{#1} +% {#4{#3}} +% { +% \leavevmode +% \@begin@tempboxa\hbox{#3} +% \setlength\@tempdima{#1} +% \ifx#4\fbox +% \setbox\@tempboxa\hb@xt@\@tempdima +% {\kern\fboxsep\csname bm@#2\endcsname\kern\fboxsep} +% \@frameb@x{\kern-\fboxrule} +% \else +% \hb@xt@\@tempdima{\csname bm@#2\endcsname} +% \fi +% \@end@tempboxa +% } +% } +%\end{verbatim} +% \end{macro} +% +% \begin{macro}{\makebox} +% \begin{macro}{\framebox} +% Given the above internal functions the declarations of |\makebox| +% and |\framebox| would then look like this: +%\begin{verbatim} +%\DeclareDocumentCommand \makebox { C{\NoValue} o O{c} m} +% { \IfNoValueTF{#1} +% { \ltx@maketextbox{#2}{#3}{#4}\mbox } +% { \ltx@makepicbox #1 {#2}{#4}\@firstofone } } +% +%\DeclareDocumentCommand \framebox { C{\NoValue} o O{c} m} +% { \IfNoValueTF{#1} +% { \ltx@maketextbox{#2}{#3}{#4}\fbox } +% { \ltx@makepicbox #1 {#2}{#4}\frame } } +%\end{verbatim} +% \end{macro} +% \end{macro} +% +% +% \StopEventually{} +% +% \section{Implementation} +% +% The implementation section currently contains several trial +% implementations and updates. This final version will probably look +% quite differently again. +% +% Set up certain defaults including to ignore white space +% within the body of this package. +% \begin{macrocode} +%<*package> +\RequirePackage{ldcsetup} +\IgnoreWhiteSpace +% \end{macrocode} +% +% + +% \subsection{The Mittelbach/Rowley prove-of-concept +% implementation for the parsing} +% +% \begin{macro}{\DeclareDocumentCommand} +% \begin{macrocode} +%<*obsolete> +\def\DeclareDocumentCommand #1 #2 { +% \parse@countargs {#2} % sets \@tempc % Not implemented yet + \def\parse@csname{#1} + \def\parse@spec{#2} + \afterassignment \declare@dt@ + \toks@ +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\declare@dt@} +% \begin{macrocode} +\def \declare@dt@ { + \expandafter \edef \parse@csname + { \noexpand \parse@something + { \parse@spec } + { \the\toks@ } + % { \@tempc } + } +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\DeclareDocumentEnvironment} +% \begin{macrocode} +\long\def\DeclareDocumentEnvironment #1 #2 { +% \parse@countargs {#2} % sets \@tempc % Not implemented yet + \def\parse@csname{#1} + \def\parse@spec{#2} + \afterassignment \declare@de@ + \toks@ +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\declare@de@} +% \begin{macrocode} +\def \declare@de@ { + \expandafter \edef \csname \parse@csname \endcsname + { \begingroup + \noexpand \parse@something + { \parse@spec } + { \the\toks@ } + % { \@tempc } + } + \afterassignment \declare@dee@ + \toks@ +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\declare@dee@} +% \begin{macrocode} +\def \declare@dee@ { + \expandafter \edef \csname end\parse@csname \endcsname + { \noexpand \parse@apply + { \the\toks@ } + \noexpand \parse@results + \endgroup + } +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\parse@apply} +% \begin{macrocode} +\def\parse@apply #1 { + \renewcommand \parse@tempa [\the\parse@cnt] {#1} + \expandafter \parse@tempa % #2 implicit +} +\let\parse@tempa\@empty % or \renew... might bulk the first time +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\parse@something} +% \begin{macrocode} +%% CCC here and elsewhere there are some suggestions for +% not counting args at run-time +\def \parse@something #1 #2 { % #3 + \parse@body {#2} + % \parse@cnt #3 + \parse@cnt \m@ne % REMOVE + \parse@args #1x \parse@args {} +} +% \end{macrocode} +% +% \begin{macrocode} +\newcount\parse@cnt +\newtoks\parse@body +% \end{macrocode} +% +% \begin{macrocode} +\def\parse@args #1 #2\parse@args #3 { + \advance \parse@cnt \@ne % REMOVE + \csname parse@#1 \endcsname {#2}{#3} +} +% \end{macrocode} +% +% \begin{macrocode} +\def \parse@s #1 #2 { + \@ifstar + { \parse@args #1 \parse@args { #2 \BooleanTrue } } + { \parse@args #1 \parse@args { #2 \BooleanFalse } } +} +% \end{macrocode} +% +% \begin{macrocode} +\def \parse@m #1 #2 #3 { + \parse@args #1 \parse@args { #2 {#3} } +} +% \end{macrocode} +% +% \begin{macrocode} +\def \parse@x #1 #2 { + \def \parse@results {#2} % for environment +% \def \parse@tempa { +% \renewcommand \parse@tempb [\the\parse@cnt] +% } +% \expandafter \parse@tempa \expandafter { \the \parse@body } +% \parse@tempb #2 + \expandafter \parse@apply \expandafter { \the \parse@body } + \parse@results % \parse@apply expands this! +} +% \end{macrocode} +% +% \begin{macrocode} +\def \parse@o #1 #2 { + \@ifnextchar [ + { \parse@o@ {#1}{#2} } + { \parse@args #1 \parse@args { #2 \NoValue } } +} +% \end{macrocode} +% +% \begin{macrocode} +\def \parse@o@ #1 #2 [#3] { + \parse@args #1 \parse@args { #2 {#3} } +} +%</obsolete> +% \end{macrocode} +% \end{macro} +% +% +% \subsection{The Carlisle implementation for the parsing} +% +% Not implemented in this version is |\DeclareDocumentEnvironment| +% (exercise for the reader).\footnote{Exercise now completed by DPC :-) +% (required re-implementing argument grabbers to grab to a toks +% register rather that into a brace group in the input stream.) } +% +% Seemed to need two toks registers. +% \begin{macrocode} +\newtoks\@temptokenb +% \end{macrocode} +% +% \begin{macrocode} +\newtoks\xparsed@args +% \end{macrocode} +% +% +% \begin{macro}{\DeclareDocumentCommand} +% Args: |#1| csname, +% |#2| soom argument spec, +% |#3| code +% +% In |#2| currently supported types are: +% s star, +% o \oarg{optional}, +% m \marg{mandatory}.\footnote{More added in reimplementation below.} +% +% |#3| is just grabbed so as to not get a space in the argument spec +% for definition. +% +% \begin{macrocode} +\long\def\DeclareDocumentCommand #1 #2 #3{ +% \end{macrocode} +% +% Needed to count no of arguments +% \begin{macrocode} + \@tempcnta\z@ +% \end{macrocode} +% +% Builds up list of argument parsers |\@ddc@s\@ddc@m| etc +% \begin{macrocode} + \toks@{} +% \end{macrocode} +% +% Builds up |#1#2#3#4| argument spec +% \begin{macrocode} + \@temptokena\toks@ +% \end{macrocode} +% +% Builds up list of m-argument parsers |\@ddc@m\@ddc@m| +% occurred since start or since argument of another type. +% \begin{macrocode} + \@temptokenb\toks@ +% \end{macrocode} +% +% Start parsing argument spec +% \begin{macrocode} + \@ddc#2X +% \end{macrocode} +% +% Define top level command, this just has the wrapper command +% |\@ddc@| then the argument grabbers from |\toks@| then the original +% command name (in case we need to |\protect|) then the internal +% command with the code. +% The |\long| below could be |\relax| if wanted to have a star-non-long +% form of this, cf |\newcommand*|. The argument preamble for +% |\def| comes from |\@temptokena|. +% \begin{macrocode} + \edef#1{ + \noexpand\@ddc@ + {\the\toks@} + \expandafter\noexpand\csname\string#1\endcsname + \noexpand#1 + } + \long\expandafter\def\csname\string#1\expandafter\endcsname + \the\@temptokena{#3}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\DeclareDocumentEnvironment} +% The implementation here could save a csname or two per environment +% if |\begin| and especially |\end| were modified but that not done here +% so each end code responsible for getting its own arguments. +% +% Arguments: |#1| env name, +% |#2| soom spec, +% |#3| begin code, +% |#4| end code. +% +% \begin{macrocode} +\long\def\DeclareDocumentEnvironment#1#2#3#4{ + \expandafter\DeclareDocumentCommand\csname #1\endcsname{#2}{ + \xparsed@args\toks@ + #3} + \expandafter\let\csname end #1\endcsname\@parsed@endenv + \long\expandafter\def\csname end \string\\#1\expandafter\endcsname + \the\@temptokena {#4}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@parsed@endenv} +% All end codes are let to this. (Could be merged into |\end|.) +% \begin{macrocode} +\def\@parsed@endenv{ + \expandafter\@parsed@endenv@\the\xparsed@args} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@parsed@endenv@} +% Helper that just replaces the internal name of the begin code +% with that of the end code. +% \begin{macrocode} +\def\@parsed@endenv@#1{ + \csname end\string#1\endcsname} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\@ddc@} +% +% Arguments: |#1| set of argument grabbers, +% |#2| internal command, +% |#3| top level command for |\protect|ing. +% +% \begin{macrocode} +\def\@ddc@#1#2#3{ + \ifx\protect\@typeset@protect + \expandafter\@firstofone + \else + \protect#3\expandafter\@gobble + \fi +% \end{macrocode} +% +% The command+arguments so far are kept in a token register until +% the last moment for ease of processing. So need to initialise +% that and use it at the end. +% \begin{macrocode} + {\toks@{#2} #1\the\toks@}} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\@ddc} +% Argument: |#1| one of s o m (or X denoting end of parsing). +% \begin{macrocode} +\def\@ddc#1{ + \ifx #1X +% \end{macrocode} +% fini +% \begin{macrocode} + \else + \ifx #1m +% \end{macrocode} +% If doing an m, just stick another |\@ddc@m| in a temporary list. +% \begin{macrocode} +% \@temptokenb\expandafter{% +% \the\@temptokenb +% \@ddc@m} + \addto@hook\@temptokenb m + \else +% \end{macrocode} +% +% Otherwise for o and s +% in |\toks@| first add any `m' argument parsers saved up +% then add |\@ddc@o| or |\@ddc@s|. +% \begin{macrocode} + \toks@\expandafter{% + \the\expandafter\toks@ + \csname @ddc@\the\@temptokenb\expandafter\endcsname + \csname @ddc@#1\endcsname} +% \end{macrocode} +% +% Clear list of m's: +% \begin{macrocode} + \@temptokenb{} + \fi +% \end{macrocode} +% +% Add one to argument count. +% \begin{macrocode} + \advance\@tempcnta\@ne +% \end{macrocode} +% +% Internally all arguments are non delimited args, so add +% |#|\meta{n} to the list in |\@temptokena| +% \begin{macrocode} + \@temptokena\expandafter{ + \the\expandafter\@temptokena\expandafter##\the\@tempcnta} +% \end{macrocode} +% +% Loop: +% \begin{macrocode} + \expandafter + \@ddc +% \end{macrocode} +% +% \begin{macrocode} + \fi} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\@ddc@s} +% Argument: |#1| any remaining argument grabbers (+ |\the|) +% \begin{macrocode} +\long\def\@ddc@s#1\toks@{ +% \end{macrocode} +% +% put back the rest of the argument grabbers, but add new +% (boolean) argument to list of arguments inside the register. +% \begin{macrocode} + \@ifstar + {\addto@hook\toks@\BooleanTrue #1\toks@} + {\addto@hook\toks@\BooleanFalse #1\toks@}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@ddc@m} +% Arguments: |#1| any remaining argument grabbers (+ |\the|), +% |#2| argument to be grabbed. +% \begin{macrocode} +\long\def\@ddc@m#1\toks@#2{ +% \end{macrocode} +% put back the rest of the argument grabbers, but copy +% argument to list of arguments inside the toks register. +% Any `m' at the end will be discarded and the internal +% command will pick up its own arguments. +% \begin{macrocode} + \addto@hook\toks@{{#2}} #1\toks@} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@ddc@o} +% Argument: |#1| any remaining argument grabbers (+ |\the|). +% \begin{macrocode} +\long\def\@ddc@o#1\toks@{ +% \end{macrocode} +% +% Put back the rest of the argument grabbers, but copy +% argument (now with |{}| or |\NoValue| to list of arguments +% inside toks register. +% \begin{macrocode} + \@ifnextchar[ + {\@ddc@o@{#1}} + {\addto@hook\toks@\NoValue #1\toks@}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@ddc@o@} +% Helper to remove []. +% \begin{macrocode} +\long\def\@ddc@o@#1[#2]{ + \addto@hook\toks@{{#2}} #1\toks@} +% \end{macrocode} +% \end{macro} +% +% +% +% \subsection{A Mittelbach update to the Carlisle implementation +% supporting O with default for optional arg and c for coordinates +% --- prove of concept only} +% +% Only changed and new commands are listed. +% +% +% \begin{macro}{\@ddc} +% The big switch that builds up the parser for the document command. +% +% The complexity of the |\@ddc| rewrite suggests that there might +% be better ways to do it, but for a proto-type solution this is +% fine enough. +% +% \begin{macrocode} +\def\@ddc#1{ + \ifx #1X +% \end{macrocode} +% Normally we do nothing at this point and don't pick up the +% trailing mandatory args into |\toks@| but if we want to reuse the +% argument list in an end environment we have to so |\perhaps@grab@ms| +% is normally |\relax| but might be |\grab@ms| instead. +% \begin{macrocode} + \perhaps@grab@ms + \else + \ifx #1m +% \end{macrocode} +% Just record how many m's seen so far +% \begin{macrocode} + \addto@hook\@temptokenb m + \else +% \end{macrocode} +% If anything other than an m is scanned we add to |\toks@| and +% argument grabber that gets all m's in one go rather than argument +% grabbers that pick up each m at a time. Right now this +% unnecessarily adds |\@ddc@x| if no m's have been +% seen.\footnote{fix, see also below} +% \begin{macrocode} + \toks@\expandafter{% + \the\expandafter\toks@ + \csname @ddc@x\the\@temptokenb\expandafter\endcsname + \csname @ddc@#1\endcsname} + \@temptokenb{} +% \end{macrocode} +% In case of |O| and |C| we have to grab the default next. +% \begin{macrocode} + \ifx #1O + \let\next@ddc\grab@default + \else + \ifx #1C + \let\next@ddc\grab@default + \fi + \fi + \fi + \advance\@tempcnta\@ne + \@temptokena\expandafter{ + \the\expandafter\@temptokena\expandafter##\the\@tempcnta} + \expandafter + \next@ddc + \fi +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\next@ddc} +% By default the loop in the |\@ddc| code above calls itself +% recursively until the whole spec is processed. +% \begin{macrocode} +\let\next@ddc\@ddc +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\grab@default} +% However if we've seen an |O| we need to grab the default value first. +% \begin{macrocode} +\def\grab@default #1{ + \toks@\expandafter{% + \the\toks@ + {#1}} + \let\next@ddc\@ddc + \@ddc +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\@ddc@O} +% This command expects the default value (to use if no |[| is +% parsed) after it. +% \begin{macrocode} +\long\def\@ddc@O#1#2\toks@{ + \@ifnextchar[ + {\@ddc@o@{#2}} + {\addto@hook\toks@{{#1}} #2\toks@}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@ddc@} +% We look for the `(' and signal an error +% if not found. By using |\@ifnextchar| this also takes care of any +% space tokens in front ot the the parentheses. +% \begin{macrocode} +\long\def\@ddc@c#1\toks@{ + \@ifnextchar ( + {\@ddc@c@ #1} + {\PackageError{xparse}{Missing~ coordinate~ argument} + {A~ value~ of~ (0,0)~ is~ assumed} + \addto@hook\toks@{{00}} #1\toks@} + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@ddc@c@} +% Helper for |\@ddc@c| and |\@ddc@C| below to parse a |(x,y)| if we +% know it is there. +% \begin{macrocode} +\long\def\@ddc@c@#1(#2,#3){ + \addto@hook\toks@{{{#2}{#3}}} #1\toks@} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@ddc@C} +% This way we can also directly implement the optional argument case in +% a natural way. +% \begin{macrocode} +\long\def\@ddc@C#1#2\toks@{ + \@ifnextchar ( + {\@ddc@c@ #2} + {\addto@hook\toks@{{#1}} #2\toks@}} +% \end{macrocode} +% \end{macro} +% +% +% +% Normally we don't pick up trailing m-args but if we do we grab them +% all at once. +% \begin{macrocode} +\let\perhaps@grab@ms\relax +\def\grab@ms { + \toks@\expandafter{ + \the\expandafter\toks@ + \csname @ddc@x\the\@temptokenb\endcsname +}} +% \end{macrocode} +% +% \begin{macro}{\@ddc@xm} +% Instead of |\@ddc@m| we use |\@ddc@xm| as with the implementation +% below we might have a need for |\@ddc@x| (that is no m's pending) +% and this would result in a name clash. A potentially better +% implementation (cause faster) would be not to use |\@temptokenb| +% above to record the number of m's seen but a counter register and +% generate grabber function names containing the number in their +% name. This way one could better single out the empty case which +% currently will always result and a |\@ddc@x| grabber doing +% nothing. +% \begin{macrocode} +\let\@ddc@m\undefined +\long\def\@ddc@xm#1\toks@#2{ + \addto@hook\toks@{{#2}} #1\toks@} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@ddc@xmm} +% \begin{macro}{\@ddc@xmmm} +% \begin{macro}{\@ddc@xmmm...} +% Arguments: |#1| any remaining argument grabbers (+ |\the|), +% |#2#3| argument to be grabbed; and so on. There can be at most 8 +% such mandatory arguments in the variations defined below. +% \begin{macrocode} +\long\def\@ddc@xmm#1\toks@#2#3{ +% \end{macrocode} +% Put back the rest of the argument grabbers, but copy +% argument to list of arguments inside the toks register. +% Any `m' at the end will be discarded and the internal +% command will pick up its own arguments. +% \begin{macrocode} + \addto@hook\toks@{{#2}{#3}} #1\toks@} +% \end{macrocode} +% +% And here are the cases for 3 to eight upcoming mandatory args: +% \begin{macrocode} +\long\def\@ddc@xmmm#1\toks@#2#3#4{ + \addto@hook\toks@{{#2}{#3}{#4}} #1\toks@} +\long\def\@ddc@xmmmm#1\toks@#2#3#4#5{ + \addto@hook\toks@{{#2}{#3}{#4}{#5}} #1\toks@} +\long\def\@ddc@xmmmmm#1\toks@#2#3#4#5#6{ + \addto@hook\toks@{{#2}{#3}{#4}{#5}{#6}} #1\toks@} +\long\def\@ddc@xmmmmmm#1\toks@#2#3#4#5#6#7{ + \addto@hook\toks@{{#2}{#3}{#4}{#5}{#6}{#7}} #1\toks@} +\long\def\@ddc@xmmmmmmm#1\toks@#2#3#4#5#6#7#8{ + \addto@hook\toks@{{#2}{#3}{#4}{#5}{#6}{#7}{#8}} #1\toks@} +\long\def\@ddc@xmmmmmmmm#1\toks@#2#3#4#5#6#7#8#9{ + \addto@hook\toks@{{#2}{#3}{#4}{#5}{#6}{#7}{#8}{#9}} #1\toks@} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\@ddc@xmmmmmmmmm} +% If we grab arguments even if they are all mandatory we might have +% even 9 such arguments, thus we also need: +% \begin{macrocode} +\long\def\@ddc@xmmmmmmmmm\the\toks@#1#2#3#4#5#6#7#8#9{ + \addto@hook\toks@{{#1}{#2}{#3}{#4}{#5}{#6}{#7}{#8}{#9}}\the\toks@} +% \end{macrocode} +% And in that case we also need to provide |\@ddc@x| as that name will +% be executed if there are no trailing mandatory arguments. +% \begin{macrocode} +\let\@ddc@x\relax +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\DeclareDocumentEnvironment} +% Fixing |\DeclareDocumentEnvironment| to not choke on the spec +% |m|. Interestingly enough |mm| does work with the old +% implementation: it simply grabs |\@checkend{name}| whereas the +% first only grabs |\@checkend| leaving |{name}| around for +% typesetting :-) +% +% If we don't make the arguments available in the end code we +% should most likely revert to David's original code which worked +% without assigning everything to toks registers (or at least check +% what is faster!) +% \begin{macrocode} +\long\def\DeclareDocumentEnvironment#1#2#3#4{ + \expandafter\DeclareDocumentCommand\csname #1\endcsname{#2}{ +% \end{macrocode} +% After |\DeclareDocumentCommand| has parsed the arguments the +% parsing result is available in |\@toks| except that trailing +% |m|'s are picked up directly and their values are therefore not +% part of this token register. So either we have to slow down +% everything by individually parsing those as well or this bright +% idea is not working. For the moment i disabled it again! +% \begin{macrocode} +% \xparsed@args\toks@ + #3} +% \end{macrocode} +% In that case the following can be simplified as well: +% \begin{macrocode} + \@namedef{end #1}{#4} +% \expandafter\let\csname end #1\endcsname\@parsed@endenv +% \long\expandafter\def\csname end \string\\#1\expandafter\endcsname +% \the\@temptokena{#4} +} +% \end{macrocode} +% And those are no longer necessary: +% \begin{macrocode} +\let\@parsed@endenv\undefined +\let\@parsed@endenv@\undefined +% \end{macrocode} +% +% The above does the fixing by not providing the arguments to the +% end command. The alternative is to do full parsing and could +% perhaps look more or less like this: +% \begin{macrocode} +%<*perhaps> +\long\def\DeclareDocumentEnvironment#1#2#3#4{ + \let\perhaps@grab@ms\grab@ms + \expandafter\DeclareDocumentCommand\csname #1\endcsname{#2}{ +% \end{macrocode} +% I think we need as a safety measure add a group here or else the +% code will fail over if people use it without |\begin|\ldots +% |\end|. +% Or not? I don't really like it but then i don't want to maintain +% a private stack here. +% \begin{macrocode} + \begingroup + \xparsed@args\toks@ + #3} + \let\perhaps@grab@ms\relax + \expandafter\let\csname end #1\endcsname\@parsed@endenv + \long\expandafter\def\csname end \string\\#1\expandafter\endcsname + \the\@temptokena {#4} +} +% \end{macrocode} +% Same as in David's again except that we have the added group now. +% \begin{macrocode} +\def\@parsed@endenv{ + \expandafter\@parsed@endenv@\the\xparsed@args\endgroup} +\def\@parsed@endenv@#1{ + \csname end\string#1\endcsname} +%</perhaps> +% \end{macrocode} +% However the above will fail with |\begin{macro}| code of the +% \texttt{doc} package as this code cancels the outer group so it is +% dangerous and for the moment i have not activated it. +% +% \end{macro} +% +% \subsection{A Quark-like datatype} +% +% If it turns out that the only quark thingie is going to be +% |\NoValue| then this can be streamlined for speed (and it looks +% like this is the case)! +% +% \begin{macro}{\IfSomethingTF} +% \begin{macro}{\IfSomethingT} +% \begin{macro}{\IfSomethingF} +% Setting up the stage \ldots +% \begin{macrocode} +\def\IfSomethingTF#1{\def\something@in{#1} \If@SomethingTF} +\def\IfSomethingT#1#2#3{\def\something@in{#1} + \If@SomethingTF{#2}{#3}\@empty} +\def\IfSomethingF#1#2#3{\def\something@in{#1} + \If@SomethingTF{#2}\@empty{#3}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\If@SomethingTF} +% \ldots and then for the recursive part: +% \begin{macrocode} +\def\If@SomethingTF#1{ + \def\something@tmp{#1} + \ifx\something@tmp\something@in +%fini true + \expandafter\@secondofthree + \else + \expandafter\def\expandafter\something@tmpb\expandafter{#1} + \ifx\something@tmp\something@tmpb +%fini false + \expandafter\expandafter\expandafter\@thirdofthree + \else +%try again expanded + \expandafter\expandafter\expandafter\@firstofone + \fi + \fi + {\expandafter\If@SomethingTF\expandafter{#1}} +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@secondofthree} +% \begin{macro}{\@thirdofthree} +% Some helpers missing in \LaTeX{}; the others are |\long| so we make +% those long as well: +% \begin{macrocode} +\long\def\@secondofthree#1#2#3{#2} +\long\def\@thirdofthree #1#2#3{#3} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% \subsection{Testing for \texttt{\textbackslash NoValue}} +% +% +% \begin{macro}{\NoValue} +% \begin{macrocode} +\def\NoValue{-NoValue-} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\NoValueInIt} +% might be handy sometimes\ldots +% \begin{macrocode} +\def\NoValueInIt{\NoValue} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\IfNoValueTF} +% \begin{macro}{\IfNoValueT} +% \begin{macro}{\IfNoValueF} +% \begin{macrocode} +\def\IfNoValueTF{\IfSomethingTF\NoValue} +\def\IfNoValueT {\IfSomethingT \NoValue} +\def\IfNoValueF {\IfSomethingF \NoValue} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\IfValueTF} +% \begin{macro}{\IfValueT} +% \begin{macro}{\IfValueF} +% \begin{macrocode} +\def\IfValueTF #1 #2 #3 { \IfNoValueTF {#1} {#3} {#2} } +\let \IfValueT \IfNoValueF +\let \IfValueF \IfNoValueT +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \subsection{A Boolean datatype} +% +% \begin{macro}{\BooleanFalse} +% \begin{macro}{\BooleanTrue} +% \begin{macrocode} +\def\BooleanFalse{TF} +\def\BooleanTrue{TT} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\IfBooleanTF} +% \begin{macro}{\IfBooleanT} +% \begin{macro}{\IfBooleanF} +% \begin{macrocode} +\def\IfBooleanTF #1 { + \if#1 + \expandafter\@firstoftwo + \else + \expandafter\@secondoftwo + \fi +} +\def\IfBooleanT #1 #2 { + \IfBooleanTF {#1} {#2} \@empty +} +\def\IfBooleanF #1 { + \IfBooleanTF {#1} \@empty +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \begin{macrocode} +%</package> +% \end{macrocode} +% +% +% \Finale +% +\endinput diff --git a/Master/texmf-dist/source/latex3/xparse/xparse.ins b/Master/texmf-dist/source/latex3/xparse/xparse.ins new file mode 100644 index 00000000000..0a785f6f587 --- /dev/null +++ b/Master/texmf-dist/source/latex3/xparse/xparse.ins @@ -0,0 +1,13 @@ +\input docstrip +\keepsilent +\askforoverwritefalse + +\preamble +\endpreamble + +\generate{% + \file{ldcsetup.sty}{\from{ldcsetup.dtx}{package}} + \file{xparse.sty}{\from{xparse.dtx}{package}} + } + +\endbatchfile diff --git a/Master/texmf-dist/source/latex3/xtheorem/xtheorem.dtx b/Master/texmf-dist/source/latex3/xtheorem/xtheorem.dtx new file mode 100644 index 00000000000..c07f240a4e9 --- /dev/null +++ b/Master/texmf-dist/source/latex3/xtheorem/xtheorem.dtx @@ -0,0 +1,386 @@ +% \iffalse +%% +%% (C) Copyright 1999 Achim Blumensath +%% All rights reserved. +%% +%% Not for general distribution. In its present form it is not allowed +%% to put this package onto CD or an archive without consulting the +%% the authors. +%% +%<*dtx> + \ProvidesFile{xtheorem.dtx} +%</dtx> +%<package>\NeedsTeXFormat{LaTeX2e} +%<package>\ProvidesPackage{xtheorem} +%<driver>\ProvidesFile{xtheorem.drv} +% \fi +% \ProvidesFile{xtheorem.dtx} + [1999/12/19 v0.1 theorem styles] +% +% \iffalse +%<*driver> + \documentclass{ltxdoc} + \usepackage{textcomp} + +% \usepackage{xparse,xlists,xlists-samples} +% \usepackage{ldcdoc} + +% next three definitions are big hacks to run the file +% without the above packages +% +\newcommand\NoValue{\texttt{\textbackslash NoValue}} + +\newenvironment{TemplateInterfaceDescription}[1] + {\subsection{The Template Type `#1'}% + \begingroup\description + \def\TemplateArgument##1##2{\item[Arg: ##1]##2\par}% + \def\TemplateSemantics{\enddescription\endgroup + \subsubsection*{Semantics:}}% + } + {\par\bigskip} + +\newenvironment{TemplateDescription}[2] + {\subsection{The Template `#2' (type #1)}% + \subsubsection*{Attributes:}% + \begingroup\description + \def\TemplateKey##1##2##3##4{\item[##1 (##2)]##3% + \ifx\TemplateKey##4\TemplateKey\else +% \hskip0ptplus3em\penalty-500\hskip 0pt plus 1filll Default:~##4% + \hfill\penalty500\hbox{}\hfill Default:~##4% + \nobreak\hskip-\parfillskip\hskip0pt\relax + \fi + \par}% + \def\TemplateSemantics{\enddescription\endgroup + \subsubsection*{Semantics \& Comments:}}% + } + {\par\bigskip} + + \begin{document} + \DocInput{xtheorem.dtx} + \end{document} +%</driver> +% \fi +% +% +% \GetFileInfo{xtheorem.dtx} +% +% \title{The \textsf{xtheorem} package\thanks{This file +% has version number \fileversion, last +% revised \filedate.}} +% \author{AB} +% \date{\filedate} +% +% \maketitle +% +% \tableofcontents +% +% \begin{abstract} +% This is a conversion of the AMS theorem classes to the template +% system. Only the interface was changed, the internals still use +% \LaTeXe\ commands. +% \end{abstract} +% +% \section{Interfaces} +% +% \begin{TemplateInterfaceDescription}{theoremstyle} +% +% \TemplateArgument{1} +% {Text of the number of the theorem (e.g., \verb|A.1|), or +% \NoValue\ to indicate that the theorem is unnumbered.} +% +% \TemplateArgument{2} +% {Name of the theorem (e.g. \verb|Theorem|, \verb|Lemma|).} +% +% \TemplateArgument{3} +% {Additional note (e.g. \verb|see [12]|), or \NoValue.} +% +% \TemplateSemantics +% +% This template starts a new environment, typesets the head of a +% theorem, and sets fonts for the body of the theorem. The +% environment is ended by an \verb|\@endtheorem| command. +% +% If the first argument is given, it is printed as the number part. +% The second argument contains the name of the theorem, and the +% third one may contain an additional note. +% +% For instance, the arguments \verb|2.1|, \verb|Lemma|, and +% \verb|Rabin~1960| could produce the output +% +% \medskip +% \noindent\textbf{Lemma 2.1 }(Rabin 1960)\textbf. +% +% \medskip\noindent +% where the following text is set in italic. +% +% \end{TemplateInterfaceDescription} +% +% +% \begin{TemplateDescription}{theoremstyle}{std} +% +% \TemplateKey{pre-skip}{l} +% {Skip above the theorem.} +% {|topsep|} +% \TemplateKey{post-skip}{l} +% {Skip below the theorem.} +% {|topsep|} +% \TemplateKey{body-style}{f0} +% {Commands to be executed before the body of the theorem in +% order to set fonts, etc.} +% {italic} +% \TemplateKey{head-style}{f0} +% {Commands to set the font of the head.} +% {bold} +% \TemplateKey{note-style}{f0} +% {Commands to set the font of the note.} +% {medium upright font} +% \TemplateKey{head-punct}{f0} +% {Text after the head.} +% {|.|} +% \TemplateKey{head-format}{f3} +% {Format of the head.} +% {Name Number (Note)} +% \TemplateKey{head-indent}{l} +% {Indent of the head.} +% {none} +% \TemplateKey{head-sep}{l} +% {Space after the head.} +% {5pt $\pm$ 1pt} +% \TemplateKey{post-head-action}{f0} +% {Command to be executed after the head (e.g., a line break).} +% {none} +% +% \TemplateSemantics +% This are all parameters provided by the AMS package, except `swaphead' +% which can be simulated by \verb|head-format|. +% +% \end{TemplateDescription} +% +% \paragraph{Problem.} +% The current solution for `head-format' is very clumsy. Perhaps it would +% be better to pass just the name of a template which does the layout +% instead of the actual code. +% +% \medskip +% \DescribeMacro\newtheorem +% The \verb|\newtheorem| command defines a new type of theorem. It takes +% the following arguments: +% +% \medskip +% \verb|\newtheorem|[|*|]$\langle$style$\rangle$\relax +% $\langle$name$\rangle$[share counter]$\langle$label$\rangle$\relax +% [count relative] +% +% \medskip\noindent +% and defines an environment named `name'. The arguments have the +% following meanings: +% \begin{description} +% \item[|*|] If present the theorem is unnumbered, otherwise it is +% numbered. +% \item[style] The name of an instace of the `theoremstyle' template +% which is used to typeset the theorem. +% \item[name] The name of the new environment. +% \item[share counter] (optional) The label of another defined theorem. +% If present both kinds of theorem share a common counter. +% \item[label] The name of the theorem which should appear in its head. +% \item[count relative] If present the counter is reset to 1 everything +% the counter with this name is changed (e.g., |section| or |chapter|). +% \end{description} +% +% For instance, the following definitions create environments named +% |Thm|, |Prop|, |Lem|, |Cor|, |Def|, |Rem|, and |Exam|. The first +% five share a common counter which is relative to the current +% section, the last two are unnumbered. +% \begin{verbatim} +% \newtheorem{plain}{Thm}{Theorem}[section] +% \newtheorem{plain}{Prop}[Thm]{Proposition} +% \newtheorem{plain}{Lem}[Thm]{Lemma} +% \newtheorem{plain}{Cor}[Thm]{Corollary} +% \newtheorem{definition}{Def}[Thm]{Definition} +% \newtheorem*{remark}{Rem}{Remark} +% \newtheorem*{remark}{Exam}{Example} +% \end{verbatim} +% +% \section{Implementation} +% +% \begin{macrocode} +%<*package> +\RequirePackage{xparse} +\RequirePackage{template} + +\IgnoreWhiteSpace +% \end{macrocode} +% +% \begin{macrocode} +\DeclareTemplateType{theoremstyle}{3} + +\newskip\TSpre@skip +\newskip\TSpost@skip +\newdimen\TShead@indent +\newskip\TShead@sep + +\DeclareTemplate{theoremstyle}{std}{3} +{ + pre-skip =l [\DelayEvaluation{\topsep}] \TSpre@skip, + post-skip =l [\DelayEvaluation{\topsep}] \TSpost@skip, + body-style =f0 [\itshape] \TSbody@style, + head-style =f0 [\bfseries] \TShead@style, + note-style =f0 [\fontseries\mddefault\upshape] \TSnote@style, + head-punct =f0 [.] \TShead@punct, + head-format =f3 [\IfNoValueF{#1}{#1\IfNoValueF{#2}{\space}} + \IfNoValueF{#2}{\textup{#2}} + \IfNoValueF{#3}{\space{\TSnote@style(#3)}}] + \TShead@format, + head-indent =l [0pt] \TShead@indent, + head-sep =l [5pt plus 1pt minus 1pt] \TShead@sep, + post-head-action =f0 [] \TSpost@head@action +} +{ + \DoParameterAssignments + \ifhmode\unskip\unskip\par\fi + \normalfont + \trivlist + \let\thmheadnl\relax + \@topsep\TSpre@skip + \@topsepadd\TSpost@skip + \IfNoValueF{#1} + {\refstepcounter{#1}} + \deferred@thm@head{ + \TShead@style + \hskip\TShead@indent + \IfNoValueTF{#1} + {\TShead@format{#2}{#1}{#3}} + {\TShead@format{#2}{\csname the#1\endcsname}{#3}} + \TShead@punct + \TSpost@head@action + \hskip\TShead@sep + } + \TSbody@style + \ignorespaces +} +% \end{macrocode} +% These functions are used by the template above. They are copied +% straight away from amsclass.dtx. +% \begin{macrocode} +\let\adjust@parskip@nobreak=\@nbitem +% \end{macrocode} +% +% \begin{macrocode} +\newtoks\dth@everypar +\dth@everypar={ + \@minipagefalse + \global\@newlistfalse + \if@inlabel + \global\@inlabelfalse + \begingroup + \setbox\z@\lastbox + \ifvoid\z@ \kern-\itemindent \fi + \endgroup + \unhbox\@labels + \fi + \if@nobreak + \@nobreakfalse + \clubpenalty\@M + \else + \clubpenalty\@clubpenalty + \everypar{} + \fi +} +% \end{macrocode} +% +% \begin{macrocode} +\def\deferred@thm@head#1{% + \if@inlabel \indent \par \fi % eject a section head if one is pending + \if@nobreak + \adjust@parskip@nobreak + \else + \addpenalty\@beginparpenalty + \addvspace\@topsep + \addvspace{-\parskip}% + \fi + \global\@inlabeltrue + \everypar\dth@everypar + \sbox\@labels{\normalfont#1}% + \ignorespaces +} +% \end{macrocode} +% The usual styles `plain', `definition', and `remark'. +% \begin{macrocode} +\DeclareInstance{theoremstyle}{plain}{std}{} + +\DeclareInstance{theoremstyle}{definition}{std} +{ + body-style = \normalfont +} + +\DeclareInstance{theoremstyle}{remark}{std} +{ + pre-skip = \DelayEvaluation{0.5\topsep}, + post-skip = \DelayEvaluation{0.5\topsep}, + body-style = \normalfont, + head-style = \itshape +} +% \end{macrocode} +% The command to end a theorem. +% \begin{macrocode} +\def\@endtheorem{\endtrivlist\@endpefalse } +% \end{macrocode} +% +% |newtheorem| just checks all cases and defines the appropriate +% environment. +% \begin{macrocode} +\DeclareDocumentCommand{\newtheorem}{smmomo} +{ + \expandafter\@ifdefinable\csname #3\endcsname + { + \global\expandafter\let\csname end#3\endcsname\@endtheorem + \IfBooleanTF{#1} + { + \expandafter\DeclareDocumentCommand\csname #3\endcsname{o} + {\UseInstance{theoremstyle}{#2}{\NoValue}{#5}{##1}} + } + { + \IfNoValueTF{#4} + { + \IfNoValueTF{#6} + { + \newcounter{#3} + } + { + \newcounter{#3}[#6] + \expandafter\xdef\csname the#3\endcsname{ + \expandafter\noexpand\csname the#6\endcsname + \@thmcountersep\@thmcounter{#3}} + } + \expandafter\DeclareDocumentCommand\csname #3\endcsname{o} + {\UseInstance{theoremstyle}{#2}{#3}{#5}{##1}} + } + { + \@ifundefined{c@#4} + { + \@nocounterr{#4} + } + { + \expandafter\xdef\csname the#3\endcsname{ + \expandafter\noexpand\csname the#4\endcsname} + \expandafter\DeclareDocumentCommand\csname #3\endcsname{o} + {\UseInstance{theoremstyle}{#2}{#4}{#5}{##1}} + } + } + } + } +} +% \end{macrocode} +% +% \begin{macrocode} +\endinput +% \end{macrocode} +% +% \begin{macrocode} +%</package> +% \end{macrocode} +% +% +% \Finale +% +\endinput diff --git a/Master/texmf-dist/source/latex3/xtheorem/xtheorem.ins b/Master/texmf-dist/source/latex3/xtheorem/xtheorem.ins new file mode 100644 index 00000000000..f9ed9513d7d --- /dev/null +++ b/Master/texmf-dist/source/latex3/xtheorem/xtheorem.ins @@ -0,0 +1,14 @@ +\input docstrip +\keepsilent +\askforoverwritefalse + +\preamble + +Not for distribution +\endpreamble + +\generate{ + \file{xtheorem.sty}{\from{xtheorem.dtx}{package,trace}} + } + +\endbatchfile |