summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/gatherenum/gatherenum.dtx
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /macros/latex/contrib/gatherenum/gatherenum.dtx
Initial commit
Diffstat (limited to 'macros/latex/contrib/gatherenum/gatherenum.dtx')
-rw-r--r--macros/latex/contrib/gatherenum/gatherenum.dtx307
1 files changed, 307 insertions, 0 deletions
diff --git a/macros/latex/contrib/gatherenum/gatherenum.dtx b/macros/latex/contrib/gatherenum/gatherenum.dtx
new file mode 100644
index 0000000000..dec13ca1ab
--- /dev/null
+++ b/macros/latex/contrib/gatherenum/gatherenum.dtx
@@ -0,0 +1,307 @@
+% \iffalse meta-comment
+% vim: tw=80 spl=en
+%
+%% File: gatherenum.dtx (C) Copyright 2016-2018 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}[2016/01/19]
+\def\ExplFileName{gatherenum}
+\def\ExplFileDescription{Crossover between align* and enumerate}
+\def\ExplFileDate{2018/06/19}
+\def\ExplFileVersion{1.7}
+%</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
+ \begin{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 } {
+ \end{gatherenum}
+ \unskip
+ \int_set_eq:NN \clubpenalty \interlinepenalty
+ \int_set_eq:NN \widowpenalty \interlinepenalty
+ \par
+ }{
+ \@@_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}