% \iffalse meta-comment %% File: latex-lab-block.dtx (C) Copyright 2021-2026 LaTeX 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 % % https://www.latex-project.org/lppl.txt % \def\ltlabenumdate{2026-04-21} \def\ltlabenumversion{0.80f} %<*driver> \DocumentMetadata{tagging=on,pdfstandard=ua-2} \documentclass[kernel]{l3in2edoc} \usepackage{longtable,tikz} \EnableCrossrefs \CodelineIndex \usepackage{todonotes} \begin{document} \DocInput{latex-lab-enumitem.dtx} \end{document} % % % \fi % % % \title{The \textsf{latex-lab-enumitem} package\\ % Emulating enumitem} % \author{\LaTeX{} Project\thanks{Initial implementation done by Ulrike Fischer}} % \date{v\ltlabenumversion\ \ltlabenumdate} % % \maketitle % % \newcommand{\xt}[1]{\textsl{\textsf{#1}}} % \newcommand{\TODO}[1]{\textbf{[TODO:} #1\textbf{]}} % \newcommand{\docclass}{document class \marginpar{\raggedright document class % customizations}} % % \newcommand\insttype[1]{\texttt{#1}} % % % \providecommand\hook[1]{\texttt{#1}} % % \ProvideDocumentCommand\fmi{sO{}m} % {\IfBooleanTF{#1}{\todo[inline,#2]{#3}}^^A % {\todo[#2]{#3}}} % % % % \begin{abstract} % The following code implements an emulation of \pkg{enumitem} usable with the Tagging Support Code. % It does \emph{not} emulate every key and command of enumitem. Also syntax and behaviour % can differ in place. % \end{abstract} % % % \section{Introduction} % % The \pkg{enumitem} package offers customizable and enhanced list environments % but is not compatible with the Tagging Support Code where lists are % reimplemented with templates. % % The following code partly emulates \pkg{enumitem} and should be loaded % instead of the package. % % \section{Key emulation} % % A large part of the \pkg{enumitem} functionality is provided through keys. Such keys % can be set in the optional argument of single lists and globally for some or all % lists in the \cs{setlist} command. Some keys are simple interfaces to list parameters, % other have quite complicated effects, e.g. if they force recalculations of dependant % parameters. % % With the new \LaTeX implementation lists do have an optional argument too % which process a key-value list. % The key names differ to the one of \pkg{enumitem} but in a number of cases a % simple mapping is possible. The \LaTeX{} key names are noted in the following % tabular in the second column. % They can be used instead of the \pkg{enumitem} keys (and will be a bit faster). % The third column shows if the \pkg{enumitem} key has been already emulated and is usable % in the optional argument. The fourth column shows if it is usable in \cs{setlist}. % % % \begin{longtable}{>{\ttfamily}l>{\ttfamily}lcll} % \caption{List of enumitem keys}\\ % \rmfamily \pkg{enumitem} key & \rmfamily \LaTeX{} key & opt.\ arg. & \cs{setlist} & comment\\ \hline \endhead % label & \rmfamily (related: \texttt{item-label}) & & &see key description\\ % label*\\ % ref \\ % font,format & label-format & yes & & see key description!! \\ % format\\ % align & label-align & yes & & see key description\\ % topsep & begin-vspace & yes & & \\ % partopsep & begin-extra-vspace & yes & & \\ % parsep & para-vspace & yes & & \\ % itemsep & item-vspace & yes & & \\ % labelindent\\ % labelindent*\\ % leftmargin & left-margin & & & see key description\\ % rightmargin & right-margin & & & see key description\\ % listparindent & para-indent & & & see key description\\ % itemindent & item-indent & & & see key description\\ % labelsep & label-sep & & & see key description\\ % labelsep* \\ % labelwidth & label-width & & & see key description \\ % left \\ % widest \\ % widest*\\ % start & start & yes & ? \\ % resume & resume & yes & ? & see key description\\ % resume* \\ % series\\ % beginpenalty & begin-penalty & yes & ?\\ % midpenalty & item-penalty & yes & ? \\ % endpenalty & end-penalty & yes & ?\\ % before \\ % before* \\ % after\\ % after*\\ % first\\ % first*\\ % style\\ % noitemsep & \textit{meta-key} & yes \\ % nosep & \textit{meta-key} & yes \\ % wide & & partly & \\ % itemjoin\\ % itemjoin*\\ % afterlabel\\ % mode\\ % \end{longtable} % % \section{Package options} % % \pkg{enumitem} has a number of package options, but none of them will % be supported by the emulation: adding support for the \pkg{enumerate} syntax % (\texttt{shortlabels}) is not planed; inline lists are not yet implemented % but once they are they will be available always. % % \begin{longtable}{lll} % \caption{List of enumitem package options}\\ % \pkg{enumitem} option \\\hline\endhead % shortlabels & \\ % inline & \\ % ignoredisplayed & \\ % series=override & \\ % sizes & \\ % loadonly & % \end{longtable} % % \section{Commands} % % \begin{longtable}{lll} % \caption{List of enumitem user commands}\\ % name & emulated & comment\\\hline\endhead % \cs{SetLabelAlign}\\ % \cs{DrawEnumitemLabel} \\ % \cs{labelindent}\\ % {\cs{EnumitemId}}\\ % {\cs{SetEnumitemKey}} & yes \\ % {\cs{SetEnumitemValue}}\\ % {\cs{SetEnumerateShortLabel}} \\ % \cs{newlist} & yes \\ % \cs{renewlist}\\ % \cs{setlist} & yes & no size-dependent settings\\ % \cs{setlistdepth}\\ % \cs{AddEnumerateCounter}\\ % \cs{restartlist}\\ % \cs{SetEnumitemSize} % \end{longtable} % % \section{Calculating values} % % When setting up the dimension of lists the values related to the left margin and % placement of the label are typically the most challenging as four dimensions are involved % (which can be negative). \pkg{enumitem} introduces a fifth dimension \cs{labelindent}. % % \begin{tikzpicture}[alt=List layout] % \coordinate(leftmargin) at (0,0); % \coordinate(labelleft) at (1,0); % \coordinate(labelright) at (4,14pt); % \draw (labelleft) rectangle (labelright); % \draw [<->] ([yshift=-5pt]labelleft) --++(3,0) node[below,midway]{\texttt{\textbackslash labelwidth}}; % \draw[<->]([yshift=-1cm]leftmargin)--++(6,0)node[below,midway]{\texttt{\textbackslash leftmargin}}; % \draw[<->](labelright)--++(2,0)node[above,midway]{\texttt{\textbackslash labelsep}}; % \draw[<->](5,-5pt)--++(1,0)node[below]{\texttt{\textbackslash itemindent}}; % \draw(5,0)--++(0,-2)--++(5,0)--++(0,2cm+14pt)--++(-4,0)--++(0,-14pt)--cycle; % \draw[<->](0,5pt)--++(1,0)node[above left]{\textit{\textbackslash labelindent}}; % \end{tikzpicture} % % The relation between the five values is set through the following equation: % % \verb!\labelindent + \labelwidth + \labelsep = \leftmargin + \itemindent! % % So obviously one of the dimensions is redundant and can be calculated if the others % are given. By default \pkg{enumitem} calculates the new, \enquote{fake} dimension % \cs{labelindent} but it is possible to give \cs{labelindent} a specific value % and declare that another one is calculated by using \texttt{!} as value. % % % Calculation should happen after all keys are set. The code here therefore executes a % key \texttt{calculate} in the list code which looks which key is currently the dependant % one and calculates its value. % % \pkg{enumitem} also offers an option to calculate \cs{labelwidth} based on the widest % entry (which can be declared with the \texttt{widest} key) by using a star \texttt{*} as % value. % % \section{Alignment} % % % % \begin{macrocode} %<*package> % \end{macrocode} % % \section{Implementation} % \begin{macrocode} \ProvidesExplPackage {latex-lab-enumitem} {\ltlabenumdate} {\ltlabenumversion} {Emulating enumitem} % \end{macrocode} % % % % \subsection{Key emulation} % % \subsubsection{\texttt{label}} % % \fmi{check all this code} % % The key \texttt{item-label} from the new \LaTeX{} list code % changes the label representation from e.g. \cs{labelenumi} % to the key value. Internally the representation of the current list is stored in % \cs{l__block_item_label_tl}. It does not change \cs{labelenumi}, \cs{theenumi} or % \cs{p@enumi} and so also doesn't affect references. % % The key \texttt{label} from \pkg{enumitem} works quite differently: it changes % the label representation command \cs{labelenumi}, the counter representation % \cs{theenumi} and sets \cs{p@enumi} to empty. So by default the reference is identical % to the label representation and if a different reference is wanted it must be set % with the \texttt{ref} key. To allow to use \cs{labelenumi} in nested list to create % chained labels enumitem replaces all \verb+\roman*+ by \verb+\roman{enumi}+ (and similar % for the other counter representations). The replacement code uses expansion and % so enumitem will error if the star is used with an unknown counter representation like % \verb+label=\fnsymbol*+ or \cs{alphalph}. Such unknown % counter representation must first be added with \cs{AddEnumerateCounter}. % % The new code is less fragile. Counter representation must only be declared with \cs{AddEnumerateCounter} % if the star-counter is used outside the current list (e.g. with the \texttt{label*} key. % % \begin{macrocode} %<@@=block> % we might want a different module in the end % \end{macrocode} % % At first a rather crude (slow) method to replace % e.g. \verb+\roman*+ by \verb+\roman{enumi}+ % in the label representation. TODO: speed up. % % \begin{macrocode} \clist_new:N \l_@@_normalize_cnt_clist \clist_set:Nn \l_@@_normalize_cnt_clist {\alph,\Alph,\roman,\Roman,\arabic,\fnsymbol} % \end{macrocode} % This command should only be used if \cs{l_@@_counter_tl} is not empty! % \begin{macrocode} \cs_new:Npn\@@_normalize_label:N #1 { \clist_map_inline:Nn\l_@@_normalize_cnt_clist { \tl_replace_all:Nne#1 {##1*}{\exp_not:N##1{\l_@@_counter_tl}} } } \cs_generate_variant:Nn\@@_normalize_label:N{c} % \end{macrocode} % % \begin{macrocode} \keys_define:nn{template/list/std} { label .code:n = { \tl_if_empty:NTF\l_@@_counter_tl { \tl_if_eq:NnTF\l_@@_inner_instance_tl{itemize} { \tl_set:cn{labelitem\int_to_roman:n{\l_@@_inner_level_counter_tl}}{#1} } { \tl_set:cn{label\l_@@_inner_instance_tl\int_to_roman:n{\l_@@_inner_level_counter_tl}}{#1} } } { \tl_set:cn{label\l_@@_counter_tl}{#1} \@@_normalize_label:c{label\l_@@_counter_tl} \tl_set_eq:cc{the\l_@@_counter_tl}{label\l_@@_counter_tl} \tl_set:cn{p@\l_@@_counter_tl}{} } } } % \end{macrocode} % % % % % \subsubsection{\texttt{label*}} % TODO: % % \subsubsection{\texttt{ref}} % TODO: % % \subsubsection{\texttt{font}, \texttt{format}} % % \begin{macrocode} \keys_define:nn{template/item/std} { font .meta:n = {label-format={#1{##1}}}} \keys_define:nn{template/item/std} { format .meta:n = {label-format={#1{##1}}}} % \end{macrocode} % % \subsubsection{\texttt{align}} % % Note: this also supports the value center but parleft is not implemented yet. % TODO: test for differences in behavior. % \begin{macrocode} \keys_define:nn{template/list/std} { align .meta:n = {label-align=#1}} % \end{macrocode} % % \subsubsection{\texttt{topsep}} % \begin{macrocode} \keys_define:nn{template/block/std} { topsep .meta:n = {begin-vspace=#1}} % \end{macrocode} % % \subsubsection{\texttt{partopsep}} % \begin{macrocode} \keys_define:nn{template/block/std} { partopsep .meta:n = {begin-extra-vspace=#1}} % \end{macrocode} % % \subsubsection{\texttt{parsep}} % \begin{macrocode} \keys_define:nn{template/block/std} { parsep .meta:n = {para-vspace=#1}} % \end{macrocode} % % \subsubsection{\texttt{itemsep}} % \begin{macrocode} \keys_define:nn{template/block/std} { itemsep .meta:n = {item-vspace=#1}} % \end{macrocode} % % \subsubsection{\texttt{leftmargin}} % TODO: handle special values ! and *.\\ % Special values do not work with \LaTeX{} key at the moment as it is a register! % \begin{macrocode} \keys_define:nn{template/block/std} { leftmargin .meta:n = {left-margin=#1}} % \end{macrocode} % % \subsubsection{\texttt{rightmargin}} % TODO: handle special values ! and *.\\ % Special values do not work with \LaTeX{} key! % \begin{macrocode} \keys_define:nn{template/block/std} { rightmargin .meta:n = {right-margin=#1}} % \end{macrocode} % % \subsubsection{\texttt{listparindent}} % TODO: handle special values ! and *.\\ % Special values do not work with \LaTeX{} key! % \begin{macrocode} \keys_define:nn{template/block/std} { listparindent .meta:n = {para-indent=#1}} % \end{macrocode} % % \subsubsection{\texttt{itemindent}} % TODO: handle special values ! and *.\\ % Special values do not work with \LaTeX{} key! % \begin{macrocode} \keys_define:nn{template/list/std} { itemindent .meta:n = {item-indent=#1}} % \end{macrocode} % % \subsubsection{\texttt{labelsep}, \texttt{labelsep*}} % TODO: handle special values ! and *.\\ % Special values do not work with \LaTeX{} key! % \begin{macrocode} \keys_define:nn{template/list/std} { labelsep .meta:n = {label-sep=#1}} % \end{macrocode} % % \subsubsection{\texttt{labelwidth}} % TODO: handle special values ! and *.\\ % Special values do not work with \LaTeX{} key! % \begin{macrocode} \keys_define:nn{template/list/std} { labelwidth .meta:n = {label-width=#1}} % \end{macrocode} % % \subsubsection{\texttt{labelindent}, \texttt{labelindent*}} % TODO:, see also \cs{labelindent}, note special value ! and * % % \subsubsection{\texttt{left}} % TODO: % % \subsubsection{\texttt{widest}, \texttt{widest*}} % TODO: % % \subsubsection{\texttt{start}} % TODO: Test with setlist % % \subsubsection{\texttt{resume}} % TODO: Test with setlist.\\ % The behavior of the key is different to enumitem, % where grouping of the environments matters: in \pkg{enumitem} % a enumerate that is e.g. in quote environment can not be resumed outside of the quote. % With the \LaTeX{} code grouping does not matter. % % \subsubsection{\texttt{resume*}} % TODO: decide if it should be implemented % % \subsubsection{\texttt{series}} % TODO: decide if it should be implemented % % \subsubsection{\texttt{beginpenalty}, \texttt{midpenalty}, \texttt{endpenalty}} % \begin{macrocode} \keys_define:nn{template/block/std} { beginpenalty .meta:n = {begin-penalty=#1}, endpenalty .meta:n = {end-penalty=#1}, midpenalty .meta:n = {item-penalty=#1} } % \end{macrocode} % % \subsubsection{\texttt{before}, \texttt{before*}} % TODO: describe behavior (second argument of list does not make sense) % Implement with hooks? % % \subsubsection{\texttt{after}, \texttt{after*}} % TODO: implement with hooks? % % \subsubsection{\texttt{first}, \texttt{first*}} % TODO: implement with hooks? % % \subsubsection{\texttt{style}} % TODO: values for description lists: standard, unboxed, nextline, sameline, multiline % % \subsubsection{\texttt{noitemsep}, \texttt{nosep}} % \begin{macrocode} \keys_define:nn{template/blockenv/std} { nosep .meta:n = { begin-vspace=0pt, begin-extra-vspace=0pt, end-vspace=0pt, end-extra-vspace=0pt, item-vspace=0pt, para-vspace=0pt } } \keys_define:nn{template/blockenv/std} { noitemsep .meta:n = { item-vspace=0pt, para-vspace=0pt } } % \end{macrocode} % % % \subsubsection{\texttt{wide}} % TODO: calculated value should be delayed ... % \begin{macrocode} \keys_define:nn{template/blockenv/std} { wide .meta:n = { label-align=left, para-indent=#1, left-margin=0pt, label-width=0pt, item-indent=\dimeval{#1+\labelsep} %should be delayed .... }, wide .default:n = \parindent } % \end{macrocode} % % % \subsubsection{\texttt{itemjoin}, \texttt{itemjoin*}, \texttt{afterlabel}} % TODO % % \subsubsection{\texttt{mode}} % TODO % % % % \subsection{Package options} % % % \subsubsection{\texttt{shortlabels}} % % % \subsubsection{\texttt{inline}} % TODO, creates three environments enumerate*, itemize* and description* % % % \subsubsection{\texttt{sizes}} % % % \subsubsection{\texttt{loadonly}} % % % % %\subsection{Command emulation} % %\subsubsection{\cs{SetLabelAlign}} % % %\subsubsection{\cs{DrawEnumitemLabel}} % % %\subsubsection{\cs{labelindent}} % see also key labelindent % % %\subsubsection{\cs{EnumitemId}} % % %\subsubsection{\cs{SetEnumitemKey}} % % The \cs{SetEnumitemKey} defines shortcuts. We can defines them as % \texttt{.meta:n} on the \insttype{block} level. If they are for % the inner instances, they get passed down as necessary (this is % slightly less efficient than defining them at the right level, % but makes life easier). % \begin{macrocode} \NewDocumentCommand \SetEnumitemKey {mm} { \keys_define:nn { template/block/std } { #1 .meta:n = { #2 } } } % \end{macrocode} % % As an example, something like \texttt{noitemsep} could have been defined as %\begin{verbatim} % \SetEnumitemKey{noitemsep}{ itemsep=0pt, parsep=0pt } %\end{verbatim} % And this can even be done recursively, e.g., %\begin{verbatim} % \SetEnumitemKey{nosep} { noitemsep, topsep=0pt, partopsep=0pt } %\end{verbatim} % % %\subsubsection{\cs{SetEnumitemValue}} % % %\subsubsection{\cs{SetEnumerateShortLabel}} % % %\subsubsection{\cs{newlist}} % % The \cs{newlist} command allows to define new lists which clones the % standard lists. The last number describes the maximum number of levels. % Note that with itemize and description at most 6 levels are allowed. % This could be changed with % \begin{verbatim} % \setcounter{maxblocklevels}{7} % \DeclareInstance{block}{std-list-7}{display}{} % \end{verbatim} % but as enumitem doesn't allow more levels either the code does not force it. % % Below is another implementation that supports arbitrarily many % levels. At some point we need to decide what we want to do here % and unify the code. Right now both sample implementations have % their restrictions. % % \begin{macro}{\newlist} % \begin{macrocode} \NewDocumentCommand\newlist{mmm} %name, type, number { \str_case:nnF{#2} { {itemize} {\@@_setup_itemize:nn{#1}{#3}} {enumerate} {\@@_setup_enumerate:nn{#1}{#3}} {description}{\@@_setup_description:nn{#1}{#3}} } % \end{macrocode} % TODO: message % \begin{macrocode} {\typeout{unknown~list~type~#2} } % \end{macrocode} % TODO: For supporting \cs{setlist} we need to set up \cs{enitdp@\#1} if we % use this implementation. % \begin{macrocode} } % % \end{macrocode} % \end{macro} % % \begin{macro}{\@@_setup_itemize:nn} % \changes{v0.80e}{2026/02/16}{Allow spaces before the optional argument (tagging/1237)} % \begin{macrocode} \cs_new_protected:Npn \@@_setup_itemize:nn #1#2 %#1 name of new list, #2 max levels { \DeclareInstanceCopy{blockenv}{#1}{itemize} \EditInstance{blockenv}{#1}{inner-instance=#1} \NewDocumentEnvironment{#1}{O{}} { \SimpleBlockEnv {#1} {max-inner-levels= \int_min:nn{\c@maxblocklevels}{#2},##1} } { \BlockEnvEnd } \int_step_inline:nnn{1}{\int_min:nn{\c@maxblocklevels}{#2}} { \IfInstanceExistsTF{list}{itemize-##1} { \DeclareInstanceCopy{list}{#1-##1}{itemize-##1} } % \end{macrocode} % The default label for lists below 4 is simply \cs{labelitemi}. % \begin{macrocode} { \ExpandArgs{c} \providecommand{labelitem\int_to_roman:n{##1}}{\labelitemi} \DeclareInstance{list}{#1-##1}{std} { item-label = \use:c{labelitem\int_to_roman:n{##1}}} } } } % \end{macrocode} % \end{macro} % % \begin{macro}{\@@_setup_description:nn} % \changes{v0.80e}{2026/02/16}{Allow spaces before the optional argument (tagging/1237)} % \begin{macrocode} \cs_new_protected:Npn \@@_setup_description:nn #1#2 { \DeclareInstanceCopy{blockenv}{#1}{description} \EditInstance{blockenv}{#1}{inner-instance=#1} \DeclareInstanceCopy{list}{#1}{description} \NewDocumentEnvironment{#1}{O{}} { \SimpleBlockEnv{#1} {max-inner-levels= \int_min:nn{\c@maxblocklevels}{#2},##1} } { \BlockEnvEnd } } % \end{macrocode} % \end{macro} % % \begin{macro}{\@@_setup_enumerate:nn} % \changes{v0.80e}{2026/02/16}{Allow spaces before the optional argument (tagging/1237)} % \begin{macrocode} \cs_new_protected:Npn \@@_setup_enumerate:nn #1#2 { \DeclareInstanceCopy{blockenv}{#1}{enumerate} \EditInstance{blockenv}{#1}{inner-instance=#1} \NewDocumentEnvironment{#1}{O{}} { \SimpleBlockEnv {#1} {max-inner-levels= #2,##1} } { \BlockEnvEnd } \int_step_inline:nnn{1}{#2} { \newcounter{#1\int_to_roman:n{##1}} \ExpandArgs{c} \newcommand{label#1\int_to_roman:n{##1}} {\arabic{#1\int_to_roman:n{##1}}.} \DeclareInstance{list}{#1-##1}{std} { item-label = \use:c{label#1\int_to_roman:n{##1}} , counter = {#1\int_to_roman:n{##1}} } } } % \end{macrocode} % \end{macro} % % % % \begin{macro}{\newlist} % This is an alternative implementation (not necessarily better). % \changes{v0.80e}{2026/02/16}{Alternative implementation for \cs{newlist}} % \begin{macrocode} \cs_set_protected:Npn \newlist #1#2#3 { \DeclareDocumentEnvironment {#1} { !O{} } { \SimpleBlockEnv {#1}{##1} } { \BlockEnvEnd } % \DeclareInstanceCopy {blockenv} {#1} {#2} % % If #3 > maxblocklevels add additional std-list instances as necessary % \int_compare:nNnT { \value{maxblocklevels} } < {#3} { \int_step_inline:nnn { \value{maxblocklevels} + 1 } {#3} { \DeclareInstanceCopy {block} {std-list-##1} {std-list-\int_eval:n{ ##1 - 1 }} % not sure if we should set up those as well ... \DeclareInstanceCopy {block} {std-display-##1} {std-display-1} \DeclareInstanceCopy {block} {quote-##1} {quote-1} \DeclareInstanceCopy {block} {quotation-##1} {quotation-1} \DeclareInstanceCopy {block} {verbatim-##1} {verbatim-1} } \setcounter{maxblocklevels}{#3} } % \IfInstanceExistsTF{list}{#2} % no levels (as with description) { \EditInstance {blockenv} {#1} { name = #1 ,inner-instance = #1 } % \DeclareInstanceCopy {list} {#1} {#2} } { \int_new:c { g_@@_ #1 _depth_int } % \EditInstance {blockenv} {#1} { name = #1 ,inner-instance = #1 ,max-inner-levels = #3 ,inner-level-counter:c = g_@@_ #1 _depth_int } % \int_step_inline:nn {#3} { \@@_setup_enum_list_instance:nnn {#1}{#2}{##1} } } % % \end{macrocode} % For supporting \cs{setlist} we need to set up \cs{enitdp@\#1} % \begin{macrocode} \cs_set_eq:cc { enitdp@#1 } { g_@@_ #1 _depth_int } % } % \end{macrocode} % % \begin{macrocode} \cs_new:Npn \@@_setup_enum_list_instance:nnn #1#2#3 { \IfInstanceExistsF{list}{#2-#3} { \DeclareInstanceCopy {list} {#2-#3} {#2-\int_eval:n{#3-1}} } \DeclareInstanceCopy {list} {#1-#3} {#2-#3} \str_case:nnF { #2 } { { enumerate } { \EditInstance {list} {#1-#3} { counter:e = #1 \int_to_roman:n {#3} ,item-label:c = label #1 \int_to_roman:n {#3} } \newcounter { #1 \int_to_roman:n {#3} } \tl_new:c { label #1 \int_to_roman:n {#3} } \tl_set:cn { label #1 \int_to_roman:n {#3} } { \arabic* } } { itemize } { \EditInstance {list} {#1-#3} { item-label:c = label #1 \int_to_roman:n {#3} } \tl_new:c { label #1 \int_to_roman:n {#3} } \tl_set:cn { label #1 \int_to_roman:n {#3} } { -- } } } { \ERROR-#2-unknown } } % \end{macrocode} % \end{macro} % % % % % % %\subsubsection{\cs{renewlist}} % % % %\subsubsection{\cs{setlist}} % % For emulating \cs{setlist} I lifted most of the code directly % from \pkg{enumitem} for now and made only minimal % adjustments. Size-dependent settings via \verb=<...>= are not % supported so far. % % TODO: rewrite in \pkg{expl3}. % TODO: decide if we want to emulate size-dependent settings % % \begin{macrocode} \ExplSyntaxOff \makeatletter % \end{macrocode} % % \begin{macrocode} \newcommand\setlist{% \@ifstar{\enit@setlist\@ne}{\enit@setlist\z@}} % \end{macrocode} % % \begin{macrocode} \def\enit@setlist#1{% \@ifnextchar<% {\enit@setlist@q#1}% {\let\enit@forsize\@empty\enit@setlist@n#1}} % \end{macrocode} % % Size-dependent settings are not supported at all. % \begin{macrocode} \def\enit@setlist@q#1<#2>{% \enit@error {Size feature not implemented}% {Size dependent setting is not available in the emulation}% % {Activate this feature with options 'sizes'}% % {Size dependent setting with \string<\string> must be\MessageBreak % explicitly activated with the package option 'sizes'}} } % \end{macrocode} % % \begin{macrocode} \def\enit@setlist@n#1{% \@ifnextchar[{\enit@setlist@x#1}{\enit@setlist@i#1\@empty}} % \end{macrocode} % % \begin{macrocode} % Let's accept \setlist[]*{}, too, because an error in <=3.5.1 \def\enit@setlist@x#1[#2]{% \@ifstar{\enit@setlist@i\@ne{#2}}{\enit@setlist@i#1{#2}}} % \end{macrocode} % % \begin{macrocode} \def\enit@setlist@i#1#2#3{% \let\enit@eltnames\relax \let\enit@b\@empty \let\enit@eltlevels\relax \let\enit@c\@empty \protected@edef\enit@a{#2}% \@for\enit@a:=\enit@a\do{% the 2nd enit@a is first expanded \enit@ifunset{enitdp@\enit@meaning\enit@a}% {\edef\enit@c{\enit@c\enit@eltlevels{\enit@a}}}% {\edef\enit@b{\enit@b\enit@eltnames{\enit@a}}}}% \ifx\enit@b\@empty \def\enit@b{\enit@eltnames{list}}% \fi \ifx\enit@c\@empty \def\enit@c{\enit@eltlevels{0}}% \fi \def\enit@eltnames##1{% \def\enit@a{##1}% \enit@c}% \def\enit@eltlevels##1{% \enit@saveset\enit@a{##1}#1{#3}}% \enit@b}% % \end{macrocode} % % \begin{macrocode} \let\c@enit@cnt\@tempcnta % \end{macrocode} % % \begin{macrocode} \def\enit@meaning{\expandafter\strip@prefix\meaning} % \end{macrocode} % % \begin{macrocode} \long\def\enit@afterelse#1\else#2\fi{\fi#1} \long\def\enit@afterfi#1\fi{\fi#1} % \end{macrocode} % % \begin{macrocode} \def\enit@error{\PackageError{enumitem}} % \end{macrocode} % % \begin{macrocode} \def\enit@ifunset#1{% \ifcsname#1\endcsname \expandafter\ifx\csname#1\endcsname\relax \enit@afterelse\expandafter\@firstoftwo \else \enit@afterfi\expandafter\@secondoftwo \fi \else \expandafter\@firstoftwo \fi } % \end{macrocode} % % \begin{macrocode} \def\enit@saveset#1#2#3#4{% \setcounter{enit@cnt}{#2}% \ifx\enit@forsize\@empty \ifcase#3% \expandafter \def\csname enit@@#1\romannumeral\c@enit@cnt\endcsname{#4}% \or \expandafter\let\expandafter\enit@b \csname enit@@#1\romannumeral\c@enit@cnt\endcsname \ifx\enit@b\relax \let\enit@b\@empty \fi \expandafter\def \csname enit@@#1\romannumeral\c@enit@cnt\expandafter\endcsname \expandafter{\enit@b,#4}% \fi \else \ifcase#3% \enit@ifunset{enit@@#1\romannumeral\c@enit@cnt}% {\expandafter\let \csname enit@@#1\romannumeral\c@enit@cnt\endcsname\@empty}% {}% \expandafter\let\expandafter\enit@b \csname enit@@#1\romannumeral\c@enit@cnt @@sizes\endcsname \ifx\enit@b\relax \let\enit@b\@empty \fi \toks@\expandafter{\enit@b}% \edef\enit@b{\the\toks@\enit@forsize\enit@keys@sizes}% \expandafter\def \csname enit@@#1\romannumeral\c@enit@cnt @@sizes\expandafter\endcsname \expandafter{\enit@b{#4}}% \else \enit@error{* and \string<\string> are not compatible}% {Use either * or angles, but not both.}% \fi \fi} % \end{macrocode} % % The \pkg{enumitem} code uses \texttt{enitdp@\meta{name}} to refer % to the list level counter of the \meta{name} list. So we do need % that around for each standard list and provide one when making a % new list with \cs{newlist}. % % TODO: check how to do this when making new lists directly. % \begin{macrocode} \let\enitdp@enumerate\@enumdepth \let\enitdp@itemize\@itemdepth \let\enitdp@description\@descriptiondepth % \end{macrocode} % % To put keys set with \cs{setlist} into the keyp processing of % \insttype{blockenv} instances we sneak them in as if they are % given in the optional argument. For this we evaluate % \cs{enit@@list} (produced by \verb=\setlist{...}=), % \cs{enit@@list\meta{roman num}} (produced by \verb=\setlist[num]{...}=), % \cs{enit@@\meta{name}} (produced by \verb=\setlist[name]{...}=), and % \cs{enit@@\meta{name}\meta{roman num}} (produced by % \verb=\setlist[name,num]{...}=) % in that order and collect all key settings stored in them and % stored them in \cs{UnusedTemplateKeys} which is then used at the % start of the \insttype{blockenv} template. % \begin{macrocode} \AddToHookWithArguments{blockenv}{% % \end{macrocode} % If \verb=\enitdp@#1= is undefined the current \insttype{blockenv} % is not a list, so we bail out. % \begin{macrocode} \enit@ifunset{enitdp@#1}{}% {% % \end{macrocode} % Otherwise put the current list level in \cs{@tempcnta} and then % evaluate the four storage places for keys. % \begin{macrocode} \@tempcnta\csname enitdp@#1\endcsname \advance\@tempcnta\@ne \enit@setkeys{list}% \enit@setkeys{list\romannumeral\@tempcnta}% \enit@setkeys{#1}% \enit@setkeys{#1\romannumeral\@tempcnta}% }% } % \end{macrocode} % % \begin{macrocode} \ExplSyntaxOn % \end{macrocode} % Evaluation means checking if \cs{enit@@\#1} exists and if so add % its content to \cs{UnusedTemplateKeys} followed by a comma. % Thus, if there aren't any keys then \cs{UnusedTemplateKeys} % remains empty. Otherwise it ends in a comma so that the % \insttype{blockenv} template can safely append any keys from the % document to make the full list of keys to be evaluated by the % template instance. % \begin{macrocode} \cs_new_protected:Npn \enit@setkeys #1 { \enit@ifunset {enit@@#1} {} { \tl_set:Ne \UnusedTemplateKeys { \exp_not:o \UnusedTemplateKeys \exp_not:v {enit@@#1} , } } } \makeatother % \end{macrocode} % % %\subsubsection{\cs{setlistdepth}} % % %\subsubsection{\cs{AddEnumerateCounter}} % % %\subsubsection{\cs{SetEnumitemSize}} % % %\subsubsection{\cs{restartlist}} % % % \begin{macrocode} % % \end{macrocode}