% \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} % %\NeedsTeXFormat{LaTeX2e} %\ProvidesPackage{galley2} %\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} % % \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 } % % \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} % \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} % \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!} % \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} % \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} % \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@ } } % % \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} % % \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} % \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} % \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 } % % \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 } % % \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+|. 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+|.\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@}% % % \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}% % \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} % \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} % } % \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} % \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} % \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 } % \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}} % \def\@afterheading{ %<*trace> \showGALcmd{@afterheading} % \if@afterindent \else \setDGPVthing:nn i \@ne \fi \setGALbreak:n 2 } \def\nofiles{% %<*trace> \showGALcmd{} % \@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} % \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{} % \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{} % \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} % \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} % % % 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} % \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} % \@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} % \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} % \@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} % \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} % % \end{macrocode} % % % \Finale %