% \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> \documentclass[full]{l3doc} \usepackage{gatherenum} \begin{document} \DocInput{\jobname.dtx} \end{document} % % \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} % % \end{macrocode} % % \end{implementation}