4

The error is caused by the definition on line 436. Although this seems not to depend on memoize, all my attempts to eliminate memoize result in the code compiling.

The definition on line 436 is not really necessary - it is the memoized version which matters - but the non-memoized definition means the error can be replicated without in one run rather than two. Unfortunately, it does not avoid the dependency on a Perl or Python library, even though memoize only uses these for extraction.

Whether in the memo or main code, the error caused by the definition is

tagpdf: INFO TEX-MC-INTO-STRUCT: 1 inserted in struct 5
! Missing number, treated as zero.
<to be read again> 
                   \def 
l.571 \end{tikzpicture}

As far as I can tell, all the numbers required are available. Inserting \showthe lines prior to the definition shows the counts and dimensions are OK. Using the definition in a minimised example (without memoize) seems to work as I'd expect. The not-yet-recorded property values default to 0 etc.

Note that the aim of the mmzx/alt plug is to produce the same typeset result as the standard alt plug, even when the tikzpicture is externalised. For the other tikz plugs, this works, but alt needs a bounding box. So the idea is to use the properties xpos and ypos, together with the min/max picture dimensions to emulate the effect of remembering the position of the picture (which would be incompatible with memoization).

Recorded properties in memoized code are replicated when utilising externalised material (with the code below). xpos/ypos, together with the picture ID are not fixed, whereas the picture dimensions are. This allows the picture to be moved or pictures to be reordered without recompilation.

I am aware that this is horribly long for an MNWE. But even getting rid of memoize and assigning the same plug (less the memoize code) seemed to compile OK and the plug code depends on the replication set up for properties, expl3 functions and sockets.

Note that some definitions look rather odd due to minimisation. For example, there is not really any point in using \str_case:nn if I am only testing against a single case and doing nothing either way. But D is the only argument spec I actually need for this particular example.

\DocumentMetadata{lang=en-GB,tagging=on,pdfversion=2.0,pdfstandard=UA-2,}
\documentclass{article}
\tagpdfsetup{math/mathml/luamml/load=false,debug/log=all,debug/show=para,}
\title{Title}
\usepackage{memoize}
\ExplSyntaxOn
\makeatletter
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
\bool_new:N \l__mmzx_replicating_bool
\bool_set_false:N \l__mmzx_replicating_bool
\int_new:N \l__mmzx_tmpa_int
\str_new:N \l__mmzx_tmpa_str
\str_new:N \l__mmzx_tmpb_str
\tl_new:N \l__mmzx_tmpa_tl
\tl_new:N \l__mmzx_tmpb_tl
\tl_new:N \l__mmzx_tmpc_tl
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
% ltproperties
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
% copïo macros ltproperties, cctab
\cs_new_eq:NN  \__mmzx_cctab_end: \cctab_end:
\cs_new_eq:NN \__mmzx_property_ref_orig:nn \property_ref:nn
\cs_new_eq:NN \__mmzx_property_record_orig:nn \property_record:nn
\seq_new:N \g__mmzx_property_shipout_seq
\seq_new:N \g__mmzx_property_now_seq
\tl_new:N \g__mmzx_rec_tl
\cs_if_exist:NF \property_value:n
{ % sylwad ulrike fischer: https://chat.stackexchange.com/transcript/message/68081869#68081869
  \cs_new:Npn\property_value:n #1 { \use:c{__property_code_ #1 :} }
  \prg_new_conditional:Npnn \property_if_shipout:n #1 {T,F,TF,p}
  {
    \bool_if:cTF {g__property_shipout_ #1 _tl} 
    {\prg_return_true:}
    {\prg_return_false:}
  }
}
\cs_new:Npn \__mmzx__property_record_value:n #1 
{
  {#1}
  {
    \property_if_shipout:nT { #1 } { \exp_not:N } 
    \property_value:n { #1 }
  }
}
\cs_generate_variant:Nn \__mmzx_property_ref_orig:nn { ee }
\cs_generate_variant:Nn \__mmzx_property_record_orig:nn { ee }
% vars/consts
\cctab_const:Nn \c__mmzx_nexpl_at_cctab {
  \cctab_select:N \c_code_cctab 
  \makeatletter
  \int_set:Nn \tex_endlinechar:D { 13 }
  \char_set_catcode_space:n      { 9 }
  \char_set_catcode_space:n      { 32 }
  \char_set_catcode_active:n     { 126 } % tilde
}
% fns mewnol: refs
\cs_new_nopar:Npn \__mmzx_auto_property_ref_noopt:nn #1#2
{
  \property_if_recorded:nnTF { #1 } { #2 } 
  {
    \__mmzx_auto_property_ref:nn { #1 } { #2 }
  } {
    \mmzAbort
    \AdviceOriginal {#1}{#2}
  }
}
\cs_new_nopar:Npn \__mmzx_auto_property_ref_opt:w [#1]#2#3
{
  \property_if_recorded:nnTF { #2 } { #3 }
  {
    \__mmzx_auto_property_ref:nn { #2 } { #3 }
  } {
    \mmzAbort
    \AdviceOriginal [#1] {#2}{#3}
  }
}
\cs_new_nopar:Npn \__mmzx_auto_property_ref_too:nnn #1#2#3
{
  \property_if_recorded:nnTF { #2 } { #3 } 
  {
    \__mmzx_auto_property_ref:nn { #2 } { #3 }
  } {
    \mmzAbort
    \AdviceOriginal {#1}{#2}{#3}
  }
}
\cs_new_nopar:Npn \__mmzx_auto_property_ref:nn #1#2
{
  \gtoksapp\mmzContextExtra{
    \detokenize { \property_ref:nn } {#1}{#2} \c_space_tl -> \c_space_tl 
    \csname __mmzx_property_ref_orig:ee \endcsname {#1}{#2}, 
  }
  \__mmzx_property_ref_orig:ee {#1}{#2} 
}
% fns mewnol: rec
\cs_new_nopar:Npn \__mmzx_auto_property_record:nn #1#2
{
  \seq_gclear:N \g__mmzx_property_shipout_seq
  \seq_gclear:N \g__mmzx_property_now_seq
  \tl_gclear:N \g__mmzx_rec_tl
  \clist_map_inline:nn { #2 }
  {
    \exp_args:Ne \property_if_shipout:nTF {\tl_to_str:n {##1}}
    {
      \seq_gput_right:Ne \g__mmzx_property_shipout_seq {\tl_to_str:n {##1}}
    } {
      \seq_gput_right:Ne \g__mmzx_property_now_seq {\tl_to_str:n {##1}}
    }
  }
  \seq_if_empty:NF \g__mmzx_property_shipout_seq
  {
    \tl_gput_left:Ne \g__mmzx_rec_tl
    {
      \c_left_brace_str
      \seq_use:Nn \g__mmzx_property_shipout_seq { , }
      \c_right_brace_str
    }
  }
  \seq_if_empty:NTF \g__mmzx_property_now_seq
  {
    \tl_if_empty:NF \g__mmzx_rec_tl
    {
      \tl_gput_right:Nn \g__mmzx_rec_tl {{}}
    }
  } {
    \tl_if_empty:NT \g__mmzx_rec_tl
    {
      \tl_gset:Nn \g__mmzx_rec_tl {{}}
    }
    \tl_gput_right:Ne \g__mmzx_rec_tl
    {
      \c_left_brace_str
      \seq_map_function:NN \g__mmzx_property_now_seq \__mmzx__property_record_value:n
      \c_right_brace_str
    }
  }
  \tl_if_empty:NF \g__mmzx_rec_tl
  {
    \tl_gput_left:Ne\g__mmzx_rec_tl 
    { 
      \exp_not:N \mmzxRecProperty{#1}  
    } 
  }
  \exp_args:NNV \gtoksapp\mmzCCMemo \g__mmzx_rec_tl
}
\cs_new_protected_nopar:Npn \__mmzx_property_record:nnn #1#2#3
{ 
  \protected@write\@auxout {} 
  {
    \string \new@label@record {#1}
    {
      \clist_map_function:nN {#2} \__mmzx__property_record_value:n #3
    } 
  }
}
% fns 2e
\cs_new_eq:NN \mmzxRecProperty \__mmzx_property_record:nnn
\cs_new_eq:NN \mmzx@auto@ref@property@too \__mmzx_auto_property_ref_too:nnn
\def\mmzx@auto@ref@property
{
  \@ifnextchar[\__mmzx_auto_property_ref_opt:w \__mmzx_auto_property_ref_noopt:nn
}
\def\mmzx@auto@rec@property#1#2
{
  \bool_if:NF \l__mmzx_replicating_bool
  {
    \__mmzx_auto_property_record:nn {#1}{#2}
  }
  \__mmzx_property_record_orig:nn {#1}{#2}
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
% expl3
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
\cs_new_protected_nopar:Npn \__mmzx_nexpl_at_begin: 
{
  \cctab_begin:N \c__mmzx_nexpl_at_cctab
}
\cs_new_nopar:Npn \__mmzx_nexpl_at_start:
{
  \cs_set_nopar:Npn \mmzxExplAtBegin {__mmzx_nexpl_at_begin:}
  \cs_set_nopar:Npn \mmzxExplAtEnd {__mmzx_cctab_end:}
}
\cs_new_nopar:Npn \__mmzx_cctab_stop:
{
  \cs_set_nopar:Npn \mmzxExplAtBegin {relax}
  \cs_set_nopar:Npn \mmzxExplAtEnd {relax}
}
\appto\mmzAtBeginMemoization{
  \xtoksapp\mmzCCMemo
  {
    \exp_not:N \csname \mmzxExplAtBegin \exp_not:N \endcsname
  }
}
\preto\mmzAtEndMemoization{
  \xtoksapp\mmzCCMemo
  {
    \exp_not:N \csname \mmzxExplAtEnd \exp_not:N \endcsname
  }
}
\hook_gput_code:nnn { begindocument/end } {mmzx}
{
  \__mmzx_nexpl_at_start:
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
% expl3 replicators
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\cs_new:Npn \__mmzx_expl_replicate_fn_aux:nnN #1#2#3
{
  \cs_if_exist:cF { __mmzx_rep_#1:#2 } 
  { 
    \int_zero:N \l__mmzx_tmpa_int
    \tl_clear:N \l__mmzx_tmpa_tl
    \tl_clear:N \l__mmzx_tmpc_tl
    \tl_map_function:nN {#2} \__mmzx_expl_replicate__aux:n
    \cs_if_exist:cF { __mmzx_rep_#1:\l__mmzx_tmpc_tl }
    {
      \cs_gset_protected:ce {__mmzx_rep_#1:\l__mmzx_tmpc_tl} 
      {
        \xtoksapp\mmzCCMemo{ 
          \exp_after:wN \exp_not:N \cs:w #1:#2 \cs_end: \l__mmzx_tmpa_tl
        }
        \exp_not:N \AdviceOriginal \l__mmzx_tmpa_tl
        \exp_not:N \group_end:
      }
    }
    \str_if_eq:eeF {#2}{\l__mmzx_tmpc_tl}
    { % ych!
      \cs_new_eq:cc {__mmzx_rep_#1:#2} {__mmzx_rep_#1:\l__mmzx_tmpc_tl}
    }
  }
  \use:c { __mmzx_rep_#1:#2 }
}
\cs_new:Npn \__mmzx_expl_replicate__aux:n #1
{
  \int_incr:N \l__mmzx_tmpa_int
  \str_case:nn { #1 }
  {
    {D} { }  
  }
}
\cs_new_nopar:Npn \__mmzx_expl_replicate__e:
{
  \PackageError{mmzx}{No~do,~sorry.~Use~replicate~with~args~instead.}
}
\cs_new:Npn \__mmzx_expl_replicate_fn:
{
  \group_begin:
    \bool_set_true:N \l__mmzx_replicating_bool
    \exp_last_unbraced:Ne \__mmzx_expl_replicate_fn_aux:nnN { \exp_args:NV \cs_split_function:N \AdviceReplaced }  
}
\cs_new:Npn \AdviceRunIfNotReplicating 
{
  \bool_if:NF \l__mmzx_replicating_bool { \ifmemoizing \AdviceRuntrue \fi }
}
\cs_new_eq:NN \mmzx@expl@replicate@fn \__mmzx_expl_replicate_fn:
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
% ltsockets
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 
% addaswyd o latex-lab-testphase-tika.sty
\cs_new:Npn \__mmzx_socket_replicate:n #1
{
  \__mmzx_socket_to_ccmemo:n {#1}
  \str_set:Ne \l__mmzx_tmpb_str {\__mmzx_socket_assigned_plug:n {#1}}
  \str_set:Ne \l__mmzx_tmpa_str {\exp_after:wN \__mmzx_socket_plug_base:w \l__mmzx_tmpb_str \q_stop}
  \socket_assign_plug:nV {#1} \l__mmzx_tmpa_str
  \socket_use:n {#1}
  \socket_assign_plug:nV {#1} \l__mmzx_tmpb_str
}
\cs_new:Npn \__mmzx_socket_to_ccmemo:n #1
{
  \xtoksapp\mmzCCMemo{\exp_not:N \csname \cs_to_str:N \socket_use:n \exp_not:N \endcsname \c_left_brace_str #1 \c_right_brace_str}
}
\cs_generate_variant:Nn \socket_assign_plug:nn {nV}
\cs_new_nopar:Npn \__mmzx_socket_assigned_plug:n #1
{ % rhybudd: fn mewnol
  \str_use:c { l__socket_#1_plug_str }
}
\cs_new_nopar:Npn \__mmzx_socket_plug_base:w  #1/#2 \q_stop {#2}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% pgf/tikz
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\socket_new_plug:nnn {tagsupport/tikz/picture/init}{mmzx/default}
{
  \gtoksapp\mmzCCMemo{\csname socket_use:nn \endcsname {tagsupport/tikz/picture/init}{#1}}
  \keys_set_known:nn { mmzx / tikz / tagging } {#1}
  \cs_set_eq:NN \tikz@fig@main \__mmzx_tikz_fig_main_replicate:n
}
\hook_gput_code_with_args:nnn {cmd/tikz@picture/before}{.}
{
  \ifmemoizing
    \socket_assign_plug:nn {tagsupport/tikz/picture/init}{mmzx/default}
  \fi
}
\socket_new_plug:nnn {tagsupport/tikz/picture/begin}{mmzx/text}
{
  \__mmzx_socket_replicate:n {tagsupport/tikz/picture/begin}
  \cs_set_eq:NN \__mmzx_pgftikz_text_replicate:n \__mmzx_pgftikz_text_replicate_default:n
  \gtoksapp\mmzCCMemo{\csname tag_suspend:n\endcsname {\tikzpicture}}
}
\socket_new_plug:nnn {tagsupport/tikz/picture/end}{mmzx/text}
{
  \gtoksapp\mmzCCMemo{\csname tag_resume:n\endcsname {\tikzpicture}}
  \__mmzx_socket_replicate:n {tagsupport/tikz/picture/end}
}
\hook_gput_code:nnn {package/tikz/after}{.}
{
  \cs_new_eq:NN \__mmzx_tikz_fig_main_orig: \tikz@fig@main
  \cs_new:Npn \__mmzx_pgftikz_text_replicate_default:n #1
  {
    \tl_if_blank:nF {#1}
    {
      \gtoksapp\mmzCCMemo{\csname tag_resume:n\endcsname {\tikzpicture}\csname tag_socket_use:n\endcsname {tikz/picture/text/begin} #1\csname tag_socket_use:n\endcsname {tikz/picture/text/end}\csname tag_suspend:n\endcsname {\tikzpicture}}
    }
  }
  \cs_new:Npn \__mmzx_pgftikz_text_replicate_alt:n #1
  {
    \tl_if_blank:nF {#1}
    {
      \gtoksapp\mmzCCMemo{\csname tag_socket_use:n\endcsname {tikz/picture/text/begin} #1\csname tag_socket_use:n\endcsname {tikz/picture/text/end}}
    }
  }
  \cs_new_eq:NN \__mmzx_pgftikz_text_replicate:n \__mmzx_pgftikz_text_replicate_default:n
  %% addaswyd o ateb Henri Menke: https://tex.stackexchange.com/a/371192/
  \cs_new_protected_nopar:Npn \__mmzx_tikz_fig_main_replicate:n #1
  {
      \__mmzx_pgftikz_text_replicate:n {#1}
      \iftikz@node@is@pic
        \tikz@node@is@picfalse
        \tikz@subpicture@handle{#1}
      \else
        \tikz@@fig@main#1\egroup
    \fi
  }
}
\socket_new_plug:nnn {tagsupport/tikz/picture/begin}{mmzx/alt}
{
  \gtoksapp\mmzCCMemo{
    \ifvmode
      {
        \if@inlabel \leavevmode \else \tag_socket_use:n{para/begin}\fi
      }
    \fi
    \tag_mc_end_push:
    \tag_struct_begin:n
    {
      tag=Figure,
      alt=\l__tikz_tagging_alt_tl
    }
    \tag_mc_begin:n{tag=Figure}
  }
  \ifvmode
    {
      \if@inlabel \leavevmode \else \tag_socket_use:n{para/begin}\fi
    }
  \fi
  \tag_mc_end_push:
  \tag_struct_begin:n
  {
    tag=Figure,
    alt=\l__tikz_tagging_alt_tl
  }
  \tag_mc_begin:n{tag=Figure}
  \cs_set_eq:NN \__mmzx_pgftikz_text_replicate:n \__mmzx_pgftikz_text_replicate_alt:n 
  % memoize increments the count only at the end of the memo, whereas pgf 
  % increments at the start
  % so increment here & then reverse at the end
  \gtoksapp\mmzCCMemo{\mmzStepPgfPictureId{1}}
}
\cs_new_nopar:Npn \__mmzx_pgftikz_tag_bbox:nnnnn #1#2#3#4#5
{
  \__mmzx_pgftikz_tag_bbox_aux:eennnn
  {
    \property_ref:nn {#1}{xpos}
  }
  {
    \property_ref:nn {#1}{ypos}
  }
  {#2}{#3}{#4}{#5}
}
\cs_generate_variant:Nn \__mmzx_pgftikz_tag_bbox:nnnnn {eeeee}
\cs_new_nopar:Npn \__mmzx_pgftikz_tag_bbox_aux:nnnnnn #1#2#3#4#5#6
{
  \dim_to_decimal_in_bp:n {#1sp+#3}
  \c_space_tl
  \dim_to_decimal_in_bp:n {#2sp-#4}
  \c_space_tl
  \dim_to_decimal_in_bp:n {#1sp+#3+#5}
  \c_space_tl
  \dim_to_decimal_in_bp:n {#2sp-#4+#6}
}
\cs_generate_variant:Nn \__mmzx_pgftikz_tag_bbox_aux:nnnnnn {ee}
\socket_new_plug:nnn {tagsupport/tikz/picture/end}{mmzx/alt}
{
  \gtoksapp\mmzCCMemo{
    \tag_mc_end:
  }
  \tag_mc_end:
  \tex_savepos:D
  % avoid recording with fixed id when utilising
  \__mmzx_property_record_orig:ee {mmzx@pgf@sys@pdf@mark@pos@pgfid\the\pgf@picture@serial@count}{xpos,ypos,}
  % record with correct id when utilising
  \gtoksapp\mmzCCMemo{
    \property_record:ee {mmzx@pgf@sys@pdf@mark@pos@pgfid\the\pgf@picture@serial@count}{xpos,ypos,}
  }
  \tex_savepos:D
  % fix picture dims but not pos or id during memoization
  \xtoksapp\mmzCCMemo{
    \exp_not:N \cs_new:cpe 
    \c_left_brace_str
       pgf@sys@pdf@mark@pos@pgfid\exp_not:N\the\exp_not:N\pgf@picture@serial@count 
    \c_right_brace_str
    \c_left_brace_str
      \exp_not:N \__mmzx_pgftikz_tag_bbox:eeeee 
      \c_left_brace_str
        mmzx@pgf@sys@pdf@mark@pos@pgfid\exp_not:N\the\exp_not:N\pgf@picture@serial@count
      \c_right_brace_str
      \c_left_brace_str
        \the\pgf@picminx
      \c_right_brace_str
      \c_left_brace_str
        \the\pgf@picminy
      \c_right_brace_str
      \c_left_brace_str
        \the\pgf@picmaxx
      \c_right_brace_str
      \c_left_brace_str
        \the\pgf@picmaxy
      \c_right_brace_str
    \c_right_brace_str
    \exp_not:N \cs_show:c 
    \c_left_brace_str
       pgf@sys@pdf@mark@pos@pgfid\exp_not:N\the\exp_not:N\pgf@picture@serial@count 
    \c_right_brace_str
  }
  % the following errors
  \cs_new:cpe { pgf@sys@pdf@mark@pos@pgfid\the\pgf@picture@serial@count }
  {
    \__mmzx_pgftikz_tag_bbox:eeeee 
    { mmzx@pgf@sys@pdf@mark@pos@pgfid\the\pgf@picture@serial@count }
    {\the\pgf@picminx}
    {\the\pgf@picminy}
    {\the\pgf@picmaxx}
    {\the\pgf@picmaxy}
  }
  \gtoksapp\mmzCCMemo{
    \tag_struct_gput:ene
    {\tag_get:n {struct_num}}
    {attribute}
  }
  \xtoksapp\mmzCCMemo{
    \c_left_brace_str
    /O /Layout /BBox \c_space_tl
    [
      \exp_not:N \use:c
      \c_left_brace_str 
      pgf@sys@pdf@mark@pos@pgfid\exp_not:N\the\exp_not:N\pgf@picture@serial@count 
      \c_right_brace_str
    ]
    \c_right_brace_str
  }
  \tag_struct_gput:ene
  {\tag_get:n {struct_num}}
  {attribute}
  {
    /O /Layout /BBox~
    [
      \use:c
      { pgf@sys@pdf@mark@pos@pgfid\the\pgf@picture@serial@count }
    ]
  }
  \gtoksapp\mmzCCMemo{
    \tag_struct_end:
    \tag_mc_begin_pop:n {}
    \mmzStepPgfPictureId{-1}
  }
  \tag_struct_end:
  \tag_mc_begin_pop:n{}
}
\socket_new_plug:nnn {tagsupport/tikz/picture/text/begin}{mmzx/default}
{
  \__mmzx_socket_replicate:n {tagsupport/tikz/picture/text/begin}
  \__mmzx_pgfsys_text_replicate:
}
\socket_new_plug:nnn {tagsupport/tikz/picture/text/end}{mmzx/default}
{
  \__mmzx_pgfsys_end_text_replicate:
  \__mmzx_socket_replicate:n {tagsupport/tikz/picture/text/end}
}
\cs_new:Npn \__mmzx_purify_tag:nn #1#2
{
  \tl_if_empty:nF {#2}
  {
    \xtoksapp\mmzCCMemo
    {
      \exp_not:N \csname tl_set:ce \exp_not:N \endcsname \c_left_brace_str  l__tikz_tagging_#1_tl \c_right_brace_str \c_left_brace_str \exp_not:N \csname text_purify:n \exp_not:N \endcsname \c_left_brace_str #2 \c_right_brace_str \c_right_brace_str
    }
    \tl_set:ce {l__tikz_tagging_#1_tl} {\text_purify:n{#2}}
  }
}
\keys_define:nn { mmzx / tikz / tagging }
{
  alt        .code:n =
  {
    \__mmzx_purify_tag:nn {alt}{#1}
    \socket_assign_plug:nn {tagsupport/tikz/picture/begin}{mmzx/alt}
    \socket_assign_plug:nn {tagsupport/tikz/picture/end}{mmzx/alt}
    \def\pgfsys@begin@text{}
    \def\pgfsys@end@text{}
  },
  tagging-setup .multichoice:,
  tagging-setup / alt .code:n =
  {
    \keys_set:nn {mmzx/tikz/tagging} {alt={#1}}
  },
  tagging-setup / unknown .code:n=
  {
    \keys_set:nn { tag/graphic }{#1}
  },
}
\hook_gput_code:nnn {package/tikz/after}{.}
{
  \pgfqkeys{/tikz}
  {
    tagging-setup/.is~choice,
    tagging-setup/.cd,
    alt/.code=
    {
      \ifmemoizing
        \keys_set:nn {mmzx/tikz/tagging}{tagging-setup=alt}
      \else
        \keys_set:nn {tikz/tagging}{tagging-setup=alt}
      \fi
    },
    /tikz/.cd,
    alt/.forward~to=/tikz/tagging-setup/alt,
  }
  \appto\mmzAtBeginMemoization{
    \exp_args:Nne \socket_if_plug_exist:nnT {tagsupport/tikz/picture/init} { mmzx/\__mmzx_socket_assigned_plug:n {tagsupport/tikz/picture/init} }
    {
      \exp_args:Nne \socket_assign_plug:nn {tagsupport/tikz/picture/init}{ mmzx/\__mmzx_socket_assigned_plug:n {tagsupport/tikz/picture/init} }
    }
  }
}
\hook_gset_rule:nnnn {package/tikz/after}{tagpdf}{<}{.}
\hook_gset_rule:nnnn {cmd/tikz@picture/before}{tagpdf}{>}{.}
\hook_gset_rule:nnnn {cmd/endpgfpicture/after}{tagpdf}{>}{.}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\mmzset{
  direct~ccmemo~input,
  trace,
  include ~ context ~ in ~ ccmemo,
  auto/ref ~ property/.style={run ~ if ~ not~replicating,outer ~ handler=\mmzx@auto@ref@property,},
  auto/ref ~ property ~ too/.style={run ~ if ~ not~replicating,outer ~ handler=\mmzx@auto@ref@property@too,},
  auto/rec ~ property/.style={run ~ if ~ not~replicating,outer ~ handler=\mmzx@auto@rec@property,},
  auto ~ csname={property_record:nn}{rec ~ property,},
  auto ~ csname={property_ref:nn}{ref ~ property,},
  auto ~ csname={property_ref:nnn}{ref ~ property ~ too,},
  auto/run~if~not~replicating/.style = {run~conditions={\AdviceRunIfNotReplicating},},
  auto/expl~fn/.style={run~if~not~replicating,outer~handler=\mmzx@expl@replicate@fn,},
  auto~csname={tex_savepos:D}{expl~fn,},
}
\makeatother
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\ExplSyntaxOff
\usepackage{tikz}
\begin{document}
\parindent=0pt
\begin{tikzpicture}[alt=Alt Text]
  \node (d) {Node D};
\end{tikzpicture}
\end{document}

I'm pretty sure this is something stupid and I just can't see it ....

10
  • @user691586 huh. I thought it would not do that on initial compilation, but I guess it runs the extraction script to see if there is anything to extract. Commented Aug 13 at 15:56
  • @user691586 thanks. I corrected the question re. dependencies, so thanks for clarifying that. the dependencies are a pain. (unless you are on linux. for me it is easy.) Commented Aug 13 at 16:00
  • trying again with my insufficient install I observe in a trace \__pdf_backend_pageobject_ref:n #1->\int_value:w \tex_pdfpageref:D #1 0 R #1<-\property_ref:nnn {mcid-1}{tagabspage}{1} and then expansion of \property_ref:nnn inserts later a \def: it is not compatible with pure expansion. Commented Aug 13 at 16:13
  • @user691586 huh. thanks. \property_ref:nnn is marked as expandable and worked in the mwe I tried, so I thought that it should be ok ... Commented Aug 13 at 16:22
  • The trace reads (with EOLs disappearing here) \property_ref:nnn ->\advice@handle {/mmz}{\property_ref:nnn } \advice@handle #1#2->\advice@init@i {#1}{#2}\AdviceRunfalse \AdviceRunCondition s \advice@handle@rc {#1}{#2} #1<-/mmz #2<-\property_ref:nnn \advice@init@i #1#2->\csname advice@i#1//\string #2\endcsname #1<-/mmz #2<-\property_ref:nnn \advice@i/mmz//\property_ref:nnn ->\def \AdviceRunConditions {\AdviceRuntrue }\ def \AdviceBailoutHandler {\relax } ! Missing number, treated as zero. Commented Aug 13 at 16:23

1 Answer 1

5

Well a bit of tracing shows before the error this

\dim_to_decimal_in_bp:n #1->\exp_after:wN \__dim_to_decimal_aux:w \int_value:w 
\__dim_eval:w #1\__dim_eval_end: \__dim_sep: 400/803\__dim_sep: 

#1<-\property_ref:nn {mmzx@pgf@sys@pdf@mark@pos@pgfid1}{xpos}sp+{-20.20798pt}

At that time \property_ref:nn has a special definition (probably done by memoization):

\property_ref:nn ->\advice@handle {/mmz}{\property_ref:nn }

which resolves to this:

\def \AdviceRunConditions {\AdviceRuntrue }\def \AdviceBailoutHandler {\relax }

And that is clearly not expandable and so the \dim command doesn't like that at all. You are basically doing this:

\documentclass{article}
\begin{document}
\ExplSyntaxOn
\dim_to_decimal_in_bp:n{\def\blub{abc}+10sp}
\ExplSyntaxOff
\end{document}

which errors with

! Missing number, treated as zero.
<to be read again> 
                   \def 
l.40 \dim_to_decimal_in_bp:n{\def\blub{abc}+10sp}

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.