summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/l3experimental/xgalley.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'macros/latex/contrib/l3experimental/xgalley.dtx')
-rw-r--r--macros/latex/contrib/l3experimental/xgalley.dtx1559
1 files changed, 1559 insertions, 0 deletions
diff --git a/macros/latex/contrib/l3experimental/xgalley.dtx b/macros/latex/contrib/l3experimental/xgalley.dtx
new file mode 100644
index 0000000000..5544223ad7
--- /dev/null
+++ b/macros/latex/contrib/l3experimental/xgalley.dtx
@@ -0,0 +1,1559 @@
+% \iffalse
+%
+%% File: xgalley.dtx
+%
+% Copyright (C) 1999-2001,2004-2009 Frank Mittelbach
+% (C) 2010-2012,2014,2016-2019 The LaTeX3 Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% 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|package>
+\RequirePackage{xparse}
+%</driver|package>
+%<*driver>
+\documentclass[full]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \textsf{xgalley} package\\ Galley^^A
+% }
+%
+% \author{^^A
+% The \LaTeX3 Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released 2019-08-25}
+%
+% \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 A 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 A 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}{2019-08-25}{}
+ {L3 Experimental galley}
+\RequirePackage{xparse,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>
+%<*package>
+\cs_new_eq:NN \l_@@_right_margin_dim \rightmargin
+%</package>
+\DeclareTemplateCode { measure } { absolute } { 0 }
+ {
+ left-margin = \l_@@_left_margin_dim ,
+ right-margin = \l_@@_right_margin_dim
+ }
+ {
+ \AssignTemplateKeys
+ \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
+ }
+ {
+ \AssignTemplateKeys
+ \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
+ }
+ {
+ \AssignTemplateKeys
+ \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
+ }
+ {
+ \AssignTemplateKeys
+ \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 }
+ } ,
+ }
+ }
+ {
+ \AssignTemplateKeys
+ \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
+ }
+ {
+ \AssignTemplateKeys
+ \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:Nx \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:
+ }
+ {
+ \AssignTemplateKeys
+ \@@_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
+ }
+ { \AssignTemplateKeys }
+% \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
+ }
+ {
+ \AssignTemplateKeys
+ \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
+ }
+ {
+ \AssignTemplateKeys
+% \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:Nx \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:Nx \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:Nx \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:Nx \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
+ }
+ {
+ \AssignTemplateKeys
+ \tl_if_empty:NF \l_galley_display_begin_par_vpenalty_tl
+ {
+ \tl_set:Nx \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:Nx \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:Nx \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:Nx \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
+ }
+ {
+ \AssignTemplateKeys
+ \tl_if_empty:NF \l_galley_display_end_par_vpenalty_tl
+ {
+ \tl_set:Nx \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:Nx \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:Nx \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:Nx \l_galley_display_end_vspace_tl
+ { \skip_eval:n { \l_galley_display_end_vspace_tl } }
+ }
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex