% \iffalse % %% File: xgalley.dtx % % Copyright (C) 1999-2001,2004-2009 Frank Mittelbach % (C) 2010-2012,2014,2016-2024 The LaTeX Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this % license or (at your option) any later version. The latest version % of this license is in the file % % https://www.latex-project.org/lppl.txt % % This file is part of the "l3experimental bundle" (The Work in LPPL) % and all files in that bundle must be distributed together. % % ----------------------------------------------------------------------- % % The development version of the bundle can be found at % % https://github.com/latex3/latex3 % % for those people who are interested. % %<*driver> \documentclass[full]{l3doc} \begin{document} \DocInput{\jobname.dtx} \end{document} % % \fi % % \title{^^A % The \pkg{xgalley} package\\ Galley^^A % } % % \author{^^A % The \LaTeX{} Project\thanks % {^^A % E-mail: % \href{mailto:latex-team@latex-project.org} % {latex-team@latex-project.org}^^A % }^^A % } % % \date{Released 2024-03-14} % % \maketitle % % \begin{documentation} % % \section{Introduction} % % In \LaTeX3 terminology a galley is a rectangular area which receives % text and other material filling it from top. The vertically extend of % a galley is normally not restricted: 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 behaviour. % % Examples for galleys are \enquote{the main galley}, where the % continuous document data gets formatted into and from which columns % and pages are constructed, and \enquote{vertical box galleys}, such % as the body of a minipage environment. The latter galleys are % typically not split after formatting, though there can be exceptions. % % \section{Formatting layers} % % The present module is mainly concerned with the formatting of text % in galleys. The mechanism by which this is achieved uses four % (somewhat) distinct layers, some of which can be addressed using the % templates provided here. % % \subsection{Layer one: external dimensions} % % The bottom layer of the system is the external dimensions of the % galley. Normally only the horizontal dimension is fixed externally, % while the vertical (filling) dimension is unspecified. The external % dimensions are fixed when starting a new galley, and are therefore % not modifiable within the galley. % % There are no templates for setting this layer directly, although the % external values are influenced by other parts of the system (for % example when creating minipage environments). % % \subsection{Layer two: internal dimensions} % % The second layer is the internal dimensions of the galley: the % \emph{measure} used for paragraph text and the position of the % paragraph relative to the edges of the galley. % % This layer is normally accessed by higher-level templates % \emph{via} the object type \texttt{measure}. Changes made using % level two templates will often extend for large parts of a document % (up to and including the entire document). % % \subsection{Layer three: paragraph shape} % % The third layer defines the paragraph shape within the measure as % provided by the second layer. In the absence of any specification % for that layer the paragraph shape used will be that of a % rectangular area of the width of the current measure. % % There are some restrictions imposed on the shape of a paragraph by the % underlying \TeX{} mechanisms. For example, cut out sections in % paragraphs can be specified from the top of the paragraph but not from % the bottom. % % \subsection{Layer four: formatting inside the paragraph} % % The forth layer deals with the paragraph formatting aspects such as % hyphenation and justification within the paragraph (this is sometimes % referred to as \enquote{\texttt{h\&j}} or \enquote{\texttt{hj}}). % % \section{Templates} % % \subsection{Layer two: internal dimensions} % % \begin{TemplateInterfaceDescription}{measure} % \TemplateArgument{}{} ^^A Some hack % \TemplateSemantics % Sets the width available to typeset material within the galley. % The \meta{left margin} and \meta{right margin} values are used in the % adjustment to over-ride any given in the template. Depending upon % the template in use, the margins may be absolute (relative only to the % edges of the galley) or relative (taking account of |measure| adjustments % already made). The template applies to the galley from the point of % us forward, unless over-ridden by another use of the |measure| % object type. % \end{TemplateInterfaceDescription} % % \begin{TemplateDescription}{measure}{absolute} % \TemplateKey{left-margin}{length} % {^^A % The distance from the left edge of the galley to the left edge of % the area for typeset material. A negative value will cause the % typeset material to extend beyond the edge of the galley.^^A % } % {0pt} % \TemplateKey{right-margin}{length} % {^^A % The distance from the right edge of the galley to the right edge of % the area for typeset material. A negative value will cause the % typeset material to extend beyond the edge of the galley.^^A % } % {0pt} % \TemplateSemantics % This template sets up the typesetting area such that typeset material % runs from |left-margin| away from the left edge of the galley to % |right-margin| away from the right edge of the galley. Both of these % distances are absolute, \emph{i.e.}~no account is taken of previous % |measure| settings. Either on or both values may be negative, in which % case the typeset material will protrude outside of the edges of the % galley. % \end{TemplateDescription} % % \begin{TemplateDescription}{measure}{relative} % \TemplateKey{left-margin}{length} % {^^A % The distance from the previous left margin of the typeset material % within the galley to the new position of the left margin. A negative % value will cause the new margin to be \enquote{outside} of the % previous one, and \emph{may} cause the typeset material to % protrude outside of the edge of the galley. % } % {0pt} % \TemplateKey{right-margin}{length} % {^^A % The distance from the previous right margin of the typeset material % within the galley to the new position of the right margin. A negative % value will cause the new margin to be \enquote{outside} of the % previous one, and \emph{may} cause the typeset material to % protrude outside of the edge of the galley. % } % {0pt} % \TemplateSemantics % This template sets up the typesetting area such that it has margins % |left-margin| and |right-margin| within those previously set. For a % galley within no previous margins, this will result in margins relative % to the edges of the galley. Within a galley in which the |measure| has % already been set, using the |relative| template will indent the typeset % material relative to the existing margins. % Either on or both values may be negative, in which % case the typeset material may protrude outside of the edges of the % galley. % \end{TemplateDescription} % % \subsection{Layer three: paragraph shape} % % \begin{TemplateInterfaceDescription}{parshape} % \TemplateArgument{}{}^^A Some hack % \TemplateSemantics % Template of this type define any shaping of the paragraph within the % current measure of the galley. Thus they are used to generate % \enquote{special} paragraph shapes, for example placing a cutout % in one side of the paragraph. Typically, \texttt{parshape} templates % will apply in a limited sense (to a single paragraph or a defined number of % lines). However, \texttt{parshape} templates may also apply in an % \enquote{ongoing} manner. % % Note that \texttt{parshape} templates do not alter any first-line % indent for paragraphs (or any other \enquote{in paragraph} setting). % Instead, they define a shape inside which the paragraph material will be % placed. % \end{TemplateInterfaceDescription} % % \begin{TemplateDescription}{parshape}{hang} % \TemplateKey{indent}{length} % {^^A % The hanging indent from either the left- or right-hand margin % (as determined by \texttt{on-left-side}).^^A % } % {0pt} % \TemplateKey{on-left-side}{boolean} % {^^A % If \texttt{true}, causes the hanging indent to be on the left-hand % side of the paragraph.^^A % } % {true} % \TemplateKey{lines}{integer} % {The number of lines of full width before hanging begins.} % {1} % \TemplateSemantics % Sets the paragraph shape such that the after a number of full-width % lines, specified by |lines|, the paragraph is indented by the % |indent| from a margin. If |on-left-side| is |true| this indent will be % from the left-hand margin, otherwise it will be from the right. In either % case, the indent is relative to the edge of the current |measure| and % may be negative (in which case an outdent will result). % This template type applies only to a single paragraph. % \end{TemplateDescription} % % \begin{TemplateDescription}{parshape}{initial} % \TemplateKey{indent}{length} % {^^A % The indent for the initial lines from either the left- or right-hand % margin (as determined by \texttt{on-left-side}).^^A % } % {0pt} % \TemplateKey{on-left-side}{boolean} % {^^A % If \texttt{true}, causes the indent to be on the left-hand % side of the paragraph.^^A % } % {true} % \TemplateKey{lines}{integer} % {The number of lines of indented lines before full-width line begins.} % {2} % \TemplateSemantics % Sets the paragraph shape such that the first |lines| lines % are indented by the |indent| given, before lines of full width begin. % If |on-left-side| is |true| this indent will be % from the left-hand margin, otherwise it will be from the right. In either % case, the indent is relative to the edge of the current |measure| and % may be negative (in which case an outdent will result). % This template type applies only to a single paragraph. % \end{TemplateDescription} % % \begin{TemplateDescription}{parshape}{std} % \TemplateKey{}{}{}{} ^^A hack % \TemplateSemantics % Sets a rectangular paragraph shape which occupies the full width % specified by the |measure|. It is therefore intended as a % \enquote{do nothing} template for use where a paragraph shape is required % but where no special formatting is needed. This template type applies only % to a single paragraph. % \end{TemplateDescription} % % \subsection{Layer four: formatting inside the paragraph} % % \begin{TemplateInterfaceDescription}{hyphenation} % \TemplateArgument{}{} ^^A Hack % \TemplateSemantics % Controls whether hyphenation is attempted within the current % galley. This object type may also alter the degree to which hyphenation % is encouraged by manipulating the underlying \TeX{} parameters. This % object type applies to the galley from the point of use forward. % \end{TemplateInterfaceDescription} % % \begin{TemplateDescription}{hyphenation}{std} % \TemplateKey{enable}{boolean} % {Switches all hyphenation on or off.} % {true} % \TemplateKey{enable-upper-case} % {boolean} % {^^A % Switches hyphenation on or off for words beginning with upper case % letters.^^A % } % {true} % \TemplateKey{penalty}{choice} % {^^A % Sets the degree to which \TeX{} is discouraged from undertaking % hyphenation, from the choices |low|, |medium| and |high|.^^A % } % {low} % \TemplateSemantics % Determines both whether hyphenation is allowed at all, and if so to % what degree it is discouraged. Setting |penalty| to |high| does not % prevent hyphenation: this is only done if |enable| is set |false|. % \end{TemplateDescription} % % \begin{TemplateInterfaceDescription}{justification} % \TemplateArgument{}{} ^^A Hack % \TemplateSemantics % Controls the nature of justification undertaken within the galley. % The template applies from the point of use forward. % \end{TemplateInterfaceDescription} % % \begin{TemplateDescription}{justification}{std} % \TemplateKey{end-skip}{skip} % {The skip inserted to fill the last line of a paragraph.} % {0pt plus 1fil} % \TemplateKey{fixed-word-spacing}{boolean} % {^^A % Determines whether inter-word spacing has a stretch component (for % non-monospaced fonts.^^A % } % {false} % \TemplateKey{indent-width}{length} % {^^A % The length of the indent inserted at the start of the first line of a % new paragraph.^^A % } % {} % \TemplateKey{left-skip}{skip} % {^^A % The skip between the left margin of the galley and the left edge of a % paragraph.^^A % } % {0pt} % \TemplateKey{right-skip}{skip} % {^^A % The skip between the right margin of the galley and the right edge of a % paragraph.^^A % } % {0pt} % \TemplateKey{start-skip}{skip} % {^^A % The skip inserted in addition to |indent-width| at the start of a % paragraph.^^A % } % {0pt} % \TemplateSemantics % The |std| template for justification provides rubber lengths % at the start and end of the paragraph and at each side of the paragraph. % It also allows for both flexible and fixed inter-word spacing. The % interaction between the settings is demonstrated in the selection of % standard instances provided. % \end{TemplateDescription} % % \begin{InstanceDescription}{justification}{justified}{std} % \InstanceKey{indent-width}{15pt} % \InstanceSemantics % Sets paragraphs fully-justified with the first line indented by % |15pt|. % \end{InstanceDescription} % % \begin{InstanceDescription}{justification}{noindent}{std} % \InstanceKey{end-skip}{15pt plus 1fil} % \InstanceKey{indent-width}{0pt} % \InstanceSemantics % Sets paragraphs fully-justified with no indent for the first line. To % ensure that paragraphs have some visual distinction, the |end-skip| is % set to insert some space in all cases. % \end{InstanceDescription} % % \begin{TemplateDescription}{justification}{single} % \TemplateKey{end-skip}{skip} % {The skip inserted to fill the last line of a paragraph.} % {0pt plus 1fil} % \TemplateKey{fixed-word-spacing}{boolean} % {^^A % Determines whether inter-word spacing has a stretch component (for % non-monospaced fonts.^^A % } % {false} % \TemplateKey{indent-width}{length} % {^^A % The length of the indent inserted at the start of the first line of a % new paragraph.^^A % } % {} % \TemplateKey{left-skip}{skip} % {^^A % The skip between the left margin of the galley and the left edge of a % paragraph.^^A % } % {0pt} % \TemplateKey{right-skip}{skip} % {^^A % The skip between the right margin of the galley and the right edge of a % paragraph.^^A % } % {0pt} % \TemplateKey{start-skip}{skip} % {^^A % The skip inserted in addition to |indent-width| at the start of a % paragraph.^^A % } % {0pt} % \TemplateKey{stretch-last-line}{boolean} % { % Determines whether inter-word spacing in the last line is stretched. % If \texttt{true}, the spacing in the last line is stretched in the % by the same factor as that in the penultimate line.^^A % } % {false} % \TemplateSemantics % The |single| template for justification provides rubber lengths % at the start and end of the paragraph and at each side of the paragraph. % It also allows for both flexible and fixed inter-word spacing. The % interaction between the settings is demonstrated in the selection of % standard instances provided. The template applies only to a single % paragraph. % \end{TemplateDescription} % % \begin{InstanceDescription}[fixed-word-spacing-xxx]{justification}{ragged-left}{std} % \InstanceKey{end-skip}{0pt} % \InstanceKey{fixed-word-spacing}{true} % \InstanceKey{indent-width}{0pt} % \InstanceKey{left-skip}{0pt plus 2em} % \InstanceKey{right-skip}{0pt} % \InstanceSemantics % Typesets material with a ragged left margin such that hyphenation will % still occur and such that very short lines are discouraged. This is % similar to the \LaTeXe{} \pkg{ragged2e} \env{RaggedLeft} environment. % \end{InstanceDescription} % % \begin{InstanceDescription}[fixed-word-spacing-xxx]{justification}{ragged-right}{std} % \InstanceKey{end-skip}{0pt} % \InstanceKey{fixed-word-spacing}{true} % \InstanceKey{indent-width}{0pt} % \InstanceKey{left-skip}{0pt} % \InstanceKey{right-skip}{0pt plus 2em} % \InstanceSemantics % Typesets material with a ragged right margin such that hyphenation will % still occur and such that very short lines are discouraged. This is % similar to the \LaTeXe{} \pkg{ragged2e} \env{RaggedLeft} environment. % \end{InstanceDescription} % % \begin{InstanceDescription}[fixed-word-spacing-xxx]{justification}{center}{std} % \InstanceKey{end-skip}{0pt} % \InstanceKey{fixed-word-spacing}{true} % \InstanceKey{indent-width}{0pt} % \InstanceKey{left-skip}{0pt plus 1fil} % \InstanceKey{right-skip}{0pt plus 1fil} % \InstanceSemantics % Centres typeset material such that hyphenation is discouraged and short % lines are allowed. % \end{InstanceDescription} % % \begin{TemplateDescription}{justification}{compound} % \TemplateKey{first-paragraph}{instance} % {Justification for the first paragraph.} % {} % \TemplateKey{other-paragraphs}{instance} % {Justification for the remaining paragraphs.} % {} % \TemplateSemantics % Here, both keys should themselves be instances of the |justification| % template. The |compound| template is used to set up a single % \enquote{non-standard} paragraph followed by \enquote{standard} ones. % For example, it can be used to ensure that one |noindent| paragraph is % then followed by |std| justification. % \end{TemplateDescription} % % \begin{TemplateInterfaceDescription}{line-breaking} % \TemplateArgument{}{} ^^A Hack % \TemplateSemantics % Controls the line breaking attempted by \TeX{} when typesetting % material for the galley. This does not include whether words are % hyphenated, which is handled separately. % \end{TemplateInterfaceDescription} % % \begin{TemplateDescription}{line-breaking}{std} % \TemplateKey{badness}{integer} % {^^A % Boundary that if exceeded will cause \TeX{} to report an % underfull line.^^A % } % {1000} % \TemplateKey{binop-penalty}{integer} % {^^A % Penalty charged if an inline math formula is broken at a % binary operator.^^A % } % {700} % \TemplateKey{double-hyphen-demerits}{integer} % {^^A % Extra demerit charge of two (or more) lines in succession end % in a hyphen.^^A % } % {10000} % \TemplateKey{emergency-stretch}{skip} % {^^A % Additional stretch assumed for each line if no better line breaking % can be found without it. This stretch is not actually added to lines, % so its use may result in underfull box warnings.^^A % } % {0pt} % \TemplateKey{final-hyphen-demerits}{integer} % {Extra demerit charge if the second last line is hyphenated.} % {5000} % \TemplateKey{fuzz}{length} % {Boundary below overfull lines are not reported.} % {0.1pt} % \TemplateKey{mismatch-demerits}{integer} % {^^A % Extra demerit charge if two visually incompatible lines follow % each other.^^A % } % {10000} % \TemplateKey{line-penalty}{integer} % {^^A % Extra penalty charged per line in the paragraph. By making % this penalty higher \TeX{} will try harder to produce compact % paragraphs.^^A % } % {10} % \TemplateKey{pretolerance}{integer} % {^^A % Maximum tolerance allowed for individual lines to break the % paragraph without attempting hyphenation.^^A % } % {100} % \TemplateKey{relation-penalty}{integer} % {^^A % Penalty charged if an inline math formula is broken at a % relational symbol.^^A % } % {500} % \TemplateKey{tolerance}{integer} % {^^A % Maximum tolerance allowed for individual lines when breaking a % paragraph while attempting hyphenation (if this limit can't be % met \texttt{emergency-stretch} comes into play).^^A % } % {200} % \TemplateSemantics % This is an interface to the underlying \TeX{} system for determining % line breaking. % \end{TemplateDescription} % % \subsection{Between paragraphs} % % \begin{TemplateInterfaceDescription}{paragraph-breaking} % \TemplateArgument{}{} ^^A Hack % \TemplateSemantics % This object type determines how \TeX{} determines the behaviour when % the paragraph-breaking algorithm is calculating whether to break up a % paragraph. Thus for example an instance of this object type may prevent % breaks within a paragraph, forbid widows or orphans, \emph{etc.} % \end{TemplateInterfaceDescription} % % \begin{TemplateDescription}{paragraph-breaking}{std} % \TemplateKey{badness}{integer} % {^^A % Boundary that if exceeded will cause \TeX{} to report an % underfull vertical box.^^A % } % {1000} % \TemplateKey{broken-penalty}{integer} % {Penalty for page breaking after a hyphenated line.} % {100} % \TemplateKey{club-penalty}{integer} % {Penalty for generating a club line when page breaking.} % {150} % \TemplateKey{display-club-penalty}{integer} % {^^A % Penalty for breaking between to leave a club line after display % math.^^A % } % {150} % \TemplateKey{display-widow-penalty}{integer} % {^^A % Penalty for breaking between to leave a widow line before display % math.^^A % } % {150} % \TemplateKey{fuzz}{length} % {Boundary below which overfull vertical boxes are not reported.} % {0.1pt} % \TemplateKey{interline-penalty}{integer} % {Penalty for breaking between lines in a paragraph.} % {0} % \TemplateKey{pre-display-penalty}{integer} % {Penalty for breaking between immediately before display math material.} % {10000} % \TemplateKey{post-display-penalty}{integer} % {Penalty for breaking between immediately after display math material.} % {0} % \TemplateKey{widow-penalty}{integer} % {Penalty for generating a widow line when page breaking.} % {150} % \TemplateSemantics % This template provides an interface to the underlying \TeX{} mechanism for % controlling page breaking. The template applies on an ongoing basis to all % paragraphs after the template is used. % \end{TemplateDescription} % % \begin{InstanceDescription}{paragraph-breaking}{std}{std} % \InstanceSemantics % Sets paragraphs such that they can break with widows and orphans % discouraged but not prevented. Breaks are possible after display math % material but no immediately before it. % \end{InstanceDescription} % % \begin{InstanceDescription}[post-display-penalty-xxxx]{paragraph-breaking}{nobreak}{std} % \InstanceKey{interline-penalty}{10000} % \InstanceKey{post-display-penalty}{10000} % \InstanceSemantics % Sets paragraphs such that they cannot be broken at all (as far as is % possible in \TeX{}). % \end{InstanceDescription} % % \begin{InstanceDescription}[post-display-penalty-xxxx]{paragraph-breaking}{nolone}{std} % \InstanceKey{club-penalty}{10000} % \InstanceKey{display-widow-penalty}{10000} % \InstanceKey{widow-penalty}{10000} % \InstanceSemantics % Sets paragraphs such that they cannot be broken to leave a club or % widow line (as far as is possible in \TeX{}). % \end{InstanceDescription} % % \begin{TemplateDescription}{paragraph-breaking}{single} % \TemplateKey{badness}{integer} % {^^A % Boundary that if exceeded will cause \TeX{} to report an % underfull vertical box.^^A % } % {\meta{none}} % \TemplateKey{broken-penalty}{integer} % {Penalty for page breaking after a hyphenated line.} % {\meta{none}} % \TemplateKey{club-penalty}{integer} % {Penalty for generating a club line when page breaking.} % {\meta{none}} % \TemplateKey{display-club-penalty}{integer} % {^^A % Penalty for breaking between to leave a club line after display % math.^^A % } % {\meta{none}} % \TemplateKey{display-widow-penalty}{integer} % {^^A % Penalty for breaking between to leave a widow line before display % math.^^A % } % {\meta{none}} % \TemplateKey{fuzz}{length} % {Boundary below which overfull vertical boxes are not reported.} % {\meta{none}} % \TemplateKey{interline-penalty}{integer} % {Penalty for breaking between lines in a paragraph.} % {\meta{none}} % \TemplateKey{pre-display-penalty}{integer} % {Penalty for breaking between immediately before display math material.} % {\meta{none}} % \TemplateKey{post-display-penalty}{integer} % {Penalty for breaking between immediately after display math material.} % {\meta{none}} % \TemplateKey{widow-penalty}{integer} % {Penalty for generating a widow line when page breaking.} % {\meta{none}} % \TemplateSemantics % This template provides an interface to the underlying \TeX{} mechanism for % controlling page breaking. The template applies only to the next paragraph, % and can thus be used to achieve effects such as non-breaking paragraphs. % \end{TemplateDescription} % % \begin{InstanceDescription}{paragraph-breaking}{single-std}{single} % \InstanceSemantics % Sets the next paragraph such that it can break with widows and orphans % discouraged but not prevented. Breaks are possible after display math % material but no immediately before it. % \end{InstanceDescription} % % \begin{InstanceDescription}[post-display-penalty-xxx]{paragraph-breaking}{single-nobreak}{single} % \InstanceKey{interline-penalty}{10000} % \InstanceKey{post-display-penalty}{10000} % \InstanceSemantics % Sets the next paragraph such that it cannot be broken at all (as far as is % possible in \TeX{}). % \end{InstanceDescription} % % \begin{InstanceDescription}[display-club-penalty-xxx]{paragraph-breaking}{single-noclub}{single} % \InstanceKey{club-penalty}{10000} % \InstanceKey{display-club-penalty}{10000} % \InstanceSemantics % Sets the next paragraph such that it cannot be broken to leave a club % line (as far as is possible in \TeX{}). % \end{InstanceDescription} % % \begin{InstanceDescription}[display-widow-penalty-xxx]{paragraph-breaking}{single-nolone}{single} % \InstanceKey{club-penalty}{10000} % \InstanceKey{display-club-penalty}{10000} % \InstanceKey{display-widow-penalty}{10000} % \InstanceKey{widow-penalty}{10000} % \InstanceSemantics % Sets the next paragraph such that it cannot be broken to leave a club or % widow line (as far as is possible in \TeX{}). % \end{InstanceDescription} % % \begin{InstanceDescription}[display-widow-penalty-xxx]{paragraph-breaking}{single-nowidow}{single} % \InstanceKey{display-widow-penalty}{10000} % \InstanceKey{widow-penalty}{10000} % \InstanceSemantics % Sets the next paragraph such that it cannot be broken to leave a % widow line (as far as is possible in \TeX{}). % \end{InstanceDescription} % % \end{documentation} % % \begin{implementation} % % \section{\pkg{xgalley} implementation} % % This module provided a template-level interface for the \LaTeX3 galley. As % such, the code here is intended for design-level changes which apply to % large blocks. The variables provided are therefore used only for supporting % the templates, while any documented interfaces are in \pkg{l3galley}. % % \begin{macrocode} %<*package> % \end{macrocode} % % \begin{macrocode} %<@@=galley> % \end{macrocode} % % \begin{macrocode} \ProvidesExplPackage{xgalley}{2024-03-14}{} {L3 Experimental galley} \RequirePackage{xtemplate,l3galley} % \end{macrocode} % % \subsection{Variables} % % \begin{variable}{\l_@@_tmpa_clist, \l_@@_tmpb_clist} % Scratch space. % \begin{macrocode} \clist_new:N \l_@@_tmpa_clist \clist_new:N \l_@@_tmpb_clist % \end{macrocode} % \end{variable} % % \subsection{Layer two: internal dimensions} % % There is a single object type for level two, the \texttt{measure} for % the text in the galley. There are no arguments, as the measure is a design % concept. % \begin{macrocode} \DeclareObjectType { measure } { 0 } % \end{macrocode} % % There are two templates for galley measures: absolute and relative. % Both use the same interface. % \begin{macrocode} \DeclareTemplateInterface { measure } { absolute } { 0 } { left-margin : length = 0pt , right-margin : length = 0pt } \DeclareTemplateInterface { measure } { relative } { 0 } { left-margin : length = 0pt , right-margin : length = 0pt } % \end{macrocode} % % \begin{variable}{\l_@@_left_margin_dim, \l_@@_right_margin_dim} % In the \texttt{absolute} template, the two margin values are relative % to the edges of the galley. This means that any existing offset or % line-length adjustment are ignored. % \begin{macrocode} %<*package> \cs_new_eq:NN \l_@@_left_margin_dim \leftmargin % %<*package> \cs_new_eq:NN \l_@@_right_margin_dim \rightmargin % \DeclareTemplateCode { measure } { absolute } { 0 } { left-margin = \l_@@_left_margin_dim , right-margin = \l_@@_right_margin_dim } { \galley_margins_set_absolute:nn \l_@@_left_margin_dim \l_@@_right_margin_dim } % \end{macrocode} % On the other hand, the \texttt{relative} template works relative to % the current indentation at both sides. % \begin{macrocode} \DeclareTemplateCode { measure } { relative } { 0 } { left-margin = \l_@@_left_margin_dim , right-margin = \l_@@_right_margin_dim } { \galley_margins_set_relative:nn \l_@@_left_margin_dim \l_@@_right_margin_dim } % \end{macrocode} % \end{variable} % % \subsection{Layer three: paragraph shape} % % The object type \texttt{parshape} is a somewhat extended interface % to the \TeX{} \cs{tex_parshape:D} primitive. As with the \texttt{measure}, % the \texttt{parshape} template has no arguments as it is essentially a % design-oriented concept. % \begin{macrocode} \DeclareObjectType { parshape } { 0 } % \end{macrocode} % % There are two standard templates for paragraph shapes which do % something, both with the same interface. The \texttt{hang} template % provides one or more standard lines followed by a hanging paragraph, % while the \texttt{initial} template cuts out a space at the start of % the paragraph. % \begin{macrocode} \DeclareTemplateInterface { parshape } { hang } { 0 } { indent : length = 0pt , on-left-side : boolean = true , lines : integer = 1 } \DeclareTemplateInterface { parshape } { initial } { 0 } { indent : length = 0pt , on-left-side : boolean = true , lines : integer = 2 } % \end{macrocode} % \begin{variable}{\l_@@_parshape_indent_dim} % \begin{variable}{\l_@@_parshape_on_left_bool} % \begin{variable}{\l_@@_parshape_lines_int} % Both of the templates are implemented as special cases of the more % general function defined earlier. % \begin{macrocode} \DeclareTemplateCode { parshape } { hang } { 0 } { indent = \l_@@_parshape_indent_dim , on-left-side = \l_@@_parshape_on_left_bool , lines = \l_@@_parshape_lines_int } { \bool_if:NTF \l_@@_parshape_on_left_bool { \galley_parshape_set_single:nVVN \l_@@_parshape_lines_int \l_@@_parshape_indent_dim \c_zero_dim \c_false_bool } { \galley_parshape_set_single:nVVN \l_@@_parshape_lines_int \c_zero_dim \l_@@_parshape_indent_dim \c_false_bool } } \DeclareTemplateCode { parshape } { initial } { 0 } { indent = \l_@@_parshape_indent_dim , on-left-side = \l_@@_parshape_on_left_bool , lines = \l_@@_parshape_lines_int } { \clist_clear:N \l_@@_tmpa_clist \clist_clear:N \l_@@_tmpb_clist \prg_replicate:nn { \l_@@_parshape_lines_int } { \clist_put_right:Nn \l_@@_tmpa_clist { \l_@@_parshape_indent_dim } \clist_put_right:Nn \l_@@_tmpb_clist { \c_zero_dim } } \bool_if:NTF \l_@@_parshape_on_left_bool { \galley_parshape_set_single:nVVN { 0 } \l_@@_tmpa_clist \l_@@_tmpb_clist \c_true_bool } { \galley_parshape_set_single:nVVN { 0 } \l_@@_tmpb_clist \l_@@_tmpa_clist \c_true_bool } } % \end{macrocode} % \end{variable} % \end{variable} % \end{variable} % % There is also a \enquote{do nothing} paragraph shape for cases where % a template is needed but no action is desirable. % \begin{macrocode} \DeclareTemplateInterface { parshape } { std } { 0 } { } \DeclareTemplateCode { parshape } { std } { 0 } { } { } % \end{macrocode} % % \subsection{Layer four: formatting inside the paragraph} % % The first type of object within a paragraph is the hyphenation. This % object needs no arguments. % \begin{macrocode} \DeclareObjectType { hyphenation } { 0 } % \end{macrocode} % % There is only hyphenation template as standard. This provides a % semi-flexible interface to the underlying \TeX{} methods. (The detail % is therefore hidden within the implementation phase.) % \begin{macrocode} \DeclareTemplateInterface { hyphenation } { std } { 0 } { enable : boolean = true , enable-upper-case : boolean = true , penalty : choice { low , medium , high } = low } % \end{macrocode} % The implementation for hyphenation mainly sets low-level values. % The minimum number of characters after a hyphen is set directly, % whereas the number before is not. This is so that % \cs{tex_lefthyphenmin:D} can also be used to completely prevent % hyphenation. % \begin{macrocode} \DeclareTemplateCode { hyphenation } { std } { 0 } { enable = \l_galley_hyphen_enable_bool , enable-upper-case = \l_galley_hyphen_uppercase_bool , penalty = { low = { \int_set:Nn \tex_hyphenpenalty:D { 51 } \int_set:Nn \tex_exhyphenpenalty:D { 51 } } , medium = { \int_set:Nn \tex_hyphenpenalty:D { 151 } \int_set:Nn \tex_exhyphenpenalty:D { 151 } } , high = { \int_set:Nn \tex_hyphenpenalty:D { 301 } \int_set:Nn \tex_exhyphenpenalty:D { 301 } } , } } { \int_set:Nn \tex_lefthyphenmin:D { \bool_if:NTF \l_galley_hyphen_enable_bool { \l_galley_hyphen_left_int } { 63 } } \int_set:Nn \tex_uchyph:D { \bool_if:NTF \l_galley_hyphen_uppercase_bool { 1 } { 0 } } } % \end{macrocode} % At this stage, the default hyphenation character should be set and % hyphenation should be enabled. % \begin{macrocode} \UseTemplate { hyphenation } { std } { } \tex_defaulthyphenchar:D 45 \scan_stop: % \end{macrocode} % % \begin{variable}{\l_@@_justification_other_tl} % Used for the reset system for justification: using this token list means % that there is no need to remove anything from % \cs{g_galley_restore_running_tl}. % \begin{macrocode} \tl_new:N \l_@@_justification_other_tl % \end{macrocode} % \end{variable} % % The second level four object is the justification, which again % takes no arguments. % \begin{macrocode} \DeclareObjectType { justification } { 0 } % \end{macrocode} % There are two templates here with the same interface: the standard one % to apply from this point onward, and one which applies only to a single % paragraph. % \begin{macrocode} \DeclareTemplateInterface { justification } { std } { 0 } { end-skip : skip = 0pt plus 1fil , fixed-word-spacing : boolean = false , indent-width : length , left-skip : skip = 0pt , right-skip : skip = 0pt , start-skip : skip = 0pt , stretch-last-line : boolean = false } \DeclareTemplateInterface { justification } { single } { 0 } { end-skip : skip = 0pt plus 1fil , fixed-word-spacing : boolean = false , indent-width : length , left-skip : skip = 0pt , right-skip : skip = 0pt , start-skip : skip = 0pt , stretch-last-line : boolean = false } % \end{macrocode} % \begin{variable}{\l_galley_fixed_spacing_bool} % The implementation here is pretty simple as almost everything that % goes on is a simple case of saving the settings, which are then % applied either by \TeX{} itself or the rest of the galley system. % \begin{macrocode} \DeclareTemplateCode { justification } { std } { 0 } { end-skip = \l_galley_par_end_skip , fixed-word-spacing = \l_galley_fixed_spacing_bool , indent-width = \l_galley_par_indent_dim , left-skip = \l_galley_line_left_skip , right-skip = \l_galley_line_right_skip , start-skip = \l_galley_par_begin_skip , stretch-last-line = \l_galley_par_stretch_last_bool } { \tl_clear:N \l_@@_justification_other_tl \galley_interword_spacing_set:N \l_galley_fixed_spacing_bool \bool_if:NTF \l_galley_par_stretch_last_bool { \int_set:Nn \l_galley_last_line_fit_int { 1000 } } { \int_zero:N \l_galley_last_line_fit_int } \skip_set:Nn \@rightskip { \l_galley_line_right_skip } } % \end{macrocode} % \end{variable} % To deal with a single paragraph, the approach used is to save the current % settings to the paragraph-reset code, then to assign the template in the % same way as for the |std| template. % \begin{macrocode} \DeclareTemplateCode { justification } { single } { 0 } { end-skip = \l_galley_par_end_skip , fixed-word-spacing = \l_galley_fixed_spacing_bool , indent-width = \l_galley_par_indent_dim , left-skip = \l_galley_line_left_skip , right-skip = \l_galley_line_right_skip , start-skip = \l_galley_par_begin_skip , stretch-last-line = \l_galley_par_stretch_last_bool } { \tl_put_left:Ne \l_@@_justification_other_tl { \skip_set:Nn \exp_not:N \l_galley_par_end_skip { \skip_use:N \l_galley_par_end_skip } \bool_if:NTF \l_galley_fixed_spacing_bool { \bool_set_true:N \exp_not:N \l_galley_fixed_spacing_bool } { \bool_set_false:N \exp_not:N \l_galley_fixed_spacing_bool } \galley_interword_spacing_set:N \exp_not:N \l_galley_fixed_spacing_bool \dim_set:Nn \exp_not:N \l_galley_par_indent_dim { \dim_use:N \l_galley_par_indent_dim } \skip_set:Nn \l_galley_line_left_skip { \skip_use:N \l_galley_line_left_skip } \skip_set:Nn \exp_not:N \l_galley_line_right_skip { \skip_use:N \l_galley_line_right_skip } \skip_set:Nn \exp_not:N \l_galley_par_begin_skip { \skip_use:N \l_galley_par_begin_skip } \int_set:Nn \exp_not:N \l_galley_last_line_fit_int { \int_use:N \l_galley_last_line_fit_int } \skip_set:Nn \exp_not:N \@rightskip { \skip_use:N \l_galley_line_right_skip } } \tl_gput_right:Nn \g_galley_restore_running_tl { \l_@@_justification_other_tl } \AssignTemplateKeys \galley_interword_spacing_set:N \l_galley_fixed_spacing_bool \bool_if:NTF \l_galley_par_stretch_last_bool { \int_set:Nn \l_galley_last_line_fit_int { 1000 } } { \int_zero:N \l_galley_last_line_fit_int } \skip_set:Nn \@rightskip { \l_galley_line_right_skip } } % \end{macrocode} % The standard instance for justification is very simple to set up as % the default values for the template are set up for exactly this case. % The advantage of this scheme is that at a design level altering the % indent used for justified paragraphs is very easy to do. As this is % the standard template for all \LaTeX3 documents, it is applied here. % \begin{macrocode} \DeclareInstance { justification } { justified } { std } { indent-width = 15pt } \UseInstance { justification } { justified } % \end{macrocode} % The instance for no indentation at all but with justified text is % intended for layouts which leave white space between paragraphs. With % no indentation, some space has to be included at the end of each % paragraph. This is set up to mirror the indent that has been removed. % \begin{macrocode} \DeclareInstance { justification } { noindent } { std } { end-skip = 15pt plus 1fil , indent-width = 0pt } % \end{macrocode} % The other standard justification schemes are for text which ragged. % The settings here are taken from the \LaTeXe{} % \pkg{ragged2e} package, as they maintain a reasonable appearance by % ensuring that \TeX{} will not be too tolerant of very short lines. % To keep the design clear here, no default values are relied on even % though this would make the instance declarations shorter. % \begin{macrocode} \DeclareInstance { justification } { ragged-left } { std } { end-skip = 0pt , fixed-word-spacing = true , indent-width = 0pt , left-skip = 0pt plus 2em , right-skip = 0pt } \DeclareInstance { justification } { ragged-right } { std } { end-skip = 0pt plus 1fil , fixed-word-spacing = true , indent-width = 0pt , left-skip = 0pt , right-skip = 0pt plus 2em } % \end{macrocode} % The \texttt{center} instance is used to center material with minimal % hyphenation. % \begin{macrocode} \DeclareInstance { justification } { center } { std } { end-skip = 0pt , fixed-word-spacing = true , indent-width = 0pt , left-skip = 0pt plus 1fil , right-skip = 0pt plus 1fil } % \end{macrocode} % % \begin{macro}{\@@_justification_first:, \@@_justification_other:} % A second form of justification template is the case where the first % paragraph is different from all of the others. This is set up by % getting the justification to reset itself after the first paragraph. % The code built into the \texttt{std} version will ensure that any % subsequent template use will over-ride the setting here correctly. % \begin{macrocode} \DeclareTemplateInterface { justification } { compound } { 0 } { first-paragraph : instance { justification } , other-paragraphs : instance { justification } } \DeclareTemplateCode { justification } { compound } { 0 } { first-paragraph = \@@_justification_first: , other-paragraphs = \@@_justification_other: } { \@@_justification_first: \tl_set:Nn \l_@@_justification_other_tl { \@@_justification_other: } \tl_gput_right:Nn \g_galley_restore_running_tl { \l_@@_justification_other_tl } } % \end{macrocode} % \end{macro} % % How \TeX{} breaks text into lines is influences by a number of % parameters, most of which are not actually likely to change. These % work with the \texttt{hyphenation} but are independent of whether % any hyphenation is actually active. The math values here could be % set up as a separate template, but in practice this seems likely to % be overkill. % \begin{macrocode} \DeclareObjectType { line-breaking } { 0 } % \end{macrocode} % The only template provided for line breaking is a simple interface to % \TeX{}'s parameters. There is not really much that can be added to this: % after all, the way that penalties work is more or less arbitrary but % works well! The default values given here are intended to be sensible % for a lot of cases. % \begin{macrocode} \DeclareTemplateInterface { line-breaking } { std } { 0 } { badness : integer = 1000 , binop-penalty : integer = 700 , double-hyphen-demerits : integer = 10000 , emergency-stretch : skip = 0pt , final-hyphen-demerits : integer = 5000 , fuzz : length = 0.1pt , line-penalty : integer = 10 , mismatch-demerits : integer = 10000 , pretolerance : integer = 100 , relation-penalty : integer = 500 , tolerance : integer = 200 } \DeclareTemplateCode{ line-breaking } { std } { 0 } { badness = \l_galley_linebreak_badness_int , binop-penalty = \l_@@_binop_penalty_int , double-hyphen-demerits = \l_galley_double_hyphen_demerits_int , emergency-stretch = \l_galley_emergency_stretch_skip , final-hyphen-demerits = \l_galley_final_hyphen_demerits_int , fuzz = \l_galley_linebreak_fuzz_dim , line-penalty = \l_@@_linebreak_penalty_int , mismatch-demerits = \l_galley_mismatch_demerits_int , pretolerance = \l_galley_linebreak_pretolerance_int , relation-penalty = \l_@@_relation_penalty_int , tolerance = \l_galley_linebreak_tolerance_int } { } % \end{macrocode} % The default values are set such that they are suitable for good % quality typesetting. So the standard template changes nothing at % all from the template. This instance should also be applied now, % as it will then apply to the entire document unless changed % deliberately. % \begin{macrocode} \DeclareInstance { line-breaking } { std } { std } { } \UseInstance { line-breaking } { std } % \end{macrocode} % % \subsection{Between paragraphs} % % \begin{variable} % { % \l_@@_club_penalty_int , % \l_@@_display_club_penalty_int , % \l_@@_display_widow_penalty_int , % \l_@@_interline_penalty_int , % \l_@@_widow_penalty_int % } % The second object here sets up how \TeX{} acts to break paragraphs at % page boundaries. As with the \texttt{line-breaking} object, there is not % much to do except provide an interface to the \TeX{} internals. The % \texttt{std} template does \emph{not} make the \eTeX{} array nature of % various penalties available. % \begin{macrocode} \DeclareObjectType { paragraph-breaking } { 0 } \DeclareTemplateInterface { paragraph-breaking } { std } { 0 } { badness : integer = 1000 , broken-penalty : integer = 100 , club-penalty : integer = 150 , display-club-penalty : integer = 150 , display-widow-penalty : integer = 150 , fuzz : length = 0.1pt , interline-penalty : integer = 0 , post-display-penalty : integer = 0 , pre-display-penalty : integer = 10000 , widow-penalty : integer = 150 } \DeclareTemplateCode { paragraph-breaking } { std } { 0 } { badness = \l_galley_parbreak_badness_int , broken-penalty = \l_@@_broken_penalty_int , club-penalty = \l_@@_club_penalty_int , display-club-penalty = \l_@@_display_club_penalty_int , display-widow-penalty = \l_@@_display_widow_penalty_int , fuzz = \l_galley_parbreak_fuzz_dim , interline-penalty = \l_@@_interline_penalty_int , post-display-penalty = \l_@@_post_display_penalty_int , pre-display-penalty = \l_@@_pre_display_penalty_int , widow-penalty = \l_@@_widow_penalty_int } { \galley_club_penalties_set:V \l_@@_club_penalty_int \galley_display_club_penalties_set:V \l_@@_display_club_penalty_int \galley_display_widow_penalties_set:V \l_@@_display_widow_penalty_int \galley_interline_penalty_set:n \l_@@_interline_penalty_int \galley_widow_penalties_set:V \l_@@_widow_penalty_int } % \end{macrocode} % \end{variable} % The standard instance of the \texttt{paragraph-breaking} object simply % applies the defaults: this is used. % \begin{macrocode} \DeclareInstance { paragraph-breaking } { std } { std } { } \UseInstance { paragraph-breaking } { std } % \end{macrocode} % Two additional instances are provided: one to prevent any breaks % at all, and a second to prevent any widow or club lines. % \begin{macrocode} \DeclareInstance { paragraph-breaking } { nobreak } { std } { interline-penalty = 10 000 , post-display-penalty = 10 000 } \DeclareInstance { paragraph-breaking } { nolone } { std } { club-penalty = 10 000 , display-club-penalty = 10 000 , display-widow-penalty = 10 000 , widow-penalty = 10 000 } % \end{macrocode} % \begin{variable} % { % \l_@@_parbreak_badness_tl , % \l_@@_broken_penalty_tl , % \l_@@_club_penalties_tl , % \l_@@_display_club_penalties_tl , % \l_@@_display_widow_penalties_tl , % \l_@@_parbreak_fuzz_tl , % \l_@@_interline_penalty_tl , % \l_@@_post_display_penalty_tl , % \l_@@_pre_display_penalty_tl , % \l_@@_widow_penalties_tl , % \c_@@_parbreak_multi_seq , % \c_@@_parbreak_single_seq % } % There is also a version of this code which applies only to one % paragraph. This is done by storing the input in token list variables % with no default: only explicit settings will be picked up. % \begin{macrocode} \DeclareTemplateInterface { paragraph-breaking } { single } { 0 } { badness : tokenlist , broken-penalty : tokenlist , club-penalty : tokenlist , display-club-penalty : tokenlist , display-widow-penalty : tokenlist , fuzz : tokenlist , interline-penalty : tokenlist , post-display-penalty : tokenlist , pre-display-penalty : tokenlist , widow-penalty : tokenlist } \DeclareTemplateCode { paragraph-breaking } { single } { 0 } { badness = \l_@@_parbreak_badness_tl , broken-penalty = \l_@@_broken_penalty_tl , club-penalty = \l_@@_club_penalties_tl , display-club-penalty = \l_@@_display_club_penalties_tl , display-widow-penalty = \l_@@_display_widow_penalties_tl , fuzz = \l_@@_parbreak_fuzz_tl , interline-penalty = \l_@@_interline_penalty_tl , post-display-penalty = \l_@@_post_display_penalty_tl , pre-display-penalty = \l_@@_pre_display_penalty_tl , widow-penalty = \l_@@_widow_penalties_tl } { % \end{macrocode} % The fuzz and interline penalties are handled explicitly as they have % particular requirements. % \begin{macrocode} \tl_if_empty:NF \l_@@_interline_penalty_tl { \tl_gput_right:Ne \g_galley_par_reset_hook_tl { \int_set:Nn \exp_not:N \l_@@_interline_penalty_int { \galley_interline_penalty: } } \int_set:Nn \l_@@_interline_penalty_int { \l_@@_interline_penalty_tl } } \tl_if_empty:NF \l_@@_parbreak_fuzz_tl { \tl_gput_right:Ne \g_galley_par_reset_hook_tl { \dim_set:Nn \exp_not:N \l_galley_parbreak_fuzz_dim { \dim_use:N \l_galley_parbreak_fuzz_dim } } \dim_set:Nn \l_galley_parbreak_fuzz_dim { \l_@@_parbreak_fuzz_tl } } % \end{macrocode} % For the single integer penalties, a simple check is needed to save the % value. % \begin{macrocode} \seq_map_inline:Nn \c_@@_parbreak_single_seq { \tl_if_empty:cF { l_galley_ ##1 _tl } { \tl_gput_right:Ne \g_galley_par_reset_hook_tl { \int_set:Nn \exp_not:c { l_galley_ ##1 _int } { \int_use:c { l_galley_ ##1 _int } } } \int_set:cn { l_galley_ ##1 _int } { \tl_use:c { l_galley_ ##1 _tl } } } } % \end{macrocode} % A bit more complex for the array penalties. Although the interface here % does not expose the arrays, it is necessary to correctly save them. % We suspend debugging to allow an assignment to a constant. % \begin{macrocode} \seq_map_inline:Nn \c_@@_parbreak_multi_seq { \tl_if_empty:cF { l_galley_ ##1 _tl } { \use:c { galley_save_ ##1 :N } \l_@@_tmpa_clist \tl_gput_right:Ne \g_galley_par_reset_hook_tl { \exp_not:c { galley_set_ ##1 :n } { \exp_not:o \l_@@_tmpa_clist } } \use:c { galley_set_ ##1 :v } { l_galley_ ##1 _tl } } } } \seq_const_from_clist:Nn \c_@@_parbreak_multi_seq { club_penalties , display_club_penalties , display_widow_penalties , widow_penalties , } \seq_const_from_clist:Nn \c_@@_parbreak_single_seq { parbreak_badness , broken_penalty , post_display_penalty , pre_display_penalty , } % \end{macrocode} % \end{variable} % \begin{macrocode} \DeclareInstance { paragraph-breaking } { single-std } { single } { } \DeclareInstance { paragraph-breaking } { single-nobreak } { single } { interline-penalty = 10 000 , post-display-penalty = 10 000 } \DeclareInstance { paragraph-breaking } { single-noclub } { single } { club-penalty = 10 000 , display-club-penalty = 10 000 } \DeclareInstance { paragraph-breaking } { single-nolone } { single } { club-penalty = 10 000 , display-club-penalty = 10 000 , display-widow-penalty = 10 000 , widow-penalty = 10 000 } \DeclareInstance { paragraph-breaking } { single-nowidow } { single } { display-widow-penalty = 10 000 , widow-penalty = 10 000 } % \end{macrocode} % % \subsection{Templates for display material} % % To allow special handling of display-like material, templates are % needed at the beginning and end of the block which set up any special % space or breaks. These need to be optional, and so are stored as token % lists: rather than \enquote{magic} values, empty lists indicate that % standard settings are to be used. To ensure that the error checking % needed takes place early, each token list is re-set with the % appropriate evaluation. % \begin{macrocode} \DeclareObjectType { display-begin } { 0 } \DeclareObjectType { display-end } { 0 } \DeclareTemplateInterface { display-begin } { std } { 0 } { par-penalty : tokenlist , par-space : tokenlist , penalty : tokenlist , space : tokenlist } \DeclareTemplateInterface { display-end } { std } { 0 } { par-penalty : tokenlist , par-space : tokenlist , penalty : tokenlist , space : tokenlist } \DeclareTemplateCode { display-begin } { std } { 0 } { par-penalty = \l_galley_display_begin_par_vpenalty_tl , par-space = \l_galley_display_begin_par_vspace_tl , penalty = \l_galley_display_begin_vpenalty_tl , space = \l_galley_display_begin_vspace_tl } { \tl_if_empty:NF \l_galley_display_begin_par_vpenalty_tl { \tl_set:Ne \l_galley_display_begin_par_vpenalty_tl { \int_eval:n { \l_galley_display_begin_par_vpenalty_tl } } } \tl_if_empty:NF \l_galley_display_begin_par_vspace_tl { \tl_set:Ne \l_galley_display_begin_par_vspace_tl { \skip_eval:n { \l_galley_display_begin_par_vspace_tl } } } \tl_if_empty:NF \l_galley_display_begin_vpenalty_tl { \tl_set:Ne \l_galley_display_begin_vpenalty_tl { \int_eval:n { \l_galley_display_begin_vpenalty_tl } } } \tl_if_empty:NF \l_galley_display_begin_vspace_tl { \tl_set:Ne \l_galley_display_begin_vspace_tl { \skip_eval:n { \l_galley_display_begin_vspace_tl } } } } \DeclareTemplateCode { display-end } { std } { 0 } { par-penalty = \l_galley_display_end_par_vpenalty_tl , par-space = \l_galley_display_end_par_vspace_tl , penalty = \l_galley_display_end_vpenalty_tl , space = \l_galley_display_end_vspace_tl } { \tl_if_empty:NF \l_galley_display_end_par_vpenalty_tl { \tl_set:Ne \l_galley_display_end_par_vpenalty_tl { \int_eval:n { \l_galley_display_end_par_vpenalty_tl } } } \tl_if_empty:NF \l_galley_display_end_par_vspace_tl { \tl_set:Ne \l_galley_display_end_par_vspace_tl { \skip_eval:n { \l_galley_display_end_par_vspace_tl } } } \tl_if_empty:NF \l_galley_display_end_vpenalty_tl { \tl_set:Ne \l_galley_display_end_vpenalty_tl { \int_eval:n { \l_galley_display_end_vpenalty_tl } } } \tl_if_empty:NF \l_galley_display_end_vspace_tl { \tl_set:Ne \l_galley_display_end_vspace_tl { \skip_eval:n { \l_galley_display_end_vspace_tl } } } } % \end{macrocode} % % \begin{macrocode} % % \end{macrocode} % % \end{implementation} % % \PrintIndex