% \iffalse meta-comment
%
%% File: tagpdf-mc.dtx
%
% Copyright (C) 2019-2020 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.
%
% \fi
%
%    \begin{macrocode}
%<@@=tag>
%<*shared>
\ProvidesExplPackage {tagpdf-mc-code-shared} {2021/02/23} {0.80}
  {part of tagpdf - code related to marking chunks -
   code shared by generic and luamode }
% I use a latex counter for the absolute count, so that it is added to
% \cl@@ckpt and restored e.g. in tabulars and align
% \int_new:N  \c@g_@@_MCID_int and
% \tl_put_right:Nn\cl@@ckpt{\@elt{g_uf_test_int}}
% would work too, but as the name is not expl3 then too, why bother?
% the absolute counter can be used to label and to check if the page
% counter needs a reset.

\newcounter { g_@@_MCID_abs_int }
\cs_new:Nn \_@@_get_mc_abs_cnt: { \int_use:N \c@g_@@_MCID_abs_int }

% tagmcabs is the label name of the absolute count which is used
% to identify the chunk
% the ref code is now in tagpdf.dtx

%stores labels of mcid.
\cs_new:Nn \_@@_mc_handle_mc_label:n
  {
    \@@_ref_label:en{tagpdf-#1}{mc}
  }

% will hold the structure numbers for the parenttree
% key:   absolute number of the mc (tagmcabs)
% value: the structure number the mc is in
\_@@_prop_new:N \g_@@_mc_parenttree_prop

% shared keys
% the rest are in the splitted code
\tl_new:N \l_@@_mc_artifact_type_tl

\keys_define:nn { @@ / mc }
  {
    stash                  .bool_set:N    = \l_@@_mc_key_stash_bool,
    artifact-bool          .bool_set:N    = \l_@@_mc_artifact_bool,
    artifact-type          .choice:,
    artifact-type / pagination .code:n    =
      {
        \tl_set:Nn \l_@@_mc_artifact_type_tl { Pagination }
      },
    artifact-type / layout     .code:n    =
      {
        \tl_set:Nn \l_@@_mc_artifact_type_tl { Layout }
      },
    artifact-type / page       .code:n    =
      {
        \tl_set:Nn \l_@@_mc_artifact_type_tl { Page }
      },
    artifact-type / background .code:n    =
      {
        \tl_set:Nn \l_@@_mc_artifact_type_tl { Background }
      },
    artifact-type / notype     .code:n    =
      {
        \tl_set:Nn \l_@@_mc_artifact_type_tl {}
      },
     artifact-type /      .code:n    =
      {
        \tl_set:Nn \l_@@_mc_artifact_type_tl {}
      },
  }
%    \end{macrocode}
%  \begin{function}[added = 2019-11-20]
%   {
%     \tag_mc_artifact_group_begin:n, \tag_mc_artifact_group_end:
%   }
%   \begin{syntax}
%     \cs{tag_mc_artifact_group_begin:n} \Arg{name}
%   \end{syntax}
%   This command pair create a group with an artifact marker at the begin
%   and the end. Inside the group the tagging commands are disabled.
%   \end{function}
%    \begin{macrocode}


\cs_new_protected:Npn \tag_mc_artifact_group_begin:n #1
 {
  \tag_mc_begin:n {artifact=#1}
  \tag_stop_group_begin:
 }

\cs_new_protected:Npn \tag_mc_artifact_group_end:
 {
  \tag_stop_group_end:
  \tag_mc_end:
 }

% we need to define it for both modes to avoid a problem with the label
\int_new:N \g_@@_MCID_tmp_bypage_int

%</shared>
%    \end{macrocode}
%    \begin{macrocode}
%<*generic>
\ProvidesExplPackage {tagpdf-mc-code-generic} {2021/02/23} {0.80}
 {part of tagpdf - code related to marking chunks - generic mode}

% for the label system
% tagmcid is the id which should be also in the pdf
% it will be (hopefully) reset by page

% ref code is in tagpdf.dtx now
%
% will hold the current maximum on a page
% it will contain key-value of type "abspagenum=max mcid on this page"
\@@_prop_new:N \g_@@_MCID_byabspage_prop

%to test nesting mc:
\bool_new:N \g_@@_in_mc_bool

\prg_new_conditional:Nnn \@@_mc_if_in: {p,T,F,TF}
  {
    \bool_if:NTF \g_@@_in_mc_bool
      { \prg_return_true:  }
      { \prg_return_false: }
  }

\prg_new_eq_conditional:NNn \tag_mc_if_in: \@@_mc_if_in: {p,T,F,TF}

%deprecated
\prg_new_eq_conditional:NNn \uftag_mc_if_in: \@@_mc_if_in: {p,T,F,TF}


% this are the low level mc command.
% they insert literals and so a are specific to generic mode
% checking if the type is defined will done somewhere else
% #1 is the type/tag
% change 04.08.2018: I don't try to escape the name, but assume that it is valid.
% Checks/conversions should perhaps be done on a higher level
\cs_new_protected:Nn \@@_mc_bmc:n
  {
    \pdf_bmc:n {#1}
%    \@@_pdfliteral_page:n
%      {
%        /#1\c_space_tl BMC
%      }
  }

\cs_new_protected:Nn \@@_mc_emc:
  {
    \pdf_emc:
    %\@@_pdfliteral_page:n
%      {
%        EMC
%      }
  }

% #1 tag, #2 properties
% change 04.08.2018: I don't escape the name. Also the dictionary content
% must imho be done at a higher level
\cs_new_protected:Nn \@@_mc_bdc:nn
  {
    \pdf_bdc:nn { #1 } { #2 }
  }

\cs_generate_variant:Nn \@@_mc_bdc:nn {nx}
% bdc with /MCID + more properties
% we need a ref-label system to ensure that the cnt restarts at 0 on a new page

\tl_new:N \l_@@_mc_ref_abspage_tl %will store the abspage value of label
\tl_new:N \l_@@_mc_tmp_tl

\cs_new:Nn \@@_mc_bdc_mcid:nn
  {
    \int_gincr:N \c@g_@@_MCID_abs_int
    \tl_set:Nx \l_@@_mc_ref_abspage_tl
      {
        \@@_ref_value:enn %3 args
          {
            mcid-\int_use:N \c@g_@@_MCID_abs_int
          }
          { tagabspage }
          {-1}
      }
    \prop_get:NoNTF
      \g_@@_MCID_byabspage_prop
      {
        \l_@@_mc_ref_abspage_tl
      }
      \l_@@_mc_tmp_tl
      {
        %key already present, use value for MCID and add 1 for the next
        \int_gset:Nn \g_@@_MCID_tmp_bypage_int { \l_@@_mc_tmp_tl }
        \@@_prop_gput:Nxx
          \g_@@_MCID_byabspage_prop
          { \l_@@_mc_ref_abspage_tl }
          { \int_eval:n {\l_@@_mc_tmp_tl +1} }
      }
      {
        %key not present, set MCID to 0 and insert 1
        \int_gzero:N \g_@@_MCID_tmp_bypage_int
        \@@_prop_gput:Nxx
          \g_@@_MCID_byabspage_prop
          { \l_@@_mc_ref_abspage_tl }
          {1}
      }
    \@@_ref_label:en
      {
        mcid-\int_use:N \c@g_@@_MCID_abs_int
      }
      { mc }
   %\exp_args:Nnx
     \@@_mc_bdc:nx
       {#1}
       { /MCID~\int_eval:n { \g_@@_MCID_tmp_bypage_int }~ \exp_not:n { #2 } }
 }

% only /MCID
\cs_new:Nn \@@_mc_bdc_mcid:n
  {
    \@@_mc_bdc_mcid:nn {#1} {}
  }

%artifact without type
\cs_new:Nn  \@@_mc_bmc_artifact:
  {
    \@@_mc_bmc:n {Artifact}
  }

%artifact with a type:
\cs_new:Nn \@@_mc_bmc_artifact:n
  {
    \@@_mc_bdc:nn {Artifact}{/Type/#1}
  }

% perhaps later: more properties for artifacts


% keyval definitions for the user commands:

\tl_new:N \l_@@_mc_key_tag_tl
\tl_new:N \g_@@_mc_key_tag_tl %for "outside" queries
\tl_new:N \l_@@_mc_key_properties_tl

% Attention! definitions are different in luamode.
% tag and raw are expanded as \directlua in lua does it too.
\keys_define:nn { @@ / mc }
  {
    tag .code:n = % the name (H,P,Spa) etc
      {
         %%????????? \pdfescapename??
        \tl_set:Nx   \l_@@_mc_key_tag_tl { #1 }
        \tl_gset:Nx  \g_@@_mc_key_tag_tl { #1 }
      },
    raw  .code:n =
      {
        \tl_put_right:Nx \l_@@_mc_key_properties_tl { #1 }
      },
    alttext .code:n = % Alt property
      {
        \str_set_convert:Nnon
          \l_@@_tmpa_str
          { #1 }
          { default }
          { utf16/hex }
        \tl_put_right:Nn \l_@@_mc_key_properties_tl { /Alt~< }
        \tl_put_right:No \l_@@_mc_key_properties_tl { \l_@@_tmpa_str>~ }
      },
    alttext-o .code:n      = % Alt property
      {
        \str_set_convert:Noon
          \l_@@_tmpa_str
          { #1 }
          { default }
          { utf16/hex }
        \tl_put_right:Nn \l_@@_mc_key_properties_tl { /Alt~< }
        \tl_put_right:No \l_@@_mc_key_properties_tl { \l_@@_tmpa_str>~ }
      },
    actualtext .code:n      = % ActualText property
      {
        \str_set_convert:Nnon
          \l_@@_tmpa_str
          { #1 }
          { default }
          { utf16/hex }
        \tl_put_right:Nn \l_@@_mc_key_properties_tl { /ActualText~< }
        \tl_put_right:No \l_@@_mc_key_properties_tl { \l_@@_tmpa_str>~ }
      },
    actualtext-o .code:n      = % ActualText property
      {
        \str_set_convert:Noon
          \l_@@_tmpa_str
          { #1 }
          { default }
          { utf16/hex }
        \tl_put_right:Nn \l_@@_mc_key_properties_tl { /ActualText~< }
        \tl_put_right:No \l_@@_mc_key_properties_tl { \l_@@_tmpa_str>~ }
      },
    label .tl_set:N        = \l_@@_mc_key_label_tl,
    artifact .code:n       =
      {
        \exp_args:Nnx
          \keys_set:nn
            { @@ / mc }
            { artifact-bool, artifact-type=#1 }
      },
    artifact .default:n    = {notype}
  }

\cs_new:Nn \@@_mc_handle_artifact:N %#1 contains the artifact type
  {
    \tl_if_empty:NTF #1
      { \@@_mc_bmc_artifact: }
      { \exp_args:No\@@_mc_bmc_artifact:n {#1} }
  }

\cs_new:Nn \@@_mc_handle_mcid:nn %#1 tag, #2 properties
  {
    \@@_mc_bdc_mcid:nn {#1} {#2}
  }

\cs_generate_variant:Nn \@@_mc_handle_mcid:nn {VV}

% puts the absolute number of an mcid in the current structure
\cs_new:Nn \@@_mc_handle_stash:n %1 mcidnum
  {
    \@@_check_mc_used:n {#1}
    \@@_struct_kid_mc_gput_right:nn
      { \g_@@_struct_stack_current_tl }
      {#1}
   \prop_gput:Nxx \g_@@_mc_parenttree_prop
     {#1}
     { \g_@@_struct_stack_current_tl }
  }

\cs_new_protected:Nn \tag_mc_begin:n
  {
    \group_begin: %hm
    \@@_check_mc_if_nested:
    \bool_gset_true:N \g_@@_in_mc_bool
    \keys_set:nn { @@ / mc } {#1}
    \bool_if:NTF \l_@@_mc_artifact_bool
      { %handle artifact
        \@@_mc_handle_artifact:N \l_@@_mc_artifact_type_tl
      }
      { %handle mcid type
        \@@_check_mc_tag:N  \l_@@_mc_key_tag_tl
        \@@_mc_handle_mcid:VV
           \l_@@_mc_key_tag_tl
           \l_@@_mc_key_properties_tl
        \tl_if_empty:NF {\l_@@_mc_key_label_tl}
          {
            \@@_mc_handle_mc_label:n { \l_@@_mc_key_label_tl }
          }
        \bool_if:NF \l_@@_mc_key_stash_bool
          {
            \@@_mc_handle_stash:n { \int_use:N \c@g_@@_MCID_abs_int }
          }
      }
    \group_end:
  }

%deprecated
\cs_set_eq:NN \uftag_mc_begin:n \tag_mc_begin:n

\cs_new_protected:Nn \tag_mc_end:
  {
    \@@_check_mc_if_open:
    \bool_gset_false:N \g_@@_in_mc_bool
    \tl_gset:Nn  \g_@@_mc_key_tag_tl { }
    \@@_mc_emc:
  }

\cs_set_eq:NN \uftag_mc_end: \tag_mc_end:

\cs_new_protected:Nn \tag_mc_use:n %#1: label name
  {
    \tl_set:Nx  \l_tmpa_tl { \@@_ref_value:enn{tagpdf-#1}{tagmcabs}{} }
    \tl_if_empty:NTF\l_tmpa_tl
      {
        \msg_warning:nnn {tag} {mc-label-unknown} {#1}
      }
      {
        \prop_gput:Nxx
          \g_@@_mc_parenttree_prop
          {
            \@@_ref_value:enn {tagpdf-#1} {tagmcabs} {}
          }
          {
            \g_@@_struct_stack_current_tl
          }
        \@@_struct_kid_mc_gput_right:nn
          {
            \g_@@_struct_stack_current_tl
          }
          {
            \@@_ref_value:enn {tagpdf-#1} {tagmcabs} {}
          }
       }
  }

%deprecated
\cs_set_eq:NN \uftag_mc_use:n \tag_mc_use:n

\cs_new:Nn \@@_get_data_mc_tag: { \g_@@_mc_key_tag_tl }

%</generic>
%    \end{macrocode}
%    \begin{macrocode}
%<*luamode>
\ProvidesExplPackage {tagpdf-mc-code-lua} {2021/02/23} {0.80}
  {tagpdf - mc code only for the luamode }

% the two attibutes are defined in the driver file.
% it also load the lua (as it can also contain functions needed by generic mode.
% (new) attributes for mc are local:
% \newattribute \l_@@_mc_type_attr     %the value represent the type
% \newattribute \l_@@_mc_cnt_attr      %will hold the \c@g_@@_MCID_abs_int value


% An attribute for the current structure probably doesn't make sense as mc chunks can be used later.
% \newattribute \g_@@_struct_type_attr %represent the current structure type. Not sure if needed
% \newattribute \g_@@_struct_cnt_attr  %will hold \c@g_@@_struct_abs_int a cnt

% handling attribute needs a different system to number the page wise mcid's:
% a tagmcbegin ... tagmcend pair no longer surrounds exactly one mc chunk: it can be split
% at page breaks. We know the included mcid(s) only after the ship out. So for the struct-> mcid mapping we
% need to record struct -> mc-cnt (in \g_@@_mc_parenttree_prop and/or a lua table
% and at shipout mc-cnt-> {mcid, mcid, ...} (in a table?)
% and when building the trees connect both

% key definitions are overwritten for luatex to store that data in tables
% the data for the mc are in ltx.@@.mc[absnum]
% the fields of the table are
% tag : the type (a string)
% raw : more properties (string)
% label: a string. Do we need a way to retrieve the num from the label from lua??
% artifact: the presence indicates an artifact, the value (string) is the type.
% kids: a array of tables {1={kid=num2,page=pagenum1}, 2={kid=num2,page=pagenum2},...},
% this describes the chunks the mc has been split to by the traversing code
% parent: the number of the structure it is in. Needed to build the parent tree.

% The main function which wanders through the shipout box to inject the literals.
% if the new callback is there, it is used.
\hook_gput_code:nnn{begindocument}{tagpdf/mc}
  {
    \bool_if:NT\g__tag_active_mc_bool
      {
        \directlua
          {
            if~luatexbase.callbacktypes.pre_shipout_filter~then~
              luatexbase.add_to_callback("pre_shipout_filter", function(TAGBOX)~
              ltx.__tag.func.mark_shipout(TAGBOX)~return~true~
              end, "tagpdf")~
            end
          }
       \directlua
         {
           if~luatexbase.callbacktypes.pre_shipout_filter~then~
           token.get_next()~
           end
         }\@secondoftwo\@gobble
           {
             \hook_gput_code:nnn{shipout/before}{tagpdf/lua}
               {
                 \directlua
                   { ltx.__tag.func.mark_shipout (tex.box["ShipoutBox"]) }
               }
           }
      }
  }

\prg_new_conditional:Nnn \@@_mc_if_in: {p,T,F,TF}
  {
    \int_compare:nNnTF { -2147483647 }={ \l_@@_mc_type_attr }
      { \prg_return_false:  }
      { \prg_return_true: }
  }

\prg_new_eq_conditional:NNn \tag_mc_if_in: \@@_mc_if_in: {p,T,F,TF}

%deprecated
\prg_new_eq_conditional:NNn \uftag_mc_if_in: \@@_mc_if_in: {p,T,F,TF}

% the keys
\tl_new:N \l_@@_mc_key_tag_tl
\tl_new:N \l_@@_mc_key_label_tl
\tl_new:N \l_@@_mc_key_properties_tl

\keys_define:nn { @@ / mc }
  {
    tag .code:n = %
      {%%????????? \pdfescapename??
        \tl_set:Nx  \l_@@_mc_key_tag_tl { #1 }
        \directlua
          {
            ltx.@@.func.store_mc_data(\@@_get_mc_abs_cnt:,"tag","#1")
          }
      },
    raw .code:n =
      {
        \tl_put_right:Nx \l_@@_mc_key_properties_tl { #1 }
        \directlua
          {
            ltx.@@.func.store_mc_data(\@@_get_mc_abs_cnt:,"raw","#1")
          }
      },
    alttext .code:n      = % Alt property
      {
        \str_set_convert:Nnon
          \l_@@_tmpa_str
          { #1 }
          { default }
          { utf16/hex }
        \tl_put_right:Nn \l_@@_mc_key_properties_tl { /Alt~< }
        \tl_put_right:No \l_@@_mc_key_properties_tl { \l_@@_tmpa_str>~ }
        \directlua
          {
            ltx.@@.func.store_mc_data
              (
                 \@@_get_mc_abs_cnt:,"alt","/Alt~<\str_use:N \l_@@_tmpa_str>"
              )
          }
      },
    alttext-o .code:n      = % Alt property
      {
        \str_set_convert:Noon
          \l_@@_tmpa_str
          { #1 }
          { default }
          { utf16/hex }
        \tl_put_right:Nn \l_@@_mc_key_properties_tl { /Alt~< }
        \tl_put_right:No \l_@@_mc_key_properties_tl { \l_@@_tmpa_str>~ }
        \directlua
          {
            ltx.@@.func.store_mc_data
              (
                \@@_get_mc_abs_cnt:,"alt","/Alt~<\str_use:N \l_@@_tmpa_str>"
              )
          }
      },
    actualtext .code:n      = % Alt property
      {
        \str_set_convert:Nnon
          \l_@@_tmpa_str
          { #1 }
          { default }
          { utf16/hex }
        \tl_put_right:Nn \l_@@_mc_key_properties_tl { /Alt~< }
        \tl_put_right:No \l_@@_mc_key_properties_tl { \l_@@_tmpa_str>~ }
        \directlua
          {
            ltx.@@.func.store_mc_data
              (
                \@@_get_mc_abs_cnt:,"actualtext","/ActualText~<\str_use:N \l_@@_tmpa_str>"
              )
         }
      },
    actualtext-o .code:n      = % Alt property
      {
        \str_set_convert:Noon
          \l_@@_tmpa_str
          { #1 }
          { default }
          { utf16/hex }
        \tl_put_right:Nn \l_@@_mc_key_properties_tl { /Alt~< }
        \tl_put_right:No \l_@@_mc_key_properties_tl { \l_@@_tmpa_str>~ }
        \directlua
          {
            ltx.@@.func.store_mc_data
              (
                \@@_get_mc_abs_cnt:,
                "actualtext",
                "/ActualText~<\str_use:N \l_@@_tmpa_str>"
              )
          }
      },
    label .code:n =
      {
        \tl_set:Nn\l_@@_mc_key_label_tl { #1 }
        \directlua
          {
            ltx.@@.func.store_mc_data
              (
                \@@_get_mc_abs_cnt:,"label","#1"
              )
          }
      },
    __artifact-store .code:n =
      {
        \directlua
          {
            ltx.@@.func.store_mc_data
              (
                \@@_get_mc_abs_cnt:,"artifact","#1"
              )
          }
      },
    artifact .code:n       =
      {
        \exp_args:Nnx
          \keys_set:nn
            { @@ / mc}
            { artifact-bool, artifact-type=#1, tag=Artifact }
        \exp_args:Nnx
          \keys_set:nn
            { @@ / mc }
            { __artifact-store=\l_@@_mc_artifact_type_tl }
      },
    artifact .default:n    = { notype }
  }


% attributes
% set the mc from a tag name

\cs_set_protected:Npn \@@_attribute_gset:Nn #1 #2
  {
    \tex_global:D \setattribute #1 #2
  }

\cs_set_protected:Npn \@@_attribute_set:Nn #1 #2
  {
    \setattribute #1 #2
  }

\cs_set_protected:Npn \@@_attribute_gunset:N #1
  {
    \tex_global:D \unsetattribute #1
  }

\cs_set_protected:Npn \@@_attribute_unset:N #1
  {
    \unsetattribute #1
  }


\cs_new:Nn \@@_mc_lua_set_mc_type_attr:n % #1 is a tag name
  {
    \@@_attribute_set:Nn \l_@@_mc_type_attr
      {
        \directlua { ltx.@@.func.output_num_from ("#1") }
      }
    \@@_attribute_set:Nn \l_@@_mc_cnt_attr  { \@@_get_mc_abs_cnt: }
  }

\cs_generate_variant:Nn\@@_mc_lua_set_mc_type_attr:n { o }

\cs_new:Nn \@@_mc_lua_unset_mc_type_attr:
  {
    \@@_attribute_unset:N \l_@@_mc_type_attr
    \@@_attribute_unset:N \l_@@_mc_cnt_attr
  }



%This command will in the finish code replace the dummy for a mc by the real mcid kids
%we need a variant for the case that it is the only kid, to get the array right
\cs_new:Nn \@@_mc_insert_mcid_kids:n
  {
    \directlua { ltx.@@.func.mc_insert_kids (#1,0) }
  }

\cs_new:Nn \@@_mc_insert_mcid_single_kids:n
  {
    \directlua {ltx.@@.func.mc_insert_kids (#1,1) }
  }


% we need to pass the info if the kids are alone or already in an array
% so we add a second argument, which should == 1 if the kids are single


% puts an mcid absolute number in the current structure
\cs_new:Nn \@@_mc_handle_stash:n %1 mcidnum
  {
    \@@_check_mc_used:n { #1 }
    \seq_gput_right:cn % Don't fill a lua table due to the command in the item,
                       % so use the kernel command
      { g_@@_struct_kids_\g_@@_struct_stack_current_tl _seq }
      {
        \@@_mc_insert_mcid_kids:n {#1}%
      }
    \directlua
      {
        ltx.@@.func.store_struct_mcabs
          (
            \g_@@_struct_stack_current_tl,#1
          )
      }
    \prop_gput:Nxx
      \g_@@_mc_parenttree_prop
      { #1 }
      { \g_@@_struct_stack_current_tl }
  }

\cs_generate_variant:Nn \@@_mc_handle_stash:n { o }

\cs_new_protected:Nn \tag_mc_begin:n
  {
    %\group_begin:
    %\@@_check_mc_if_nested:
    %\bool_gset_true:N \g_@@_in_mc_bool
    \bool_set_false:N\l_@@_mc_artifact_bool
    \int_gincr:N \c@g_@@_MCID_abs_int
    \tl_clear:N \l_@@_mc_key_properties_tl
    \keys_set:nn { @@ / mc }{ label={}, #1 }
    %check that a tag or artifact has been used
    \@@_check_mc_tag:N \l_@@_mc_key_tag_tl
    %set the attributes:
    \@@_mc_lua_set_mc_type_attr:o  { \l_@@_mc_key_tag_tl }
    \bool_if:NF \l_@@_mc_artifact_bool
      { % store the absolute num name in a label:
        \tl_if_empty:NF {\l_@@_mc_key_label_tl}
          {
            \@@_mc_handle_mc_label:n { \l_@@_mc_key_label_tl }
          }
       % if not stashed record the absolute number
        \bool_if:NF \l_@@_mc_key_stash_bool
          {
            \exp_args:Nx \@@_mc_handle_stash:n { \@@_get_mc_abs_cnt: }
          }
      }
    %\bool_set_false:N\l_@@_mc_artifact_bool
    %\group_end:
  }

%deprecated
\cs_set_eq:NN \uftag_mc_begin:n \tag_mc_begin:n

\cs_new_protected:Nn \tag_mc_end:
  {
    %\@@_check_mc_if_open:
    %\bool_gset_false:N \g_@@_in_mc_bool
    \bool_set_false:N\l_@@_mc_artifact_bool
    \@@_mc_lua_unset_mc_type_attr:
    \tl_set:Nn  \l_@@_mc_key_tag_tl { }
  }

\cs_set_eq:NN \uftag_mc_end: \tag_mc_end:

\cs_new_protected:Nn \tag_mc_use:n %#1: label name
  {
    \tl_set:Nx  \l_tmpa_tl { \@@_ref_value:enn{tagpdf-#1}{tagmcabs}{} }
    \tl_if_empty:NTF\l_tmpa_tl
      {
        \msg_warning:nnn {tag} {mc-label-unknown} { #1 }
      }
      {
        \@@_mc_handle_stash:o { \l_tmpa_tl }
      }
  }

\cs_set_eq:NN \uftag_mc_use:n \tag_mc_use:n

\cs_new:Nn \@@_get_data_mc_tag: { \l_@@_mc_key_tag_tl }
%</luamode>
%    \end{macrocode}
