% \iffalse meta-comment
%
%% File: tagpdf-user.dtx
%
% Copyright (C) 2019-2023 Ulrike Fischer
%
% 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 "tagpdf bundle" (The Work in LPPL)
% and all files in that bundle must be distributed together.
%
% -----------------------------------------------------------------------
%
% The development version of the bundle can be found at
%
%    https://github.com/u-fischer/tagpdf
%
% for those people who are interested.
%<*driver>
\DocumentMetadata{}
\documentclass{l3doc}
\usepackage{array,booktabs,caption}
\hypersetup{pdfauthor=Ulrike Fischer,
 pdftitle=tagpdf-user module (tagpdf)}
\begin{document}
  \DocInput{\jobname.dtx}
\end{document}
%</driver>
% \fi
% \title{^^A
%   The \pkg{tagpdf-user} module\\ Code related to \LaTeX2e user commands and document commands   ^^A
%   \\ Part of the tagpdf package
% }
%
% \author{^^A
%  Ulrike Fischer\thanks
%    {^^A
%      E-mail:
%        \href{mailto:fischer@troubleshooting-tex.de}
%          {fischer@troubleshooting-tex.de}^^A
%    }^^A
% }
%
% \date{Version 0.98q, released 2023-11-19}
% \maketitle
% \begin{documentation}
% \section{Setup commands}
% \begin{function}{\tagpdfsetup}
% \begin{syntax}
% \cs{tagpdfsetup}\Arg{key val list}
% \end{syntax}
% This is the main setup command to adapt the behaviour of tagpdf.
% It can be used in the preamble and in the document (but not all keys make sense there).
% \end{function}
%
% \begin{function}{activate (setup-key)}
% And additional setup key which combine the other activate keys
% |activate-mc|, |activate-tree|, |activate-struct| and additionally
% add a document structure.
% \end{function}
%
% \begin{function}{\tag_tool:n,\tagtool}
% \begin{syntax}
% \cs{tag_tool:n}\Arg{key val}
% \end{syntax}
% The tagging of basic document elements will require a variety of small commands
% to configure and adapt the tagging. This command will collect them under a command
% interface. The argument is \emph{one} key-value like string. This is work in progress
% and both syntax, known arguments and implementation can change!
% \end{function}
%
% \section{Commands related to mc-chunks}
% \begin{function}{\tagmcbegin, \tagmcend,\tagmcuse}
% \begin{syntax}
% \cs{tagmcbegin} \Arg{key-val}\\
% \cs{tagmcend}\\
% \cs{tagmcuse}\Arg{label}
% \end{syntax}
% These are wrappers around |\tag_mc_begin:n|, |\tag_mc_end:| and |\tag_mc_use:n|.
% The commands and their argument are documentated in the \pkg{tagpdf-mc} module.
% In difference to the expl3 commands, \cs{tagmcbegin} issues also an \cs{ignorespaces},
% and \cs{tagmcend} will issue in horizontal mode an \cs{unskip}.
% \end{function}
%
% \begin{function}{\tagmcifinTF}
% \begin{syntax}
% \cs{tagmcifin} \Arg{true code}\Arg{false code}
% \end{syntax}
% This is a wrapper around |\tag_mc_if_in:TF|.
% and tests if an mc is open or not. It is mostly of
% importance for pdflatex as lualatex doesn't mind much if a mc tag is not
% correctly closed. Unlike the expl3 command it is not expandable.
%
% The command is probably not of much use and will perhaps disappear in future
% versions. It normally makes more sense to push/pop an mc-chunk.
% \end{function}
%
% \section{Commands related to structures}
% \begin{function}{\tagstructbegin, \tagstructend,\tagstructuse}
% \begin{syntax}
% \cs{tagstructbegin} \Arg{key-val}\\
% \cs{tagstructend}\\
% \cs{tagstructuse}\Arg{label}
% \end{syntax}
% These are direct wrappers around |\tag_struct_begin:n|,
% |\tag_struct_end:| and |\tag_struct_use:n|.
% The commands and their argument are documentated in the \pkg{tagpdf-struct} module.
% \end{function}



% \section{Debugging}
% \begin{function}{\ShowTagging}
%   \begin{syntax}
%   \cs{ShowTagging} \Arg{key-val}
%   \end{syntax}
% This is a generic function to output various debugging helps. It not
% necessarly stops the compilation. The keys and their function are described below.
% \end{function}
%
% \begin{function}{mc-data (show-key)}
%  \begin{syntax}
%    |mc-data| = \meta{number}
%  \end{syntax}
% This key is (currently?) relevant for lua mode only.
% It shows the data of all mc-chunks created so far.
% It is accurate only after shipout (and perhaps a second compilation),
% so typically should be issued after a
% newpage. The value is a positive integer and sets the first mc-shown. If no value
% is given, 1 is used and so all mc-chunks created so far are shown.
% \end{function}
% \begin{function}{mc-current (show-key)}
%  \begin{syntax}
%    |mc-current|
%  \end{syntax}
% This key shows the number and the tag of the currently open mc-chunk. If no
% chunk is open it shows only the state of the abs count. It works in all mode,
% but the output in luamode looks different.
% \end{function}
% \begin{function}{mc-marks (show-key)}
%  \begin{syntax}
%    |mc-marks| = |show|\verb+|+|use|
%  \end{syntax}
% This key helps to debug the page marks. It should only be used at shipout in
% header or footer.
% \end{function}
% \begin{function}{struct-stack (show-key)}
%  \begin{syntax}
%    |struct-stack| = |log|\verb+|+|show|
%  \end{syntax}
% This key shows the current structure stack. With |log| the info is only
% written to the log-file, |show| stops the compilation and shows on the terminal.
% If no value is used, then the default is |show|.
% \end{function}
%
% \section{Extension commands}
% The following commands and code parts are not core command of tagpdf.
% They either provide work-arounds for missing functionality elsewhere,
% or do a first step to apply tagpdf commands to document commands.
%
% The commands and keys should be view as experimental!
%
% This part will be regularly revisited to check if the code should go to a
% better place or can be improved and so can change easily.
%
% \subsection{Fake space}
% \begin{function}{\pdffakespace}
% (lua-only) This provides a lua-version of the |\pdffakespace| primitive of
% pdftex.
% \end{function}
%
% \subsection{Paratagging}
%
% This is a first try to make use of the new paragraph hooks in a current LaTeX to
% automate the tagging of paragraph. It requires sane paragraph nesting,
% faulty code, e.g. a missing |\par| at the end of a low-level vbox can highly
% confuse the tagging. The tags should be carefully checked if this is used.
%
% \begin{function}{paratagging (setup-key),paratagging-show (setup-key)}
%  \begin{syntax}
%    |paratagging| = |true|\verb+|+|false|\\
%    |paratagging-show| = |true|\verb+|+|false|\\
%  \end{syntax}
% This keys can be used in |\tagpdfsetup| and enable/disable paratagging.
% |paratagging-show| puts small red numbers at the begin and end of a paragraph.
% This is meant as a debugging help. The number are boxes and have a (tiny) height,
% so they can affect typesetting.
% \end{function}
%
% \begin{function}{\tagpdfparaOn,\tagpdfparaOff}
% These commands allow to enable/disable para tagging too and are a bit
% faster then |\tagpdfsetup|. But I'm not sure if the names are good.
% \end{function}
%
% \begin{function}{\tagpdfsuppressmarks}
%  This command allows to suppress the creation of the marks. It takes an argument
%  which should normally be one of the mc-commands, puts a group around it and
%  suppress the marks creation in this group. This command should be used if
%  the begin and end command are at different boxing levels. E.g.
%  \begin{verbatim}
%  \@hangfrom
%   {
%    \tagstructbegin{tag=H1}%
%    \tagmcbegin    {tag=H1}%
%    #2
%   }
%   {#3\tagpdfsuppressmarks{\tagmcend}\tagstructend}%
%  \end{verbatim}
% \end{function}
%
% \subsection{Header and footer}
% Header and footer are automatically excluded from tagging. This can
% be disabled with the following key.
% If some real content is in the header and
% footer, tagging must be restarted there explicitly.
% The key accepts the values |true| which surrounds the header with an artifact
% mc-chunk, |false| which disables the automatic tagging, and |pagination| which
% additionally adds an artifact structure with an pagination attribute.
%
% \begin{function}{exclude-header-footer (setup-key)}
%  \begin{syntax}
%    |exclude-header-footer| = |true|\verb+|+|false|\verb+|+pagination
%  \end{syntax}%
% \end{function}

% \subsection{Link tagging}
% Links need a special structure and cross reference system.
% This is added through hooks of the l3pdfannot module and will work
% automatically if tagging is activated.
%
% Links should (probably) have an alternative text in the Contents
% key. It is unclear which text this should be and
% how to get it. Currently the code simply adds the fix texts |url| and |ref|.
% Another text can be added by changing the dictionary value:
% \begin{verbatim}
% \pdfannot_dict_put:nnn
% { link/GoTo }
% { Contents }
% { (ref) }
% \end{verbatim}
% \end{documentation}
%
% \begin{implementation}
% \section{User commands and extensions of document commands}
%    \begin{macrocode}
%<@@=tag>
%<*header>
\ProvidesExplPackage {tagpdf-user} {2023-11-19} {0.98q}
  {tagpdf - user commands}
%</header>
%    \end{macrocode}
% \section{Setup and preamble commands}
% \begin{macro}{\tagpdfsetup}
%    \begin{macrocode}
%<base>\NewDocumentCommand \tagpdfsetup { m }{}
%<*package>
\RenewDocumentCommand \tagpdfsetup { m }
  {
    \keys_set:nn { @@ / setup } { #1 }
  }
%</package>
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\tag_tool:n,\tagtool}
% This is a first definition of the tool command.
% Currently it uses key-val, but this should be probably
% be flattened to speed it up.
%    \begin{macrocode}
%<base>\cs_new_protected:Npn\tag_tool:n #1 {}
%<base>\cs_set_eq:NN\tagtool\tag_tool:n
%<*package>
\cs_set_protected:Npn\tag_tool:n #1 
  {
    \tag_if_active:T { \keys_set:nn {tag / tool}{#1} }  
  }
\cs_set_eq:NN\tagtool\tag_tool:n  
%</package>
%    \end{macrocode}
% \end{macro}

% \section{Commands for the mc-chunks}
% \begin{macro}{\tagmcbegin,\tagmcend,\tagmcuse  }
%    \begin{macrocode}
%<*base>
\NewDocumentCommand \tagmcbegin { m }
  {
    \tag_mc_begin:n {#1}
  }


\NewDocumentCommand \tagmcend {  }
  {
    \tag_mc_end:
  }

\NewDocumentCommand \tagmcuse { m }
  {
    \tag_mc_use:n {#1}
  }
%</base>
%    \end{macrocode}
% \end{macro}

% \begin{macro}{\tagmcifinTF}
% This is a wrapper around |\tag_mc_if_in:| and tests if an mc is open or not. It is mostly of
% importance for pdflatex as lualatex doesn't mind much if a mc tag is not
% correctly closed. Unlike the expl3 command it is not expandable.
%    \begin{macrocode}
%<*package>
\NewDocumentCommand \tagmcifinTF { m m }
  {
    \tag_mc_if_in:TF { #1 } { #2 }
  }
%</package>
%    \end{macrocode}
% \end{macro}
%
% \section{Commands for the structure}
% \begin{macro}{\tagstructbegin,\tagstructend,\tagstructuse  }
%
% These are structure related user commands. There are direct wrapper around the
% expl3 variants.
%    \begin{macrocode}
%<*base>
\NewDocumentCommand \tagstructbegin { m }
  {
    \tag_struct_begin:n {#1}
  }

\NewDocumentCommand \tagstructend {  }
  {
   \tag_struct_end:
  }

\NewDocumentCommand \tagstructuse { m }
  {
    \tag_struct_use:n {#1}
  }
%</base>
%    \end{macrocode}
% \end{macro}
%
%
%
% \section{Debugging}
% \begin{macro}{\ShowTagging}
% This is a generic command for various show commands.
% It takes a keyval list, the various keys are implemented below.
%    \begin{macrocode}
%<*package>
\NewDocumentCommand\ShowTagging { m }
  {
    \keys_set:nn { @@ / show }{ #1}

  }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{mc-data (show-key)}
% This key is (currently?) relevant for lua mode only.
% It shows the data of all mc-chunks created so far.
% It is accurate only after shipout, so typically should be issued after a
% newpage. With the optional argument the minimal number can be set.
%    \begin{macrocode}
\keys_define:nn { @@ / show }
  {
    mc-data .code:n =
      {
        \sys_if_engine_luatex:T
          {
            \lua_now:e{ltx.@@.trace.show_all_mc_data(#1,\@@_get_mc_abs_cnt:,0)}
          }
      }
    ,mc-data .default:n = 1
  }

%    \end{macrocode}
% \end{macro}
% \begin{macro}{mc-current (show-key)}
% This shows some info about the current mc-chunk. It works in generic and lua-mode.
%    \begin{macrocode}
\keys_define:nn { @@ / show }
  { mc-current .code:n =
     {
       \bool_if:NTF \g_@@_mode_lua_bool
         {
           \sys_if_engine_luatex:T
             {
               \int_compare:nNnTF
                 { -2147483647 }
                  =
                 {
                   \lua_now:e
                     {
                        tex.print
                         (tex.getattribute
                           (luatexbase.attributes.g_@@_mc_cnt_attr))
                     }
                 }
                 {
                   \lua_now:e
                     {
                       ltx.@@.trace.log
                        (
                          "mc-current:~no~MC~open,~current~abscnt
                           =\@@_get_mc_abs_cnt:"
                          ,0
                        )
                       texio.write_nl("")
                     }
                 }
                 {
                   \lua_now:e
                     {
                       ltx.@@.trace.log
                        (
                          "mc-current:~abscnt=\@@_get_mc_abs_cnt:=="
                           ..
                           tex.getattribute(luatexbase.attributes.g_@@_mc_cnt_attr)
                           ..
                           "~=>tag="
                           ..
                           tostring
                             (ltx.@@.func.get_tag_from
                               (tex.getattribute
                                 (luatexbase.attributes.g_@@_mc_type_attr)))
                           ..
                           "="
                           ..
                           tex.getattribute
                            (luatexbase.attributes.g_@@_mc_type_attr)
                           ,0
                        )
                       texio.write_nl("")
                     }
                 }
             }
         }
         {
          \msg_note:nn{ tag }{ mc-current }
         }
     }
  }
%    \end{macrocode}
% \end{macro}
% \begin{macro}{mc-marks (show-key)}
% It maps the mc-marks into the sequences and then shows them.
% This allows to inspect the first and last mc-Mark on a page.
% It should only be used in the shipout (header/footer).
%    \begin{macrocode}
\keys_define:nn { @@ / show }
  {
    mc-marks .choice: ,
    mc-marks / show .code:n =
      {
        \@@_mc_get_marks:
        \@@_check_if_mc_in_galley:TF
         {
          \iow_term:n {Marks~from~this~page:~}
         }
         {
           \iow_term:n {Marks~from~a~previous~page:~}
         }
        \seq_show:N \l_@@_mc_firstmarks_seq
        \seq_show:N \l_@@_mc_botmarks_seq
        \@@_check_if_mc_tmb_missing:T
         {
           \iow_term:n {BDC~missing~on~this~page!}
         }
        \@@_check_if_mc_tme_missing:T
         {
           \iow_term:n {EMC~missing~on~this~page!}
         }
      },
    mc-marks / use .code:n =
      {
        \@@_mc_get_marks:
        \@@_check_if_mc_in_galley:TF
         { Marks~from~this~page:~}
         { Marks~from~a~previous~page:~}
        \seq_use:Nn \l_@@_mc_firstmarks_seq {,~}\quad
        \seq_use:Nn \l_@@_mc_botmarks_seq {,~}\quad
        \@@_check_if_mc_tmb_missing:T
         {
           BDC~missing~
         }
        \@@_check_if_mc_tme_missing:T
         {
           EMC~missing
         }
      },
   mc-marks .default:n = show
  }
%    \end{macrocode}
% \end{macro}
% \begin{macro}{struct-stack (show-key)}
%    \begin{macrocode}
\keys_define:nn { @@ / show }
  {
     struct-stack .choice:
    ,struct-stack / log .code:n = \seq_log:N \g_@@_struct_tag_stack_seq
    ,struct-stack / show .code:n = \seq_show:N \g_@@_struct_tag_stack_seq
    ,struct-stack .default:n = show
  }
%</package>  
%    \end{macrocode}
% \end{macro}
% \begin{macro}{debug/structures (show-key)}
%  The following key is available only if the tagpdf-debug package is loaded
%  and shows all structures starting with the one with the number 
%  given by the key.
%    \begin{macrocode}
%<*debug>
\keys_define:nn { @@ / show }
  {
    ,debug/structures .code:n = 
      {
        \int_step_inline:nnn{#1}{\c@g_@@_struct_abs_int}
           {
            \msg_term:nneeee 
                   { tag/debug } { show-struct }
                   { ##1 }
                   { 
                     \prop_map_function:cN 
                       {g_@@_struct_debug_##1_prop} 
                       \msg_show_item_unbraced:nn 
                   }
                   { } { }
            \msg_term:nneeee  
                   { tag/debug } { show-kids }
                   {  ##1 }
                   { 
                     \seq_map_function:cN 
                       {g_@@_struct_debug_kids_##1_seq} 
                       \msg_show_item_unbraced:n
                   }
                   { } { }       
          }
      }    
    ,debug/structures .default:n = 0
  }
%</debug>  
%    \end{macrocode}
% \end{macro}
%
% \section{Commands to extend document commands}
% The following commands and code parts are not core command of tagpdf.
% They either provide work-arounds for missing functionality elsewhere,
% or do a first step to apply tagpdf commands to document commands.
% This part should be regularly revisited to check if the code should go to a
% better place or can be improved.
% 
% \subsection{new ref system}
% Until l3ref is in the kernel, we provide a definition for \cs{newlabeldata} in 
% the aux-file to avoid errors if a document switches between tagging and non-tagging.
%    \begin{macrocode}
%<base>\AddToHook{begindocument}
%<base> {\immediate\write\@mainaux{\string\providecommand\string\newlabeldata[2]{}}}
%<*package>
%    \end{macrocode}
% \subsection{Document structure}
% \begin{macro}{\g_@@_root_default_tl,activate (setup-key)}
%    \begin{macrocode}
\tl_new:N\g_@@_root_default_tl
\tl_gset:Nn\g_@@_root_default_tl {Document}

\hook_gput_code:nnn{begindocument}{tagpdf}{\tagstructbegin{tag=\g_@@_root_default_tl}}
\hook_gput_code:nnn{tagpdf/finish/before}{tagpdf}{\tagstructend}

\keys_define:nn { @@ / setup}
 {    
   activate  .code:n =
    {
      \keys_set:nn { @@ / setup }
        { activate-mc,activate-tree,activate-struct }
      \tl_gset:Nn\g_@@_root_default_tl {#1}  
    },
   activate .default:n = Document
 }
 
%    \end{macrocode}
% \end{macro}
% \subsection{Structure destinations}
% In TeXlive 2022 pdftex and luatex will offer support for structure destinations.
% The  pdfmanagement has already backend support. We activate them if the
% prerequisites are there: structures should be activated,
% the code in the pdfmanagement must be there.
% Structure destinations are actually PDF 2.0  only but they don't harm in 
% older PDF and can improve html export. 
%    \begin{macrocode}
\AddToHook{begindocument/before}
  {
    \bool_lazy_all:nT
      {
        { \g_@@_active_struct_dest_bool }
        { \g_@@_active_struct_bool }
        { \cs_if_exist_p:N \pdf_activate_structure_destination: }
      }
      {
        \tl_set:Nn \l_pdf_current_structure_destination_tl { _@@/struct/\g_@@_struct_stack_current_tl }
        \pdf_activate_structure_destination:
      }
   }
%    \end{macrocode}

% \subsection{Fake space}
% \begin{macro}{\pdffakespace}
% We need a luatex variant for |\pdffakespace|. This should probably go into
% the kernel at some time. We also provide a no-op version for dvi mode
%    \begin{macrocode}
\sys_if_engine_luatex:T
  {
    \NewDocumentCommand\pdffakespace { }
     {
       \@@_fakespace:
     }
  }
\providecommand\pdffakespace{}  
%    \end{macrocode}
% \end{macro}
%
% \subsection{Paratagging}
%  The following are some simple commands to enable/disable paratagging.
%  Probably one should add some checks if we are already in a paragraph.
%
%
%  \begin{macro}{
%   \l_@@_para_bool,
%   \l_@@_para_flattened_bool,
%   \l_@@_para_show_bool,
%   \g_@@_para_begin_int,
%   \g_@@_para_end_int,
%   \g_@@_para_main_begin_int,
%   \g_@@_para_main_end_int,
%   \l_@@_para_tag_default_tl,
%   \l_@@_para_tag_tl,
%   \l_@@_para_main_tag_tl}
%  At first some variables.
%    \begin{macrocode}
\bool_new:N \l_@@_para_bool
%</package>
%<base>\bool_new:N \l_@@_para_flattened_bool
%<*package>
\bool_new:N \l_@@_para_show_bool
\int_new:N  \g_@@_para_begin_int
\int_new:N  \g_@@_para_end_int
\int_new:N  \g_@@_para_main_begin_int
\int_new:N  \g_@@_para_main_end_int
\tl_new:N   \l_@@_para_tag_default_tl
\tl_set:Nn  \l_@@_para_tag_default_tl { text }
\tl_new:N   \l_@@_para_tag_tl
\tl_set:Nn  \l_@@_para_tag_tl { \l_@@_para_tag_default_tl }
\tl_new:N   \l_@@_para_main_tag_tl
\tl_set:Nn  \l_@@_para_main_tag_tl {text-unit}
%    \end{macrocode}
% \end{macro}

% \begin{macro}
%   {
%   \@@_gincr_para_main_begin_int:,
%   \@@_gincr_para_main_end_int:,
%   \@@_gincr_para_begin_int:,
%   \@@_gincr_para_end_int:
%   }
% The global para counter should be set through commands so
% that \cs{tag_stop:} can stop them.  
%    \begin{macrocode}
\cs_new_protected:Npn \@@_gincr_para_main_begin_int:
 {
   \int_gincr:N \g_@@_para_main_begin_int
 }
\cs_new_protected:Npn \@@_gincr_para_begin_int:
 {
   \int_gincr:N \g_@@_para_begin_int
 }
\cs_new_protected:Npn \@@_gincr_para_main_end_int:
 {
   \int_gincr:N \g_@@_para_main_end_int
 }
\cs_new_protected:Npn \@@_gincr_para_end_int:
 {
   \int_gincr:N \g_@@_para_end_int
 }
%    \end{macrocode}
% \end{macro}

% \begin{macro}{\@@_start_para_ints:,\@@_stop_para_ints:}
%    \begin{macrocode}
\cs_new_protected:Npn \@@_start_para_ints:
 {
   \cs_set_protected:Npn \@@_gincr_para_main_begin_int:
     {
       \int_gincr:N \g_@@_para_main_begin_int
     }
   \cs_set_protected:Npn \@@_gincr_para_begin_int:
    {
      \int_gincr:N \g_@@_para_begin_int
    }
   \cs_set_protected:Npn \@@_gincr_para_main_end_int:
    {
      \int_gincr:N \g_@@_para_main_end_int
    }
   \cs_set_protected:Npn \@@_gincr_para_end_int:
    {
      \int_gincr:N \g_@@_para_end_int
    }  
 }
\cs_new_protected:Npn \@@_stop_para_ints:
 {
   \cs_set_eq:NN \@@_gincr_para_main_begin_int:\prg_do_nothing:
   \cs_set_eq:NN \@@_gincr_para_begin_int: \prg_do_nothing:
   \cs_set_eq:NN \@@_gincr_para_main_end_int: \prg_do_nothing:
   \cs_set_eq:NN \@@_gincr_para_end_int: \prg_do_nothing:
 } 
%    \end{macrocode}
% \end{macro}
%
% TEMPORARLY FIX (2023-11-17). Until latex-lab is update we must adapt a sec command:
%    \begin{macrocode}
\AddToHook{package/latex-lab-testphase-sec/after}
 {
   \cs_set_protected:Npn \@kernel@tag@hangfrom #1
    {
     \tagstructbegin{tag=\l__tag_para_tag_tl}
     \__tag_gincr_para_begin_int:
     \tagstructbegin{tag=Lbl}
     \setbox\@tempboxa
       \hbox
         {
           \bool_lazy_and:nnT
            {\tag_if_active_p:}
            {\g__tag_mode_lua_bool}
            {\tagmcbegin{tag=Lbl}}
           {#1}
         }
   \tag_stop:n{hangfrom}
   \hangindent \wd\@tempboxa\noindent
   \tag_start:n{hangfrom}
   \tagmcbegin{}\box\@tempboxa\tagmcend\tagstructend\tagmcbegin{}
   }
 } 
%    \end{macrocode}
% and two adaptions from the block module:
%    \begin{macrocode}
\AddToHook{package/latex-lab-testphase-block/after}
 {
   \cs_set_protected:Npn \__block_start_para_structure:n #1 {
     \__block_debug_typeout:n
        { @endpe = \legacy_if:nTF { @endpe }{true}{false}
          \on@line }
     \legacy_if:nF { @endpe }
       {
         \bool_if:NF \l__tag_para_flattened_bool
            {
              \@@_gincr_para_main_begin_int:
              \tag_struct_begin:n{tag=\l__tag_para_main_tag_tl}
            }
        }
     \@@_gincr_para_begin_int:
     \__block_debug_typeout:n{increment~ P \on@line }
     \tag_struct_begin:n
         {
            tag=\l__tag_para_tag_tl
           ,attribute-class=\l_tag_para_attr_class_tl
         }
     \__tag_check_para_begin_show:nn {green}{#1}    
     \tag_mc_begin:n {}
  }
  \RemoveFromHook{para/end}[latex-lab-testphase-block]
  \AddToHook{para/end}[latex-lab-testphase-block]
   {
    \bool_if:NT \l__tag_para_bool
      {
        \__tag_gincr_para_end_int:
        \__block_debug_typeout:n{increment~ /P \on@line }
        \tag_mc_end:
        \__tag_check_para_end_show:nn {red}{}
        \tag_struct_end:
        \bool_if:NF \l__tag_para_flattened_bool
         {
           \__tag_gincr_para_main_end_int:
           \tag_struct_end:
         }
      }
   }
} 
  
%    \end{macrocode}
%\begin{macro}
% {
%  paratagging (setup-key),
%  paratagging-show (setup-key),
%  paratag (setup-key),
%  paratag (tool-key),
%  unittag (tool-key),
%  para-flattened (tool-key),
%  }
% These keys enable/disable locally paratagging, and the debug modus.
% It can affect the typesetting if |paratagging-show| is used. The small numbers
% are boxes and they have a (small) height. The |paratag| key sets the tag used by
% the next automatic paratagging, it can also be changed with |\tag_tool:n|
%    \begin{macrocode}
\keys_define:nn { @@ / setup }
  {
    paratagging      .bool_set:N = \l_@@_para_bool,
    paratagging-show .bool_set:N = \l_@@_para_show_bool,
    paratag          .tl_set:N   = \l_@@_para_tag_tl
  }
\keys_define:nn { tag / tool} 
  {
    paratag .tl_set:N = \l_@@_para_tag_tl,
    unittag .tl_set:N = \l_@@_para_main_tag_tl,
    para-flattened .bool_set:N = \l_@@_para_flattened_bool
  }
%    \end{macrocode}
% \end{macro}
% This fills the para hooks with the needed code.
%    \begin{macrocode}
\cs_new_protected:Npn \@@_check_para_begin_show:nn #1 #2 
 %#1 color, #2 prefix
  {
    \bool_if:NT \l_@@_para_show_bool
      { 
        \tag_mc_begin:n{artifact}
        \llap{\color_select:n{#1}\tiny#2\int_use:N\g_@@_para_begin_int\ }
        \tag_mc_end:
      }
  }

\cs_new_protected:Npn \@@_check_para_end_show:nn #1 #2
 %#1  color, #2 prefix
  {
    \bool_if:NT \l_@@_para_show_bool
      { 
        \tag_mc_begin:n{artifact}
        \rlap{\color_select:n{#1}\tiny\ #2\int_use:N\g_@@_para_end_int}
        \tag_mc_end:
      }
  }
  
\AddToHook{para/begin}
  {
   \bool_if:NT \l_@@_para_bool
     {
       \bool_if:NF \l_@@_para_flattened_bool
         {
           \@@_gincr_para_main_begin_int:
           \tag_struct_begin:n
             {
               tag=\l_@@_para_main_tag_tl,
             }
         }
       \@@_gincr_para_begin_int:
       \tag_struct_begin:n {tag=\l_@@_para_tag_tl}
       \@@_check_para_begin_show:nn {green}{}
       \tag_mc_begin:n {}
     }
  }
\AddToHook{para/end}
  {
    \bool_if:NT \l_@@_para_bool
      {
        \@@_gincr_para_end_int:
        \tag_mc_end:
        \@@_check_para_end_show:nn {red}{}
        \tag_struct_end:
        \bool_if:NF \l_@@_para_flattened_bool
         {
           \@@_gincr_para_main_end_int:
           \tag_struct_end:
         }
      }
  }
%    \end{macrocode}
% We check the para count at the end. If tagging is not active it is not a error,
% but we issue a warning as it perhaps indicates that the testphase code didn't guard
% everything correctly.
%    \begin{macrocode}
\AddToHook{enddocument/info}
  {
    \tag_if_active:F
      {
        \msg_redirect_name:nnn { tag } { para-hook-count-wrong } { warning }
      }  
    \int_compare:nNnF {\g_@@_para_main_begin_int}={\g_@@_para_main_end_int}
         {
           \msg_error:nneee
             {tag}
             {para-hook-count-wrong}
             {\int_use:N\g_@@_para_main_begin_int}
             {\int_use:N\g_@@_para_main_end_int}
             {text-unit}
         }
    \int_compare:nNnF {\g_@@_para_begin_int}={\g_@@_para_end_int}
         {
           \msg_error:nneee
             {tag}
             {para-hook-count-wrong}
             {\int_use:N\g_@@_para_begin_int}
             {\int_use:N\g_@@_para_end_int}
             {text}
         }  
  }
%    \end{macrocode}
% We need at least the new-or-1 code.
% In generic mode we also must insert the code to finish the MC-chunks 
%    \begin{macrocode}
\@ifpackageloaded{footmisc}
  {\PackageWarning{tagpdf}{tagpdf~has~been~loaded~too~late!}} %
  {\RequirePackage{latex-lab-testphase-new-or-1}}
 
\AddToHook{begindocument/before}
 {
   \providecommand\@kernel@tagsupport@@@@makecol{}
   \providecommand\@kernel@before@cclv{}
   \bool_if:NF \g_@@_mode_lua_bool
     {
        \cs_if_exist:NT \@kernel@before@footins
         {
           \tl_put_right:Nn \@kernel@before@footins
             { \@@_add_missing_mcs_to_stream:Nn \footins {footnote} }
           \tl_put_right:Nn \@kernel@before@cclv
             {
               \@@_check_typeout_v:n {====>~In~\token_to_str:N \@makecol\c_space_tl\the\c@page}
               \@@_add_missing_mcs_to_stream:Nn \@cclv {main}
             }
           \tl_put_right:Nn \@kernel@tagsupport@@@@makecol
             {
               \@@_check_typeout_v:n {====>~In~\token_to_str:N \@makecol\c_space_tl\the\c@page}
               \@@_add_missing_mcs_to_stream:Nn \@outputbox {main}
             }  
           \tl_put_right:Nn \@mult@ptagging@hook
             {
               \@@_check_typeout_v:n {====>~In~\string\page@sofar}
               \process@cols\mult@firstbox
                {
                  \@@_add_missing_mcs_to_stream:Nn \count@ {multicol}
                }
               \@@_add_missing_mcs_to_stream:Nn \mult@rightbox {multicol}
             }
         }
     }
  }
%</package>
%    \end{macrocode}
% \begin{macro}
%   {
%    \tagpdfparaOn,
%    \tagpdfparaOff
%   }
%  This two command switch para mode on and off. |\tagpdfsetup| could be used
%  too but is longer. An alternative is |\tag_tool:n{para=false}|
%    \begin{macrocode}
%<base>\newcommand\tagpdfparaOn {}
%<base>\newcommand\tagpdfparaOff{}
%<*package>
\renewcommand\tagpdfparaOn {\bool_set_true:N \l_@@_para_bool}
\renewcommand\tagpdfparaOff{\bool_set_false:N \l_@@_para_bool}
\keys_define:nn { tag / tool} 
  {
    para .bool_set:N = \l_@@_para_bool,
    para-flattened .bool_set:N = \l_@@_para_flattened_bool,
  }  
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}
%   {
%    \tagpdfsuppressmarks
%   }
%  This command allows to suppress the creation of the marks. It takes an argument
%  which should normally be one of the mc-commands, puts a group around it and
%  suppress the marks creation in this group. This command should be used if
%  the begin and end command are at different boxing levels. E.g.
%  \begin{verbatim}
%  \@hangfrom
%   {
%    \tagstructbegin{tag=H1}%
%    \tagmcbegin    {tag=H1}%
%    #2
%   }
%   {#3\tagpdfsuppressmarks{\tagmcend}\tagstructend}%
%  \end{verbatim}
%    \begin{macrocode}
\NewDocumentCommand\tagpdfsuppressmarks{m}
  {{\use:c{@@_mc_disable_marks:} #1}}
%    \end{macrocode}
% \end{macro}
% \subsection{Header and footer}
% Header and footer should normally be tagged as artifacts. The following code
% requires the new hooks.
% For now we allow to disable this function, but probably the code should always there at
% the end.
% TODO check if Pagination should be changeable.
%    \begin{macrocode}
\cs_new_protected:Npn\@@_hook_kernel_before_head:{}
\cs_new_protected:Npn\@@_hook_kernel_after_head:{}
\cs_new_protected:Npn\@@_hook_kernel_before_foot:{}
\cs_new_protected:Npn\@@_hook_kernel_after_foot:{}

\AddToHook{begindocument}
 {
  \cs_if_exist:NT \@kernel@before@head
   {
     \tl_put_right:Nn \@kernel@before@head {\@@_hook_kernel_before_head:}
     \tl_put_left:Nn  \@kernel@after@head  {\@@_hook_kernel_after_head:}
     \tl_put_right:Nn \@kernel@before@foot {\@@_hook_kernel_before_foot:}
     \tl_put_left:Nn  \@kernel@after@foot  {\@@_hook_kernel_after_foot:}
   }
 }

\bool_new:N \g_@@_saved_in_mc_bool
\cs_new_protected:Npn \@@_exclude_headfoot_begin:
 {
    \bool_set_false:N  \l_@@_para_bool
    \bool_if:NTF \g_@@_mode_lua_bool
     {
      \tag_mc_end_push:
     }
     {
       \bool_gset_eq:NN   \g_@@_saved_in_mc_bool \g_@@_in_mc_bool
       \bool_gset_false:N \g_@@_in_mc_bool
     }
    \tag_mc_begin:n {artifact}
    \tag_stop:n{headfoot}
 }
\cs_new_protected:Npn \@@_exclude_headfoot_end:
 {
    \tag_start:n{headfoot}
    \tag_mc_end:
    \bool_if:NTF \g_@@_mode_lua_bool
     {
      \tag_mc_begin_pop:n{}
     }
     {
       \bool_gset_eq:NN \g_@@_in_mc_bool\g_@@_saved_in_mc_bool
     }
 }
%    \end{macrocode}
% This version allows to use an Artifact structure
%    \begin{macrocode}
\@@_attr_new_entry:nn {@@/attr/pagination}{/O/Artifact/Type/Pagination}
\cs_new_protected:Npn \@@_exclude_struct_headfoot_begin:n #1
 {
    \bool_set_false:N  \l_@@_para_bool
    \bool_if:NTF \g_@@_mode_lua_bool
     {
      \tag_mc_end_push:
     }
     {
       \bool_gset_eq:NN   \g_@@_saved_in_mc_bool \g_@@_in_mc_bool
       \bool_gset_false:N \g_@@_in_mc_bool
     }
    \tag_struct_begin:n{tag=Artifact,attribute-class=@@/attr/#1}
    \tag_mc_begin:n {artifact=#1}
    \tag_stop:n{headfoot}
 }

\cs_new_protected:Npn \@@_exclude_struct_headfoot_end:
 {
    \tag_start:n{headfoot}
    \tag_mc_end:
    \tag_struct_end:
    \bool_if:NTF \g_@@_mode_lua_bool
     {
      \tag_mc_begin_pop:n{}
     }
     {
       \bool_gset_eq:NN \g_@@_in_mc_bool\g_@@_saved_in_mc_bool
     }
 }
%    \end{macrocode}
% And now the keys
% \begin{macro}{exclude-header-footer (setup-key)}
%    \begin{macrocode}
\keys_define:nn { @@ / setup }
  {
    exclude-header-footer .choice:,
    exclude-header-footer / true .code:n =
     {
       \cs_set_eq:NN \@@_hook_kernel_before_head: \@@_exclude_headfoot_begin:
       \cs_set_eq:NN \@@_hook_kernel_before_foot: \@@_exclude_headfoot_begin:
       \cs_set_eq:NN \@@_hook_kernel_after_head:  \@@_exclude_headfoot_end:
       \cs_set_eq:NN \@@_hook_kernel_after_foot:  \@@_exclude_headfoot_end:
     },
    exclude-header-footer / pagination .code:n =
     {
       \cs_set:Nn \@@_hook_kernel_before_head: { \@@_exclude_struct_headfoot_begin:n {pagination} }
       \cs_set:Nn \@@_hook_kernel_before_foot: { \@@_exclude_struct_headfoot_begin:n {pagination} }
       \cs_set_eq:NN \@@_hook_kernel_after_head:  \@@_exclude_struct_headfoot_end:
       \cs_set_eq:NN \@@_hook_kernel_after_foot:  \@@_exclude_struct_headfoot_end:
     },
    exclude-header-footer / false .code:n =
     {
       \cs_set_eq:NN \@@_hook_kernel_before_head: \prg_do_nothing:
       \cs_set_eq:NN \@@_hook_kernel_before_foot: \prg_do_nothing:
       \cs_set_eq:NN \@@_hook_kernel_after_head:  \prg_do_nothing:
       \cs_set_eq:NN \@@_hook_kernel_after_foot:  \prg_do_nothing:
     },
   exclude-header-footer .default:n = true,
   exclude-header-footer .initial:n = true
  }
%    \end{macrocode}
% \end{macro}
% \subsection{Links}
% We need to close and reopen mc-chunks around links.
% Currently we handle URI and GoTo (internal) links.
% Links should have an alternative text in the Contents
% key. It is unclear which text this should be and
% how to get it.
%    \begin{macrocode}
\hook_gput_code:nnn
  {pdfannot/link/URI/before}
  {tagpdf}
  {
    \tag_mc_end_push:
    \tag_struct_begin:n { tag=Link }
    \tag_mc_begin:n { tag=Link }
    \pdfannot_dict_put:nne
      { link/URI }
      { StructParent }
      { \tag_struct_parent_int: }
  }

\hook_gput_code:nnn
  {pdfannot/link/URI/after}
  {tagpdf}
  {
     \tag_struct_insert_annot:ee {\pdfannot_link_ref_last:}{\tag_struct_parent_int:}
     \tag_mc_end:
     \tag_struct_end:
     \tag_mc_begin_pop:n{}
  }

\hook_gput_code:nnn
  {pdfannot/link/GoTo/before}
  {tagpdf}
  {
     \tag_mc_end_push:
     \tag_struct_begin:n{tag=Link}
     \tag_mc_begin:n{tag=Link}
     \pdfannot_dict_put:nne
       { link/GoTo }
       { StructParent }
       { \tag_struct_parent_int: }
  }

\hook_gput_code:nnn
  {pdfannot/link/GoTo/after}
  {tagpdf}
  {
    \tag_struct_insert_annot:ee {\pdfannot_link_ref_last:}{\tag_struct_parent_int:}
    \tag_mc_end:
    \tag_struct_end:
    \tag_mc_begin_pop:n{}

  }

% "alternative descriptions " for PAX3. How to get better text here??
\pdfannot_dict_put:nnn
 { link/URI }
 { Contents }
 { (url) }

\pdfannot_dict_put:nnn
 { link/GoTo }
 { Contents }
 { (ref) }

%    \end{macrocode}
%</package>
% \end{implementation}
% \PrintIndex
