summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/l3experimental/xgalley
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2011-10-10 21:53:20 +0000
committerKarl Berry <karl@freefriends.org>2011-10-10 21:53:20 +0000
commit8fdc0d5c9ee743261c162302bdafbb83f9cfb542 (patch)
tree05e2062f23f57880ed2e0a26ad898e81b9d813be /Master/texmf-dist/source/latex/l3experimental/xgalley
parentd2d088ff389655c2c3aad324760138895af2a9d3 (diff)
l3experimental 2900 (10oct11)
git-svn-id: svn://tug.org/texlive/trunk@24258 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex/l3experimental/xgalley')
-rw-r--r--Master/texmf-dist/source/latex/l3experimental/xgalley/l3galley.dtx2140
-rw-r--r--Master/texmf-dist/source/latex/l3experimental/xgalley/xgalley.dtx1602
-rw-r--r--Master/texmf-dist/source/latex/l3experimental/xgalley/xgalley.ins41
3 files changed, 3783 insertions, 0 deletions
diff --git a/Master/texmf-dist/source/latex/l3experimental/xgalley/l3galley.dtx b/Master/texmf-dist/source/latex/l3experimental/xgalley/l3galley.dtx
new file mode 100644
index 00000000000..fa54ac37e59
--- /dev/null
+++ b/Master/texmf-dist/source/latex/l3experimental/xgalley/l3galley.dtx
@@ -0,0 +1,2140 @@
+% \iffalse
+%
+%% File: l3galley.dtx Copyright (C) 1999-2001, 2004-2009 Frank Mittelbach
+%% (C) 2010,2011 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
+%%
+%% http://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 released version of this bundle is available from CTAN.
+%%
+%% -----------------------------------------------------------------------
+%%
+%% The development version of the bundle can be found at
+%%
+%% http://www.latex-project.org/svnroot/experimental/trunk/
+%%
+%% for those people who are interested.
+%%
+%%%%%%%%%%%
+%% NOTE: %%
+%%%%%%%%%%%
+%%
+%% Snapshots taken from the repository represent work in progress and may
+%% not work or may contain conflicting material! We therefore ask
+%% people _not_ to put them into distributions, archives, etc. without
+%% prior consultation with the LaTeX Project Team.
+%%
+%% -----------------------------------------------------------------------
+%%
+%
+%<*driver|package>
+\RequirePackage{l3names}
+\GetIdInfo$Id: l3galley.dtx 2899 2011-10-09 21:22:06Z joseph $
+ {L3 Experimental galley code}
+%</driver|package>
+%<*driver>
+\documentclass[full]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \textsf{l3galley} package\\ Galley code^^A
+% \thanks{This file describes v\ExplFileVersion,
+% last revised \ExplFileDate.}^^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 \ExplFileDate}
+%
+% \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}}). This
+% layer is somewhat distinct from the galley as such, but is handled in
+% the same place as there is, internally, interaction between the different
+% layers.
+%
+% \section{Code interfaces}
+%
+% \subsection{Galley layers}
+%
+% \begin{variable}{\l_galley_width_dim}
+% The total width of a galley, set either by the page geometry code
+% for the main vertical galley or when creating an independent galley,
+% such as a minipage.
+% \end{variable}
+%
+% \begin{function}{\galley_level:}
+% \begin{syntax}
+% \cs{galley_level:}
+% \end{syntax}
+% Sets up a vertical box to contain a new galley level. The box should
+% be \enquote{colour safe}, which is automatic for \LaTeX3 coffins but
+% must be included manually (using \cs{color_group_begin:} and
+% \cs{color_group_end:}) in \enquote{raw} vertical boxes.
+% \end{function}
+%
+% \subsection{Measure}
+%
+% \begin{function}
+% {\galley_margins_set_absolute:nn, \galley_margins_set_relative:nn}
+% \begin{syntax}
+% \cs{galley_margins_set_absolute:nn} \Arg{left margin} \Arg{right margin}
+% \cs{galley_margins_set_relative:nn} \Arg{left margin} \Arg{right margin}
+% \end{syntax}
+% Sets the width of the measure to have the \meta{left margin} and
+% \meta{right margin} specified by the arguments, both of which are
+% \meta{dimension expressions}. The \texttt{relative} function will adjust
+% the text width within any existing margins, whereas the \texttt{absolute}
+% measure sets the margins based on the edges of the galley only. One or
+% both of the \meta{margins} may be negative, to specify and outdent.
+% \end{function}
+%
+% \subsection{Between paragraphs}
+%
+% \begin{variable}{\g_galley_restore_running_tl}
+% When galley settings need to be reset at the end of a paragraph, the
+% appropriate detail should be added to this token list. It is inserted
+% immediately before the start of each paragraph, and can therefore be
+% used to clear otherwise global settings. The token list itself is
+% also cleared as part of this process.
+% \end{variable}
+%
+% \begin{variable}{\g_galley_no_break_next_bool}
+% Indicates that no page break should be allowed between the current
+% paragraph and the next paragraph.
+% \end{variable}
+%
+% \begin{function}{\g_galley_omit_next_indent_bool}
+% Indicates that the indent should be omitted from the start of the next
+% paragraph started.
+% \end{function}
+%
+% \begin{variable}{\l_galley_interpar_penalty_int}
+% The \meta{penalty} for a break between paragraphs. The \meta{penalty}
+% should be in the range $-10\,000$ to $10\,000$, where $-10\,000$ forces a
+% page break, $0$ has no effect at all and $10\,000$ forbids a page break.
+% Note that setting \cs{g_galley_no_break_next_bool} to \texttt{true}
+% will override any setting of \cs{l_galley_interpar_penalty_int}.
+% \end{variable}
+%
+% \begin{variable}{\l_galley_interpar_vspace_skip}
+% Stretchable space to be inserted between paragraphs, set at the design
+% or template level.
+% \end{variable}
+%
+% \begin{function}{\galley_set_user_penalty:n}
+% \begin{syntax}
+% \cs{galley_set_user_penalty:n} \Arg{penalty}
+% \end{syntax}
+% Sets the \meta{penalty} for a break between the current and next
+% paragraph on a one-off basis. This function is intended for user-level
+% adjustments to design, and takes precedent over both settings from
+% \cs{galley_set_penalty:n} and from \cs{galley_no_break_next:}.
+% \end{function}
+%
+% \begin{function}{\galley_set_user_vspace:n}
+% \begin{syntax}
+% \cs{galley_set_user_vspace:n} \Arg{space}
+% \end{syntax}
+% Sets the \meta{space} f to be inserted between the current and next
+% paragraph on a one-off basis. This function is intended for user-level
+% adjustments to design, and otherwise is analogous to
+% \cs{galley_set_vspace:n}.
+% \end{function}
+%
+% \subsection{Paragraph shape}
+%
+% \begin{function}
+% {
+% \galley_parshape_multi_par:nnnN,
+% \galley_parshape_multi_par:nVVN,
+% \galley_parshape_single_par:nnnN,
+% \galley_parshape_single_par:nVVN
+% }
+% \begin{syntax}
+% \cs{galley_parshape_multi_par:nnnN} \Arg{unaltered lines} \Arg{left indents} \Arg{right indents} \meta{resume flag}
+% \cs{galley_parshape_single_par:nnnN} \Arg{unaltered lines} \Arg{left indents} \Arg{right indents} \meta{resume flag}
+% \end{syntax}
+% Sets the current paragraph shape to create an arbitrary paragraph shape.
+% The paragraph shape is set such that there are \meta{unaltered lines} which
+% have width and indent as set by the measure. The \enquote{altered} lines
+% are then defined by the comma-separated lists of \meta{left indents} and
+% \meta{right indents}. These are both indents from the edge of the measure,
+% and may be negative, and should both contain the same number of items.
+% If the \meta{resume flag} is \texttt{true}, after the last
+% altered line the paragraph shape returns to that of the measure. On the
+% other hand, if the flag is \texttt{false} then the shape of the last line
+% is retained for the rest of the paragraph.
+% For example,
+% \begin{verbatim}
+% \galley_parshape_set_multi_par:nnnN { 1 }
+% { 2 pt , 4 pt , 6 pt } { 2 pt , 4 pt , 6 pt } \c_true_bool
+% \end{verbatim}
+% would create a paragraph shape in which the first line is the full
+% width of the measure, the second line is indented by $2$\,pt on each side,
+% the third line by by $4$\,pt and the fourth line and subsequent lines by
+% $6$\,pt from the edge of the measure on each side.
+%
+% The \texttt{single_par} version applies only to a single paragraph,
+% while the \texttt{multi_par} function sets the paragraph shape on an
+% ongoing basis within the scope of the current \TeX{} group.
+% \end{function}
+%
+% \begin{function}
+% {
+% \galley_parshape_fixed_lines:nnn,
+% \galley_parshape_fixed_lines:nVV
+% }
+% \begin{syntax}
+% \cs{galley_parshape_fixed_lines:nnn} \Arg{unaltered lines} \Arg{left indents} \Arg{right indents}
+% \end{syntax}
+% Sets the paragraph shape to create an arbitrary paragraph shape which will
+% apply to an exact number of lines.
+% The paragraph shape is set such that there are \meta{unaltered lines} which
+% have width and indent as set by the measure. The \enquote{altered} lines
+% are then defined by the comma-separated lists of \meta{left indents} and
+% \meta{right indents}. These are both indents from the edge of the measure,
+% and may be negative, and should both contain the same number of items.
+% The altered lines will apply to one or more paragraphs, such that the
+% entire indent specification is honoured before the standard measure
+% resumes.
+% \end{function}
+%
+% \subsection{Formatting inside the paragraph}
+%
+% The settings described here apply \enquote{inside} the paragraph, and so
+% are active irrespective of any paragraph shape within the measure.
+%
+% \begin{variable}{\l_galley_line_left_skip, \l_galley_line_right_skip}
+% Stretchable space added to the appropriate side each line in a paragraph.
+% \end{variable}
+%
+% \begin{variable}{\l_galley_par_begin_skip, \l_galley_par_end_skip}
+% Stretchable space added to the beginning of the first line and end of
+% the last line of a paragraph, respectively.
+% \end{variable}
+%
+% \begin{variable}{\l_galley_par_indent_dim}
+% Fixed space added to the start of each paragraph except for those where
+% \cs{l_galley_omit_next_indent_bool} is \texttt{true}.
+% \end{variable}
+%
+% \begin{variable}{\l_galley_last_line_fit_int}
+% Determines how the inter-word stretch is set for the last line of a
+% paragraph when
+% \begin{enumerate}
+% \item The value of \cs{l_galley_par_end_skip} contains an infinite
+% (\texttt{fil}) component;
+% \item The values of \cs{l_galley_line_left_skip} and
+% \cs{l_galley_line_right_skip} do \emph{not} contain an infinite
+% (\texttt{fil}) component.
+% \end{enumerate}
+% Under these circumstances, \cs{l_galley_last_line_fit_int} is active, and
+% applies as follows:
+% \begin{itemize}
+% \item Set to $0$, the last line of the paragraph is set with
+% the inter-word spacing at natural width;
+% \item Set to a $1000$ (or above), the inter-word spacing in the last line
+% is stretched by the same factor as that applied to the penultimate
+% line;
+% \item Set to $n$ between these extremes, the inter-word spacing in the
+% last line is stretched by $n/1000$ times the factor used for the
+% penultimate line.
+% \end{itemize}
+% \end{variable}
+%
+% \begin{function}{\galley_set_interword_spacing:N}
+% \begin{syntax}
+% \cs{galley_set_interword_spacing:N} \meta{fixed spacing bool}
+% \end{syntax}
+% Sets the inter-word spacing used based on the values supplied by the
+% current font. If the \meta{fixed spacing bool} flag is \texttt{true} then
+% no stretch is permitted between words, otherwise the stretch specified by
+% the font designer is used.
+% \end{function}
+%
+% \subsection{Display material}
+%
+% Material which is set in \enquote{display-style} require additional settings
+% to control the relationship with the surrounding material.
+%
+% \begin{function}{\galley_display_begin:, \galley_display_end:}
+% \begin{syntax}
+% \cs{galley_display_begin:}
+% \ldots
+% \cs{galley_display_end:}
+% \end{syntax}
+% Sets up a group to contain display-style material. Unlike an independent
+% galley level, settings are inherited from the surroundings. However,
+% the interaction of a display block with the paragraphs before and after it
+% can be adjusted independent of the design of text.
+% \end{function}
+%
+% \subsection{Line breaking}
+%
+% \begin{variable}{\l_galley_binop_penalty_int}
+% Penalty charged if an inline math formula is broken at a
+% binary operator.
+% \end{variable}
+%
+% \begin{variable}{\l_galley_double_hyphen_demerits_int}
+% Extra demerit charge of two (or more) lines in succession end
+% in a hyphen.
+% \end{variable}
+%
+% \begin{variable}{\l_galley_emergency_stretch_skip}
+% 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.
+% \end{variable}
+%
+% \begin{variable}{\l_galley_final_hyphen_demerits_int}
+% Extra demerit charge if the second last line is hyphenated.
+% \end{variable}
+%
+% \begin{variable}{\l_galley_linebreak_badness_int}
+% Boundary that if exceeded will cause \TeX{} to report an
+% underfull line.
+% \end{variable}
+%
+% \begin{variable}{\l_galley_linebreak_fuzz_dim}
+% Boundary below which overfull lines are not reported.
+% \end{variable}
+%
+% \begin{variable}{\l_galley_linebreak_penalty_int}
+% Extra penalty charged per line in the paragraph. By making
+% this penalty higher \TeX{} will try harder to produce compact
+% paragraphs.
+% \end{variable}
+%
+% \begin{variable}{\l_galley_linebreak_pretolerance_int}
+% Maximum tolerance allowed for individual lines to break the
+% paragraph without attempting hyphenation.
+% \end{variable}
+%
+% \begin{variable}{\l_galley_linebreak_tolerance_int}
+% Maximum tolerance allowed for individual lines when breaking a
+% paragraph while attempting hyphenation (if this limit can't be
+% met \cs{l_galley_emergency_stretch_skip} comes into play).
+% \end{variable}
+%
+% \begin{variable}{\l_galley_mismatch_demerits_int}
+% Extra demerit charge if two visually incompatible lines follow
+% each other.
+% \end{variable}
+%
+% \begin{variable}{\l_galley_relation_penalty_int}
+% Penalty charged if an inline math formula is broken at a
+% relational symbol.
+% \end{variable}
+%
+% \subsection{Paragraph breaking}
+%
+% \begin{variable}{\l_galley_parbreak_badness_int}
+% Boundary that if exceeded will cause \TeX{} to report an
+% underfull vertical box.
+% \end{variable}
+%
+% \begin{variable}{\l_galley_parbreak_fuzz_dim}
+% Boundary below which overfull vertical boxes are not reported.
+% \end{variable}
+%
+% \begin{variable}{\l_galley_broken_penalty_int}
+% Penalty for page breaking after a hyphenated line.
+% \end{variable}
+%
+% \begin{variable}{\l_galley_pre_display_penalty_int}
+% Penalty for breaking between immediately before display math material.
+% \end{variable}
+%
+% \begin{variable}{\l_galley_post_display_penalty_int}
+% Penalty for breaking between immediately after display math material.
+% \end{variable}
+%
+% \begin{function}
+% {
+% \galley_set_club_penalties:n,
+% \galley_set_club_penalties:V,
+% \galley_set_club_penalties:v,
+% \galley_set_display_club_penalties:n,
+% \galley_set_display_club_penalties:V,
+% \galley_set_display_club_penalties:v,
+% \galley_set_display_widow_penalties:n,
+% \galley_set_display_widow_penalties:V,
+% \galley_set_display_widow_penalties:v,
+% \galley_set_widow_penalties:n,
+% \galley_set_widow_penalties:V,
+% \galley_set_widow_penalties:v
+% }
+% \begin{syntax}
+% \cs{galley_set_club_penalties:n} \Arg{penalty list}
+% \end{syntax}
+% Set the penalties for breaking lines at the beginning and end of
+% (partial) paragraphs. In each case, the \meta{penalty list} is a
+% comma-separated list of penalty values. The list applies as follows:
+% \begin{itemize}
+% \item[\texttt{club}] Penalties for breaking after the first, second,
+% third, \emph{etc.}~line of the paragraph.
+% \item[\texttt{display_club}] Penalties for breaking after the first,
+% second, third, \emph{etc.}~line after a display math environment.
+% \item[\texttt{display_club}] Penalties for breaking before the last,
+% penultimate, antepenultimate, \emph{etc.}~line before a display
+% math environment.
+% \item[\texttt{widow}] Penalties for breaking before the last,
+% penultimate, antepenultimate, \emph{etc.}~line of the paragraph.
+% \end{itemize}
+% In all cases, these penalties apply in addition to the general interline
+% penalty or to any \enquote{special} line penalties.
+% \end{function}
+%
+% \begin{function}{\galley_set_interline_penalty:n}
+% \begin{syntax}
+% \cs{galley_set_interline_penalty:n} \Arg{penalty}
+% \end{syntax}
+% Sets the standard interline penalty applied between lines of a paragraph.
+% This value is added to any (display) club or widow penalty in force.
+% \end{function}
+%
+% \begin{function}
+% {
+% \galley_set_interline_penalties:n,
+% \galley_set_interline_penalties:V
+% }
+% \begin{syntax}
+% \cs{galley_set_interline_penalties:n} \Arg{penalty list}
+% \end{syntax}
+% Sets \enquote{special} interline penalties to be used in place of
+% the standard value, specified as a comma-separated \meta{penalty list}.
+% The \meta{penalties} apply to the first, second, third, \emph{etc.}~line
+% of the paragraph.
+% \end{function}
+%
+% \begin{function}
+% {
+% \galley_save_club_penalties:N,
+% \galley_save_display_club_penalties:N,
+% \galley_save_display_widow_penalties:N,
+% \galley_save_interline_penalties:N,
+% \galley_save_widow_penalties:N
+% }
+% \begin{syntax}
+% \cs{galley_save_club_penalties:N} \Arg{comma list}
+% \end{syntax}
+% These functions save the current value of the appropriate to the
+% comma list specified, within the current \TeX{} group.
+% \end{function}
+%
+% \begin{function}[EXP]{\galley_interline_penalty:}
+% \begin{syntax}
+% \cs{galley_interline_penalty:}
+% \end{syntax}
+% Expands to the current interline penalty as a \meta{integer denotation}.
+% \end{function}
+%
+% \section{Hooks and insertion points}
+%
+% \begin{variable}{\g_galley_par_begin_hook_tl}
+% Token list inserted at the beginning of every paragraph in horizontal mode.
+% This is inserted after any paragraph indent but before any other horizontal
+% mode material.
+% \end{variable}
+%
+% \begin{variable}{\g_galley_par_end_hook_tl}
+% Token list inserted at the end of every paragraph in horizontal mode.
+% \end{variable}
+%
+% \begin{variable}{\g_galley_par_after_hook_tl}
+% Token list inserted after each paragraph. This is used for resetting
+% galley parameters, and is therefore cleared after use.
+% \end{variable}
+%
+% \begin{variable}{\g_galley_whatsit_next_tl}
+% Token list for whatsits to be inserted at the very beginning of the next
+% paragraph started.
+% \end{variable}
+%
+% \begin{variable}{\g_galley_whatsit_previous_hook_tl}
+% Token list for whatsits to be inserted at the very end of the last
+% paragraph started.
+% \end{variable}
+%
+% \section{Internal variables}
+%
+% Some of the internal variables for the galley mechanism may be of
+% interest to the programmer. These should all be treated as read-only
+% values and accessed only through the defined interfaces described above.
+%
+% \begin{variable}{\l_galley_total_left_margin_dim}
+% The total margin between the left side of the galley and the left side of
+% the text block. This may be negative if the measure is set to overlap
+% the text beyond the edge of the galley.
+% \end{variable}
+%
+% \begin{variable}{\l_galley_total_right_margin_dim}
+% The total margin between the right side of the galley and the right side
+% of the text block. This may be negative if the measure is set to overlap
+% the text beyond the edge of the galley.
+% \end{variable}
+%
+% \begin{variable}{\l_galley_text_width_dim}
+% The width of a line of text within the galley, taking account of
+% any margins added. This may be larger than \cs{l_galley_width_dim}
+% if the margins are negative.
+% \end{variable}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3galley} Implementation}
+%
+% At the implementation level, there are a number of challenges which
+% have to be overcome in order to make the galley easy to use at the
+% designer and user levels. Inserting material into the main vertical
+% list is in many ways an irreversible operation. Inserting items as
+% they appear in the source is therefore not desirable. Instead,
+% inserting vertical-mode material needs to be delayed until the start
+% of the \enquote{next} paragraph. This is particularly notable for
+% invisible items such as whatsits and specials, which will otherwise
+% cause changes in spacing. Delaying insertion enables user-supplied
+% settings to override design settings in a reliable fashion. This can
+% be achieved as the design-level material can be ignored if a user
+% value is supplied. There is a need to allow proper nesting of
+% galleys, which means that all of the above needs to be set up so that
+% it can be saved and restored. All of these manipulations require
+% altering the meaning of the \cs{par} token, which is particularly
+% awkward as \TeX{} inserts a token \emph{called} \cs{par} rather than
+% one with a particular meaning. This makes moving \cs{par} to somewhere
+% \enquote{safe} extremely challenging.
+%
+% Added to all of this complexity, there is a need to deal with
+% \enquote{display-like} material. The most obvious example is the way
+% lists are handled. These use \cs{par} tokens to achieve the correct
+% appearance, but at the same time
+% \begin{verbatim}
+% Text
+% \begin{itemize}
+% \item An item
+% \end{itemize}
+% More text
+% \end{verbatim}
+% should form one visual paragraph while
+% \begin{verbatim}
+% Text
+% \begin{itemize}
+% \item An item
+% \end{itemize}
+%
+% More text
+% \end{verbatim}
+% should be shown as two paragraphs. This requires an additional level
+% of handling so that the \cs{par} token used to end the list in the
+% first case does not start a new paragraph in a visual sense while the
+% second does.
+%
+% Another factor to bear in mind is that \cs{tex_everypar:D} may be
+% executed inside a group. For example, a paragraph starting
+% \begin{verbatim}
+% {Text} here
+% \end{verbatim}
+% will insert the tokens such that the current group level is $1$
+% higher for \enquote{Text} than for \enquote{here}. The result of this
+% is that it's very important to watch how flags are set and reset. This
+% can only be done reliably on a global level, which then has a knock-on
+% effect on the rest of the implementation.
+%
+% At a \TeX{} level, settings can only apply to the current paragraph,
+% but conceptually there is a need to allow for both single-paragraph
+% and \enquote{running} settings. Whenever the code switches galley
+% level both of these need to be correctly saved.
+%
+% \begin{macrocode}
+%<*initex|package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*package>
+\ProvidesExplPackage
+ {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
+\package_check_loaded_expl:
+%</package>
+% \end{macrocode}
+%
+% \subsection{Support items}
+%
+% Functions or settings which are needed by the galley but perhaps also
+% elsewhere.
+%
+% \begin{macro}{\galley_leave_vmode:}
+% The standard mode to leave vertical mode, starting a paragraph.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \galley_leave_vmode:
+ { \tex_unhbox:D \c_empty_box }
+% \end{macrocode}
+% \end{macro}
+%
+% The default hyphenation character should be set and hyphenation should be
+% enabled.
+% \begin{macrocode}
+%<*initex>
+\tex_defaulthyphenchar:D 45 \scan_stop:
+%</initex>
+% \end{macrocode}
+%
+% \subsection{Galley settings}
+%
+% Settings for application by the galley respect the usual \TeX{} grouping and
+% so are all local variables.
+%
+% \begin{variable}
+% {
+% \l_galley_parshape_left_indent_clist,
+% \l_galley_parshape_right_indent_clist
+% }
+% \begin{variable}
+% {
+% \l_galley_parshape_multipar_bool,
+% \l_galley_parshape_resume_std_bool,
+% \l_galley_parshape_fixed_lines_bool
+% }
+% Setting up paragraph shape interacts with setting up the measure. The only
+% way to keep things flexible is to have a rather \enquote{rich} set of data
+% available.
+% \begin{macrocode}
+\clist_new:N \l_galley_parshape_left_indent_clist
+\clist_new:N \l_galley_parshape_right_indent_clist
+\bool_new:N \l_galley_parshape_multipar_bool
+\bool_new:N \l_galley_parshape_resume_std_bool
+\bool_new:N \l_galley_parshape_fixed_lines_bool
+\int_new:N \l_galley_parshape_std_lines_int
+% \end{macrocode}
+% \end{variable}
+% \end{variable}
+%
+% \begin{variable}{\l_galley_text_width_dim}
+% The width of the current measure: the \enquote{running} setting can be
+% inherited from \LaTeXe{}.
+% \begin{macrocode}
+%<*initex>
+\dim_new:N \l_galley_text_width_dim
+%</initex>
+%<*package>
+\cs_new_eq:NN \l_galley_text_width_dim \linewidth
+%</package>
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}
+% {\l_galley_total_left_margin_dim, \l_galley_total_right_margin_dim}
+% Margins of the current text within the galley: these plus the galley
+% width are one way to define the measure width. See also the text width,
+% which is an alternative view (and should be in sync with this one!).
+% \begin{macrocode}
+%<*initex>
+\dim_new:N \l_galley_total_left_margin_dim
+%</initex>
+%<*package>
+\cs_new_eq:NN \l_galley_total_left_margin_dim \@totalleftmargin
+%</package>
+\dim_new:N \l_galley_total_right_margin_dim
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}
+% {\l_galley_interpar_penalty_skip, \l_galley_interpar_vspace_skip}
+% Items between paragraphs at the design level.
+% \begin{macrocode}
+\int_new:N \l_galley_interpar_penalty_int
+\skip_new:N \l_galley_interpar_vspace_skip
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_galley_width_dim}
+% The external size of a galley is the stored in the \TeX{} primitive
+% \cs{tex_hsize:D}, which is renamed. This will only ever be reset by
+% the code constructing a new galley, for example the start of a
+% minipage. This value will be set for the main galley by the page
+% layout system.
+% \begin{macrocode}
+\cs_new_eq:NN \l_galley_width_dim \tex_hsize:D
+% \end{macrocode}
+% \end{variable}
+%
+% \subsection{Galley data structures}
+%
+% In contrast to settings, the data structures used by the galley are all set
+% globally. To allow different galley levels to exist, a local variant is
+% defined for each one to save the value when starting a new level.
+%
+% \begin{variable}{\g_galley_begin_level_bool, \l_galley_begin_level_bool}
+% Indicates that the galley is at the very beginning of the level, and that
+% no material has yet been set. As a result, the global version is set
+% \texttt{true} to begin with.
+% \begin{macrocode}
+\bool_new:N \g_galley_begin_level_bool
+\bool_new:N \l_galley_begin_level_bool
+\bool_gset_true:N \g_galley_begin_level_bool
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\g_galley_omit_next_indent_bool, \l_galley_omit_next_indent_bool}
+% A global flag is needed for suppressing indentation of the next
+% paragraph. This does not need a \enquote{running} version since that
+% should be handled using the \texttt{justification} object: the two
+% concepts are related but not identical. The flag here is needed in
+% cases such as the very first paragraph in a galley or immediately
+% following a heading.
+% \begin{macrocode}
+\bool_new:N \g_galley_omit_next_indent_bool
+\bool_new:N \l_galley_omit_next_indent_bool
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\g_galley_parshape_set_bool, \l_galley_parshape_set_bool}
+% This is not a setting for paragraph shape, but rather a tracker for the
+% galley system.
+% \begin{macrocode}
+\bool_new:N \g_galley_parshape_set_bool
+\bool_new:N \l_galley_parshape_set_bool
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\g_galley_nobreak_next_bool, \l_galley_nobreak_next_bool}
+% Dealing with the no-break flag is pretty much the same as the case
+% for the indent: this applies on a single paragraph basis.
+% \begin{macrocode}
+\bool_new:N \g_galley_nobreak_next_bool
+\bool_new:N \l_galley_nobreak_next_bool
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}
+% {
+% \g_galley_par_begin_hook_tl, \l_galley_par_begin_hook_tl,
+% \g_galley_par_end_hook_tl, \l_galley_par_end_hook_tl,
+% }
+% Hooks for user-level code: these are not used by the galley itself.
+% \begin{macrocode}
+\tl_new:N \g_galley_par_begin_hook_tl
+\tl_new:N \l_galley_par_begin_hook_tl
+\tl_new:N \g_galley_par_end_hook_tl
+\tl_new:N \l_galley_par_end_hook_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}
+% {\g_galley_par_after_hook_tl, \l_galley_par_after_hook_tl}
+% This one is used by the galley: it happens \enquote{after} the current
+% paragraph, and is used for reset purposes.
+% \begin{macrocode}
+\tl_new:N \g_galley_par_after_hook_tl
+\tl_new:N \l_galley_par_after_hook_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}
+% {\g_galley_previous_par_lines_int, \l_galley_previous_par_lines_int}
+% The number of lines in the previous typeset paragraph. This is reset at
+% the start of the paragraph and \emph{added to} when each \cs{tex_par:D}
+% primitive is used: \LaTeX{} uses the primitive in places that do not end
+% a (conceptual) paragraph.
+% \begin{macrocode}
+\int_new:N \g_galley_previous_par_lines_int
+\int_new:N \l_galley_previous_par_lines_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\g_galley_restore_running_tl, \l_galley_restore_running_tl}
+% When a parameter is altered from the \enquote{running} value to a
+% different \enquote{current} one, there needs to be a method to restore
+% the \enquote{running} value. This is done by adding the necessary
+% assignment to a token list, which can be executed when needed. At the
+% same time, this information is itself part of the galley parameter
+% structure, and so there has to be a local save version.
+% \begin{macrocode}
+\tl_new:N \g_galley_restore_running_tl
+\tl_new:N \l_galley_restore_running_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}
+% {
+% \g_galley_whatsit_next_tl, \l_galley_whatsit_next_tl,
+% \g_galley_whatsit_previous_tl, \l_galley_whatsit_previous_tl
+% }
+% Whatsits only apply on a per-paragraph basis and so there is no need
+% to differentiate between current and running values. However, there
+% is a need to differentiate between whatsits that attach to the
+% previous (completed) paragraph and those that attach to the next
+% paragraph.
+% \begin{macrocode}
+\tl_new:N \g_galley_whatsit_next_tl
+\tl_new:N \l_galley_whatsit_next_tl
+\tl_new:N \g_galley_whatsit_previous_tl
+\tl_new:N \l_galley_whatsit_previous_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}
+% {\g_galley_interpar_penalty_user_tl, \l_galley_interpar_penalty_user_tl}
+% The user may want to over-ride the penalty for a break between
+% paragraphs, for example to prevent a break when the overall design
+% allows one. This is handled using an additional penalty.
+% \begin{macrocode}
+\tl_new:N \g_galley_interpar_penalty_user_tl
+\tl_new:N \l_galley_interpar_penalty_user_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}
+% {\g_galley_interpar_vspace_user_tl, \l_galley_interpar_vspace_user_tl}
+% Arbitrary vertical space can be inserted by the user on a one-off
+% basis. This is used in place of any running space between paragraphs.
+% \begin{macrocode}
+\tl_new:N \g_galley_interpar_vspace_user_tl
+\tl_new:N \l_galley_interpar_vspace_user_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \subsection{Independent galley levels}
+%
+% As well as the main vertical list, independent galleys are required
+% for items such as minipages and marginal notes. Each of these galleys
+% requires an independent set of global data structures. This is
+% achieved by storing the data structures in \emph{local} variables. The
+% later are only used to save and restore the global value, and so \TeX{}
+% grouping will manage the values correctly. This implies that each
+% galley level must form a group: galley levels are tided to vertical
+% boxes and so this is a reasonable requirements.
+%
+% \begin{macro}{\galley_initialise_variables:}
+% At the start of a galley level, both the global and local variables
+% will need to be reset to standard values. For example, the measure
+% is set to the galley width and any paragraph shape is cleared.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \galley_initialise_variables:
+ {
+ \bool_gset_true:N \g_galley_begin_level_bool
+ \tl_gclear:N \g_galley_interpar_penalty_user_tl
+ \tl_gclear:N \g_galley_interpar_vspace_user_tl
+ \bool_gset_true:N \g_galley_omit_next_indent_bool
+ \bool_gset_false:N \g_galley_nobreak_next_bool
+ \tl_gclear:N \g_galley_par_begin_hook_tl
+ \tl_gclear:N \g_galley_par_end_hook_tl
+ \tl_gclear:N \g_galley_par_after_hook_tl
+ \bool_gset_false:N \g_galley_parshape_set_bool
+ \int_gzero:N \g_galley_previous_par_lines_int
+ \tl_gclear:N \g_galley_restore_running_tl
+ \tl_gclear:N \g_galley_whatsits_previous_tl
+ \tl_gclear:N \g_galley_whatsits_next_tl
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\galley_initialise_settings:}
+% This sets the local values of the various galley settings.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \galley_initialise_settings:
+ {
+ \dim_set_eq:NN \l_galley_text_width_dim \l_galley_width_dim
+ \dim_zero:N \l_galley_left_margin_dim
+ \dim_zero:N \l_galley_right_margin_dim
+ \dim_zero:N \l_galley_total_left_margin_dim
+ \dim_zero:N \l_galley_total_right_margin_dim
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\galley_save_parameters:, \galley_restore_parameters:}
+% Saving and restoring parameters is carried out by a series of copy
+% functions.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \galley_save_parameters:
+ {
+ \bool_set_eq:NN \l_galley_begin_level_bool
+ \g_galley_begin_level_bool
+ \tl_set_eq:NN \l_galley_interpar_penalty_user_tl
+ \g_galley_interpar_penalty_user_tl
+ \tl_set_eq:NN \l_galley_interpar_vspace_user_tl
+ \g_galley_interpar_vspace_user_tl
+ \bool_set_eq:NN \l_galley_omit_next_indent_bool
+ \g_galley_omit_next_indent_bool
+ \bool_set_eq:NN \l_galley_nobreak_next_bool
+ \g_galley_nobreak_next_bool
+ \tl_set_eq:NN \l_galley_par_begin_hook_tl
+ \g_galley_par_begin_hook_tl
+ \tl_set_eq:NN \l_galley_par_end_hook_tl
+ \g_galley_par_end_hook_tl
+ \tl_set_eq:NN \l_galley_par_after_hook_tl
+ \g_galley_par_after_hook_tl
+ \bool_set_eq:NN \l_galley_parshape_set_bool
+ \g_galley_parshape_set_bool
+ \int_set_eq:NN \l_galley_previous_par_lines_int
+ \g_galley_previous_par_lines_int
+ \tl_set_eq:NN \l_galley_restore_running_tl
+ \g_galley_restore_running_tl
+ \tl_set_eq:NN \l_galley_whatsits_previous_tl
+ \g_galley_whatsits_previous_tl
+ \tl_set_eq:NN \l_galley_whatsits_next_tl
+ \g_galley_whatsits_next_tl
+ }
+\cs_new_protected_nopar:Npn \galley_restore_parameters:
+ {
+ \bool_gset_eq:NN \g_galley_begin_level_bool
+ \l_galley_begin_level_bool
+ \tl_gset_eq:NN \g_galley_interpar_penalty_user_tl
+ \l_galley_interpar_penalty_user_tl
+ \tl_gset_eq:NN \g_galley_interpar_vspace_user_tl
+ \l_galley_interpar_vspace_user_tl
+ \bool_gset_eq:NN \g_galley_omit_next_indent_bool
+ \l_galley_omit_next_indent_bool
+ \bool_gset_eq:NN \g_galley_nobreak_next_bool
+ \l_galley_nobreak_next_bool
+ \tl_gset_eq:NN \g_galley_par_begin_hook_tl
+ \l_galley_par_begin_hook_tl
+ \tl_gset_eq:NN \g_galley_par_end_hook_tl
+ \l_galley_par_end_hook_tl
+ \tl_gset_eq:NN \g_galley_par_after_hook_tl
+ \l_galley_par_after_hook_tl
+ \bool_gset_eq:NN \g_galley_parshape_set_bool
+ \l_galley_parshape_set_bool
+ \int_gset_eq:NN \g_galley_previous_par_lines_int
+ \l_galley_previous_par_lines_int
+ \tl_gset_eq:NN \g_galley_restore_running_tl
+ \l_galley_restore_running_tl
+ \tl_gset_eq:NN \g_galley_whatsits_previous_tl
+ \l_galley_whatsits_previous_tl
+ \tl_gset_eq:NN \g_galley_whatsits_next_tl
+ \l_galley_whatsits_next_tl
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\galley_level:}
+% \begin{macro}[aux]{\galley_level_end:}
+% Galley levels are created by saving all of the current global
+% settings, starting a group then initialising both the local and global
+% variables.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \galley_level:
+ {
+ \galley_save_parameters:
+ \group_begin:
+ \galley_initialise_variables:
+ \galley_initialise_settings:
+ \group_insert_after:N \galley_level_end:
+ }
+% \end{macrocode}
+% At the end of the level, the global values are restored using the
+% saved \emph{local} versions, hence the position of the close-of-group
+% instruction. As this code can be inserted automatically, at the point
+% of use only the start of a galley level needs to be marked up: the end
+% must come in a fixed location. All of this relies on the the
+% \enquote{colour safe} group used inside a box.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \galley_level_end:
+ {
+ \par
+ \galley_restore_parameters:
+ \group_end:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{The \cs{par} token}
+%
+% \begin{macro}{\galley_std_par:}
+% In vertical mode, the standard paragraph insert is just the primitive
+% \cs{tex_par:D}.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \galley_std_par:
+ {
+ \mode_if_vertical:TF
+ { \tex_par:D }
+% \end{macrocode}
+% In horizontal mode, the paragraph shape is set \enquote{just in time}
+% before inserting \cs{tex_par:D}. The \cs{tex_par:D} is inside a
+% group to preserve some dynamic settings (for example
+% \cs{etex_interlinepenalties}). Once the
+% paragraph has been typeset, the number of lines is \emph{added} to the
+% running total. It's possible that the conceptual paragraph contains
+% display-like material, and simply setting the number of lines equal to
+% \cs{tex_prevgraf:D} would \enquote{loose} these.
+% \begin{macrocode}
+ {
+ \g_galley_par_end_hook_tl
+ \galley_set_measure_and_parshape:
+ \group_begin:
+ \tex_par:D
+ \group_end:
+ \int_gadd:Nn \g_galley_previous_par_lines_int \tex_prevgraf:D
+ }
+ \g_galley_par_after_hook_tl
+ \tl_gclear:N \g_galley_par_after_hook_tl
+% \end{macrocode}
+% The non-breaking penalty is needed here as within the \cs{tex_everypar:D}
+% hook there is an additional \cs{tex_par:D}. This leads to an extra
+% \cs{tex_parskip:D}, which will leave an unwanted break-point here
+% otherwise.
+% \begin{macrocode}
+ \tex_penalty:D \c_ten_thousand
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\par}
+% The meaning of the token \cs{par} itself starts off as a standard
+% paragraph.
+% \begin{macrocode}
+\cs_set_protected_nopar:Npn \par { \galley_std_par: }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@par}
+% \LaTeXe{} requires a \enquote{long term} version of \cs{par}, which is
+% stored as \cs{@par}. Things are done a bit differently by \LaTeX3 and
+% so this will only be needed in package mode.
+% \begin{macrocode}
+%<*package>
+\tl_set:Nn \@par { \galley_std_par: }
+%</package>
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Display levels}
+%
+% \begin{macro}{\galley_display_begin:, \galley_display_end:}
+% \begin{macro}[aux]{\galley_display_penalty:N, \galley_display_vspace:N}
+% \begin{macro}[aux]{\galley_display_par_setup:, \galley_display_par:}
+% Display items within the galley are a bit like galley levels: they
+% may have different paragraph settings to the main part of the galley.
+% On the other hand, unlike independent galleys they should inherit the
+% settings from the surrounding material. They may also start and end with
+% special spacing values.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \galley_display_begin:
+ {
+ \group_begin:
+ \galley_save_parameters:
+ \mode_if_vertical:TF
+ {
+ \galley_display_penalty:N \l_galley_display_begin_par_penalty_tl
+ \galley_display_vspace:N \l_galley_display_begin_par_vspace_tl
+ }
+ {
+ \galley_display_penalty:N \l_galley_display_begin_penalty_tl
+ \galley_display_vspace:N \l_galley_display_begin_vspace_tl
+ }
+ \par
+ }
+% \end{macrocode}
+% Two short-cuts for setting up any special penalty or vertical space.
+% The idea is that the standard value is saved to the \enquote{restore}
+% token list, before setting up the value to the special value needed
+% in this one case.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \galley_display_penalty:N #1
+ {
+ \tl_if_empty:NF #1
+ {
+ \tl_gput_right:Nx \g_galley_restore_running_tl
+ {
+ \int_gset:Nn \exp_not:N \g_galley_penalty_int
+ { \int_use:N \g_galley_penalty_int }
+ }
+ \int_gset:Nn \g_galley_penalty_int {#1}
+ }
+ }
+\cs_new_protected_nopar:Npn \galley_display_vspace:N #1
+ {
+ \tl_if_empty:NF #1
+ {
+ \tl_gput_right:Nx \g_galley_restore_running_tl
+ {
+ \skip_gset:Nn \exp_not:N \g_galley_vspace_skip
+ { \skip_use:N \g_galley_vspace_skip }
+ }
+ \skip_gset:Nn \g_galley_vspace_int {#1}
+ }
+ }
+% \end{macrocode}
+% The \cs{par} token at the end of the display needs to go in at the same
+% group level as the text, hence this function cannot be placed using
+% \cs{group_insert_after:N}. Resetting the meaning of the \cs{par} token
+% needs to be carried out after the group used for the environment.
+% As \LaTeXe{} already adds one group, there are two \enquote{escapes}
+% here: the format version needs only one escape.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \galley_display_end:
+ {
+ \par
+ \galley_restore_parameters:
+ \group_end:
+%<*package>
+ \group_insert_after:N \group_insert_after:N
+%</package>
+ \group_insert_after:N \galley_display_par_setup:
+ }
+% \end{macrocode}
+% The method used here is to assume that the next piece of horizontal
+% mode material will follow on from the displayed output without an
+% intervening \cs{par} token (probably a blank line). The meaning of the
+% \cs{par} token is then altered so that a check can be made to see if
+% this assumption was correct.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \galley_display_par_setup:
+ {
+ \bool_gset_false:N \g_galley_omit_next_indent_bool
+ \cs_set_eq:NN \par \galley_display_par:
+ }
+% \end{macrocode}
+% The \enquote{special} meaning of the paragraph token starts by putting
+% things back to normal: there should never need to be more than one
+% special paragraph marker in one group. If \TeX{} is in vertical mode,
+% then there has been a paragraph token inserted, most likely by a
+% blank line. Thus the next piece of material is a separate conceptual
+% paragraph from the display. In that case, the assumption from above is
+% undone and the indent is turned back on. On the other hand, for the
+% case where \TeX{} is in horizontal mode then a \cs{tex_par:D} primitive
+% is required in the same way as in \cs{galley_standard_par:}.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \galley_display_par:
+ {
+ \cs_set_eq:NN \par \galley_std_par:
+ \mode_if_vertical:TF
+ {
+ \par
+ \bool_gset_false:N \g_galley_omit_next_indent_bool
+ \galley_display_penalty:N \l_galley_display_end_par_penalty_tl
+ \galley_display_vspace:N \l_galley_display_end_par_vspace_tl
+ }
+ {
+ \galley_set_measure_and_parshape:
+ \group_begin:
+ \tex_par:D
+ \group_end:
+ \int_gadd:Nn \g_galley_previous_par_lines_int \tex_prevgraf:D
+ \galley_display_penalty:N \l_galley_display_end_penalty_tl
+ \galley_display_vspace:N \l_galley_display_end_vspace_tl
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Insertions using \cs{tex_everypar:D}}
+%
+% The key to the entire galley mechanism is hooking into the
+% \cs{tex_everypar:D} token register. This requires that the original
+% is moved out of the way, with appropriate hooks left attached for
+% further modification by other modules and by the user. This is all
+% done such that there is no danger of accidentally deactivating the
+% galley mechanism.
+%
+% \begin{macro}{\everypar}
+% When used on top of \LaTeXe{} the original primitive name needs to be
+% available without the risk of completely overwriting the new
+% mechanism. This is implemented as a token register in case low-level
+% \TeX{} is used. The \TeX{} primitive is set here as otherwise the
+% \LaTeXe{} \cs{@nodocument} is never removed from the register.
+% This precaution is not be needed for a stand-alone format.
+% \begin{macrocode}
+%<*initex>
+\tex_everypar:D % TEMP
+ {
+ \bool_if:NTF \g_galley_begin_level_bool
+ { \galley_start_paragraph_first: }
+ { \galley_start_paragraph_std: }
+ }
+%</initex>
+%<*package>
+\cs_undefine:N \everypar
+\newtoks \everypar
+\AtBeginDocument
+ {
+ \tex_everypar:D
+ {
+ \bool_if:NTF \g_galley_begin_level_bool
+ { \galley_start_paragraph_first: }
+ { \galley_start_paragraph_std: }
+ \tex_the:D \everypar
+ }
+ }
+%</package>
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{The galley mechanism}
+%
+% \begin{variable}{\g_galley_last_box}
+% A temporary box to hold the box inserted by \TeX{} when a paragraph
+% is inserted with an indent. The galley actually inserts the space
+% (\emph{i.e.}~\cs{tex_parindent:D} is globally zero), but there is
+% still an empty box to test for.
+% \begin{macrocode}
+\box_new:N \g_galley_last_box
+% \end{macrocode}
+% \end{variable}
+%
+% The \enquote{start of paragraph} routines are fired by \cs{tex_everypar:D}.
+% This can take place within a group in a construction such as
+% \begin{verbatim}
+% ... end of last par.
+%
+% {\Large Start} of par
+% \end{verbatim}
+% and so anything applied here must be done globally.
+%
+% \begin{macro}[int]{\galley_start_paragraph_std:}
+% The routine at the start of a paragraph starts by removing any
+% (empty) indent box from the vertical list. As there may be vertical
+% mode items still to insert, a \cs{tex_par:D} primitive is used to
+% get back into vertical mode before they are tidied up. To get back
+% again to horizontal mode, \cs{tex_noindent:D} can be used. To avoid
+% an infinite loop, \cs{tex_everypar:D} is locally cleared before doing
+% that. Back in horizontal mode, the horizontal mode items can be
+% tidied up before sorting out any items which have been set on a
+% single-paragraph basis.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \galley_start_paragraph_std:
+ {
+ \group_begin:
+ \box_gset_to_last:N \g_galley_last_box
+ \tex_par:D
+ \galley_insert_vertical_items:
+ \tex_everypar:D { }
+ \tex_noindent:D
+ \group_end:
+ \int_gzero:N \g_galley_previous_par_lines_int
+ \galley_insert_horizontal_items:
+ \galley_restore_running_parameters:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\galley_start_paragraph_first:}
+% For the very first paragraph in a galley, the code needs to avoid
+% adding any unnecessary vertical items at the top as it will interfere with
+% vertical positioning in \cs{tex_vtop:D}.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \galley_start_paragraph_first:
+ {
+ \bool_gset_false:N \g_galley_begin_level_bool
+ \mode_if_horizontal:TF
+ {
+ \group_begin:
+ \box_gset_to_last:N \g_galley_last_box
+ \tex_par:D
+ \galley_insert_vspace:
+ \tex_everypar:D { }
+ \tex_noindent:D
+ \group_end:
+ }
+ { \galley_insert_vspace: }
+ \galley_insert_horizontal_items:
+ \galley_restore_running_parameters:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\galley_insert_vertical_items, \galley_insert_vspace:}
+% The aim here is to insert the vertical items such that they attach to
+% the correct place. This function is used as part of the \cs{tex_everypar:D}
+% mechanism, meaning that the immediately-preceding item on the vertical
+% list is the \cs{tex_parskip:D}, always zero-length but an implicit
+% penalty. So any whatsits \enquote{attached} to the previous paragraph
+% should stay glued on. After the whatsits, a penalty for
+% breaking will be inserted. This will be the user penalty if supplied,
+% or the running penalty unless the no-break flag is set. Finally,
+% the inter-paragraph space is applied.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \galley_insert_vertical_items:
+ {
+ \g_galley_whatsit_previous_tl
+ \tl_gclear:N \g_galley_whatsit_previous_tl
+ \tl_if_empty:NTF \g_galley_interpar_penalty_user_tl
+ {
+ \bool_if:NTF \g_galley_nobreak_next_bool
+ { \tex_penalty:D \c_ten_thousand }
+ { \tex_penalty:D \l_galley_interpar_penalty_int }
+ }
+ {
+ \tex_penalty:D
+ \int_eval:w \g_galley_interpar_penalty_user_tl \int_eval_end:
+ \tl_gclear:N \g_galley_interpar_penalty_user_tl
+ }
+ \bool_gset_false:N \g_galley_nobreak_next_bool
+ \galley_insert_vspace:
+ }
+% \end{macrocode}
+% Inserting vertical space is set up as a separate function as it comes
+% up in a few places. The idea here is that any user-set space will
+% override the design value, and only one space is ever inserted.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \galley_insert_vspace:
+ {
+ \tl_if_empty:NTF \g_galley_interpar_vspace_user_tl
+ { \skip_vertical:N \l_galley_interpar_vspace_skip }
+ {
+ \skip_vertical:n { \g_galley_interpar_vspace_user_tl }
+ \tl_gclear:N \g_galley_interpar_vspace_user_tl
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\galley_insert_horizontal_items:}
+% Horizontal mode objects start with the whatsits for the next paragraph. An
+% indent is then included if the removed box was not void.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \galley_insert_horizontal_items:
+ {
+ \g_galley_whatsit_next_tl
+ \tl_gclear:N \g_galley_whatsit_next_tl
+ \bool_if:NT \g_galley_omit_next_indent_bool
+ {
+ \box_if_empty:NF \g_galley_last_box
+ { \hbox_to_wd:nn \l_galley_par_indent_dim { } }
+ }
+ \skip_horizontal:N \l_galley_par_begin_skip
+ \g_galley_par_begin_hook_tl
+ \bool_gset_true:N \g_galley_omit_next_indent_bool
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\galley_restore_running_parameters:}
+% Restoring the ongoing parameters just means using the token list
+% variable in which the appropriate assignments are stored. The
+% list can then be cleared.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \galley_restore_running_parameters:
+ {
+ \g_galley_restore_running_tl
+ \tl_gclear:N \g_galley_restore_running_tl
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Measure}
+%
+% \begin{macro}
+% {\galley_margins_set_absolute:nn, \galley_margins_set_relative:nn}
+% Setting the measure is just a question of adjusting margins, either
+% in a relative or absolute sense.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \galley_margins_set_absolute:nn #1#2
+ {
+ \dim_set:Nn \l_galley_total_left_margin_dim {#1}
+ \dim_set:Nn \l_galley_total_right_margin_dim {#2}
+ \dim_set:Nn \l_galley_text_width_dim
+ {
+ \l_galley_width_dim
+ - \l_galley_total_left_margin_dim
+ - \l_galley_total_right_margin_dim
+ }
+ }
+\cs_new_protected_nopar:Npn \galley_margins_set_relative:nn #1#2
+ {
+ \dim_add:Nn \l_galley_total_left_margin_dim {#1}
+ \dim_add:Nn \l_galley_total_right_margin_dim {#2}
+ \dim_set:Nn \l_galley_text_width_dim
+ {
+ \l_galley_width_dim
+ - \l_galley_total_left_margin_dim
+ - \l_galley_total_right_margin_dim
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Paragraph shape}
+%
+% \begin{macro}
+% {
+% \galley_parshape_fixed_lines:nnn,
+% \galley_parshape_fixed_lines:nVV,
+% \galley_parshape_multi_par:nnnN,
+% \galley_parshape_multi_par:nVVN,
+% \galley_parshape_single_par:nnnN,
+% \galley_parshape_single_par:nVVN
+% }
+% Setting the paragraph shape is easy as most of the real work is done
+% later. So this is just a case of saving the various pieces of data
+% to the correct locations.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \galley_parshape_fixed_lines:nnn #1#2#3
+ {
+ \bool_gset_true:N \g_galley_parshape_set_bool
+ \bool_set_true:N \l_galley_parshape_fixed_lines_bool
+ \int_set:Nn \l_galley_parshape_std_lines_int {#1}
+ \clist_set:Nn \l_galley_parshape_left_indent_clist {#2}
+ \clist_set:Nn \l_galley_parshape_right_indent_clist {#3}
+ \bool_set_true:N \l_galley_parshape_resume_std_bool
+ }
+\cs_new_protected_nopar:Npn \galley_parshape_multi_par:nnnN #1#2#3#4
+ {
+ \bool_gset_true:N \g_galley_parshape_set_bool
+ \bool_set_true:N \l_galley_parshape_multipar_bool
+ \bool_set_false:N \l_galley_parshape_fixed_lines_bool
+ \int_set:Nn \l_galley_parshape_std_lines_int {#1}
+ \clist_set:Nn \l_galley_parshape_left_indent_clist {#2}
+ \clist_set:Nn \l_galley_parshape_right_indent_clist {#3}
+ \bool_set_eq:NN \l_galley_parshape_resume_std_bool #4
+ }
+\cs_new_protected_nopar:Npn \galley_parshape_single_par:nnnN #1#2#3#4
+ {
+ \bool_gset_true:N \g_galley_parshape_set_bool
+ \bool_set_false:N \l_galley_parshape_multipar_bool
+ \bool_set_false:N \l_galley_parshape_fixed_lines_bool
+ \int_set:Nn \l_galley_parshape_std_lines_int {#1}
+ \clist_set:Nn \l_galley_parshape_left_indent_clist {#2}
+ \clist_set:Nn \l_galley_parshape_right_indent_clist {#3}
+ \bool_set_eq:NN \l_galley_parshape_resume_std_bool #4
+ }
+\cs_generate_variant:Nn \galley_parshape_fixed_lines:nnn { nVV }
+\cs_generate_variant:Nn \galley_parshape_multi_par:nnnN { nVV }
+\cs_generate_variant:Nn \galley_parshape_single_par:nnnN { nVV }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\galley_set_measure_and_parshape:}
+% To set the paragraph shape for the current paragraph, there is a check to
+% see if the measure alone should be used. If not, then the shape may be
+% built by paragraph or based on the number of lines required.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \galley_set_measure_and_parshape:
+ {
+ \bool_if:NTF \g_galley_parshape_set_bool
+ {
+ \bool_if:NTF \l_galley_parshape_fixed_lines_bool
+ {
+ \int_compare:nNnTF \g_galley_previous_par_lines_int > \c_zero
+ { \galley_generate_parshape_lines: }
+ { \galley_generate_parshape: }
+ }
+ {
+ \bool_gset_eq:NN \g_galley_parshape_set_bool
+ \l_galley_parshape_multipar_bool
+ \galley_generate_parshape:
+ }
+ }
+ {
+ \tex_global:D \tex_parshape:D
+ \c_one
+ \dim_use:N \l_galley_total_left_margin_dim
+ \c_space_tl
+ \dim_use:N \l_galley_text_width_dim
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{\galley_generate_parshape:}
+% \begin{macro}[aux]{\galley_set_parshape_map:nn, \galley_set_parshape_map:oo}
+% \begin{macro}[aux]{\galley_set_parshape_map_aux:nw}
+% For a shape to apply on a paragraph basis, the two user-supplied comma
+% lists are taken and converted into left-side offsets and line lengths.
+% This is all dependent on the current measure.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \galley_generate_parshape:
+ {
+ \tex_global:D \tex_parshape:D
+ \int_eval:w
+ \l_galley_parshape_std_lines_int +
+ \int_min:nn
+ { \clist_length:N \l_galley_parshape_left_indent_clist }
+ { \clist_length:N \l_galley_parshape_right_indent_clist }
+ \bool_if:NT \l_galley_parshape_resume_std_bool { + 1 }
+ \int_eval_end:
+ \prg_replicate:nn \l_galley_parshape_std_lines_int
+ {
+ \dim_use:N \l_galley_total_left_margin_dim
+ \c_space_tl
+ \dim_use:N \l_galley_text_width_dim
+ \c_space_tl
+ }
+ \galley_set_parshape_map:oo
+ \l_galley_parshape_left_indent_clist
+ \l_galley_parshape_right_indent_clist
+ \bool_if:NT \l_galley_parshape_resume_std_bool
+ {
+ \c_space_tl
+ \dim_use:N \l_galley_total_left_margin_dim
+ \c_space_tl
+ \dim_use:N \l_galley_text_width_dim
+ }
+ }
+\cs_new_nopar:Npn \galley_set_parshape_map:nn #1#2
+ { \galley_set_parshape_map_aux:nw { } #1 , \q_mark #2 , \q_stop }
+\cs_generate_variant:Nn \galley_set_parshape_map:nn { oo }
+\cs_new_nopar:Npn \galley_set_parshape_map_aux:nw
+ #1#2 , #3 \q_mark #4 , #5 \q_stop
+ {
+ \bool_if:nTF { \tl_if_empty_p:n {#3} || \tl_if_empty_p:n {#4} }
+ {
+ #1
+ \dim_eval:n { \l_galley_total_left_margin_dim + ( #2 ) }
+ \c_space_tl
+ \dim_eval:n { \l_galley_text_width_dim - ( ( #2 ) + ( #4 ) ) }
+ }
+ {
+ \galley_set_parshape_map_aux:nw
+ {
+ #1
+ \dim_eval:n { \l_galley_total_left_margin_dim + ( #2 ) }
+ \c_space_tl
+ \dim_eval:n { \l_galley_text_width_dim - ( ( #2 ) + ( #4 ) ) }
+ \c_space_tl
+ }
+ #3 \q_mark #5 \q_stop
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[int]{\galley_generate_parshape_lines:}
+% \begin{macro}[aux]{\galley_generate_parshape_lines_aux:n}
+% The idea here is to construct a paragraph shape based on the remaining
+% lines from the shape in the previous paragraph. If the previous paragraph
+% was sufficiently long, then life is \enquote{back to normal} and the
+% standard shape is set. If a special shape is needed, this is recovered
+% from the paragraph shape using the \eTeX{} primitives.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \galley_generate_parshape_lines:
+ {
+ \int_compare:nNnTF \tex_parshape:D > \g_galley_previous_par_lines_int
+ {
+ \tex_global:D \tex_parshape:D
+ \int_eval:w \tex_parshape:D - \g_galley_previous_par_lines_int
+ \int_eval_end:
+ \prg_stepwise_function:nnnN
+ { \g_galley_previous_par_lines_int + \c_one }
+ \c_one \tex_parshape:D \galley_generate_parshape_lines_aux:n
+ }
+ {
+ \bool_gset_false:N \g_galley_parshape_set_bool
+ \tex_global:D \tex_parshape:D
+ \c_one
+ \dim_use:N \l_galley_total_left_margin_dim
+ \c_space_tl
+ \dim_use:N \l_galley_text_width_dim
+ }
+ }
+\cs_new_nopar:Npn \galley_generate_parshape_lines_aux:n #1
+ {
+ \etex_parshapeindent:D #1
+ ~
+ \etex_parshapelength:D #1
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Between paragraphs}
+%
+% \begin{macro}{\galley_set_user_penalty:n, \galley_set_user_vspace:n}
+% User supplied penalties and spaces only apply for a single paragraph.
+% In both cases, the input values need to be checked for the correct
+% form but are stored as token lists. The \texttt{x}-type expansion
+% deals with this nicely.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \galley_set_user_penalty:n #1
+ { \tl_gset:Nx \g_galley_interpar_penalty_user_tl { \int_eval:n {#1} } }
+\cs_new_protected_nopar:Npn \galley_set_user_vspace:n #1
+ { \tl_gset:Nx \g_galley_interpar_vspace_user_tl { \skip_eval:n {#1} } }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\parskip}
+% For the package, the \cs{parskip} primitive is moved out of the
+% way as the code above is handling things.
+% \begin{macrocode}
+%<*package>
+\dim_set:Nn \parskip \c_zero_dim
+\cs_undefine:N \parskip
+\skip_new:N \parskip
+%</package>
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Formatting inside the paragraph}
+%
+% Justification is more complex than is necessarily desirable as the various
+% \TeX{} parameters here interact in ways which mean that clear separation
+% between different areas is not so easy.
+%
+% \begin{variable}
+% {
+% \l_galley_line_left_skip,
+% \l_galley_line_right_skip,
+% \l_galley_par_begin_skip,
+% \l_galley_par_end_skip,
+% \l_galley_par_indent_dim
+% }
+% The variables for setting paragraph shape: essentially, these are
+% the \TeX{} set.
+% \begin{macrocode}
+\cs_new_eq:NN \l_galley_line_left_skip \tex_leftskip:D
+\cs_new_eq:NN \l_galley_line_right_skip \tex_rightskip:D
+\dim_new:N \l_galley_par_begin_skip
+\cs_new_eq:NN \l_galley_par_end_skip \tex_parfillskip:D
+\cs_new_eq:NN \l_galley_par_indent_dim \tex_parindent:D
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_galley_last_line_fit_int}
+% One from \eTeX{}.
+% \begin{macrocode}
+\cs_new_eq:NN \l_galley_last_line_fit_int \etex_lastlinefit:D
+% \end{macrocode}
+% \end{variable}
+%
+% \subsection{Inter-word spacing}
+%
+% Setting the spacing between words and between sentences is important
+% for achieving the correct output from ragged and centred output. At
+% the same time, as far as possible the aim is to retain the spacing
+% specified by the font designer and not to use arbitrary values
+% (\emph{cf.}~the approach in \emph{The \TeX{}book}, p.~101).
+%
+% \begin{macro}{\galley_set_interword_spacing:N}
+% The approach taken to setting a fixed space is to use the information
+% from the current font to set the spacing. This means that only
+% \cs{tex_spacefactor:D} needs to be set, while \cs{tex_xspacefactor:D}
+% is left alone. However, this is only necessary for fonts which have
+% a stretch component to the inter-word spacing in the first place,
+% \emph{i.e.}~monospaced fonts require no changes. The code therefore
+% checks whether there is any stretch, and if there is uses the fixed
+% component to set \cs{tex_spaceskip:D}. If there is a stretch component
+% (non-zero \cs{tex_fontdimen:D} \texttt{3}), then the \cs{teX_spaceskip:D}
+% is set to the fixed component from the font.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \galley_set_interword_spacing:N #1
+ {
+ \bool_if:NTF #1
+ { % TODO Hook for font changes required!
+ \dim_compare:nNnTF { \tex_fontdimen:D \c_three \tex_font:D }
+ = \c_zero_dim
+ { \tex_spaceskip:D \c_zero_dim }
+ { \tex_spaceskip:D \tex_fontdimen:D \c_two \tex_font:D }
+ }
+ { \tex_spaceskip:D \c_zero_dim }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Hyphenation}
+%
+% \subsection{Line breaking}
+%
+% \begin{variable}
+% {
+% \l_galley_binop_penalty_int,
+% \l_galley_double_hyphen_demerits_int,
+% \l_galley_emergency_stretch_skip,
+% \l_galley_final_hyphen_demerits_int,
+% \l_galley_linebreak_badness_int,
+% \l_galley_linebreak_fuzz_dim,
+% \l_galley_linebreak_penalty_int,
+% \l_galley_linebreak_pretolerance_int,
+% \l_galley_linebreak_tolerance_int,
+% \l_galley_mismatch_demerits_int,
+% \l_galley_relation_penalty_int
+% }
+% All \TeX{} primitives renamed.
+% \begin{macrocode}
+\cs_new_eq:NN \l_galley_binop_penalty_int \tex_binoppenalty:D
+\cs_new_eq:NN \l_galley_double_hyphen_demerits_int \tex_doublehyphendemerits:D
+\cs_new_eq:NN \l_galley_emergency_stretch_skip \tex_emergencystretch:D
+\cs_new_eq:NN \l_galley_final_hyphen_demerits_int \tex_finalhyphendemerits:D
+\cs_new_eq:NN \l_galley_linebreak_badness_int \tex_hbadness:D
+\cs_new_eq:NN \l_galley_linebreak_fuzz_dim \tex_hfuzz:D
+\cs_new_eq:NN \l_galley_linebreak_penalty_int \tex_linepenalty:D
+\cs_new_eq:NN \l_galley_linebreak_pretolerance_int \tex_pretolerance:D
+\cs_new_eq:NN \l_galley_mismatch_demerits_int \tex_adjdemerits:D
+\cs_new_eq:NN \l_galley_relation_penalty_int \tex_relpenalty:D
+\cs_new_eq:NN \l_galley_linebreak_tolerance_int \tex_tolerance:D
+% \end{macrocode}
+% \end{variable}
+%
+% \subsection{Paragraph breaking}
+%
+% \begin{variable}
+% {
+% \l_galley_broken_penalty_int,
+% \l_galley_interline_penalty_int,
+% \l_galley_parbreak_badness_int,
+% \l_galley_parbreak_fuzz_dim,
+% \l_galley_post_display_penalty_int,
+% \l_galley_pre_display_penalty_int
+%
+% }
+% \TeX{} primitives renamed cover \emph{some} of this.
+% \begin{macrocode}
+\cs_new_eq:NN \l_galley_broken_penalty_int \tex_brokenpenalty:D
+\cs_new_eq:NN \l_galley_interline_penalty_int \tex_interlinepenalty:D
+\cs_new_eq:NN \l_galley_parbreak_badness_int \tex_vbadness:D
+\cs_new_eq:NN \l_galley_parbreak_fuzz_dim \tex_vfuzz:D
+\cs_new_eq:NN \l_galley_post_display_penalty_int \tex_postdisplaypenalty:D
+\cs_new_eq:NN \l_galley_pre_display_penalty_int \tex_predisplaypenalty:D
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\l_galley_club_penalties_clist, \l_galley_line_penalties_clist}
+% These are used to keep a track of information which cannot be
+% extracted out of the primitives due to the overlapping nature of
+% the meanings.
+% \begin{macrocode}
+\clist_new:N \l_galley_club_penalties_clist
+\clist_new:N \l_galley_line_penalties_clist
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \galley_set_display_widow_penalties:n,
+% \galley_set_display_widow_penalties:V,
+% \galley_set_display_widow_penalties:v,
+% \galley_set_widow_penalties:n,
+% \galley_set_widow_penalties:V,
+% \galley_set_widow_penalties:v
+% }
+% \begin{macro}[aux]{\galley_set_aux:n}
+% By far the easiest penalties to deal with are those for widows. These
+% work exactly as the names imply, with the display version only used
+% immediately before display math, and the standard penalty used at the end
+% of a paragraph. Thus there is only the need to convert the argument into
+% the correct form, and add a $0$ penalty at the end to nullify the effect of
+% repeating the last value.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \galley_set_display_widow_penalties:n #1
+ {
+ \etex_displaywidowpenalties:D
+ \int_eval:w \clist_length:n {#1} + \c_one \int_eval_end:
+ \clist_map_function:nN {#1} \galley_set_aux:n
+ \c_zero
+ }
+\cs_generate_variant:Nn \galley_set_display_widow_penalties:n { V , v }
+\cs_new_protected_nopar:Npn \galley_set_widow_penalties:n #1
+ {
+ \etex_widowpenalties:D
+ \int_eval:w \clist_length:n {#1} + \c_one \int_eval_end:
+ \clist_map_function:nN {#1} \galley_set_aux:n
+ \c_zero
+ }
+\cs_generate_variant:Nn \galley_set_widow_penalties:n { V , v }
+\cs_new_nopar:Npn \galley_set_aux:n #1 { #1 ~ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \galley_set_club_penalties:n,
+% \galley_set_club_penalties:V,
+% \galley_set_club_penalties:v,
+% \galley_set_interline_penalties:n,
+% \galley_set_interline_penalties:V,
+% \galley_set_interline_penalties:v
+% }
+% Setting club or special line penalties is easy, as these are handled
+% mainly by the interline set up function. The two concepts are essentially
+% the same, but having two takes makes some special effects easier to
+% carry out.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \galley_set_club_penalties:n #1
+ {
+ \clist_set:Nn \l_galley_club_penalties_clist {#1}
+ \galley_calc_interline_penalties:
+ }
+\cs_generate_variant:Nn \galley_set_club_penalties:n { V , v }
+\cs_new_protected_nopar:Npn \galley_set_interline_penalties:n #1
+ {
+ \clist_set:Nn \l_galley_line_penalties_clist {#1}
+ \galley_calc_interline_penalties:
+ }
+\cs_generate_variant:Nn \galley_set_interline_penalties:n { V , v }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \galley_set_display_club_penalties:n,
+% \galley_set_display_club_penalties:V,
+% \galley_set_display_club_penalties:v
+% }
+% Setting the display club penalties means first setting the primitive,
+% then recalculating the interline array to allow for these new values.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \galley_set_display_club_penalties:n #1
+ {
+ \etex_clubpenalties:D
+ \int_eval:w \clist_length:n {#1} + \c_one \int_eval_end:
+ \clist_map_function:nN {#1} \galley_set_aux:n
+ \c_zero
+ \galley_calc_interline_penalties:
+ }
+\cs_generate_variant:Nn \galley_set_display_club_penalties:n { V , v }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\galley_set_interline_penalty:n}
+% \begin{macro}[aux]{\galley_set_interline_penalty_aux:nn}
+% \begin{macro}[aux]
+% {
+% \galley_set_interline_penalty_aux_i:n,
+% \galley_set_interline_penalty_aux_ii:n
+% }
+% Dealing with the general interline penalty is handled in one shot.
+% The idea is that for lines with no special penalty, the old general
+% penalty is removed and the new one is added. If there is currently
+% no shape set, then after adding the general interline value the
+% generic build system is invoked (in case the
+% \cs{etex_interlinepenalties:D} has accidentally been cleared).
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \galley_set_interline_penalty:n #1
+ {
+ \int_compare:nNnTF { \etex_interlinepenalties:D \c_zero } = \c_zero
+ {
+ \etex_interlinepenalties:D \c_one \int_eval:w #1 \int_eval_end:
+ \galley_calc_interline_penalties:
+ }
+ {
+ \cs_set_nopar:Npn \galley_set_interline_penalty_aux_ii:n ##1
+ {
+ \int_eval:w
+ \etex_interlinepenalties:D ##1
+ - \etex_interlinepenalties:D \etex_interlinepenalties:D \c_zero
+ + #1
+ \int_eval_end:
+ }
+ \exp_args:Nf \galley_set_interline_penalty_aux:nn
+ { \clist_length:N \l_galley_line_penalties_clist } {#1}
+ }
+ }
+\cs_new_protected_nopar:Npn \galley_set_interline_penalty_aux:nn #1#2
+ {
+ \etex_interlinepenalties:D
+ \etex_interlinepenalties:D \c_zero
+ \prg_stepwise_function:nnnN \c_one \c_one {#1}
+ \galley_set_interline_penalty_aux_i:n
+ \prg_stepwise_function:nnnN { #1 + \c_one } \c_one
+ { \etex_interlinepenalties:D \c_zero - \c_one }
+ \galley_set_interline_penalty_aux_ii:n
+ \int_eval:w #2 \int_eval_end:
+ }
+\cs_new_nopar:Npn \galley_set_interline_penalty_aux_i:n #1
+ { \etex_interlinepenalties:D \int_eval:w #1 \int_eval_end: }
+\cs_new_nopar:Npn \galley_set_interline_penalty_aux_ii:n #1 { }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[int]{\galley_calc_interline_penalties:}
+% \begin{macro}[aux]{\galley_calc_interline_penalties_aux:nn}
+% \begin{macro}[aux]
+% {
+% \galley_calc_interline_penalties_aux_i:n,
+% \galley_calc_interline_penalties_aux_ii:n
+% }
+% The underlying interline penalty array has to deal with club penalties,
+% display club penalties and any special line penalties, and include
+% the general interline penalty. These requirements lead to a rather
+% complex requirement on how many lines to deal with. This is needed twice,
+% so an \texttt{f}-type expansion is used to make life a little less
+% complex.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \galley_calc_interline_penalties:
+ {
+ \exp_args:Nff \galley_calc_interline_penalties_aux:nn
+ {
+ \int_eval:n
+ {
+ \int_max:nn
+ {
+ \clist_length:N \l_galley_club_penalties_clist
+ + \c_one
+ }
+ {
+ \int_max:nn
+ {
+ \clist_length:N \l_galley_line_penalties_clist
+ + \c_one
+ }
+ { \etex_clubpenalties:D \c_zero }
+ }
+ }
+ }
+ { \clist_length:N \l_galley_line_penalties_clist }
+ }
+% \end{macrocode}
+% The idea is now to calculate the correct penalties. Two auxiliary functions
+% are used: one for any \enquote{special penalty} lines and a second for
+% normal lines. At the end of the process, the standard interline
+% penalty is always included.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \galley_calc_interline_penalties_aux:nn
+ #1#2
+ {
+ \etex_interlinepenalties:D #1 ~
+ \prg_stepwise_function:nnnN \c_one \c_one {#2}
+ \galley_calc_interline_penalties_aux_i:n
+ \prg_stepwise_function:nnnN { #2 + \c_one } \c_one { #1 - \c_one }
+ \galley_calc_interline_penalties_aux_ii:n
+ \etex_interlinepenalties:D \etex_interlinepenalties:D \c_zero
+ }
+\cs_new_nopar:Npn \galley_calc_interline_penalties_aux_i:n
+ #1
+ {
+ \int_eval:w
+ \clist_item:Nn \l_galley_line_penalties_clist { #1 - \c_one }
+ + 0 \clist_item:Nn \l_galley_club_penalties_clist
+ { #1 - \c_one }
+ - \etex_clubpenalties:D #1 ~
+ \int_eval_end:
+ }
+\cs_new_nopar:Npn \galley_calc_interline_penalties_aux_ii:n
+ #1
+ {
+ \int_eval:w
+ \etex_interlinepenalties:D \etex_interlinepenalties:D \c_zero
+ + 0 \clist_item:Nn \l_galley_club_penalties_clist
+ { #1 - \c_one }
+ - \etex_clubpenalties:D #1 ~
+ \int_eval_end:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \galley_save_club_penalties:N,
+% \galley_save_interline_penalties:N,
+% \galley_save_display_club_penalties:N,
+% \galley_save_display_widow_penalties:N,
+% \galley_save_widow_penalties:N
+% }
+% \begin{macro}[aux]
+% {
+% \galley_save_display_club_penalties_aux:n,
+% \galley_save_display_widow_penalties_aux:n,
+% \galley_save_widow_penalties_aux:n
+% }
+% \begin{macro}{\galley_interline_penalty:}
+% Saving the array penalties varies in complexity depending on how they are
+% stored internally. The first two are easy: these are simply copies.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \galley_save_club_penalties:N #1
+ { \clist_set_eq:NN #1 \l_galley_club_penalties_clist }
+\cs_new_protected_nopar:Npn \galley_save_interline_penalties:N #1
+ { \clist_set_eq:NN #1 \l_galley_line_penalties_clist }
+% \end{macrocode}
+% These all require appropriate mappings, using the fact that
+% \cs{clist_set:Nx} will tidy up the excess comma.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \galley_save_display_club_penalties:N #1
+ {
+ \clist_set:Nx #1
+ {
+ \prg_stepwise_function:nnnN \c_one \c_one
+ { \etex_clubpenalties:D \c_zero - \c_one }
+ \galley_save_display_club_penalties:_aux:n
+ }
+ }
+\cs_new_nopar:Npn \galley_save_display_club_penalties:_aux:n #1
+ { \int_use:N \etex_clubpenaltes:D \int_eval:w #1 \int_eval_end: , }
+\cs_new_protected_nopar:Npn \galley_save_display_widow_penalties:N #1
+ {
+ \clist_set:Nx #1
+ {
+ \prg_stepwise_function:nnnN \c_one \c_one
+ { \etex_displaywidowpenalties:D \c_zero - \c_one }
+ \galley_save_display_widow_penalties:_aux:n
+ }
+ }
+\cs_new_nopar:Npn \galley_save_display_widow_penalties:_aux:n #1
+ { \int_use:N \etex_displaywidowpenalties:D \int_eval:w #1 \int_eval_end: , }
+\cs_new_protected_nopar:Npn \galley_save_widow_penalties:N #1
+ {
+ \clist_set:Nx #1
+ {
+ \prg_stepwise_function:nnnN \c_one \c_one
+ { \etex_widowpenalties:D \c_zero - \c_one }
+ \galley_save_widow_penalties:_aux:n
+ }
+ }
+\cs_new_nopar:Npn \galley_save_widow_penalties:_aux:n #1
+ { \int_use:N \etex_widowpenalties:D \int_eval:w #1 \int_eval_end: , }
+% \end{macrocode}
+% This one is not an array, but is stored in a primitive, so there is
+% a simple conversion. The general interline penalty is always the
+% last value in the primitive array.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \galley_interline_penalty:
+ { \int_use:N \etex_interlinepenalties:D \etex_interlinepenalties:D \c_zero }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{\LaTeXe{} fixes}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+%
+% Purely for testing, some internal \LaTeXe{} functions are altered to work
+% with the mechanism here. This material is not comprehensive: additions are
+% made as-needed for test purposes.
+%
+% \begin{macro}{\@afterheading}
+% Set some flags and hope for the best!
+% \begin{macrocode}
+\cs_set_protected_nopar:Npn \@afterheading
+ {
+ \bool_gset_true:N \g_galley_no_break_next_bool
+ \if@afterindent
+ \else
+ \bool_gset_true:N \galley_omit_next_indent_bool
+ \fi
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@hangfrom}
+% The \cs{tex_handindent:D} primitive is no longer used, so the paragraph
+% shape is set in a different way. As a result, the label is part of the
+% same paragraph as the main body, hence the need to leave vertical mode.
+% \begin{macrocode}
+\cs_set_protected:Npn \@hangfrom #1
+ {
+ \setbox \@tempboxa = \hbox { {#1} }
+ \galley_parshape_single_par:nnnN
+ \c_one
+ { \box_wd:N \@tempboxa }
+ \c_zero_dim
+ \c_false_bool
+ \bool_gset_true:N \g_galley_no_break_next_bool
+ \bool_gset_true:N \galley_omit_next_indent_bool
+ \box \@tempboxa
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@makefntext}
+% Here, the paragraph indent is set up using the template system, and
+% as in other places the code ensures that the label is set in horizontal
+% mode. The flag used for omitting the indent is once again the galley
+% one.
+% \begin{macrocode}
+\cs_set_protected:Npn \@makefntext #1
+ {
+ \UseTemplate { justification } { std } { indent-width = 1 em }
+ \bool_gset_true:N \galley_omit_next_indent_bool
+ \galley_leave_vmode:
+ \hb@xt@ 1.8em { \hss \@makefnmark } #1
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</initex|package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex \ No newline at end of file
diff --git a/Master/texmf-dist/source/latex/l3experimental/xgalley/xgalley.dtx b/Master/texmf-dist/source/latex/l3experimental/xgalley/xgalley.dtx
new file mode 100644
index 00000000000..0dc1c85b610
--- /dev/null
+++ b/Master/texmf-dist/source/latex/l3experimental/xgalley/xgalley.dtx
@@ -0,0 +1,1602 @@
+% \iffalse
+%
+%% File: xgalley.dtx Copyright (C) 1999-2001, 2004-2009 Frank Mittelbach
+%% (C) 2010,2011 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
+%%
+%% http://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 released version of this bundle is available from CTAN.
+%%
+%% -----------------------------------------------------------------------
+%%
+%% The development version of the bundle can be found at
+%%
+%% http://www.latex-project.org/svnroot/experimental/trunk/
+%%
+%% for those people who are interested.
+%%
+%%%%%%%%%%%
+%% NOTE: %%
+%%%%%%%%%%%
+%%
+%% Snapshots taken from the repository represent work in progress and may
+%% not work or may contain conflicting material! We therefore ask
+%% people _not_ to put them into distributions, archives, etc. without
+%% prior consultation with the LaTeX Project Team.
+%%
+%% -----------------------------------------------------------------------
+%%
+%
+%<*driver|package>
+\RequirePackage{l3names}
+\GetIdInfo$Id: xgalley.dtx 2895 2011-10-09 15:58:19Z joseph $
+ {L3 Experimental galley}
+%</driver|package>
+%<*driver>
+\documentclass[full]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \textsf{xgalley} package\\ Galley^^A
+% \thanks{This file describes v\ExplFileVersion,
+% last revised \ExplFileDate.}^^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 \ExplFileDate}
+%
+% \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
+% }
+% {0 pt}
+% \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
+% }
+% {0 pt}
+% \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.
+% }
+% {0 pt}
+% \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.
+% }
+% {0 pt}
+% \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
+% }
+% {0 pt}
+% \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
+% }
+% {0 pt}
+% \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.}
+% {0 pt plus 1 fil}
+% \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
+% }
+% {0 pt}
+% \TemplateKey{right-skip}{skip}
+% {^^A
+% The skip between the right margin of the galley and the right edge of a
+% paragraph.^^A
+% }
+% {0 pt}
+% \TemplateKey{start-skip}{skip}
+% {^^A
+% The skip inserted in addition to |indent-width| at the start of a
+% paragraph.^^A
+% }
+% {0 pt}
+% \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}{15 pt}
+% \InstanceSemantics
+% Sets paragraphs fully-justified with the first line indented by
+% |15 pt|.
+% \end{InstanceDescription}
+%
+% \begin{InstanceDescription}{justification}{noindent}{std}
+% \InstanceKey{end-skip}{15 pt plus 1 fil}
+% \InstanceKey{indent-width}{0 pt}
+% \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.}
+% {0 pt plus 1 fil}
+% \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
+% }
+% {0 pt}
+% \TemplateKey{right-skip}{skip}
+% {^^A
+% The skip between the right margin of the galley and the right edge of a
+% paragraph.^^A
+% }
+% {0 pt}
+% \TemplateKey{start-skip}{skip}
+% {^^A
+% The skip inserted in addition to |indent-width| at the start of a
+% paragraph.^^A
+% }
+% {0 pt}
+% \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}{justification}{centered}{std}
+% \InstanceKey{end-skip}{0 pt}
+% \InstanceKey{fixed-word-spacing}{true}
+% \InstanceKey{indent-width}{0 pt}
+% \InstanceKey{left-skip}{0 pt plus 1 em}
+% \InstanceKey{right-skip}{0 pt plus 1 em}
+% \InstanceSemantics
+% Centres typeset material such that hyphenation will still occur and
+% such that very short lines are discouraged. This is similar to the
+% \LaTeXe{} \pkg{ragged2e} \env{Centering} environment.
+% \end{InstanceDescription}
+%
+% \begin{InstanceDescription}{justification}{ragged-left}{std}
+% \InstanceKey{end-skip}{0 pt}
+% \InstanceKey{fixed-word-spacing}{true}
+% \InstanceKey{indent-width}{0 pt}
+% \InstanceKey{left-skip}{0 pt plus 2 em}
+% \InstanceKey{right-skip}{0 pt}
+% \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}{justification}{ragged-right}{std}
+% \InstanceKey{end-skip}{0 pt}
+% \InstanceKey{fixed-word-spacing}{true}
+% \InstanceKey{indent-width}{0 pt}
+% \InstanceKey{left-skip}{0 pt}
+% \InstanceKey{right-skip}{0 pt plus 2 em}
+% \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}{justification}{center}{std}
+% \InstanceKey{end-skip}{0 pt}
+% \InstanceKey{fixed-word-spacing}{true}
+% \InstanceKey{indent-width}{0 pt}
+% \InstanceKey{left-skip}{0 pt plus 1 fil}
+% \InstanceKey{right-skip}{0 pt plus 1 fil}
+% \InstanceSemantics
+% Centres typeset material such that hyphenation is strongly discouraged
+% and short lines are allowed. This template is suited to centring arbitrary
+% material (such as boxes) rather than centring text. In the later case, the
+% |centered| instance should be used.
+% \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
+% }
+% {10 000}
+% \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
+% }
+% {0 pt}
+% \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.1 pt}
+% \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.1 pt}
+% \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.}
+% {10 000}
+% \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}{paragraph-breaking}{nobreak}{std}
+% \InstanceKey{interline-penalty}{10 000}
+% \InstanceKey{post-display-penalty}{10 000}
+% \InstanceSemantics
+% Sets paragraphs such that they cannot be broken at all (as far as is
+% possible in \TeX{}).
+% \end{InstanceDescription}
+%
+% \begin{InstanceDescription}{paragraph-breaking}{nolone}{std}
+% \InstanceKey{club-penalty}{10 000}
+% \InstanceKey{display-widow-penalty}{10 000}
+% \InstanceKey{widow-penalty}{10 000}
+% \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}{paragraph-breaking}{single-nobreak}{single}
+% \InstanceKey{interline-penalty}{10 000}
+% \InstanceKey{post-display-penalty}{10 000}
+% \InstanceSemantics
+% Sets the next paragraph such that it cannot be broken at all (as far as is
+% possible in \TeX{}).
+% \end{InstanceDescription}
+%
+% \begin{InstanceDescription}{paragraph-breaking}{single-noclub}{single}
+% \InstanceKey{club-penalty}{10 000}
+% \InstanceKey{display-club-penalty}{10 000}
+% \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}{paragraph-breaking}{single-nolone}{single}
+% \InstanceKey{club-penalty}{10 000}
+% \InstanceKey{display-club-penalty}{10 000}
+% \InstanceKey{display-widow-penalty}{10 000}
+% \InstanceKey{widow-penalty}{10 000}
+% \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}{paragraph-breaking}{single-nowidow}{single}
+% \InstanceKey{display-widow-penalty}{10 000}
+% \InstanceKey{widow-penalty}{10 000}
+% \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}
+\ProvidesExplPackage
+ {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
+\RequirePackage{xparse,xtemplate,l3galley}
+% \end{macrocode}
+%
+% \subsection{Variables}
+%
+% \begin{variable}{\l_galley_tmpa_clist, \l_galley_tmpb_clist}
+% Scratch space.
+% \begin{macrocode}
+\clist_new:N \l_galley_tmpa_clist
+\clist_new:N \l_galley_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 = 0 pt ,
+ right-margin : length = 0 pt
+ }
+\DeclareTemplateInterface { measure } { relative } { 0 }
+ {
+ left-margin : length = 0 pt ,
+ right-margin : length = 0 pt
+ }
+% \end{macrocode}
+%
+% \begin{variable}{\l_galley_left_margin_dim, \l_galley_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_galley_left_margin_dim \leftmargin
+%</package>
+%<*package>
+\cs_new_eq:NN \l_galley_right_margin_dim \rightmargin
+%</package>
+\DeclareTemplateCode { measure } { absolute } { 0 }
+ {
+ left-margin = \l_galley_left_margin_dim ,
+ right-margin = \l_galley_right_margin_dim
+ }
+ {
+ \AssignTemplateKeys
+ \galley_margins_set_absolute:nn \l_galley_left_margin_dim
+ \l_galley_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_galley_left_margin_dim ,
+ right-margin = \l_galley_right_margin_dim
+ }
+ {
+ \AssignTemplateKeys
+ \galley_margins_set_relative:nn \l_galley_left_margin_dim
+ \l_galley_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 = 0 pt ,
+ on-left-side : boolean = true ,
+ lines : integer = 1
+ }
+\DeclareTemplateInterface { parshape } { initial } { 0 }
+ {
+ indent : length = 0 pt ,
+ on-left-side : boolean = true ,
+ lines : integer = 2
+ }
+% \end{macrocode}
+% \begin{variable}{\l_galley_parshape_indent_dim}
+% \begin{variable}{\l_galley_parshape_on_left_bool}
+% \begin{variable}{\l_galley_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_galley_parshape_indent_dim ,
+ on-left-side = \l_galley_parshape_on_left_bool ,
+ lines = \l_galley_parshape_lines_int
+ }
+ {
+ \AssignTemplateKeys
+ \bool_if:NTF \l_galley_parshape_on_left_bool
+ {
+ \galley_parshape_single_par:nVVN
+ \l_galley_parshape_lines_int
+ \l_galley_parshape_indent_dim
+ \c_zero_dim
+ \c_false_bool
+ }
+ {
+ \galley_parshape_single_par:nVVN
+ \l_galley_parshape_lines_int
+ \c_zero_dim
+ \l_galley_parshape_indent_dim
+ \c_false_bool
+ }
+ }
+\DeclareTemplateCode { parshape } { initial } { 0 }
+ {
+ indent = \l_galley_parshape_indent_dim ,
+ on-left-side = \l_galley_parshape_on_left_bool ,
+ lines = \l_galley_parshape_lines_int
+ }
+ {
+ \AssignTemplateKeys
+ \clist_clear:N \l_galley_tmpa_clist
+ \clist_clear:N \l_galley_tmpb_clist
+ \prg_replicate:nn { \l_galley_parshape_lines_int }
+ {
+ \clist_put_right:Nn \l_galley_tmpa_clist
+ { \l_galley_parshape_indent_dim }
+ \clist_put_right:Nn \l_galley_tmpb_clist
+ { \c_zero_dim }
+ }
+ \bool_if:NTF \l_galley_parshape_on_left_bool
+ {
+ \galley_parshape_single_par:nVVN
+ \c_zero
+ \l_galley_tmpa_clist
+ \l_galley_tmpb_clist
+ \c_true_bool
+ }
+ {
+ \galley_parshape_single_par:nVVN
+ \c_zero
+ \l_galley_tmpb_clist
+ \l_galley_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_galley_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_galley_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 = 0 pt plus 1 fil ,
+ fixed-word-spacing : boolean = false ,
+ indent-width : length ,
+ left-skip : skip = 0 pt ,
+ right-skip : skip = 0 pt ,
+ start-skip : skip = 0 pt ,
+ stretch-last-line : boolean = false
+ }
+\DeclareTemplateInterface { justification } { single } { 0 }
+ {
+ end-skip : skip = 0 pt plus 1 fil ,
+ fixed-word-spacing : boolean = false ,
+ indent-width : length ,
+ left-skip : skip = 0 pt ,
+ right-skip : skip = 0 pt ,
+ start-skip : skip = 0 pt ,
+ 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_galley_justification_other_tl
+ \galley_set_interword_spacing:N \l_galley_fixed_spacing_bool
+ \bool_if:NTF \l_galley_par_stretch_last_bool
+ { \int_set_eq:NN \l_galley_last_line_fit_int \c_one_thousand }
+ { \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_galley_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_set_interword_space: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_start_skip
+ { \skip_use:N \l_galley_par_start_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_galley_justification_other_tl }
+ \AssignTemplateKeys
+ \galley_set_interword_spacing:N \l_galley_fixed_spacing_bool
+ \bool_if:NTF \l_galley_par_stretch_last_bool
+ { \int_set_eq:NN \l_galley_last_line_fit_int \c_one_thousand }
+ { \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 = 15 pt }
+\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 = 15 pt plus 1 fil ,
+ indent-width = 0 pt
+ }
+% \end{macrocode}
+% The other standard justification schemes are for text which is either
+% centred or 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 } { centered } { std }
+ {
+ end-skip = 0 pt ,
+ fixed-word-spacing = true ,
+ indent-width = 0 pt ,
+ left-skip = 0 pt plus 1 em ,
+ right-skip = 0 pt plus 1 em
+ }
+\DeclareInstance { justification } { ragged-left } { std }
+ {
+ end-skip = 0 pt ,
+ fixed-word-spacing = true ,
+ indent-width = 0 pt ,
+ left-skip = 0 pt plus 2 em ,
+ right-skip = 0 pt
+ }
+\DeclareInstance { justification } { ragged-right } { std }
+ {
+ end-skip = 0 pt plus 1 fil ,
+ fixed-word-spacing = true ,
+ indent-width = 0 pt ,
+ left-skip = 0 pt ,
+ right-skip = 0 pt plus 2 em
+ }
+% \end{macrocode}
+% The \texttt{centering} instance is used to centre material without
+% hyphenation: this is used for centring arbitrary material rather
+% than text.
+% \begin{macrocode}
+\DeclareInstance { justification } { centering } { std }
+ {
+ end-skip = 0 pt ,
+ fixed-word-spacing = true ,
+ indent-width = 0 pt ,
+ left-skip = 0 pt plus 1 fil ,
+ right-skip = 0 pt plus 1 fil
+ }
+% \end{macrocode}
+%
+% \begin{macro}{\galley_justification_first:, \galley_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 = \galley_justification_first: ,
+ other-paragraphs = \galley_justification_other:
+ }
+ {
+ \AssignTemplateKeys
+ \galley_justification_first:
+ \tl_set:Nn \l_galley_justification_other_tl
+ { \galley_justification_other: }
+ \tl_gput_right:Nn \g_galley_restore_running_tl
+ { \l_galley_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 = 10 000 ,
+ emergency-stretch : skip = 0 pt ,
+ final-hyphen-demerits : integer = 5000 ,
+ fuzz : length = 0.1 pt ,
+ line-penalty : integer = 10 ,
+ mismatch-demerits : integer = 10 000 ,
+ pretolerance : integer = 100 ,
+ relation-penalty : integer = 500 ,
+ tolerance : integer = 200
+ }
+\DeclareTemplateCode{ line-breaking } { std } { 0 }
+ {
+ badness = \l_galley_linebreak_badness_int ,
+ binop-penalty = \l_galley_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_galley_linebreak_penalty_int ,
+ mismatch-demerits = \l_galley_mismatch_demerits_int ,
+ pretolerance = \l_galley_linebreak_pretolerance_int ,
+ relation-penalty = \l_galley_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_galley_club_penalty_int ,
+% \l_galley_display_club_penalty_int ,
+% \l_galley_display_widow_penalty_int ,
+% \l_galley_interline_penalty_int ,
+% \l_galley_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.1 pt ,
+ interline-penalty : integer = 0 ,
+ post-display-penalty : integer = 0 ,
+ pre-display-penalty : integer = 10 000 ,
+ widow-penalty : integer = 150
+ }
+\DeclareTemplateCode { paragraph-breaking } { std } { 0 }
+ {
+ badness = \l_galley_parbreak_badness_int ,
+ broken-penalty = \l_galley_broken_penalty_int ,
+ club-penalty = \l_galley_club_penalty_int ,
+ display-club-penalty = \l_galley_display_club_penalty_int ,
+ display-widow-penalty = \l_galley_display_widow_penalty_int ,
+ fuzz = \l_galley_parbreak_fuzz_dim ,
+ interline-penalty = \l_galley_interline_penalty_int ,
+ post-display-penalty = \l_galley_post_display_penalty_int ,
+ pre-display-penalty = \l_galley_pre_display_penalty_int ,
+ widow-penalty = \l_galley_widow_penalty_int
+ }
+ {
+ \AssignTemplateKeys
+ \galley_set_club_penalties:V \l_galley_club_penalty_int
+ \galley_set_display_club_penalties:V \l_galley_display_club_penalty_int
+ \galley_set_display_widow_penalties:V \l_galley_display_widow_penalty_int
+ \galley_set_interline_penalty:n \l_galley_interline_penalty_int
+ \galley_set_widow_penalties:V \l_galley_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_galley_parbreak_badness_tl ,
+% \l_galley_broken_penalty_tl ,
+% \l_galley_club_penalties_tl ,
+% \l_galley_display_club_penalties_tl ,
+% \l_galley_display_widow_penalties_tl ,
+% \l_galley_parbreak_fuzz_tl ,
+% \l_galley_interline_penalty_tl ,
+% \l_galley_post_display_penalty_tl ,
+% \l_galley_pre_display_penalty_tl ,
+% \l_galley_widow_penalties_tl ,
+% \c_galley_parbreak_multi_seq ,
+% \c_galley_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_galley_parbreak_badness_tl ,
+ broken-penalty = \l_galley_broken_penalty_tl ,
+ club-penalty = \l_galley_club_penalties_tl ,
+ display-club-penalty = \l_galley_display_club_penalties_tl ,
+ display-widow-penalty = \l_galley_display_widow_penalties_tl ,
+ fuzz = \l_galley_parbreak_fuzz_tl ,
+ interline-penalty = \l_galley_interline_penalty_tl ,
+ post-display-penalty = \l_galley_post_display_penalty_tl ,
+ pre-display-penalty = \l_galley_pre_display_penalty_tl ,
+ widow-penalty = \l_galley_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_galley_interline_penalty_tl
+ {
+ \tl_gput_right:Nx \g_galley_par_after_hook_tl
+ {
+ \int_set:Nn \exp_not:N \l_galley_interline_penalty_int
+ { \galley_interline_penalty: }
+ }
+ \int_set:Nn \l_galley_interline_penalty_int
+ { \l_galley_interline_penalty_tl }
+ }
+ \tl_if_empty:NF \l_galley_parbreak_fuzz_tl
+ {
+ \tl_gput_right:Nx \g_galley_par_after_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_galley_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_galley_parbreak_single_seq
+ {
+ \tl_if_empty:cF { l_galley_ ##1 _tl }
+ {
+ \tl_gput_right:Nx \g_galley_par_after_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.
+% \begin{macrocode}
+ \seq_map_inline:Nn \c_galley_parbreak_multi_seq
+ {
+ \tl_if_empty:cF { l_galley_ ##1 _tl }
+ {
+ \use:c { galley_save_ ##1 :N } \l_galley_tmpa_clist
+ \tl_gput_right:Nx \g_galley_par_after_hook_tl
+ {
+ \exp_not:c { galley_set_ ##1 :n }
+ { \exp_not:o \l_galley_tmpa_clist }
+ }
+ \use:c { galley_set_ ##1 :v } { l_galley_ ##1 _tl }
+ }
+ }
+ }
+\seq_new:N \c_galley_parbreak_multi_seq
+\seq_gput_right:Nn \c_galley_parbreak_multi_seq { club_penalties }
+\seq_gput_right:Nn \c_galley_parbreak_multi_seq { display_club_penalties }
+\seq_gput_right:Nn \c_galley_parbreak_multi_seq { display_widow_penalties }
+\seq_gput_right:Nn \c_galley_parbreak_multi_seq { widow_penalties }
+\seq_new:N \c_galley_parbreak_single_seq
+\seq_gput_right:Nn \c_galley_parbreak_single_seq { parbreak_badness }
+\seq_gput_right:Nn \c_galley_parbreak_single_seq { broken_penalty }
+\seq_gput_right:Nn \c_galley_parbreak_single_seq { post_display_penalty }
+\seq_gput_right:Nn \c_galley_parbreak_single_seq { 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}
+%
+% \subsection{\LaTeXe{} functions}
+%
+% \begin{macro}{\nobreak}
+% \begin{macro}{\noindent}
+% \begin{macro}{\vspace}
+% In package mode, some of \LaTeXe{}'s functions are re-implemented using
+% the galley system. Not all of the optional arguments currently work!
+% \begin{macrocode}
+\RenewDocumentCommand \nobreak { }
+ { \bool_gset_true:N \g_galley_no_break_next_bool }
+\RenewDocumentCommand \noindent { }
+ { \bool_gset_false:N \g_galley_omit_next_indent_bool }
+\RenewDocumentCommand \vspace { s m } { \galley_set_vspace_user:n {#2} }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex
diff --git a/Master/texmf-dist/source/latex/l3experimental/xgalley/xgalley.ins b/Master/texmf-dist/source/latex/l3experimental/xgalley/xgalley.ins
new file mode 100644
index 00000000000..cadc1d2a98f
--- /dev/null
+++ b/Master/texmf-dist/source/latex/l3experimental/xgalley/xgalley.ins
@@ -0,0 +1,41 @@
+\iffalse meta-comment
+
+File xgalley.ins Copyright (C) 2010,2011 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
+
+ http://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 released version of this bundle is available from CTAN.
+
+\fi
+
+\input docstrip.tex
+\askforoverwritefalse
+
+\preamble
+
+EXPERIMENTAL CODE
+
+Do not distribute this file without also distributing the
+source files specified above.
+
+Do not distribute a modified version of this file.
+
+\endpreamble
+% stop docstrip adding \endinput
+\postamble
+\endpostamble
+
+\keepsilent
+
+\generate{\file{l3galley.sty}{\from{l3galley.dtx}{package}}}
+\generate{\file{xgalley.sty} {\from{xgalley.dtx} {package}}}
+
+\endbatchfile