% \iffalse meta-comment
% vim: tw=80 spl=en
%
%% File: gatherenum.dtx (C) Copyright 2016-2019 RIVAUD Julien
%%
%% It may be distributed and/or modified under the conditions of the
%% General Public License (GPL), either version 3 of this
%% license or (at your option) any later version.
%
%<*driver|package>
% The version of expl3 required is tested as early as possible, as
% some really old versions do not define \ProvidesExplPackage.
\NeedsTeXFormat{LaTeX2e}[1995/12/01]
\RequirePackage{expl3}[2018/06/19]
\def\ExplFileName{gatherenum}
\def\ExplFileDescription{Crossover between align* and enumerate}
\def\ExplFileDate{2019/09/29}
\def\ExplFileVersion{1.8}
%</driver|package>
%<*driver>
\documentclass[full]{l3doc}
\usepackage{gatherenum}
\begin{document}
  \DocInput{\jobname.dtx}
\end{document}
%</driver>
% \fi
%
% \title{^^A
%   The \textsf{\ExplFileName} package\\
%   Gathered, display-like \env{enumerate}^^A
%   \thanks{This file describes v\ExplFileVersion,
%     last revised \ExplFileDate.}^^A
% }
%
% \author{^^A
%  Julien ``\_FrnchFrgg\_'' \textsc{Rivaud}\thanks
%    {^^A
%      E-mail:
%        \href{mailto:frnchfrgg@free.fr}
%             {frnchfrgg@free.fr}^^A
%    }^^A
% }
%
% \date{Released \ExplFileDate}
%
% \maketitle
%
% \begin{documentation}
%
% \section{Documentation}
%
% \subsection{Package description}
%
% This package (ab)uses the inline enumeration capabilities of \pkg{enumitem} to
% add a ``displayed'' enumeration mode, triggered by adding |gathered| to the
% key-val option list of the \env{enumerate} environment.
%
% The end result is similar to The end result is similar to a regular enumerate
% environment wrapped in a multicols environment, with the following advantages:
% \begin{itemize}
%   \item \emph{gathered} enumerate can pack items depending on their actual
%       width rather than a fixed, constant number per line;
%   \item it fills items in a line-major order (instead of column-major order),
%       which my students found less confusing.Your mileage may vary.
% \end{itemize}
%
% All settings of the standard enumeration that are relevant still apply to the
% gathered mode --- which would not have been the case with a separate
% inline enumeration like the \env{enumerate*} provided by \pkg{enumitem}.
%
% Individual items are separately boxed, to mimic the behavior of \env{align}.
% This package is not for you if you want free-flow enumeration in a paragraph,
% since \pkg{enumitem} already provides a reasonable one, and you probably do
% not want to share that many settings with regular \env{enumerate} due to the
% very different nature and look of inline enumerations.
%
% Say:
%\begin{verbatim}
% \setlist{enumerate}{label=\arabic*.}
% \begin{enumerate}
%   \item Test
%   \item $\int_a^b$ with math
%   \item And another
%   \item $f(x) = 6$
%   \item $D(t) = 0$
%   \item $d$~and~$d'$ are parallel
% \end{enumerate}
%\end{verbatim}
% produces:
% \setlist[enumerate]{label=\arabic*.}
% \begin{enumerate}
%   \item Test
%   \item $\int_a^b$ with math
%   \item And another
%   \item $f(x) = 6$
%   \item $D(t) = 0$
%   \item $d$~and~$d'$ are parallel
% \end{enumerate}
%
% Then:
%\begin{verbatim}
% \begin{enumerate}[gathered]
%   \item Test
%   \item $\int_a^b$ with math
%   \item And another
%   \item $f(x) = 6$
%   \item $D(t) = 0$
%   \item $d$~and~$d'$ are parallel
% \end{enumerate}
%\end{verbatim}
% will produce:
% \begin{enumerate}[gathered]
%   \item Test
%   \item $\int_a^b$ with math
%   \item And another
%   \item $f(x) = 6$
%   \item $D(t) = 0$
%   \item $d$~and~$d'$ are parallel
% \end{enumerate}
%
% \subsection{Customizing}
%
% Most of the changes are in fact done through the usual \pkg{enumitem}
% interface. |itemjoin| can be a useful setting to tweak. \pkg{gatherenum}
% provides several additional options:
%
% \begin{itemize}[noitemsep]
%   \item |gatherformat| this is put just before every item content; the last
%       token in that option can take an argument, which will be the unboxed
%       item content.  Note that since the item has already been typeset in an
%       horizontal box, you cannot change the font family, shape or size at that
%       point, but can add a frame around for instance.
%   \item |center| display the items in a centered paragraph. This is the most
%       display-like and is the default. Equivalent to |before*=\centering|.
%   \item |alignleft| display the items in a left-aligned paragraph.\\
%       Equivalent
%       to |before*=\raggedright|.
% \end{itemize}
%
% Lastly, an example of something I use a lot:
%
% \bigskip
% \hrule\medskip
% Compute the following:
% \begin{enumerate}[gathered, label={$\alph* = {}$}, labelsep=0pt]
%   \item $1+1$
%   \item $\sin\left( 2\pi + \frac{\pi}{3} \right)$
%   \item $\displaystyle \int_0^{+\infty} \mathrm{e}^{-t^2} \mathrm{d}t$
%   \item $\varphi(52330)$
% \end{enumerate}
% \medskip\hrule
% \begin{verbatim}
% Compute the following:
% \begin{enumerate}[gathered, label={$\alph* = {}$}, labelsep=0pt]
%   \item $1+1$
%   \item $\sin\left( 2\pi + \frac{\pi}{3} \right)$
%   \item $\displaystyle \int_0^{+\infty} \mathrm{e}^{-t^2} \mathrm{d}t$
%   \item $\varphi(52330)$
% \end{enumerate}
% \end{verbatim}
% \hrule
%
% \end{documentation}
%
% \begin{implementation}
%
% \section{\pkg{\ExplFileName} implementation}
%
%    \begin{macrocode}
%<*package>
%<@@=gatherenum>
%    \end{macrocode}
%
%    \begin{macrocode}
\ProvidesExplPackage
  {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
%    \end{macrocode}
%
%   We use \pkg{enumitem} as a base, and \pkg{xparse} to define our environment.
%    \begin{macrocode}
\RequirePackage{enumitem}
\RequirePackage{xparse}
%    \end{macrocode}
%
%   \pkg{enumitem} has a mechanism to make the \env{enumerate} environment use
%   settings and counters prefixed by \cs{enum} instead of \cs{enumerate}
%   (because that's what \LaTeX\ does). We take advantage of that to define our
%   internal enumeration, because we want to share settings and counter with
%   \env{enumerate} since we will act as an option of that environment.
%    \begin{macrocode}
\tl_set:Nn \enit@shortgatherenum {enum}
\newlist{gatherenum}{enumerate*}{3}
%    \end{macrocode}
%
%   Since \pkg{enumitem} inline enumerations are intended for pararaph-like
%   enumerations, the item content is unpacked with \cs{unhbox} even in
%   \emph{boxed} mode. That's not what we want, so we have to add another layer
%   of boxing. While we're at it, we add a formatting command for the user
%   to customize.
%    \begin{macrocode}
\tl_new:N \l@@_itemformat
\cs_new_protected_nopar:Nn \@@_boxitem: {
    \nobreak\skip_horizontal:n {\labelsep}
    \hbox_set:Nn \enit@inbox {
        \hbox:n {
            \l@@_itemformat{\hbox_unpack:N \enit@inbox}
        }
    }
}
\enitkv@key{enumitem}{gatherformat}{\tl_set:Nn\l@@_itemformat{#1}}
%    \end{macrocode}
%
%   Now is the time to change the enumerate environment. We save the start and
%   end of existing environment from \pkg{enumitem} to be able to fall back to
%   it.
%    \begin{macrocode}
\let\@@_save_enumerate:w\enumerate
\let\@@_save_endenumerate:w\endenumerate
\RenewDocumentEnvironment{enumerate}{ O{} }{
%    \end{macrocode}
%
%   The trigger for gathered enumeration is the \texttt{gathered} option given
%   by the user in the list of local options. If there is no such option, we
%   directly use the original \cs{endenumerate}.
%
%    \begin{macrocode}
    \clist_if_in:nnTF { #1 } { gathered } {
%    \end{macrocode}
%
%   To act more display-like, we ensure that running heads that are not already
%   typeset are flushed now. This is especially important in the default
%   centered typesetting: we don't want to center the theorem or enumerate heads
%   along with our content.
%    \begin{macrocode}
        \if@inlabel
            \leavevmode
        \fi
        \par
        \centering
%    \end{macrocode}
%
%   Synchronise the current depth of gatherenum with that of enumerate
%   (oddly \cs{enit@shortgatherenum} doesn't imply that). That enables us to get
%   the right settings depending on depth (labels, mostly, since indention is
%   irrelevant here).
%    \begin{macrocode}
        \int_set_eq:NN \enitdp@gatherenum \enitdp@enumerate
%    \end{macrocode}
%
%   Insert a display-like penalty, and start our inline enumeration. Since
%   setting defaults for gatherenum would clobber (or a least mess with)
%   the settings of normal enumerate, we give them here using the optional
%   argument (recall that they share most counters and settings).
%
%   We use a trivial align mode to ensure \pkg{enumitem} doesn't try to apply
%   indention, alignment or spacing effects to the label. \meta{afterlabel} is
%   a hook that enumitem calls after closing the \cs{hbox} with item content,
%   after typesetting the label, but before unboxing the content. We use
%   \cs{@@_boxitem:} defined before to ensure the content stays
%   boxed.
%    \begin{macrocode}
        \penalty \predisplaypenalty
        \gatherenum[
            itemjoin=\skip_horizontal:n{1em plus 1fil},
            #1,
            mode=boxed,
            align=none,
            afterlabel=\@@_boxitem:,
        ]
    }{
        \@@_save_enumerate:w[#1]
    }
}{
%    \end{macrocode}
%
%   Finish the environment, either by closing the standard \env{enumerate}, or
%   by ending our horizontal enumeration, and closing the paragraph. We are
%   less strict on widows and clubs than normal.
%    \begin{macrocode}
    \clist_if_in:nnTF { #1 } { gathered } {
        \endgatherenum
        \unskip
        \int_set_eq:NN \clubpenalty \interlinepenalty
        \int_set_eq:NN \widowpenalty \interlinepenalty
        \use:c{@ @ par}% avoid l3docstrip replacement of @
    }{
        \@@_save_endenumerate:w
    }
}
%    \end{macrocode}
%
%   Last touches: a \texttt{gathered} key for \pkg{enumitem} so that it doesn't
%   complain when it sees it (this enables us to keep the key in the list
%   instead of filtering it with \cs{clist_remove_all:Nn}). Next is the trivial
%   align mode we talked about earlier, and at last some shorthands for common
%   layouts.
%
%    \begin{macrocode}
\SetEnumitemKey{gathered}{}
\SetLabelAlign{none}{#1}
\SetEnumitemKey{centered}{before*=\centering}
\SetEnumitemKey{alignleft}{before*=\raggedright}
%</package>
%    \end{macrocode}
%
% \end{implementation}
