% \iffalse meta-comment
%
% File: ltx-talk-structure.dtx Copyright (C) 2024-2026 Joseph Wright
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
% license or (at your option) any later version.  The latest version
% of this license is in the file
%
%    https://www.latex-project.org/lppl.txt
%
% This file is part of the "ltx-talk bundle" (The Work in LPPL)
% and all files in that bundle must be distributed together.
%
% The released version of this bundle is available from CTAN.
%
% -----------------------------------------------------------------------
%
% The development version of the bundle can be found at
%
%    https://github.com/josephwright/ltx-talk
%
% for those people who are interested.
%
% -----------------------------------------------------------------------
%
%<*driver>
\documentclass{l3doc}
% Additional commands needed in this source
\NewDocumentCommand\email{m}{\href{mailto:#1}{\nolinkurl{#1}}}
\begin{document}
  \DocInput{\jobname.dtx}
\end{document}
%</driver>
% \fi
%
% ^^A As we are dealing with a class, this has to be done manually
% \def\filedate{2026-08-23}
% \def\fileversion{v0.6.0}
%
% \title{^^A
%   \pkg{ltx-talk-structure} -- Structural commands^^A
%   \thanks{This file describes \fileversion,
%     last revised \filedate.}^^A
% }
%
% \author{^^A
%  Joseph Wright^^A
%  \thanks{^^A
%    E-mail: \email{joseph@texdev.net}^^A
%   }^^A
% }
%
% \date{Released \filedate}
%
% \maketitle
%
% \begin{documentation}
%
% \end{documentation}
%
% \begin{implementation}
%
% \section{\pkg{ltx-talk-structure} implementation}
%
% Start the \pkg{DocStrip} guards.
%    \begin{macrocode}
%<*class>
%    \end{macrocode}
%
% Identify the internal prefix.
%    \begin{macrocode}
%<@@=talk>
%    \end{macrocode}
%
% \subsection{Frame title}
%
% \begin{variable}{\g_@@_frame_title_tl, \g_@@_frame_subtitle_tl}
%    \begin{macrocode}
\tl_new:N \g_@@_frame_title_tl
\tl_new:N \g_@@_frame_subtitle_tl
%    \end{macrocode}
% \end{variable}
%
% \begin{macro}{\frametitle}
%   Just data storage: at the present no use of the optional argument.
%    \begin{macrocode}
\NewDocumentCommand \frametitle { D <> { all } O {#3} m }
  {
    \@@_if_overlay:nT {#1}
      { \tl_gset:Nn \g_@@_frame_title_tl {#3} }
  }
\NewDocumentCommand \framesubtitle { D <> { all } O {#3} m }
  {
    \@@_if_overlay:nT {#1}
      { \tl_gset:Nn \g_@@_frame_subtitle_tl {#3} }
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@@_frame_title:n, \@@_frame_title_tagged:n}
%   Inserting the frame title requires we deal with tagging as well as
%   appearance: if there is a title, we need to tag just this part of the
%   header.
%    \begin{macrocode}
\NewTemplateType { frametitle } { 1 }
\DeclareTemplateInterface { frametitle } { talk } { 1 }
  {
    after-vspace  : skip = \bigskipamount ,
    before-vspace : skip = 0em ,
    color         : tokenlist = ,
    font          : tokenlist = \Large \bfseries
  }
\DeclareTemplateCode { frametitle } { talk } { 1 }
  {
    after-vspace  = \l_@@_frametitle_after_skip ,
    before-vspace = \l_@@_frametitle_before_skip ,
    color         = \l_@@_frametitle_color_tl ,
    font          = \l_@@_frametitle_font_tl
  }
  {
    \noindent
    \vspace { \l_@@_frametitle_before_skip }
    \group_begin:
      \tl_if_empty:NF \l_@@_frametitle_color_tl
        { \color_select:V \l_@@_frametitle_color_tl }
      \l_@@_frametitle_font_tl
      \tl_if_blank:nF {#1}
        { \@@_frame_title:n {#1} }
      \par
    \group_end:
    \vspace { \l_@@_frametitle_after_skip }
  }
\DeclareInstance { frametitle } { header } { talk } { }
\cs_new_protected:Npn \@@_frame_title:n #1
  {
    \bool_if:NTF \g_@@_frame_tag_bool
      { \@@_frame_title_tagged:n }
      { \use:n }
        {#1}
  }
\cs_new_protected:Npn \@@_frame_title_tagged:n #1
  {
   \@@_header_tag_begin:e
      {
        firstkid = true ,
        parent   = \int_use:N \g_@@_frame_struct_int ,
        tag      = frametitle ,
        title    = { \text_purify:n { \g_@@_frame_title_tl } } ,
      }
    \group_begin:
      \tagpdfparaOff
      #1
    \group_end:
    \@@_header_tag_end:
  }
%    \end{macrocode}
% \end{macro}
%
% \subsection{Headings}
%
% \begin{variable}
%   {
%     \l_@@_section_tl ,
%     \g_@@_section_tl ,
%     \l_@@_subsection_tl ,
%     \g_@@_subsection_tl ,
%     \l_@@_subsubsection_tl ,
%     \g_@@_subsubsection_tl
%   }
%   Two versions of the data store: one set locally (but at the top level) for
%   general use, one set (and more importantly cleared) globally to allow
%   insertion in the header area just once per name.
%    \begin{macrocode}
\tl_new:N \l_@@_section_tl
\tl_new:N \g_@@_section_tl
\tl_new:N \l_@@_subsection_tl
\tl_new:N \g_@@_subsection_tl
\tl_new:N \l_@@_subsubsection_tl
\tl_new:N \g_@@_subsubsection_tl
%    \end{macrocode}
% \end{variable}
%
% \begin{variable}
%   {
%     \l_@@_sec_bookmark_tl   ,
%     \l_@@_sec_label_tl      ,
%     \l_@@_sec_nameref_tl    ,
%     \l_@@_sec_numbered_bool ,
%     \l_@@_sec_quote_tl      ,
%     \l_@@_sec_running_tl    ,
%     \l_@@_sec_subtitle_tl   ,
%     \l_@@_sec_toc_tl
%   }
%   Here, we set up the same keyval interface as used by the kernel
%   (see \file{latex-lab-sec-template.dtx})
%    \begin{macrocode}
\keys_define:nn { talk / heading }
  {
    bookmark .tl_set:N =
      \l_@@_sec_bookmark_tl ,
    label .code:n =
      { \tl_put_right:N \l_@@_sec_label_tl { \label {#1} } } ,
    nameref .tl_set:N =
      \l_@@_sec_nameref_tl ,
    numbered .bool_set:N
      = \l_@@_sec_numbered_bool ,
    numbered .default:n 
      = true ,
    unnumbered .bool_set_inverse:N
      = \l_@@_sec_numbered_bool ,
    unnumbered .default:n
      = true ,
    quote .tl_set:N =
      \l_@@_sec_quote_tl ,
    running .tl_set:N =
      \l_@@_sec_running_tl ,
    shorttitle .meta:n =
      {
        bookmark = {#1} ,
        nameref  = {#1} ,
        running  = {#1} ,
        toc      = {#1}
      } ,
    subtitle .tl_set:N =
      \l_@@_sec_subtitle_tl ,
    toc .tl_set:N =
      \l_@@_sec_toc_tl
  }
\tl_new:N \l_@@_sec_label_tl
%    \end{macrocode}
% \end{variable}
%
% \begin{macro}{\section, \subsection, \subsubsection}
% \begin{macro}{\thesection, \thesubsection, \thesubsubsection}
%  Here, we need full \LaTeX{} counters, so create them using the appropriate
%  mechanism: that also means we can sort out counter dependency and the
%  appearance (using the same setup as in \pkg{article}). As (subsub)section
%  numbers never increment inside frames, we remove these counters from the
%  general tracker.
%    \begin{macrocode}
\newcounter { section }
\newcounter { subsection } [ section ]
\newcounter { subsubsection } [ subsection ]
\seq_gremove_all:Nn \g_@@_cnt_reset_seq { section }
\seq_gremove_all:Nn \g_@@_cnt_reset_seq { subsection }
\seq_gremove_all:Nn \g_@@_cnt_reset_seq { subsubsection }
\cs_gset:Npn \thesection { \@arabic \c@section }
\cs_gset:Npn \thesubsection { \thesection . \@arabic \c@subsection }
\cs_gset:Npn \thesubsubsection { \thesubsection . \@arabic \c@subsubsection }
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\section, \subsection, \subsubsection}
% \begin{macro}
%   {
%     \insertsection       ,
%     \insertsubsection   ,
%     \insertsubsubsection
%   }
% \begin{macro}
%   {
%     \@@_head_section:Nnn,
%     \@@_head_subsection:Nnn,
%     \@@_head_subsubsection:Nnn
%   }
%  The sectioning commands all have essentially the same form: we therefore
%  create using a generator with the necessary conditionals in place. As we
%  do not typeset sections at this stage, the code is quite different from
%  \pkg{article}. This also means that the bookmark links need to point forward
%  to the next slide: if that doesn't appear, the bookmarks will be out. Using
%  the general scratch sequence here should be OK: it really is a one-off
%  setting. We need a sequence to allow indexed mapping to avoid any extra
%  setup for the depth value.
%    \begin{macrocode}
\seq_set_from_clist:Nn \l_tmpa_seq
  { section , subsection , subsubsection }
\seq_map_indexed_inline:Nn \l_tmpa_seq
  {
    \use:e
      {
        \NewDocumentCommand \exp_not:c { insert #2 } { }
          {
            \exp_not:N \tl_use:N
            \exp_not:c { l_@@_ #2 _tl }
          }
        \NewDocumentCommand \exp_not:c {#2}
          { s D <> { all } = { shorttitle } O {##4} m }
          {
            \exp_not:N \bool_if:NF \exp_not:N \l_@@_frame_bool
              {
                \@@_if_overlay:nT {##2}
                  { \exp_not:c { @@_head_ #1 :Nnn } ##1 {##3} {##4} }
              }
          }
        \cs_new_protected:Npn \exp_not:c { @@_head_ #1 :Nnn } ##1##2##3
          {
            \exp_not:N \refstepcounter {#2}
            \UseTaggingSocket { sec / end } { \use:c { toclevel@ #2 } }
            \UseTaggingSocket { sec / begin }
              {
                { \use:c { toclevel@ #2 } }
                {
                  tag =
                    \exp_not:N \UseStructureName
                      { sec / \use:c { toclevel@ #2 } }
                }
              }
            \tl_set:Nn \exp_not:c { l_@@_ #2 _tl } {##3}
            \keys_set:nn { talk / heading } { shorttitle = {##3} , ##2 }
            \exp_not:N \bool_if:NT ##1
              {
                \tl_clear:N \exp_not:N \l_@@_sec_bookmark_tl
                \tl_clear:N \exp_not:N \l_@@_sec_running_tl
                \tl_clear:N \exp_not:N \l_@@_sec_toc_tl
                \bool_set_false:N \exp_not:N \l_@@_sec_numbered_bool
              }
            \UseTaggingSocket { talk / sec / title } {#2}
            \str_if_eq:nnT {#2} { section }
              { \tl_clear:N \exp_not:N \l_@@_subsection_tl }
            \str_if_eq:nnF {#2} { subsubsection }
              { \tl_clear:N \exp_not:N \l_@@_subsubsection_tl }
            \exp_not:N \@@_head_marks:nnVVV {#2} {#1}
              \exp_not:N \l_@@_sec_toc_tl
              \exp_not:N \l_@@_sec_bookmark_tl
              \exp_not:N \l_@@_sec_nameref_tl
            \hook_use:n { #2 / begin }
          }
        \hook_new:n { #2 / begin }
      }
}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \begin{macro}
%   {
%     \addcontentslinebookmark    ,
%     \addcontentslinebookmarkOff ,
%     \addcontentslinebookmarkOn
%   }
%   Patches as in \file{latex-lab-sec-template.dtx}.
%    \begin{macrocode}
\providecommand \addcontentslinebookmark [ 3 ] { }
\providecommand \addcontentslinebookmarkOff { }
\providecommand \addcontentslinebookmarkReset { }
\providecommand \texorpdfstring [ 2 ] {#1}
%    \end{macrocode}
% \end{macro}
% \begin{macro}{\@@_head_marks:nnnnn, \@@_head_marks:nnVVV}
% \begin{macro}{\@@_head_marks_aux:Nnn}
%   For handling bookmarks, TOC, \foreign{etc.}: the naming here follows the
%   \LaTeX{} kernel, as does the code in general, but with some minor
%   adjustments.
%    \begin{macrocode}
\cs_new_protected:Npn \@@_head_marks:nnnnn #1#2#3#4#5
  {
    \tl_set:Nn \@currentlabelname {#5}
    \tl_if_blank:nTF {#3}
      {
        \tl_if_blank:nF {#4}
          {
            \@@_head_marks_aux:Nnnn
              \addcontentslinebookmark {#1} {#2} {#4}
          }
      }
      {
        \tl_if_blank:nT {#4}
          { \addcontentslinebookmarkOff }
        \@@_head_marks_aux:Nnnn
          \addcontentsline {#1} {#2} { \texorpdfstring {#3} {#4} }
      }
  }
\cs_generate_variant:Nn \@@_head_marks:nnnnn { nnVVV }
\cs_new_protected:Npn \@@_head_marks_aux:Nnnn #1#2#3#4
  {
    #1 { toc } {#2}
      {
        \int_compare:nNnF {#3} > { \value { secnumdepth } }
          { \protect \numberline { \use:c { the #2 } } }
         #4
      }
  }
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\appendixmarker}
% \begin{macro}{\contentsline, \@@_saved_contentline:nnnn}
%   At present, the best way to deal with the TOC for the appendix is to set a
%   marker: this will likely be generalized once we add support for parts.
%    \begin{macrocode}
\NewDocumentCommand \appendixmarker { }
  {
    \bool_if:NTF \l_@@_appendix_bool
      { \cs_gset_eq:NN \contentsline \@@_saved_contentline:nnnn }
      { \cs_gset_eq:NN \contentsline \use_none:nnnn }
  }
\cs_new_eq:NN \@@_saved_contentline:nnnn \use_none:nnnn
\cs_gset_eq:NN \@@_saved_contentline:nnnn \contentsline
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{talk/sec/title}
% \begin{macro}{\@@_head_tag:nn}
%   The argument is one of section, subsection or subsubsection.
%    \begin{macrocode}
\NewTaggingSocket { talk / sec / title } { 1 }
\NewTaggingSocketPlug { talk / sec / title } { default }
  {
      \exp_args:Ne \@@_head_tag:nn
        { \text_purify:v { l_@@_ #1 _ tl } } {#1}
  }
\cs_new_protected:Npn \@@_head_tag:nn #1#2
  {
    \tag_struct_begin:e
      {
        tag        =
          \UseStructureName { sec / \use:c { toclevel@ #2 } / title } ,
        title      = {#1} ,
        actualtext = {#1} ,
      }
    \tag_struct_end:
  }
\AssignTaggingSocketPlug { talk / sec / title } { default } 
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \subsection{Table of contents}
%
% \begin{macro}{\@starttoc}
% \begin{macro}{\@starttoc@aux@@nn}
%   The standard kernel implementation here deliberately overwrites the file
%   as soon as it's read. That's no good for us as the table of contents can
%   be read multiple times. So we modify the code: we start from the
%   tagging-aware version (this may need to be revisited). We retain the
%   \LaTeXe{} code as much as possible.
%    \begin{macrocode}
\cs_gset_protected:Npn \@starttoc #1
  {
    \begingroup
      \makeatletter
      \bool_if:NTF \g_@@_frame_tag_bool
        { \@starttoc@aux@@@@nn }
        { \use_ii:nn }
          {#1} { \@input { \jobname . #1 } }
      \legacy_if:nT { @filesw }
        {
          \AddToHook { enddocument / afterlastpage }
            {
              \expandafter \newwrite \csname tf@ #1 \endcsname
              \immediate \openout \csname tf@ #1 \endcsname \jobname .#1 \relax
            }
        }
      \@nobreakfalse
    \endgroup
  }
\cs_new_protected:Npn \@starttoc@aux@@@@nn #1#2
  {
    \UseTaggingSocket { toc / starttoc / before } {#1}
    #2
    \UseTaggingSocket { toc / starttoc / after } {#1}
  }
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\tableofcontents}
%   For the present simply print the output.
%    \begin{macrocode}
\NewDocumentCommand \tableofcontents { O { } }
  {
    \group_begin:
      \@starttoc { toc }
    \group_end:
  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\l@section, \l@subsection, \l@subsubsection}
% \begin{macro}{\@@_toc_aux:nnnn}
% \begin{macro}{\@@_toc_dest:n}
% \begin{macro}{\@@_toc_dest:w}
% \begin{macro}{\@@_toc_level:nnnn}
%   Initial hard-coded versions to be templated once we have some other effects
%   also working. We may need to look at this \enquote{higher up} as we will need
%   to know the section numbers.
%    \begin{macrocode}
\cs_new_protected:Npn \l@section #1#2
  { \@@_toc_aux:nnnn { 1 } { \bfseries \color { structure } } {#1} {#2} }
\cs_new_protected:Npn \l@subsection #1#2
  {
    \@@_toc_aux:nnnn
      { 2 }
      {
        \skip_set:Nn \leftskip { 2em }
        \color_ensure_current:
      }
      {#1} {#2}
  }
\cs_new_protected:Npn \l@subsubsection #1#2
  {
    \@@_toc_aux:nnnn
      { 3 }
      {
        \skip_set:Nn \leftskip { 4em }
        \color_ensure_current:
        \footnotesize
      }
      {#1} {#2}
  }
\cs_new_protected:Npn \@@_toc_aux:nnnn #1#2#3#4
  {
    \int_compare:nNnTF { \value { section } } < 1
      { \use:n }
      { \@@_toc_dest:n }
        { \@@_toc_level:nnnn {#1} {#2} {#3} {#4} }
  }
%    \end{macrocode}
%   We can extract the details for the TOC levels from
%   \tn{@contentsline@destination}. At present, that is quite simple-minded:
%   if we are in the current section, show fully, else make semi-opaque. Needs
%   a rounded-out interface but the basic idea will be the same.
%    \begin{macrocode}
\cs_new_protected:Npn \@@_toc_dest:n
  {
    \exp_after:wN \@@_toc_dest:w \@contentsline@destination
      . 0 . 0 . 0 . \q_stop
  }
\cs_new_protected:Npn \@@_toc_dest:w #1 . #2 . #3 . #4 . #5 \q_stop #6
  {
    \bool_lazy_or:nnTF 
      {
        \bool_lazy_and_p:nn 
          { \int_compare_p:nNn { \value { section } } = {#2} }
          { \int_compare_p:nNn { \value { subsection } } = 0 }
       }
       {
         \bool_lazy_and_p:nn 
           { \int_compare_p:nNn { \value { section } } = {#2} }
           { \int_compare_p:nNn { \value { subsection } } = {#3} }
      }
      {#6}
      {
        \opacity_begin:n { 0.2 }
          #6
        \opacity_end:
      }
  }
\cs_new_protected:Npn \@@_toc_level:nnnn #1#2#3#4
  {
    \int_compare:nNnF {#1} > { \value { tocdepth } }
      {
        \group_begin:
          \noindent
          #2
          \UseHookWithArguments { contentsline / text / before } { 4 }
            {#1} {#3} {#4} { \@contentsline@destination }
          #3
          \UseHookWithArguments { contentsline / text / after } { 4 }
            {#1} {#3} {#4} { \@contentsline@destination }
          \UseHookWithArguments { contentsline / page / before } { 4 }
            {#1} {#3} {#4}
            { \@contentsline@destination }
         \UseHookWithArguments { contentsline / page / after } { 4 }
            {#1} {#3} {#4}
            { \@contentsline@destination }
          \par
        \group_end:
        \vfil
      }
  }
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
%    \begin{macrocode}
\setcounter { tocdepth } { 2 }
%    \end{macrocode}
%
% \subsection{Block environments}
%
% \begin{environment}{description, quote, quotation, verse}
% \begin{environment}{stdquote, stdquotation, stdverse}
%   Stub logical environments: needed as the tagging setup expects these
%   to exist.
%    \begin{macrocode}
\NewDocumentEnvironment { description } { } { } { }
\NewDocumentEnvironment { quote } { } { } { }
\NewDocumentEnvironment { quotation } { } { } { }
\NewDocumentEnvironment { verse } { } { } { }
\AddToHook { begindocument / before }
  {
    \clist_map_inline:nn { quote , quotation , verse }
      {
        \NewEnvironmentCopy { std #1 } {#1}
        \RenewDocumentEnvironment {#1} { d <> !O { } }
          {
            \@@_action_begin:n {##1}
            \begin { std #1 } [ {##2} ]
              \ignorespaces
          }
          {
            \end { std #1 }
            \@@_action_end:
          }
      }
  }
%    \end{macrocode}
% \end{environment}
% \end{environment}
%
% \begin{environment}{block}
%    \begin{macrocode}
\NewDocumentEnvironment { block } { d <> m }
  {
    \@@_action_begin:n {#1}
    \par
    \vbox_set:Nw \l_@@_tmp_box
      \group_begin:
        \medskip
        \leavevmode
        \normalfont \large \bfseries
        \color { structure }
        #2
        \par
        \medskip
      \group_end:
  }
  {
    \vbox_set_end:
    \box_use:N \l_@@_tmp_box
    \par
    \@@_action_end:
  }
%    \end{macrocode}
% \end{environment}
%
% \subsection{Lists}
%
% \begin{macro}{\item}
% \begin{macro}{\@@_item_parse_spec:w}
% \begin{macro}{\@@_item_parse_spec:n}
%   Again, add the additional argument: here, we have to do a little
%   gymnastics. The test for an overlay has to come after the standard item
%   definition: in a list, items have to \emph{close} the structure before
%   them first, so if we test too early, we'd end up covering then uncovering
%   straight away! Once it is stable, we should revisit here to see if it would
%   be sensible to use the hook mechanism.
%    \begin{macrocode}
\AddToHook { begindocument / before }
  {
    \NewCommandCopy \stditem \item
    \RenewDocumentCommand \item { d <> o }
      {
        \IfNoValueTF {#2}
          { \stditem }
          { \stditem [ {#2} ] }
        \IfNoValueTF {#1}
          {
            \exp_after:wN \@@_item_parse_spec:w
              \l_@@_action_spec_str < all > \q_stop
          }
          { \@@_item_parse_spec:n {#1} }
      }
  }
%    \end{macrocode}
%   Parsing the spec is a separate function here as there are a couple of
%   routes to get here. At present we only have a \texttt{false} branch, but
%   for spacing we likely will need to add something to the \texttt{true}
%   branch too. The odd stuff with \tn{currentgrouplevel} here is needed
%   so we only close the item at the correct nesting, allowing for the
%   group that gets added.
%    \begin{macrocode}
\cs_new_protected:Npn \@@_item_parse_spec:w #1 < #2 > #3 \q_stop
  { \@@_item_parse_spec:n {#2} }
\cs_new_protected:Npn \@@_item_parse_spec:n #1
  {
    \bool_lazy_or:nnF
      { \tl_if_blank_p:n {#1} }
      { \str_if_eq_p:nn {#1} { all } }
      {
        \tl_set:Ne \l_@@_list_end_tl
          {
            \exp_not:N \int_compare:nNnT \tex_currentgrouplevel:D =
              { \int_eval:n { \tex_currentgrouplevel:D + 1 } }
              {
                \@@_action_end:
                \tl_clear:N \exp_not:N \l_@@_list_end_tl
              }
          }
        \@@_action_begin:n {#1}
      }
  }
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \begin{variable}{\l_@@_list_end_tl}
%    \begin{macrocode}
\tl_new:N \l_@@_list_end_tl
%    \end{macrocode}
% \end{variable}
% \begin{macro}{\__block_inter_item:, \BlockEnvEnd, \endblockenv}
%  Before \LaTeX{} 2026-6-01, there was no hook pair for surrounding items, so
%  so patching had to be done. The extra complexity here is that there
%  is no test for hook existence, and the hook was not in the first
%  dev release of 2026-06-01. So there is some low-level testing needed:
%  \cs{l__block_topsepadd_skip} is used as a marker.
%    \begin{macrocode}
\cs_if_exist:NTF \l__block_topsepadd_skip
  {
    \cs_gset_protected:Npn \__block_inter_item:
      {
        \legacy_if:nT { @inlabel }
          { \indent \par }
       \mode_if_horizontal:T
         {
           \__block_skip_remove_last:
           \__block_skip_remove_last:
           \par
         }
        \l_@@_list_end_tl
        \__kernel_list_item_end:
        \__kernel_list_item_begin:
        \addpenalty \@itempenalty 
        \addvspace \itemsep
      }
%    \end{macrocode}
%   A rather long block done by expansion to avoid duplication in a patch.
%    \begin{macrocode}
    \cs_gset_protected:Npe \BlockEnvEnd
      {
        \exp_not:n
          { \__block_debug_typeout:n { blockenv~common~ending \on@line } }
          \cs_if_exist:NTF \l__block_transparent_level_bool
            {
              \exp_not:N \bool_if:NF
              \exp_not:N \l__block_transparent_level_bool
            }
            {
              \exp_not:N \bool_if:NT
              \exp_not:N \l__block_level_incr_bool
            }
            { \int_gdecr:N \exp_not:N \g_block_nesting_depth_int }
        \exp_not:n
          {
            \legacy_if:nT { @inlabel }
              {
                \mode_leave_vertical: 
                \legacy_if_gset_false:n { @inlabel }
              }
            \__block_if_list:T
              { \legacy_if:nT { @newlist } { \@noitemerr } }
            \mode_if_horizontal:TF
               {
                 \__block_skip_remove_last:
                 \__block_skip_remove_last:
                 \par
               }
               { \@inmatherr { \end { \@currenvir } } }
            \l_@@_list_end_tl
            \__kernel_displayblock_end:
            \__block_if_list:T { \legacy_if_gset_false:n { @newlist } }
            \legacy_if_gset_false:n { @nobreak }
            \legacy_if:nF { @noparlist }
              {
                \__block_skip_set_to_last:N \l_tmpa_skip
                \dim_compare:nNnT \l_tmpa_skip > \c_zero_dim
                  {
                    \skip_vertical:n { - \l_tmpa_skip }
                    \skip_vertical:n
                      { \l_tmpa_skip + \parskip - \@outerparskip }
                  }
                \addpenalty \@endparpenalty
                \addvspace \l__block_topsepadd_skip
              }
            \socket_use:n { block / endpe }
          }
      }
  }
%    \end{macrocode}
% \end{macro}
% The branch where \cs{l__block_topsepadd_skip} is not defined, which means we
% have a sufficiently new kernel to use the hooks. When we revise for the updated
% kernel, we could consider simply adding the code directly to the hook rather
% than using a token list, although that would mean hook operations each time
% there is an overlay.
%    \begin{macrocode}
  {
    \AddToHook { item / after }
      { \l_@@_list_end_tl }
  }
%    \end{macrocode}
% \begin{environment}{itemize, enumerate, description}
%   Allow for the classical \cls{beamer} syntax: currently two versions but that
%   will only last until the 2026-06-01 release of \LaTeX{} is out.
%    \begin{macrocode}
\AddToHook { begindocument / before }
  {
    \clist_map_inline:nn { itemize , enumerate , description }
      {
        \RenewDocumentEnvironment {#1} { = { action-spec } !o }
          { \SimpleBlockEnv {#1} {##1} }
          { \BlockEnvEnd }
      }
  }
%    \end{macrocode}
% \end{environment}
% And add the structural color to item labels.
%    \begin{macrocode}
\AddToHook { begindocument / before }
  {
    \EditInstance { item } { basic }
      { label-format = \color { structure } #1 }
    \EditInstance { item } { description }
      { label-format = \normalfont \bfseries \color { structure } #1 }
  }
%    \end{macrocode}
%
% \begin{variable}{\l_@@_action_spec_str}
%   Add an overlay key to the \texttt{block} template.  Placed here, it applies
%   \emph{before} the \cs{item} starts, so we do not have to redefine the
%   latter to do actions up-front. This also means it can apply to whatever we
%   want it to within a block.
%    \begin{macrocode}
\keys_define:nn { template / block / std  }
  { action-spec .str_set:N = \l_@@_action_spec_str }
%    \end{macrocode}
% \end{variable}
%
% \subsection{Theorems, \foreign{etc.}}
%
% \begin{macro}{\newtheorem, \stdnewtheorem}
%   We need to extend the creation of theorems by adding the overlay
%   argument. This means grabbing all of the arguments up-front, then having
%   to pass them on to different versions of \cs{newtheorem} depending on
%   what else has been loaded.
%    \begin{macrocode}
\NewCommandCopy \stdnewtheorem \newtheorem
\RenewDocumentCommand \newtheorem { s m o m o }
  {
    \use:e
      {
        \exp_not:N \stdnewtheorem
          \IfBooleanT #1 { * }
          { \exp_not:n {#2} }
          \IfNoValueF {#3} { \exp:not:n { [ {#3} ] } }
          { \exp_not:n {#4} }
          \IfNoValueF {#5} { \exp:not:n { [ {#5} ] } }
      }
    \NewEnvironmentCopy { std #2 } {#2}
    \RenewDocumentEnvironment {#2} { D <> { all } o }
      {
        \@@_action_begin:n {##1}
        \IfNoValueTF {##2}
          { \begin { std #2 } }
          { \begin { std #2 } [ {##2} ] }
            \ignorespaces
      }
      {
        \end { std #2 }
        \@@_action_end:
      }
  }
%    \end{macrocode}
% \end{macro}
%
% \subsection{Bibliographies}
%
% \begin{macro}{thebibliography}
%   The \cls{article} definition but without the section part.
%    \begin{macrocode}
\NewDocumentEnvironment { thebibliography } { m }
  {
    \list { \@biblabel { \@arabic \c@enumiv } }
      {
        \settowidth \labelwidth { \@biblabel {#1} }
        \leftmargin \labelwidth
        \advance \leftmargin \labelsep
        \@openbib@code
        \usecounter { enumiv }
        \let \p@enumiv \@empty
        \renewcommand \theenumiv { \@arabic \c@enumiv }
      }
    \sloppy
    \clubpenalty 4000
    \@clubpenalty \clubpenalty
    \widowpenalty 4000
    \sfcode `\. \@m
  }
  {
    \def \@noitemerr
      { \@latex@warning { Empty~`thebibliography'~environment } }
    \endlist
  }
\cs_set_eq:NN \@openbib@code \@empty
%    \end{macrocode}
% \end{macro}
%
% \subsection{Supplementary material}
%
% \begin{variable}{\l_@@_appendix_bool}
%    \begin{macrocode}
\bool_new:N \l_@@_appendix_bool
%    \end{macrocode}
% \end{variable}
%
% \begin{macro}{\appendix}
%   Set up the global boolean and the TOC control.
%    \begin{macrocode}
\NewDocumentCommand \appendix { D <> { all } }
  {
    \@@_if_overlay:nT {#1}
      { \bool_set_true:N \l_@@_appendix_bool }
    \addtocontents { toc } { \appendixmarker }
    \cs_gset_eq:NN \contentsline \use_none:nnnn
  }
%    \end{macrocode}
% \end{macro}
%
%    \begin{macrocode}
%</class>
%    \end{macrocode}
%
% \end{implementation}
%
% \PrintIndex
