% \iffalse meta-comment
% ======================================================================
% tocbasic.dtx
% Copyright (c) Markus Kohm, 2008-2025
%
% This file is part of the LaTeX2e KOMA-Script bundle.
%
% This work may be distributed and/or modified under the conditions of
% the LaTeX Project Public License, version 1.3c of the license.
% The latest version of this license is in
%   http://www.latex-project.org/lppl.txt
% and version 1.3c or later is part of all distributions of LaTeX
% version 2005/12/01 or later and of this work.
%
% This work has the LPPL maintenance status "author-maintained".
%
% The Current Maintainer and author of this work is Markus Kohm.
%
% This work consists of all files listed in MANIFEST.md.
% ======================================================================
%%% From File: $Id: tocbasic.dtx 4251 2025-12-31 10:31:49Z kohm $
%<identify>%%%            (run: identify)
%<prepare>%%%            (run: prepare)
%<option>%%%            (run: option)
%<execoption>%%%            (run: execoption)
%<preparebody>%%%            (run: preparebody)
%<body>%%%            (run: body)
%<exit>%%%            (run: exit)
%<*dtx>
\ifx\ProvidesFile\undefined\def\ProvidesFile#1[#2]{}\fi
\begingroup
  \def\filedate$#1: #2-#3-#4 #5${\gdef\filedate{#2/#3/#4}}
  \filedate$Date: 2025-12-31 11:31:49 +0100 (Mi, 31 Dez 2025) $
  \def\filerevision$#1: #2 ${\gdef\filerevision{r#2}}
  \filerevision$Revision: 4251 $
\endgroup
\ProvidesFile{tocbasic.dtx}[\filedate\space\filerevision\space
%</dtx>
%<package&identify>\NeedsTeXFormat{LaTeX2e}[2022/06/01]
%<package&identify>\ProvidesPackage{tocbasic}[%
%<*dtx|(package&identify)>
%!KOMAScriptVersion
  package
%<*dtx>
  source
%</dtx>
%</dtx|(package&identify)>
%<package&identify>  (handling toc-files)%
%<*dtx>
  (dtx)%
%</dtx>
%<*dtx|(package&identify)>
]
%</dtx|(package&identify)>
%<*dtx>
\ifx\documentclass\undefined
  \input scrdocstrip.tex
  \@@input scrkernel-version.dtx
  \@@input scrstrip.inc
  \KOMAdefVariable{COPYRIGHTFROM}{2008}
  \generate{\usepreamble\defaultpreamble
    \file{tocbasic.sty}{%
      \from{tocbasic.dtx}{package,identify}%
      \from{tocbasic.dtx}{package,prepare}%
      \from{tocbasic.dtx}{package,option}%
      \from{tocbasic.dtx}{package,execoption}%
      \from{tocbasic.dtx}{package,preparebody}%
      \from{tocbasic.dtx}{package,body,deprecated}%
      \from{scrkernel-tocstyle.dtx}{package,body}%
      \from{scrkernel-tocstyle.dtx}{package,style,gobble}%
      \from{scrkernel-tocstyle.dtx}{package,style,dottedtocline}%
      \from{scrkernel-tocstyle.dtx}{package,style,undottedtocline}%
      \from{scrkernel-tocstyle.dtx}{package,style,largetocline}%
      \from{scrkernel-tocstyle.dtx}{package,style,tocline}%
      \from{scrkernel-tocstyle.dtx}{package,style,toctext}%
      \from{scrkernel-tocstyle.dtx}{package,style,default}%
      \from{tocbasic.dtx}{package,exit}%
      \from{scrlogo.dtx}{logo}%
    }%
  }%
  \@@input scrstrop.inc
\else
  \let\endbatchfile\relax
\fi
\endbatchfile
\documentclass[USenglish]{koma-script-source-doc}
\usepackage{babel}
\setcounter{StandardModuleDepth}{2}
\begin{document}
\DocInput{tocbasic.dtx}
\end{document}
%</dtx>
% \fi
%
% \changes{v3.36}{2022/02/10}{switch over from \cls*{scrdoc} to
%   \cls*{koma-script-source-doc}}
% \changes{v3.36}{2022/02/10}{require package \pkg*{scrlogo} instead of
%   defining \cs{KOMAScript}}
% \changes{v3.40}{2023/04/17}{guide names changed}
%
% \GetFileInfo{tocbasic.dtx}
% \title{Handling of Tables and Lists of Contents with
%   \href{https://komascript.de}{\KOMAScript} Package \pkg*{tocbasic}}
% \author{\href{mailto:komascript@gmx.info}{Markus Kohm}}
% \date{Revision \fileversion{} of \filedate}
% \maketitle
% \begin{abstract}
%   The main purpose of package \pkg*{tocbasic} is to provide features for
%   authors of classes and packages to create own tables or lists of contents
%   like the list of figures and the list of tables and thereby allow other
%   classes or packages some types of control over these. For examples package
%   \pkg*{tocbasic} delegates language control of all these tables and lists
%   of contents to package \pkg{babel}. So automatic change of language
%   will be provided inside all these tables and lists of contents. Using
%   \pkg*{tocbasic} will exculpate authors of classes and packages from
%   implementation of such features.
%
%   \KOMAScript{} classes use \pkg*{tocbasic} not only for the table of
%   contents but also for the already mentioned lists of figures and tables.
% \end{abstract}
% \tableofcontents
% 
% \section{User Manual}
%
% You can find the user manuals of \pkg*{tocbasic} in the \KOMAScript{}
% manual, either the German \file{scrguide-de.pdf} or the English
% \file{scrguide-en.pdf}.
%
%
% \MaybeStop{\PrintIndex}
%
%
% \section{Implementation}
% \label{sec:implementation}
%
%    \begin{macrocode}
%<@@=tocbasic>
%<*package>
%    \end{macrocode}
%
% All macros with prefix \cs{tb@} or \cs{@} are internal macros and should not
% be used by package and class authors. Macros with prefix \cs{tocbasic@} are
% internal macros, that may be used by class and packages authors. Macros
% without \texttt{@} are interface commands and may be used by class and
% package authors and users.
%
% Note: Parts of the implementation of package \pkg*{tocbasic} are
% out-sourced into file \file{scrkernel-tocbasic.dtx}.
%
%
% \subsection{Requirements}
% \label{sec:packages}
%
% \changes{v3.42}{2023/09/08}{We need at least \LaTeX{} 2022-06-01}
% For full functionality at least \LaTeX{} 2022-06-01 is needed.
%    \begin{macrocode}
%<*prepare>
\newif\if@tocbasic@old@latex@found
\ifnum 0=\ifcsname IfFormatAtLeastTF\endcsname
    \IfFormatAtLeastTF{2022-06-01}{1}{0}
  \else
    0
  \fi\relax
  \PackageWarningNoLine{tocbasic}{%
    LaTeX kernel too old!\MessageBreak
    For full functionality the package needs at least\MessageBreak
    LaTeX 2022-06-01.\MessageBreak
    You are using an older LaTeX version.\MessageBreak
    So the functionality will be limited.\MessageBreak
    Note that this also can result in error messages,\MessageBreak
    that would not raise with an up-to-date LaTeX%
  }
  \@tocbasic@old@latex@foundtrue
\fi
%    \end{macrocode}
% \changes{v3.41}{2023/06/28}{required packages moved to \texttt{prepare} run}
% \changes{v3.41}{2023/06/28}{\pkg{expl3} and \pkg{xparse} are required}
% Package \pkg*{scrbase} is needed to process all macro options.
%    \begin{macrocode}
\RequirePackage{scrbase}
%    \end{macrocode}
%
% Now we can load \pkg{xparse} if needed, which also would load \pkg{expl3}:
%    \begin{macrocode}
\scr@ifundefinedorrelax{NewDocumentCommand}{%
  \RequirePackage{xparse}[2018-04-12]%
}{}
%    \end{macrocode}
%
% \changes{v3.50}{2025/12/31}{stop loading with \cls{beamer}}
% Now we can detect \cls{beamer} to stop loading the package.
%    \begin{macrocode}
\IfClassLoadedTF{beamer}{%
  \PackageWarningNoLine{tocbasic}{%
    beamer class detected,\MessageBreak
    loading package tocbasic aborted%
  }%
  \DeclareOption*{}
  \ProcessOptions
  \endinput
}{}
%</prepare>
%    \end{macrocode}
%
%
% \subsection{Options}
% \label{sec:options}
%
% \changes{v3.42}{2023/09/08}{with old \LaTeX{} all options are unknown}
%
% \begin{option}{enablepatch,disablepatch}
% \changes{v3.42}{2023/09/08}{added}
% From version 3.42 there a several optional patches executed while
% |\begin{document}|. Every one of that patch can be enabled or disabled.
% \ExplSyntaxOn
% \begin{macro}{\g_@@_patch_all_bool,\g_@@_patch_starttoc_bool,
%               \g_@@_patch_chapter_bool,
%               \g_@@_patch_listoffigures_bool,\g_@@_patch_listoftables_bool}
% \ExplSyntaxOff
% \changes{v3.42}{2023/09/08}{added}
% \changes{v3.46}{2025/06/10}{respecting l3 naming convention}
% Enabling and disabling will be done using a boolean variable with default
% |false| (disabled). The |all| patch is somehow different. It enables or
% disables doing all patches. So |disablepatch=all| does not disable all
% patches but disables to ignore the single patches.
%    \begin{macrocode}
%<*option>
\if@tocbasic@old@latex@found\else
  \ExplSyntaxOn

  \bool_new:N \g_@@_patch_all_bool
  \bool_new:N \g_@@_patch_starttoc_bool
  \bool_new:N \g_@@_patch_chapter_bool
  \bool_new:c { g_@@_patch_chapter*_bool }
  \bool_new:N \g_@@_patch_listoffigures_bool
  \bool_new:N \g_@@_patch_listoftables_bool

%    \end{macrocode}
% \end{macro}
% \ExplSyntaxOff
% \ExplSyntaxOn
% \begin{macro}{\g_@@_patch_caption_bool}
%   \ExplSyntaxOff
%   \changes{v3.46}{2025/06/10}{added}
%   From version 3.46 the caption code of the \KOMAScript{} classes is
%   (partially) redesigned and move to \pkg*{tocbasic}. But it is only
%   activated with option \opt{enablepatch=caption}. The \KOMAScript{} classes
%   load \pkg*{tocbasic} with this option. Nevertheless you can overwrite it
%   an so get lost of all the extended caption features.
%    \begin{macrocode}
  \bool_new:N \g_@@_patch_caption_bool
%    \end{macrocode}
% \end{macro}
% \ExplSyntaxOff
% The most simple part of the story is the definition of the two
% options. Both allow a comma separated list of patches to set the
% corresponding boolean value to |true| or |false|.
%    \begin{macrocode}
  \keys_define:nn { tocbasic }
    {
      enablepatch  .code             = \@@_endisable_patch:nn {#1} \c_true_bool,
      enablepatch  .usage            = preamble,
      enablepatch  .value_required:n = true,
      disablepatch .code             = \@@_endisable_patch:nn {#1} \c_false_bool,
      disablepatch .usage            = preamble,
      disablepatch .value_required:n = true,
    }

%    \end{macrocode}
% \ExplSyntaxOn
% \begin{macro}{\@@_endisable_patch:nn}
% \ExplSyntaxOff
% \changes{v3.42}{2023/09/08}{added}
% \changes{v3.43}{2024/10/22}{deprecated \cs{char\_uppercase:N} replaced by
%   \cs{text\_uppercase:n}}
% Switch the patch \#1 depending on argument \#2 or raise a warning for
% unknown patches.
%    \begin{macrocode}
  \msg_new:nnnn { tocbasic } { unknown-patch }
    {
      \text_uppercase:n #1bling~of~unknown~patch~#2~ignored.
    }
    {
      You've~tried~to~#1able~patch~#2,~
      but~this~is~not~a~known~patch.~
      Because~of~this~your~attempt~is~ignored.~
      See~the~KOMA-Script~user~manual~for~more~information~about~known~patches.
    }

  \cs_new:Nn \@@_endisable_patch:nn
    {
      \clist_map_inline:nn { #1 }
        {
          \cs_if_exist:cTF { g_@@_patch_##1_bool }
            {
              \bool_set_eq:cN { g_@@_patch_##1_bool } #2
            }
            {
              \exp_args:Nnnx \msg_warning:nnnn { tocbasic } { unknown-patch }
                { \bool_if:NTF #2 { en } { dis } } { ##1 }
            }
        }
    }

  \ExplSyntaxOff
\fi
%</option>
%    \end{macrocode}
% \end{macro}
% \ExplSyntaxOff
% The patch codes are executed while |\begin{document}|. Some patches may be
% dangerous, in which case message |dangerous-patch| is used.
% \begin{description}
% \item[ToDo:] We are using the old \cs{AtBeginDocument} here. Maybe a new
%   hook would be cleaner.
% \end{description}
%    \begin{macrocode}
%<*body>
\if@tocbasic@old@latex@found\else
  \ExplSyntaxOn
  \msg_new:nnnn { tocbasic } { dangerous-patch }
    {
      Dangerous~#2~patch~enabled \str_if_empty:nF { #1 } { ~using~#1 } .
    }
    {
      \str_if_empty:nF { #1 } { Class~#1~does~not~need~the~#2~patch.~ }
      Using~this~patch~can~even~result~in~harm.~
      If~you~are~not~sure~that~this~patch~is~needed,~
      you~should~not~enable~it.~
      Please,~see~the~KOMA-Script~user~manual~for~more~information~about~
      the~#2~patch.
    }

  \AtBeginDocument
    {

%    \end{macrocode}
% The patches are:
% \begin{description}
% \item[\texttt{all}:]
%   \changes{v3.46}{2025/06/13}{\opt{enablepath\quotechar=all} enables the
%     caption patch, if \pkg*{caption} has not been loaded}
%   activate all other patches. The \texttt{chapter} patch
%   is not enabled for \KOMAScript{} classes. So if you want to use this patch
%   with a \KOMAScript{} class\,---\,which usually will not make sense\,---\,,
%   you have to use an explicit |enabelpatch=chapter|.
%    \begin{macrocode}
      \bool_if:NT \g_@@_patch_all_bool
        {
          \bool_set_true:N \g_@@_patch_starttoc_bool
          \cs_if_exist:NF \KOMAClassName
            {
              \bool_set_true:N \g_@@_patch_chapter_bool
              \bool_set_true:c { g_@@_patch_chapter*_bool }
            }
          \bool_set_true:N \g_@@_patch_listoffigures_bool
          \bool_set_true:N \g_@@_patch_listoftables_bool
          \IfPackageLoadedTF{ caption } { }
            { \bool_set_true:N \g_@@_patch_caption_bool }
        }

%    \end{macrocode}
% \item[\texttt{chapter}:] patches \cs{@makechapterhead} to add \cs{addvspace}
%   to every float list. It does \emph{not} patch \cs{@makeschapterhead}. Note
%   that this patch should not be activated using a \KOMAScript{} class unless
%   you are using an incompatible \cs{chapter} definition. This patch is
%   potentially dangerous. So we raise at least a note and maybe a warning.
%    \begin{macrocode}
      \bool_if:NT \g_@@_patch_chapter_bool
        {
          \@@_chapter_patch_code:
        }

%    \end{macrocode}
% \item[\texttt{starttoc}:] executes \cs{tocbasicautomode}
%    \begin{macrocode}
      \bool_if:NT \g_@@_patch_starttoc_bool \tocbasicautomode  

%    \end{macrocode}
% \item[\texttt{listoffigures}] redefines \cs{listoffigures} to use
%   \pkg*{tocbasic} (but without changing \cs{l@figure}, because
%   \cs{DeclareTOCSTyleEntry} already has defaults for \texttt{figure}).
%    \begin{macrocode}
      \bool_if:NT \g_@@_patch_listoffigures_bool
        {
          \@@_listof_patch_code:n{figure}
        }

%    \end{macrocode}
% \item[\texttt{listoftables}] redefines \cs{listoftables} to use
%   \pkg*{tocbasic} (but without changing \cs{l@table}, because
%   \cs{DeclareTOCSTyleEntry} already has defaults for \texttt{table}).
%    \begin{macrocode}
      \bool_if:NT \g_@@_patch_listoftables_bool
        {
          \@@_listof_patch_code:n{table}
        }

%    \end{macrocode}
% \end{description}
%    \begin{macrocode}
    }

  \ExplSyntaxOff
\fi
%</body>
%    \end{macrocode}
% \end{option}
% \ExplSyntaxOff
%
%    \begin{macrocode}
%<*execoption>
\if@tocbasic@old@latex@found
  \ProcessOptions\relax
\else
  \ProcessKeyOptions[tocbasic]
\fi
%</execoption>
%    \end{macrocode}
%
%
% \subsection{Unwanted packages}
% \label{sec:unpackages}
%
% There are packages, that are not recommended to be used together with
% \pkg*{tocbasic}:
%    \begin{macrocode}
%<*body>
%    \end{macrocode}
% \begin{description}
% \item[\pkg{multitoc}:] This package implements multi-column ToCs using
%   \pkg{multicol}. Unfortunately there is a bug in that package, that
%   disables all extensions but \file{toc}, \file{lof} and \file{lot} and
%   even these if the corresponding option has not been set.
%    \begin{macrocode}
\AfterPackage*{multitoc}{%
  \@ifpackagelater{multitoc}{2022/02/10}{}{%
    \PackageWarningNoLine{tocbasic}{%
      Usage of package `multitoc' is not recommended!\MessageBreak
      Note, this package generally results in empty ToCs\MessageBreak
      for all extension but `toc', `lof' and `lot' and\MessageBreak
      even for these extensions if you do not use the\MessageBreak
      corresponding multitoc options.\MessageBreak
      It is recommended to use:\MessageBreak
      \space\space\string\usepackage{multicol}\MessageBreak
      \space\space\string\BeforeStartingTOC{\string\begin{multicols}{2}}%
      \MessageBreak
      \space\space\string\AfterStartingTOC{\string\end{multicols}}%
      \MessageBreak
      instead of loading package `multitoc'.\MessageBreak
      See the KOMA-Script manual for more information\MessageBreak
      about using \string\BeforeStartingTOC\space and
      \string\AfterStartingTOC\MessageBreak
      and the multicol manual for more information\MessageBreak
      about the `multicols' environment%
    }%
  }%
}
%    \end{macrocode}
% \end{description}
%    \begin{macrocode}
%</body>
%    \end{macrocode}
%
%
% \subsection{Having a list of all toc-files}
% \label{sec:listoftocs}
%
% If we have a list of all toc-files we may do commands for all
% toc-files. Somethimes it may be usefull to known the package, that created
% the toc-file, so this information will be stored additionally.
%
% \begin{macro}{\tb@listoftocs}
% This is the list of toc-files. The list will be:
% \begin{quote}
%   \cs{do}\marg{extension}\marg{class or
%   package}\cs{do}\marg{extension}\marg{class or package}\dots
% \end{quote}
% With this, adding and processing the list will be very fast but removing
% an element will be very slow.
%
% The initial state of the list will be \emph{empty}.
%    \begin{macrocode}
%<*body>
\newcommand*{\tb@listoftocs}{}
%    \end{macrocode}
% \end{macro}
%
% \begin{command}{\ifattoclist,\Ifattoclist}
% \changes{v3.28}{2019/11/19}{\cs{ifattoclist} renamed to \cs{Ifattoclist}}
% This command tests, if an extension is already at the list of toc-files. The
% extension has to be the first argument. The second argument will be done, if
% the extension is already at the list of toc-files. The third argument will
% be done, if the extension is at the list of toc-files not yet.
%    \begin{macrocode}
\providecommand*{\ifattoclist}{%
  \PackageWarning{tocbasic}{Usage of deprecated command
    `\string\ifattoclist'.\MessageBreak
    The command has been renamed because of a\MessageBreak
    recommendation of The LaTeX Project Team.\MessageBreak
    Please replace `\string\ifattoclist' by `\string\Ifattoclist'%
  }%
  \Ifattoclist
}
\newcommand{\Ifattoclist}[1]{%
  \begingroup
    \def\do##1##2{%
      \edef\reserved@a{##1}%
      \ifx\reserved@a\reserved@b\@tempswatrue\fi
    }%
    \edef\reserved@b{#1}\@tempswafalse\tb@listoftocs
    \if@tempswa\aftergroup\@firstoftwo\else\aftergroup\@secondoftwo\fi
  \endgroup
}
%    \end{macrocode}
% \end{command}^^A \ifattoclist,\Ifattoclist
%
% \begin{macro}{\tb@optowner}
% \changes{v3.41}{2023/06/28}{added}
% Several of the following commands use an optional argument for the
% owner. Almost always if the argument is not given but \cs{@currname} is not
% empty \texttt{\cs{@currname}.\cs{@currext}} should be used. If the argument
% is not given but \cs{@currname} is empty, an empty value should be used. And
% if the optional argument is given, it should be used unchanged. So here is a
% helper macro for exactly this logic. Note, that argument here is not
% optional but mandatory and should be an optional argument of
% \cs{NewDocumentCommand}.
%    \begin{macrocode}
\newcommand*{\tb@optowner}[1]{%
  \IfValueTF{#1}{%
    #1%
  }{%
    \ifx\@currname\@empty\else
      \@currname.\@currext%
    \fi
  }%
}
%    \end{macrocode}
% \end{macro}
% \begin{command}{\addtotoclist}
% \changes{v3.06a}{2010/09/14}{expand the arguments while adding them to the
%   internal list}
% \changes{v3.41}{2023/06/28}{using \cs{NewDocumentCommand} to not need all
%   the helpers}
% This command adds an extension to the list of toc-files. The first,
% optional argument is the class or package name with the corresponding
% extension of class or package files. If this argument was omitted
% \pkg*{tocbasic} tries to get it automatically. This should be
% successfull while loading a class or package but not while processing any
% command of a class or package after loading the class or package. The
% second, mandatory argument is the extension of the toc-file. NOTE: An
% empty first argument is not the same like omitting the first argument!
%    \begin{macrocode}
%<@@=>
\NewDocumentCommand\addtotoclist{om}{%
  \edef\reserved@b{\tb@optowner{#1}}%
  \Ifattoclist{#2}{%
    \PackageError{tocbasic}{%
      file extension `#2' cannot be used twice
    }{%
      File extension `#2' is already used by a toc-file, while
      \ifx\relax#1\relax someone\else #2\fi\MessageBreak
      tried to use it again for a toc-file.\MessageBreak
      This may be either an incompatibility of packages, an error at a
      package,\MessageBreak
      or a mistake by the user.\MessageBreak
    }%
  }{%
    \begingroup
      \edef\reserved@a{%
        \noexpand\g@addto@macro\noexpand\tb@listoftocs{%
          \noexpand\do{#2}{\reserved@b}}}\reserved@a
    \endgroup
    \ifx\reserved@b\@empty\else
      \@ifundefined{tb@\reserved@b @add@hook}{}{%
        \edef\reserved@a{%
          \noexpand\def\noexpand\@currext{#2}%
          \noexpand\@nameuse{tb@\reserved@b @add@hook}%
          \noexpand\def\noexpand\@currext{\@currext}%
        }\reserved@a
      }%
    \fi
    \edef\reserved@a{%
      \noexpand\def\noexpand\@currext{#2}%
      \noexpand\@nameuse{tb@@add@hook}%
      \noexpand\def\noexpand\@currext{\@currext}%
    }\reserved@a
  }%
}
%<@@=tocbasic>
%    \end{macrocode}
% \end{command}
%
% \begin{command}{\owneroftoc}
% \changes{v3.22}{2016/08/09}{added}
% \changes{v3.28}{2019/11/18}{\cs{ifstr} renamed to \cs{Ifstr}}
% Returns the owner of a TOC or uses the owner of a TOC as argument of the
% optional argument, if it exists.
%    \begin{macrocode}
\newcommand*{\owneroftoc}[2][\@firstofone]{%
  \begingroup
    \let\reserved@a\endgroup
    \def\do##1##2{\Ifstr{#2}{##1}{\def\reserved@a{\endgroup#1{##2}}}{}}%
    \tb@listoftocs
  \reserved@a
}
%    \end{macrocode}
% \end{command}
% \begin{command}{\categoryoftoc}
% \changes{v3.27}{2019/05/12}{added}
% Synonym for \cs{owneroftoc}.
%    \begin{macrocode}
\newcommand*{\categoryoftoc}{\owneroftoc}
%    \end{macrocode}
% \end{command}
%
% \begin{command}{\AtAddToTocList}
% \changes{v3.20}{2016/04/12}{\cs{@ifnextchar} replaced by
%   \cs{kernel@ifnextchar}}
% \changes{v3.41}{2023/06/28}{using \cs{NewDocumentCommand} to not need all
%   the helpers}
% Action to be done, when adding a toc-file of a known owner. The first
% optional argument is the owner. The second, mandatory argument is the
% action. While doing the action \cs{@currext} will be the extension of the
% added toc-file. If the first argument was omitted \pkg*{tocbasic} tries
% to get it automatically. This should be successfull while loading a class
% or package but not while processing any command of a class or package
% after loading the class or package. The second, mandatory argument is the
% extension of the toc-file. NOTE: An empty first argument is not the same
% like omitting the first argument, but set's up the general hook. The
% general hook will be done for every adding after the individual hook (this
% means, you may dactivate features at the individual hook before processing
% the general hook). But the individual hook will not be processed for
% toc-files without any owner!
%    \begin{macrocode}
\NewDocumentCommand\AtAddToTocList{o}{%
  \edef\reserved@a{\tb@optowner{#1}}%
  \@ifundefined{tb@\reserved@a @add@hook}%
    {\@namedef{tb@\reserved@a @add@hook}{}}%
    {}%
  \expandafter\g@addto@macro\csname tb@\reserved@a @add@hook\endcsname
}
%    \end{macrocode}
% \end{command}
%
% \begin{macro}{\tocbasic@extend@babel}
% \changes{v3.28}{2019/11/19}{\cs{iftocfeature} replaced by
%   \cs{Iftocfeature}}
% \changes{v3.38}{2022/07/22}{first test feature than availability}
% NOTE: To extend the original \cs{bbl@set@language} the argument of
% \cs{tocbasic@extend@babel} must not be a local macro (like \cs{@currext})
%    \begin{macrocode}
\newcommand*{\tocbasic@extend@babel}[1]{%
  \Iftocfeature{#1}{nobabel}{%
    \PackageInfo{tocbasic}{omitting babel extension for `#1'\MessageBreak
      because of feature `nobabel' available\MessageBreak
      for `#1'}%
  }{%
    \scr@ifundefinedorrelax{bbl@set@language}{%
      \PackageInfo{tocbasic}{omitting babel extension for `#1'\MessageBreak
        because of missing \string\bbl@set@language}%
    }{%
%    \end{macrocode}
% \changes{v3.23}{2017/02/23}{using \cs{BabelContentsFiles} if available}
% Since version 3.9a provides adding extensions to the language switch
% preparation. So it is used if it is available.
%    \begin{macrocode}
      \scr@ifundefinedorrelax{BabelContentsFiles}{%
        \PackageInfo{tocbasic}{setting babel extension for `#1'}%
        \expandafter\gdef\expandafter\bbl@set@language
        \expandafter##\expandafter1%
        \expandafter{%
          \bbl@set@language{##1}%
          \addtocontents{#1}{\xstring\select@language{\languagename}}%
        }%
      }{%
        \@expandtwoargs\in@{,#1,}{,\BabelContentsFiles,}%
        \ifin@
          \PackageInfo{tocbasic}{omitting babel extension for
            `#1'\MessageBreak
            because it is already in \string\BabelContentsFiles}%
        \else
          \PackageInfo{tocbasic}{setting babel extension for `#1'}%
          \xdef\BabelContentsFiles{\BabelContentsFiles,#1}%
        \fi
      }%
    }%
  }%
}
%    \end{macrocode}
% This feature should be used for all toc-files (unless feature
% \opt{nobabel} was set for the toc-file).
%    \begin{macrocode}
\AtAddToTocList[]{\expandafter\tocbasic@extend@babel\expandafter{\@currext}}
%    \end{macrocode}
% \end{macro}
%
% \begin{command}{\removefromtoclist}
% \changes{v3.20}{2016/04/12}{\cs{@ifnextchar} replaced by
%   \cs{kernel@ifnextchar}}
% \changes{v3.22}{2016/09/06}{missing \cs{global} added}
% \changes{v3.41}{2023/06/28}{using \cs{NewDocumentCommand} to not need all
%   the helpers}
% This command will remove an extension from the list of toc-files. If the
% first, optional argument is given, the extension will only be removed, if
% it was added by the given owner. NOTE: An empty first argument is not the
% same like omitting the first argument!
%    \begin{macrocode}
\NewDocumentCommand\removefromtoclist{om}{%
  \begingroup
    \let\tb@oldlist\tb@listoftocs
    \edef\reserved@b{#2}%
    \global\let\tb@listoftocs\empty
    \def\do##1##2{%
      \edef\reserved@a{##1}%
      \ifx\reserved@a\reserved@b
        \IfValueT{#1}{%
          \begingroup
            \edef\@currext{##2}%
            \edef\reserved@b{#1}%
            \ifx\@currext\reserved@b
            \else
              \g@addto@macro\tb@listoftocs{\do{##1}{##2}}%
            \fi
          \endgroup
        }%
      \else
        \g@addto@macro\tb@listoftocs{\do{##1}{##2}}%
      \fi
    }%
    \tb@oldlist
  \endgroup
}
%    \end{macrocode}
% \end{command}
%
% \begin{command}{\doforeachtocfile}
% \changes{v3.09}{2011/03/01}{\cs{@currext} defined using \cs{edef} instead
%   of \cs{def}}
% \changes{v3.20}{2016/04/12}{\cs{@ifnextchar} replaced by
%   \cs{kernel@ifnextchar}}
% \changes{v3.41}{2023/06/28}{using \cs{NewDocumentCommand} to not need all
%   the helpers}
% This command does the second, mandatory argument for each toc-file at the
% list of toc-files. If the first, optional argument was given this will be
% done only for the toc-files of that owner. NOTE: An empty first argument
% is not the same like omitting the first argument!
% While processing the second argument \cs{@currext} is the extension of
% the toc-file. The second argument will be processed with increased group
% level!
% See \cs{addtoeachtocfile} for an example of usage of
% \cs{doforeachtocfile}.
%    \begin{macrocode}
\NewDocumentCommand\doforeachtocfile{o+m}{%
  \IfValueTF{#1}{%
    \def\do##1##2{%
      \edef\reserved@a{#1}\edef\reserved@b{##2}%
      \ifx\reserved@a\reserved@b \edef\@currext{##1}#2\fi
    }%
  }{%
    \def\do##1##2{\edef\@currext{##1}#2}%
  }%
  \edef\reserved@a{%
    \noexpand\tb@listoftocs
    \noexpand\def\noexpand\@currext{\@currext}%
  }\reserved@a
%    \end{macrocode}
% \changes{v3.41}{2023/05/16}{don't \cs{let}\cs{do}\cs{relax}}
% Former versions of \KOMAScript{} have used |\let\do\relax| to undefined
% \cs{do} after the walk-through. But some packages like \pkg{dynkin-diagrams}
% have had problems using \cs{renewcommand} instead of \cs{def} or \cs{let} to
% change \cs{do}. So from version 3.41 \KOMAScript{} has changed this to
% |\let\do\noexpand|, because this is the default of \LaTeX{} after
% |\begin{document}|. However, this is only a workaround for a
% workaround. Best would be to remove the final change of \cs{do}. But this
% could also break packages.
%    \begin{macrocode}
  \let\do\noexpand
}
%    \end{macrocode}
% \end{command}
% 
% \begin{command}{\addtoeachtocfile}
% \changes{v3.20}{2016/04/12}{\cs{@ifnextchar} replaced by
%   \cs{kernel@ifnextchar}}
% \changes{v3.41}{2023/06/28}{using \cs{NewDocumentCommand} to not need all
%   the helpers}
% This command calls \cs{addtocontents} with the section, mandatory
% argument for each toc-file at the list of toc-files. If the first,
% optional argument was given this will be done only for the toc-files of
% that owner. NOTE: An empty first argument is not the same like omitting
% the first argument! And don't forget to protect the commands, that should
% not be expanded, at the mandatory argument.
%    \begin{macrocode}
\NewDocumentCommand\addtoeachtocfile{o+m}{%
  \doforeachtocfile[{#1}]{\addtocontents{\@currext}{#2}}%
}
%</body>
%    \end{macrocode}
% \end{command}
%
% \subsection{Adding entries into toc-files}
%
% We have a new general command to add entries to several toc-files at
% once. And we have some special commands for the table of contents.
%
% \begin{command}{\addcontentslinetoeachtocfile}
% \changes{v3.20}{2016/04/12}{\cs{@ifnextchar} replaced by
%   \cs{kernel@ifnextchar}}
% \changes{v3.41}{2023/06/28}{using \cs{NewDocumentCommand} to not need all
%   the helpers}
% Something like a combination of \cs{addtoeachtocfile} and
% \cs{addcontentsline}.
%    \begin{macrocode}
%<*body>
\NewDocumentCommand\addcontentslinetoeachtocfile{omm}{%
   \doforeachtocfile[{#1}]{\addcontentsline{\@currext}{#2}{#3}}%
} 
%    \end{macrocode}
% \end{command}
% 
% \begin{command}{\addxcontentsline}
% \changes{v3.12}{2013/09/24}{added}
% \changes{v3.20}{2016/04/12}{\cs{@ifnextchar} replaced by
%   \cs{kernel@ifnextchar}}
% \changes{v3.41}{2023/06/28}{using \cs{NewDocumentCommand} to not need all
%   the helpers}
% This will be used instead of \cs{addcontentsline} to generate numbered or
% not numbered entries to a toc-file. First argument is the toc-file, second
% the entry type, e.g., |chapter|, the third is the entry number or empty and
% the fourth and last is the entry text.
%    \begin{macrocode}
\NewDocumentCommand\addxcontentsline{mmO{}m}{%
  \scr@ifundefinedorrelax{add#2#1entry}{%
    \tocbasic@addxcontentsline{#1}{#2}{#3}{#4}%
  }{%
    \@nameuse{add#2#1entry}{#3}{#4}%
  }%
}
%    \end{macrocode}
% \begin{macro}[noprint]{\@addxcontentsline}
% \changes{v3.12}{2013/09/24}{added}
% \changes{v3.41}{2023/06/28}{removed}
% \end{macro}
% \begin{command}{\nonumberline}
% \changes{v3.12}{2013/09/24}{added}
% Either \cs{relax} or \cs{numberline} depending on the feature
% \opt{numberline}.
%    \begin{macrocode}
\newcommand*{\nonumberline}{}%
%    \end{macrocode}
% \end{command}
% \begin{macro}{\tocbasic@addxcontentsline}
% This may be used to either use a heading type command or the general default
% one. You are not allowed to use it in the definition of a heading type
% command like \cs{addchaptertocentry}! You may use
% \cs{tocbasic@addxcontentsline} at the definition of those commands.
%    \begin{macrocode}
\newcommand*{\tocbasic@addxcontentsline}[4]{%
  \IfArgIsEmpty{#3}{%
    \addcontentsline{#1}{#2}{\protect\nonumberline#4}%
  }{%
    \addcontentsline{#1}{#2}{\protect\numberline{#3}#4}%
  }%
}
%    \end{macrocode}
% \end{macro}
% \end{command}
%
% \begin{command}{\addxcontentslinetoeachtocfile}
% \changes{v3.12}{2013/09/24}{added}
% \changes{v3.20}{2016/04/12}{\cs{@ifnextchar} replaced by
%   \cs{kernel@ifnextchar}}
% \changes{v3.41}{2023/06/28}{using \cs{NewDocumentCommand} to not need all
%   the helpers}
% Similar to \cs{addcontentslinetoeachtocfile} using
% \cs{addxcontentsline} instead of \cs{addcontentsline}.
%    \begin{macrocode}
\NewDocumentCommand\addxcontentslinetoeachtocfile{omom}{%
  \doforeachtocfile[{#1}]{\addxcontentsline{\@currext}{#2}[{#3}]{#4}}
}
%</body>
%    \end{macrocode}
% \end{command}
%
% \ExplSyntaxOn
% \begin{macro}{\@@_chapter_patch_code:,\tocbasic@chapter@skip}
% \ExplSyntaxOff
%   From version 3.42 \pkg*{tocbasic} provides the feature to patch
%   \cs{@makechapterhead} to add a vertical space to every ToC of category
%   \texttt{float}. From version 3.46 this is extended to also allow
%   patching \cs{@makeschapterhead} and the code is moved to an internal
%   macro. Patching of \cs{@makeschapterhead} is only supported as extension
%   of \cs{@makechapterhead}.
%    \begin{macrocode}
%<*body>
\if@tocbasic@old@latex@found\else
  \ExplSyntaxOn
  \cs_new:Npn \@@_chapter_patch_code:
    {
      \cs_if_exist:NTF \KOMAClassName
        {
          \exp_args:Nnnx \msg_warn:nnnn { tocbasic } { dangerous-patch }
            { \KOMAClassName } { chapter }
        }
        {
          \exp_args:Nnnx \msg_note:nnnn { tocbasic } { dangerous-patch }
            { } { chapter }
        }
      \hook_gput_code:nnn { cmd/@makechapterhead/before } { tocbasic }
        {
          \doforeachtocfile[float]{
            \addtocontents{\@currext}{\tocbasic@chapter@skip}
          }
        }
      \bool_if:cT { g_@@_patch_chapter*_bool }
        {
          \hook_gput_code:nnn { cmd/@makeschapterhead/before } { tocbasic }
            {
              \doforeachtocfile[float]{
                \addtocontents{\@currext}{\tocbasic@chapter@skip}
              }
            }
        }
      \ProvideDocumentCommand \tocbasic@chapter@skip { } { \addvspace{10\p@} }
    }
  \ExplSyntaxOff
\fi
%</body>
%    \end{macrocode}
% \end{macro}
% \ExplSyntaxOff
%
%
% \subsection{Show list of toc-file}
% \label{sec:showlistoftocfile}
%
% If you have a toc-file you want a list-of-command for this toc-file,
% too. Here are basics and high level commands for this.
%
% \begin{macro}{\tocbasic@starttoc}
% \changes{v3.17}{2015/03/23}{usage of feature \opt{noparskipfake}}
% \changes{v3.27}{2019/07/08}{hack to add \cs{par} at end of (main) file}
% \changes{v3.28}{2019/11/19}{\cs{iftocfeature} replaced by
%   \cs{Iftocfeature}}
% \changes{v3.32}{2020/08/25}{replace \cs{par} hack by \cs{par} solution}
% \changes{v3.32}{2020/08/25}{reentrant warning}
% Some basics are done like setting up \cs{parskip}, \cs{parindent} and
% \cs{parfillskip}, a general hook will be called, an individual hook will
% be called, the toc will be started, an individual hook will be called, an
% general hook wil be called, that's it.
%    \begin{macrocode}
%<*body>
%<@@=>
\newcommand*{\tocbasic@starttoc}[1]{%
  \begingroup
    \tocbasic@reentrant@warning
    \def\tocbasic@reentrant@warning{%
      \PackageWarning{tocbasic}{%
        Loading one auxiliary file inside the setup context\MessageBreak
        of another auxiliary file is not recommended.\MessageBreak
        In this case settings for `\@currext' could also influence\MessageBreak
        settings of `#1' and local states of `#1' can also\MessageBreak
        influence local states of `\@currext'%
      }%
    }%
    \edef\@currext{#1}%
    \Iftocfeature{\@currext}{noparskipfake}{}{%
      \ifvmode
        \@tempskipa\lastskip
        \vskip-\lastskip
        \addtolength{\@tempskipa}{\parskip}%
        \vskip\@tempskipa
      \fi
    }%
    \setlength{\parskip}{\z@}%
    \setlength{\parindent}{\z@}%
    \setlength{\parfillskip}{\z@\@plus 1fil}%
    \csname tocbasic@@before@hook\endcsname
    \csname tb@#1@before@hook\endcsname
    \@starttoc{#1}%
    \BeforeClosingMainAux{%
      \addtocontents{#1}{%
        \string\providecommand\string\tocbasic@end@toc@file{}%
        \string\tocbasic@end@toc@file
      }%
    }%
    \edef\@currext{#1}%
    \csname tb@#1@after@hook\endcsname
    \csname tocbasic@@after@hook\endcsname
  \endgroup
}
%    \end{macrocode}
% \begin{macro}{tocbasic@end@toc@file}
% \changes{v3.32}{2020/08/25}{added}
%    \begin{macrocode}
\newcommand*{\tocbasic@end@toc@file}{\par}
%    \end{macrocode}
% \end{macro}^^A \tocbasic@end@toc@file
% \begin{macro}{\tocbasic@reentrant@warning}
% \changes{v3.32}{2020/08/25}{added}
%    \begin{macrocode}
\newcommand*{\tocbasic@reentrant@warning}{}
%    \end{macrocode}
% \end{macro}^^A \tocbasic@reentrant@warning
% \begin{macro}{\tocbasic@@before@hook,\tocbasic@@after@hook}
% These are the general hooks. They may be used by classes and packages for
% commands, that should be used for all lists of not only the own lists of,
% e.\,g., \KOMAScript{} may use it to handle option \opt{tocleft}.
%    \begin{macrocode}
\newcommand*{\tocbasic@@before@hook}{}
\newcommand*{\tocbasic@@after@hook}{}
%    \end{macrocode}
% \end{macro}^^A \tocbasic@@before@hook,\tocbasic@@after@hook
% \begin{command}{\BeforeStartingTOC,\AfterStartingTOC}
% \changes{v3.04b}{2010/01/05}{fix:define the hook if not already defined}
% \changes{v3.06}{2010/06/09}{fix: using \cs{@ifundefined} instead of
%   undefined \cs{scr@ifundefinedorrelax}}
% \changes{v3.26}{2018/08/10}{message moved to \texttt{trace}}
% These are the commands to add code to the general or individual hooks. If
% the first, optional argument was given, the second, mandatory argument
% will be added to the individual hook, otherwise the general hook will be
% extended.
%    \begin{macrocode}
\newcommand{\BeforeStartingTOC}[2][]{%
  \ifx\relax#1\relax
    \g@addto@macro\tocbasic@@before@hook{#2}%
  \else
    \@ifundefined{tb@#1@before@hook}{%
%<*trace>
      \PackageInfo{tocbasic}{defining new hook before starting
        \IfArgIsEmpty{#1}{any toc}{`#1'}}%
%</trace>
      \expandafter\global\expandafter\let\csname tb@#1@before@hook\endcsname
      \@empty
    }{}%
    \expandafter\g@addto@macro\csname tb@#1@before@hook\endcsname{#2}%
  \fi
}
\newcommand{\AfterStartingTOC}[2][]{%
  \ifx\relax#1\relax
    \g@addto@macro\tocbasic@@after@hook{#2}%
  \else
    \@ifundefined{tb@#1@after@hook}{%
%<*trace>
      \PackageInfo{tocbasic}{defining new hook after starting
        \IfArgIsEmpty{#1}{any toc}{`#1'}}%
%</trace>
      \expandafter\global\expandafter\let\csname tb@#1@after@hook\endcsname
      \@empty
    }{}%
    \expandafter\g@addto@macro\csname tb@#1@after@hook\endcsname{#2}%
  \fi
}
%<@@=tocbasic>
%    \end{macrocode}
% \end{command}^^A \BeforeStartingTOC,\AfterStartingTOC
% \end{macro}^^A \tocbasic@starttoc
%
% \begin{command}{\listoftoc}
% \changes{v3.20}{2016/04/12}{\cs{@ifstar} replaced by \cs{kernel@ifstar}}
% \begin{macro}{\@listoftoc}
% \changes{v1.0a}{2008/11/12}{\cs{twocolumn} fixed}
% \changes{v1.01}{2008/11/13}{new feature \opt{onecolumn}}
% \changes{v3.09}{2011/03/01}{\cs{@currext} defined using \cs{edef} instead
%   of \cs{def}}
% \changes{v3.28}{2019/11/19}{\cs{iftocfeature} replaced by
%   \cs{Iftocfeature}}
% \changes{v3.31}{2020/07/08}{use one time expansion of local
%   \cs{list@fname}}
% Command to handle the hole list of something. There are additional hooks
% for this. The first optional argument is the title for this list. If the
% optional argument was omitted \cs{listof\#2name} will be used. The star
% version does not set up a heading or switch the column number!
%    \begin{macrocode}
\newcommand*{\listoftoc}{%
  \kernel@ifstar \tocbasic@starttoc\@listoftoc
}
\newcommand*{\@listoftoc}[2][]{%
  \begingroup
    \def\list@fname{#1}%
    \@ifundefined{listof#2name}{%
      \ifx\list@fname\@empty
        \PackageWarning{tocbasic}{%
          You should either define \expandafter\string\csname
          listof#2name\endcsname\MessageBreak
          or use the optional argument of \string\listoftoc\space\MessageBreak
          to set the term to be used for the\MessageBreak
          heading of list of #2}%
        \def\list@fname{\listofname~#2}%
      \fi
    }{%
      \expandafter\let\expandafter\list@fname\csname listof#2name\endcsname
    }%
    \edef\@currext{#2}%
    \Iftocfeature{\@currext}{onecolumn}{%
      \Iftocfeature{\@currext}{leveldown}{}{%
        \if@twocolumn
          \aftergroup\twocolumn\onecolumn
        \fi
      }%
    }{}%
    \Iftocfeature{\@currext}{numberline}{\def\nonumberline{\numberline{}}}{}%
    \expandafter\tocbasic@listhead\expandafter{\list@fname}%
    \scr@ifundefinedorrelax{microtypesetup}{}{%
      \Iftocfeature{\@currext}{noprotrusion}{}{%
        \microtypesetup{protrusion=false}%
        \PackageInfo{tocbasic}{%
          character protrusion at \@currext\space deactivated}%
      }%
    }%
    \tocbasic@starttoc{#2}%
  \endgroup
}
%    \end{macrocode}
% \end{macro}
% \end{command}
%
% \ExplSyntaxOn
% \begin{macro}{\@@_listof_patch_code:nn}
% \ExplSyntaxOff
% \changes{v3.46}{2025/06/10}{added}
% Patch \cs{listof\#1} with extension \texttt{\#2} to use \cs{listoftoc}.
%    \begin{macrocode}
\if@tocbasic@old@latex@found\else
  \ExplSyntaxOn
  \cs_new:Nn \@@_listof_patch_code:n
    {
      \cs_set:cpn { listof#1s } { \exp_args:Nc \listoftoc { ext@#1  } }
      \cs_if_exist:cF { listof \use:c { ext@#1 } name }
        {
          \cs_new:cpn { listof \use:c { ext@#1 } name }
            { \use:c { list#1name } }
        }
    }
  \ExplSyntaxOff
\fi
%    \end{macrocode}
% \end{macro}
% \ExplSyntaxOff
%
% \changes{v3.25}{2017/11/21}{\pkg{tocbibind} warning added}
% \changes{v3.46}{2025/06/16}{revert to \cs{IfPackageLoadedTF} instead of
%   \cs{IfPackageLoadedF} and \cs{IfPackageLoadedT}, because in \LaTeX{}
%   2022-06-01 is only the first one available}
% Using \pkg{tocbibind} and \pkg*{tocbasic} together can break features
% either of \pkg{tocbibind} or \pkg*{tocbasic}.  Here we add at least a
% warning:
%    \begin{macrocode}
\IfPackageLoadedTF{tocbibind}{}{%
  \AtBeginDocument{%
    \IfPackageLoadedTF{tocbibind}{%
      \PackageInfo{tocbasic}{usage of `tocbibind' detected}%
      \newcommand*{\tb@tocbibindpatch}[3]{%
        \long\def\reserved@a{\tocfile{#2}{#1} }%
        \ifx #3\reserved@a
          \PackageWarningNoLine{tocbasic}{%
            `tocbibind' redefinition of `\string#3'\MessageBreak
            detected.\MessageBreak
            Note: Loading `tocbibind' without option `not#1'\MessageBreak
            can break several features of `tocbasic'%
            \scr@ifundefinedorrelax{KOMAClassName}{%
              .\MessageBreak
              Loading `tocbibind' before `tocbasic' would avoid\MessageBreak
              this warning message%
            }{}%
          }%
        \fi
      }%
      \tb@tocbibindpatch{toc}{\contentsname}{\tableofcontents}%
      \tb@tocbibindpatch{lof}{\listfigurename}{\listoffigures}%
      \tb@tocbibindpatch{lot}{\listtablename}{\listoftables}%
    }{}%
  }%
}
%    \end{macrocode}
%
% \begin{command}{\listofname}
% While this is only an emergency command, we don't support languages.
%    \begin{macrocode}
\newcommand*{\listofname}{List of}
%    \end{macrocode}
% \end{command}
%
% \begin{command}{\listofeachtoc}
% \changes{v3.03b}{2009/06/08}{typo fix at usage of \cs{doforeachtocfile}}
% \changes{v3.20}{2016/04/12}{\cs{@ifnextchar} replaced by
%   \cs{kernel@ifnextchar}}
% \changes{v3.41}{2023/06/28}{using \cs{NewDocumentCommand} to not need all
%   the helpers}
% Another example of using \cs{doforeachtocfile}.
%    \begin{macrocode}
\NewDocumentCommand\listofeachtoc{o}{%
  \doforeachtocfile[{#1}]{\listoftoc{\@currext}}%
}
%    \end{macrocode}
% \end{command}
%
% \begin{macro}{\ext@toc}
% \changes{v3.23}{2017/02/23}{use indirect extension for toc}
% We do not longer hard code extension \file{toc} for the table of
% contents. This allowes users to change it. Classes or other packages may
% also define it. So it seems to be better to \cs{providecommand} instead of
% \cs{newcommand} here.
%    \begin{macrocode}
\providecommand*{\ext@toc}{toc}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\tocbasic@listhead}
% \changes{v3.02a}{2009/01/20}{no explicite marks if ``numbered''}
% \changes{v3.09a}{2011/04/12}{again no explicite marks if ``numbered''}
% \changes{v3.12}{2013/09/24}{usage of new \cs{tocbasic@addxcontentsline}}
% \changes{v3.15}{2014/12/10}{moved \cs{@mkboth} inside \cs{chapter*}}
% \changes{v3.15}{2014/12/10}{usage of \cs{addsec} if available}
% \changes{v3.15}{2014/12/10}{usage of \cs{@mkright} if available}
% \changes{v3.17}{2015/03/08}{moved \cs{@mkboth} outside \cs{chapter*}}
% \changes{v3.17}{2015/03/08}{usage of \cs{@mkdouble} if available}
% \changes{v3.17}{2015/03/25}{penalty and skip reconstruction after
%   \cs{@mkright}, \cs{@mkboth}, or \cs{@mkdouble}}
% \changes{v3.26}{2018/06/22}{removed spurious group}
% \changes{v3.26}{2018/09/03}{usage of \cs{addsecmark} or \cs{sectionmark}
%   instead of \cs{@mkright} or \cs{markright}}
% \changes{v3.28}{2019/11/19}{\cs{iftocfeature} replaced by
%   \cs{Iftocfeature}}
% Setting the headings of a list of something. The heading is the only
% argument.
%    \begin{macrocode}
%<@@=>
\newcommand*{\tocbasic@listhead}[1]{%
  \@ifundefined{tocbasic@listhead@\@currext}{%
    \scr@ifundefinedorrelax{chapter}{%
      \expandafter\def\csname tocbasic@listhead@\@currext\endcsname##1{%
        \Iftocfeature{\@currext}{leveldown}{%
          \Iftocfeature{\@currext}{numbered}{%
            \subsection[##1]{##1}%
          }{%
            \subsection*{##1}%
            \ifvmode\@tempcnta\lastpenalty\@tempskipa\lastskip\unskip\fi
            \begingroup
              \Iftocfeature{\@currext}{totoc}{%
                \expandafter\addxcontentsline\expandafter{\ext@toc}%
                {subsection}{##1}%
              }{}%
              \c@secnumdepth=-\maxdimen
              \subsectionmark{##1}%
            \endgroup
            \ifvmode\penalty\@tempcnta\vskip\@tempskipa\fi
          }%
        }{%
          \Iftocfeature{\@currext}{numbered}{%
            \section[##1]{##1}%
          }{%
            \section*{##1}%
            \ifvmode\@tempcnta\lastpenalty\@tempskipa\lastskip\unskip\fi
            \begingroup
              \Iftocfeature{\@currext}{totoc}{%
                \expandafter\addxcontentsline\expandafter{\ext@toc}%
                {section}{##1}%
              }{}%
              \@ifundefined{@mkdouble}{%
                \@mkboth{\MakeMarkcase{##1}}{\MakeMarkcase{##1}}%
              }{%
                \@mkdouble{\MakeMarkcase{##1}}%
              }%
            \endgroup
            \ifvmode\penalty\@tempcnta\vskip\@tempskipa\fi
          }%
        }%
      }%
    }{%
      \expandafter\def\csname tocbasic@listhead@\@currext\endcsname##1{%
        \Iftocfeature{\@currext}{leveldown}{%
          \Iftocfeature{\@currext}{numbered}{%
            \section{##1}%
          }{%
            \Iftocfeature{\@currext}{totoc}{%
              \@ifundefined{addsec}{%
                \section*{##1}%
                \ifvmode\@tempcnta\lastpenalty\@tempskipa\lastskip\unskip\fi
                \begingroup
                  \@ifundefined{@mkright}{%
                    \IfActiveMkBoth{\markright{\MakeMarkcase{##1}}}{}%
                  }{%
                    \@mkright{\MakeMarkcase{##1}}%
                  }%
                  \expandafter\addxcontentsline\expandafter{\ext@toc}%
                  {section}{##1}%
                \endgroup
                \ifvmode\penalty\@tempcnta\vskip\@tempskipa\fi
              }{%
                \addsec{##1}%
              }%
            }{%
              \section*{##1}%
              \ifvmode\@tempcnta\lastpenalty\@tempskipa\lastskip\unskip\fi
              \begingroup
                \@ifundefined{addsecmark}{%
                  \c@secnumdepth=-\maxdimen
                  \sectionmark{##1}%
                }{%
                  \addsecmark{##1}%
                }%
              \endgroup
              \ifvmode\penalty\@tempcnta\vskip\@tempskipa\fi
            }%
          }%
        }{%
          \Iftocfeature{\@currext}{numbered}{%
            \chapter[##1]{##1}%
          }{%
            \chapter*{##1}%
            \ifvmode\@tempcnta\lastpenalty\@tempskipa\lastskip\unskip\fi
            \begingroup
              \@ifundefined{@mkdouble}{%
                \@mkboth{\MakeMarkcase{##1}}{\MakeMarkcase{##1}}%
              }{%
                \@mkdouble{\MakeMarkcase{##1}}%
              }%
              \Iftocfeature{\@currext}{totoc}{%
                \expandafter\addxcontentsline\expandafter{\ext@toc}%
                {chapter}{##1}%
              }{}%
            \endgroup
            \ifvmode\penalty\@tempcnta\vskip\@tempskipa\fi
          }%
        }%
      }%
    }%
  }{}%
  \csname tb@@beforehead@hook\endcsname
  \csname tb@\@currext @beforehead@hook\endcsname
  \csname tocbasic@listhead@\@currext\endcsname{#1}%
  \csname tb@\@currext @afterhead@hook\endcsname
  \csname tb@@afterhead@hook\endcsname
}
%<@@=tocbasic>
%    \end{macrocode}
% \begin{command}{\BeforeTOCHead,\AfterTOCHead}
% \changes{v3.04b}{2010/01/05}{fix: define the hook if not already defined}
% \changes{v3.06}{2010/06/09}{fix: using \cs{@ifundefined} instead of
%   undefined \cs{scr@ifundefinedorrelax}}
% \changes{v3.26}{2018/08/10}{message moved to \texttt{trace}}
% These are the commands to add code to the general or individual hooks. If
% the first, optional argument was given, the second, mandatory argument
% will be added to the individual hook, otherwise the general hook will be
% extended.
%    \begin{macrocode}
\newcommand{\BeforeTOCHead}[2][]{%
  \@ifundefined{tb@#1@beforehead@hook}{%
%<*trace>
    \PackageInfo{tocbasic}{defining new hook before heading of
      \IfArgIsEmpty{#1}{each toc}{`#1'}}%
%</trace>
    \expandafter\global\expandafter\let\csname tb@#1@beforehead@hook\endcsname
    \@empty
  }{}%
  \expandafter\g@addto@macro\csname tb@#1@beforehead@hook\endcsname{#2}%
}
\newcommand{\AfterTOCHead}[2][]{%
  \@ifundefined{tb@#1@afterhead@hook}{%
%<*trace>
    \PackageInfo{tocbasic}{defining new hook after heading of
      \IfArgIsEmpty{#1}{each toc}{`#1'}}%
%</trace>
    \expandafter\global\expandafter\let\csname tb@#1@afterhead@hook\endcsname
    \@empty
  }{}%
  \expandafter\g@addto@macro\csname tb@#1@afterhead@hook\endcsname{#2}%
}
%</body>
%    \end{macrocode}
% \end{command}
% \end{macro}
%
% \begin{command}{\MakeMarkcase}
% Use upper-case or not?
%    \begin{macrocode}
%<*exit>
\AtBeginDocument{%
  \@ifundefined{MakeMarkcase}{%
    \scr@ifundefinedorrelax{KOMAClassName}{%
      \let\MakeMarkcase\MakeUppercase
    }{%
      \let\MakeMarkcase\@firstofone
    }%
  }{}%
}
%</exit>
%    \end{macrocode}
% \end{command}
%
% \begin{command}{\deftocheading}
% Define a toc headings command with one argument (the title).
%    \begin{macrocode}
%<*body>
\newcommand*{\deftocheading}[1]{%
  \@namedef{tocbasic@listhead@#1}##1}
%    \end{macrocode}
% \end{command}
%
% \begin{command}{\setuptoc,\unsettoc}
% \changes{v3.26}{2018/08/29}{using \cs{scr@trim@spaces} instead of
%   \cs{tb@@sp@def}}
% Known features are:
% \begin{description}
% \item[\opt{totoc}] writes the title of the list of to the table of
%   contents
% \item[\opt{numberline}] redefines \cs{nonumberline} to use
%   \cs{numberline}
% \item[\opt{numbered}] uses a numbered headings for the list of
% \item[\opt{leveldown}] uses not the top level heading (e.\,g.,
%   \cs{chapter} with book) but the first sub level (e.\,g., \cs{section} with
%   book).
% \item[\opt{nobabel}] prevents the extension to be added to the babel
%   handling of toc-files.  To make this work, you have to set the feature
%   before adding the extension to the list of known extension.
% \item[\opt{noprotrusion}] prevents disabling character protrusion at
%   the toc.
% \end{description}
% Other features may be package dependent. You may test the feature using:
% \begin{quote}
%   \cs{@ifundefined}\texttt{\{tocbasic@\meta{toc}@feature@\meta{feature}\}}\\
%   \phantom{\cs{@ifundefined}}\marg{do if feature not set}\\
%   \phantom{\cs{@ifundefined}}\marg{do if feature set}
% \end{quote}
% See \cs{tocbasic@listhead} for an example of this.
%    \begin{macrocode}
\newcommand*{\setuptoc}[2]{%
  \@for\@tempa:=#2\do{%
    \scr@trim@spaces\@tempa
    \@namedef{tocbasic@#1@feature@\@tempa}{}%
  }%
}
\newcommand*{\unsettoc}[2]{%
  \@for\@tempa:=#2\do{%
    \scr@trim@spaces\@tempa
    \expandafter\let\csname tocbasic@#1@feature@\@tempa\endcsname\relax
  }%
}
%    \end{macrocode}
% Do not add the files, that babel handles by default.
%    \begin{macrocode}
\setuptoc{toc}{nobabel}
\setuptoc{lof}{nobabel}
\setuptoc{lot}{nobabel}
%    \end{macrocode}
% \begin{command}{\Iftocfeature,\iftocfeature}
% \changes{v3.28}{2019/11/19}{\cs{iftocfeature} renamed to \cs{Iftocfeature}}
% We need a test for the features
%    \begin{macrocode}
%<*deprecated>
\providecommand*{\iftocfeature}{%
  \PackageWarning{tocbasic}{Usage of deprecated command
    `\string\iftocfeature'.\MessageBreak
    The command has been renamed because of a\MessageBreak
    recommendation of The LaTeX Project Team.\MessageBreak
    Please replace `\string\iftocfeature' by `\string\Iftocfeature'%
  }%
  \Iftocfeature
}
%</deprecated>
\newcommand*{\Iftocfeature}[2]{%
  \scr@ifundefinedorrelax{tocbasic@#1@feature@#2}{%
    \expandafter\@secondoftwo
  }{%
    \expandafter\@firstoftwo
  }%
}
%</body>
%    \end{macrocode}
% \end{command}
% \end{command}
%
% \begin{command}{\tocbasicautomode}
% \changes{v1.0a}{2008/11/11}{use of \cs{addtotoclist} instead of
%   internal}
% \changes{v3.07a}{2010/11/25}{fix: added missing
%   \cs{let}\cs{@starttoc}\cs{tocbasic@starttoc}}
% \changes{v3.28}{2019/11/19}{\cs{ifattoclist} replaced by
%   \cs{Ifattoclist}}
% \pkg*{tocbasic} can overtake \cs{@starttoc} to automaticly add all
% used extensions to the list of known extensions and use
% \cs{tocbasic@starttoc} instead of \cs{@starttoc} from \LaTeX{}
% kernel. Please note, that we don't need a fix for the unfriendly
% redefinition of \cs{@starttoc} by \pkg{hyperref}, because hyperref
% does it only at the first \LaTeX{} run. So this action of \pkg{hyperref}
% may only result in the need of one more \LaTeX{} run, but not in a permanent
% mistake.
%    \begin{macrocode}
%<*body>
\newcommand*{\tocbasicautomode}{%
  \let\tb@saved@starttoc\@starttoc
  \let\@starttoc\tocbasic@starttoc
  \BeforeStartingTOC{%
    \let\@starttoc\tb@saved@starttoc
    \expandafter\Ifattoclist\expandafter{\@currext}{}{%
      \addtotoclist[tocbasicautomode]{\@currext}%
    }%
  }%
}
%</body>
%    \end{macrocode}
% \end{command}
%
%
% \subsection{High level interface for generating new ToCs and floats resp. nonfloats}
% \label{sec:newfloats}
%
% \begin{command}{\DeclareNewTOC}
% \changes{v3.06}{2010/06/01}{added}
% \changes{v3.18}{2015/06/20}{\cs{tb@nt@types} and \cs{tb@nt@listname} are
%   initialised \cs{relax}}
% \changes{v3.20}{2016/04/12}{\cs{@ifnextchar} replaced by
%   \cs{kernel@ifnextchar}}
% \changes{v3.26a}{2018/12/30}{fixed usage of \cs{kernel@ifnextchar}}
% \changes{v3.28}{2019/11/18}{\cs{ifstr} renamed to \cs{Ifstr}}
% This command defines only a new TOC and a new caption command for this
% TOC.  It does not define a new foat unless option float was set!  It does
% not define a new nonfloat unless option nonfloat was set!  The optional
% argument is used to set up several settings using \pkg{keyval}.  The
% mandatory argument is the shortcut.  The default type is the shortcut.
% The extension is the shortcut.  The default owner is ``\texttt{float}''.
%    \begin{macrocode}
%<*body>
\DefineFamily{KOMAarg}
\DefineFamilyMember[.toc]{KOMAarg}
\newcommand*{\DeclareNewTOC}[2][]{%
  \newif\iftb@nt@float
  \newif\iftb@nt@nonfloat
  \newif\iftb@nt@forcenames
  \def\tb@nt@floattype{\tb@nt@autofloattype}%
  \def\tb@nt@floatpos{tbp}%
  \def\tb@nt@ext{#2}%
  \edef\tb@nt@type{#2}%
  \let\tb@nt@types\relax
  \def\tb@nt@owner{float}%
%    \end{macrocode}
% \begin{description}
% \item[ToDo:] We still do not use \cs{MakeTitlecase} of \LaTeX{} from
%   2022/06/01~PL\,5 here (and later), because \pkg{hyperref} 2022-06-20
%   v7.00s is still not able to process it. So we would get a warning message
%   instead of switching to uppercase. But maybe in some future, this could be
%   changed.
% \end{description}
%    \begin{macrocode}
  \def\tb@nt@name{\expandafter\protect\expandafter\MakeUppercase\tb@nt@type}%
  \let\tb@nt@listname\relax
  \let\tb@nt@counterwithin\@empty
  \let\tb@nt@atbegin\@empty
  \let\tb@nt@atend\@empty
  \def\tb@nt@tocentrystyle{default}%
%    \end{macrocode}
% \changes{v3.20}{2016/04/29}{need more initialization for empty optional
%   argument}
%    \begin{macrocode}
  \def\tb@nt@tocstyle@options{level=1}%
  \IfArgIsEmpty{#1}{%
%    \end{macrocode}
% Also need to call the style init code, to set the defaults for options
% \opt{numwidth} and \opt{indent}.
%    \begin{macrocode}
    \begingroup
      \let\scr@dte@current\tb@nt@type
      \@ExecuteTOCEntryStyleInitCode{\tb@nt@tocentrystyle}{\tb@nt@type}%
      \def\do@endgroup{\endgroup}%
      \def\do##1{%
        \Ifstr{##1}{numwidth}{%
          \l@addto@macro\do@endgroup{%
            \l@addto@macro{\tb@nt@tocstyle@options}{,numwidth=1.5em}%
          }%
        }{%
          \Ifstr{##1}{indent}{%
%<trace>            \PackageInfo{tocbasic}{%
%<trace>              TRACE \string\DeclareNewTOC[...]{#2}:
%<trace>              set default indent 1em}%
            \l@addto@macro\do@endgroup{%
              \l@addto@macro{\tb@nt@tocstyle@options}{,indent=1em}%
            }%
          }{}%
        }%
        \kernel@ifnextchar[%]
          {\@dodefault}%
          {}%
      }%
      \def\@dodefault[##1]{}%
      \scr@dte@doopts
    \do@endgroup
  }{%
    \let\tb@nt@extra@relax@opts\@empty
%    \end{macrocode}
% After initialisation of the local values we need to know the style of the
% toc entry, to define style dependend options.
% \begin{macro}{\tb@nt@type}
% \changes{v3.20}{2015/12/16}{locally valid only}
% The type of list is used for environment and counter names and as part of
% several internal and user macros. It is needed before defining the style
% dependend options. So we use a first run to set it up.
%    \begin{macrocode}
    \DefineFamilyKey[.toc]{KOMAarg}{type}{%
      \tb@ifvalueisnotempty{##1}{\edef\tb@nt@type{##1}}%
    }%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\tb@nt@tocentrystyle}
% \changes{v3.20}{2015/12/16}{added}
% The style of the toc entry. It is needed before defining the style
% dependend options. So we use a first run to set it up.
%    \begin{macrocode}
    \DefineFamilyKey[.toc]{KOMAarg}{tocentrystyle}[default]{%
      \IfArgIsEmpty{##1}{%
        \edef\tb@nt@tocentrystyle{##1}%
        \FamilyKeyStateProcessed
      }{%
        \scr@ifundefinedorrelax{scr@dte@def@l@##1}{%
          \FamilyKeyStateUnknownValue
        }{%
          \edef\tb@nt@tocentrystyle{##1}%
          \FamilyKeyStateProcessed
        }%
      }%
    }%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\tb@nt@ext}
% \changes{v3.20}{2015/12/16}{locally valid only}
% \changes{v3.25}{2017/11/20}{moved to pass 1}
% Don't tell the user, that the mandatory argument of the command may be
% overloaded by this option. This was only done to simplify the definition.
%    \begin{macrocode}
    \DefineFamilyKey[.toc]{KOMAarg}{extension}{%
      \tb@ifvalueisnotempty{##1}{\edef\tb@nt@ext{##1}}%
    }%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\tb@nt@owner}
% \changes{v3.20}{2015/12/16}{locally valid only}
% \changes{v3.26}{2018/06/09}{moved to pass 1}
% \changes{v3.27}{2019/05/12}{\opt{category} is a synonym for \opt{owner}}
% The owner of the new list extension.
%    \begin{macrocode}
    \DefineFamilyKey[.toc]{KOMAarg}{owner}{%
      \tb@ifvalueisnotempty{##1}{\edef\tb@nt@owner{##1}}%
    }%
    \DefineFamilyKey[.toc]{KOMAarg}{category}{%
      \tb@ifvalueisnotempty{##1}{\edef\tb@nt@owner{##1}}%
    }%
%    \end{macrocode}
% \end{macro}
% After this we define pseudo option \opt{@else@} to ignore all currently
% not needed options. After this we do the first option execution run.
%    \begin{macrocode}
    \DefineFamilyKey[.toc]{KOMAarg}{@else@}{\FamilyKeyStateProcessed}%
    \FamilyExecuteOptions[.toc]{KOMAarg}{#1}%
    \RelaxFamilyKey[.toc]{KOMAarg}{@else@}%
%    \end{macrocode}
% \changes{v3.26}{2018/06/09}{add extension already after first pass}
% First of all, every TOC needs an extension, that should be added to the
% list of known extensions. This has to be done also, if no options has been
% given!
%    \begin{macrocode}
  }%
  \expandafter\newcommand\csname ext@\tb@nt@type\endcsname{}%
  \expandafter\let\csname ext@\tb@nt@type\endcsname\tb@nt@ext
  \addtotoclist[\tb@nt@owner]{\csname ext@\tb@nt@type\endcsname}%
  \IfArgIsEmpty{#1}{}{%
%    \end{macrocode}
% For the second option pass we do not need to set up these options
% again. So define it as no-opt.
%    \begin{macrocode}
    \DefineFamilyKey[.toc]{KOMAarg}{type}{\FamilyKeyStateProcessed}%
    \DefineFamilyKey[.toc]{KOMAarg}{tocentrystyle}{\FamilyKeyStateProcessed}%
    \DefineFamilyKey[.toc]{KOMAarg}{extension}{\FamilyKeyStateProcessed}%
    \DefineFamilyKey[.toc]{KOMAarg}{category}{\FamilyKeyStateProcessed}%
%    \end{macrocode}
% \changes{v3.20}{2015/12/16}{defining toc style depending options}
% \changes{v3.20}{2016/06/12}{using prefix \opt{tocentry} instead of
%     \opt{toc}}
% \changes{v3.27}{2019/10/02}{additional \opt{:}-options}
% If the toc style is empty we won't define any \cs{l@\dots}. Otherwise we
% need to define additional options.
%    \begin{macrocode}
    \Ifstr{\tb@nt@tocentrystyle}{}{}{%
      \begingroup
        \let\scr@dte@current\tb@nt@type
        \@ExecuteTOCEntryStyleInitCode{\tb@nt@tocentrystyle}{\tb@nt@type}%
        \def\do@endgroup{\endgroup}%
        \def\do##1{%
          \l@addto@macro\do@endgroup{%
            \l@addto@macro\tb@nt@extra@relax@opts{%
              \RelaxFamilyKey[.toc]{KOMAarg}{toc##1}%
              \RelaxFamilyKey[.toc]{KOMAarg}{tocentry##1}%
              \RelaxFamilyKey[.toc]{KOMAarg}{tocentry##1:}%
            }%
          }%
          \kernel@ifnextchar[%]
            {\@dodefault{##1}}%
            {\@donodefault{##1}}%
        }%
        \def\@donodefault##1{%
          \l@addto@macro\do@endgroup{%
            \DefineFamilyKey[.toc]{KOMAarg}{toc##1}{%
              \PackageWarning{tocbasic}{you should use `tocentry##1'
                instead\MessageBreak
                of `toc##1'}%
              \l@addto@macro{\tb@nt@tocstyle@options}{,##1={####1}}%
              \FamilyKeyStateProcessed
            }%
            \DefineFamilyKey[.toc]{KOMAarg}{tocentry##1}{%
              \l@addto@macro{\tb@nt@tocstyle@options}{,##1={####1}}%
              \FamilyKeyStateProcessed
            }%
            \DefineFamilyKey[.toc]{KOMAarg}{tocentry##1:}{%
              \l@addto@macro{\tb@nt@tocstyle@options}{,##1:={####1}}%
            }%
          }%
        }%
        \def\@dodefault##1[##2]{%
          \l@addto@macro\do@endgroup{%
            \DefineFamilyKey[.toc]{KOMAarg}{toc##1}[##2]{%
              \PackageWarning{tocbasic}{you should use `tocentry##1'
                instead\MessageBreak
                of `toc##1'}%
              \l@addto@macro{\tb@nt@tocstyle@options}{,##1={####1}}%
              \FamilyKeyStateProcessed
            }%
            \DefineFamilyKey[.toc]{KOMAarg}{tocentry##1}[##2]{%
              \l@addto@macro{\tb@nt@tocstyle@options}{,##1={####1}}%
              \FamilyKeyStateProcessed
            }%
            \DefineFamilyKey[.toc]{KOMAarg}{tocentry##1:}{%
              \l@addto@macro{\tb@nt@tocstyle@options}{,##1:={####1}}%
            }%
          }%
        }%
        \scr@dte@doopts
      \do@endgroup
    }%
%    \end{macrocode}
% After this, we need to define all the other options and do the real option
% execution.
% \begin{macro}{\tb@nt@atbegin}
% \changes{v3.09}{2011/03/01}{new optional identifier \opt{atbegin}}
% \changes{v3.11c}{2013/02/01}{\opt{atbegin} argument may be empty}
% \changes{v3.20}{2015/12/16}{locally valid only}
% Additional code executed at the begin of a new defined environment.
%    \begin{macrocode}
    \FamilyStringKey[.toc]{KOMAarg}{atbegin}{\tb@nt@atbegin}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\tb@nt@atend}
% \changes{v3.09}{2011/03/01}{new optional identifier \opt{atbend}}
% \changes{v3.11c}{2013/02/01}{\opt{atend} argument may be empty}
% \changes{v3.20}{2015/12/16}{locally valid only}
% Additional code executed at the end of a new defined environment.
%    \begin{macrocode}
    \FamilyStringKey[.toc]{KOMAarg}{atend}{\tb@nt@atend}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\tb@nt@counterwithin}
% \changes{v3.20}{2015/12/16}{locally valid only}
% If a counter will be defined, this counter may depend on another counter
% (like figure counter depends on chapter counter at book classes). If the
% value is empty, the counter does not depend on any other counter.
%    \begin{macrocode}
    \DefineFamilyKey[.toc]{KOMAarg}{counterwithin}{%
      \edef\tb@nt@counterwithin{##1}\FamilyKeyStateProcessed
    }%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\iftb@nt@float}
% \changes{v3.20}{2015/12/16}{locally valid only}
% \changes{v3.06}{2010/06/01}{added}
% This boolean indicates, that float environments should also be defined.
%    \begin{macrocode}
    \FamilyBoolKey[.toc]{KOMAarg}{float}{tb@nt@float}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\tb@nt@floatpos}
% \changes{v3.20}{2015/12/16}{locally valid only}
% Simply the value for the |\fps@...| macro.
%    \begin{macrocode}
    \DefineFamilyKey[.toc]{KOMAarg}{floatpos}{%
      \tb@ifvalueisnotempty{##1}{\edef\tb@nt@floatpos{##1}}%
    }%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\tb@nt@floattype}
% \changes{v3.20}{2015/12/16}{locally valid only}
% Simply the value for the |\ftype@...| macro. It has to be
% $1<=\textrm{value}<=31$.
%    \begin{macrocode}
    \DefineFamilyKey[.toc]{KOMAarg}{floattype}{%
      \FamilySetCounterMacro{KOMAarg}{floattype}{\reserved@d}{##1}%
      \ifx\FamilyKeyState\FamilyKeyStateProcessed
        \ifnum 0=
          \ifnum\reserved@d<1 0 \else\ifnum\reserved@d>31 0 \else 1 \fi\fi
          \FamilyKeyStateUnknownValue
        \else
          \let\tb@nt@floattype\reserved@d
        \fi
      \fi
    }%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\iftb@nt@forcenames}
% \changes{v3.06}{2010/06/01}{added}
% \changes{v3.20}{2015/12/16}{locally valid only}
% The |\...name| commands will only be defined, if they are not already
% defined. But some users may want to define their own names even if there
% are already definitions. So this boolean option may switch to force the
% definition.
%    \begin{macrocode}
    \FamilyBoolKey[.toc]{KOMAarg}{forcenames}{tb@nt@forcenames}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}[noprint]{\tb@nt@hang}
% \changes{v3.20}{2015/12/16}{removed}
% \end{macro}
% Earch entry of a TOC/list of is idented on the left side. This is the
% amount of the indention of the text of the entry.
%    \begin{macrocode}
%<*deprecated>
    \DefineFamilyKey[.toc]{KOMAarg}{hang}{%
      \scr@ifundefinedorrelax{KV@KOMAarg.toc@tocnumwidth}{%
        \PackageWarning{tocbasic}{%
          deprecated option `hang'.\MessageBreak
          Option will be ignored, because toc entry style\MessageBreak
          `\tb@nt@tocentrystyle' does not provide option `numwidth'%
        }%
      }{%
        \PackageWarning{tocbasic}{%
          deprecated option `hang'.\MessageBreak
          You should replace option `hang' by option\MessageBreak
          `tocentrynumwidth'%
        }%
        \l@addto@macro\tb@nt@tocstyle@options{,numwidth={##1}}%
      }%
      \FamilyKeyStateProcessed
    }%
%</deprecated>
    \scr@ifundefinedorrelax{KV@KOMAarg.toc@tocnumwidth}{}{%
      \l@addto@macro\tb@nt@tocstyle@options{,numwidth=1.5em}%
    }%
%    \end{macrocode}
% \begin{macro}[noprint]{\tb@nt@indent}
% \changes{v3.20}{2015/12/16}{removed}
% \end{macro}
% Earch entry of a TOC/list of is idented on the left side. This is the
% amount of the indention of the number part.
%    \begin{macrocode}
%<*deprecated>
    \DefineFamilyKey[.toc]{KOMAarg}{indent}{%
      \scr@ifundefinedorrelax{KV@KOMAarg.toc@tocindent}{%
        \PackageWarning{tocbasic}{%
          deprecated option `indent'.\MessageBreak
          Option will be ignored, because toc entry style\MessageBreak
          `\tb@nt@tocentrystyle' does not provide option `indent'%
        }%
      }{%
        \PackageWarning{tocbasic}{%
          deprecated option `indent'.\MessageBreak
          You should replace option `indent' by option\MessageBreak
          `tocentryindent'%
        }%
        \l@addto@macro\tb@nt@tocstyle@options{,indent={##1}}%
      }%
      \FamilyKeyStateProcessed
    }%
%</deprecated>
    \scr@ifundefinedorrelax{KV@KOMAarg.toc@tocindent}{}{%
%<trace>      \PackageInfo{tocbasic}{%
%<trace>        TRACE \string\DeclareNewTOC[...]{#2}: set default indent 1em}%
      \l@addto@macro\tb@nt@tocstyle@options{,indent=1em}%
    }%
%    \end{macrocode}
% \begin{macro}[noprint]{\tb@nt@level}
% \changes{v3.20}{2015/12/16}{removed}
% \end{macro}
% \changes{v3.30}{2020/02/25}{spurious space in warning message removed}
% Each entry to a TOC/list of has a numeric level. You may set up your own
% level.
%    \begin{macrocode}
%<*deprecated>
    \DefineFamilyKey[.toc]{KOMAarg}{level}{%
      \PackageWarning{tocbasic}{%
        deprecated option `level'.\MessageBreak
        You should replace option `level' by option\MessageBreak
        `tocentrylevel'%
      }%
      \l@addto@macro\tb@nt@tocstyle@options{,level={##1}}%
      \FamilyKeyStateProcessed
    }%
%</deprecated>
%    \end{macrocode}
% \begin{macro}{\tb@nt@listname}
% \changes{v3.18}{2015/06/20}{using \cs{def} instead of \cs{edef}}
% \changes{v3.20}{2015/12/16}{locally valid only}
% The list itself has a heading. A |\list<type>name| will also be defined.
%    \begin{macrocode}
    \DefineFamilyKey[.toc]{KOMAarg}{listname}{%
      \tb@ifvalueisnotempty{##1}{\def\tb@nt@listname{##1}}%
    }%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\tb@nt@name}
% \changes{v3.20}{2015/12/16}{locally valid only}
% We need a name/term for the entries of the new list. This may e.\,g. be used
% for |caption| output. A |\<type>name| will also be defined.
%    \begin{macrocode}
    \DefineFamilyKey[.toc]{KOMAarg}{name}{%
      \tb@ifvalueisnotempty{##1}{\edef\tb@nt@name{##1}}%
    }%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\iftb@nt@nonfloat}
% \changes{v3.06}{2010/06/01}{added}
% \changes{v3.20}{2015/12/16}{locally valid only}
% This boolean indicates, that non-float environment should also be
% defined. The environment has the postfix ``-''.
%    \begin{macrocode}
    \FamilyBoolKey[.toc]{KOMAarg}{nonfloat}{tb@nt@nonfloat}%
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\tb@nt@types}
% \changes{v3.20}{2015/12/16}{locally valid only}
% Sometimes the plural of the type is needed and may be defined by a
% seperate option.
%    \begin{macrocode}
    \DefineFamilyKey[.toc]{KOMAarg}{types}{%
      \tb@ifvalueisnotempty{##1}{\edef\tb@nt@types{##1}}%
    }%
%    \end{macrocode}
% \end{macro}
% \changes{v3.25}{2017/11/20}{option \opt{setup} added}
% The new option \opt{setup} allowes to setup ToC features provided by
% \cs{setuptoc}. Note, currently there is no test whether or not a feature
% does exist!
%    \begin{macrocode}
    \DefineFamilyKey[.toc]{KOMAarg}{setup}{%
      \setuptoc\tb@nt@ext{##1}%
    }%
%    \end{macrocode}
% \changes{v3.25}{2017/11/20}{option \opt{unset} added}
% The new option \opt{unset} allowes to unset ToC features provided
% by \cs{unsettoc}. Note, currently there is no test whether or not a
% feature does exist!
%    \begin{macrocode}
    \DefineFamilyKey[.toc]{KOMAarg}{unset}{%
      \unsettoc\tb@nt@ext{##1}%
    }%
%    \end{macrocode}
% Last but not least we have to execute the options and reset the option
% definitions.
% \changes{v3.25}{2017/09/27}{\opt{nonfloat} fixed}
% \changes{v3.26}{2018/06/09}{added missing reset of \opt{unset} and
%   \opt{setup}}
%    \begin{macrocode}
    \FamilyExecuteOptions[.toc]{KOMAarg}{#1}%
    \RelaxFamilyKey[.toc]{KOMAarg}{unset}%
    \RelaxFamilyKey[.toc]{KOMAarg}{setup}%
    \RelaxFamilyKey[.toc]{KOMAarg}{types}%
    \RelaxFamilyKey[.toc]{KOMAarg}{nonfloat}%
    \RelaxFamilyKey[.toc]{KOMAarg}{name}%
    \RelaxFamilyKey[.toc]{KOMAarg}{listname}%
    \RelaxFamilyKey[.toc]{KOMAarg}{level}%
    \RelaxFamilyKey[.toc]{KOMAarg}{indent}%
    \RelaxFamilyKey[.toc]{KOMAarg}{hang}%
    \RelaxFamilyKey[.toc]{KOMAarg}{forcenames}%
    \RelaxFamilyKey[.toc]{KOMAarg}{floatpos}%
    \RelaxFamilyKey[.toc]{KOMAarg}{float}%
    \RelaxFamilyKey[.toc]{KOMAarg}{counterwithin}%
    \RelaxFamilyKey[.toc]{KOMAarg}{atend}%
    \RelaxFamilyKey[.toc]{KOMAarg}{atbegin}%
    \tb@nt@extra@relax@opts
    \RelaxFamilyKey[.toc]{KOMAarg}{category}%
    \RelaxFamilyKey[.toc]{KOMAarg}{owner}%
    \RelaxFamilyKey[.toc]{KOMAarg}{extension}%
    \RelaxFamilyKey[.toc]{KOMAarg}{tocentrystyle}%
    \RelaxFamilyKey[.toc]{KOMAarg}{type}%
  }%
%    \end{macrocode}
% We save the type of the extension at \cs{tb@nt@type@\meta{extension}}
% for later usage.
%    \begin{macrocode}
  \expandafter\let\csname tb@nt@type@\tb@nt@ext\endcsname\tb@nt@type
%    \end{macrocode}
% Then we need the TOC itself with a name:
% \changes{v3.25}{2017/10/10}{use \cs{ext@\dots} instead of the extension
%   itself in definition of \cs{listof\dots}}
%    \begin{macrocode}
  \scr@ifundefinedorrelax{tb@nt@types}{%
    \edef\tb@nt@types{\tb@nt@type s}%
  }{}%
  \scr@ifundefinedorrelax{tb@nt@listname}{%
    \protected@edef\tb@nt@listname{List of \protect\MakeUppercase\tb@nt@types}%
  }{}%
  \@ifundefined{\tb@nt@type name}{%
    \expandafter\protected@edef\csname \tb@nt@type name\endcsname{\tb@nt@name}%
  }{%
    \iftb@nt@forcenames
      \expandafter\protected@edef\csname \tb@nt@type name\endcsname
      {\tb@nt@name}%
    \fi
  }%
  \@ifundefined{list\tb@nt@type name}{%
    \expandafter\let\csname list\tb@nt@type name\endcsname\tb@nt@listname
  }{%
    \iftb@nt@forcenames
      \expandafter\let\csname list\tb@nt@type name\endcsname\tb@nt@listname
    \fi
  }%
  \expandafter\newcommand\csname listof\tb@nt@ext name\expandafter\endcsname
    \expandafter{\csname list\tb@nt@type name\endcsname}%
  \begingroup\edef\@tempa{\endgroup
    \noexpand\newcommand*\csname listof\tb@nt@types\endcsname{%
      \noexpand\listoftoc{%
        \expandafter\noexpand\csname ext@\tb@nt@type\endcsname}%
    }%
  }\@tempa
%    \end{macrocode}
% The list entry:
% \changes{v3.20}{2016/04/05}{warning if \cs{l@\dots} is undefined}
%    \begin{macrocode}
  \Ifstr{\tb@nt@tocentrystyle}{}{%
    \@ifundefined{l@\tb@nt@type}{%
      \PackageWarning{tocbasic}{%
        \expandafter\string\csname l@\tb@nt@type\endcsname\space
        undefined!\MessageBreak
        I hope you know, what you are doing, but\MessageBreak
        maybe it would be better to use proper\MessageBreak
        `tocentrystyle' settings%
      }%
    }{}%
  }{%
    \edef\reserved@a{%
      \noexpand\DeclareTOCStyleEntry[%
        {\unexpanded\expandafter{\tb@nt@tocstyle@options}}%
      ]{\tb@nt@tocentrystyle}{\tb@nt@type}%
    }%
    \reserved@a
  }%
%    \end{macrocode}
% \changes{v3.12}{2013/05/03}{fixed: definition of
%   \cs{listof\meta{type}entryname} added as explained in the manual}
%    \begin{macrocode}
  \@ifundefined{listof\tb@nt@ext entryname}{%
    \expandafter\let\csname listof\tb@nt@ext entryname\endcsname\tb@nt@name
  }{}%
%    \end{macrocode}
% The setup command:
%    \begin{macrocode}
  \begingroup\edef\@tempa{\endgroup
    \noexpand\newcommand*\csname setup\tb@nt@types\endcsname{%
      \noexpand\setuptoc{\tb@nt@ext}%
    }%
  }\@tempa
  \@tempswafalse
%    \end{macrocode}
% The float environments:
% \changes{v3.09a}{2011/05/30}{fixed: floats may have an optional argument}
% \changes{v3.12}{2013/12/10}{fixed: usage of default placement}
% \changes{v3.46}{2025/06/13}{keys definition added}
%    \begin{macrocode}
  \iftb@nt@float
    \expandafter\newcommand\expandafter*\csname fps@\tb@nt@type\expandafter
    \endcsname\expandafter{\tb@nt@floatpos}%
    \expandafter\newcommand\expandafter*\csname ftype@\tb@nt@type\expandafter
    \endcsname\expandafter{\tb@nt@floattype}%
    \begingroup
      \edef\@tempa{%
        \noexpand\endgroup
        \noexpand\newenvironment{\tb@nt@type}{%
          \noexpand\kernel@ifnextchar[%]
          {\noexpand\tb@atbegin@after\noexpand\@float{\tb@nt@type}}%
          {\noexpand\edef\noexpand\reserved@a{%
              \noexpand\noexpand\noexpand\tb@atbegin@after
              \noexpand\noexpand\noexpand\@float{\tb@nt@type}%
              [\noexpand\csname fps@\tb@nt@type\noexpand\endcsname]}%
            \noexpand\reserved@a}%
        }{%
          \noexpand\csname \tb@nt@type @atend\noexpand\endcsname
          \noexpand\end@float
        }%
        \noexpand\newenvironment{\tb@nt@type*}{%
          \noexpand\kernel@ifnextchar[%]
          {\noexpand\tb@atbegin@after\noexpand\@dblfloat{\tb@nt@type}}%
          {\noexpand\edef\noexpand\reserved@a{%
              \noexpand\noexpand\noexpand\tb@atbegin@after
              \noexpand\noexpand\noexpand\@dblfloat{\tb@nt@type}%
              [\noexpand\csname fps@\tb@nt@type\noexpand\endcsname]}%
            \noexpand\reserved@a}%
        }{%
          \noexpand\csname \tb@nt@type @atend\noexpand\endcsname
          \noexpand\end@dblfloat
        }%
        \if@tocbasic@old@latex@found\else
          \expandafter\noexpand\csname tocbasic_define_caption_keys:n\endcsname
            {\tb@nt@type}%
        \fi
      }%
    \@tempa
    \@tempswatrue
  \fi
%    \end{macrocode}
% The nonfloat environment:
%    \begin{macrocode}
  \iftb@nt@nonfloat
    \begingroup
      \edef\@tempa{%
        \noexpand\endgroup
        \noexpand\newenvironment{\tb@nt@type-}{%
          \noexpand\trivlist\noexpand\item\noexpand\relax
          \noexpand\minipage{\noexpand\linewidth}%
          \noexpand\def\noexpand\@captype{\tb@nt@type}%
          \noexpand\csname \tb@nt@type @atbegin\noexpand\endcsname
        }{%
          \noexpand\csname \tb@nt@type @atend\noexpand\endcsname
          \noexpand\endminipage\noexpand\endtrivlist
        }%
        \if@tocbasic@old@latex@found\else
          \expandafter\noexpand\csname tocbasic_define_caption_keys:n\endcsname
            {\tb@nt@type}%
        \fi
      }%
    \@tempa
    \@tempswatrue
  \fi
%    \end{macrocode}
% The counter and hooks of float and nonfloat environments:
% \changes{v3.10b}{2012/04/04}{\cs{noexpand} added to fix problems using
%   \cs{autodot}}
% \changes{v3.13}{2014/07/31}{add \cs{autodot} only to hierachical
%   counters}
% \changes{v3.35}{2021/10/12}{ignore \opt{counterwithin} if it is
%   ``\texttt{chapter}'' resp. ``\texttt{section}'' and \cs{if@mainmatter} is
%   not \cs{iffalse} and the counterwithin counter is < 1}
% \changes{v3.37}{2022/05/24}{mainmatter test fixed}
%    \begin{macrocode}
  \if@tempswa
    \@ifundefined{c@\tb@nt@type}{%
      \newcounter{\tb@nt@type}%
    }{%
      \PackageWarning{tocbasic}{using already defined counter `\tb@nt@type'}%
    }%
    \ifx\tb@nt@counterwithin\@empty\else
      \@addtoreset{\tb@nt@type}{\tb@nt@counterwithin}%
      \begingroup
        \def\reserved@c{section}%
        \@ifundefined{chapter}{}{%
          \@ifundefined{c@chapter}{}{%
            \@ifundefined{l@chapter}{}{%
              \def\reserved@c{chapter}}}}%
        \expandafter\Ifstr\expandafter{\reserved@c}{\tb@nt@counterwithin}{%
          \edef\@tempa{%
            \noexpand\endgroup
            \noexpand\renewcommand*\expandafter\noexpand
            \csname the\tb@nt@type\endcsname{%
              \unexpanded{%
                \expandafter\ifx\csname if@mainmatter\expandafter\endcsname
                \csname iffalse\endcsname\else
              }%
                \noexpand\ifnum
                \expandafter\noexpand\csname c@\tb@nt@counterwithin\endcsname
                >\noexpand\z@
                  \expandafter\noexpand\csname the\tb@nt@counterwithin\endcsname
                  .%
                \noexpand\fi
              \noexpand\fi  
              \noexpand\arabic{\tb@nt@type}%
            }%
          }%
        }{%
          \edef\@tempa{%
            \noexpand\endgroup
            \noexpand\renewcommand*\expandafter\noexpand
            \csname the\tb@nt@type\endcsname{%
              \expandafter\noexpand\csname the\tb@nt@counterwithin\endcsname
              .%
              \noexpand\arabic{\tb@nt@type}%
            }%
          }%
        }%
      \@tempa
    \fi
    \begingroup
      \edef\@tempa{%
        \noexpand\endgroup
        \noexpand\newcommand*\expandafter\noexpand
        \csname \tb@nt@type format\endcsname{%
          \expandafter\noexpand\csname \tb@nt@type name\endcsname
          \noexpand\nobreakspace
          \expandafter\noexpand\csname the\tb@nt@type\endcsname
          \ifx\tb@nt@counterwithin\@empty\else
            \noexpand\csname autodot\endcsname
          \fi
        }%
        \noexpand\newcommand*\expandafter\noexpand
        \csname fnum@\tb@nt@type\endcsname{%
          \expandafter\noexpand\csname \tb@nt@type format\endcsname
        }%
      }%
    \@tempa
    \expandafter\newcommand\expandafter*\csname \tb@nt@type @atbegin\expandafter
    \endcsname\expandafter{\tb@nt@atbegin}%
    \expandafter\newcommand\expandafter*\csname \tb@nt@type @atend\expandafter
    \endcsname\expandafter{\tb@nt@atend}%
  \fi
}
%    \end{macrocode}
% \begin{macro}{\tb@atbegin@after}
% \changes{v3.09a}{2011/05/30}{added}
% Processes command \#1 with argument \#2 and optional argument \#3 and than
% \verb|\csname #2@atbegin\endcsname|. This is used to add
% \verb|csname #2@atbegin\endcsname| at begin part of a float (but after
% optional argument of the float).
%    \begin{macrocode}
\newcommand*{\tb@atbegin@after}[3]{}
\def\tb@atbegin@after#1#2[#3]{%
  #1{#2}[#3]%
  \csname #2@atbegin\endcsname
}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\tb@ifvalueisnotempty}
% \changes{v3.06}{2010/05/21}{added}
% \changes{v3.20}{2015/12/16}{simpler definition}
% \changes{v3.28}{2019/11/18}{\cs{ifstr} renamed to \cs{Ifstr}}
% This is only a helper for defining some of the keys.
%    \begin{macrocode}
\newcommand*{\tb@ifvalueisnotempty}[1]{%
  \Ifstr{#1}{}{%
    \FamilyKeyStateUnknownValue
    \expandafter\@gobble
  }{%
    \FamilyKeyStateProcessed
    \expandafter\@firstofone
  }%
}
%    \end{macrocode}
% \end{macro}
% \begin{macro}[noprint]{\tb@boolkey,\tb@dimkey,\tb@numkey}
% \changes{v3.06}{2010/05/21}{added}
% \changes{v3.20}{2015/12/16}{removed}
% \end{macro}
% \begin{macro}{\tb@nt@autofloattype}
% \changes{v3.06}{2010/06/01}{added}
% This macro saves the float type for auto generated float types.
%    \begin{macrocode}
\newcommand*{\tb@nt@autofloattype}{16}
%</body>
%    \end{macrocode}
% \end{macro}
% \end{command}
%
% \subsection{Caption handling}
%
% \changes{v3.46}{2025/06/10}{\pkg*{tocbasic} handles captions}
% From version 3.46 package \pkg*{tocbasic} not only supports but provides the
% caption handling that was formerly part of the \KOMAScript{} classes. This
% allows us also a (partial) redesign of the implementation. Nevertheless, we
% try to keep it compatible. When package \pkg{caption} is loaded, most of the
% features are delegated to that package.
%
% \ExplSyntaxOn
% \begin{macro}{\g_@@__caption_above_bool}
%   \ExplSyntaxOff
%   \changes{v3.46}{2025/06/13}{added}
%   The default formation for captions should above (instead of below) the
%   content. This has to be predefined, because
%   \cs{tocbasic\_define\_caption\_keys:n} does not automatically define
%   it. The initial value is \optvalue{false}.
%    \begin{macrocode}
%<*option>
\if@tocbasic@old@latex@found\else
\ExplSyntaxOn
\bool_new:N \g_@@__caption_above_bool
%    \end{macrocode}
% \end{macro}
% \begin{command}{\tocbasic_define_caption_keys:n}
%   \ExplSyntaxOff
%   \changes{v3.46}{2025/06/13}{added}
%   Allows to define the boolean looking choice options \opt{\#1captionabove}
%   and \opt{\#1captionbelow} and the choice options \opt{\#1captionposition}
%   with the three values \optvalue{top}, \optvalue{bottom} and
%   \optvalue{default}. Value \optvalue{default} resets the caption position
%   for \texttt{\#1} to the default caption position. If \texttt{\#1} is
%   empty, the default value is not defined! The code not only respects
%   package \pkg{caption} but actively supports its use. This is the main
%   reason, why it cannot use real boolean options, but needs to simulate them
%   using choice options. The code looks complicated because resetting the
%   \pkg{caption} options for floats is different for \env{figures} and
%   \env{tables} than for other floats. Also resetting \pkg{caption} options
%   of single floats needs an extra command (at least after
%   \verb|\begin{document}|).
%    \begin{macrocode}
\cs_new:Nn \tocbasic_define_caption_keys:n
  {
    \keys_if_exist:nnF { tocbasic } { #1captionabove }
      {
        \keys_define:nn { tocbasic }
          {
            #1captionabove .choice:,
            #1captionabove / true .code:n       =
              { \@@_set_caption_position_top_bottom:nn { #1 } { t } },
            #1captionabove / false .code:n      =
              { \@@_set_caption_position_top_bottom:nn { #1 } { b } },
            #1captionabove / unknown .code:n    =
              { \msg_error:nne { keys } { boolean-values-only } \l_keys_path_str },
            #1captionabove .usage:n             = general,
            #1captionabove .default:n           = true,
            #1captionbelow .choice:,
            #1captionbelow / true .code:n       =
              { \@@_set_caption_position_top_bottom:nn { #1 } { b } },
            #1captionbelow / false .code:n      =
              { \@@_set_caption_position_top_bottom:nn { #1 } { t } },
            #1captionbelow / unknown .code:n    =
              { \msg_error:nne { keys } { boolean-values-only } \l_keys_path_str },
            #1captionbelow .usage:n             = general,
            #1captionbelow .default:n           = true,
            #1captionposition .choice:,
            #1captionposition / top .code:n     =
              { \@@_set_caption_position_top_bottom:nn { #1 } { t } },
            #1captionposition / bottom .code:n  =
              { \@@_set_caption_position_top_bottom:nn { #1 } { b } },
            #1captionposition .usage:n          = general,
            #1captionposition .value_required:n = true,
          }
        \str_if_empty:nF { #1 }
          {
            \keys_define:nn { tocbasic }
              {
                #1captionposition / default .code:n =
                  { \@@_set_caption_position_top_bottom:nn { #1 } { default } },
                #1captionposition .initial:n = default
              }
          }
        \cs_if_exist:NTF \captionsetup
          {
            \bool_if_exist:cTF { g_@@_ #1 _caption_above_bool }
              {
                \exp_last_unbraced:Ne \captionsetup
                  {
                    \str_if_empty:nF {#1} {[#1]}
                    {
                      #1position=
                      { \bool_if:cTF { g_@@_ #1 _caption_above_bool } tb }
                    }
                  }
              }
              {
                \tl_if_exist:cT { caption@opt@#1 }
                  {
                    \tl_if_empty:cF { caption@opt@#1 }
                      { \clearcaptionsetup[position]{#1} }
                  }
              }  
          }
          {
            \tl_if_eq:VnT \everypar { \@nodocument }
              {
                \str_if_in:nnTF { ,table,figure,, } { ,#1, }
                  {
                    \exp_args:Ne \PassOptionsToPackage
                      {
                        #1position=
                        \bool_if_exist:cTF { g_@@_ #1 _caption_above_bool }
                          { \bool_if:cTF { g_@@_ #1 _caption_above_bool } tb }
                          { default }
                      }
                      { caption }
                  }
                  {  
                    \hook_gput_code:nnn { package / caption / after } { tocbasic }
                      {
                        \bool_if_exist:cT { g_@@_ #1 _caption_above_bool }
                          {
                            \exp_last_unbraced:Ne \captionsetup
                              {
                                \str_if_empty:nF {#1} {[#1]}
                                { position=\bool_if:cTF { g_@@_ #1 _caption_above_bool } tb }
                              }
                          }
                      }
                  }
              }
          }
      }
  }
%    \end{macrocode}
% \ExplSyntaxOn
% \begin{macro}{\@@_set_caption_position_top_bottom:nn}
%   \ExplSyntaxOff
%   This is the helper to set option \opt{position} to top (\texttt{\#2=t}) or
%   bottom (\texttt{\#2=b}). If \texttt{\#1} is not empty but the name of a
%   float, it can also be \optvalue{default}. Most of the logic of the options
%   and the \pkg{caption} support is here.
%    \begin{macrocode}
\cs_new:Nn \@@_set_caption_position_top_bottom:nn
  { 
    \str_if_eq:nnTF { #2 } { default }
      {
        \bool_if_exist:cT { g_@@_ #1 _caption_above_bool }
          { \cs_undefine:c { g_@@_ #1 _caption_above_bool } }
        \cs_if_exist:NTF \clearcaptionsetup
          {
            \tl_if_exist:cT { caption@opt@#1 }
              {
                \tl_if_empty:cF { caption@opt@#1 }
                  { \clearcaptionsetup[position]{ #1 } }
              }
          }
          {
            \tl_if_eq:VnT \everypar { \@nodocument }
              {
                \str_if_in:nnT { ,table,figure,, } { ,#1, }
                  {
                    \PassOptionsToPackage { #1position=#2 } { caption }
                  }
              }
          }
      }
      { 
        \bool_if_exist:cF { g_@@_ #1 _caption_above_bool }
          { \bool_new:c { g_@@_ #1 _caption_above_bool } }
        \str_if_eq:nnTF { #2 } { t }
          { \bool_set_true:c }
          { \bool_set_false:c }
          { g_@@_ #1 _caption_above_bool }
        \cs_if_exist:NTF \captionsetup
          {
            \exp_last_unbraced:Ne \captionsetup
              { \str_if_empty:nF {#1} {[#1]} }
              { position=#2 }
          }
          {
            \tl_if_eq:VnT \everypar { \@nodocument }
              {
                \str_if_in:nnT { ,table,figure,, } { ,#1, }
                  {
                    \PassOptionsToPackage { #1position=#2 } { caption }
                  }
              }
          }
      }
  }
%    \end{macrocode}
% \end{macro}
% \ExplSyntaxOff
% Now, we can initialize not only the option for the default caption position
%    \begin{macrocode}
\tocbasic_define_caption_keys:n {}
%    \end{macrocode}
% but also for usual floats like \env{table} and \env{figure}. Note, that the
% captions of \env{lstlisting} are not configured here. If you want, you can
% add such configuration using:
% \begin{verbatim}
%   \tocbasic_define_caption_keys:n { lstlisting }
% \end{verbatim}
%    \begin{macrocode}
\clist_map_inline:nn { table, figure }
  {
    \bool_if:nT
      {
        { \cs_if_exist_p:c { #1 } && \cs_if_exist_p:c { end#1 } }
        ||
        { \cs_if_exist_p:c { #1- } && \cs_if_exist_p:c { end#1- } }
      }
      {
        \tocbasic_define_caption_keys:n { #1 }
      }
  }

\ExplSyntaxOff
\fi  
%</option>
%    \end{macrocode}
% \end{command}
%
% \ExplSyntaxOn
% \begin{macro}{\@@_caption_patch_code:}
%   \ExplSyntaxOff
%   \changes{v3.46}{2025/06/13}{added}
%   \changes{v3.48}{2025/08/29}{%
%     \cs{cs\_set\_eq:NN} replaced by \cs{DeclareCommandCopy}}
%   Now we can define the patch code. Note, that the caption patch is not
%   automatically activated if the \pkg{caption} package is detected. And if
%   you manually activate it, you will get a warning.
%    \begin{macrocode}
%<*body>
\if@tocbasic@old@latex@found\else
\ExplSyntaxOn
\hook_gput_code:nnn { begindocument } { tocbasic }
  {
    \DeclareCommandCopy { \@@_saved_caption:w } { \caption }
    \bool_if:NT \g_@@_patch_caption_bool
      {
        \@@_caption_patch_code:
      }
  }

\hook_gset_rule:nnnn { begindocument } { tocbasic } { after } { caption }
\hook_gset_rule:nnnn { begindocument } { tocbasic } { after } { caption3 }

\cs_new:Npn \@@_caption_patch_code:
  {
    \DeclareCommandCopy { \caption } { \@@_caption:w }
    \DeclareCommandCopy { \captionof } { \@@_caption_of:w }
  }
%    \end{macrocode}
%   \changes{v3.49}{2025/11/05}{set \cs{caption@documentclass} if loaded
%     before package \pkg{caption3}}
%   \changes{v3.50}{2025/12/31}{set \cs{caption@documentclass} only with
%     \KOMAScript{} classes}
%   And as long as the \pkg{caption3} package does not load special code for
%   the standard classes, we fake here \cs{caption@documentclass}, to avoid
%   loading of extra caption code, when package \pkg{tocbasic} is used.
%    \begin{macrocode}
\msg_new:nnnn { tocbasic } { caption-code-by-class-deactivated }
  {
    Loading~of~class-dependent~code~for~package~caption3\\
    prevented~\msg_line_context:.
  }
  {
    The~caption3~package~attempts~to~detect~classes~known~to~it~
    using~a~number~of~heuristics~and,~if~necessary,~
    reload~class-dependent~code.~
    Unfortunately,~the~code~from~caption-koma.sto,~for~example,~
    is~no~longer~compatible~with~the~KOMA-Script~package~tocbasic~
    since~KOMA-Script~3.46.~
    Therefore,~the~tocbasic~package~attempts~to~prevent~this~file~
    from~being~loaded~by~pretending~to~caption3~that~a~standard~class~
    is~being~used.~
    Since~the~caption3~package,~as~part~of~the~caption~collection,~
    is~no~longer~maintained,~and~since~the~KOMA-Script~author~himself~
    is~trying~to~maintain~the~compatibility~of~the~caption~package~
    with~KOMA-Script,~this~is~currently~the~best~known~method~
    to~prevent~unnecessary~warnings~from~caption~or~caption3.
  }
\cs_if_exist:NT \KOMAClassName
  {
    \hook_gput_code:nnn { package / caption3 / before } { tocbasic }
      {
        \cs_set:Npn \caption@documentclass { standard }
        \msg_info:nn { tocbasic } { caption-code-by-class-deactivated }
      }
  }
%    \end{macrocode}
% \end{macro}
% \ExplSyntaxOn
% \begin{command}{\tocbasic_if_caption_above_p:n,
%                 \tocbasic_if_caption_above:nT,
%                 \tocbasic_if_caption_above:nF,
%                 \tocbasic_if_caption_above:nTF,
%                 \tocbasic_if_caption_above_p:,
%                 \tocbasic_if_caption_above:T,
%                 \tocbasic_if_caption_above:F,
%                 \tocbasic_if_caption_above:TF}
% \ExplSyntaxOff
%    \begin{macrocode}
\prg_new_conditional:Nnn \tocbasic_if_caption_above:n { p, T, F, TF }
  {
    \bool_if:nTF
      {
        \cs_if_exist_use:cF { g_@@_ #1 _caption_above_bool }
          {
            \g_@@__caption_above_bool
          }
      }
      {
        \prg_return_true:
      }
      {
        \prg_return_false:
      }
  }
\prg_new_conditional:Npnn \tocbasic_if_caption_above: { p, T, F, TF }
  {
    \bool_if:nTF
      {
        \cs_if_exist_use:cF { g_@@_ \@captype _caption_above_bool }
          {
            \g_@@__caption_above_bool
          }
      }
      {
        \prg_return_true:
      }
      {
        \prg_return_false:
      }
  }
%    \end{macrocode}
% \end{command}
% \ExplSyntaxOn
% \begin{macro}{\@@_caption_setup:,\@@_captionof_setup:n}
%   \changes{v3.46}{2025/06/13}{added}
%   \changes{v3.49}{2025/10/31}{renamed to remove double \texttt{tocbasic}}
% \begin{macro}{\@@_caption_setup:nn}
%   \changes{v3.47}{2025/08/25}{added}
%   \changes{v3.49}{2025/10/31}{renamed to remove double \texttt{tocbasic}}
%   \ExplSyntaxOff
%   Does all the setup needed before being able to call
%   \cs{@@\_saved\_caption:w} either for a given caption type or
%   \cs{@captype}. This should be used local only!
%    \begin{macrocode}
\cs_new:Nn \@@_caption_setup:
  {
    \tocbasic_if_caption_above:TF
      {
        \cs_if_exist:NTF \captionsetup
          { \captionsetup { position=top } }
          { \@@_swap_skip: }
      }
      {
        \cs_if_exist:NT \captionsetup
          { \captionsetup { position=bottom } }
      }
  }
\cs_new:Nn \@@_captionof_setup:n
  {
    \exp_args:Nne \hook_gput_next_code:nn { tocbasic / caption / after }
      {
        \cs_if_exist:NTF \@captype
          { \exp_not:N \tl_set:Nn \exp_not:N \@captype { \@captype } }
          { \exp_not:n { \cs_set_eq:NN \@captype \tex_undefined:D } }
      }
    \tocbasic_if_caption_above:nTF { #1 }
      {
        \cs_if_exist:NTF \captionsetup
          { \captionsetup { type=#1, position=top } }
          {
            \tl_set:Ne \@captype { #1 }
            \@@_swap_skip:
          }
      }
      {
        \cs_if_exist:NTF \captionsetup
          { \captionsetup { type=#1, position=bottom } }
          { \tl_set:Ne \@captype { #1 } }
      }
  }  
\cs_new:Nn \@@_captionof_setup:nn
  {
    \exp_args:Nne \hook_gput_next_code:nn { tocbasic / caption / after }
      {
        \cs_if_exist:NTF \@captype
          { \exp_not:N \tl_set:Nn \exp_not:N \@captype { \@captype } }
          { \exp_not:n { \cs_set_eq:NN \@captype \tex_undefined:D } }
      }
    \str_if_eq:eeTF { #2 } { top }
      {
        \cs_if_exist:NTF \captionsetup
          { \captionsetup { type=#1, position=top } }
          {
            \tl_set:Ne \@captype { #1 }
            \@@_swap_skip:
          }
      }
      {
        \cs_if_exist:NTF \captionsetup
          { \captionsetup { type=#1, position=#2 } }
          { \tl_set:Ne \@captype { #1 } }
      }
  }  
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \ExplSyntaxOn
% \begin{macro}{\@@_caption:w}
%   \ExplSyntaxOff
%   \changes{v3.46}{2025/06/13}{added}
%   \changes{v3.47}{2025/08/25}{extra group eliminted}
%   \changes{v3.49}{2025/10/31}{use optional argument only, if used}
%   \changes{v3.50}{2025/12/01}{use long mandatory argument}
%   This is, what will be \cs{caption}, if \cs{caption} is patched.
%    \begin{macrocode}
\NewDocumentCommand \@@_caption:w { s o +m }
  {
    \@@_caption_setup:
    \exp_last_unbraced:Ne \@@_saved_caption:w
      { \IfBooleanT{#1}* \IfValueT{#2} { \exp_not:n {[{#2}]} } }
      {#3}
    \hook_use:n { tocbasic / caption / after }
  }
%    \end{macrocode}
% \end{macro}
% \ExplSyntaxOff
% \begin{command}{\captionabove,\captionbelow}
%   \changes{v3.46}{2025/06/13}{new implementation moved to \pkg*{tocbasic}}
%   \changes{v3.47}{2025/08/25}{extra group eliminted}
%   \changes{v3.50}{2025/12/01}{use long mandatory argument}
%    \begin{macrocode}
\NewDocumentCommand \captionabove { s O{#3} +m }
  {
    \cs_if_exist:NTF \captionsetup
      { \captionsetup { position=top } }
      { \@@_swap_skip: }
    \exp_last_unbraced:Ne \@@_saved_caption:w { \IfBooleanT{#1}* }
      [{#2}] {#3}
    \hook_use:n { tocbasic / caption / after }
  }

\NewDocumentCommand \captionbelow { s O{#3} +m }
  {
    \cs_if_exist:NT \captionsetup
      { \captionsetup { position=bottom } }
    \exp_last_unbraced:Ne \@@_saved_caption:w { \IfBooleanT{#1}* }
      [{#2}] {#3}
    \hook_use:n { tocbasic / caption / after }
  }
%    \end{macrocode}
% \end{command}
% \ExplSyntaxOn
% \begin{command}{\captionof,\@@_caption_of:w}
%   \ExplSyntaxOff
%   \changes{v3.46}{2025/06/13}{added}
%   \changes{v3.47}{2025/08/25}{extra group eliminted}
%   \changes{v3.48}{2025/08/29}{%
%     \cs{cs\_set\_eq:NN} replaced by \cs{DeclareCommandCopy}}
%   \changes{v3.49}{2025/10/31}{use optional argument only, if used}
%   \changes{v3.50}{2025/12/01}{use long last mandatory argument}
%   This is, what will be \cs{captionof}, if \cs{captionof} is patched or not
%   defined.
%    \begin{macrocode}
\NewDocumentCommand \@@_caption_of:w { s m o +m }
  {
    \@@_captionof_setup:n { #2 }
    \exp_last_unbraced:Ne \@@_saved_caption:w
      { \IfBooleanT{#1}* \IfValueT{#3} { \exp_not:n {[{#3}]} } }
      {#4}
    \hook_use:n { tocbasic / caption / after }
  }

\cs_if_exist:NF { \captionof }
  { \DeclareCommandCopy { \captionof } { \@@_caption_of:w } }
%    \end{macrocode}
% \ExplSyntaxOn
% \begin{macro}{\@@_swap_skips:}
% \ExplSyntaxOff
%   Helper to (locally) interchange the values of \cs{abovecaptionskip} and
%   \cs{belowcaptionskip}. We also provide a socket (with older \LaTeX{}
%   kernels a hook) to react on the swap.
%    \begin{macrocode}
\cs_if_exist:NTF \socket_new:nn
  { \socket_new:nn { tocbasic / swapskip / after } { 0 } }
  { \hook_new:n { tocbasic / swapskip / after } }
\hook_new:n { tocbasic / caption / after }
\cs_new:Nn \@@_swap_skip:
  {
    \skip_set_eq:NN \l_tmpa_skip \abovecaptionskip
    \skip_set_eq:NN \abovecaptionskip \belowcaptionskip
    \skip_set_eq:NN \belowcaptionskip \l_tmpa_skip
    \hook_gput_next_code:nn { tocbasic / caption / after } {
      \skip_set_eq:NN \l_tmpa_skip \abovecaptionskip
      \skip_set_eq:NN \abovecaptionskip \belowcaptionskip
      \skip_set_eq:NN \belowcaptionskip \l_tmpa_skip
    }
    \cs_if_exist_use:NF \socket_use:n \hook_use:n
      { tocbasic / swapskip / after }
  }
%    \end{macrocode}
% \end{macro}
% \end{command}
% \ExplSyntaxOff
% \begin{command}{\captionaboveof,\captionbelowof}
%   \changes{v3.46}{2025/06/13}{new implementation moved to \pkg*{tocbasic}}
%   \changes{v3.47}{2025/08/25}{extra group eliminted}
%   \changes{v3.50}{2025/12/01}{use long last mandatory argument}
%    \begin{macrocode}
\NewDocumentCommand \captionaboveof { s m O{#4} +m }
  {
    \@@_captionof_setup:nn { #2 } { top }
    \exp_last_unbraced:Ne \@@_saved_caption:w { \IfBooleanT{#1}* }
      [{#3}] {#4}
    \hook_use:n { tocbasic / caption / after }
  }

\NewDocumentCommand \captionbelowof { s m O{#4} +m }
  {
    \@@_captionof_setup:nn { #2 } { bottom }
    \exp_last_unbraced:Ne \@@_saved_caption:w { \IfBooleanT{#1}* }
      [{#3}] {#4}
    \hook_use:n { tocbasic / caption / after }
  }
\ExplSyntaxOff
\fi  
%<@@=>
%</body>
%    \end{macrocode}
% \end{command}
% \ExplSyntaxOff
%
% \begin{macrocode}
%</package>
%    \end{macrocode}
%
% \subsection{Loading the package}
% Used at \KOMAScript{} packages and classes to load the package.
% \changes{v3.46}{2025/06/13}{\KOMAScript{} classes need to load
%   \pkg*{tocbasic} with option \opt{enablepatch\quotechar=caption}}
%    \begin{macrocode}
%<*load>
\RequirePackage[enablepatch=caption]{tocbasic}[%
%!KOMAScriptVersion
]
%    \end{macrocode}
% And do an early initialization of additional keys.
%    \begin{macrocode}
\ExplSyntaxOn
\tocbasic_define_caption_keys:n { table }
\tocbasic_define_caption_keys:n { figure }
\ExplSyntaxOff
%</load>
%    \end{macrocode}
%
%
% \Finale
% \PrintChanges
%
\endinput
% Local Variables:
% mode: doctex
% ispell-local-dictionary: "en_US"
% eval: (flyspell-mode 1)
% TeX-master: t
% TeX-engine: luatex-dev
% eval: (setcar (or (cl-member "Index" (setq-local TeX-command-list (copy-alist TeX-command-list)) :key #'car :test #'string-equal) (setq-local TeX-command-list (cons nil TeX-command-list))) '("Index" "mkindex %s" TeX-run-index nil t :help "makeindex for dtx"))
% End:
