% \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-01-16}
\def\ltlabenumversion{0.80b}

%<*driver>
\DocumentMetadata{tagging=on,pdfstandard=ua-2}
\documentclass[kernel]{l3in2edoc}

\usepackage{longtable,tikz}
\EnableCrossrefs
\CodelineIndex
\begin{document}
  \DocInput{latex-lab-enumitem.dtx}
\end{document}
%</driver>
%
% \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}}
%
% \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}}\\
%  {\cs{SetEnumitemValue}}\\
%  {\cs{SetEnumerateShortLabel}}\\
%  \cs{newlist}  & yes \\
%  \cs{renewlist}\\
%  {\cs{setlist}}\\
%  \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}}
%
% 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-extra-vspace=0pt, 
      begin-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. 
%  
% \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}
% \end{macro}
% 
% \begin{macro}{\@@_setup_itemize:nn}
%    \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}
%    \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}
%    \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}
% 
%\subsubsection{\cs{renewlist}}
% 
%\subsubsection{\cs{setlist}}
% 
%    \begin{macrocode}
\NewDocumentCommand\setlist{O{}m}{} %dummy for now
%    \end{macrocode}
% 
%\subsubsection{\cs{setlistdepth}}
% 
%\subsubsection{\cs{AddEnumerateCounter}}
% 
%\subsubsection{\cs{SetEnumitemSize}}
% 
%\subsubsection{\cs{restartlist}}
% 
%    \begin{macrocode}
%</package>
%    \end{macrocode}
