texlive[72568] Master/texmf-dist: postnotes (16oct24)

commits+karl at tug.org commits+karl at tug.org
Wed Oct 16 21:34:12 CEST 2024


Revision: 72568
          https://tug.org/svn/texlive?view=revision&revision=72568
Author:   karl
Date:     2024-10-16 21:34:12 +0200 (Wed, 16 Oct 2024)
Log Message:
-----------
postnotes (16oct24)

Modified Paths:
--------------
    trunk/Master/texmf-dist/doc/latex/postnotes/CHANGELOG.md
    trunk/Master/texmf-dist/doc/latex/postnotes/postnotes-code.pdf
    trunk/Master/texmf-dist/doc/latex/postnotes/postnotes-code.tex
    trunk/Master/texmf-dist/doc/latex/postnotes/postnotes-doc.pdf
    trunk/Master/texmf-dist/doc/latex/postnotes/postnotes-doc.tex
    trunk/Master/texmf-dist/source/latex/postnotes/postnotes.dtx
    trunk/Master/texmf-dist/source/latex/postnotes/postnotes.ins
    trunk/Master/texmf-dist/tex/latex/postnotes/postnotes.sty

Modified: trunk/Master/texmf-dist/doc/latex/postnotes/CHANGELOG.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/postnotes/CHANGELOG.md	2024-10-16 19:34:03 UTC (rev 72567)
+++ trunk/Master/texmf-dist/doc/latex/postnotes/CHANGELOG.md	2024-10-16 19:34:12 UTC (rev 72568)
@@ -1,7 +1,16 @@
 # Changelog
 
-## [Unreleased](https://github.com/gusbrs/postnotes/compare/v0.2.8...HEAD)
+## [Unreleased](https://github.com/gusbrs/postnotes/compare/v0.3.0...HEAD)
 
+## [v0.3.0](https://github.com/gusbrs/postnotes/compare/v0.2.8...v0.3.0) (2024-10-15)
+
+### Added
+- Provide `multiple` option, with functionality akin the the same named option
+  from `footmisc`.
+- Provide (experimental) support for PDF tagging. For this, the required LaTeX
+  kernel version was bumped to 2024-06-01. Tagging support requires
+  `testphase=phase-III` (`phase-II` with `listenv=none`).
+
 ## [v0.2.8](https://github.com/gusbrs/postnotes/compare/v0.2.7...v0.2.8) (2023-12-12)
 
 ## Fixed

Modified: trunk/Master/texmf-dist/doc/latex/postnotes/postnotes-code.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/postnotes/postnotes-code.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/postnotes/postnotes-code.tex	2024-10-16 19:34:03 UTC (rev 72567)
+++ trunk/Master/texmf-dist/doc/latex/postnotes/postnotes-code.tex	2024-10-16 19:34:12 UTC (rev 72568)
@@ -4,7 +4,7 @@
 %
 % This file is part of the LaTeX package "postnotes".
 %
-% Copyright (C) 2022-2023  gusbrs
+% Copyright (C) 2022-2024  gusbrs
 %
 % It may be distributed and/or modified under the conditions of the
 % LaTeX Project Public License (LPPL), either version 1.3c of this

Modified: trunk/Master/texmf-dist/doc/latex/postnotes/postnotes-doc.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/postnotes/postnotes-doc.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/postnotes/postnotes-doc.tex	2024-10-16 19:34:03 UTC (rev 72567)
+++ trunk/Master/texmf-dist/doc/latex/postnotes/postnotes-doc.tex	2024-10-16 19:34:12 UTC (rev 72568)
@@ -385,6 +385,16 @@
 At the point \opt{maketextmark} gets typeset, the \cs{pnthepage} variable
 contains the value of \cs{thepage} where its corresponding note was set.
 
+\DescribeMacro{multiple} %
+\DescribeMacro{multisep} %
+Just as for footnotes, when two or more \cs{postnote}s are called in imediate
+sequence, the marks typeset in superscript give impression of being one large
+number, instead of the sequence of smaller ones they were supposed to convey.
+Enabling the \opt{multiple} option makes \pkg{postnotes} typeset a separator
+between marks occurring in sequence.  The separator can be configured with the
+\opt{multisep} option, which has a comma as initial value.  \opt{multiple} is
+a boolean option, and has \texttt{false} as initial value.
+
 \DescribeOption{pretextmark} %
 \DescribeOption{posttextmark} %
 \DescribeOption{postprintnote} %
@@ -1079,6 +1089,10 @@
   % 2023-02-10: https://chat.stackexchange.com/transcript/message/62955941#62955941 (and discussion)
   % 2023-02-19: https://tex.stackexchange.com/q/675818#comment1678904_675818
   % 2023-12-12: https://chat.stackexchange.com/transcript/message/64848034#64848034 (and discussion)
+  % 2024-01-28: https://chat.stackexchange.com/transcript/message/65071091#65071091 (discussion)
+  % 2024-10-09: https://chat.stackexchange.com/transcript/message/66415504#66415504 (discussion)
+  % 2024-10-10: https://chat.stackexchange.com/transcript/message/66421777#66421777 (discussion)
+  % 2024-10-15: https://chat.stackexchange.com/transcript/message/66444011#66444011 (discussion)
   David Carlisle,
   % 2022-03-28: https://chat.stackexchange.com/transcript/message/60754383#60754383
   % 2022-04-08: https://tex.stackexchange.com/a/640035 (comments)
@@ -1085,11 +1099,14 @@
   % 2023-02-10: https://chat.stackexchange.com/transcript/message/62955941#62955941 (and discussion)
   % 2023-02-10: https://tex.stackexchange.com/a/674846
   % 2023-12-12: https://chat.stackexchange.com/transcript/message/64848034#64848034 (and discussion)
+  % 2024-01-28: https://chat.stackexchange.com/transcript/message/65071091#65071091 (discussion)
+  % 2024-10-15: https://chat.stackexchange.com/transcript/message/66444011#66444011 (discussion)
   Moritz Wemheuer,
   % 2022-04-05: https://tex.stackexchange.com/q/597359#comment1594585_597389
   Joseph Wright,
   % 2023-02-10: https://chat.stackexchange.com/transcript/message/62955941#62955941 (and discussion)
   % 2023-12-12: https://chat.stackexchange.com/transcript/message/64848034#64848034 (and discussion)
+  % 2024-10-15: https://chat.stackexchange.com/transcript/message/66444011#66444011 (discussion)
   \username{SwitWu},
   % 2023-11-29: https://github.com/gusbrs/postnotes/pull/4
   % 2023-11-30: https://github.com/gusbrs/postnotes/pull/5

Modified: trunk/Master/texmf-dist/source/latex/postnotes/postnotes.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/postnotes/postnotes.dtx	2024-10-16 19:34:03 UTC (rev 72567)
+++ trunk/Master/texmf-dist/source/latex/postnotes/postnotes.dtx	2024-10-16 19:34:12 UTC (rev 72568)
@@ -4,7 +4,7 @@
 %
 % This file is part of the LaTeX package "postnotes".
 %
-% Copyright (C) 2022-2023  gusbrs
+% Copyright (C) 2022-2024  gusbrs
 %
 % It may be distributed and/or modified under the conditions of the
 % LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -132,12 +132,13 @@
 % simplifies the relation with \pkg{hyperref} (\texttt{ltnews35},
 % \texttt{hyperref-linktarget}): the provision of \cs{MakeLinkTarget} and the
 % definition by the kernel of the starred version of \cs{ref}, which we can
-% use regardless of \pkg{hyperref} being loaded.  Finally, since we followed
-% the move to \texttt{e}-type expansion, to play safe we require the
-% 2023-11-01 kernel or newer.
+% use regardless of \pkg{hyperref} being loaded.  Also, since we followed the
+% move to \texttt{e}-type expansion, to play safe we require the 2023-11-01
+% kernel or newer.  Finally, the tagging sockets and block code required for
+% tagging support need the 2024-06-01 kernel.
 %
 %    \begin{macrocode}
-\def\postnotes at required@kernel{2023-11-01}
+\def\postnotes at required@kernel{2024-06-01}
 \NeedsTeXFormat{LaTeX2e}[\postnotes at required@kernel]
 \providecommand\IfFormatAtLeastTF{\@ifl at t@r\fmtversion}
 \IfFormatAtLeastTF{\postnotes at required@kernel}
@@ -152,7 +153,7 @@
 %
 %
 %    \begin{macrocode}
-\ProvidesExplPackage {postnotes} {2023-12-12} {0.2.8}
+\ProvidesExplPackage {postnotes} {2024-10-15} {0.3.0}
   {Endnotes for LaTeX}
 %    \end{macrocode}
 %
@@ -541,6 +542,7 @@
     maketextmark .value_required:n = true ,
     maketextmark .initial:n = { #2 #1 . #3 } ,
   }
+\cs_generate_variant:Nn \@@_make_mark:nnn { Vnn }
 %    \end{macrocode}
 %
 %
@@ -625,6 +627,159 @@
 %    \end{macrocode}
 %
 %
+% \subsection*{\opt{multiple}, \opt{multisep} options}
+%
+% As far as I can tell, the \opt{multiple} option has its origins in the
+% \pkg{footmisc} package, which offers this feature for footnotes.  About this
+% option, \file{footmisc.dtx} observes:
+%
+% \begin{quote}
+%   This (revised) code derives from a suggestion by Alexander Rozhenko (the
+%   author of the \pkg{manyfoot} package): the intention is that
+%   \pkg{footmisc} and \pkg{manyfoot} should be able to `interwork', in the
+%   sense that each would recognize the other's footnote marks and behave
+%   appropriately.  The trick is that both \cs{footnote} and \cs{footnotemark}
+%   insert a marker (a cancelling pair of kerns of \cs{multiplefootnotemarker}
+%   (of opposite signs), which is detected in following \cs{footnote} or
+%   \cs{footnotemark} commands.
+% \end{quote}
+%
+% About the same option, \file{manyfoot.dtx} notes:
+%
+% \begin{quote}
+%   To support \opt{multiple} option from \pkg{footmisc} we add the
+%   \cs{FN at mf@prepare} command from \pkg{footmisc} (suggested by Frank
+%   Mittelbach).
+% \end{quote}
+%
+% Whatever the exact origin of this feature, the fact is that it has spread
+% throughout the ecosystem, using not only the same basic mechanism but,
+% typically, using \emph{the same variables}: \cs{multiplefootnotemarker} and
+% \cs{multfootsep}.  With the intention, naturally, that different classes and
+% packages can ``interwork'' with regard to this feature.  And this became a
+% sort of ``shared feature'' in the ecosystem (the list includes
+% \pkg{footmisc}, \texttt{KOMA-Script}, \pkg{eledmac}, \pkg{reledmac},
+% \cls{tufte}, \cls{memoir}, \pkg{parnotes}, \pkg{sidenotes}, and now also
+% \pkg{postnotes}, see discussion at
+% \url{https://chat.stackexchange.com/transcript/message/66421777#66421777}).
+% What is crucial for this interplay, however, is not quite the variables
+% themselves, but \emph{the value of the canceling pair of kerns}, stored in
+% \cs{multiplefootnotemarker}.  The fact that the same variables are used by
+% most of the classes and packages which provide the feature speaks for
+% convenience, in that a change in one of them reflects in all participating
+% in the ``pool''.
+%
+% Convenient as it is, this shared use of the same variables can only work as
+% long as the community agrees in what these variables contain to some degree.
+% As far as \cs{multiplefootnotemarker} goes, I see no divergence, and
+% everybody uses the value of \texttt{3sp} for the canceling kerns from
+% \cs{FN at mf@prepare}.  \file{latex-lab-footnotes.dtx} even documents this
+% value for this purpose in its list of ``use of kerns to mark h-mode
+% positions'' (see
+% \url{https://chat.stackexchange.com/transcript/message/66421893#66421893}).
+% Things are not as smooth with regard to \cs{multfootsep} though.
+% \pkg{footmisc} stores a plain comma in \cs{multfootsep} and applies
+% formatting around it in \cs{FN at mf@check} (hard-coded as
+% \cs{textsuperscript}).  \texttt{KOMA-Script} also stores plain content in
+% \cs{multfootsep} and applies the formatting in the check function.
+% \cls{memoir}, however, stores the formatting directly \cs{multfootsep} and
+% applies no formatting later.  Also, \file{latex-lab-footmisc.ltx}, in adding
+% PDF tagging support for \pkg{footmisc} stores the tagging code directly in
+% \cs{multfootsep}.  I don't know if there are others, but these cases are
+% already relevant enough to spoil things.  The problem is not that they
+% disagree on the value of \cs{multfootsep}, but on the function(s) this macro
+% is supposed to perform.  That given, any other parties trying to partake in
+% this feature have to handle things differently depending on the value of
+% \cs{multfootsep}.  All in all, \pkg{postnotes} takes the cautious stance of
+% using internal variables, instead of the shared ones, to implement the
+% \opt{multiple} option.  The only thing that really needs to be common is the
+% value of the canceling kerns of \texttt{3sp} in \cs{@@_multiple_prepare:}.
+%
+%    \begin{macrocode}
+\cs_new_eq:NN \@@_multiple_prepare: \prg_do_nothing:
+\cs_new_eq:NN \@@_multiple_check: \prg_do_nothing:
+\cs_new_eq:NN \@@_multiple_store_lastkern: \prg_do_nothing:
+\tl_new:N \l_@@_multisep_tl
+\tl_const:Nn \c_postnotes_multi_notemarker_tl { 3sp }
+\dim_new:N \l_@@_multi_lastkern_dim
+\bool_new:N \l_@@_multi_stored_lastkern_bool
+\tl_new:N \l_@@_saved_spacefactor_multi_tl
+\keys_define:nn { postnotes/setup }
+  {
+    multiple .choice: ,
+    multiple / true .code:n =
+      {
+%    \end{macrocode}
+% I'm using the definitions in \pkg{latex-lab-footmisc.ltx} as base, see
+% \texttt{texdoc latex-lab-footnotes}.  For the formatting of the separator,
+% though, I take inspiration from \texttt{KOMA-Script} and use
+% \cs{@@_make_mark:nnn}, instead of hard-coding \cs{textsuperscript}.
+%    \begin{macrocode}
+        \cs_set_protected:Npn \@@_multiple_prepare:
+          {
+            \kern -\c_postnotes_multi_notemarker_tl
+            \kern  \c_postnotes_multi_notemarker_tl
+            \scan_stop:
+          }
+        \cs_set_protected:Npn \@@_multiple_check:
+          {
+            \dim_compare:nNnT
+              { \c_postnotes_multi_notemarker_tl } =
+              {
+                \bool_if:NTF \l_@@_multi_stored_lastkern_bool
+                  { \l_@@_multi_lastkern_dim }
+                  { \lastkern }
+              }
+              {
+                \tl_set:Ne \l_@@_saved_spacefactor_multi_tl
+                  { \int_use:N \spacefactor }
+%    \end{macrocode}
+% \pkg{latex-lab-footmisc.ltx} comments at this point ``shouldn't that be 2
+% unkerns?? (none would also be ok)'' and goes on to add a second \cs{unkern}.
+% If these calls are supposed to undo the \cs{kern}s in
+% \cs{@@_multiple_prepare:}, in our case we probably lost those at this point,
+% for the same reason we have to store \cs{lastkern} at the beginning of
+% \cs{posnote} (see below).  So, we might as well go with ``none'', since
+% otherwise we might be removing from the list a kern we didn't intend to.
+%    \begin{macrocode}
+                % \unkern
+                % \unkern
+                \tag_socket_use:n { postnotes/multsep/begin }
+                \@@_make_mark:Vnn \l_@@_multisep_tl { } { }
+                \tag_socket_use:n { postnotes/multsep/end }
+                \spacefactor \l_@@_saved_spacefactor_multi_tl
+                \scan_stop:
+              }
+          }
+%    \end{macrocode}
+% \cs{postnote} does quite a lot of stuff before actually calling
+% \cs{@@_typeset_mark:eV} which results in \cs{lastkern} set by the previous
+% \cs{@@_multiple_prepare:} being lost (why?), so we need to store it earlier.
+%    \begin{macrocode}
+        \cs_set_protected:Npn \@@_multiple_store_lastkern:
+          {
+            \dim_set_eq:NN \l_@@_multi_lastkern_dim \lastkern
+            \bool_set_true:N \l_@@_multi_stored_lastkern_bool
+          }
+      } ,
+    multiple / false .code:n =
+      {
+        \cs_set_eq:NN \@@_multiple_prepare: \prg_do_nothing:
+        \cs_set_eq:NN \@@_multiple_check: \prg_do_nothing:
+        \cs_set_eq:NN \@@_multiple_store_lastkern: \prg_do_nothing:
+      } ,
+    multiple / unknown .code:n =
+      { \msg_error:nnn { postnotes } { boolean-values-only } { multiple } } ,
+    multiple .default:n = true ,
+    multisep .tl_set:N = \l_@@_multisep_tl ,
+    multisep .initial:n = {,} ,
+  }
+\msg_new:nnnn { postnotes } { boolean-values-only }
+  { Key~'#1'~accepts~boolean~values~only. }
+  { The~key~'#1'~only~accepts~the~values~'true'~and~'false'. }
+%    \end{macrocode}
+%
+%
 % \subsection*{\opt{sort} option}
 %
 %    \begin{macrocode}
@@ -766,7 +921,7 @@
 % what is distinctive of the kernel's footnote apparatus, which allows it as
 % much flexibility as one would like, is receiving an arbitrary number as
 % argument and not stepping the counter.  And as far as \cs{footnotemark} and
-% \cs{footnotetext}) are concerned, the main point of the optional argument is
+% \cs{footnotetext} are concerned, the main point of the optional argument is
 % really to ``manually establish the relation'' between the two of them.  So,
 % if \emph{not stepping the counter} is what is needed to handle the general
 % case, is it viable to do so? What would we loose in so doing?
@@ -903,6 +1058,7 @@
 \cs_new_protected:Npn \@@_note:nn #1#2
   {
     \group_begin:
+    \@@_multiple_store_lastkern:
     \keys_set:nn { postnotes/note } {#1}
     \@@_inhibit_note:F
       {
@@ -920,12 +1076,13 @@
         \MakeLinkTarget* { postnote. \l_postnotes_note_id_tl .mark }
         \@@_set_mark_page_label:e { \l_postnotes_note_id_tl }
         \@@_set_user_labels:
-        \bool_if:NF \l_@@_nomark_bool
+        \@@_store:nn { \l_postnotes_note_id_tl } {#2}
+        \bool_if:NTF \l_@@_nomark_bool
+          { \tag_socket_use:n { postnotes/mark/nomark } }
           {
             \@@_typeset_mark:eV
               { \l_postnotes_note_id_tl } \l_@@_mark_tl
           }
-        \@@_store:nn { \l_postnotes_note_id_tl } {#2}
       }
     \group_end:
   }
@@ -1017,8 +1174,13 @@
                   \tl_set:Nn \l_@@_mark_tl { \thepostnote }
               }
           }
-        \@@_typeset_mark_wrapper:n
-          { \@@_make_mark:nnn { \l_@@_mark_tl } { } { } }
+        \group_begin:
+        \socket_assign_plug:nn { tagsupport/postnotes/multsep/begin } { noop }
+        \socket_assign_plug:nn { tagsupport/postnotes/multsep/end } { noop }
+        \@@_typeset_mark_wrapper:nnn
+          { \@@_make_mark:Vnn \l_@@_mark_tl { } { } }
+          { } { }
+        \group_end:
       }
     \bool_if:NTF \l_@@_inhibit_note_bool
       { \prg_return_true:  }
@@ -1031,19 +1193,20 @@
 % \begin{macro}
 %   {
 %     \@@_typeset_mark:nn ,
-%     \@@_typeset_mark_wrapper:n ,
+%     \@@_typeset_mark_wrapper:nnn ,
 %   }
 %   Auxiliary functions for mark typesetting in \cs{@@_note:nn}.
-%   \cs{@@_typeset_mark_wrapper:n} is based on the definition of
+%   \cs{@@_typeset_mark_wrapper:nnn} is based on the definition of
 %   \cs{@footnotemark} in the kernel.
 %   \begin{syntax}
 %     \cs{@@_typeset_mark:nn} \Arg{note id} \Arg{mark}
-%     \cs{@@_typeset_mark_wrapper:n} \Arg{mark}
+%     \cs{@@_typeset_mark_wrapper:nnn}
+%       \Arg{mark} \Arg{begin tagging} \Arg{end tagging}
 %   \end{syntax}
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_typeset_mark:nn #1#2
   {
-    \@@_typeset_mark_wrapper:n
+    \@@_typeset_mark_wrapper:nnn
       {
         \bool_if:NTF \l_@@_hyperlink_bool
           {
@@ -1053,18 +1216,25 @@
           }
           { \@@_make_mark:nnn {#2} { } { } }
       }
+      { \tag_socket_use:n { postnotes/mark/begin } }
+      { \tag_socket_use:n { postnotes/mark/end }   }
   }
 \cs_generate_variant:Nn \@@_typeset_mark:nn { eV }
 \tl_new:N \l_@@_saved_spacefactor_tl
-\cs_new_protected:Npn \@@_typeset_mark_wrapper:n #1
+\cs_new_protected:Npn \@@_typeset_mark_wrapper:nnn #1#2#3
   {
     \mode_leave_vertical:
     \mode_if_horizontal:T
       {
-        \tl_set:Ne \l_@@_saved_spacefactor_tl { \the\spacefactor }
+        \tl_set:Ne \l_@@_saved_spacefactor_tl
+          { \int_use:N \spacefactor }
+        \@@_multiple_check:
         \nobreak
       }
-    #1
+    #2 % begin tagging function
+    #1 % mark
+    #3 % end tagging function
+    \@@_multiple_prepare:
     \mode_if_horizontal:T
       { \spacefactor \l_@@_saved_spacefactor_tl }
     \scan_stop:
@@ -1081,7 +1251,7 @@
   {
     \tl_if_empty:NF \l_@@_note_label_tl
       { \exp_args:NV \label \l_@@_note_label_tl }
-   \tl_if_empty:NF \l_@@_note_zlabel_tl
+    \tl_if_empty:NF \l_@@_note_zlabel_tl
       { \exp_args:NV \zlabel \l_@@_note_zlabel_tl }
   }
 %    \end{macrocode}
@@ -1107,10 +1277,12 @@
 %     \cs{@@_note_ref:nn} \Arg{star bool} \Arg{label}
 %   \end{syntax}
 %    \begin{macrocode}
+\tl_new:N \l_@@_note_ref_label_tl
 \cs_new_protected:Npn \@@_note_ref:nn #1#2
   {
     \group_begin:
-    \@@_typeset_mark_wrapper:n
+    \tl_set:Nn \l_@@_note_ref_label_tl {#2}
+    \@@_typeset_mark_wrapper:nnn
       {
         \bool_lazy_and:nnTF
           { ! #1 }
@@ -1121,6 +1293,8 @@
           }
           { \@@_make_mark:nnn { \ref*{#2} } { } { } }
       }
+      { \tag_socket_use:n { postnotes/postnoteref/begin } }
+      { \tag_socket_use:n { postnotes/postnoteref/end }   }
     \group_end:
   }
 %    \end{macrocode}
@@ -1404,6 +1578,7 @@
                     \bool_if:NTF \l_@@_print_as_list_bool
                       { \exp_args:Ne \begin { \l_@@_print_env_tl } }
                       { \group_begin: }
+                    \tag_socket_use:n { postnotes/printlist/begin }
                     \l_@@_print_format_tl
                   }
                 \group_begin:
@@ -1424,6 +1599,7 @@
                   { \l_@@_print_counter_tl }
                 \cs_set:Npe \@currentlabel
                   { \p at postnote \l_@@_print_mark_tl }
+                \tag_socket_use:n { postnotes/printnote/begin }
                 \@@_text_mark_wrapper:n
                   {
                     \MakeLinkTarget*
@@ -1434,7 +1610,10 @@
                       { \l_postnotes_print_note_id_tl }
                       \l_@@_print_mark_tl
                   }
+                \tag_socket_use:n { postnotes/printtext/begin }
                 \l_@@_print_content_tl
+                \tag_socket_use:n { postnotes/printtext/end }
+                \tag_socket_use:n { postnotes/printnote/end }
                 \l_@@_post_printnote_tl
                 \group_end:
 %    \end{macrocode}
@@ -1457,6 +1636,7 @@
                   }
                 \tl_if_eq:NnF \l_@@_print_type_next_tl { note }
                   {
+                    \tag_socket_use:n { postnotes/printlist/end }
                     \bool_if:NTF \l_@@_print_as_list_bool
                       { \exp_args:Ne \end { \l_@@_print_env_tl } }
                       { \group_end: }
@@ -1524,7 +1704,12 @@
   {
     \bool_if:NTF \l_@@_print_as_list_bool
       {
-        \item [ \l_@@_pre_textmark_tl #1 \l_@@_post_textmark_tl ]
+        \item
+          [
+            \tag_socket_use:n { postnotes/printmark/begin }
+            \l_@@_pre_textmark_tl #1 \l_@@_post_textmark_tl
+            \tag_socket_use:n { postnotes/printmark/end }
+          ]
 %    \end{macrocode}
 % Leave vertical mode to avoid ``perhaps a missing \cs{item}'' error for empty
 % notes.
@@ -1531,7 +1716,11 @@
 %    \begin{macrocode}
         \mode_leave_vertical:
       }
-      { \l_@@_pre_textmark_tl #1 \l_@@_post_textmark_tl }
+      {
+        \tag_socket_use:n { postnotes/printmark/begin }
+        \l_@@_pre_textmark_tl #1 \l_@@_post_textmark_tl
+        \tag_socket_use:n { postnotes/printmark/end }
+      }
   }
 %    \end{macrocode}
 % \end{macro}
@@ -2345,10 +2534,12 @@
 %     \cs{@@_note_zref:nn} \Arg{star bool} \Arg{label}
 %   \end{syntax}
 %    \begin{macrocode}
+    \tl_new:N \l_@@_note_zref_zlabel_tl
     \cs_new_protected:Npn \@@_note_zref:nn #1#2
       {
         \group_begin:
-        \@@_typeset_mark_wrapper:n
+        \tl_set:Nn \l_@@_note_zref_zlabel_tl {#2}
+        \@@_typeset_mark_wrapper:nnn
           {
             \bool_lazy_all:nTF
               {
@@ -2363,6 +2554,8 @@
               }
               { \@@_make_mark:nnn { \zref{#2} } { } { } }
           }
+          { \tag_socket_use:n { postnotes/postnotezref/begin } }
+          { \tag_socket_use:n { postnotes/postnotezref/end }   }
         \group_end:
       }
 %    \end{macrocode}
@@ -2578,6 +2771,663 @@
 %    \end{macrocode}
 %
 %
+% \subsection*{PDF Tagging (experimental)}
+%
+% Note: All of this mostly presumes
+% \texttt{\cs{DocumentMetadata}\{testphase=phase-III\}} and was tested with
+% it.  For \opt{listenv=none}, I'd expect things to work with
+% \texttt{phase-II}, but this is only lightly tested.
+%
+% A first thing to consider in tagging endnotes is how we want to represent
+% them in the PDF structure.  My first thought, for lack of another, was:
+% emulate footnotes.  There's no relevant semantic difference at the structure
+% level between the two, and the tagging support for footnotes was done by the
+% pros.  And one distinctive characteristic the the footnotes tagging is that
+% the footnote itself is placed in the structure as a child to the (parent)
+% \texttt{text} element which surrounds the footnote mark.  However, for
+% endnotes this introduces a number of problems and complicates things.  While
+% footnotes ``float around'' and have no real structure of their own, that is
+% not true for endnotes.  Endnotes comprise a proper document section, and may
+% be printed in a list environment, etc.  So when the tagging of footnotes
+% places the footnote structure element as a child element of the mark's
+% surrounding text, this is arguably for a lack of other options.  Where else,
+% after all?  Indeed, a typical \texttt{html} would render footnotes at the
+% end of the page, and not inline.  True the normal \texttt{html} page is much
+% smaller than our typical PDF, but the point stands.  We can have a hover
+% over call out for footnotes, but the same could be done for end notes,
+% regardless of the parent-child relation (as long as the required
+% cross-references are in place).  On the other hand, for endnotes this is not
+% an issue: they have a natural place to be plugged into.  Furthermore, making
+% an endnote a child of the text surrounding its mark leaves an empty
+% ``skeleton'' of the endnotes section: the heading, the list structure, etc.
+% Technically, we could clean that too, but clearly that's not the way to
+% go\dots{}.
+%
+% Finally, the parent-child relation is not required by \texttt{PDF} standards
+% for the relevant structure types.  The \texttt{PDF} 2.0 standard
+% (ISO~32000-2:2020), says the following about \texttt{FENote}:
+%
+% \begin{quote}
+%   Used to markup footnotes and endnotes.  Footnotes and endnotes are content
+%   that is not normally read as part of the enclosing content from which it
+%   is referenced, but rather consulted at the reading person's discretion.
+%   In order for text to be considered a footnote or endnote, there should be
+%   a reference from the enclosing content to the footnote or endnote.  Such
+%   reference may be achieved by means of a Link structure element through a
+%   structure destination in its link annotation (see ``Table 368 — General
+%   inline level structure types''), or use of Ref in structure elements (see
+%   ``Table 355 — Entries in a structure element dictionary'').
+% \end{quote}
+%
+% The \texttt{PDF} 1.7 standard (PDF~32000-1:2008), says the following about
+% \texttt{Note}:
+%
+% \begin{quote}
+%   An item of explanatory text, such as a footnote or an endnote, that is
+%   referred to from within the body of the document.  It may have a label
+%   (structure type Lbl; see ``List Elements'' in 14.8.4.3, ``Block-Level
+%   Structure Elements'') as a child.  The note may be included as a child of
+%   the structure element in the body text that refers to it, or it may be
+%   included elsewhere (such as in an endnotes section) and accessed by means
+%   of a reference (structure type Reference).
+%
+%   Tagged PDF does not prescribe the placement of footnotes in the page
+%   content order.  They may be either inline or at the end of the page, at
+%   the discretion of the conforming writer.
+% \end{quote}
+%
+% So, the note \emph{may} be included as a child of the surrounding text, but
+% that's not required (PDF 2.0 does not even mention that).  What is required
+% is the reference between the elements.  All in all, let's not follow
+% footnotes in establishing the parent-child relation.
+%
+%
+% Another smaller but related issue is how to treat the list structure in
+% \cs{printpostnotes} when \opt{listenv} is used.  The natural thing here
+% would be to use an \env{enumerate} type list (or, in PDF lingo, for the
+% \texttt{ListNumbering} attribute to be \texttt{Ordered}), where the mark is
+% used as the item's label (even if, technically, we use the list like a
+% \env{description} in that we feed the label of every \cs{item} and though
+% there is an implicit underlying counter, the list itself has no bearing upon
+% it).  The problem here is that the PDF 2.0 standards determine that the
+% \texttt{FENote} structure element cannot be a child of a \texttt{LI} (list
+% item).  However, at least in principle, we also would like to have the
+% \texttt{endnotelabel} element to be a child of the \texttt{endnote} element.
+% Thus, we have a conflict, the mc-chunk can only be used once, and can be
+% either the \texttt{Lbl} of the \texttt{LI}, or the \texttt{endnotelabel} for
+% the \texttt{endnote}.  Currently, for the list case, I'm using an
+% \texttt{EndnotesList} class, which we define to have \texttt{ListNumbering}
+% as \texttt{Ordered}, with the mark as \texttt{Lbl} for \texttt{LI}, and
+% letting \texttt{endnote} be a child of \texttt{LBody}.  In a way, the
+% possibility of exporting the tagged content to different formats makes me
+% think that this is the most appropriate for the this case.  For the case of
+% \texttt{listenv=none}, the \texttt{endnote}s were made child of the
+% \texttt{Sect} in which they occur.  The \texttt{endnotelabel} was then
+% included as part (child) of the \texttt{endnote}.  In this, this treatment
+% emulates the one given for footnotes in the kernel.  But, at the same time,
+% it is less than ideal for machine readability purposes, since whether the
+% \texttt{endnotelabel} is part of \texttt{endnote} or not depends on if there
+% is a list environment involved.  Alas, I see no easy way around the PDF
+% standard restriction for the list case.
+%
+%
+% On the \LaTeX{} side of things, adding support for tagging entails two basic
+% tasks: i) applying the tagging markup at the appropriate places; ii)
+% generating references between the ``mark(s)'' and the ``text'' (plus
+% cross-reference commands to their respective targets).
+%
+% Regarding tagging references, we have three different cases: i) a regular
+% \cs{postnote}; ii) a \cs{postnoteref} to a note labeled from inside the
+% note; and iii) a \cs{postnoteref} to a note labeled with the \opt{label}
+% option.
+%
+% For regular \cs{postnote}s it is trivial to establish the reference using
+% the \texttt{label} / \texttt{ref} options of \pkg{tagpdf}.
+%
+% For \cs{postnoteref}s, however labeled, the connection \emph{must} be
+% established at \cs{postnoteref}, for the simple fact that any \cs{postnote}
+% can be referenced by arbitrarily many \cs{postnotref}s.  So we need to be
+% able to retrieve the note ID from the ``text'' to which the reference refers
+% to at \cs{postnoteref}.  However, at \cs{postnotref} the only information we
+% have is the \meta{label} but, since it is unique, we can establish a
+% connection through it.
+%
+% When the label is set from inside the note, it is actually set at
+% \cs{printposntones}, at which place we have access to
+% \cs{l_postnotes_print_note_id_tl} so we can use the \meta{label} to pass
+% that information around to \cs{postnoteref}.  With a standard \cs{label} we
+% must set an additional \pkg{ltproperties} label, using the new
+% \texttt{label} hook, which \cs{postnoteref} can retrieve from its own
+% \meta{label} argument.  For \cs{zlabel} this particular task is trivial,
+% since we can simply add a property to store the note ID with the label,
+% which \cs{postnotezref} can extract.
+%
+% When the label is set from the option, things are slightly more complicated,
+% because the label is set at \cs{postnote}, at which place we do not have
+% access to the note ID of the ``text''.  What we do here is then store the
+% label with the note and restore it later at \cs{printpostnotes} as usual.
+% Then, at that point, we can set an auxiliary label which can be retrieved
+% from \cs{postnoteref} from its own \meta{label} argument, as we did for the
+% case of labels inside the note.  Auxiliary labels are handled with
+% \pkg{ltproperties} labels.
+%
+%
+% Unconditionally define tagging support sockets.
+%    \begin{macrocode}
+\socket_new:nn { tagsupport/postnotes/mark/begin }{ 0 }
+\socket_new:nn { tagsupport/postnotes/mark/end }{ 0 }
+\socket_new:nn { tagsupport/postnotes/mark/nomark }{ 0 }
+\socket_new:nn { tagsupport/postnotes/multsep/begin }{ 0 }
+\socket_new:nn { tagsupport/postnotes/multsep/end }{ 0 }
+\socket_new:nn { tagsupport/postnotes/printlist/begin }{ 0 }
+\socket_new:nn { tagsupport/postnotes/printlist/end }{ 0 }
+\socket_new:nn { tagsupport/postnotes/printnote/begin }{ 0 }
+\socket_new:nn { tagsupport/postnotes/printnote/end }{ 0 }
+\socket_new:nn { tagsupport/postnotes/printmark/begin }{ 0 }
+\socket_new:nn { tagsupport/postnotes/printmark/end }{ 0 }
+\socket_new:nn { tagsupport/postnotes/printtext/begin }{ 0 }
+\socket_new:nn { tagsupport/postnotes/printtext/end }{ 0 }
+\socket_new:nn { tagsupport/postnotes/postnoteref/begin }{ 0 }
+\socket_new:nn { tagsupport/postnotes/postnoteref/end }{ 0 }
+\socket_new:nn { tagsupport/postnotes/postnotezref/begin }{ 0 }
+\socket_new:nn { tagsupport/postnotes/postnotezref/end }{ 0 }
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+\bool_lazy_and:nnT
+  { \cs_if_exist_p:N \tag_if_active_p: }
+  { \tag_if_active_p: }
+  {
+%    \end{macrocode}
+% FIXME Review or remove these settings if/when they are included upstream
+% (see \url{https://github.com/latex3/tagging-project/issues/728}).
+%    \begin{macrocode}
+    \tagpdfsetup
+      {
+        role/new-tag = { tag=endnote, role=FENote } ,
+        role/new-tag = { tag=endnotemark, role=Lbl } ,
+        role/new-tag = { tag=endnotelabel, role=Lbl } ,
+        role/new-attribute =
+          { EndnoteType } { /O /FENote /NoteType /Endnote } ,
+        role/new-attribute =
+          { EndnotesList } { /O /List /ListNumbering /Ordered } ,
+      }
+%    \end{macrocode}
+% \cs{postnote}
+%    \begin{macrocode}
+    \socket_new_plug:nnn { tagsupport/postnotes/mark/begin } { default }
+      {
+        \tag_mc_end_push:
+        \tag_struct_begin:n
+          {
+            tag = endnotemark ,
+            label = { postnotemark. \l_postnotes_note_id_tl } ,
+            ref = { postnote. \l_postnotes_note_id_tl } ,
+          }
+        \@@_tagsup_store_sctructnum:nN
+          { postnotemark } \l_postnotes_note_id_tl
+        \tag_mc_begin:n{}
+      }
+    \socket_new_plug:nnn { tagsupport/postnotes/mark/end } { default }
+      {
+        \tag_mc_end:
+        \tag_struct_end: % endnotemark
+        \tag_mc_begin_pop:n{}
+      }
+    \socket_new_plug:nnn { tagsupport/postnotes/mark/nomark } { default }
+      {
+        \tag_struct_begin:n
+          {
+            tag = NonStruct ,
+            label = { postnotemark. \l_postnotes_note_id_tl } ,
+            ref = { postnote. \l_postnotes_note_id_tl } ,
+          }
+        \@@_tagsup_store_sctructnum:nN
+          { postnotemark } \l_postnotes_note_id_tl
+        \tag_struct_end: % NonStruct
+      }
+    \socket_assign_plug:nn { tagsupport/postnotes/mark/begin } { default }
+    \socket_assign_plug:nn { tagsupport/postnotes/mark/end } { default }
+    \socket_assign_plug:nn { tagsupport/postnotes/mark/nomark } { default }
+%    \end{macrocode}
+% \opt{multiple}
+%    \begin{macrocode}
+    \socket_new_plug:nnn { tagsupport/postnotes/multsep/begin } { default }
+      {
+        \tag_mc_end_push:
+        \tag_mc_begin:n { artifact }
+      }
+    \socket_new_plug:nnn { tagsupport/postnotes/multsep/end } { default }
+      {
+        \tag_mc_end:
+        \tag_mc_begin_pop:n{}
+      }
+    \socket_assign_plug:nn { tagsupport/postnotes/multsep/begin } { default }
+    \socket_assign_plug:nn { tagsupport/postnotes/multsep/end } { default }
+%    \end{macrocode}
+% \cs{printpostnotes}
+%    \begin{macrocode}
+    \socket_new_plug:nnn { tagsupport/postnotes/printlist/begin } { default }
+      { \tag_tool:n { para/tagging=false } }
+    \socket_new_plug:nnn { tagsupport/postnotes/printlist/end } { default }
+      { }
+    \socket_assign_plug:nn { tagsupport/postnotes/printlist/begin } { default }
+    \socket_assign_plug:nn { tagsupport/postnotes/printlist/end } { default }
+    \socket_new_plug:nnn { tagsupport/postnotes/printnote/begin } { default }
+      {
+        \bool_if:NF \l_@@_print_as_list_bool
+          {
+            \tag_struct_begin:n
+              {
+                tag = endnote ,
+                attribute-class = EndnoteType ,
+                label = { postnote. \l_postnotes_print_note_id_tl } ,
+%    \end{macrocode}
+% CHECK Should we really add a back reference here?  I couldn't find any hint
+% about this in the standards, but \pkg{latex-lab-footnotes} does it.  No
+% harm, I guess.
+%    \begin{macrocode}
+                ref = { postnotemark. \l_postnotes_print_note_id_tl } ,
+              }
+            \@@_tagsup_store_sctructnum:nN
+              { postnote } \l_postnotes_print_note_id_tl
+         }
+      }
+    \socket_new_plug:nnn { tagsupport/postnotes/printnote/end } { default }
+      {
+        \bool_if:NF \l_@@_print_as_list_bool
+          { \tag_struct_end: }  % endnote
+      }
+    \socket_assign_plug:nn { tagsupport/postnotes/printnote/begin } { default }
+    \socket_assign_plug:nn { tagsupport/postnotes/printnote/end } { default }
+    \socket_new_plug:nnn { tagsupport/postnotes/printmark/begin } { default }
+      {
+        \bool_if:NF \l_@@_print_as_list_bool
+         {
+           \tag_struct_begin:n { tag=endnotelabel }
+           \tag_mc_begin:n{ tag=Lbl }
+         }
+      }
+    \socket_new_plug:nnn { tagsupport/postnotes/printmark/end } { default }
+      {
+        \bool_if:NF \l_@@_print_as_list_bool
+         {
+           \tag_mc_end:
+           \tag_struct_end: % endnotelabel
+         }
+      }
+    \socket_assign_plug:nn { tagsupport/postnotes/printmark/begin } { default }
+    \socket_assign_plug:nn { tagsupport/postnotes/printmark/end } { default }
+    \socket_new_plug:nnn { tagsupport/postnotes/printtext/begin } { default }
+      {
+        \bool_if:NTF \l_@@_print_as_list_bool
+          {
+            \tag_struct_begin:n
+              {
+                tag = endnote ,
+                attribute-class = EndnoteType ,
+                label = { postnote. \l_postnotes_print_note_id_tl } ,
+%    \end{macrocode}
+% CHECK Ditto.
+%    \begin{macrocode}
+                ref = { postnotemark. \l_postnotes_print_note_id_tl } ,
+              }
+            \@@_tagsup_store_sctructnum:nN
+              { postnote } \l_postnotes_print_note_id_tl
+            \tag_struct_begin:n { tag=text-unit }
+            \tag_struct_begin:n { tag=text }
+            \tag_tool:n { para/tagging=true }
+            \tag_mc_begin:n{}
+          }
+          {
+            \tag_struct_begin:n { tag=text-unit }
+            \tag_struct_begin:n { tag=text }
+            \tag_tool:n { para/tagging=true }
+            \tag_mc_begin:n{}
+          }
+      }
+    \socket_new_plug:nnn { tagsupport/postnotes/printtext/end } { default }
+      {
+        \bool_if:NTF \l_@@_print_as_list_bool
+          {
+            \tag_mc_end:
+            \tag_tool:n { para/tagging=false }
+            \tag_struct_end: % text
+            \tag_struct_end: % text-unit
+            \tag_struct_end: % endnote
+          }
+          {
+            \tag_mc_end:
+            \tag_tool:n { para/tagging=false }
+            \tag_struct_end: % text
+            \tag_struct_end: % text-unit
+          }
+      }
+    \socket_assign_plug:nn { tagsupport/postnotes/printtext/begin } { default }
+    \socket_assign_plug:nn { tagsupport/postnotes/printtext/end } { default }
+%    \end{macrocode}
+% Provide \pkg{xtemplate} based redefinitions of \env{postnoteslist} and
+% \pkg{postnoteslisthang}.  This is needed because, as far as I can tell, it
+% is the only way to set \opt{tag} and \opt{attribute-class} for the list
+% struct without tampering with \pkg{latex-lab-testphase-block}'s internals.
+%    \begin{macrocode}
+    \IfInstanceExistsT { blockenv } { list }
+      {
+        \DeclareInstance { blockenv } { postnoteslist } { display }
+          {
+            env-name       = postnoteslist ,
+            tag-name       = L ,
+            tag-class      = EndnotesList ,
+            tagging-recipe = list ,
+            inner-level-counter = ,
+            level-increase = true ,
+            setup-code     = ,
+            block-instance = list ,
+            inner-instance = postnoteslist ,
+          }
+        \DeclareInstanceCopy { blockenv }
+          { postnoteslisthang } { postnoteslist }
+        \EditInstance { blockenv } { postnoteslisthang }
+          { env-name = postnoteslisthang }
+        \DeclareInstance { list } { postnoteslist } { std }
+          { item-instance = postnoteslist }
+        \DeclareInstance { item } { postnoteslist } { std }
+          {
+            label-format = { \hspace { \labelsep } \normalfont ~ #1 } ,
+            label-align = left ,
+          }
+        \RenewDocumentEnvironment { postnoteslist } { }
+          {
+            \UseInstance { blockenv } { postnoteslist }
+              {
+                leftmargin     = 0pt ,
+                label-width    = 0pt ,
+                item-indent    = .5\parindent ,
+                rightmargin    = 0pt ,
+                parindent      = \parindent ,
+                par-skip       = \parskip ,
+                item-skip      = 0pt ,
+                beginsep       = .5\topsep ,
+                begin-par-skip = .5\partopsep ,
+              }
+          }
+          { \endblockenv }
+        \RenewDocumentEnvironment { postnoteslisthang } { }
+          {
+            \UseInstance { blockenv } { postnoteslisthang }
+              {
+                leftmargin     = 1em ,
+                label-width    = -\leftmargin ,
+                item-indent    = -2\leftmargin ,
+                rightmargin    = 0pt ,
+                parindent      = \parindent ,
+                par-skip       = \parskip ,
+                item-skip      = 0pt ,
+                beginsep       = .5\topsep ,
+                begin-par-skip = .5\partopsep ,
+              }
+          }
+          { \endblockenv }
+      }
+%    \end{macrocode}
+% Setup for \cs{label} and \cs{zlabel} inside the note.
+%    \begin{macrocode}
+    \bool_new:N \l_@@_inside_note_bool
+    \AddToHookWithArguments { label } [ postnotes/tagsup ]
+      {
+        \bool_if:NT \l_@@_inside_note_bool
+          {
+            \property_record:nn { postnote at label@innote. #1 }
+              { postnotes/tagsup at noteid }
+          }
+      }
+    \AddToHook { postnotes/print/note/begin } [ postnotes/tagsup ]
+      { \bool_set_true:N \l_@@_inside_note_bool }
+    \property_new:nnnn { postnotes/tagsup at noteid } { now } { 0 }
+      { \l_postnotes_print_note_id_tl }
+    \AddToHook { package/zref-user/after } [ postnotes/tagsup ]
+      {
+        \zref at newprop { postnotes at tagsup@noteid } [ 0 ]
+          { \l_postnotes_print_note_id_tl }
+        \AddToHook { postnotes/print/note/begin } [ postnotes/tagsup ]
+          { \zref at localaddprop { main } { postnotes at tagsup@noteid } }
+      }
+%    \end{macrocode}
+% Setup for \opt{label} and \opt{zlabel} options.
+%    \begin{macrocode}
+    \AddToHook { postnotes/note/store } [ postnotes/tagsup ]
+      {
+        \tl_if_empty:NF \l_@@_note_label_tl
+          {
+            \prop_gput:cnV
+              { \@@_data_name:e { \l_postnotes_note_id_tl } }
+              { label } \l_@@_note_label_tl
+          }
+      }
+    \AddToHook { package/zref-user/after } [ postnotes/tagsup ]
+      {
+        \AddToHook { postnotes/note/store } [ postnotes/tagsup ]
+          {
+            \tl_if_empty:NF \l_@@_note_zlabel_tl
+              {
+                \prop_gput:cnV
+                  { \@@_data_name:e { \l_postnotes_note_id_tl } }
+                  { zlabel } \l_@@_note_zlabel_tl
+              }
+          }
+      }
+    \AddToHook { postnotes/print/note/begin } [ postnotes/tagsup ]
+      {
+        \@@_prop_get:nnN { \l_postnotes_print_note_id_tl }
+          { label } \l_@@_restore_tmp_tl
+        \tl_if_empty:NF \l_@@_restore_tmp_tl
+          {
+            \exp_args:Ne \property_record:nn
+              { postnote at label@option. \l_@@_restore_tmp_tl }
+              { postnotes/tagsup at noteid }
+          }
+        \@@_prop_get:nnN { \l_postnotes_print_note_id_tl }
+          { zlabel } \l_@@_restore_tmp_tl
+        \tl_if_empty:NF \l_@@_restore_tmp_tl
+          {
+            \exp_args:Ne \property_record:nn
+              { postnote at zlabel@option. \l_@@_restore_tmp_tl }
+              { postnotes/tagsup at noteid }
+          }
+      }
+%    \end{macrocode}
+% CHECK \pkg{latex-lab-footnotes} creates the footnote structure element
+% (\texttt{FENote} tag) and adds to it a \texttt{/Ref} entry pointing to the
+% structures of \emph{all} marks related to the note, and that includes
+% \cs{footref}s.  I don't see anything stating something of the sort in the
+% standards, the backref of the original mark is already a stretch.  I also
+% fail to see why this is needed, and how it could be used.  But\dots{} I
+% trust Ulrike knows better than me.
+% \begin{macro}
+%   {
+%     \@@_tagsup_store_sctructnum:nN
+%     \@@_tagsup_store_crossref:nN
+%   }
+%   \begin{syntax}
+%     \cs{@@_tagsup_store_sctructnum:nN} \Arg{ref type} \Arg{ID number of note}
+%     \cs{@@_tagsup_store_crossref:nN} \Arg{ref type} \Arg{ID number of note}
+%   \end{syntax}
+%   \meta{ref type} is either ``\texttt{postnote}'' or
+%   ``\texttt{postnotemark}''.
+%    \begin{macrocode}
+    \prop_new:N \g_@@_tagsup_structnums_prop
+    \cs_new_protected:Npn \@@_tagsup_store_sctructnum:nN #1#2
+      {
+        \prop_gput:Nee \g_@@_tagsup_structnums_prop
+          { #1 . #2 } { \tag_get:n { struct_num } }
+      }
+    \prop_new:N \g_@@_tagsup_crossrefs_prop
+    \cs_new_protected:Npn \@@_tagsup_store_crossref:nN #1#2
+      {
+        \prop_gput:Nee \g_@@_tagsup_crossrefs_prop
+          { \tag_get:n { struct_num } } { #1 . #2 }
+      }
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\@@_tagsup_gput_ref:nn}
+%   \begin{syntax}
+%     \cs{@@_tagsup_gput_ref:nn} \Arg{structnum refering from}
+%     ~~~~\Arg{structnum being referenced to}
+%   \end{syntax}
+%   See \cs{__fnote_gput_ref:nn}.
+%    \begin{macrocode}
+    \cs_new_protected:Npn \@@_tagsup_gput_ref:nn #1#2
+      {
+        \tag_if_active:T
+          { \tag_struct_gput:ene {#1} {ref} { \tag_struct_object_ref:e {#2} } }
+      }
+%    \end{macrocode}
+% \end{macro}
+% The actual inclusion of the reference has to be done at the end, since the
+% \opt{ref} option called by \cs{tag_struct_begin:n} does not check if the
+% variable to store the refs already exists, resulting in a clash if we add it
+% immediately and a \cs{posnoteref} is made before \cs{printposnotes}, and
+% also so that the ``main'' reference always comes first at the list.
+%    \begin{macrocode}
+    \AddToHook { tagpdf/finish/before } [ postnotes/tagsup ]
+      {
+        \prop_map_inline:Nn \g_@@_tagsup_crossrefs_prop
+          {
+            \@@_tagsup_gput_ref:nn
+              { \prop_item:Nn \g_@@_tagsup_structnums_prop {#2} }
+              {#1}
+          }
+      }
+%    \end{macrocode}
+% \cs{postnoteref}
+%    \begin{macrocode}
+    \socket_new_plug:nnn { tagsupport/postnotes/postnoteref/begin } { default }
+      {
+        \tag_mc_end_push:
+        \property_if_recorded:eeTF
+          { postnote at label@innote. \l_@@_note_ref_label_tl }
+          { postnotes/tagsup at noteid }
+          {
+%    \end{macrocode}
+% Label coming from a \cs{label} inside the note.
+%    \begin{macrocode}
+            \tl_set:Ne \l_@@_tmpa_tl
+              {
+                \property_ref:ee
+                  { postnote at label@innote. \l_@@_note_ref_label_tl }
+                  { postnotes/tagsup at noteid }
+              }
+            \tag_struct_begin:n
+              {
+                tag = endnotemark ,
+                ref = { postnote. \l_@@_tmpa_tl } ,
+              }
+            \@@_tagsup_store_crossref:nN
+              { postnote } \l_@@_tmpa_tl
+          }
+          {
+            \property_if_recorded:eeTF
+              { postnote at label@option. \l_@@_note_ref_label_tl }
+              { postnotes/tagsup at noteid }
+              {
+%    \end{macrocode}
+% Label coming from a \opt{label} option.
+%    \begin{macrocode}
+                \tl_set:Ne \l_@@_tmpa_tl
+                  {
+                    \property_ref:ee
+                      { postnote at label@option. \l_@@_note_ref_label_tl }
+                      { postnotes/tagsup at noteid }
+                  }
+                \tag_struct_begin:n
+                  {
+                    tag = endnotemark ,
+                    ref = { postnotemark. \l_@@_tmpa_tl } ,
+                  }
+                \@@_tagsup_store_crossref:nN
+                  { postnotemark } \l_@@_tmpa_tl
+              }
+              { \tag_struct_begin:n { tag = endnotemark } }
+          }
+        \tag_mc_begin:n{}
+      }
+    \socket_new_plug:nnn { tagsupport/postnotes/postnoteref/end } { default }
+      {
+        \tag_mc_end:
+        \tag_struct_end: % endnotemark
+        \tag_mc_begin_pop:n{}
+      }
+    \socket_assign_plug:nn { tagsupport/postnotes/postnoteref/begin } { default }
+    \socket_assign_plug:nn { tagsupport/postnotes/postnoteref/end } { default }
+%    \end{macrocode}
+% \cs{postnotezref}
+%    \begin{macrocode}
+    \AddToHook { package/zref-user/after } [ postnotes/tagsup ]
+      {
+        \socket_new_plug:nnn { tagsupport/postnotes/postnotezref/begin } { default }
+          {
+            \tag_mc_end_push:
+            \zref at ifrefcontainsprop { \l_@@_note_zref_zlabel_tl }
+              { postnotes at tagsup@noteid }
+              {
+%    \end{macrocode}
+% Label coming from a \cs{zlabel} inside the note.
+%    \begin{macrocode}
+                \tl_set:Ne \l_@@_tmpa_tl
+                  {
+                    \zref at extract { \l_@@_note_zref_zlabel_tl }
+                      { postnotes at tagsup@noteid }
+                  }
+                \tag_struct_begin:n
+                  {
+                    tag = endnotemark ,
+                    ref = { postnote. \l_@@_tmpa_tl } ,
+                  }
+                \@@_tagsup_store_crossref:nN
+                  { postnote } \l_@@_tmpa_tl
+              }
+              {
+                \property_if_recorded:eeTF
+                  { postnote at zlabel@option. \l_@@_note_zref_zlabel_tl }
+                  { postnotes/tagsup at noteid }
+                  {
+%    \end{macrocode}
+% Label coming from a \opt{zlabel} option.
+%    \begin{macrocode}
+                    \tl_set:Ne \l_@@_tmpa_tl
+                      {
+                        \property_ref:ee
+                          {
+                            postnote at zlabel@option.
+                            \l_@@_note_zref_zlabel_tl
+                          }
+                          { postnotes/tagsup at noteid }
+                      }
+                    \tag_struct_begin:n
+                      {
+                        tag = endnotemark ,
+                        ref = { postnotemark. \l_@@_tmpa_tl } ,
+                      }
+                    \@@_tagsup_store_crossref:nN
+                      { postnotemark } \l_@@_tmpa_tl
+                  }
+                  { \tag_struct_begin:n { tag = endnotemark } }
+              }
+            \tag_mc_begin:n{}
+          }
+        \socket_new_plug:nnn { tagsupport/postnotes/postnotezref/end } { default }
+          {
+            \tag_mc_end:
+            \tag_struct_end: % endnotemark
+            \tag_mc_begin_pop:n{}
+          }
+        \socket_assign_plug:nn { tagsupport/postnotes/postnotezref/begin } { default }
+        \socket_assign_plug:nn { tagsupport/postnotes/postnotezref/end } { default }
+      }
+  }
+%    \end{macrocode}
+%
+%
 % \section{Languages}
 % \label{sec:languages}
 %
@@ -2804,3 +3654,7 @@
 % \PrintIndex
 %
 %
+
+% Local Variables:
+% jinx-local-words: "endnote endnotes"
+% End:

Modified: trunk/Master/texmf-dist/source/latex/postnotes/postnotes.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/postnotes/postnotes.ins	2024-10-16 19:34:03 UTC (rev 72567)
+++ trunk/Master/texmf-dist/source/latex/postnotes/postnotes.ins	2024-10-16 19:34:12 UTC (rev 72568)
@@ -4,7 +4,7 @@
 %
 % This file is part of the LaTeX package "postnotes".
 %
-% Copyright (C) 2022-2023  gusbrs
+% Copyright (C) 2022-2024  gusbrs
 %
 % It may be distributed and/or modified under the conditions of the
 % LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -49,7 +49,7 @@
 
 This file was generated from file(s) of the LaTeX package "postnotes".
 
-Copyright (C) 2022-2023  gusbrs
+Copyright (C) 2022-2024  gusbrs
 
 It may be distributed and/or modified under the conditions of the
 LaTeX Project Public License (LPPL), either version 1.3c of this

Modified: trunk/Master/texmf-dist/tex/latex/postnotes/postnotes.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/postnotes/postnotes.sty	2024-10-16 19:34:03 UTC (rev 72567)
+++ trunk/Master/texmf-dist/tex/latex/postnotes/postnotes.sty	2024-10-16 19:34:12 UTC (rev 72568)
@@ -8,7 +8,7 @@
 %% 
 %% This file was generated from file(s) of the LaTeX package "postnotes".
 %% 
-%% Copyright (C) 2022-2023  gusbrs
+%% Copyright (C) 2022-2024  gusbrs
 %% 
 %% It may be distributed and/or modified under the conditions of the
 %% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -41,7 +41,7 @@
 %% 
 %% -----------------------------------------------------------------------
 %% 
-\def\postnotes at required@kernel{2023-11-01}
+\def\postnotes at required@kernel{2024-06-01}
 \NeedsTeXFormat{LaTeX2e}[\postnotes at required@kernel]
 \providecommand\IfFormatAtLeastTF{\@ifl at t@r\fmtversion}
 \IfFormatAtLeastTF{\postnotes at required@kernel}
@@ -52,7 +52,7 @@
         'postnotes' requires a LaTeX kernel \postnotes at required@kernel\space or newer.%
       }%
   }%
-\ProvidesExplPackage {postnotes} {2023-12-12} {0.2.8}
+\ProvidesExplPackage {postnotes} {2024-10-15} {0.3.0}
   {Endnotes for LaTeX}
 \tl_new:N \l__postnotes_tmpa_tl
 \tl_new:N \l__postnotes_tmpb_tl
@@ -258,6 +258,7 @@
     maketextmark .value_required:n = true ,
     maketextmark .initial:n = { #2 #1 . #3 } ,
   }
+\cs_generate_variant:Nn \__postnotes_make_mark:nnn { Vnn }
 \tl_new:N \l__postnotes_pre_textmark_tl
 \tl_new:N \l__postnotes_post_textmark_tl
 \tl_new:N \l__postnotes_post_printnote_tl
@@ -324,6 +325,67 @@
   { Option~'#1'~only~available~in~the~preamble~\msg_line_context:. }
 \msg_new:nnn { postnotes } { missing-hyperref }
   { Missing~'hyperref'~package.~Setting~'hyperref=false'. }
+\cs_new_eq:NN \__postnotes_multiple_prepare: \prg_do_nothing:
+\cs_new_eq:NN \__postnotes_multiple_check: \prg_do_nothing:
+\cs_new_eq:NN \__postnotes_multiple_store_lastkern: \prg_do_nothing:
+\tl_new:N \l__postnotes_multisep_tl
+\tl_const:Nn \c_postnotes_multi_notemarker_tl { 3sp }
+\dim_new:N \l__postnotes_multi_lastkern_dim
+\bool_new:N \l__postnotes_multi_stored_lastkern_bool
+\tl_new:N \l__postnotes_saved_spacefactor_multi_tl
+\keys_define:nn { postnotes/setup }
+  {
+    multiple .choice: ,
+    multiple / true .code:n =
+      {
+        \cs_set_protected:Npn \__postnotes_multiple_prepare:
+          {
+            \kern -\c_postnotes_multi_notemarker_tl
+            \kern  \c_postnotes_multi_notemarker_tl
+            \scan_stop:
+          }
+        \cs_set_protected:Npn \__postnotes_multiple_check:
+          {
+            \dim_compare:nNnT
+              { \c_postnotes_multi_notemarker_tl } =
+              {
+                \bool_if:NTF \l__postnotes_multi_stored_lastkern_bool
+                  { \l__postnotes_multi_lastkern_dim }
+                  { \lastkern }
+              }
+              {
+                \tl_set:Ne \l__postnotes_saved_spacefactor_multi_tl
+                  { \int_use:N \spacefactor }
+                % \unkern
+                % \unkern
+                \tag_socket_use:n { postnotes/multsep/begin }
+                \__postnotes_make_mark:Vnn \l__postnotes_multisep_tl { } { }
+                \tag_socket_use:n { postnotes/multsep/end }
+                \spacefactor \l__postnotes_saved_spacefactor_multi_tl
+                \scan_stop:
+              }
+          }
+        \cs_set_protected:Npn \__postnotes_multiple_store_lastkern:
+          {
+            \dim_set_eq:NN \l__postnotes_multi_lastkern_dim \lastkern
+            \bool_set_true:N \l__postnotes_multi_stored_lastkern_bool
+          }
+      } ,
+    multiple / false .code:n =
+      {
+        \cs_set_eq:NN \__postnotes_multiple_prepare: \prg_do_nothing:
+        \cs_set_eq:NN \__postnotes_multiple_check: \prg_do_nothing:
+        \cs_set_eq:NN \__postnotes_multiple_store_lastkern: \prg_do_nothing:
+      } ,
+    multiple / unknown .code:n =
+      { \msg_error:nnn { postnotes } { boolean-values-only } { multiple } } ,
+    multiple .default:n = true ,
+    multisep .tl_set:N = \l__postnotes_multisep_tl ,
+    multisep .initial:n = {,} ,
+  }
+\msg_new:nnnn { postnotes } { boolean-values-only }
+  { Key~'#1'~accepts~boolean~values~only. }
+  { The~key~'#1'~only~accepts~the~values~'true'~and~'false'. }
 \bool_new:N \l__postnotes_sort_bool
 \keys_define:nn { postnotes/setup }
   {
@@ -375,6 +437,7 @@
 \cs_new_protected:Npn \__postnotes_note:nn #1#2
   {
     \group_begin:
+    \__postnotes_multiple_store_lastkern:
     \keys_set:nn { postnotes/note } {#1}
     \__postnotes_inhibit_note:F
       {
@@ -392,12 +455,13 @@
         \MakeLinkTarget* { postnote. \l_postnotes_note_id_tl .mark }
         \__postnotes_set_mark_page_label:e { \l_postnotes_note_id_tl }
         \__postnotes_set_user_labels:
-        \bool_if:NF \l__postnotes_nomark_bool
+        \__postnotes_store:nn { \l_postnotes_note_id_tl } {#2}
+        \bool_if:NTF \l__postnotes_nomark_bool
+          { \tag_socket_use:n { postnotes/mark/nomark } }
           {
             \__postnotes_typeset_mark:eV
               { \l_postnotes_note_id_tl } \l__postnotes_mark_tl
           }
-        \__postnotes_store:nn { \l_postnotes_note_id_tl } {#2}
       }
     \group_end:
   }
@@ -455,8 +519,13 @@
                   \tl_set:Nn \l__postnotes_mark_tl { \thepostnote }
               }
           }
-        \__postnotes_typeset_mark_wrapper:n
-          { \__postnotes_make_mark:nnn { \l__postnotes_mark_tl } { } { } }
+        \group_begin:
+        \socket_assign_plug:nn { tagsupport/postnotes/multsep/begin } { noop }
+        \socket_assign_plug:nn { tagsupport/postnotes/multsep/end } { noop }
+        \__postnotes_typeset_mark_wrapper:nnn
+          { \__postnotes_make_mark:Vnn \l__postnotes_mark_tl { } { } }
+          { } { }
+        \group_end:
       }
     \bool_if:NTF \l__postnotes_inhibit_note_bool
       { \prg_return_true:  }
@@ -464,7 +533,7 @@
   }
 \cs_new_protected:Npn \__postnotes_typeset_mark:nn #1#2
   {
-    \__postnotes_typeset_mark_wrapper:n
+    \__postnotes_typeset_mark_wrapper:nnn
       {
         \bool_if:NTF \l__postnotes_hyperlink_bool
           {
@@ -474,18 +543,25 @@
           }
           { \__postnotes_make_mark:nnn {#2} { } { } }
       }
+      { \tag_socket_use:n { postnotes/mark/begin } }
+      { \tag_socket_use:n { postnotes/mark/end }   }
   }
 \cs_generate_variant:Nn \__postnotes_typeset_mark:nn { eV }
 \tl_new:N \l__postnotes_saved_spacefactor_tl
-\cs_new_protected:Npn \__postnotes_typeset_mark_wrapper:n #1
+\cs_new_protected:Npn \__postnotes_typeset_mark_wrapper:nnn #1#2#3
   {
     \mode_leave_vertical:
     \mode_if_horizontal:T
       {
-        \tl_set:Ne \l__postnotes_saved_spacefactor_tl { \the\spacefactor }
+        \tl_set:Ne \l__postnotes_saved_spacefactor_tl
+          { \int_use:N \spacefactor }
+        \__postnotes_multiple_check:
         \nobreak
       }
-    #1
+    #2 % begin tagging function
+    #1 % mark
+    #3 % end tagging function
+    \__postnotes_multiple_prepare:
     \mode_if_horizontal:T
       { \spacefactor \l__postnotes_saved_spacefactor_tl }
     \scan_stop:
@@ -494,15 +570,17 @@
   {
     \tl_if_empty:NF \l__postnotes_note_label_tl
       { \exp_args:NV \label \l__postnotes_note_label_tl }
-   \tl_if_empty:NF \l__postnotes_note_zlabel_tl
+    \tl_if_empty:NF \l__postnotes_note_zlabel_tl
       { \exp_args:NV \zlabel \l__postnotes_note_zlabel_tl }
   }
 \NewDocumentCommand \postnoteref { s m }
   { \__postnotes_note_ref:nn {#1} {#2} }
+\tl_new:N \l__postnotes_note_ref_label_tl
 \cs_new_protected:Npn \__postnotes_note_ref:nn #1#2
   {
     \group_begin:
-    \__postnotes_typeset_mark_wrapper:n
+    \tl_set:Nn \l__postnotes_note_ref_label_tl {#2}
+    \__postnotes_typeset_mark_wrapper:nnn
       {
         \bool_lazy_and:nnTF
           { ! #1 }
@@ -513,6 +591,8 @@
           }
           { \__postnotes_make_mark:nnn { \ref*{#2} } { } { } }
       }
+      { \tag_socket_use:n { postnotes/postnoteref/begin } }
+      { \tag_socket_use:n { postnotes/postnoteref/end }   }
     \group_end:
   }
 \NewDocumentCommand \postnotesection { O { } +m }
@@ -649,6 +729,7 @@
                     \bool_if:NTF \l__postnotes_print_as_list_bool
                       { \exp_args:Ne \begin { \l__postnotes_print_env_tl } }
                       { \group_begin: }
+                    \tag_socket_use:n { postnotes/printlist/begin }
                     \l__postnotes_print_format_tl
                   }
                 \group_begin:
@@ -669,6 +750,7 @@
                   { \l__postnotes_print_counter_tl }
                 \cs_set:Npe \@currentlabel
                   { \p at postnote \l__postnotes_print_mark_tl }
+                \tag_socket_use:n { postnotes/printnote/begin }
                 \__postnotes_text_mark_wrapper:n
                   {
                     \MakeLinkTarget*
@@ -679,7 +761,10 @@
                       { \l_postnotes_print_note_id_tl }
                       \l__postnotes_print_mark_tl
                   }
+                \tag_socket_use:n { postnotes/printtext/begin }
                 \l__postnotes_print_content_tl
+                \tag_socket_use:n { postnotes/printtext/end }
+                \tag_socket_use:n { postnotes/printnote/end }
                 \l__postnotes_post_printnote_tl
                 \group_end:
                 \seq_if_empty:NTF \g__postnotes_queue_seq
@@ -696,6 +781,7 @@
                   }
                 \tl_if_eq:NnF \l__postnotes_print_type_next_tl { note }
                   {
+                    \tag_socket_use:n { postnotes/printlist/end }
                     \bool_if:NTF \l__postnotes_print_as_list_bool
                       { \exp_args:Ne \end { \l__postnotes_print_env_tl } }
                       { \group_end: }
@@ -731,10 +817,19 @@
   {
     \bool_if:NTF \l__postnotes_print_as_list_bool
       {
-        \item [ \l__postnotes_pre_textmark_tl #1 \l__postnotes_post_textmark_tl ]
+        \item
+          [
+            \tag_socket_use:n { postnotes/printmark/begin }
+            \l__postnotes_pre_textmark_tl #1 \l__postnotes_post_textmark_tl
+            \tag_socket_use:n { postnotes/printmark/end }
+          ]
         \mode_leave_vertical:
       }
-      { \l__postnotes_pre_textmark_tl #1 \l__postnotes_post_textmark_tl }
+      {
+        \tag_socket_use:n { postnotes/printmark/begin }
+        \l__postnotes_pre_textmark_tl #1 \l__postnotes_post_textmark_tl
+        \tag_socket_use:n { postnotes/printmark/end }
+      }
   }
 \cs_new_protected:Npn \__postnotes_verify_multipass:N #1
   {
@@ -1024,10 +1119,12 @@
       }
     \NewDocumentCommand \postnotezref { s m }
       { \__postnotes_note_zref:nn {#1} {#2} }
+    \tl_new:N \l__postnotes_note_zref_zlabel_tl
     \cs_new_protected:Npn \__postnotes_note_zref:nn #1#2
       {
         \group_begin:
-        \__postnotes_typeset_mark_wrapper:n
+        \tl_set:Nn \l__postnotes_note_zref_zlabel_tl {#2}
+        \__postnotes_typeset_mark_wrapper:nnn
           {
             \bool_lazy_all:nTF
               {
@@ -1042,6 +1139,8 @@
               }
               { \__postnotes_make_mark:nnn { \zref{#2} } { } { } }
           }
+          { \tag_socket_use:n { postnotes/postnotezref/begin } }
+          { \tag_socket_use:n { postnotes/postnotezref/end }   }
         \group_end:
       }
   }
@@ -1159,6 +1258,426 @@
           }
       }
   }
+\socket_new:nn { tagsupport/postnotes/mark/begin }{ 0 }
+\socket_new:nn { tagsupport/postnotes/mark/end }{ 0 }
+\socket_new:nn { tagsupport/postnotes/mark/nomark }{ 0 }
+\socket_new:nn { tagsupport/postnotes/multsep/begin }{ 0 }
+\socket_new:nn { tagsupport/postnotes/multsep/end }{ 0 }
+\socket_new:nn { tagsupport/postnotes/printlist/begin }{ 0 }
+\socket_new:nn { tagsupport/postnotes/printlist/end }{ 0 }
+\socket_new:nn { tagsupport/postnotes/printnote/begin }{ 0 }
+\socket_new:nn { tagsupport/postnotes/printnote/end }{ 0 }
+\socket_new:nn { tagsupport/postnotes/printmark/begin }{ 0 }
+\socket_new:nn { tagsupport/postnotes/printmark/end }{ 0 }
+\socket_new:nn { tagsupport/postnotes/printtext/begin }{ 0 }
+\socket_new:nn { tagsupport/postnotes/printtext/end }{ 0 }
+\socket_new:nn { tagsupport/postnotes/postnoteref/begin }{ 0 }
+\socket_new:nn { tagsupport/postnotes/postnoteref/end }{ 0 }
+\socket_new:nn { tagsupport/postnotes/postnotezref/begin }{ 0 }
+\socket_new:nn { tagsupport/postnotes/postnotezref/end }{ 0 }
+\bool_lazy_and:nnT
+  { \cs_if_exist_p:N \tag_if_active_p: }
+  { \tag_if_active_p: }
+  {
+    \tagpdfsetup
+      {
+        role/new-tag = { tag=endnote, role=FENote } ,
+        role/new-tag = { tag=endnotemark, role=Lbl } ,
+        role/new-tag = { tag=endnotelabel, role=Lbl } ,
+        role/new-attribute =
+          { EndnoteType } { /O /FENote /NoteType /Endnote } ,
+        role/new-attribute =
+          { EndnotesList } { /O /List /ListNumbering /Ordered } ,
+      }
+    \socket_new_plug:nnn { tagsupport/postnotes/mark/begin } { default }
+      {
+        \tag_mc_end_push:
+        \tag_struct_begin:n
+          {
+            tag = endnotemark ,
+            label = { postnotemark. \l_postnotes_note_id_tl } ,
+            ref = { postnote. \l_postnotes_note_id_tl } ,
+          }
+        \__postnotes_tagsup_store_sctructnum:nN
+          { postnotemark } \l_postnotes_note_id_tl
+        \tag_mc_begin:n{}
+      }
+    \socket_new_plug:nnn { tagsupport/postnotes/mark/end } { default }
+      {
+        \tag_mc_end:
+        \tag_struct_end: % endnotemark
+        \tag_mc_begin_pop:n{}
+      }
+    \socket_new_plug:nnn { tagsupport/postnotes/mark/nomark } { default }
+      {
+        \tag_struct_begin:n
+          {
+            tag = NonStruct ,
+            label = { postnotemark. \l_postnotes_note_id_tl } ,
+            ref = { postnote. \l_postnotes_note_id_tl } ,
+          }
+        \__postnotes_tagsup_store_sctructnum:nN
+          { postnotemark } \l_postnotes_note_id_tl
+        \tag_struct_end: % NonStruct
+      }
+    \socket_assign_plug:nn { tagsupport/postnotes/mark/begin } { default }
+    \socket_assign_plug:nn { tagsupport/postnotes/mark/end } { default }
+    \socket_assign_plug:nn { tagsupport/postnotes/mark/nomark } { default }
+    \socket_new_plug:nnn { tagsupport/postnotes/multsep/begin } { default }
+      {
+        \tag_mc_end_push:
+        \tag_mc_begin:n { artifact }
+      }
+    \socket_new_plug:nnn { tagsupport/postnotes/multsep/end } { default }
+      {
+        \tag_mc_end:
+        \tag_mc_begin_pop:n{}
+      }
+    \socket_assign_plug:nn { tagsupport/postnotes/multsep/begin } { default }
+    \socket_assign_plug:nn { tagsupport/postnotes/multsep/end } { default }
+    \socket_new_plug:nnn { tagsupport/postnotes/printlist/begin } { default }
+      { \tag_tool:n { para/tagging=false } }
+    \socket_new_plug:nnn { tagsupport/postnotes/printlist/end } { default }
+      { }
+    \socket_assign_plug:nn { tagsupport/postnotes/printlist/begin } { default }
+    \socket_assign_plug:nn { tagsupport/postnotes/printlist/end } { default }
+    \socket_new_plug:nnn { tagsupport/postnotes/printnote/begin } { default }
+      {
+        \bool_if:NF \l__postnotes_print_as_list_bool
+          {
+            \tag_struct_begin:n
+              {
+                tag = endnote ,
+                attribute-class = EndnoteType ,
+                label = { postnote. \l_postnotes_print_note_id_tl } ,
+                ref = { postnotemark. \l_postnotes_print_note_id_tl } ,
+              }
+            \__postnotes_tagsup_store_sctructnum:nN
+              { postnote } \l_postnotes_print_note_id_tl
+         }
+      }
+    \socket_new_plug:nnn { tagsupport/postnotes/printnote/end } { default }
+      {
+        \bool_if:NF \l__postnotes_print_as_list_bool
+          { \tag_struct_end: }  % endnote
+      }
+    \socket_assign_plug:nn { tagsupport/postnotes/printnote/begin } { default }
+    \socket_assign_plug:nn { tagsupport/postnotes/printnote/end } { default }
+    \socket_new_plug:nnn { tagsupport/postnotes/printmark/begin } { default }
+      {
+        \bool_if:NF \l__postnotes_print_as_list_bool
+         {
+           \tag_struct_begin:n { tag=endnotelabel }
+           \tag_mc_begin:n{ tag=Lbl }
+         }
+      }
+    \socket_new_plug:nnn { tagsupport/postnotes/printmark/end } { default }
+      {
+        \bool_if:NF \l__postnotes_print_as_list_bool
+         {
+           \tag_mc_end:
+           \tag_struct_end: % endnotelabel
+         }
+      }
+    \socket_assign_plug:nn { tagsupport/postnotes/printmark/begin } { default }
+    \socket_assign_plug:nn { tagsupport/postnotes/printmark/end } { default }
+    \socket_new_plug:nnn { tagsupport/postnotes/printtext/begin } { default }
+      {
+        \bool_if:NTF \l__postnotes_print_as_list_bool
+          {
+            \tag_struct_begin:n
+              {
+                tag = endnote ,
+                attribute-class = EndnoteType ,
+                label = { postnote. \l_postnotes_print_note_id_tl } ,
+                ref = { postnotemark. \l_postnotes_print_note_id_tl } ,
+              }
+            \__postnotes_tagsup_store_sctructnum:nN
+              { postnote } \l_postnotes_print_note_id_tl
+            \tag_struct_begin:n { tag=text-unit }
+            \tag_struct_begin:n { tag=text }
+            \tag_tool:n { para/tagging=true }
+            \tag_mc_begin:n{}
+          }
+          {
+            \tag_struct_begin:n { tag=text-unit }
+            \tag_struct_begin:n { tag=text }
+            \tag_tool:n { para/tagging=true }
+            \tag_mc_begin:n{}
+          }
+      }
+    \socket_new_plug:nnn { tagsupport/postnotes/printtext/end } { default }
+      {
+        \bool_if:NTF \l__postnotes_print_as_list_bool
+          {
+            \tag_mc_end:
+            \tag_tool:n { para/tagging=false }
+            \tag_struct_end: % text
+            \tag_struct_end: % text-unit
+            \tag_struct_end: % endnote
+          }
+          {
+            \tag_mc_end:
+            \tag_tool:n { para/tagging=false }
+            \tag_struct_end: % text
+            \tag_struct_end: % text-unit
+          }
+      }
+    \socket_assign_plug:nn { tagsupport/postnotes/printtext/begin } { default }
+    \socket_assign_plug:nn { tagsupport/postnotes/printtext/end } { default }
+    \IfInstanceExistsT { blockenv } { list }
+      {
+        \DeclareInstance { blockenv } { postnoteslist } { display }
+          {
+            env-name       = postnoteslist ,
+            tag-name       = L ,
+            tag-class      = EndnotesList ,
+            tagging-recipe = list ,
+            inner-level-counter = ,
+            level-increase = true ,
+            setup-code     = ,
+            block-instance = list ,
+            inner-instance = postnoteslist ,
+          }
+        \DeclareInstanceCopy { blockenv }
+          { postnoteslisthang } { postnoteslist }
+        \EditInstance { blockenv } { postnoteslisthang }
+          { env-name = postnoteslisthang }
+        \DeclareInstance { list } { postnoteslist } { std }
+          { item-instance = postnoteslist }
+        \DeclareInstance { item } { postnoteslist } { std }
+          {
+            label-format = { \hspace { \labelsep } \normalfont ~ #1 } ,
+            label-align = left ,
+          }
+        \RenewDocumentEnvironment { postnoteslist } { }
+          {
+            \UseInstance { blockenv } { postnoteslist }
+              {
+                leftmargin     = 0pt ,
+                label-width    = 0pt ,
+                item-indent    = .5\parindent ,
+                rightmargin    = 0pt ,
+                parindent      = \parindent ,
+                par-skip       = \parskip ,
+                item-skip      = 0pt ,
+                beginsep       = .5\topsep ,
+                begin-par-skip = .5\partopsep ,
+              }
+          }
+          { \endblockenv }
+        \RenewDocumentEnvironment { postnoteslisthang } { }
+          {
+            \UseInstance { blockenv } { postnoteslisthang }
+              {
+                leftmargin     = 1em ,
+                label-width    = -\leftmargin ,
+                item-indent    = -2\leftmargin ,
+                rightmargin    = 0pt ,
+                parindent      = \parindent ,
+                par-skip       = \parskip ,
+                item-skip      = 0pt ,
+                beginsep       = .5\topsep ,
+                begin-par-skip = .5\partopsep ,
+              }
+          }
+          { \endblockenv }
+      }
+    \bool_new:N \l__postnotes_inside_note_bool
+    \AddToHookWithArguments { label } [ postnotes/tagsup ]
+      {
+        \bool_if:NT \l__postnotes_inside_note_bool
+          {
+            \property_record:nn { postnote at label@innote. #1 }
+              { postnotes/tagsup at noteid }
+          }
+      }
+    \AddToHook { postnotes/print/note/begin } [ postnotes/tagsup ]
+      { \bool_set_true:N \l__postnotes_inside_note_bool }
+    \property_new:nnnn { postnotes/tagsup at noteid } { now } { 0 }
+      { \l_postnotes_print_note_id_tl }
+    \AddToHook { package/zref-user/after } [ postnotes/tagsup ]
+      {
+        \zref at newprop { postnotes at tagsup@noteid } [ 0 ]
+          { \l_postnotes_print_note_id_tl }
+        \AddToHook { postnotes/print/note/begin } [ postnotes/tagsup ]
+          { \zref at localaddprop { main } { postnotes at tagsup@noteid } }
+      }
+    \AddToHook { postnotes/note/store } [ postnotes/tagsup ]
+      {
+        \tl_if_empty:NF \l__postnotes_note_label_tl
+          {
+            \prop_gput:cnV
+              { \__postnotes_data_name:e { \l_postnotes_note_id_tl } }
+              { label } \l__postnotes_note_label_tl
+          }
+      }
+    \AddToHook { package/zref-user/after } [ postnotes/tagsup ]
+      {
+        \AddToHook { postnotes/note/store } [ postnotes/tagsup ]
+          {
+            \tl_if_empty:NF \l__postnotes_note_zlabel_tl
+              {
+                \prop_gput:cnV
+                  { \__postnotes_data_name:e { \l_postnotes_note_id_tl } }
+                  { zlabel } \l__postnotes_note_zlabel_tl
+              }
+          }
+      }
+    \AddToHook { postnotes/print/note/begin } [ postnotes/tagsup ]
+      {
+        \__postnotes_prop_get:nnN { \l_postnotes_print_note_id_tl }
+          { label } \l__postnotes_restore_tmp_tl
+        \tl_if_empty:NF \l__postnotes_restore_tmp_tl
+          {
+            \exp_args:Ne \property_record:nn
+              { postnote at label@option. \l__postnotes_restore_tmp_tl }
+              { postnotes/tagsup at noteid }
+          }
+        \__postnotes_prop_get:nnN { \l_postnotes_print_note_id_tl }
+          { zlabel } \l__postnotes_restore_tmp_tl
+        \tl_if_empty:NF \l__postnotes_restore_tmp_tl
+          {
+            \exp_args:Ne \property_record:nn
+              { postnote at zlabel@option. \l__postnotes_restore_tmp_tl }
+              { postnotes/tagsup at noteid }
+          }
+      }
+    \prop_new:N \g__postnotes_tagsup_structnums_prop
+    \cs_new_protected:Npn \__postnotes_tagsup_store_sctructnum:nN #1#2
+      {
+        \prop_gput:Nee \g__postnotes_tagsup_structnums_prop
+          { #1 . #2 } { \tag_get:n { struct_num } }
+      }
+    \prop_new:N \g__postnotes_tagsup_crossrefs_prop
+    \cs_new_protected:Npn \__postnotes_tagsup_store_crossref:nN #1#2
+      {
+        \prop_gput:Nee \g__postnotes_tagsup_crossrefs_prop
+          { \tag_get:n { struct_num } } { #1 . #2 }
+      }
+    \cs_new_protected:Npn \__postnotes_tagsup_gput_ref:nn #1#2
+      {
+        \tag_if_active:T
+          { \tag_struct_gput:ene {#1} {ref} { \tag_struct_object_ref:e {#2} } }
+      }
+    \AddToHook { tagpdf/finish/before } [ postnotes/tagsup ]
+      {
+        \prop_map_inline:Nn \g__postnotes_tagsup_crossrefs_prop
+          {
+            \__postnotes_tagsup_gput_ref:nn
+              { \prop_item:Nn \g__postnotes_tagsup_structnums_prop {#2} }
+              {#1}
+          }
+      }
+    \socket_new_plug:nnn { tagsupport/postnotes/postnoteref/begin } { default }
+      {
+        \tag_mc_end_push:
+        \property_if_recorded:eeTF
+          { postnote at label@innote. \l__postnotes_note_ref_label_tl }
+          { postnotes/tagsup at noteid }
+          {
+            \tl_set:Ne \l__postnotes_tmpa_tl
+              {
+                \property_ref:ee
+                  { postnote at label@innote. \l__postnotes_note_ref_label_tl }
+                  { postnotes/tagsup at noteid }
+              }
+            \tag_struct_begin:n
+              {
+                tag = endnotemark ,
+                ref = { postnote. \l__postnotes_tmpa_tl } ,
+              }
+            \__postnotes_tagsup_store_crossref:nN
+              { postnote } \l__postnotes_tmpa_tl
+          }
+          {
+            \property_if_recorded:eeTF
+              { postnote at label@option. \l__postnotes_note_ref_label_tl }
+              { postnotes/tagsup at noteid }
+              {
+                \tl_set:Ne \l__postnotes_tmpa_tl
+                  {
+                    \property_ref:ee
+                      { postnote at label@option. \l__postnotes_note_ref_label_tl }
+                      { postnotes/tagsup at noteid }
+                  }
+                \tag_struct_begin:n
+                  {
+                    tag = endnotemark ,
+                    ref = { postnotemark. \l__postnotes_tmpa_tl } ,
+                  }
+                \__postnotes_tagsup_store_crossref:nN
+                  { postnotemark } \l__postnotes_tmpa_tl
+              }
+              { \tag_struct_begin:n { tag = endnotemark } }
+          }
+        \tag_mc_begin:n{}
+      }
+    \socket_new_plug:nnn { tagsupport/postnotes/postnoteref/end } { default }
+      {
+        \tag_mc_end:
+        \tag_struct_end: % endnotemark
+        \tag_mc_begin_pop:n{}
+      }
+    \socket_assign_plug:nn { tagsupport/postnotes/postnoteref/begin } { default }
+    \socket_assign_plug:nn { tagsupport/postnotes/postnoteref/end } { default }
+    \AddToHook { package/zref-user/after } [ postnotes/tagsup ]
+      {
+        \socket_new_plug:nnn { tagsupport/postnotes/postnotezref/begin } { default }
+          {
+            \tag_mc_end_push:
+            \zref at ifrefcontainsprop { \l__postnotes_note_zref_zlabel_tl }
+              { postnotes at tagsup@noteid }
+              {
+                \tl_set:Ne \l__postnotes_tmpa_tl
+                  {
+                    \zref at extract { \l__postnotes_note_zref_zlabel_tl }
+                      { postnotes at tagsup@noteid }
+                  }
+                \tag_struct_begin:n
+                  {
+                    tag = endnotemark ,
+                    ref = { postnote. \l__postnotes_tmpa_tl } ,
+                  }
+                \__postnotes_tagsup_store_crossref:nN
+                  { postnote } \l__postnotes_tmpa_tl
+              }
+              {
+                \property_if_recorded:eeTF
+                  { postnote at zlabel@option. \l__postnotes_note_zref_zlabel_tl }
+                  { postnotes/tagsup at noteid }
+                  {
+                    \tl_set:Ne \l__postnotes_tmpa_tl
+                      {
+                        \property_ref:ee
+                          {
+                            postnote at zlabel@option.
+                            \l__postnotes_note_zref_zlabel_tl
+                          }
+                          { postnotes/tagsup at noteid }
+                      }
+                    \tag_struct_begin:n
+                      {
+                        tag = endnotemark ,
+                        ref = { postnotemark. \l__postnotes_tmpa_tl } ,
+                      }
+                    \__postnotes_tagsup_store_crossref:nN
+                      { postnotemark } \l__postnotes_tmpa_tl
+                  }
+                  { \tag_struct_begin:n { tag = endnotemark } }
+              }
+            \tag_mc_begin:n{}
+          }
+        \socket_new_plug:nnn { tagsupport/postnotes/postnotezref/end } { default }
+          {
+            \tag_mc_end:
+            \tag_struct_end: % endnotemark
+            \tag_mc_begin_pop:n{}
+          }
+        \socket_assign_plug:nn { tagsupport/postnotes/postnotezref/begin } { default }
+        \socket_assign_plug:nn { tagsupport/postnotes/postnotezref/end } { default }
+      }
+  }
 \tl_new:N \pntitle
 \tl_new:N \pnhdnotes
 \tl_new:N \pnhdtopage
@@ -1238,6 +1757,7 @@
 \__postnotes_set_babel_language:nn { swissgerman }  { german }
 \__postnotes_set_babel_language:nn { nswissgerman } { german }
 \__postnotes_set_polyglossia_language:nn { german } { german }
+
 %% 
 %%
 %% End of file `postnotes.sty'.



More information about the tex-live-commits mailing list.