% \iffalse meta-comment
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% memoize-ext.dtx
% Additions and changes Copyright (C) 2024-2026 Clea F. Rees.
% Code from skeleton.dtx Copyright (C) 2015-2024 Scott Pakin (see below).
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3c
% of this license or (at your option) any later version.
% The latest version of this license is in
%   https://www.latex-project.org/lppl.txt
% and version 1.3c or later is part of all distributions of LaTeX
% version 2008-05-04 or later.
%
% This work has the LPPL maintenance status 'muaintained'.
%
% The Current Maintainer of this work is Clea F. Rees.
%
% This work consists of all files listed in manifest.txt.
%
% The file memoize-ext.dtx is a derived work under the terms of the
% LPPL. It is based on version 2.4 of skeleton.dtx which is part of
% dtxtut by Scott Pakin. A copy of dtxtut, including the
% unmodified version of skeleton.dtx is available from
% https://www.ctan.org/pkg/dtxtut and released under the LPPL.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \fi
%
% \iffalse
%<*driver>
\GetIdInfo $Id: memoize-ext-tag.dtx 11815 2026-03-25 19:50:49Z cfrees $ {Extensions for Memoize}
\ProvidesExplFile{\ExplFileName}{\ExplFileDate}{v0.3.5 \ExplFileVersion}{\ExplFileDescription}
\begin{document}
\let\MakePrivateLetters\MyMakePrivateLetters
\DocInput{\filename}
\end{document}
%</driver>
% \fi
% 
%
% \title{\ExplFileName}
% \date{\ExplFileVersion~\ExplFileDate}
% \maketitle
%
% \begin{abstract}
%   \noindent\pkg{memoize-ext-tag} is part of \pkg{memoize-ext}.
%   It supports tagging memoized content/the memoization of tagged content.
% \end{abstract}
%
%
% \tableofcontents
% 
% 
% \MaybeStop{%
% \PrintChanges
% \PrintIndex
% }
% 
% ^^A \section{Implementation}
%
% Uses and/or redefines the following internals, primitives and other nefarious methods:
% \begin{itemize}
%   \item \verb|\l__socket_assigned_plug:n| thing
%   \begin{itemize}
%     \item If a public interface for retrieving the plug is provided at some point, I will see if I can use that.
%       However, they do not wish it to be expandable. 
%       This is manageable, but it is very nice having an expandable function here, so I will see if I realise, remember and can do it not-too-painfully, I guess.
%   \end{itemize}
%   \item \pkg{latex-lab} variables, keys etc.
%   \begin{itemize}
%     \item This is fairly fragile: patching patches to make them work with patched patches \dots.
%     \item But I guess the \pkg{l3keys} and \pkg{pgfkeys} are public.
%       I'm not sure about the sockets/plugs.
%       Are these supposed to be used by external code?
%     \item The use of \verb|l__tikz_tagging_alt_tl| and \verb|l__tikz_tagging_actualtext_tl| is definitely ungood, but I do not currently see a better way.
%       Hopefully most people will use the \pkg{pgfkeys} interface, as that's much more natural here?
%   \end{itemize}
%   \item \verb|\tex_savepos:D|
%   \begin{itemize}
%     \item This is more-or-less routine and actually documented, so no worries really here?
%   \end{itemize}
%   \item \cs{mmzIncludeExtern}
%   \begin{itemize}
%     \item Documented as internal, certainly not something to redefine, but maybe I can persuade Sašo to add the sockets I need here?
%   \end{itemize}
% \end{itemize}
%
%<*sty>
%<@@=mmzx>
%    \begin{macrocode}
\GetIdInfo $Id: memoize-ext-tag.dtx 11815 2026-03-25 19:50:49Z cfrees $ {Extensions for Memoize for tagged tikz pictures}
%<!debug>    \ProvidesExplPackage{\ExplFileName}{\ExplFileDate}
%<!debug>     {v0.3.5 \ExplFileVersion}{\ExplFileDescription}
%<debug>    \ProvidesExplPackage{\ExplFileName-debug}{\ExplFileDate}
%<debug>      {v0.3.5 \ExplFileVersion}{\ExplFileDescription}
%
%<!debug>    \disable@package@load {memoize-ext-tag-debug}
%<debug>    \disable@package@load {memoize-ext-tag}
{ Only~one~of~memoize-ext-tag~and~memoize-ext-tag-debug~
  should~be~loaded.
  Since~
%<!debug>    memoize-ext-tag
%<debug>    memoize-ext-tag-debug
  ~has~been~loaded,~I~will~ignore~your~request~for~
%<debug>    memoize-ext-tag
%<!debug>    memoize-ext-tag-debug
.}
%    \end{macrocode}
%    \begin{macrocode}
%<!debug>    \RequirePackage{memoize-ext}
%<debug>    \RequirePackage{memoize-ext-debug}
%
%    \end{macrocode}
% We don't want inconsistent names in hooks.
%    \begin{macrocode}
\SetDefaultHookLabel{memoize-ext}
%
\cs_generate_variant:Nn \socket_assign_plug:nn {nV}
%    \end{macrocode}
% \begin{var}{\g_@@_tagpic_int,\l_@@_toks_tl,\l_@@_ok_bool,\g_@@_plug_orig_str}
% \begin{toksr}{\mmzxtagtoks}
%   Tracking \& storage variables.
%    \begin{macrocode}
\bool_new:N \l_@@_ok_bool
\int_new:N \g_@@_tagpic_int
\str_new:N \g_@@_plug_orig_str
\tl_new:N \l_@@_toks_tl
\newtoks\mmzxtagtoks
%    \end{macrocode}
% \end{toksr}
% \end{var}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \begin{socket}{tagsupport/memoize/include/extern/before,tagsupport/memoize/include/extern/after}
%   New sockets for extern utilisation.
%    \begin{macrocode}
\socket_new:nn {tagsupport/memoize/include/extern/before} {3}
\socket_new:nn {tagsupport/memoize/include/extern/after} {0}
%    \end{macrocode}
% \end{socket}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Ulrike's pgf/tikz keys don't do anything with the arguments they receive? 
% It only seems they do because \texttt{init} passes them also to the l3keys?
%
% And so we have to pass them from tikz to l3keys and back to tikz \dots.
%
% This creates a problem of synchronisation.
% It would be nice to use module-specific names to track \pkg{latex-lab} internal variables for ease of maintenance, but I don't think this is possible.
% If I let a new name to a token list variable, I'll just get the current value. 
% 
% On the one hand, if users use \pkg{pgfkeys} to set the values for \texttt{alt} and \texttt{actualtext}, we can easily avoid \pkg{latex-lab} internals, at least.
% But we do that by introducing additional variables and then have the problem of synchronisation.
%
% On the other hand, we could avoid the synchronisation problems by using \pkg{latex-lab} internals more consistently, but then even the \pkg{pgfkeys} interface will be dependent on the internal implementation\footnote{%
%   I get the prohibition on internals.
%   I really do.
%   But there are cases where it just makes things much more complicated and error-prone.
%   And sometimes it just doesn't not seem worth the additional fragility that introduces, even at the cost of some additional fragility due to the use of internals.%
% }.
% \changes{v0.2}{2026-02-27}{See \texttt{init}.}
% 
% Note: will need revising when the \pkg{pgfkeys} version of the \pkg{latex-lab} code gets published.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%    \begin{macrocode}
\hook_gput_code:nnn {package/tikz/after} {.}
{
  \pgfqkeys{/tikz}{
    alt/.forward~to=/mmz/alt,
    actualtext/.forward~to=/mmz/actualtext,
    artifact/.forward~to=/mmz/artifact,
    tagging-setup/.forward~to=/mmz/tagging-setup,
    /mmzx/tagging@setup/.is~family,
    alt/.belongs~to~family=/mmzx/tagging@setup,
    artifact/.belongs~to~family=/mmzx/tagging@setup,
    actualtext/.belongs~to~family=/mmzx/tagging@setup,
    tagging-setup/.belongs~to~family=/mmzx/tagging@setup,
  }
  \mmzset{
    alt/.code={
      \keys_set:nn {tikz/tagging}{alt={#1}}
      \bool_set_true:N \l_@@_ok_bool
      \str_gset:Nn \g_@@_plug_orig_str {alt}
      \exp_args:Ne \mmzxtagtoks { \text_purify:n {#1} }
      \socket_assign_plug:nn 
        {tagsupport/memoize/include/extern/before} {mmzx/alt}
      \socket_assign_plug:nn 
        {tagsupport/memoize/include/extern/after} {mmzx/alt}
%<debug>    \tl_log:e {\exp_args:No \exp_not:n {\the\mmzCCMemo}}
    },
    actualtext/.code={
      \keys_set:nn {tikz/tagging}{actualtext={#1}}
      \bool_set_true:N \l_@@_ok_bool
      \str_gset:Nn \g_@@_plug_orig_str {actualtext}
      \exp_args:Ne \mmzxtagtoks { \text_purify:n {#1} }
      \socket_assign_plug:nn 
        {tagsupport/memoize/include/extern/before} {mmzx/actualtext}
      \socket_assign_plug:nn 
        {tagsupport/memoize/include/extern/after} {mmzx/actualtext}
%<debug>    \tl_log:e {\exp_args:No \exp_not:n {\the\mmzCCMemo}}
    },
    artifact/.code={
      \keys_set:nn {tikz/tagging}{artifact}
      \bool_set_true:N \l_@@_ok_bool
      \str_gset:Nn \g_@@_plug_orig_str {artifact}
      \mmzxtagtoks {}
      \socket_assign_plug:nn 
        {tagsupport/memoize/include/extern/before} {mmzx/artifact}
      \socket_assign_plug:nn 
        {tagsupport/memoize/include/extern/after} {mmzx/artifact}
%<debug>    \tl_log:e {\exp_args:No \exp_not:n {\the\mmzCCMemo}}
    },
    tagging-setup/.is~choice,
    tagging-setup/alt/.forward~to=/mmz/alt,
    tagging-setup/actualtext/.forward~to=/mmz/actualtext,
    tagging-setup/artifact/.forward~to=/mmz/artifact,
    tagging-setup/.unknown/.code =
    {
      \exp_args:Nno
      \keys_set:nn {tikz/tagging}{\pgfkeyscurrentname={#1}}
    },
    alt/.belongs~to~family=/mmzx/tagging@setup,
    actualtext/.belongs~to~family=/mmzx/tagging@setup,
    artifact/.belongs~to~family=/mmzx/tagging@setup,
    tagging-setup/.belongs~to~family=/mmzx/tagging@setup,
    tagging-setup/alt/.belongs~to~family=/mmzx/tagging@setup,
    tagging-setup/actualtext/.belongs~to~family=/mmzx/tagging@setup,
    tagging-setup/artifact/.belongs~to~family=/mmzx/tagging@setup,
  }
}
%    \end{macrocode}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% So it is possible to do without this, but it is \emph{much} more straightforward to do with.
%
% The basic idea is this:
% \begin{itemize}
%   \item At the start of memoization, we redefine the (internal) command \cs{mmzIncludeExtern}.
%   \item In its place, we use simple wrapper around a copy of the original.
%   \item The wrapper defines a socket before and after executing the original.
% \end{itemize}
% This lets us wrap utilisation of the extern in an appropriate tagging structure.
% At least, that's the idea.
%
% It would be nice to assign the plug here just based on whichever plugs are installed, but it is too early, while \cs{mmzAtEndMemoization} is too late.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%    \begin{macrocode}
\appto\mmzAtBeginMemoization{
  \gtoksapp\mmzCCMemo{
    \let\mmzxIncludeExternOrig\mmzIncludeExtern
    \let\mmzIncludeExtern\mmzxIncludeExtern
  }
}
%    \end{macrocode}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \begin{fn}{\@@_noop:nNnnnnnnn,\@@_include_extern:nNnnnnnnn}
% \begin{macro}{\mmzxIncludeExtern,\mmzxIncludeExternOrig}
%   \cs{mmzIncludeExtern} only seems to be defined during utilisation, so we set up a command \cs{mmzxIncludeExternOrig} and set it to noop here, then redefine it locally when the extern is utilised.
%   \cs{mmzIncludeExtern} is then redefined to \cs{mmzxIncludeExtern}, which wraps \cs{mmzxIncludeExternOrig} in a tagging structure\footnote{%
%   Note to self: check output of tests visually if you do not want documents to be inaccessible to that tiny group of people who rely on vision to read.%
% }.
%
%   Note this not only uses, but redefines an internal command which the manual says users should never need to even use \dots.
%
%   On the other hand, this is exactly the kind of thing \pkg{memoize} does to \emph{other} packages' internals and, indeed, to the \LaTeX{} Project's.
%   Which is more than can be said to defend my use of their internals \dots.
%
%   But does that lessen my guilt? :-)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%    \begin{macrocode}
\cs_new_protected_nopar:Npn 
  \@@_noop:nNnnnnnnn #1#2#3#4#5#6#7#8#9 {}
\cs_new_protected_nopar:Npn \@@_include_extern:nNnnnnnnn #1#2#3#4#5#6#7#8#9
{
  \int_gincr:N \g_@@_tagpic_int
%<debug>    \@@_debug:n {Args:~#1;~#2;~#3;~#4;~#5;~#6;~#7;~#8;~#9}
  \socket_use:nnnn {tagsupport/memoize/include/extern/before}
    {#3}{#4}{#5}
%<debug>    \@@_debug:n {Executing~original~inclusion~macro.}
  \mmzxIncludeExternOrig {#1}#2{#3}{#4}{#5}{#6}{#7}{#8}{#9}
%<debug>    \@@_debug:n {Closing~tagging~structures.}
  \socket_use:n {tagsupport/memoize/include/extern/after}
}
\cs_new_eq:NN \mmzxIncludeExtern \@@_include_extern:nNnnnnnnn
\cs_new_eq:NN \mmzxIncludeExternOrig \@@_noop:nNnnnnnnn
%    \end{macrocode}
% \end{macro}
% \end{fn}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \begin{plug}{tagsupport/memoize/include/extern/before~mmzx/alt}
% pgf/tikz
% addaswyd o latex-lab-testphase-tika.sty
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% <<<
%    \begin{macrocode}
\socket_new_plug:nnn {tagsupport/memoize/include/extern/before} {mmzx/alt}
{
%<debug>    \@@_debug:n {Executing~plug~mmzx/alt~in~socket~
%<debug>      tagsupport/memoize/include/extern/before.}
  \mode_if_vertical:T
  {
    \if@inlabel
      \mode_leave_vertical:
    \else
      \tag_socket_use:n {para/begin}
    \fi
  }
  \tag_mc_end_push:
  \tl_set:No \l_@@_toks_tl {\the\mmzxtagtoks}
  \tag_struct_begin:n 
  {
    tag=Figure,
    alt=\l_@@_toks_tl,
  }
  \tag_mc_begin:n {tag=Figure}
  \cs_new:cpe {mmzx@tag@tikz@mark@pos@\int_to_arabic:n {\g_@@_tagpic_int}}
  {
    \@@_pgftikz_tag_bbox:ennn {mmzx-id\int_to_arabic:n {\g_@@_tagpic_int}}
    {#1}{#2}{#3}
  }
%<debug>    \cs_log:c {mmzx@tag@tikz@mark@pos@\int_to_arabic:n 
%<debug>      {\g_@@_tagpic_int}}
  \tag_struct_gput:ene
  {\tag_get:n {struct_num}}
  {attribute}
  {
    /O /Layout /BBox~
    [
      \use:c
      {mmzx@tag@tikz@mark@pos@\int_to_arabic:n {\g_@@_tagpic_int}}
    ]
  }
%<debug>    \@@_debug:e {Recording~xpos,~
%<debug>      ypos~of~mmxc-id\int_to_arabic:n {\g_@@_tagpic_int}.}
  \tex_savepos:D
  \@@_property_record_orig:ee
    {mmzx-id\int_to_arabic:n {\g_@@_tagpic_int}}
    {xpos,ypos}
  \tex_savepos:D
}
%    \end{macrocode}
% \end{plug}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% >>>
% \begin{plug}{tagsupport/memoize/include/extern/after~mmzx/alt}
% pgf/tikz
% addaswyd o latex-lab-testphase-tika.sty
% bod yn onest, cafodd ei ddwyn o \pkg{latex-lab} yn hollol
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% <<<
%    \begin{macrocode}
\socket_new_plug:nnn {tagsupport/memoize/include/extern/after} {mmzx/alt}
{
%<debug>    \@@_debug:n {Executing~plug~mmzx/alt~in~socket~
%<debug>      tagsupport/memoize/include/extern/after.}
  \tag_mc_end:
  \tag_struct_end:
  \tag_mc_begin_pop:n {}
}
%    \end{macrocode}
% \end{plug}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% >>>
% \begin{plug}{%
%   tagsupport/memoize/include/extern/before~mmzx/actualtext,
%   tagsupport/memoize/include/extern/after~mmzx/actualtext,
% }
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% <<<
% addaswyd o latex-lab-testphase-tika.sty
%    \begin{macrocode}
\socket_new_plug:nnn {tagsupport/memoize/include/extern/before} {mmzx/actualtext}
{
%<debug>    \@@_debug:n {Executing~plug~mmzx/actualtext~in~socket~
%<debug>      tagsupport/memoize/include/extern/before.}
  \keys_set:nn {tikz/tagging} {actualtext:o = {\the\mmzxtagtoks},}
  \socket_use:n {tagsupport/tikz/picture/begin}
}
\socket_new_plug:nnn {tagsupport/memoize/include/extern/after} {mmzx/actualtext}
{
%<debug>    \@@_debug:n {Executing~plug~mmzx/actualtext~in~socket~
%<debug>      tagsupport/memoize/include/extern/after.}
  \socket_use:n {tagsupport/tikz/picture/end}
}
%    \end{macrocode}
% \end{plug}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% >>>
% \begin{plug}{%
%   tagsupport/memoize/include/extern/before~mmzx/artifact,
%   tagsupport/memoize/include/extern/after~mmzx/artifact,
% }
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% <<<
% addaswyd o latex-lab-testphase-tika.sty
%    \begin{macrocode}
\socket_new_plug:nnn {tagsupport/memoize/include/extern/before} {mmzx/artifact}
{
%<debug>    \@@_debug:n {Executing~plug~mmzx/artifact~in~socket~
%<debug>      tagsupport/memoize/include/extern/before.}
  \keys_set:nn {tikz/tagging} {artifact,}
  \socket_use:n {tagsupport/tikz/picture/begin}
}
\socket_new_plug:nnn {tagsupport/memoize/include/extern/after} {mmzx/artifact}
{
%<debug>    \@@_debug:n {Executing~plug~mmzx/artifact~in~socket~
%<debug>      tagsupport/memoize/include/extern/after.}
  \socket_use:n {tagsupport/tikz/picture/end}
}
%    \end{macrocode}
% \end{plug}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% >>>
% \begin{fn}{\@@_pgftikz_tag_bbox:nnnn,\@@_pgftikz_tag_bbox:ennn}
%   A \pkg{memoize}-friendly alternative to get the bounding box for the \texttt{alt} plug.
%    \begin{macrocode}
\cs_new_nopar:Npn \@@_pgftikz_tag_bbox:nnnn #1#2#3#4
{
  \_@@_pgftikz_tag_bbox_aux:eennn
  {
    \mmzx_property_ref_orig:ee {#1}{xpos}
  }
  {
    \mmzx_property_ref_orig:ee {#1}{ypos}
  }
  {#2}{#3}{#4}
}
\cs_generate_variant:Nn \@@_pgftikz_tag_bbox:nnnn {ennn}
%    \end{macrocode}
% \end{fn}
% \begin{fn}{\@@_pgftikz_tag_bbox_aux:nnnnn,\@@_pgftikz_tag_bbox_aux:eennn}
%   Auxiliary. 
%    \begin{macrocode}
\cs_new_nopar:Npn \@@_pgftikz_tag_bbox_aux:nnnnn #1#2#3#4#5
{
  \dim_to_decimal_in_bp:n {#1sp}
  \c_space_tl
  \dim_to_decimal_in_bp:n {#2sp-#5}
  \c_space_tl
  \dim_to_decimal_in_bp:n {#1sp+#3}
  \c_space_tl
  \dim_to_decimal_in_bp:n {#2sp+#4+#5}
}
\cs_generate_variant:Nn \@@_pgftikz_tag_bbox_aux:nnnnn {eennn}
%    \end{macrocode}
% \end{fn}
%    \begin{macrocode}
\hook_gput_code_with_args:nnn {cmd/tikz@picture/before} {mmzx}
{
  \tag_if_active:T
  {
%<debug>    \@@_debug:n {Executing~mmzx~code~in~hook~cmd/tikz@picture/before.}
    \socket_assign_plug:nn {tagsupport/tikz/picture/init} {mmzx}
  }
}
%    \end{macrocode}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% >>>
% \begin{plug}{tagsupport/tikz/picture/init~mmzx}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% <<<
%   Originally, I made something much more complicated, which worked, but meh.
%   Here the idea is that \emph{if we are memoizing, we do not tag at all}.
%   There's no real downside to this: a document which includes code memoized during the current run is not usable anyway and tagging the memoized code is pointless and inefficient.
%   (Actually, so is executing the original code for use during the current run, which is, I believe, how it works. 
%   But that is not my fault.)
%
%   Instead, we tag \emph{only the utilisation of memos}. 
%   We don't need to get the bounding box --- \pkg{memoize} already does that.
%   All we need do is get the position on the page during utilisation.
%   Everything else is for free.
%
%   Note that this code uses multiple format/\pkg{latex-lab} internals.
%   If the support for \pkg{tikz} used exclusively \pkg{pgfkeys}, this would be easily avoided: we could stick to the public interface for all but one of these usages.
%   But because it supports also \pkg{l3keys}, I don't see a way to avoid depending on internal variables there, too. 
%   \pkg{l3keys} does not have a \verb|.forward_to:n| or similar.
%   There is \verb|.inherit:n|, but that does not work at all in the same way.
% \changes{v0.2}{2026-02-27}{Avoid processing non-tagging keys too early and too often.
%   Save and restore existing filter state.%
% }
% Filtering and family code (below) is copied from the code I suggested for \pkg{latex-lab}'s \TikZ{} support (\href{https://github.com/latex3/latex2e/pull/2004}{\#2004}).
%    \begin{macrocode}
\socket_new_plug:nnn {tagsupport/tikz/picture/init} {mmzx}
{
%<debug>    \@@_debug:n {Executing~plug~mmzx~in~socket~
%<debug>      tagsupport/tikz/picture/init.}
  \bool_set_false:N \l_@@_ok_bool
  \legacy_if:nT {memoizing}
  {
%<debug>    \@@_debug:n {Arg~to~tagsupport/tikz/picture/init~is~#1.}
    \pgfkeyssavekeyfilterstateto\mmzx@tagging@setup@saved@filterstate
    \pgfkeysinstallkeyfilter{/pgf/key~filters/active~families}{}
    \pgfqkeysactivatesinglefamilyandfilteroptions{/mmzx/tagging@setup}{/tikz}{#1}
%<debug>    \@@_debug:e { Restoring~filter~state:~\exp_not:V 
%<debug>      \mmzx@tagging@setup@saved@filterstate }
    \mmzx@tagging@setup@saved@filterstate
    \bool_if:NF \l_@@_ok_bool
    {
%<debug>            \@@_debug:n {
%<debug>              No~plug~set~for~utilisation.~Trying~to~match~latex-lab~plug.
%<debug>            }
%    \end{macrocode}
% If the argument to the picture set the plug, it is already in the code hash.
% Otherwise, we add the value of the \pkg{latex-lab} plug to the context, using \cs{mmzContextExtra} and appending globally as we are memoizing by hypothesis.
% \changes{v0.3.1}{2026-03-06}{Default to OK.}
%    \begin{macrocode}
      \xtoksapp\mmzContextExtra {
        tagging~plug=\@@_socket_assigned_plug:n {tagsupport/tikz/picture/begin},
      }
      \str_case_e:nn
      {\@@_socket_assigned_plug:n {tagsupport/tikz/picture/begin}}
      {
        {alt} {
          \exp_args:Ne \mmzset{
            alt = \exp_not:V \l__tikz_tagging_alt_tl,
          }
%<debug>            \@@_debug:n {Using~alt~plug.}
        }
        {actualtext} {
          \exp_args:Ne \mmzset{
            actualtext = \exp_not:V \l__tikz_tagging_actualtext_tl,
          }
%<debug>            \@@_debug:n {Using~actualtext~plug.}
        }
        {artifact} {
          \mmzset{artifact,}
%<debug>            \@@_debug:n {Using~artifact~plug.}
        }
        {text} {
          \bool_set_false:N \l_@@_ok_bool
%<debug>            \@@_debug:e {Found~unsupported~
%<debug>              text~
%<debug>              {tagsupport/tikz/picture/begin}~plug.}
          \PackageWarning{memoize-ext}{Unsupported~tag~config~for~tikz~picture.~
            Please~use~alt,~actualtext,~artifact~or~another supported~plug.~
            Note~that~text~(the~latex-lab~default)~is~NOT~supported.~
            Aborting~memoization~and~marking~code~unmemoizable.
          }
          \mmzUnmemoizable
        }
      }
    }
  }
  \bool_if:NT \l_@@_ok_bool
  {
    % ^^A uses the currently assigned plugs for the before/after sockets
    \@@_tag_socket_plug_record: 
%<debug>    \@@_debug:n {Disabling~tagging~for~current~tikz~picture~during~
%<debug>      current~run.}
    \socket_assign_plug:nn {tagsupport/tikz/picture/begin} {noop}
    \socket_assign_plug:nn {tagsupport/tikz/picture/end} {noop}
    \socket_assign_plug:nn {tagsupport/tikz/picture/text/begin} {noop}
    \socket_assign_plug:nn {tagsupport/tikz/picture/text/end} {noop}
  } 
}
%    \end{macrocode}
% \end{plug}
%    \begin{macrocode}
\hook_gput_code:nnn {cmd/mmzAbort/after} {.}
{
  \legacy_if:nT {memoizing} {
    \PackageWarning{memoize-ext}{
      Memoization~has~been~aborted.~If~something~like~a~reference~needs~
      resolving,~just~compile~again.~If~the~content~is~unmemoizable~--~
      e.g.~contains~remember~picture,~a~breakable~tcolorbox~or~suchlike,~
      you~**must**~mark~the~content~unmemoizable~or~the~tagging~will~be~
      incorrect.~You~may~do~this~automatically~or~manually.~Aborted~
    }
  }
}
%    \end{macrocode}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% >>>
% \begin{fn}{\@@_tag_socket_plug_record:nnn,
%   \@@_tag_socket_plug_record:nn,
%   \@@_tag_socket_plug_record:ee,
%   \@@_tag_socket_plug_record:,
%   %
% }
% Wrappers for the most common cases of recording plugs for use in utilisation.
% \changes{v0.3.4}{2026-03-24}{Add fns.\ \ecs{@@_tag_socket_plug_record:nnn}, \ecs{@@_tag_socket_plug_record:nn}, \ecs{@@_tag_socket_plug_record:ee} and \ecs{@@_tag_socket_plug_record:}.}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% <<<
%    \begin{macrocode}
\cs_new_protected:Npn \@@_tag_socket_plug_record:nn #1#2
{
  \xtoksapp\mmzCCMemo{
    \exp_not:N \mmzxtagtoks
    =
    \c_left_brace_str
    \the\mmzxtagtoks
    \c_right_brace_str
    \exp_not:N \AssignSocketPlug
    \c_left_brace_str
    tagsupport/memoize/include/extern/before
    \c_right_brace_str
    \c_left_brace_str
    #1
    \c_right_brace_str
    \exp_not:N \AssignSocketPlug
    \c_left_brace_str
    tagsupport/memoize/include/extern/after
    \c_right_brace_str
    \c_left_brace_str
    #2
    \c_right_brace_str
  }
}
\cs_generate_variant:Nn \@@_tag_socket_plug_record:nn {ee}
\cs_new_protected:Npn \@@_tag_socket_plug_record: 
{
  \@@_tag_socket_plug_record:ee 
  {\@@_socket_assigned_plug:n {tagsupport/memoize/include/extern/before}}
  {\@@_socket_assigned_plug:n {tagsupport/memoize/include/extern/after}}
}
\cs_new_protected:Npn \@@_tag_socket_plug_record:nnn #1#2#3
{
  \mmzxtagtoks { \text_purify:n {#3} }
  \@@_tag_socket_plug_record:nn {#1} {#2}
}
%    \end{macrocode}
% \end{fn}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% >>>
% \begin{fn}{\mmzx_tag_get_recorded:N}
%   \changes{v0.3.4}{2026-03-25}{New expl3 fn.\ to get recorded text.}
%   Intended for use in plugs.
% 
%   \verb|#1| should be a local token list variable.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% <<<
%    \begin{macrocode}
\cs_new_protected_nopar:Npn \mmzx_tag_get_recorded:N #1
{
  \tl_set:No #1 {\the\mmzxtagtoks}
}
%    \end{macrocode}
% \end{fn}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% >>>
% \begin{fn}{\mmzx_tag_socket_plug_record:nnn,
%   \mmzx_tag_socket_plug_record:nn,
%   \mmzx_tag_socket_plug_record:%
% }
% \changes{v0.3.4}{2026-03-24}{Add fns.\ \ecs{mmzx_tag_socket_plug_record:nn} and \ecs{mmzx_tag_socket_plug_record:}.}
% Public names for recording and auto-recording plugs.
% Note \cs{mmzxtagtoks} is available here and is auto-recorded regardless.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% <<<
%    \begin{macrocode}
\cs_new_eq:NN \mmzx_tag_socket_plug_record:nnn \@@_tag_socket_plug_record:nnn
\cs_new_eq:NN \mmzx_tag_socket_plug_record:nn \@@_tag_socket_plug_record:nn
\cs_new_eq:NN \mmzx_tag_socket_plug_record: \@@_tag_socket_plug_record:
%    \end{macrocode}
% \end{fn}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% >>>
% pgf/tikz
% addaswyd o latex-lab-testphase-tika.sty
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Hook rules to ensure our substitutes override the format's.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% <<<
%    \begin{macrocode}
\hook_gset_rule:nnnn {cmd/tikz@picture/before}{latex-lab-testphase-tikz}{>}{.}
\hook_gset_rule:nnnn {cmd/tikz@picture/before}{tagpdf}{>}{.}
\hook_gset_rule:nnnn {cmd/tikz@picture/before}{tikz}{>}{.}
\hook_gset_rule:nnnn {cmd/endpgfpicture/after}{latex-lab-testphase-tikz}{>}{.}
\hook_gset_rule:nnnn {cmd/endpgfpicture/after}{tikz}{>}{.}
\hook_gset_rule:nnnn {cmd/endpgfpicture/after}{tagpdf}{>}{.}
\hook_gset_rule:nnnn {package/tikz/after} {.} {>} {latex-lab-testphase-tikz}
\hook_gset_rule:nnnn {package/tikz/after} {.} {>} {tagpdf}
\hook_gset_rule:nnnn {package/tikz/after} {.} {>} {tikz}
%<debug>       \hook_log:n {package/tikz/after}
\hook_gput_code:nnn {begindocument/end} {.}
{
%<debug>       \hook_log:n {cmd/tikz@picture/before}
%<debug>       \hook_log:n {cmd/endpgfpicture/after}
%    \end{macrocode}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% >>>
% \begin{fn}{\mmzx_property_ref_orig:nn}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% <<<
%   Avoid dependency on \pkg{memoize-ext-properties}.
%    \begin{macrocode}
  \cs_if_free:NT \mmzx_property_ref_orig:nn
  {
    \cs_new_eq:NN \mmzx_property_ref_orig:nn \property_ref:nn
    \cs_generate_variant:Nn \mmzx_property_ref_orig:nn {ee}
  }
%    \end{macrocode}
% \end{fn}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% >>>
% \begin{fn}{\@@_property_record_orig:nn}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% <<<
%   Avoid dependency on \pkg{memoize-ext-properties}.
%    \begin{macrocode}
  \cs_if_free:NT \@@_property_record_orig:nn
  {
    \cs_new_eq:NN \@@_property_record_orig:nn \property_record:nn
    \cs_generate_variant:Nn \@@_property_record_orig:nn {ee}
  }
%    \end{macrocode}
% \end{fn}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% >>>
%    \begin{macrocode}
}
%    \end{macrocode}
%</sty>
% 
%\Finale
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
%^^A vim: et:tw=0:sw=2:ts=2:foldmethod=marker:fmr=<<<,>>>:
