% \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 2938 2011-10-25 18:41:20Z 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_tl}
%   Token list for whatsits to be inserted at the very end of the last
%   paragraph started.
% \end{variable}
% 
% \section{Additional effects}
%
% \begin{function}{\galley_end_par:n}
%   \begin{syntax}
%     \cs{galley_end_par:n} \Arg{tokens}
%   \end{syntax}
%   Adds the \meta{tokens} to the material collected for the last paragraph
%   before finalising the last paragraph in the usual way. This function should
%   therefore be the \emph{first} non-expandable entry used when a function
%   needs to add tokens to the preceding paragraph.
% \end{function}
%
% \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{TO BE MOVED}
%
% \begin{macro}{\scan_marker_new:N, \scan_marker_new:c}
% Temporary: needs to go somewhere else if this concept is retained.
%    \begin{macrocode}
\cs_new_protected:Npn \scan_marker_new:N #1
  { \cs_new_eq:NN #1 \scan_stop: }
\cs_generate_variant:Nn \scan_marker_new:N { c }
%    \end{macrocode}
% \end{macro}
%
% \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
%    \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_whatsit_previous_tl
    \tl_gclear:N \g_galley_whatsit_next_tl
  }
\galley_initialise_variables:
%    \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_whatsit_previous_tl
      \g_galley_whatsit_previous_tl
    \tl_set_eq:NN \l_galley_whatsit_next_tl
      \g_galley_whatsit_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_whatsit_previous_tl
      \l_galley_whatsit_previous_tl
    \tl_gset_eq:NN \g_galley_whatsit_next_tl
      \l_galley_whatsit_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{variable}{\s_par_omit}
%   Used to indicate that a paragraph should be omitted.
%    \begin{macrocode}
\scan_marker_new:N \s_par_omit
%    \end{macrocode}
% \end{variable}
%
% \begin{macro}{\galley_std_par:}
% \begin{macro}[aux]{\galley_std_par_aux_i:, \galley_std_par_aux_ii:}
% \begin{macro}[aux]{\galley_std_par_aux:N}
%   The idea here is to expand the next token in exactly the same way as \TeX{}
%   would do anyway. The \texttt{f}-type expansion will ignore any protection,
%   but will stop at a scan marker. Thus the code can test for an
%   \enquote{omit paragraph} marker.
%    \begin{macrocode}
\cs_new_protected_nopar:Npn \galley_std_par:
  {
    \s_par_omit
    \exp_after:wN \galley_std_par_aux_i: \tex_romannumeral:D - `0
  }
\cs_new_protected:Npn \galley_std_par_aux_i:
  {
    \peek_meaning:NTF \s_par_omit
      { \galley_std_par_aux:N }
      { \galley_std_par_aux_ii: }
  }
\cs_new_protected:Npn \galley_std_par_aux:N #1
  {
    \str_if_eq:xxF {#1} { \s_par_omit }
      {
        \galley_std_par_aux_ii:
        #1
      }
  }
%    \end{macrocode}
%   No marker, so really insert a paragraph. In vertical mode, 
%    \begin{macrocode}
\cs_new_protected_nopar:Npn \galley_std_par_aux_ii:
  {
    \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}
% \end{macro}
% \end{macro}
% 
% \begin{macro}{\galley_end_par:n}
%   Inserts tokens such that they are appended to the end of the last
%   paragraph, using the paragraph-omitting system.
%    \begin{macrocode}
\cs_new_protected:Npn \galley_end_par:n #1
  {
    \s_par_omit
    \bool_if:nF \g_galley_begin_level_bool
      {
        #1
        \galley_std_par:
      }
  }
%    \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:NF \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_false: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{} functions}
% 
%    \begin{macrocode}
%<*package>
%    \end{macrocode}
%
% \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}
\cs_set_protected_nopar:Npn \nobreak
  { \bool_gset_true:N \g_galley_no_break_next_bool }
%    \end{macrocode}
%  The \tn{noindent} primitive will causes problems, as it is used by
%  \LaTeXe{} documents to implicitly leave vertical mode as well as to
%  prevent indentation. Rather than patch \emph{every} place where we
%  need leave vertical mode, at the moment we stick with the primitive as
%  well as setting the galley flag.
%    \begin{macrocode}
\cs_set_protected_nopar:Npn \noindent
  {
    \tex_noindent:D
    \bool_gset_false:N \g_galley_omit_next_indent_bool
  }
\cs_set_protected_nopar:Npn \vspace #1
  {
    \@ifstar
      { \galley_set_user_vspace:n {#1} }
      { \galley_set_user_vspace:n {#1} }
  }
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \subsection{\LaTeXe{} fixes}
%
% 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}{\@@par}
%   The primitive is moved as otherwise the clever skipping code will fail.
%    \begin{macrocode}
\cs_set_eq:NN \@@par \galley_std_par:
%    \end{macrocode}
% \end{macro}
%
% \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
  {
    \bool_gset_true:N \g_galley_omit_next_indent_bool
    \leavevmode
    \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 \g_galley_omit_next_indent_bool
    \box \@tempboxa
  }
%    \end{macrocode}
% \end{macro}
%
%    \begin{macrocode}
%</package>
%    \end{macrocode}
%
%    \begin{macrocode}
%</initex|package>
%    \end{macrocode}
%
% \end{implementation}
%
% \PrintIndex