texlive[72770] Master/texmf-dist: postnotes (5nov24)

commits+karl at tug.org commits+karl at tug.org
Tue Nov 5 21:18:59 CET 2024


Revision: 72770
          https://tug.org/svn/texlive?view=revision&revision=72770
Author:   karl
Date:     2024-11-05 21:18:59 +0100 (Tue, 05 Nov 2024)
Log Message:
-----------
postnotes (5nov24)

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-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/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-11-05 20:18:50 UTC (rev 72769)
+++ trunk/Master/texmf-dist/doc/latex/postnotes/CHANGELOG.md	2024-11-05 20:18:59 UTC (rev 72770)
@@ -1,7 +1,40 @@
 # Changelog
 
-## [Unreleased](https://github.com/gusbrs/postnotes/compare/v0.3.0...HEAD)
+## [Unreleased](https://github.com/gusbrs/postnotes/compare/v0.4.0...HEAD)
 
+## [v0.4.0](https://github.com/gusbrs/postnotes/compare/v0.3.0...v0.4.0) (2024-11-04)
+
+*WARNING*: You may need to clear your .aux files after this update.
+- (Internally, the macro used in the .aux file, `\post at note`, used to take two
+  arguments, but now it takes four.)
+
+### Added
+- Provide (experimental) `counteraux` option: full automation of notes
+  numbering and sequence capable of handling both multiple passes from
+  measuring operations and floats shuffling the sequence of notes.
+  `\postnote`s set inside floats may float past `\printpostnotes` and belong
+  to the section where they are actually typeset.
+- Provide options `checkduplicates` and `checkfloats`, which issue warnings in
+  case of duplicate notes from measuring passes and of notes order mismatch
+  resulting from float placement.
+- Provide `maybemulti` option, exposing to users a simple method to handle
+  cases of duplicate notes resulting from measuring passes which was already
+  used internally.
+- Warning at `enddocument` for stray `\postnote`s left after the last
+  `\printpostnotes`.
+- Support for `xltabular` package.
+
+### Fixed
+- Fixed `style=endnotes` tagging error (see issue
+  [#8](https://github.com/gusbrs/postnotes/issues/8))
+
+### Changed
+- Improved handling of nested notes, example added to the User manual.
+
+### Removed
+- Command `\postnotesectionx`, which had been deprecated since v0.2.0 from
+  2022-12-28, has been removed.
+
 ## [v0.3.0](https://github.com/gusbrs/postnotes/compare/v0.2.8...v0.3.0) (2024-10-15)
 
 ### Added
@@ -13,7 +46,7 @@
 
 ## [v0.2.8](https://github.com/gusbrs/postnotes/compare/v0.2.7...v0.2.8) (2023-12-12)
 
-## Fixed
+### Fixed
 - Fixed `multibool` test in `\__postnotes_verify_multipass:N`.
 
 ## [v0.2.7](https://github.com/gusbrs/postnotes/compare/v0.2.6...v0.2.7) (2023-11-14)

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

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-11-05 20:18:50 UTC (rev 72769)
+++ trunk/Master/texmf-dist/doc/latex/postnotes/postnotes-doc.tex	2024-11-05 20:18:59 UTC (rev 72770)
@@ -130,6 +130,7 @@
     \pnhdnamefirst ,
     \pnhdnamelast ,
     \mypnheader ,
+    \thepostnote ,
     \demochapter ,
     \origlatexchapter ,
     \l_postnotes_note_id_tl ,
@@ -154,7 +155,7 @@
   \zcsetup{countertype={lstlisting=example}}%
   \lstset{#1}%
   \stepcounter{pnexample}%
-  \setcounter{lstlisting}{\value{pnexample}}%
+  \setcounter{lstlisting}{\value{pnexample}-1}%
 }{}
 \lstnewenvironment{pnsnippet}[1][]{%
   \renewcommand{\lstlistingname}{Example}%
@@ -311,10 +312,10 @@
 
 
 \section{Options}
-\zlabel{sec:options}
+\label{sec:options}
 
 \subsection*{Package options}
-\zlabel{sec:package-options}
+\label{sec:package-options}
 
 \begin{function}{\postnotesetup}
   \begin{syntax}
@@ -385,16 +386,6 @@
 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} %
@@ -418,6 +409,16 @@
 the values \texttt{endnotes} or \texttt{pagenote} so that \cs{printpostnotes}
 works as its counterparts in each of these packages.
 
+\DescribeOption{multiple} %
+\DescribeOption{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{hyperref} %
 \DescribeOption{backlink} %
 The \opt{hyperref} option controls the use of \pkg{hyperref} by
@@ -450,9 +451,58 @@
 only reasonable thing to do.  \opt{sort} is a boolean option, and defaults to
 \texttt{true}.
 
+\DescribeOption{checkduplicates} %
+\DescribeOption{checkfloats} %
+Issue warnings in case of duplicate notes resulting from measuring/trial
+passes and from mismatches in the sequence of notes resulting from floats,
+respectively.  These checks are only expected to be meaningful in a document
+for which the compilation has stabilized: with labels and floats already in
+place.  See \zcref{sec:thorns} for discussion.  Note that the
+\opt{checkfloats} option does not test ``if my notes are in numeric order''
+(that's the job of \opt{sort}), but rather whether the order the marks are
+typeset along the document and the order the notes are printed in
+\cs{printposnotes} are the same.  These options are booleans.
+\opt{checkduplicates} is initially enabled, since whether a place performs
+measuring passes does not really change, and it is easy to deal with a note in
+this situation with the \opt{maybemulti} option. \opt{checkfloats}, on the
+other hand, is initially disabled.  Float placement (and its implications for
+\pkg{postnotes}) is something one should not worry about until the very last
+stages of the document.  At that time, I expect it to be useful, but during
+the writing phase, such a warning would only be distracting.  Think of if as
+something to use like you would use the \pkg{widows-and-orphans} package, for
+example.
 
+\DescribeOption{maybemulti} %
+A \cs{postnote} set while \opt{maybemulti} is true is checked at
+\cs{printposnotes} and only kept in the printing queue if its corresponding
+(internal) page label exists.  See \zcref{sec:thorns} for discussion.  The
+drawback is that, since it requires the label for the check, a new note set
+with \opt{maybemulti} will need one more compilation run than otherwise.  This
+is a boolean option, and the initial value is false.
+
+\DescribeOption{counteraux} %
+\DescribeMacro{\pnsetcounteraux\marg{int}} %
+\DescribeMacro{\pnaddtocounteraux\marg{int}} %
+(Experimental) Build the printing queue based on the (internal) page labels
+set in the \file{.aux} file, and also handle the counter stepping at the same
+time.  This should provide us with a fully automated sequence of notes which
+is both exempt from duplicates resulting from measuring passes and from notes
+order issues caused by floats.  See \zcref{sec:thorns} for discussion.  Since
+the counter sequence is determined during the input of the \file{.aux} file,
+the regular counter commands will not work as intended.  \cs{pnsetcounteraux}
+and \cs{pnaddtocounteraux} take an integer number as argument, and do what
+their names imply, but at the time they can actually affect the sequence used
+by \opt{counteraux}.  The option is a boolean, is initially disabled, and is
+preamble only.  Enabling \opt{counteraux} also disables \opt{sort} at
+\texttt{begindocument/before}.\footnote{The truth is, I have not yet thought
+  it through how these options may interact.  So, this is done out of caution.
+  I don't expect them to clash but, in principle, with \opt{counteraux},
+  \opt{sort} is not needed.  You are not blocked from re-enabling it later
+  but, if you do, be mindful of possible interactions.}
+
+
 \subsection*{Note options}
-\zlabel{sec:note-options}
+\label{sec:note-options}
 
 The options accepted by \cs{postnote}\oarg{options}\marg{text} are the
 following:
@@ -498,9 +548,13 @@
 \opt{zlabel} option is also provided.  See \zcref{sec:cross-references} for
 details about cross-referencing.
 
+\DescribeOption{maybemulti} %
+Does the same thing as the corresponding package option, but is applied for a
+particular \cs{postnote}.
 
+
 \subsection*{Section options}
-\zlabel{sec:section-options}
+\label{sec:section-options}
 
 The options accepted by \cs{postnotesection}\oarg{options}\marg{text} are the
 following:
@@ -525,11 +579,11 @@
 
 
 \section{Notes sections}
-\zlabel{sec:notes-sections}
+\label{sec:notes-sections}
 
 As mentioned above, \cs{postnotesection} is the basic interface for
 subdividing the notes when printed.  For those familiar with it, this command
-is \pkg{postnotes}'s equivalent to \pkg{endnotes}' \cs{addtoendnotes}.  It has
+is \pkg{postnotes}' equivalent to \pkg{endnotes}' \cs{addtoendnotes}.  It has
 the same intended use -- to add text or commands along the notes' sequence at
 the point it is called -- and the way it works is quite similar to
 \cs{addtoendnotes}.  But there are some differences, prominently a
@@ -772,7 +826,7 @@
 
 
 \section{Headers}
-\zlabel{sec:headers}
+\label{sec:headers}
 
 \pkg{postnotes}' support for running headers comprises a basic header, enabled
 by default, generating headers in the form ``Notes to pages N--M'', but also
@@ -920,7 +974,7 @@
 
 
 \section{Cross-references}
-\zlabel{sec:cross-references}
+\label{sec:cross-references}
 
 Cross-referencing with \pkg{postnotes} works in a pretty standard way: set a
 label, make references to it.  However, there are two ways to set a label to a
@@ -942,7 +996,7 @@
 
 
 \section{Localization}
-\zlabel{sec:localization}
+\label{sec:localization}
 
 \DescribeMacro{\pntitle} %
 \DescribeMacro{\pnhdnotes} %
@@ -980,7 +1034,7 @@
 
 
 \section{Further examples}
-\zlabel{sec:further-examples}
+\label{sec:further-examples}
 
 This section collects some further usage examples which did not fit into the
 previous sections, but might still be of interest.
@@ -1039,19 +1093,21 @@
 
 \zcref{ex:x:caption} illustrates a couple of techniques to handle long
 captions.  Captions pose a problem to \cs{postnote} because, if you set a
-\cs{postnote} inside a standard caption, whose text is long enough to require
+\cs{postnote} inside a standard caption whose text is long enough to require
 two lines, the content of the caption ends up being typeset twice: once to
 check if it would have fitted in a single line, the second to typeset the two
-lines since it didn't fit in one.  This triggers the \texttt{postnote} counter
-to be stepped twice (and any other counter that happens to be there too).  One
-way to handle the situation is, if you know(!) that the caption takes two
-lines, you can decrement the counter just before it, and place the note
-directly in the caption, this will get you a correctly numbered note.  Another
-way is to use the pairing between a \opt{nomark} \cs{postnote} and
-\cs{postnoteref}: place a note outside the caption (but close to it, since its
-position will determine the anchor for the backlink) with the \opt{nomark}
-option, set a label inside it and, inside the caption make a \cs{postnoteref}
-to the label.  In practice:
+lines since it didn't fit in one.\footnote{This is the case for the
+  \cs{caption} command provided by the kernel, but it may be different
+  depending on the document class, packages and options in use.}  This
+triggers the \texttt{postnote} counter to be stepped twice (and any other
+counter that happens to be there too).  One way to handle the situation is to
+use the pairing between a \opt{nomark} \cs{postnote} and \cs{postnoteref}:
+place a note outside the caption (but close to it, since its position will
+determine the anchor for the backlink) with the \opt{nomark} option, set a
+label inside it and, inside the caption make a \cs{postnoteref} to the label.
+Another method is to call \cs{stepcounter}\texttt{\{postnote\}} before the
+caption, then place a \cs{postnote} setting the \opt{mark} option with
+\cs{arabic}\texttt{\{postnote\}}.  In practice:
 
 \begin{pnexample}[caption={Long caption},label={ex:x:caption}]
 \documentclass{article}
@@ -1060,22 +1116,225 @@
 \usepackage{hyperref}
 \begin{document}
 \begin{figure}
-  Figure.
-  \addtocounter{postnote}{-1}
-  \caption[Caption for LOF]{A long caption, long enough to require two
-    lines\postnote{A note.}}
+Figure.
+\postnote[nomark]{\label{en:1}A note.}%
+\caption[Short caption]{A long caption, long enough to require two
+lines\postnoteref{en:1}}
 \end{figure}
 \begin{figure}
-  Figure.
-  \postnote[nomark]{\label{en:1}A note.}%
-  \caption[Caption for LOF]{A long caption, long enough to require two
-    lines\postnoteref{en:1}}
+Figure.
+\stepcounter{postnote}
+\caption[Short caption]{A long caption, long enough to require two
+lines\postnote[mark=\arabic{postnote}]{A note.}}
 \end{figure}
 \printpostnotes
 \end{document}
 \end{pnexample}
 
+Arguably, the second method is more interesting for normal cases, since it
+does not offset the note's anchor.  The first one would work for multiple
+notes as well, and it is also more robust to multiple passes of the content.
+\pkg{postnotes} controls for this in a number of known cases to avoid notes in
+duplicity, but obviously cannot cover every possibility, in which case
+\opt{nomark} with \cs{postnoteref} has you covered.  Caveat, these techniques
+assume the floats do not disturb the order of the notes, otherwise we are back
+to the case discussed in \zcref{ex:x:float}.
 
+The (experimental) \opt{counteraux} option, shown in \zcref{ex:x:counteraux},
+is an attempt to fully ``automate away'' the issues illustrated in
+\zcref{ex:x:float,ex:x:caption}, so that there's no need to manipulate either
+the counter or the mark.  See \zcref{sec:thorns} for discussion.
+
+\begin{pnexample}[caption={\opt{counteraux} option},label={ex:x:counteraux}]
+\documentclass{book}
+\usepackage[textwidth=8cm]{geometry}
+\usepackage{postnotes}
+\postnotesetup{counteraux}
+\usepackage{hyperref}
+\begin{document}
+\chapter{First chapter}
+\postnote{one}
+\postnote{two}
+\begin{figure}[p]
+Figure.%
+\caption[Short caption]{A long caption, long enough to require two
+lines\postnote{three}}
+\end{figure}
+\postnote{four}
+\postnote{five}
+\clearpage
+\postnote{six}
+\printpostnotes
+\end{document}
+\end{pnexample}
+
+Nested notes.  To be honest, the design of the package was not made with this
+use case in mind.  However, since \pkg{postnotes} does not use the method of
+writing the notes' contents to an external file and printing the notes by
+inputting it, the technical restriction of the traditional method does not
+apply.  Hence, it mostly works.  However, nested notes are not included in the
+ongoing \cs{printpostnotes}, but are left for the next call.  So, if nesting,
+call \cs{printpostnotes} again to print the nested ones.  Which is actually
+convenient, since different settings may be applied to each set.  Also, expect
+limitations, particularly with regard to the context variables stored by the
+package: the context of a nested note is the notes section, not the one to
+which the parent note belongs to.  Finally, be watchful of results, because
+what works does so more by luck than by design.  Still, it is not too bad that
+\pkg{postnotes} can handle not only nesting but even split sections of nested
+notes as shown in \zcref{ex:x:nesting}.
+
+\begin{pnexample}[caption={Nested notes},label={ex:x:nesting}]
+\documentclass{book}
+\usepackage{postnotes}
+\usepackage{hyperref}
+\counterwithin*{postnote}{chapter}
+\begin{document}
+\chapter{First chapter}
+\postnotesection{\section*{Notes to chapter 1}%
+  \setcounter{postnote}{0}%
+  \postnotesection{\section*{Editor's notes to chapter 1}}}
+Foo.\postnote{Foo note.}\par
+Bar.\postnote{Bar note.\postnote{Editor's note bar.}}\par
+Baz.\postnote{A note.\postnote{Editor's note baz.}}
+\chapter{Second chapter}
+\postnotesection{\section*{Notes to chapter 2}%
+  \setcounter{postnote}{0}%
+  \postnotesection{\section*{Editor's notes to chapter 2}}}
+Foo.\postnote{Foo note.}\par
+Bar.\postnote{Bar note.\postnote{Editor's note bar.}}\par
+Baz.\postnote{A note.\postnote{Editor's note baz.}}
+\begingroup
+\renewcommand*{\thepostnote}{\roman{postnote}}
+\printpostnotes
+\renewcommand*{\pntitle}{Editor's notes}
+\printpostnotes
+\endgroup
+\end{document}
+\end{pnexample}
+
+
+\section{Thorny cases}
+\label{sec:thorns}
+
+Depending on where one places a \cs{postnote}, some undesirable side-effects
+may ensue.  A note set somewhere which is subject to measuring/trial passes
+may be stored multiple times, thus appearing in duplicity at
+\cs{printpostnotes}.\footnote{That would normally be the case, but
+  \pkg{postnotes} already handles some known instances of this, avoiding the
+  duplicates.  It doesn't mean there are not places unknown to the package
+  which do the same.}  Also, a note placed within a float may result in the
+sequence of notes being disturbed, depending on where the float ends up being
+typeset.  These problems are usually not too frequent, but they come up
+occasionally and, when they do, they can be a pain.
+
+\pkg{postnotes} offers some ways to deal with these issues.  Sorting falls
+into this category.  The traditional ``counter juggling'' around a float which
+disrupted the sequence of the notes could always be used to fix the sequence
+the marks got typeset (see \zcref{ex:x:float}), and the \opt{sort} option
+handles the sequence at \cs{printpostnotes}.
+
+Besides sorting, what the package does offer is, ultimately, based on the page
+labels each \cs{postnote} sets internally, the \cs{post at note}s in the
+\file{.aux} file.  These labels are non-immediate writes (whatsits, in the
+jargon), as they must be, since we are interested in the page number.  As a
+result, measuring passes don't get written, and they are also written in the
+order the document elements get shipped out.  Hence, the labels set in the
+\file{.aux} file are free of duplicates resulting from measuring passes, and
+are also ordered the same as the typeset order of the document, floats
+considered.  Based on the information gathered from these labels, we have a
+number of options.
+
+For known cases of measuring/trial passes where it's possible to distinguish
+the measuring from the final pass, \pkg{postnotes} uses that information to
+inhibit the note and also handles the counter appropriately so that the
+measuring pass has the correct value to measure.  Currently, such support is
+provided for \pkg{amsmath} display math environments, \pkg{csquotes}'
+\cs{blockcquote}s, \pkg{tabularx}, \pkg{tabularray}, and \pkg{xltabular}.  For
+cases where it is not possible to distinguish the trial from the final pass,
+\pkg{postnotes} uses the page labels mentioned above, and for \cs{postnote}s
+flagged as potential duplicates, it checks whether the page label exists, and
+drops the (duplicate) note if it doesn't.  Prominent example here is the
+kernel's \cs{caption}.  This mechanism is exposed to users through the
+\opt{maybemulti} option.  Important distinction here between this method and
+the more controlled inhibition above is that there's little we can do about
+the counter.  The counter itself can be adjusted manually if need be, to
+restore the sequence.  But the value the measuring pass receives is out of our
+hands, hence it may be off.  Of course, the expected difference should
+normally be small.  But if the measuring is presumed to be exact, some
+mysterious slightly overfull \cs{hbox}es may occur.
+
+\pkg{postnotes} also offers some checks, to issue warnings for cases of
+duplicates or sequence problems: the \opt{checkduplicates} and
+\opt{checkfloats} options.  They use the information generated by the page
+labels to perform some consistency checks, and report problems.  I expect them
+to be useful, since this is the kind of issue that may trick even a competent
+proofreader.
+
+Finally, \pkg{postnotes} also provides the (experimental) \opt{counteraux}
+option, which is an attempt to fully ``automate away'' these issues.  The
+basic idea is that, since we are already using the data generated by the page
+labels to handle some of the issues and perform some checks, why not use that
+information directly?  The page labels are already net of duplicates and in
+the order the document elements are typeset.  Indeed, why not use them?
+That's what \opt{counteraux} does: the queue which feeds \cs{printpostnotes}
+is built from the calls of \cs{post at note} in the \file{.aux} file and the
+counter is also stepped, as appropriate, at the same time.  Technically, I
+should say ``a counter'', which is then used to locally set the value of the
+user facing counter, \texttt{postnote}, at the moment \cs{postnote} is called,
+with a cross-reference of sorts.
+
+Some differences.  In the standard behavior, a \cs{postnote} inside a float
+belongs where the float environment was set, because that's where the
+numbering of the note is defined.  With \opt{counteraux}, a \cs{postnote}
+inside a float belongs where the float ends up being typeset, and for the same
+reason.  This means a note inside a float may float past a subsequent call of
+\cs{printpostnotes}, and will belong to the next call.  That's actually neat,
+and I'd call it a feature.  But you should be mindful of the warning for
+``stray notes'' issued at \texttt{enddocument} by the package, and make sure
+to extinguish your floats before a final \cs{printpostnotes}.  A limitation of
+the package's design is that the opposite cannot occur, if a note inside a
+float goes to the top of the page and happens to be typeset before a
+\cs{printpostnotes} which actually precedes it, the information to print the
+note is not available, so it's still left for the next call, but the numbering
+will be off.
+
+Some inconveniences.  You cannot set the counter directly, as you normally
+would.  Also \cs{counterwithin} will not affect the counter being stepped in
+the \file{.aux} file.  \pkg{postnotes} offers \cs{pnsetcounteraux} and
+\cs{pnaddtocounteraux} for the purpose.  But, normally, all you should ever
+need is a \texttt{\textbackslash{}pnsetcounteraux\{0\}} when splitting
+sections for your notes.  Also, the heavy reliance on labels will normally
+require one additional compilation run, and some possible transitory content
+swings.
+
+Some caveats.  I mentioned above that, in the case of multiple passes handled
+with the \opt{maybemulti} method, it is hard to ensure the value of the
+counter is correct for the measuring pass(es).  \opt{counteraux} makes this
+issue worse, because even in the cases where we can identify the measuring
+pass, we can't ensure the correct value, since the sequence of the passes is
+lost in the \file{.aux} file.  Indeed, the measuring passes do not even exist
+there, and we cannot, in general, reestablish the connection the original
+sequence offered.  Fortunately, there is a reasonable way around it.  If a
+\cs{postnote} sets a label (through the \opt{label} option of the note, not
+inside the content), the connection can be reestablished.  ``Connection'' is
+perhaps too much of a word for this, it's simpler.  With the label, a
+cross-reference to the mark is available, which can then be fed to the
+measuring pass.  And we know that value to be correct, because the label
+belongs to the pass which is actually typeset.  In sum, if some measuring
+problems do occur, set a label for the note, even if you do not refer to it,
+\pkg{postnotes} will use it.  Alas, if you are unlucky enough, you may even
+find yourself stuck in an infinite loop.\footnote{In a situation similar to
+  \pkg{varioref}, but in the choice of which pass is the measuring and which
+  is the final, instead of the reference crossing page boundaries.  However,
+  given the typical width of a mark, and the even smaller variations of those
+  widths which may result from floating, I expect the likelihood of meeting
+  such case in practice to be narrow.  There is no attempt to warn about this
+  here though, as \pkg{varioref} does, and probably no way to do it either.}
+In this case, setting the label is no relief, and the alternatives I can think
+of are either using a manual mark with \cs{pnaddtocounteraux} or a
+\opt{nomark} \cs{postnote} with \cs{postnoteref}.
+
+
 \section{Acknowledgments}
 
 Some people have kindly contributed to \pkg{postnotes}.  Suggestions, ideas,
@@ -1093,6 +1352,10 @@
   % 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)
+  % 2024-10-17: https://chat.stackexchange.com/transcript/message/66456022#66456022
+  % 2024-10-22: https://github.com/gusbrs/postnotes/issues/8#issuecomment-2429501962
+  % 2024-10-25: https://chat.stackexchange.com/transcript/message/66510334#66510334 (discussion)
+  % 2024-11-03: https://chat.stackexchange.com/transcript/message/66554870#66554870 (discussion)
   David Carlisle,
   % 2022-03-28: https://chat.stackexchange.com/transcript/message/60754383#60754383
   % 2022-04-08: https://tex.stackexchange.com/a/640035 (comments)
@@ -1110,8 +1373,14 @@
   \username{SwitWu},
   % 2023-11-29: https://github.com/gusbrs/postnotes/pull/4
   % 2023-11-30: https://github.com/gusbrs/postnotes/pull/5
-  and Jonathan P. Spratte (\username{Skillmon}).
+  Jonathan P. Spratte, % @Skillmon
   % 2023-12-12: https://chat.stackexchange.com/transcript/message/64848034#64848034 (and discussion)
+  Clea F. Rees, % @cfr
+  % 2024-10-24: https://chat.stackexchange.com/transcript/message/66493234#66493234 (discussion)
+  Romano Giannetti, % @Rmano
+  % 2024-10-24: https://chat.stackexchange.com/transcript/message/66493234#66493234 (discussion)
+  and Frank Mittelbach.
+  % 2024-10-29: https://github.com/latex3/latex2e/issues/1514#issuecomment-2444889179
 
 The package's language support have been provided or improved thanks to:
   \username{Pika78} (French)

Modified: trunk/Master/texmf-dist/source/latex/postnotes/postnotes.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/postnotes/postnotes.dtx	2024-11-05 20:18:50 UTC (rev 72769)
+++ trunk/Master/texmf-dist/source/latex/postnotes/postnotes.dtx	2024-11-05 20:18:59 UTC (rev 72770)
@@ -153,7 +153,7 @@
 %
 %
 %    \begin{macrocode}
-\ProvidesExplPackage {postnotes} {2024-10-15} {0.3.0}
+\ProvidesExplPackage {postnotes} {2024-11-04} {0.4.0}
   {Endnotes for LaTeX}
 %    \end{macrocode}
 %
@@ -163,6 +163,7 @@
 %      \l_@@_tmpa_tl ,
 %      \l_@@_tmpb_tl ,
 %      \l_@@_tmpa_seq ,
+%      \l_@@_tmpb_seq ,
 %      \l_@@_tmpa_box ,
 %   }
 %   Temporary scratch variables.
@@ -170,6 +171,7 @@
 \tl_new:N \l_@@_tmpa_tl
 \tl_new:N \l_@@_tmpb_tl
 \seq_new:N \l_@@_tmpa_seq
+\seq_new:N \l_@@_tmpb_seq
 \box_new:N \l_@@_tmpa_box
 %    \end{macrocode}
 % \end{macro}
@@ -295,25 +297,70 @@
 % \end{macro}
 %
 %
-% \begin{macro}[int]{\post at note}
-%   The \cs{newlabel} equivalent for \pkg{postnotes}.  Based on the kernel's
-%   \cs{@newl at bel} so that we get \LaTeX{} checks for multiple and changed
-%   references for free (procedure learnt from \pkg{zref}).  \cs{post at note},
-%   when the \file{.aux} file is read, defines macros named
-%   \texttt{\textbackslash{}postnote at r@\meta{label name}}, according to the
-%   prefix set by \cs{c_@@_ref_prefix_tl}.
+% \begin{macro}[int]
+%   {
+%     \post at note ,
+%     \@@_store_labelseq:nn ,
+%     \@@_step_counteraux:nnn ,
+%   }
+%   \cs{post at note} is the \cs{newlabel} equivalent for \pkg{postnotes}.
+%   Based on the kernel's \cs{@newl at bel} so that we get \LaTeX{} checks for
+%   multiple and changed references for free (procedure learnt from
+%   \pkg{zref}).  \cs{post at note}, when the \file{.aux} file is read, defines
+%   macros named \texttt{\textbackslash{}postnote at r@\meta{label
+%   type}@\meta{id}}, according to the prefix set by \cs{c_@@_ref_prefix_tl}.
+%   \cs{@@_store_labelseq:nn} is an auxiliary function to store the sequence
+%   of the labels in the \file{.aux} file, used to check for possible sorting
+%   problems due to floats. \cs{@@_step_counteraux:nnn} handles counter
+%   stepping and storing for the \opt{counteraux} option.
 %     \begin{syntax}
-%       \cs{post at note} \Arg{label name} \Arg{label content}
+%       \cs{post at note} \Arg{label type} \Arg{id} \Arg{label content (page)}
+%       ~~\Arg{counteraux step}
+%       \cs{@@_store_labelseq:nn} \Arg{label type} \Arg{id}
+%       \cs{@@_step_counteraux:nnn} \Arg{label type} \Arg{id}
+%       ~~\Arg{counteraux step}
 %     \end{syntax}
 %    \begin{macrocode}
 \tl_const:Nn \c_@@_ref_prefix_tl { postnote at r }
-\cs_new_protected:Npe \post at note #1#2
-  { \exp_not:N \@newl at bel { \c_@@_ref_prefix_tl } {#1} {#2} }
+\seq_new:N \g_@@_labelseq_seq
+\int_new:N \g_@@_postnote_counteraux_int
+\prop_new:N \g_@@_counteraux_prop
+\bool_new:N \g_@@_firstrun_bool
+\bool_gset_true:N \g_@@_firstrun_bool
+\cs_new_protected:Npn \@@_store_labelseq:nn #1#2
+  {
+    \bool_lazy_any:nT
+      {
+        { \str_if_eq_p:nn {#1} { mark } }
+        { \str_if_eq_p:nn {#1} { section } }
+        { \str_if_eq_p:nn {#1} { preprint } }
+      }
+      { \seq_gput_right:Nn \g_@@_labelseq_seq { {#1} {#2} } }
+  }
+\cs_new_protected:Npn \@@_step_counteraux:nnn #1#2#3
+  {
+    \bool_lazy_and:nnT
+      { \g_@@_counteraux_bool }
+      { \str_if_eq_p:nn {#1} { mark } }
+      {
+        \int_gadd:Nn \g_@@_postnote_counteraux_int { #3 }
+        \prop_gput:Nne \g_@@_counteraux_prop { #2 }
+          { \int_use:N \g_@@_postnote_counteraux_int }
+      }
+  }
+\cs_new_protected:Npe \post at note #1#2#3#4
+  {
+    \exp_not:N \bool_gset_false:N \exp_not:N \g_@@_firstrun_bool
+    \exp_not:N \@@_store_labelseq:nn { #1 } { #2 }
+    \exp_not:N \@@_step_counteraux:nnn { #1 } { #2 } { #4 }
+    \exp_not:N \@newl at bel { \c_@@_ref_prefix_tl } { #1 @ #2 } { #3 }
+  }
 %    \end{macrocode}
 % \end{macro}
 %
-% And ensure \cs{post at note} is defined in the \file{.aux} file.  The hooks are
-% the same used by \pkg{hyperref} for similar purpose.
+% And ensure \cs{post at note}, \cs{postnote at setcounteraux}, and
+% \cs{postnote at addtocounteraux} are defined in the \file{.aux} file.  The
+% hooks are the same used by \pkg{hyperref} for similar purpose.
 %
 %    \begin{macrocode}
 \AddToHook { begindocument }
@@ -321,7 +368,20 @@
     \legacy_if:nT { @filesw }
       {
         \iow_now:Ne \@mainaux
-          { \token_to_str:N \providecommand \token_to_str:N \post at note [2]{} }
+          {
+            \token_to_str:N \providecommand
+            \token_to_str:N \post at note [4] { }
+          }
+        \iow_now:Ne \@mainaux
+          {
+            \token_to_str:N \providecommand
+            \token_to_str:N \postnote at setcounteraux [1] { }
+          }
+        \iow_now:Ne \@mainaux
+          {
+            \token_to_str:N \providecommand
+            \token_to_str:N \postnote at addtocounteraux [1] { }
+          }
       }
   }
 \AddToHook { include/before }
@@ -328,8 +388,21 @@
   {
     \legacy_if:nT { @filesw }
       {
-        \iow_now:Ne \@partaux
-          { \token_to_str:N \providecommand \token_to_str:N \post at note [2]{} }
+        \iow_now:Ne \@mainaux
+          {
+            \token_to_str:N \providecommand
+            \token_to_str:N \post at note [4] { }
+          }
+        \iow_now:Ne \@mainaux
+          {
+            \token_to_str:N \providecommand
+            \token_to_str:N \postnote at setcounteraux [1] { }
+          }
+        \iow_now:Ne \@mainaux
+          {
+            \token_to_str:N \providecommand
+            \token_to_str:N \postnote at addtocounteraux [1] { }
+          }
       }
   }
 %    \end{macrocode}
@@ -337,38 +410,49 @@
 %
 % \begin{macro}
 %   {
-%     \@@_set_label:nn ,
-%     \@@_set_mark_page_label:n ,
+%     \@@_set_label:nnnn ,
+%     \@@_set_mark_page_label:nn ,
+%     \@@_set_section_page_label:n ,
 %     \@@_set_text_page_label:n ,
 %     \@@_set_print_page_label:n ,
+%     \@@_set_pre_print_label:n ,
 %   }
 %   Label setting functions for each pertinent context.  They must use
-%   \cs{iow_shipout_x:Nn}, since the main information we are interested in is
+%   \cs{iow_shipout_e:Nn}, since the main information we are interested in is
 %   the \texttt{page}.
 %     \begin{syntax}
-%       \cs{@@_set_label:nn} \Arg{label name} \Arg{value}
-%       \cs{@@_set_mark_page_label:n} \Arg{note id}
+%       \cs{@@_set_label:nnnn} \Arg{label type} \Arg{note id} \Arg{value}
+%       ~~\Arg{counteraux step}
+%       \cs{@@_set_mark_page_label:nn} \Arg{note id} \Arg{counteraux step}
+%       \cs{@@_set_section_page_label:n} \Arg{note id}
 %       \cs{@@_set_text_page_label:n} \Arg{note id}
 %       \cs{@@_set_print_page_label:n} \Arg{note id}
+%       \cs{@@_set_pre_print_label:n} \Arg{note id}
 %     \end{syntax}
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_set_label:nn #1#2
+\cs_new_protected:Npn \@@_set_label:nnnn #1#2#3#4
   {
     \legacy_if:nT { @filesw }
       {
-        \iow_shipout_x:Nn \@auxout
-          { \token_to_str:N \post at note { #1 } { #2 } }
+        \iow_shipout_e:Nn \@auxout
+          { \token_to_str:N \post at note { #1 } { #2 } { #3 } { #4 } }
       }
   }
-\cs_new_protected:Npn \@@_set_mark_page_label:n #1
-  { \@@_set_label:nn { mark@ #1 } { \thepage } }
-\cs_generate_variant:Nn \@@_set_mark_page_label:n { e }
+\cs_new_protected:Npn \@@_set_mark_page_label:nn #1#2
+  { \@@_set_label:nnnn { mark } { #1 } { \thepage } { #2 } }
+\cs_generate_variant:Nn \@@_set_mark_page_label:nn { ee }
+\cs_new_protected:Npn \@@_set_section_page_label:n #1
+  { \@@_set_label:nnnn { section } { #1 } { \thepage } { } }
+\cs_generate_variant:Nn \@@_set_section_page_label:n { e }
 \cs_new_protected:Npn \@@_set_text_page_label:n #1
-  { \@@_set_label:nn { text@ #1 } { \int_use:N \c at page } }
+  { \@@_set_label:nnnn { text } { #1 } { \int_use:N \c at page } { } }
 \cs_generate_variant:Nn \@@_set_text_page_label:n { e }
 \cs_new_protected:Npn \@@_set_print_page_label:n #1
-  { \@@_set_label:nn { print@ #1 } { \int_use:N \c at page } }
+  { \@@_set_label:nnnn { print } { #1 } { \int_use:N \c at page } { } }
 \cs_generate_variant:Nn \@@_set_print_page_label:n { e }
+\cs_new_protected:Npn \@@_set_pre_print_label:n #1
+  { \@@_set_label:nnnn { preprint } { #1 } { } { } }
+\cs_generate_variant:Nn \@@_set_pre_print_label:n { e }
 %    \end{macrocode}
 % \end{macro}
 %
@@ -564,6 +648,47 @@
 %    \end{macrocode}
 %
 %
+% \subsection*{\opt{style} option}
+%
+%    \begin{macrocode}
+\keys_define:nn { postnotes/setup }
+  {
+    style .choice: ,
+    style / endnotes .meta:n =
+      {
+        listenv = none ,
+        format =
+          {
+            \footnotesize
+            \setlength { \rightskip } { 0pt   }
+            \setlength { \leftskip  } { 0pt   }
+            \setlength { \parindent } { 1.8em }
+          } ,
+%    \end{macrocode}
+% \pkg{endnotes} uses a zero width box to get the desired alignment to the
+% right, but that does not play well with the backlinks, so we have a little
+% more work to do to get this right.
+%    \begin{macrocode}
+        maketextmark =
+          {
+            \hbox_set:Nn \l_@@_tmpa_box
+              { \@textsuperscript { \normalfont ##1 } }
+            \skip_horizontal:n { - \box_wd:N \l_@@_tmpa_box }
+            ##2 \box_use:N \l_@@_tmpa_box ##3
+          } ,
+      } ,
+    style / pagenote .meta:n =
+      {
+        listenv = none ,
+        format = { } ,
+        pretextmark = { \noindent } ,
+        maketextmark = { { \normalfont ##2 ##1 . ##3 } } ,
+        posttextmark = { ~ } ,
+      } ,
+  }
+%    \end{macrocode}
+%
+%
 % \subsection*{\opt{hyperref} and \opt{backlink} options}
 %
 %    \begin{macrocode}
@@ -696,87 +821,60 @@
 % 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
+\bool_new:N \l_@@_multiple_bool
 \tl_new:N \l_@@_saved_spacefactor_multi_tl
 \keys_define:nn { postnotes/setup }
   {
-    multiple .choice: ,
-    multiple / true .code:n =
-      {
+    multiple .bool_set:N = \l_@@_multiple_bool ,
+    multiple .default:n = true ,
+    multiple .initial:n = false ,
+    multisep .tl_set:N = \l_@@_multisep_tl ,
+    multisep .value_required:n = true ,
+    multisep .initial: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 }
+\cs_new_protected:Npn \@@_multiple_prepare:
+  {
+    \bool_if:NT \l_@@_multiple_bool
+      {
+        \kern -\c_postnotes_multi_notemarker_tl
+        \kern  \c_postnotes_multi_notemarker_tl
+        \scan_stop:
+      }
+  }
 %    \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.
+% Note that \cs{@@_multiple_check:} has to be called before any whatsits
+% (labels, anchors, etc.) are placed, since they destroy \cs{lastkern} (see
+% \url{https://chat.stackexchange.com/transcript/message/66554870#66554870},
+% thanks \contributor{Ulrike Fischer}).
 %    \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:
+\cs_new_protected:Npn \@@_multiple_check:
+  {
+    \bool_if:NT \l_@@_multiple_bool
+      {
+        \dim_compare:nNnT
+          { \c_postnotes_multi_notemarker_tl } = { \lastkern }
           {
-            \dim_set_eq:NN \l_@@_multi_lastkern_dim \lastkern
-            \bool_set_true:N \l_@@_multi_stored_lastkern_bool
+            \tl_set:Ne \l_@@_saved_spacefactor_multi_tl
+              { \int_use:N \spacefactor }
+            \unkern
+            \unkern
+            \tag_socket_use:n { postnotes/multisep/begin }
+            \@@_make_mark:Vnn \l_@@_multisep_tl { } { }
+            \tag_socket_use:n { postnotes/multisep/end }
+            \spacefactor \l_@@_saved_spacefactor_multi_tl
+            \scan_stop:
           }
-      } ,
-    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}
 %
 %
@@ -793,48 +891,109 @@
 %    \end{macrocode}
 %
 %
-% \subsection*{\opt{style} option}
+% \subsection*{\opt{checkduplicates} and \opt{checkfloats} options}
 %
 %    \begin{macrocode}
+\bool_new:N \l_@@_check_dupli_bool
+\bool_new:N \l_@@_check_floats_bool
 \keys_define:nn { postnotes/setup }
   {
-    style .choice: ,
-    style / endnotes .meta:n =
+    checkduplicates .bool_set:N = \l_@@_check_dupli_bool ,
+    checkduplicates .default:n = true ,
+    checkduplicates .initial:n = true ,
+    checkfloats .bool_set:N = \l_@@_check_floats_bool ,
+    checkfloats .default:n = true ,
+    checkfloats .initial:n = false ,
+  }
+%    \end{macrocode}
+%
+%
+% \subsection*{\opt{maybemulti} option}
+%
+%    \begin{macrocode}
+\bool_new:N \l_@@_maybe_multi_bool
+\keys_define:nn { postnotes/setup }
+  {
+    maybemulti .bool_set:N = \l_@@_maybe_multi_bool ,
+    maybemulti .default:n = true ,
+    maybemulti .initial:n = false ,
+  }
+%    \end{macrocode}
+%
+%
+% \subsection*{\opt{counteraux} option}
+%
+%    \begin{macrocode}
+\bool_new:N \g_@@_counteraux_bool
+\keys_define:nn { postnotes/setup }
+  {
+    counteraux .bool_gset:N = \g_@@_counteraux_bool ,
+    counteraux .default:n = true ,
+    counteraux .initial:n = false ,
+  }
+%    \end{macrocode}
+%
+%
+%    \begin{macrocode}
+\AddToHook { begindocument/before }
+  {
+    \bool_if:NT \g_@@_counteraux_bool
+      { \postnotesetup { sort=false } }
+    \keys_define:nn { postnotes/setup }
       {
-        listenv = none ,
-        format =
+        counteraux .code:n =
           {
-            \footnotesize
-            \setlength { \rightskip } { 0pt   }
-            \setlength { \leftskip  } { 0pt   }
-            \setlength { \parindent } { 1.8em }
+            \msg_warning:nnn { postnotes }
+              { option-preamble-only } { counteraux }
           } ,
-        pretextmark = { \par } ,
+      }
+  }
 %    \end{macrocode}
-% \pkg{endnotes} uses a zero width box to get the desired alignment to the
-% right, but that does not play well with the backlinks, so we have a little
-% more work to do to get this right.
+%
+%
+% \begin{macro}[int]
+%   {
+%     \pnsetcounteraux ,
+%     \pnaddtocounteraux ,
+%     \postnote at setcounteraux ,
+%     \postnote at addtocounteraux ,
+%   }
+%   \begin{syntax}
+%     \cs{pnsetcounteraux}\marg{int}
+%     \cs{pnaddtocounteraux}\marg{int}
+%     \cs{postnote at setcounteraux}\marg{int}
+%     \cs{postnote at addtocounteraux}\marg{int}
+%   \end{syntax}
 %    \begin{macrocode}
-        maketextmark =
-         {
-           \hbox_set:Nn \l_@@_tmpa_box
-             { \@textsuperscript { \normalfont ##1 } }
-           \skip_horizontal:n { - \box_wd:N \l_@@_tmpa_box }
-           ##2 \box_use:N \l_@@_tmpa_box ##3
-         } ,
-      } ,
-    style / pagenote .meta:n =
+\cs_new_protected:Npn \postnote at setcounteraux #1
+  { \int_gset:Nn \g_@@_postnote_counteraux_int { #1 } }
+\cs_new_protected:Npn \postnote at addtocounteraux #1
+  { \int_gadd:Nn \g_@@_postnote_counteraux_int { #1 } }
+\NewDocumentCommand \pnsetcounteraux { m }
+  {
+    \@bsphack
+    \legacy_if:nT { @filesw }
       {
-        listenv = none ,
-        format = { } ,
-        pretextmark = { \par\noindent } ,
-        maketextmark = { { \normalfont ##2 ##1 . ##3 } } ,
-        posttextmark = { ~ } ,
-      } ,
+        \iow_shipout_e:Nn \@auxout
+          { \token_to_str:N \postnote at setcounteraux { #1 } }
+      }
+    \@esphack
   }
+\NewDocumentCommand \pnaddtocounteraux { m }
+  {
+    \@bsphack
+    \legacy_if:nT { @filesw }
+      {
+        \iow_shipout_e:Nn \@auxout
+          { \token_to_str:N \postnote at addtocounteraux { #1 } }
+      }
+    \@esphack
+  }
 %    \end{macrocode}
+% \end{macro}
 %
 %
+%
 % \subsection*{\cs{postnotesetup}}
 %
 %
@@ -1010,11 +1169,14 @@
 \newcounter { postnote }
 %    \end{macrocode}
 %
-% \begin{macro}
+% \begin{macro}[int]
 %   {
 %     \g_@@_note_id_int ,
 %     \l_postnotes_note_id_tl ,
 %     \g_@@_queue_seq ,
+%     \l_@@_counteraux_step_int ,
+%     \l_@@_mark_typeset_tl ,
+%     \l_@@_note_set_labels_tl ,
 %   }
 %   \cs{g_@@_note_id_int} is the internal, unique counter which provides the
 %   ID number of each note.  It ties ``mark'' and ``text'' together, is also
@@ -1028,6 +1190,9 @@
 \tl_new:N \l_postnotes_note_id_tl
 \tl_set:Nn \l_postnotes_note_id_tl { \int_use:N \g_@@_note_id_int }
 \seq_new:N \g_@@_queue_seq
+\int_new:N \l_@@_counteraux_step_int
+\tl_new:N \l_@@_mark_typeset_tl
+\tl_new:N \l_@@_note_set_labels_tl
 %    \end{macrocode}
 % \end{macro}
 %
@@ -1035,7 +1200,7 @@
 % \begin{macro}[int]{\postnote}
 %   Provide \cs{postnote}.
 %   \begin{syntax}
-%     \cs{postnote} \oarg{options} \marg{note text}
+%     \cs{postnote}\oarg{options}\marg{note text}
 %   \end{syntax}
 %    \begin{macrocode}
 \NewDocumentCommand \postnote { O { } +m }
@@ -1051,7 +1216,7 @@
 %   features/packages, but can also be used, for example, to add an extra
 %   local property for \pkg{zref}.
 %   \begin{syntax}
-%     \cs{@@_note:nn}\oarg{options}\marg{note content}
+%     \cs{@@_note:nn} \oarg{options} \marg{note content}
 %   \end{syntax}
 %    \begin{macrocode}
 \NewHook { postnotes/note/begin }
@@ -1058,32 +1223,68 @@
 \cs_new_protected:Npn \@@_note:nn #1#2
   {
     \group_begin:
-    \@@_multiple_store_lastkern:
-    \keys_set:nn { postnotes/note } {#1}
-    \@@_inhibit_note:F
-      {
-        \int_gincr:N \g_@@_note_id_int
-        \tl_if_empty:NT \l_@@_mark_tl
-          {
-            \stepcounter { postnote }
-            \tl_set:Ne \l_@@_mark_tl { \thepostnote }
-          }
-        \seq_gput_right:Ne \g_@@_queue_seq
-          { \l_postnotes_note_id_tl }
-        \UseHook { postnotes/note/begin }
-        \cs_set:Npn \@currentcounter { postnote }
-        \cs_set:Npe \@currentlabel { \p at postnote \l_@@_mark_tl }
-        \MakeLinkTarget* { postnote. \l_postnotes_note_id_tl .mark }
-        \@@_set_mark_page_label:e { \l_postnotes_note_id_tl }
-        \@@_set_user_labels:
-        \@@_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
-          }
-      }
+      \keys_set:nn { postnotes/note } {#1}
+      \bool_if:NT \l_@@_nomark_bool { \@bsphack }
+      \@@_inhibit_note:F
+        {
+          \int_gincr:N \g_@@_note_id_int
+          \tl_if_empty:NTF \l_@@_mark_tl
+            {
+              \stepcounter { postnote }
+              \int_set:Nn \l_@@_counteraux_step_int { 1 }
+              \bool_if:NT \g_@@_counteraux_bool
+                {
+                  \exp_args:NNe \prop_gpop:NnNT \g_@@_counteraux_prop
+                    { \l_postnotes_note_id_tl } \l_@@_tmpa_tl
+                    { \int_set:Nn \c at postnote { \l_@@_tmpa_tl } }
+                  \tl_clear:N \l_@@_tmpa_tl
+                }
+              \tl_set:Ne \l_@@_mark_tl { \thepostnote }
+            }
+            { \int_set:Nn \l_@@_counteraux_step_int { 0 } }
+          \UseHook { postnotes/note/begin }
+          \seq_gput_right:Ne \g_@@_queue_seq
+            { \l_postnotes_note_id_tl }
+          \cs_set:Npn \@currentcounter { postnote }
+          \cs_set:Npe \@currentlabel { \p at postnote \l_@@_mark_tl }
+          \@@_store:nn { \l_postnotes_note_id_tl } {#2}
+          \tl_set_eq:NN \l_@@_mark_typeset_tl \l_@@_mark_tl
+%    \end{macrocode}
+% Prefer \opt{label} for typesetting measuring passes, if available, see
+% comments at \cs{@@_inhibit_note:F}.
+%    \begin{macrocode}
+          \bool_lazy_or:nnT
+            { \g_@@_counteraux_bool }
+            { \l_@@_maybe_multi_bool }
+            {
+              \bool_lazy_and:nnT
+                { ! \g_@@_firstrun_bool }
+                {
+                  ! \cs_if_exist_p:c
+                    { \c_@@_ref_prefix_tl @ mark @ \l_postnotes_note_id_tl }
+                }
+                { \@@_get_label_if_exist:N \l_@@_mark_typeset_tl }
+            }
+          \tl_set:Nn \l_@@_note_set_labels_tl
+            {
+              \MakeLinkTarget* { postnote. \l_postnotes_note_id_tl .mark }
+              \@@_set_mark_page_label:ee { \l_postnotes_note_id_tl }
+                { \int_use:N \l_@@_counteraux_step_int }
+              \@@_set_user_labels:
+            }
+          \bool_if:NTF \l_@@_nomark_bool
+            {
+              \tag_socket_use:n { postnotes/nomark/begin }
+              \l_@@_note_set_labels_tl
+              \tag_socket_use:n { postnotes/nomark/end }
+            }
+            {
+              \@@_typeset_mark:eVN
+                { \l_postnotes_note_id_tl } \l_@@_mark_typeset_tl
+                \l_@@_note_set_labels_tl
+            }
+        }
+      \bool_if:NT \l_@@_nomark_bool { \@esphack }
     \group_end:
   }
 %    \end{macrocode}
@@ -1096,9 +1297,8 @@
 \tl_new:N \l_@@_mark_tl
 \bool_new:N \l_@@_nomark_bool
 \fp_new:N \l_@@_sort_num_fp
-\tl_new:N \l_@@_note_label_tl
+\str_new:N \l_@@_note_label_str
 \bool_new:N \l_@@_manual_sortnum_bool
-\bool_new:N \l_@@_maybe_multi_bool
 \keys_define:nn { postnotes/note }
   {
     markstr .tl_set:N = \l_@@_mark_tl ,
@@ -1117,8 +1317,10 @@
     mark .value_required:n = true ,
     nomark .bool_set:N = \l_@@_nomark_bool ,
     nomark .default:n = true ,
-    label .tl_set:N = \l_@@_note_label_tl ,
+    label .str_set:N = \l_@@_note_label_str ,
     label .value_required:n = true ,
+    maybemulti .bool_set:N = \l_@@_maybe_multi_bool ,
+    maybemulti .default:n = true ,
   }
 %    \end{macrocode}
 %
@@ -1157,29 +1359,49 @@
 % counter had been stepped, we increment \cs{c at postnote} locally and grouped,
 % and smuggle \cs{thepostnote} out of the group.
 %    \begin{macrocode}
-    \bool_if:NT \l_@@_print_plain_mark_bool
+    \bool_lazy_all:nT
       {
-        \tl_if_empty:NT \l_@@_mark_tl
+        { \l_@@_inhibit_note_bool }
+        { \l_@@_print_plain_mark_bool }
+        { ! \l_@@_nomark_bool }
+      }
+      {
+        \tl_if_empty:NTF \l_@@_mark_tl
           {
             \bool_if:NTF \l_@@_print_plain_mark_stepcounter_bool
               {
                 \stepcounter { postnote }
-                \tl_set:Ne \l_@@_mark_tl { \thepostnote }
+                \tl_set:Ne \l_@@_mark_typeset_tl { \thepostnote }
               }
               {
                 \group_begin:
-                \int_incr:N \c at postnote
-                \exp_args:NNNe
-                  \group_end:
-                  \tl_set:Nn \l_@@_mark_tl { \thepostnote }
+                  \int_incr:N \c at postnote
+                  \exp_args:NNNe
+                    \group_end:
+                    \tl_set:Nn \l_@@_mark_typeset_tl { \thepostnote }
               }
+%    \end{macrocode}
+% If the note has a \opt{label}, use a cross-reference to that as the mark
+% instead.  In principle, the procedure above is expected to work reasonably
+% well for cases where we know whether we are in a measuring pass or not, and
+% how it handles the counters (if it restores counters or not).  This is true
+% though, only if we are going in the expansion order of the document.  If we
+% are using the \opt{counteraux} option, the mere sequence of the notes is no
+% longer an indicator of who is a measuring pass of who, indeed the measuring
+% pass does not even get to the \file{.aux} file.  If the label exists,
+% though, it is \emph{known to be right} regardless of the case, since it
+% belongs to the pass which actually gets typeset.  Hence, if we have a label,
+% it is more general and more reliable: use it.
+%    \begin{macrocode}
+            \@@_get_label_if_exist:N \l_@@_mark_typeset_tl
           }
+          { \tl_set_eq:NN \l_@@_mark_typeset_tl \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 { } { } }
-          { } { }
+          \socket_assign_plug:nn { tagsupport/postnotes/multisep/begin } { noop }
+          \socket_assign_plug:nn { tagsupport/postnotes/multisep/end } { noop }
+          \@@_typeset_mark_wrapper:nnn
+            { \@@_make_mark:Vnn \l_@@_mark_typeset_tl { } { } }
+            { } { }
         \group_end:
       }
     \bool_if:NTF \l_@@_inhibit_note_bool
@@ -1189,10 +1411,54 @@
 %    \end{macrocode}
 % \end{macro}
 %
+% \begin{macro}{\@@_get_label_if_exist:N}
+%   \begin{syntax}
+%     \cs{@@_get_label_if_exist:N} \meta{\cs{l_@@_mark_tl}}
+%   \end{syntax}
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_get_label_if_exist:N #1
+  {
+    \str_if_empty:NTF \l_@@_note_label_str
+      {
+        \str_if_empty:NF \l_@@_note_zlabel_str
+          {
+            \exp_args:NV \zref at ifrefundefined \l_@@_note_zlabel_str
+              { }
+              {
+                \exp_args:NV \zref at ifrefcontainsprop
+                  \l_@@_note_zlabel_str
+                  { postnote at mark }
+                  {
+                    \exp_args:NNNo \exp_args:NNo \tl_set:Nn #1
+                      {
+                        \zref at extract
+                          { \l_@@_note_zlabel_str } { postnote at mark }
+                      }
+                  }
+                  { }
+              }
+          }
+      }
+      {
+        \exp_args:Ne \property_if_recorded:nnT
+          { postnotes@ \l_@@_note_label_str }
+          { postnotes/mark }
+          {
+            \tl_set:Ne #1
+              {
+                \property_ref:ee
+                  { __postnotes_ \l_@@_note_label_str } { postnotes/mark }
+              }
+          }
+      }
+  }
+%    \end{macrocode}
+% \end{macro}
 %
+%
 % \begin{macro}
 %   {
-%     \@@_typeset_mark:nn ,
+%     \@@_typeset_mark:nnN ,
 %     \@@_typeset_mark_wrapper:nnn ,
 %   }
 %   Auxiliary functions for mark typesetting in \cs{@@_note:nn}.
@@ -1199,15 +1465,16 @@
 %   \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:nnn}
-%       \Arg{mark} \Arg{begin tagging} \Arg{end tagging}
+%     \cs{@@_typeset_mark:nnN} \Arg{note id} \Arg{mark} \Arg{labels}
+%     \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
+\cs_new_protected:Npn \@@_typeset_mark:nnN #1#2#3
   {
     \@@_typeset_mark_wrapper:nnn
       {
+        #3
         \bool_if:NTF \l_@@_hyperlink_bool
           {
             \@@_make_mark:nnn {#2}
@@ -1219,7 +1486,7 @@
       { \tag_socket_use:n { postnotes/mark/begin } }
       { \tag_socket_use:n { postnotes/mark/end }   }
   }
-\cs_generate_variant:Nn \@@_typeset_mark:nn { eV }
+\cs_generate_variant:Nn \@@_typeset_mark:nnN { eVN }
 \tl_new:N \l_@@_saved_spacefactor_tl
 \cs_new_protected:Npn \@@_typeset_mark_wrapper:nnn #1#2#3
   {
@@ -1231,9 +1498,9 @@
         \@@_multiple_check:
         \nobreak
       }
-    #2 % begin tagging function
+    #2 % begin tagging socket
     #1 % mark
-    #3 % end tagging function
+    #3 % end tagging socket
     \@@_multiple_prepare:
     \mode_if_horizontal:T
       { \spacefactor \l_@@_saved_spacefactor_tl }
@@ -1249,11 +1516,16 @@
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_set_user_labels:
   {
-    \tl_if_empty:NF \l_@@_note_label_tl
-      { \exp_args:NV \label \l_@@_note_label_tl }
-    \tl_if_empty:NF \l_@@_note_zlabel_tl
-      { \exp_args:NV \zlabel \l_@@_note_zlabel_tl }
+    \str_if_empty:NF \l_@@_note_label_str
+      {
+        \exp_args:NV \label \l_@@_note_label_str
+        \property_record:ee { __postnotes_ \l_@@_note_label_str }
+          { postnotes/mark }
+      }
+    \str_if_empty:NF \l_@@_note_zlabel_str
+      { \exp_args:NV \zlabel \l_@@_note_zlabel_str }
   }
+\property_new:nnnn { postnotes/mark } { now } { } { \l_@@_mark_tl }
 %    \end{macrocode}
 % \end{macro}
 %
@@ -1281,20 +1553,20 @@
 \cs_new_protected:Npn \@@_note_ref:nn #1#2
   {
     \group_begin:
-    \tl_set:Nn \l_@@_note_ref_label_tl {#2}
-    \@@_typeset_mark_wrapper:nnn
-      {
-        \bool_lazy_and:nnTF
-          { ! #1 }
-          { \l_@@_hyperlink_bool }
-          {
-            \hyperref [#2]
-              { \@@_make_mark:nnn { \ref*{#2} } { } { } }
-          }
-          { \@@_make_mark:nnn { \ref*{#2} } { } { } }
-      }
-      { \tag_socket_use:n { postnotes/postnoteref/begin } }
-      { \tag_socket_use:n { postnotes/postnoteref/end }   }
+      \tl_set:Nn \l_@@_note_ref_label_tl {#2}
+      \@@_typeset_mark_wrapper:nnn
+        {
+          \bool_lazy_and:nnTF
+            { ! #1 }
+            { \l_@@_hyperlink_bool }
+            {
+              \hyperref [#2]
+                { \@@_make_mark:nnn { \ref*{#2} } { } { } }
+            }
+            { \@@_make_mark:nnn { \ref*{#2} } { } { } }
+        }
+        { \tag_socket_use:n { postnotes/postnoteref/begin } }
+        { \tag_socket_use:n { postnotes/postnoteref/end }   }
     \group_end:
   }
 %    \end{macrocode}
@@ -1303,30 +1575,18 @@
 %
 % \section{\cs{postnotesection}}
 %
-% \begin{macro}[int]
-%   {
-%     \postnotesection ,
-%     \postnotesectionx ,
-%   }
-%   Provide \cs{postnotesection} and \cs{postnotesectionx}.
+% \begin{macro}[int]{\postnotesection}
+%   Provide \cs{postnotesection}.
 %   \begin{syntax}
 %     \cs{postnotesection}\oarg{options}\marg{section content}
-%     \cs{postnotesectionx}\oarg{options}\marg{section content}
 %   \end{syntax}
 %    \begin{macrocode}
 \NewDocumentCommand \postnotesection { O { } +m }
-  { \@@_section:nn {#1} {#2} }
-\NewDocumentCommand \postnotesectionx { O { } +m }
   {
-    % NOTE Command deprecated in 2022-12-27 for v0.2.0.
-    \msg_warning:nn { postnotes } { postnotesectionx-deprecated }
-    \postnotesection [ #1 , exp ] {#2}
+    \@bsphack
+    \@@_section:nn {#1} {#2}
+    \@esphack
   }
-\msg_new:nnn { postnotes } { postnotesectionx-deprecated }
-  {
-    '\iow_char:N\\postnotesectionx'~is~deprecated~\msg_line_context:.~
-    Use~the~'exp'~option~of~'\iow_char:N\\postnotesection'~instead.
-  }
 %    \end{macrocode}
 % \end{macro}
 %
@@ -1340,14 +1600,15 @@
 \cs_new_protected:Npn \@@_section:nn #1#2
   {
     \group_begin:
-    \int_gincr:N \g_@@_sectid_int
-    \int_gincr:N \g_@@_note_id_int
-    \seq_gput_right:Ne \g_@@_queue_seq { \l_postnotes_note_id_tl }
-    \tl_gclear:N \g_@@_section_name_tl
-    \keys_set:nn { postnotes/section } {#1}
-    \bool_if:NTF \l_@@_section_exp_bool
-      { \@@_store_section:ne { \l_postnotes_note_id_tl } {#2} }
-      { \@@_store_section:nn { \l_postnotes_note_id_tl } {#2} }
+      \int_gincr:N \g_@@_sectid_int
+      \int_gincr:N \g_@@_note_id_int
+      \seq_gput_right:Ne \g_@@_queue_seq { \l_postnotes_note_id_tl }
+      \tl_gclear:N \g_@@_section_name_tl
+      \keys_set:nn { postnotes/section } {#1}
+      \@@_set_section_page_label:e { \l_postnotes_note_id_tl }
+      \bool_if:NTF \l_@@_section_exp_bool
+        { \@@_store_section:ne { \l_postnotes_note_id_tl } {#2} }
+        { \@@_store_section:nn { \l_postnotes_note_id_tl } {#2} }
     \group_end:
   }
 %    \end{macrocode}
@@ -1407,13 +1668,15 @@
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}
+% \begin{macro}[int]
 %   {
 %     \g_@@_print_postnotes_int ,
+%     \g_@@_print_queue_seq ,
 %     \l_postnotes_print_note_id_tl ,
 %     \l_@@_print_note_id_next_tl ,
 %     \l_@@_print_counter_tl ,
 %     \l_@@_print_mark_tl ,
+%     \l_@@_print_typeset_mark_tl ,
 %     \l_@@_print_type_curr_tl ,
 %     \l_@@_print_type_next_tl ,
 %     \l_@@_print_type_prev_tl ,
@@ -1423,10 +1686,12 @@
 %   Auxiliary variables for \cs{@@_print_notes:}.
 %    \begin{macrocode}
 \int_new:N \g_@@_print_postnotes_int
+\seq_new:N \g_@@_print_queue_seq
 \tl_new:N \l_postnotes_print_note_id_tl
 \tl_new:N \l_@@_print_note_id_next_tl
 \tl_new:N \l_@@_print_counter_tl
 \tl_new:N \l_@@_print_mark_tl
+\tl_new:N \l_@@_print_typeset_mark_tl
 \tl_new:N \l_@@_print_type_curr_tl
 \tl_new:N \l_@@_print_type_next_tl
 \tl_new:N \l_@@_print_type_prev_tl
@@ -1436,7 +1701,7 @@
 % \end{macro}
 %
 %
-% \cs{@@_print_notes:} hooks.  Both meant at providing points of entry for
+% \cs{@@_print_notes:}' hooks.  Both meant at providing points of entry for
 % additional setup, specially to add support to packages and features which
 % require it.  The \texttt{postnotes/print/begin} hook is run early in
 % \cs{@@_print_notes:} and only once per call, after the user options have
@@ -1491,21 +1756,51 @@
 \cs_new_protected:Npn \@@_print_notes:
   {
     \group_begin:
-    \int_gincr:N \g_@@_print_postnotes_int
-    \seq_if_empty:NTF \g_@@_queue_seq
-      { \msg_warning:nn { postnotes } { empty-printpostnotes } }
-      {
-        \pnheading
-        \UseHook { postnotes/print/begin }
-        \tl_set:Nn \l_@@_print_type_prev_tl { open }
-        \seq_set_eq:NN \l_@@_clear_queue_seq \g_@@_queue_seq
-        \@@_verify_multipass:N \g_@@_queue_seq
-        \bool_if:NT \l_@@_sort_bool
-          { \@@_sort_queue:N \g_@@_queue_seq }
-        \bool_gset_true:N \g_@@_header_vars_next_bool
-        \@@_get_headers_data:N \g_@@_queue_seq
-        \@@_set_headers_vars_first:
+      \int_gincr:N \g_@@_print_postnotes_int
+      \@@_split_labelseq:
 %    \end{macrocode}
+% We make the cut at this point.  \cs{g_@@_print_queue_seq} is stored won't
+% receive any more notes for the duration of this call of \cs{printpostnotes},
+% any notes added to the queue from this point on belong to the next call of
+% \cs{printpostnotes}.
+%    \begin{macrocode}
+      \bool_lazy_and:nnTF
+        { \g_@@_counteraux_bool }
+        { ! \g_@@_firstrun_bool }
+        {
+          \seq_gset_eq:NN \g_@@_print_queue_seq
+            \g_@@_print_labelseq_queue_seq
+        }
+        {
+          \seq_gset_eq:NN \g_@@_print_queue_seq
+            \g_@@_queue_seq
+        }
+      \seq_set_eq:NN \l_@@_clear_queue_seq \g_@@_print_queue_seq
+      \seq_gclear:N \g_@@_queue_seq
+%    \end{macrocode}
+% The  purpose of this label is to provide a point for splitting the labelseq
+% with the \opt{counteraux} option.  It only needs to exist, it doesn't even
+% store the page value.  The \cs{@@_set_print_page_label:e} done at
+% \cs{@@_set_headers_vars_first:} right below does not suffice for this
+% purpose for two reasons.  It won't be set if the queue is empty (or not yet
+% populated), and also it comes after the heading (as it must), which means
+% \cs{postnotesection}s added through hooks to it will come before it.
+%    \begin{macrocode}
+      \@@_set_pre_print_label:e
+        { \int_use:N \g_@@_print_postnotes_int }
+      \seq_if_empty:NTF \g_@@_print_queue_seq
+        { \msg_warning:nn { postnotes } { empty-printpostnotes } }
+        {
+          \pnheading
+          \UseHook { postnotes/print/begin }
+          \tl_set:Nn \l_@@_print_type_prev_tl { open }
+          \@@_check_duplicates:N \g_@@_print_queue_seq
+          \@@_sort_queue:N \g_@@_print_queue_seq
+          \@@_check_floats:N \g_@@_print_queue_seq
+          \bool_gset_true:N \g_@@_header_vars_next_bool
+          \@@_get_headers_data:N \g_@@_print_queue_seq
+          \@@_set_headers_vars_first:
+%    \end{macrocode}
 % Ensure the first note after a heading has paragraph indentation when
 % \opt{listenv} is \texttt{none}.  \pkg{endnotes} uses a workaroundish
 % solution in \cs{enoteheading}, setting a box and then skipping back a line.
@@ -1514,157 +1809,183 @@
 % suggests the use of \cs{@afterindenttrue}, which is what \pkg{indentfirst}
 % does (we do the same, just locally).
 %    \begin{macrocode}
-        \bool_if:NF \l_@@_print_as_list_bool
-          {
-            \cs_set_eq:NN \@afterindentfalse \@afterindenttrue
-            \@afterindenttrue
-          }
-        \bool_until_do:nn { \seq_if_empty_p:N \g_@@_queue_seq }
-          {
-            \seq_gpop_left:NN \g_@@_queue_seq
-              \l_postnotes_print_note_id_tl
-            \@@_prop_get:nnN { \l_postnotes_print_note_id_tl }
-              { type } \l_@@_print_type_curr_tl
-            \tl_if_eq:NnTF \l_@@_print_type_curr_tl { section }
-              { % type_curr = `section'
-                \seq_if_empty:NTF \g_@@_queue_seq
-                  {
-                    \tl_set:Nn \l_@@_print_note_id_next_tl { noid }
-                    \tl_set:Nn \l_@@_print_type_next_tl { close }
-                  }
-                  {
-                    \seq_get_left:NN \g_@@_queue_seq
-                      \l_@@_print_note_id_next_tl
-                    \@@_prop_get:nnN
-                      { \l_@@_print_note_id_next_tl }
-                      { type } \l_@@_print_type_next_tl
-                  }
+          \bool_if:NF \l_@@_print_as_list_bool
+            {
+              \cs_set_eq:NN \@afterindentfalse \@afterindenttrue
+              \@afterindenttrue
+            }
+          \bool_until_do:nn { \seq_if_empty_p:N \g_@@_print_queue_seq }
+            {
+              \seq_gpop_left:NN \g_@@_print_queue_seq
+                \l_postnotes_print_note_id_tl
+              \@@_prop_get:nnN { \l_postnotes_print_note_id_tl }
+                { type } \l_@@_print_type_curr_tl
+              \tl_if_eq:NnTF \l_@@_print_type_curr_tl { section }
+                { % type_curr = `section'
+                  \seq_if_empty:NTF \g_@@_print_queue_seq
+                    {
+                      \tl_set:Nn \l_@@_print_note_id_next_tl { noid }
+                      \tl_set:Nn \l_@@_print_type_next_tl { close }
+                    }
+                    {
+                      \seq_get_left:NN \g_@@_print_queue_seq
+                        \l_@@_print_note_id_next_tl
+                      \@@_prop_get:nnN
+                        { \l_@@_print_note_id_next_tl }
+                        { type } \l_@@_print_type_next_tl
+                    }
 %    \end{macrocode}
 % We only process the entry if \texttt{type_next} is \texttt{note}: here are
 % skipped empty sections.
 %    \begin{macrocode}
-                \tl_if_eq:NnT \l_@@_print_type_next_tl { note }
-                  {
-                    \stepcounter { postnotesection }
-                    \group_begin:
+                  \tl_if_eq:NnT \l_@@_print_type_next_tl { note }
+                    {
+                      \stepcounter { postnotesection }
+                      \group_begin:
+                        \@@_prop_get:nnN
+                          { \l_postnotes_print_note_id_tl }
+                          { thechapter } \pnthechapter
+                        \@@_prop_get:nnN
+                          { \l_postnotes_print_note_id_tl }
+                          { thesection } \pnthesection
+                        \tl_set:NV \pnidnextnote
+                          \l_@@_print_note_id_next_tl
+                        \@@_prop_get:nnN
+                          { \l_@@_print_note_id_next_tl }
+                          { thechapter } \pnthechapternextnote
+                        \@@_prop_get:nnN
+                          { \l_@@_print_note_id_next_tl }
+                          { thesection } \pnthesectionnextnote
+                        \@@_prop_get:nnN
+                          { \l_postnotes_print_note_id_tl }
+                          { content } \l_@@_print_content_tl
+                        \l_@@_print_content_tl
+                      \group_end:
+%    \end{macrocode}
+% Set \texttt{type_prev} for the next iteration.
+%    \begin{macrocode}
+                      \tl_set:NV \l_@@_print_type_prev_tl
+                        \l_@@_print_type_curr_tl
+                    }
+                }
+                { % type_curr = `note'
+                  \seq_if_empty:NTF \g_@@_print_queue_seq
+                    {
+                      \tl_set:Nn \l_@@_print_note_id_next_tl { noid }
+                      \tl_set:Nn \l_@@_print_type_next_tl { close }
+                    }
+                    {
+                      \seq_get_left:NN \g_@@_print_queue_seq
+                        \l_@@_print_note_id_next_tl
+                      \@@_prop_get:nnN
+                        { \l_@@_print_note_id_next_tl }
+                        { type } \l_@@_print_type_next_tl
+                    }
+                  \tl_if_eq:NnF \l_@@_print_type_prev_tl { note }
+                    {
+                      \bool_if:NTF \l_@@_print_as_list_bool
+                        { \exp_args:NV \begin \l_@@_print_env_tl }
+                        { \group_begin: }
+                      \tag_socket_use:n { postnotes/printlist/begin }
+                      \l_@@_print_format_tl
+                    }
+                  \group_begin:
+                    \UseHook { postnotes/print/note/begin }
+                    \@@_get_pageref:Ne \pnthepage
+                      { mark@ \l_postnotes_print_note_id_tl }
                     \@@_prop_get:nnN
                       { \l_postnotes_print_note_id_tl }
-                      { thechapter } \pnthechapter
+                      { mark } \l_@@_print_mark_tl
                     \@@_prop_get:nnN
                       { \l_postnotes_print_note_id_tl }
-                      { thesection } \pnthesection
-                    \tl_set:NV \pnidnextnote \l_@@_print_note_id_next_tl
+                      { counter } \l_@@_print_counter_tl
                     \@@_prop_get:nnN
-                      { \l_@@_print_note_id_next_tl }
-                      { thechapter } \pnthechapternextnote
-                    \@@_prop_get:nnN
-                      { \l_@@_print_note_id_next_tl }
-                      { thesection } \pnthesectionnextnote
-                    \@@_prop_get:nnN
                       { \l_postnotes_print_note_id_tl }
                       { content } \l_@@_print_content_tl
-                    \l_@@_print_content_tl
-                    \group_end:
+                    \cs_set:Npn \@currentcounter { postnotetext }
+                    \int_set:Nn \c at postnotetext
+                      { \l_@@_print_counter_tl }
+                    \cs_set:Npe \@currentlabel
+                      { \p at postnote \l_@@_print_mark_tl }
+                    \tl_set:Nn \l_@@_print_typeset_mark_tl
+                      {
+                        \tag_socket_use:n { postnotes/printmark/begin }
+                        \MakeLinkTarget*
+                          { postnote. \l_postnotes_print_note_id_tl .text }
+                        \@@_set_text_page_label:e
+                          { \l_postnotes_print_note_id_tl }
+                        \l_@@_pre_textmark_tl
+                        \@@_typeset_text_mark:eV
+                          { \l_postnotes_print_note_id_tl }
+                          \l_@@_print_mark_tl
+                        \l_@@_post_textmark_tl
+                        \tag_socket_use:n { postnotes/printmark/end }
+                      }
 %    \end{macrocode}
-% Set \texttt{type_prev} for the next iteration.
+% Note that the placement of the tagging socket for the list case may depend
+% on the tagging structure, in other words, on the content of the socket.  It
+% currently does nothing for the list case, so I've placed it in the
+% ``potentially most useful place''.  Review this if the content changes.
+% Leave vertical mode after \cs{item} for the list case to avoid ``perhaps a
+% missing \cs{item}'' error for empty notes (see
+% \file{pn-bug-empty-postnote01.lvt}).  And leave vertical mode before the
+% note (and the tagging socket) for \opt{listenv=none} (see
+% \url{https://github.com/gusbrs/postnotes/issues/8#issuecomment-2429501962},
+% thanks \contributor{Ulrike Fischer}).
 %    \begin{macrocode}
-                    \tl_set:NV \l_@@_print_type_prev_tl
-                      \l_@@_print_type_curr_tl
-                  }
-              }
-              { % type_curr = `note'
-                \tl_if_eq:NnF \l_@@_print_type_prev_tl { note }
-                  {
                     \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:
-                \UseHook { postnotes/print/note/begin }
-                \@@_get_pageref:Ne \pnthepage
-                  { mark@ \l_postnotes_print_note_id_tl }
-                \@@_prop_get:nnN
-                  { \l_postnotes_print_note_id_tl }
-                  { mark } \l_@@_print_mark_tl
-                \@@_prop_get:nnN
-                  { \l_postnotes_print_note_id_tl }
-                  { counter } \l_@@_print_counter_tl
-                \@@_prop_get:nnN
-                  { \l_postnotes_print_note_id_tl }
-                  { content } \l_@@_print_content_tl
-                \cs_set:Npn \@currentcounter { postnotetext }
-                \int_set:Nn \c at postnotetext
-                  { \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*
-                      { postnote. \l_postnotes_print_note_id_tl .text }
-                    \@@_set_text_page_label:e
-                      { \l_postnotes_print_note_id_tl }
-                    \@@_typeset_text_mark:eV
-                      { \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:
+                      {
+                        \item
+                          [
+                            \tag_socket_use:n { postnotes/printnote/begin }
+                            \l_@@_print_typeset_mark_tl
+                          ]
+                        \mode_leave_vertical:
+                      }
+                      {
+                        \mode_leave_vertical:
+                        \tag_socket_use:n { postnotes/printnote/begin }
+                        \l_@@_print_typeset_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:
+                  \tl_if_eq:NnF \l_@@_print_type_next_tl { note }
+                    {
+                      \tag_socket_use:n { postnotes/printlist/end }
 %    \end{macrocode}
-% For notes, query for next note's type \texttt{after} the current note was
-% typeset, to handle possible nesting.  Even if nesting is not a feature, this
-% should avoid hard crashes related to ``lonely \cs{item}'' or ``extra
-% \cs{endgroup}'' errors, in case it occurs.
-%    \begin{macrocode}
-                \seq_if_empty:NTF \g_@@_queue_seq
-                  {
-                    \tl_set:Nn \l_@@_print_note_id_next_tl { noid }
-                    \tl_set:Nn \l_@@_print_type_next_tl { close }
-                  }
-                  {
-                    \seq_get_left:NN \g_@@_queue_seq
-                      \l_@@_print_note_id_next_tl
-                    \@@_prop_get:nnN
-                      { \l_@@_print_note_id_next_tl }
-                      { type } \l_@@_print_type_next_tl
-                  }
-                \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: }
-%    \end{macrocode}
-% Ensure \cs{par} at the end of \cs{printopostnotes} (see
+% Ensure \cs{par} at the end of \cs{printpostnotes} (see
 % \url{https://github.com/u-fischer/tagpdf/issues/68#issuecomment-1587343876},
 % thanks \contributor{Ulrike Fischer}).
 %    \begin{macrocode}
-                    \par
-                  }
+                      \bool_if:NTF \l_@@_print_as_list_bool
+                        {
+                          \exp_args:NV \end \l_@@_print_env_tl
+                          \par
+                        }
+                        {
+                          \par
+                          \group_end:
+                        }
+                    }
 %    \end{macrocode}
 % Set \texttt{type_prev} for the next iteration.
 %    \begin{macrocode}
-                \tl_set:NV \l_@@_print_type_prev_tl
-                  \l_@@_print_type_curr_tl
-              }
-          }
-        \AddToHookNext { shipout/after }
-          { \bool_gset_false:N \g_@@_header_vars_next_bool }
+                  \tl_set:NV \l_@@_print_type_prev_tl
+                    \l_@@_print_type_curr_tl
+                }
+            }
+          \AddToHookNext { shipout/after }
+            { \bool_gset_false:N \g_@@_header_vars_next_bool }
 %    \end{macrocode}
 % We won't use the variables anymore, clear them to reduce memory usage.
-% Given how we populated \cs{l_@@_clear_queue_seq}, this won't catch nested
-% notes.  But it's not worth to conditionally add new items along the way
-% (testing it every iteration) for this.  Again, not a feature.
 %    \begin{macrocode}
-        \seq_map_inline:Nn \l_@@_clear_queue_seq
-          { \@@_prop_gclear:n { ##1 } }
-      }
+          \seq_map_inline:Nn \l_@@_clear_queue_seq
+            { \@@_prop_gclear:n { ##1 } }
+        }
     \group_end:
   }
 %    \end{macrocode}
@@ -1676,15 +1997,10 @@
 %    \end{macrocode}
 %
 %
-% \begin{macro}
-%   {
-%     \@@_typeset_text_mark:nn ,
-%     \@@_text_mark_wrapper:n ,
-%   }
-%   Auxiliary functions for mark typesetting in \cs{@@_print_notes:}.
+% \begin{macro}{\@@_typeset_text_mark:nn}
+%   Auxiliary function for mark typesetting in \cs{@@_print_notes:}.
 %   \begin{syntax}
 %     \cs{@@_typeset_text_mark:nn} \Arg{note id} \Arg{mark}
-%     \cs{@@_text_mark_wrapper:n} \Arg{mark}
 %   \end{syntax}
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_typeset_text_mark:nn #1#2
@@ -1700,47 +2016,144 @@
       { \@@_make_text_mark:nnn {#2} { } { } }
   }
 \cs_generate_variant:Nn \@@_typeset_text_mark:nn { eV }
-\cs_new_protected:Npn \@@_text_mark_wrapper:n #1
+%    \end{macrocode}
+% \end{macro}
+%
+%
+% \subsection*{Print auxiliary}
+%
+% The conditions used to split \cs{g_@@_labelseq_seq} are subtly different
+% depending on whether we are using \cs{g_@@_counteraux_bool} or not.  In the
+% standard case, the numbering of the floats are set at ``expansion time'', so
+% they belong where they are set.  With \opt{counteraux}, the numbering of
+% floats are set at ``shipout time'', so they belong where they are typeset.
+% In other words, with \opt{counteraux} notes on floats can cross the
+% boundaries of \cs{printpostnotes}, while without it, they must not.
+% Furthermore, the purpose of \cs{g_@@_labelseq_seq} is different in each
+% case.  With \opt{counteraux} it is used to build the actual print queue,
+% while in the standard case it is only used in \cs{@@_check_floats:N}.
+% Therefore, with \opt{counteraux} the cut is made at the place the preprint
+% label for the current \cs{printpostnotes} is found, while in the standard
+% case, \cs{g_@@_note_id_int} is used directly to distribute the elements
+% between the current \cs{printpostnotes} and future ones.
+%
+%
+% \begin{macro}{\@@_split_labelseq:}
+%    \begin{macrocode}
+\seq_new:N \g_@@_print_labelseq_queue_seq
+\cs_new_protected:Npn \@@_split_labelseq:
   {
-    \bool_if:NTF \l_@@_print_as_list_bool
-      {
-        \item
-          [
-            \tag_socket_use:n { postnotes/printmark/begin }
-            \l_@@_pre_textmark_tl #1 \l_@@_post_textmark_tl
-            \tag_socket_use:n { postnotes/printmark/end }
-          ]
+    \group_begin:
+      \seq_clear:N \l_@@_tmpa_seq
+      \seq_clear:N \l_@@_tmpb_seq
+      \bool_if:NTF \g_@@_counteraux_bool
+        {
+          \tl_set:Ne \l_@@_tmpa_tl
+            { { preprint } { \int_use:N \g_@@_print_postnotes_int } }
 %    \end{macrocode}
-% Leave vertical mode to avoid ``perhaps a missing \cs{item}'' error for empty
-% notes.
+% The preprint label of a \cs{printpostnotes} at the end of the document may
+% not have been written: if it's empty, it may not be shipped out at all.
+% But, since it's a counter, stepped sequentially and not floating, even if it
+% is transitorily missing, it will be at the end.  In other words, if this one
+% is not found, there will be no subsequent preprints in the sequence.
 %    \begin{macrocode}
-        \mode_leave_vertical:
-      }
-      {
-        \tag_socket_use:n { postnotes/printmark/begin }
-        \l_@@_pre_textmark_tl #1 \l_@@_post_textmark_tl
-        \tag_socket_use:n { postnotes/printmark/end }
-      }
+          \seq_if_in:NVF \g_@@_labelseq_seq \l_@@_tmpa_tl
+            { \seq_gput_right:NV \g_@@_labelseq_seq \l_@@_tmpa_tl }
+          \bool_do_until:nn
+            { \tl_if_eq_p:NN \l_@@_tmpb_tl \l_@@_tmpa_tl }
+            {
+              \seq_gpop_left:NN \g_@@_labelseq_seq \l_@@_tmpb_tl
+              \str_case:enT
+                { \tl_item:Nn \l_@@_tmpb_tl { 1 } }
+                {
+                  { mark }    { }
+                  { section } { }
+                }
+                {
+%    \end{macrocode}
+% If the id of the labelseq item is larger than the current note id, we don't
+% have data for the note at this point, and cannot print it.  Period.  Now,
+% usually this will occur due to transitory effects.  But it is theoretically
+% possible that a float is sent to the top of the page and gets typeset before
+% a ``future \cs{printpostnotes}''.  So what we cannot print, we give back to
+% the label sequence of the next \cs{printpostnotes}.  If they are transitory,
+% they will eventually go away.  If they are not, better to keep them with the
+% wrong numbering than dropping it altogether.  Alas, there's nothing else we
+% could do, short of writing the whole data to the \file{.aux} file, which is
+% clearly not worth this corner case.
+%    \begin{macrocode}
+                  \int_compare:nNnTF
+                    { \tl_item:Nn \l_@@_tmpb_tl { 2 } }
+                    >
+                    { \g_@@_note_id_int }
+                    {
+                      \seq_put_right:Ne \l_@@_tmpb_seq
+                        \l_@@_tmpb_tl
+                    }
+                    {
+                      \seq_put_right:Ne \l_@@_tmpa_seq
+                        { \tl_item:Nn \l_@@_tmpb_tl { 2 } }
+                    }
+                }
+%    \end{macrocode}
+% No need for the \texttt{F} branch of \cs{str_case:enT}, at this point the
+% preprint of past \cs{printpostnotes} can no longer be here, and we don't go
+% further than the current one.  In theory, we could even go without
+% \cs{str_case:enT}, but let's play safe and keep the function robust against
+% future changes of the code.
+%    \begin{macrocode}
+            }
+          \seq_gset_eq:NN \g_@@_print_labelseq_queue_seq
+            \l_@@_tmpa_seq
+          \seq_concat:NNN \l_@@_tmpa_seq \l_@@_tmpb_seq
+            \g_@@_labelseq_seq
+          \seq_gset_eq:NN \g_@@_labelseq_seq \l_@@_tmpa_seq
+        }
+        {
+          \seq_map_inline:Nn \g_@@_labelseq_seq
+            {
+              \str_case:enT
+                { \tl_item:nn { ##1 } { 1 } }
+                {
+                  { mark }    { }
+                  { section } { }
+                }
+                {
+                  \int_compare:nNnTF
+                    { \tl_item:nn { ##1 } { 2 } }
+                    >
+                    { \g_@@_note_id_int }
+                    { \seq_put_right:Nn \l_@@_tmpb_seq { ##1 } }
+                    {
+                      \seq_put_right:Ne \l_@@_tmpa_seq
+                        { \tl_item:nn { ##1 } { 2 } }
+                    }
+                }
+%    \end{macrocode}
+% Also no need for the \texttt{F} branch here, but for a different reason.
+% The preprint label plays no role whatsoever if \opt{couteraux=false}, so we
+% just drop them altogether if found.
+%    \begin{macrocode}
+            }
+          \seq_gset_eq:NN \g_@@_print_labelseq_queue_seq
+            \l_@@_tmpa_seq
+          \seq_gset_eq:NN \g_@@_labelseq_seq \l_@@_tmpb_seq
+        }
+    \group_end:
   }
 %    \end{macrocode}
 % \end{macro}
 %
 %
-% \subsection*{Print auxiliary}
-%
-% \cs{@@_verify_multipass:N} provides a general procedure for handling cases
+% \cs{@@_check_duplicates:N} provides a general procedure for handling cases
 % of multiple passes of content.  Ideally, the job should be done at
 % \cs{@@_inhibit_note:F}, if at all possible.  But, failing that, we can rely
-% on the fact that \cs{postnote}s of measuring/trial passes don't end up being
-% output and hence don't generate labels in the \file{.aux} file.  This is the
-% equivalent for \pkg{postnotes} to the effect of write restrictions for the
-% packages based on external files, which is how they actually handle these
-% cases.  However, despite this being a general test, and a reasonable one,
-% I'd like to restrain it's use to the minimum possible.  First, using this
-% criterion across the board would result in large swings on the content of
-% \cs{printpostnotes} and spurious warnings in an initial compilation since
-% the labels are not available on the first run.  Second, I'd prefer not to
-% interfere with the queue, unless we really need to.  Hence, we only apply
+% on the fact that the labels of \cs{postnote}s of measuring/trial passes,
+% being delayed \cs{write}s (whatsits), don't end up being written to the
+% \file{.aux} file.  However, despite this being a general test, and a
+% reasonable one, I'd like to restrain it's use to the minimum possible.
+% Using this criterion across the board could result in large swings on the
+% content of \cs{printpostnotes} and spurious warnings.  Hence, we only apply
 % this check for ``eligible'' items.  For signaling this eligibility, the note
 % must have been stored with the \cs{l_@@_maybe_multi_bool} set to
 % \texttt{true}, which is then saved in the \texttt{multibool} property.  One
@@ -1749,71 +2162,184 @@
 % labels of the printed notes will be written only on the second run and the
 % document will thus require a third one to stabilize.
 %
-% \begin{macro}{\@@_verify_multipass:N}
+% \begin{macro}{\@@_check_duplicates:N}
 %   \begin{syntax}
-%     \cs{@@_verify_multipass:N} \meta{\cs{g_@@_queue_seq}}
+%     \cs{@@_check_duplicates:N} \meta{\cs{g_@@_print_queue_seq}}
 %   \end{syntax}
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_verify_multipass:N #1
+\cs_new_protected:Npn \@@_check_duplicates:N #1
   {
-    \group_begin:
-    \seq_clear:N \l_@@_tmpa_seq
-    \seq_map_inline:Nn #1
+%    \end{macrocode}
+% On a first run, don't even try to check for duplicates.  Better
+% \texttt{transitorily} let some duplicates pass than to drop every legitimate
+% note.
+%    \begin{macrocode}
+    \bool_lazy_and:nnT
+      { ! \g_@@_firstrun_bool }
+      { ! \g_@@_counteraux_bool }
       {
-        \@@_prop_get:nnN {##1} { multibool } \l_@@_tmpa_tl
-        \str_if_eq:VnTF \l_@@_tmpa_tl { true }
-          {
-            \cs_if_exist:cT
-              { \c_@@_ref_prefix_tl @ mark@ ##1 }
-              { \seq_put_right:Nn \l_@@_tmpa_seq {##1} }
-          }
-          { \seq_put_right:Nn \l_@@_tmpa_seq {##1} }
+        \group_begin:
+          \seq_clear:N \l_@@_tmpa_seq
+          \seq_map_inline:Nn #1
+            {
+              \bool_lazy_or:nnTF
+                { \cs_if_exist_p:c { \c_@@_ref_prefix_tl @ mark @ ##1 } }
+%    \end{macrocode}
+% Always keep sections.  Empty sections are discarded anyway, and they are
+% unlikely to occur in places performing multiple passes.
+%    \begin{macrocode}
+                {
+                  \str_if_eq_p:ee
+                    { \@@_prop_item:nn {##1} { type } } { section }
+                }
+                { \seq_put_right:Nn \l_@@_tmpa_seq {##1} }
+                {
+%    \end{macrocode}
+% If \texttt{multibool} is true for the note, we drop it silently, otherwise
+% we include it, but warn of possible duplicate.
+%    \begin{macrocode}
+                  \str_if_eq:eeF
+                    { \@@_prop_item:nn {##1} { multibool } }
+                    { true }
+                    {
+                      \seq_put_right:Nn \l_@@_tmpa_seq {##1}
+                      \bool_if:NT \l_@@_check_dupli_bool
+                        {
+                          \msg_warning:nne { postnotes } { possible-duplicate }
+                            { \@@_prop_item:nn {##1} { mark } }
+                        }
+                    }
+                }
+            }
+          \seq_gset_eq:NN #1 \l_@@_tmpa_seq
+        \group_end:
       }
-    \seq_gset_eq:NN #1 \l_@@_tmpa_seq
-    \group_end:
   }
 %    \end{macrocode}
 % \end{macro}
 %
+%    \begin{macrocode}
+\msg_new:nnn { postnotes } { possible-duplicate }
+  { Possible~duplicate~*around*~note~'#1'~\msg_line_context:. }
+%    \end{macrocode}
 %
+%
+% \begin{macro}{\@@_check_floats:N}
+%   \begin{syntax}
+%     \cs{@@_check_floats:N} \meta{\cs{g_@@_print_queue_seq}}
+%   \end{syntax}
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_check_floats:N #1
+  {
+    \bool_lazy_and:nnT
+      { \l_@@_check_floats_bool }
+%    \end{macrocode}
+% Ditto.  In this case, the queue is not touched, but it would still be a
+% spurious warning.
+%    \begin{macrocode}
+      { ! \g_@@_firstrun_bool }
+      {
+        \group_begin:
+%    \end{macrocode}
+% Only compare sequence net of non-existing labels.
+%    \begin{macrocode}
+          \seq_set_filter:NNn \l_@@_tmpa_seq #1
+            {
+              \bool_lazy_or_p:nn
+                { \cs_if_exist_p:c { \c_@@_ref_prefix_tl @ mark @ ##1 } }
+                { \cs_if_exist_p:c { \c_@@_ref_prefix_tl @ section @ ##1 } }
+            }
+%    \end{macrocode}
+% Not very \texttt{expl3}-y, I know.  But I don't see a \cs{seq_if_eq:NNTF}
+% available and, technically, sequences are just structured token lists.
+%    \begin{macrocode}
+          \tl_if_eq:NNF
+            \g_@@_print_labelseq_queue_seq \l_@@_tmpa_seq
+            { \msg_warning:nn { postnotes } { possible-shuffle } }
+        \group_end:
+      }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+%    \begin{macrocode}
+\msg_new:nnn { postnotes } { possible-shuffle }
+  { Possible~out~of~sequence~notes~due~to~floats~\msg_line_context:. }
+%    \end{macrocode}
+%
+%
 % \begin{macro}{\@@_sort_queue:N}
 %   Sorting function for \cs{@@_print_notes:}.
 %   \begin{syntax}
-%     \cs{@@_sort_queue:N} \meta{\cs{g_@@_queue_seq}}
+%     \cs{@@_sort_queue:N} \meta{\cs{g_@@_print_queue_seq}}
 %   \end{syntax}
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_sort_queue:N #1
   {
-    \group_begin:
-    \seq_gsort:Nn #1
+    \bool_if:NT \l_@@_sort_bool
       {
-        \@@_prop_get:nnN {##1} { pnsectid } \l_@@_tmpa_tl
-        \@@_prop_get:nnN {##2} { pnsectid } \l_@@_tmpb_tl
-        \tl_if_eq:NNTF \l_@@_tmpa_tl \l_@@_tmpb_tl
-          {
-            \@@_prop_get:nnN {##1} { type } \l_@@_tmpa_tl
-            \@@_prop_get:nnN {##2} { type } \l_@@_tmpb_tl
-            \bool_lazy_and:nnTF
-              { \str_if_eq_p:Vn \l_@@_tmpa_tl { note } }
-              { \str_if_eq_p:Vn \l_@@_tmpb_tl { note } }
-              {
-                \@@_prop_get:nnN {##1} { sortnum } \l_@@_tmpa_tl
-                \@@_prop_get:nnN {##2} { sortnum } \l_@@_tmpb_tl
-                \fp_compare:nNnTF
-                  { \l_@@_tmpa_tl } > { \l_@@_tmpb_tl }
-                  { \sort_return_swapped: }
-                  { \sort_return_same:    }
-              }
-              { \sort_return_same: }
-          }
-          { \sort_return_same: }
+        \group_begin:
+          \seq_gsort:Nn #1
+            {
+              \@@_prop_get:nnN {##1} { pnsectid } \l_@@_tmpa_tl
+              \@@_prop_get:nnN {##2} { pnsectid } \l_@@_tmpb_tl
+              \tl_if_eq:NNTF \l_@@_tmpa_tl \l_@@_tmpb_tl
+                {
+                  \@@_prop_get:nnN {##1} { type } \l_@@_tmpa_tl
+                  \@@_prop_get:nnN {##2} { type } \l_@@_tmpb_tl
+                  \bool_lazy_and:nnTF
+                    { \str_if_eq_p:Vn \l_@@_tmpa_tl { note } }
+                    { \str_if_eq_p:Vn \l_@@_tmpb_tl { note } }
+                    {
+                      \@@_prop_get:nnN {##1}
+                        { sortnum } \l_@@_tmpa_tl
+                      \@@_prop_get:nnN {##2}
+                        { sortnum } \l_@@_tmpb_tl
+                      \fp_compare:nNnTF
+                        { \l_@@_tmpa_tl } > { \l_@@_tmpb_tl }
+                        { \sort_return_swapped: }
+                        { \sort_return_same:    }
+                    }
+                    { \sort_return_same: }
+                }
+                { \sort_return_same: }
+            }
+        \group_end:
       }
-    \group_end:
   }
 %    \end{macrocode}
 % \end{macro}
 %
 %
+%    \begin{macrocode}
+\AddToHook { enddocument/afterlastpage }
+  {
+    \group_begin:
+      \bool_if:NTF \g_@@_counteraux_bool
+        {
+          \seq_set_filter:NNn \l_@@_tmpa_seq \g_@@_labelseq_seq
+            { \str_if_eq_p:ee { \tl_item:nn {#1} { 1 } } { mark } }
+        }
+        {
+          \seq_set_filter:NNn \l_@@_tmpa_seq \g_@@_queue_seq
+            { \str_if_eq_p:ee { \@@_prop_item:nn {#1} { type } } { note } }
+        }
+      \seq_if_empty:NF \l_@@_tmpa_seq
+        {
+          \msg_warning:nne { postnotes } { stray-notes }
+            { \seq_count:N \l_@@_tmpa_seq }
+        }
+    \group_end:
+  }
+\msg_new:nnn { postnotes } { stray-notes }
+  {
+    There~are~'#1'~stray~notes~after~the~last~'\iow_char:N\\printpostnotes'~
+    \msg_line_context:.~At~this~point,~they~are~lost.
+  }
+%    \end{macrocode}
+%
+%
+%
 % \section{Headers}
 %
 % The headers infrastructure of \pkg{postnotes} is comprised of three basic
@@ -1827,7 +2353,7 @@
 %   since we want the printed representation of it for typesetting purposes,
 %   the latter ones store the value of the \texttt{page} counter, since we
 %   don't need to typeset it, but do need to perform algebraic operations with
-%   it.  These labels are set by \cs{@@_set_mark_page_label:n},
+%   it.  These labels are set by \cs{@@_set_mark_page_label:nn},
 %   \cs{@@_set_text_page_label:n}, and \cs{@@_set_print_page_label:n} at the
 %   appropriate places.  The set of these labels provides a mapping from each
 %   note's ``mark'' and ``text'' to the page where it occurs.
@@ -1939,66 +2465,66 @@
 % \begin{macro}{\@@_get_headers_data:N}
 %   Process header data for \cs{@@_set_headers_vars:n}.
 %   \begin{syntax}
-%     \cs{@@_get_headers_data:N} \meta{\cs{g_@@_queue_seq}}
+%     \cs{@@_get_headers_data:N} \meta{\cs{g_@@_print_queue_seq}}
 %   \end{syntax}
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_get_headers_data:N #1
   {
     \group_begin:
-    \tl_gclear:N \pnhdpagefirst
-    \tl_gclear:N \pnhdpagelast
-    \tl_gclear:N \pnhdchapfirst
-    \tl_gclear:N \pnhdchaplast
-    \tl_gclear:N \pnhdsectfirst
-    \tl_gclear:N \pnhdsectlast
-    \tl_gclear:N \pnhdnamefirst
-    \tl_gclear:N \pnhdnamelast
-    \prop_gclear:N \g_@@_header_page_first_prop
-    \prop_gclear:N \g_@@_header_page_last_prop
-    \prop_gclear:N \g_@@_header_chap_first_prop
-    \prop_gclear:N \g_@@_header_chap_last_prop
-    \prop_gclear:N \g_@@_header_sect_first_prop
-    \prop_gclear:N \g_@@_header_sect_last_prop
-    \prop_gclear:N \g_@@_header_name_first_prop
-    \prop_gclear:N \g_@@_header_name_last_prop
-    \tl_gclear:N \g_@@_header_prev_last_page_tl
-    \tl_gclear:N \g_@@_header_prev_last_chap_tl
-    \tl_gclear:N \g_@@_header_prev_last_sect_tl
-    \tl_gclear:N \g_@@_header_prev_last_name_tl
-    \tl_clear:N \l_@@_prev_text_page_tl
-    \tl_clear:N \l_@@_curr_text_page_tl
-    \tl_clear:N \l_@@_prev_mark_page_tl
-    \tl_clear:N \l_@@_prev_mark_chap_tl
-    \tl_clear:N \l_@@_prev_mark_sect_tl
-    \tl_clear:N \l_@@_prev_mark_name_tl
-    \seq_map_inline:Nn #1
-      {
-        \exp_args:Ne \tl_if_eq:nnT
-          { \@@_prop_item:nn {##1} { type } }
-          { note }
-          {
-            \@@_get_pageref:Nn
-              \l_@@_curr_text_page_tl { text@ ##1 }
-            \tl_if_empty:NF \l_@@_curr_text_page_tl
-              {
-                \tl_if_eq:NNTF
-                  \l_@@_prev_text_page_tl
-                  \l_@@_curr_text_page_tl
-                  {
+      \tl_gclear:N \pnhdpagefirst
+      \tl_gclear:N \pnhdpagelast
+      \tl_gclear:N \pnhdchapfirst
+      \tl_gclear:N \pnhdchaplast
+      \tl_gclear:N \pnhdsectfirst
+      \tl_gclear:N \pnhdsectlast
+      \tl_gclear:N \pnhdnamefirst
+      \tl_gclear:N \pnhdnamelast
+      \prop_gclear:N \g_@@_header_page_first_prop
+      \prop_gclear:N \g_@@_header_page_last_prop
+      \prop_gclear:N \g_@@_header_chap_first_prop
+      \prop_gclear:N \g_@@_header_chap_last_prop
+      \prop_gclear:N \g_@@_header_sect_first_prop
+      \prop_gclear:N \g_@@_header_sect_last_prop
+      \prop_gclear:N \g_@@_header_name_first_prop
+      \prop_gclear:N \g_@@_header_name_last_prop
+      \tl_gclear:N \g_@@_header_prev_last_page_tl
+      \tl_gclear:N \g_@@_header_prev_last_chap_tl
+      \tl_gclear:N \g_@@_header_prev_last_sect_tl
+      \tl_gclear:N \g_@@_header_prev_last_name_tl
+      \tl_clear:N \l_@@_prev_text_page_tl
+      \tl_clear:N \l_@@_curr_text_page_tl
+      \tl_clear:N \l_@@_prev_mark_page_tl
+      \tl_clear:N \l_@@_prev_mark_chap_tl
+      \tl_clear:N \l_@@_prev_mark_sect_tl
+      \tl_clear:N \l_@@_prev_mark_name_tl
+      \seq_map_inline:Nn #1
+        {
+          \exp_args:Ne \tl_if_eq:nnT
+            { \@@_prop_item:nn {##1} { type } }
+            { note }
+            {
+              \@@_get_pageref:Nn
+                \l_@@_curr_text_page_tl { text@ ##1 }
+              \tl_if_empty:NF \l_@@_curr_text_page_tl
+                {
+                  \tl_if_eq:NNTF
+                    \l_@@_prev_text_page_tl
+                    \l_@@_curr_text_page_tl
+                    {
 %    \end{macrocode}
 % We are on the same page as the previous note, just update the
 % \texttt{prev_mark} data.
 %    \begin{macrocode}
-                    \@@_get_pageref:Nn
-                      \l_@@_prev_mark_page_tl { mark@ ##1 }
-                    \@@_prop_get:nnN {##1} { thechapter }
-                      \l_@@_prev_mark_chap_tl
-                    \@@_prop_get:nnN {##1} { thesection }
-                      \l_@@_prev_mark_sect_tl
-                    \@@_prop_get:nnN {##1} { pnsectname }
-                      \l_@@_prev_mark_name_tl
-                  }
-                  {
+                      \@@_get_pageref:Nn
+                        \l_@@_prev_mark_page_tl { mark@ ##1 }
+                      \@@_prop_get:nnN {##1} { thechapter }
+                        \l_@@_prev_mark_chap_tl
+                      \@@_prop_get:nnN {##1} { thesection }
+                        \l_@@_prev_mark_sect_tl
+                      \@@_prop_get:nnN {##1} { pnsectname }
+                        \l_@@_prev_mark_name_tl
+                    }
+                    {
 %    \end{macrocode}
 % We are on the transition between two pages, current ID is the first note of
 % the new page (or on the very first note of \cs{printpostnotes}, given
@@ -2010,49 +2536,49 @@
 % on \cs{l_@@_prev_text_page_tl} being empty, which only occurs on the first
 % note).
 %    \begin{macrocode}
-                    \tl_if_empty:NF \l_@@_prev_text_page_tl
-                      {
-                        \prop_gput:Nee \g_@@_header_page_last_prop
-                          { \l_@@_prev_text_page_tl }
-                          { \l_@@_prev_mark_page_tl }
-                        \prop_gput:Nee \g_@@_header_chap_last_prop
-                          { \l_@@_prev_text_page_tl }
-                          { \l_@@_prev_mark_chap_tl }
-                        \prop_gput:Nee \g_@@_header_sect_last_prop
-                          { \l_@@_prev_text_page_tl }
-                          { \l_@@_prev_mark_sect_tl }
-                        \prop_gput:Nee \g_@@_header_name_last_prop
-                          { \l_@@_prev_text_page_tl }
-                          { \l_@@_prev_mark_name_tl }
-                      }
+                      \tl_if_empty:NF \l_@@_prev_text_page_tl
+                        {
+                          \prop_gput:Nee \g_@@_header_page_last_prop
+                            { \l_@@_prev_text_page_tl }
+                            { \l_@@_prev_mark_page_tl }
+                          \prop_gput:Nee \g_@@_header_chap_last_prop
+                            { \l_@@_prev_text_page_tl }
+                            { \l_@@_prev_mark_chap_tl }
+                          \prop_gput:Nee \g_@@_header_sect_last_prop
+                            { \l_@@_prev_text_page_tl }
+                            { \l_@@_prev_mark_sect_tl }
+                          \prop_gput:Nee \g_@@_header_name_last_prop
+                            { \l_@@_prev_text_page_tl }
+                            { \l_@@_prev_mark_name_tl }
+                        }
 %    \end{macrocode}
 %
 % Set `first' values for current page, based on the current note ID.
 %    \begin{macrocode}
-                    \prop_gput:Nee \g_@@_header_page_first_prop
-                      { \l_@@_curr_text_page_tl }
-                      { \@@_extract_pageref:n { mark@ ##1 } }
-                    \prop_gput:Nee \g_@@_header_chap_first_prop
-                      { \l_@@_curr_text_page_tl }
-                      { \@@_prop_item:nn {##1} { thechapter } }
-                    \prop_gput:Nee \g_@@_header_sect_first_prop
-                      { \l_@@_curr_text_page_tl }
-                      { \@@_prop_item:nn {##1} { thesection } }
-                    \prop_gput:Nee \g_@@_header_name_first_prop
-                      { \l_@@_curr_text_page_tl }
-                      { \@@_prop_item:nn {##1} { pnsectname } }
+                      \prop_gput:Nee \g_@@_header_page_first_prop
+                        { \l_@@_curr_text_page_tl }
+                        { \@@_extract_pageref:n { mark@ ##1 } }
+                      \prop_gput:Nee \g_@@_header_chap_first_prop
+                        { \l_@@_curr_text_page_tl }
+                        { \@@_prop_item:nn {##1} { thechapter } }
+                      \prop_gput:Nee \g_@@_header_sect_first_prop
+                        { \l_@@_curr_text_page_tl }
+                        { \@@_prop_item:nn {##1} { thesection } }
+                      \prop_gput:Nee \g_@@_header_name_first_prop
+                        { \l_@@_curr_text_page_tl }
+                        { \@@_prop_item:nn {##1} { pnsectname } }
 %    \end{macrocode}
 %
 % Store \texttt{prev_mark} data for the first note on the page.
 %    \begin{macrocode}
-                    \@@_get_pageref:Nn
-                      \l_@@_prev_mark_page_tl { mark@ ##1 }
-                    \@@_prop_get:nnN {##1} { thechapter }
-                      \l_@@_prev_mark_chap_tl
-                    \@@_prop_get:nnN {##1} { thesection }
-                      \l_@@_prev_mark_sect_tl
-                    \@@_prop_get:nnN {##1} { pnsectname }
-                      \l_@@_prev_mark_name_tl
+                      \@@_get_pageref:Nn
+                        \l_@@_prev_mark_page_tl { mark@ ##1 }
+                      \@@_prop_get:nnN {##1} { thechapter }
+                        \l_@@_prev_mark_chap_tl
+                      \@@_prop_get:nnN {##1} { thesection }
+                        \l_@@_prev_mark_sect_tl
+                      \@@_prop_get:nnN {##1} { pnsectname }
+                        \l_@@_prev_mark_name_tl
 %    \end{macrocode}
 %
 % Set \cs{l_@@_prev_text_page_tl} for the next page
@@ -2059,12 +2585,12 @@
 % (\cs{l_@@_curr_text_page_tl} is never empty at this point, since we
 % conditioned to it).
 %    \begin{macrocode}
-                    \tl_set:NV \l_@@_prev_text_page_tl
-                      \l_@@_curr_text_page_tl
-                  }
-              }
-          }
-      }
+                      \tl_set:NV \l_@@_prev_text_page_tl
+                        \l_@@_curr_text_page_tl
+                    }
+                }
+            }
+        }
 %    \end{macrocode}
 % We can't catch the transition from the last page of \cs{printpostnotes} to
 % the following one through the mapping above, but the \texttt{prev_mark}
@@ -2071,21 +2597,21 @@
 % values of the last note in the loop are the ones we want, so we set `last'
 % values for the last page based on them.
 %    \begin{macrocode}
-    \tl_if_empty:NF \l_@@_prev_text_page_tl
-      {
-        \prop_gput:Nee \g_@@_header_page_last_prop
-          { \l_@@_prev_text_page_tl }
-          { \l_@@_prev_mark_page_tl }
-        \prop_gput:Nee \g_@@_header_chap_last_prop
-          { \l_@@_prev_text_page_tl }
-          { \l_@@_prev_mark_chap_tl }
-        \prop_gput:Nee \g_@@_header_sect_last_prop
-          { \l_@@_prev_text_page_tl }
-          { \l_@@_prev_mark_sect_tl }
-        \prop_gput:Nee \g_@@_header_name_last_prop
-          { \l_@@_prev_text_page_tl }
-          { \l_@@_prev_mark_name_tl }
-      }
+      \tl_if_empty:NF \l_@@_prev_text_page_tl
+        {
+          \prop_gput:Nee \g_@@_header_page_last_prop
+            { \l_@@_prev_text_page_tl }
+            { \l_@@_prev_mark_page_tl }
+          \prop_gput:Nee \g_@@_header_chap_last_prop
+            { \l_@@_prev_text_page_tl }
+            { \l_@@_prev_mark_chap_tl }
+          \prop_gput:Nee \g_@@_header_sect_last_prop
+            { \l_@@_prev_text_page_tl }
+            { \l_@@_prev_mark_sect_tl }
+          \prop_gput:Nee \g_@@_header_name_last_prop
+            { \l_@@_prev_text_page_tl }
+            { \l_@@_prev_mark_name_tl }
+        }
     \group_end:
   }
 %    \end{macrocode}
@@ -2114,54 +2640,54 @@
 \cs_new_protected:Npn \@@_set_headers_vars:n #1
   {
     \group_begin:
-    \prop_get:NnNTF \g_@@_header_page_first_prop
-      {#1} \l_@@_tmpa_tl
-      { \tl_gset:NV \pnhdpagefirst \l_@@_tmpa_tl }
-      { \tl_gset:NV \pnhdpagefirst \g_@@_header_prev_last_page_tl }
-    \prop_get:NnNTF \g_@@_header_page_last_prop
-      {#1} \l_@@_tmpa_tl
-      {
-        \tl_gset:NV \pnhdpagelast \l_@@_tmpa_tl
-        \tl_gset:NV \g_@@_header_prev_last_page_tl
-          \l_@@_tmpa_tl
-      }
-      { \tl_gset:NV \pnhdpagelast \g_@@_header_prev_last_page_tl }
-    \prop_get:NnNTF \g_@@_header_chap_first_prop
-      {#1} \l_@@_tmpa_tl
-      { \tl_gset:NV \pnhdchapfirst \l_@@_tmpa_tl }
-      { \tl_gset:NV \pnhdchapfirst \g_@@_header_prev_last_chap_tl }
-    \prop_get:NnNTF \g_@@_header_chap_last_prop
-      {#1} \l_@@_tmpa_tl
-      {
-        \tl_gset:NV \pnhdchaplast \l_@@_tmpa_tl
-        \tl_gset:NV \g_@@_header_prev_last_chap_tl
-          \l_@@_tmpa_tl
-      }
-      { \tl_gset:NV \pnhdchaplast \g_@@_header_prev_last_chap_tl }
-    \prop_get:NnNTF \g_@@_header_sect_first_prop
-      {#1} \l_@@_tmpa_tl
-      { \tl_gset:NV \pnhdsectfirst \l_@@_tmpa_tl }
-      { \tl_gset:NV \pnhdsectfirst \g_@@_header_prev_last_sect_tl }
-    \prop_get:NnNTF \g_@@_header_sect_last_prop
-      {#1} \l_@@_tmpa_tl
-      {
-        \tl_gset:NV \pnhdsectlast \l_@@_tmpa_tl
-        \tl_gset:NV \g_@@_header_prev_last_sect_tl
-          \l_@@_tmpa_tl
-      }
-      { \tl_gset:NV \pnhdsectlast \g_@@_header_prev_last_sect_tl }
-    \prop_get:NnNTF \g_@@_header_name_first_prop
-      {#1} \l_@@_tmpa_tl
-      { \tl_gset:NV \pnhdnamefirst \l_@@_tmpa_tl }
-      { \tl_gset:NV \pnhdnamefirst \g_@@_header_prev_last_name_tl }
-    \prop_get:NnNTF \g_@@_header_name_last_prop
-      {#1} \l_@@_tmpa_tl
-      {
-        \tl_gset:NV \pnhdnamelast \l_@@_tmpa_tl
-        \tl_gset:NV \g_@@_header_prev_last_name_tl
-          \l_@@_tmpa_tl
-      }
-      { \tl_gset:NV \pnhdnamelast \g_@@_header_prev_last_name_tl }
+      \prop_get:NnNTF \g_@@_header_page_first_prop
+        {#1} \l_@@_tmpa_tl
+        { \tl_gset:NV \pnhdpagefirst \l_@@_tmpa_tl }
+        { \tl_gset:NV \pnhdpagefirst \g_@@_header_prev_last_page_tl }
+      \prop_get:NnNTF \g_@@_header_page_last_prop
+        {#1} \l_@@_tmpa_tl
+        {
+          \tl_gset:NV \pnhdpagelast \l_@@_tmpa_tl
+          \tl_gset:NV \g_@@_header_prev_last_page_tl
+            \l_@@_tmpa_tl
+        }
+        { \tl_gset:NV \pnhdpagelast \g_@@_header_prev_last_page_tl }
+      \prop_get:NnNTF \g_@@_header_chap_first_prop
+        {#1} \l_@@_tmpa_tl
+        { \tl_gset:NV \pnhdchapfirst \l_@@_tmpa_tl }
+        { \tl_gset:NV \pnhdchapfirst \g_@@_header_prev_last_chap_tl }
+      \prop_get:NnNTF \g_@@_header_chap_last_prop
+        {#1} \l_@@_tmpa_tl
+        {
+          \tl_gset:NV \pnhdchaplast \l_@@_tmpa_tl
+          \tl_gset:NV \g_@@_header_prev_last_chap_tl
+            \l_@@_tmpa_tl
+        }
+        { \tl_gset:NV \pnhdchaplast \g_@@_header_prev_last_chap_tl }
+      \prop_get:NnNTF \g_@@_header_sect_first_prop
+        {#1} \l_@@_tmpa_tl
+        { \tl_gset:NV \pnhdsectfirst \l_@@_tmpa_tl }
+        { \tl_gset:NV \pnhdsectfirst \g_@@_header_prev_last_sect_tl }
+      \prop_get:NnNTF \g_@@_header_sect_last_prop
+        {#1} \l_@@_tmpa_tl
+        {
+          \tl_gset:NV \pnhdsectlast \l_@@_tmpa_tl
+          \tl_gset:NV \g_@@_header_prev_last_sect_tl
+            \l_@@_tmpa_tl
+        }
+        { \tl_gset:NV \pnhdsectlast \g_@@_header_prev_last_sect_tl }
+      \prop_get:NnNTF \g_@@_header_name_first_prop
+        {#1} \l_@@_tmpa_tl
+        { \tl_gset:NV \pnhdnamefirst \l_@@_tmpa_tl }
+        { \tl_gset:NV \pnhdnamefirst \g_@@_header_prev_last_name_tl }
+      \prop_get:NnNTF \g_@@_header_name_last_prop
+        {#1} \l_@@_tmpa_tl
+        {
+          \tl_gset:NV \pnhdnamelast \l_@@_tmpa_tl
+          \tl_gset:NV \g_@@_header_prev_last_name_tl
+            \l_@@_tmpa_tl
+        }
+        { \tl_gset:NV \pnhdnamelast \g_@@_header_prev_last_name_tl }
     \group_end:
   }
 \cs_generate_variant:Nn \@@_set_headers_vars:n { e }
@@ -2182,7 +2708,7 @@
 %   \cs{@@_set_headers_vars_first:} must set a label and retrieve its value to
 %   be able to have a reliable value of its own page.
 %    \begin{macrocode}
-\AddToHook { shipout/before } [ postnotes/header ]
+\AddToHook { shipout/before } [ ./header ]
   { \@@_set_headers_vars_next: }
 \bool_new:N \g_@@_header_vars_next_bool
 \cs_new_protected:Npn \@@_set_headers_vars_next:
@@ -2233,22 +2759,21 @@
 % \subsection*{\cs{caption}}
 %
 % For \cs{caption}'s possible two passes.  This catches more than just
-% captions, of course, but is not overkill.
+% captions, of course, but is not overkill.  A hook to \cs{@makecaption} would
+% be better, but \pkg{ltcmdhooks} does not allow it, and using lower level
+% methods for this is a bad idea.
 %
 % From the user's perspective, one-line captions will just work.  For two-line
-% captions, there are two alternatives: i) decrement the counter by 1
-% \texttt{\textbackslash{}addtocounter\{postnote\}\{-1\}} before the caption,
-% then call \cs{postnote} inside the caption; or ii) right before the caption,
-% call
+% captions, there are two alternatives: i)
+% \texttt{\textbackslash{}stepcounter\{postnote\}} before the caption, then
+% call \cs{postnote} with \texttt{mark=\textbackslash{}arabic\{postnote\}}; or
+% ii) right before the caption, call
 % \texttt{\textbackslash{}postnote[nomark]\{\textbackslash{}label\{mynote\}...\}},
 % then use \texttt{\textbackslash{}postnoteref\{mynote\}} inside the caption.
 %
 %    \begin{macrocode}
-\AddToHook { postnotes/note/begin } [ postnotes ]
-  {
-    \cs_if_exist:NT \@captype
-      { \bool_set_true:N \l_@@_maybe_multi_bool }
-  }
+\AddToHook { postnotes/note/begin } [ ./compat/caption ]
+  { \cs_if_exist:NT \@captype { \postnotesetup { maybemulti } } }
 %    \end{macrocode}
 %
 %
@@ -2259,13 +2784,13 @@
 %
 %
 %    \begin{macrocode}
-\AddToHook { package/biblatex/after }
+\AddToHook { package/biblatex/after } [ ./compat/biblatex ]
   {
 %    \end{macrocode}
 % Let \pkg{biblatex} know we are in a ``notes'' context.  See
 % \url{https://tex.stackexchange.com/a/304464}, including comments.
 %    \begin{macrocode}
-    \AddToHook { postnotes/print/begin } [ postnotes ]
+    \AddToHook { postnotes/print/begin } [ postnotes/compat/biblatex ]
       { \toggletrue { blx at footnote } }
 %    \end{macrocode}
 % Make \pkg{biblatex}'s \cs{mkbibendnote} use \cs{postnote}.  This is very
@@ -2274,11 +2799,10 @@
 % \texttt{\textbackslash{}RemoveFromHook\{begindocument/before\}[postnotes/mkbibendnote]}
 % in the preamble.
 %    \begin{macrocode}
-    \AddToHook { begindocument/before } [ postnotes/mkbibendnote ]
+    \AddToHook { begindocument/before } [ postnotes/compat/biblatex ]
       {
         \cs_set:Npn \blx at theendnote { \postnote }
-        \cs_set:Npn \blx at theendnotetext
-          { \blx at err@endnote \footnotetext }
+        \cs_set:Npn \blx at theendnotetext { \blx at err@endnote \footnotetext }
       }
   }
 %    \end{macrocode}
@@ -2308,12 +2832,12 @@
 % The attempt was the following (currently ``gobbled'' from the package):
 %
 %    \begin{macrocode}
-\AddToHook { package/biblatex/after }
+\AddToHook { package/biblatex/after } [ ./compat/biblatex ]
   {
 %    \end{macrocode}
 % Store \pkg{biblatex} variables for each note.
 %    \begin{macrocode}
-    \AddToHook { postnotes/note/store } [ postnotes ]
+    \AddToHook { postnotes/note/store } [ postnotes/compat/biblatex ]
       {
         \prop_gput:cne { \@@_data_name:e { \l_postnotes_note_id_tl } }
           { biblatex at refsection } { \int_use:N \c at refsection }
@@ -2328,7 +2852,7 @@
 %    \end{macrocode}
 % \pkg{biblatex} setup, once for \cs{printpostnotes} call.
 %    \begin{macrocode}
-    \AddToHook { postnotes/print/begin } [ postnotes ]
+    \AddToHook { postnotes/print/begin } [ postnotes/compat/biblatex ]
       {
         \@@_biblatex_endrefcontext_local:
         \@@_biblatex_citereset_local:
@@ -2336,7 +2860,7 @@
 %    \end{macrocode}
 % Restore \pkg{biblatex} variables for each note.
 %    \begin{macrocode}
-    \AddToHook { postnotes/print/note/begin } [ postnotes ]
+    \AddToHook { postnotes/print/note/begin } [ postnotes/compat/biblatex ]
       {
         \@@_prop_get:nnN { \l_postnotes_print_note_id_tl }
           { biblatex at refsection } \l_@@_restore_tmp_tl
@@ -2454,11 +2978,11 @@
 % \cs{l_@@_biblatex_orig_refsection_tl}.
 %
 %    \begin{macrocode}
-\AddToHook { package/biblatex/after }
+\AddToHook { package/biblatex/after } [ ./compat/biblatex ]
   {
     \tl_new:N \l_@@_biblatex_orig_refsection_tl
     \tl_new:N \g_@@_biblatex_prev_refsection_tl
-    \AddToHook { postnotes/print/begin } [ postnotes ]
+    \AddToHook { postnotes/print/begin } [ postnotes/compat/biblatex ]
       {
         \tl_set:Ne \l_@@_biblatex_orig_refsection_tl
           { \int_use:N \c at refsection }
@@ -2465,7 +2989,7 @@
         \tl_gset:Ne \g_@@_biblatex_prev_refsection_tl
           { \l_@@_biblatex_orig_refsection_tl }
      }
-    \AddToHook { postnotes/print/note/begin } [ postnotes ]
+    \AddToHook { postnotes/print/note/begin } [ postnotes/compat/biblatex ]
       {
         \@@_prop_get:nnN { \l_postnotes_print_note_id_tl }
           { biblatex at refsection } \l_@@_restore_tmp_tl
@@ -2478,10 +3002,10 @@
             \tl_gset_eq:NN \g_@@_biblatex_prev_refsection_tl
               \l_@@_restore_tmp_tl
             \group_begin:
-            \cs_set_eq:NN \label \use_none:n
-            \cs_set_eq:NN \blx at info \use_none:n
-            \blx at endrefsection
-            \refsection
+              \cs_set_eq:NN \label \use_none:n
+              \cs_set_eq:NN \blx at info \use_none:n
+              \blx at endrefsection
+              \refsection
             \group_end:
           }
       }
@@ -2495,17 +3019,17 @@
 %
 % \subsection*{\pkg{zref-user}}
 %
-% \begin{macro}{\l_@@_note_zlabel_tl}
+% \begin{macro}{\l_@@_note_zlabel_str}
 %   Even though the \opt{zlabel} option is provided only when \pkg{zref-user}
-%   is loaded, \cs{l_@@_note_zlabel_tl} must be unconditionally defined, since
-%   it is presumed to exist by \cs{@@_set_user_labels:}.
+%   is loaded, \cs{l_@@_note_zlabel_str} must be unconditionally defined,
+%   since it is presumed to exist by \cs{@@_set_user_labels:} and elsewhere.
 %    \begin{macrocode}
-\tl_new:N \l_@@_note_zlabel_tl
+\str_new:N \l_@@_note_zlabel_str
 %    \end{macrocode}
 % \end{macro}
 %
 %    \begin{macrocode}
-\AddToHook { package/zref-user/after }
+\AddToHook { package/zref-user/after } [ ./compat/zref-user ]
   {
 %    \end{macrocode}
 % Provide \opt{zlabel} option.
@@ -2512,10 +3036,16 @@
 %    \begin{macrocode}
     \keys_define:nn { postnotes/note }
       {
-        zlabel .tl_set:N = \l_@@_note_zlabel_tl ,
+        zlabel .str_set:N = \l_@@_note_zlabel_str ,
         zlabel .value_required:n = true ,
       }
 %    \end{macrocode}
+% Provide property to store the mark for measuring passes.
+%    \begin{macrocode}
+    \zref at newprop { postnote at mark } [] { \l_@@_mark_tl }
+    \AddToHook { postnotes/note/begin }  [ postnotes/compat/zref-user ]
+      { \zref at localaddprop { main } { postnote at mark } }
+%    \end{macrocode}
 %
 % \begin{macro}[int]{\postnotezref}
 %   Provide \cs{postnotezref}.
@@ -2538,24 +3068,24 @@
     \cs_new_protected:Npn \@@_note_zref:nn #1#2
       {
         \group_begin:
-        \tl_set:Nn \l_@@_note_zref_zlabel_tl {#2}
-        \@@_typeset_mark_wrapper:nnn
-          {
-            \bool_lazy_all:nTF
-              {
-                { ! #1 }
-                { \l_@@_hyperlink_bool }
-                { \l_@@_zrefhyperref_bool }
-              }
-              {
-                \hyperlink
-                  { \zref at extractdefault {#2} { anchor } { } }
-                  { \@@_make_mark:nnn { \zref{#2} } { } { } }
-              }
-              { \@@_make_mark:nnn { \zref{#2} } { } { } }
-          }
-          { \tag_socket_use:n { postnotes/postnotezref/begin } }
-          { \tag_socket_use:n { postnotes/postnotezref/end }   }
+          \tl_set:Nn \l_@@_note_zref_zlabel_tl {#2}
+          \@@_typeset_mark_wrapper:nnn
+            {
+              \bool_lazy_all:nTF
+                {
+                  { ! #1 }
+                  { \l_@@_hyperlink_bool }
+                  { \l_@@_zrefhyperref_bool }
+                }
+                {
+                  \hyperlink
+                    { \zref at extractdefault {#2} { anchor } { } }
+                    { \@@_make_mark:nnn { \zref{#2} } { } { } }
+                }
+                { \@@_make_mark:nnn { \zref{#2} } { } { } }
+            }
+            { \tag_socket_use:n { postnotes/postnotezref/begin } }
+            { \tag_socket_use:n { postnotes/postnotezref/end }   }
         \group_end:
       }
 %    \end{macrocode}
@@ -2567,7 +3097,7 @@
 %
 %    \begin{macrocode}
 \bool_new:N \l_@@_zrefhyperref_bool
-\AddToHook { package/zref-hyperref/after }
+\AddToHook { package/zref-hyperref/after } [ ./compat/zref-hyperref ]
   { \bool_set_true:N \l_@@_zrefhyperref_bool }
 %    \end{macrocode}
 %
@@ -2575,7 +3105,7 @@
 % \subsection*{\pkg{zref-clever}}
 %
 %    \begin{macrocode}
-\AddToHook { package/zref-clever/after }
+\AddToHook { package/zref-clever/after } [ ./compat/zref-clever ]
   {
     \zcsetup
       {
@@ -2582,7 +3112,7 @@
         countertype = { postnote = endnote } ,
         countertype = { postnotetext = endnote } ,
       }
-    \AddToHook { postnotes/print/begin } [ postnotes ]
+    \AddToHook { postnotes/print/begin } [ postnotes/compat/zref-clever ]
       { \zcsetup { counterresetby = { postnotetext = postnotesection } } }
   }
 %    \end{macrocode}
@@ -2591,11 +3121,11 @@
 % \subsection*{\pkg{zref-check}}
 %
 %    \begin{macrocode}
-\AddToHook { package/zref-check/after }
+\AddToHook { package/zref-check/after } [ ./compat/zref-check ]
   {
     \IfPackageAtLeastTF { zref-check } { 2022-07-05 }
       {
-        \AddToHook { postnotes/note/store } [ postnotes ]
+        \AddToHook { postnotes/note/store } [ postnotes/compat/zref-check ]
           {
             \prop_gput:cne { \@@_data_name:e { \l_postnotes_note_id_tl } }
               { zref-check at abschap } { \int_use:N \c at zc@abschap }
@@ -2602,7 +3132,7 @@
             \prop_gput:cne { \@@_data_name:e { \l_postnotes_note_id_tl } }
               { zref-check at abssec } { \int_use:N \c at zc@abssec }
           }
-        \AddToHook { postnotes/print/note/begin } [ postnotes ]
+        \AddToHook { postnotes/print/note/begin } [ postnotes/compat/zref-check ]
           {
             \@@_prop_get:nnN { \l_postnotes_print_note_id_tl }
               { zref-check at abschap } \l_@@_restore_tmp_tl
@@ -2620,13 +3150,13 @@
 % \subsection*{\pkg{amsmath}}
 %
 %    \begin{macrocode}
-\AddToHook { package/amsmath/after }
+\AddToHook { package/amsmath/after } [ ./compat/amsmath ]
   {
 %    \end{macrocode}
 % Testing for \cs{ifmeasuring@} is sufficient to get things right for the
 % measuring passes in math environments.
 %    \begin{macrocode}
-    \AddToHook { postnotes/note/inhibit } [ postnotes ]
+    \AddToHook { postnotes/note/inhibit } [ postnotes/compat/amsmath ]
       {
         \legacy_if:nT { measuring@ }
           {
@@ -2640,24 +3170,21 @@
 % \pkg{amsmath}), poses problems if its own.  Despite my best efforts, I could
 % not salvage things from the use of \cs{mathchoice} and the redefinitions of
 % \cs{setcounter} and \cs{addtocounter} performed by \pkg{amstext}.  Setting
-% \cs{l_@@_maybe_multi_bool} when \texttt{firstchoice@} is \texttt{false}
-% grants us a working situation for display style.  But the use of
-% \cs{postnote} inside \cs{text} (and, if \pkg{amsmath} is loaded,
-% \cs{textnormal}, \cs{textup}, etc.) in inline math environments is not
-% supported.  If a note really needs to be there, one can use the \opt{nomark}
-% option and \cs{postnoteref}.  Things should work in text mode and in display
-% style.  For some related discussion with regard to footnotes,
-% see \url{https://tex.stackexchange.com/a/82820} and, in particular, Barbara
+% \opt{maybemulti} when \texttt{firstchoice@} is \texttt{false} grants us a
+% working situation for display style.  But the use of \cs{postnote} inside
+% \cs{text} (and, if \pkg{amsmath} is loaded, \cs{textnormal}, \cs{textup},
+% etc.) in inline math environments is not supported.  If a note really needs
+% to be there, one can use the \opt{nomark} option and \cs{postnoteref}.
+% Things should work in text mode and in display style.  For some related
+% discussion with regard to footnotes, see
+% \url{https://tex.stackexchange.com/a/82820} and, in particular, Barbara
 % Beeton's comment: ``This is certainly bravura code.  I do hope it doesn't
 % result in a request to add \cs{footnote} capabilities to \pkg{amsmath}'s
 % multi-line display facilities.  (The answer will almost certainly be "no".
 % We agree with Kopka \& Daly.)''
 %    \begin{macrocode}
-    \AddToHook { postnotes/note/begin } [ postnotes ]
-      {
-        \legacy_if:nF { firstchoice@ }
-          { \bool_set_true:N \l_@@_maybe_multi_bool }
-      }
+    \AddToHook { postnotes/note/begin } [ postnotes/compat/amsmath ]
+      { \legacy_if:nF { firstchoice@ } { \postnotesetup { maybemulti } } }
   }
 %    \end{macrocode}
 %
@@ -2665,12 +3192,12 @@
 % \subsection*{\pkg{csquotes}}
 %
 %    \begin{macrocode}
-\AddToHook { package/csquotes/after }
+\AddToHook { package/csquotes/after } [ ./compat/csquotes ]
   {
     \bool_new:N \l_@@_csquotes_measuring_bool
     \BlockquoteDisable
       { \bool_set_true:N \l_@@_csquotes_measuring_bool }
-    \AddToHook { postnotes/note/inhibit } [ postnotes ]
+    \AddToHook { postnotes/note/inhibit } [ postnotes/compat/csquotes ]
       {
         \bool_if:NT \l_@@_csquotes_measuring_bool
           {
@@ -2692,15 +3219,15 @@
 % \url{https://tex.stackexchange.com/a/352134}.
 %
 %    \begin{macrocode}
-\AddToHook { package/tabularx/after }
+\AddToHook { package/tabularx/after } [ ./compat/tabularx ]
   {
     \bool_new:N \l_@@_tabularx_inside_env_bool
-    \AddToHook { env/tabularx/begin } [ postnotes ]
+    \AddToHook { env/tabularx/begin } [ postnotes/compat/tabularx ]
       {
         \bool_set_true:N \l_@@_tabularx_inside_env_bool
         \cs_set_eq:NN \@@_tabularx_saved_write:Nn \write
       }
-    \AddToHook { postnotes/note/inhibit } [ postnotes ]
+    \AddToHook { postnotes/note/inhibit } [ postnotes/compat/tabularx ]
       {
         \bool_lazy_and:nnT
           { \l_@@_tabularx_inside_env_bool }
@@ -2711,6 +3238,14 @@
             \bool_set_true:N \l_@@_print_plain_mark_stepcounter_bool
           }
       }
+    \AddToHook { package/xltabular/after } [ postnotes/compat/xltabular ]
+      {
+        \AddToHook { env/xltabular/begin } [ postnotes/compat/xltabular ]
+          {
+            \bool_set_true:N \l_@@_tabularx_inside_env_bool
+            \cs_set_eq:NN \@@_tabularx_saved_write:Nn \write
+          }
+      }
   }
 %    \end{macrocode}
 %
@@ -2718,7 +3253,7 @@
 % \subsection*{\pkg{tabularray}}
 %
 %    \begin{macrocode}
-\AddToHook { package/tabularray/after }
+\AddToHook { package/tabularray/after } [ ./compat/tabularray ]
   {
 %    \end{macrocode}
 % Since version \texttt{2023A}, from 2023-03-01, \pkg{tabularray} offers the
@@ -2727,7 +3262,7 @@
 % and \url{https://github.com/lvjr/tabularray/issues/179} (thanks
 % \contributor{Ulrike Fischer}).
 %    \begin{macrocode}
-    \bool_if_exist:NTF \lTblrMeasuringBool
+    \bool_if_exist:NT \lTblrMeasuringBool
       {
 %    \end{macrocode}
 % I'd be inclined to restrict the inhibition effect to known \pkg{tabularray}
@@ -2739,10 +3274,10 @@
 % \cs{l_@@_print_plain_mark_stepcounter_bool} to true presumes
 % \pkg{tabularray}'s \texttt{counter} module is enabled.  But, since this is
 % the only way to get the measuring right in this context if there is more
-% than one \cs{postnote} inside a given table, pkg{postnotes} expects and
+% than one \cs{postnote} inside a given table, \pkg{postnotes} expects and
 % requires the \texttt{counter} module.
 %    \begin{macrocode}
-        \AddToHook { postnotes/note/inhibit } [ postnotes ]
+        \AddToHook { postnotes/note/inhibit } [ postnotes/compat/tabularray ]
           {
             \bool_if:NT \lTblrMeasuringBool
               {
@@ -2752,21 +3287,6 @@
               }
           }
       }
-      {
-%    \end{macrocode}
-% If the new boolean is not yet available, we use \cs{@@_verify_multipass:N}
-% to distinguish a trial/measure pass from the final one.
-%    \begin{macrocode}
-        \clist_map_inline:nn
-          {
-            tblr , longtblr , talltblr , booktabs ,
-            longtabs , talltabs , +array
-          }
-          {
-            \AddToHook { env/#1/begin } [ postnotes ]
-              { \bool_set_true:N \l_@@_maybe_multi_bool }
-          }
-      }
   }
 %    \end{macrocode}
 %
@@ -2886,14 +3406,14 @@
 %
 % 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
+% can be referenced by arbitrarily many \cs{postnoteref}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
+% to at \cs{postnoteref}.  However, at \cs{postnoteref} 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{printpostnotes}, 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
@@ -2916,9 +3436,10 @@
 %    \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/nomark/begin }{ 0 }
+\socket_new:nn { tagsupport/postnotes/nomark/end }{ 0 }
+\socket_new:nn { tagsupport/postnotes/multisep/begin }{ 0 }
+\socket_new:nn { tagsupport/postnotes/multisep/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 }
@@ -2966,15 +3487,15 @@
           }
         \@@_tagsup_store_sctructnum:nN
           { postnotemark } \l_postnotes_note_id_tl
-        \tag_mc_begin:n{}
+        \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{}
+        \tag_mc_begin_pop:n { }
       }
-    \socket_new_plug:nnn { tagsupport/postnotes/mark/nomark } { default }
+    \socket_new_plug:nnn { tagsupport/postnotes/nomark/begin } { default }
       {
         \tag_struct_begin:n
           {
@@ -2984,26 +3505,28 @@
           }
         \@@_tagsup_store_sctructnum:nN
           { postnotemark } \l_postnotes_note_id_tl
-        \tag_struct_end: % NonStruct
       }
+    \socket_new_plug:nnn { tagsupport/postnotes/nomark/end } { default }
+      { \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_assign_plug:nn { tagsupport/postnotes/nomark/begin } { default }
+    \socket_assign_plug:nn { tagsupport/postnotes/nomark/end } { default }
 %    \end{macrocode}
 % \opt{multiple}
 %    \begin{macrocode}
-    \socket_new_plug:nnn { tagsupport/postnotes/multsep/begin } { default }
+    \socket_new_plug:nnn { tagsupport/postnotes/multisep/begin } { default }
       {
         \tag_mc_end_push:
         \tag_mc_begin:n { artifact }
       }
-    \socket_new_plug:nnn { tagsupport/postnotes/multsep/end } { default }
+    \socket_new_plug:nnn { tagsupport/postnotes/multisep/end } { default }
       {
         \tag_mc_end:
-        \tag_mc_begin_pop:n{}
+        \tag_mc_begin_pop:n { }
       }
-    \socket_assign_plug:nn { tagsupport/postnotes/multsep/begin } { default }
-    \socket_assign_plug:nn { tagsupport/postnotes/multsep/end } { default }
+    \socket_assign_plug:nn { tagsupport/postnotes/multisep/begin } { default }
+    \socket_assign_plug:nn { tagsupport/postnotes/multisep/end } { default }
 %    \end{macrocode}
 % \cs{printpostnotes}
 %    \begin{macrocode}
@@ -3043,18 +3566,18 @@
     \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 }
-         }
+          {
+            \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
-         }
+          {
+            \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 }
@@ -3077,13 +3600,13 @@
             \tag_struct_begin:n { tag=text-unit }
             \tag_struct_begin:n { tag=text }
             \tag_tool:n { para/tagging=true }
-            \tag_mc_begin:n{}
+            \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{}
+            \tag_mc_begin:n { }
           }
       }
     \socket_new_plug:nnn { tagsupport/postnotes/printtext/end } { default }
@@ -3197,11 +3720,11 @@
 %    \begin{macrocode}
     \AddToHook { postnotes/note/store } [ postnotes/tagsup ]
       {
-        \tl_if_empty:NF \l_@@_note_label_tl
+        \str_if_empty:NF \l_@@_note_label_str
           {
             \prop_gput:cnV
               { \@@_data_name:e { \l_postnotes_note_id_tl } }
-              { label } \l_@@_note_label_tl
+              { label } \l_@@_note_label_str
           }
       }
     \AddToHook { package/zref-user/after } [ postnotes/tagsup ]
@@ -3208,11 +3731,11 @@
       {
         \AddToHook { postnotes/note/store } [ postnotes/tagsup ]
           {
-            \tl_if_empty:NF \l_@@_note_zlabel_tl
+            \str_if_empty:NF \l_@@_note_zlabel_str
               {
                 \prop_gput:cnV
                   { \@@_data_name:e { \l_postnotes_note_id_tl } }
-                  { zlabel } \l_@@_note_zlabel_tl
+                  { zlabel } \l_@@_note_zlabel_str
               }
           }
       }
@@ -3286,7 +3809,7 @@
 % 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
+% immediately and a \cs{posnoteref} is made before \cs{printpostnotes}, and
 % also so that the ``main'' reference always comes first at the list.
 %    \begin{macrocode}
     \AddToHook { tagpdf/finish/before } [ postnotes/tagsup ]
@@ -3349,13 +3872,13 @@
               }
               { \tag_struct_begin:n { tag = endnotemark } }
           }
-        \tag_mc_begin:n{}
+        \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{}
+        \tag_mc_begin_pop:n { }
       }
     \socket_assign_plug:nn { tagsupport/postnotes/postnoteref/begin } { default }
     \socket_assign_plug:nn { tagsupport/postnotes/postnoteref/end } { default }
@@ -3413,13 +3936,13 @@
                   }
                   { \tag_struct_begin:n { tag = endnotemark } }
               }
-            \tag_mc_begin:n{}
+            \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{}
+            \tag_mc_begin_pop:n { }
           }
         \socket_assign_plug:nn { tagsupport/postnotes/postnotezref/begin } { default }
         \socket_assign_plug:nn { tagsupport/postnotes/postnotezref/end } { default }
@@ -3653,8 +4176,8 @@
 %
 % \PrintIndex
 %
+% \endinput
 %
-
 % Local Variables:
 % jinx-local-words: "endnote endnotes"
 % End:

Modified: trunk/Master/texmf-dist/tex/latex/postnotes/postnotes.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/postnotes/postnotes.sty	2024-11-05 20:18:50 UTC (rev 72769)
+++ trunk/Master/texmf-dist/tex/latex/postnotes/postnotes.sty	2024-11-05 20:18:59 UTC (rev 72770)
@@ -52,11 +52,12 @@
         'postnotes' requires a LaTeX kernel \postnotes at required@kernel\space or newer.%
       }%
   }%
-\ProvidesExplPackage {postnotes} {2024-10-15} {0.3.0}
+\ProvidesExplPackage {postnotes} {2024-11-04} {0.4.0}
   {Endnotes for LaTeX}
 \tl_new:N \l__postnotes_tmpa_tl
 \tl_new:N \l__postnotes_tmpb_tl
 \seq_new:N \l__postnotes_tmpa_seq
+\seq_new:N \l__postnotes_tmpb_seq
 \box_new:N \l__postnotes_tmpa_box
 \cs_new:Npn \__postnotes_data_name:n #1
   { g__postnotes_ #1 _data_prop }
@@ -116,14 +117,58 @@
 \cs_new_protected:Npn \__postnotes_prop_gclear:n #1
   { \prop_gclear:c { \__postnotes_data_name:e {#1} } }
 \tl_const:Nn \c__postnotes_ref_prefix_tl { postnote at r }
-\cs_new_protected:Npe \post at note #1#2
-  { \exp_not:N \@newl at bel { \c__postnotes_ref_prefix_tl } {#1} {#2} }
+\seq_new:N \g__postnotes_labelseq_seq
+\int_new:N \g__postnotes_postnote_counteraux_int
+\prop_new:N \g__postnotes_counteraux_prop
+\bool_new:N \g__postnotes_firstrun_bool
+\bool_gset_true:N \g__postnotes_firstrun_bool
+\cs_new_protected:Npn \__postnotes_store_labelseq:nn #1#2
+  {
+    \bool_lazy_any:nT
+      {
+        { \str_if_eq_p:nn {#1} { mark } }
+        { \str_if_eq_p:nn {#1} { section } }
+        { \str_if_eq_p:nn {#1} { preprint } }
+      }
+      { \seq_gput_right:Nn \g__postnotes_labelseq_seq { {#1} {#2} } }
+  }
+\cs_new_protected:Npn \__postnotes_step_counteraux:nnn #1#2#3
+  {
+    \bool_lazy_and:nnT
+      { \g__postnotes_counteraux_bool }
+      { \str_if_eq_p:nn {#1} { mark } }
+      {
+        \int_gadd:Nn \g__postnotes_postnote_counteraux_int { #3 }
+        \prop_gput:Nne \g__postnotes_counteraux_prop { #2 }
+          { \int_use:N \g__postnotes_postnote_counteraux_int }
+      }
+  }
+\cs_new_protected:Npe \post at note #1#2#3#4
+  {
+    \exp_not:N \bool_gset_false:N \exp_not:N \g__postnotes_firstrun_bool
+    \exp_not:N \__postnotes_store_labelseq:nn { #1 } { #2 }
+    \exp_not:N \__postnotes_step_counteraux:nnn { #1 } { #2 } { #4 }
+    \exp_not:N \@newl at bel { \c__postnotes_ref_prefix_tl } { #1 @ #2 } { #3 }
+  }
 \AddToHook { begindocument }
   {
     \legacy_if:nT { @filesw }
       {
         \iow_now:Ne \@mainaux
-          { \token_to_str:N \providecommand \token_to_str:N \post at note [2]{} }
+          {
+            \token_to_str:N \providecommand
+            \token_to_str:N \post at note [4] { }
+          }
+        \iow_now:Ne \@mainaux
+          {
+            \token_to_str:N \providecommand
+            \token_to_str:N \postnote at setcounteraux [1] { }
+          }
+        \iow_now:Ne \@mainaux
+          {
+            \token_to_str:N \providecommand
+            \token_to_str:N \postnote at addtocounteraux [1] { }
+          }
       }
   }
 \AddToHook { include/before }
@@ -130,27 +175,46 @@
   {
     \legacy_if:nT { @filesw }
       {
-        \iow_now:Ne \@partaux
-          { \token_to_str:N \providecommand \token_to_str:N \post at note [2]{} }
+        \iow_now:Ne \@mainaux
+          {
+            \token_to_str:N \providecommand
+            \token_to_str:N \post at note [4] { }
+          }
+        \iow_now:Ne \@mainaux
+          {
+            \token_to_str:N \providecommand
+            \token_to_str:N \postnote at setcounteraux [1] { }
+          }
+        \iow_now:Ne \@mainaux
+          {
+            \token_to_str:N \providecommand
+            \token_to_str:N \postnote at addtocounteraux [1] { }
+          }
       }
   }
-\cs_new_protected:Npn \__postnotes_set_label:nn #1#2
+\cs_new_protected:Npn \__postnotes_set_label:nnnn #1#2#3#4
   {
     \legacy_if:nT { @filesw }
       {
-        \iow_shipout_x:Nn \@auxout
-          { \token_to_str:N \post at note { #1 } { #2 } }
+        \iow_shipout_e:Nn \@auxout
+          { \token_to_str:N \post at note { #1 } { #2 } { #3 } { #4 } }
       }
   }
-\cs_new_protected:Npn \__postnotes_set_mark_page_label:n #1
-  { \__postnotes_set_label:nn { mark@ #1 } { \thepage } }
-\cs_generate_variant:Nn \__postnotes_set_mark_page_label:n { e }
+\cs_new_protected:Npn \__postnotes_set_mark_page_label:nn #1#2
+  { \__postnotes_set_label:nnnn { mark } { #1 } { \thepage } { #2 } }
+\cs_generate_variant:Nn \__postnotes_set_mark_page_label:nn { ee }
+\cs_new_protected:Npn \__postnotes_set_section_page_label:n #1
+  { \__postnotes_set_label:nnnn { section } { #1 } { \thepage } { } }
+\cs_generate_variant:Nn \__postnotes_set_section_page_label:n { e }
 \cs_new_protected:Npn \__postnotes_set_text_page_label:n #1
-  { \__postnotes_set_label:nn { text@ #1 } { \int_use:N \c at page } }
+  { \__postnotes_set_label:nnnn { text } { #1 } { \int_use:N \c at page } { } }
 \cs_generate_variant:Nn \__postnotes_set_text_page_label:n { e }
 \cs_new_protected:Npn \__postnotes_set_print_page_label:n #1
-  { \__postnotes_set_label:nn { print@ #1 } { \int_use:N \c at page } }
+  { \__postnotes_set_label:nnnn { print } { #1 } { \int_use:N \c at page } { } }
 \cs_generate_variant:Nn \__postnotes_set_print_page_label:n { e }
+\cs_new_protected:Npn \__postnotes_set_pre_print_label:n #1
+  { \__postnotes_set_label:nnnn { preprint } { #1 } { } { } }
+\cs_generate_variant:Nn \__postnotes_set_pre_print_label:n { e }
 \cs_new_protected:Npn \__postnotes_get_pageref:Nn #1#2
   {
     \cs_if_exist:cTF { \c__postnotes_ref_prefix_tl @ #2 }
@@ -271,6 +335,36 @@
     postprintnote .tl_set:N = \l__postnotes_post_printnote_tl ,
     postprintnote .value_required:n = true ,
   }
+\keys_define:nn { postnotes/setup }
+  {
+    style .choice: ,
+    style / endnotes .meta:n =
+      {
+        listenv = none ,
+        format =
+          {
+            \footnotesize
+            \setlength { \rightskip } { 0pt   }
+            \setlength { \leftskip  } { 0pt   }
+            \setlength { \parindent } { 1.8em }
+          } ,
+        maketextmark =
+          {
+            \hbox_set:Nn \l__postnotes_tmpa_box
+              { \@textsuperscript { \normalfont ##1 } }
+            \skip_horizontal:n { - \box_wd:N \l__postnotes_tmpa_box }
+            ##2 \box_use:N \l__postnotes_tmpa_box ##3
+          } ,
+      } ,
+    style / pagenote .meta:n =
+      {
+        listenv = none ,
+        format = { } ,
+        pretextmark = { \noindent } ,
+        maketextmark = { { \normalfont ##2 ##1 . ##3 } } ,
+        posttextmark = { ~ } ,
+      } ,
+  }
 \bool_new:N \l__postnotes_hyperlink_bool
 \bool_new:N \l__postnotes_hyperref_warn_bool
 \bool_new:N \l__postnotes_backlink_bool
@@ -325,67 +419,47 @@
   { 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
+\bool_new:N \l__postnotes_multiple_bool
 \tl_new:N \l__postnotes_saved_spacefactor_multi_tl
 \keys_define:nn { postnotes/setup }
   {
-    multiple .choice: ,
-    multiple / true .code:n =
+    multiple .bool_set:N = \l__postnotes_multiple_bool ,
+    multiple .default:n = true ,
+    multiple .initial:n = false ,
+    multisep .tl_set:N = \l__postnotes_multisep_tl ,
+    multisep .value_required:n = true ,
+    multisep .initial:n = {,} ,
+  }
+\cs_new_protected:Npn \__postnotes_multiple_prepare:
+  {
+    \bool_if:NT \l__postnotes_multiple_bool
       {
-        \cs_set_protected:Npn \__postnotes_multiple_prepare:
+        \kern -\c_postnotes_multi_notemarker_tl
+        \kern  \c_postnotes_multi_notemarker_tl
+        \scan_stop:
+      }
+  }
+\cs_new_protected:Npn \__postnotes_multiple_check:
+  {
+    \bool_if:NT \l__postnotes_multiple_bool
+      {
+        \dim_compare:nNnT
+          { \c_postnotes_multi_notemarker_tl } = { \lastkern }
           {
-            \kern -\c_postnotes_multi_notemarker_tl
-            \kern  \c_postnotes_multi_notemarker_tl
+            \tl_set:Ne \l__postnotes_saved_spacefactor_multi_tl
+              { \int_use:N \spacefactor }
+            \unkern
+            \unkern
+            \tag_socket_use:n { postnotes/multisep/begin }
+            \__postnotes_make_mark:Vnn \l__postnotes_multisep_tl { } { }
+            \tag_socket_use:n { postnotes/multisep/end }
+            \spacefactor \l__postnotes_saved_spacefactor_multi_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 }
   {
@@ -393,37 +467,68 @@
     sort .initial:n = true ,
     sort .default:n = true ,
   }
+\bool_new:N \l__postnotes_check_dupli_bool
+\bool_new:N \l__postnotes_check_floats_bool
 \keys_define:nn { postnotes/setup }
   {
-    style .choice: ,
-    style / endnotes .meta:n =
+    checkduplicates .bool_set:N = \l__postnotes_check_dupli_bool ,
+    checkduplicates .default:n = true ,
+    checkduplicates .initial:n = true ,
+    checkfloats .bool_set:N = \l__postnotes_check_floats_bool ,
+    checkfloats .default:n = true ,
+    checkfloats .initial:n = false ,
+  }
+\bool_new:N \l__postnotes_maybe_multi_bool
+\keys_define:nn { postnotes/setup }
+  {
+    maybemulti .bool_set:N = \l__postnotes_maybe_multi_bool ,
+    maybemulti .default:n = true ,
+    maybemulti .initial:n = false ,
+  }
+\bool_new:N \g__postnotes_counteraux_bool
+\keys_define:nn { postnotes/setup }
+  {
+    counteraux .bool_gset:N = \g__postnotes_counteraux_bool ,
+    counteraux .default:n = true ,
+    counteraux .initial:n = false ,
+  }
+\AddToHook { begindocument/before }
+  {
+    \bool_if:NT \g__postnotes_counteraux_bool
+      { \postnotesetup { sort=false } }
+    \keys_define:nn { postnotes/setup }
       {
-        listenv = none ,
-        format =
+        counteraux .code:n =
           {
-            \footnotesize
-            \setlength { \rightskip } { 0pt   }
-            \setlength { \leftskip  } { 0pt   }
-            \setlength { \parindent } { 1.8em }
+            \msg_warning:nnn { postnotes }
+              { option-preamble-only } { counteraux }
           } ,
-        pretextmark = { \par } ,
-        maketextmark =
-         {
-           \hbox_set:Nn \l__postnotes_tmpa_box
-             { \@textsuperscript { \normalfont ##1 } }
-           \skip_horizontal:n { - \box_wd:N \l__postnotes_tmpa_box }
-           ##2 \box_use:N \l__postnotes_tmpa_box ##3
-         } ,
-      } ,
-    style / pagenote .meta:n =
+      }
+  }
+\cs_new_protected:Npn \postnote at setcounteraux #1
+  { \int_gset:Nn \g__postnotes_postnote_counteraux_int { #1 } }
+\cs_new_protected:Npn \postnote at addtocounteraux #1
+  { \int_gadd:Nn \g__postnotes_postnote_counteraux_int { #1 } }
+\NewDocumentCommand \pnsetcounteraux { m }
+  {
+    \@bsphack
+    \legacy_if:nT { @filesw }
       {
-        listenv = none ,
-        format = { } ,
-        pretextmark = { \par\noindent } ,
-        maketextmark = { { \normalfont ##2 ##1 . ##3 } } ,
-        posttextmark = { ~ } ,
-      } ,
+        \iow_shipout_e:Nn \@auxout
+          { \token_to_str:N \postnote at setcounteraux { #1 } }
+      }
+    \@esphack
   }
+\NewDocumentCommand \pnaddtocounteraux { m }
+  {
+    \@bsphack
+    \legacy_if:nT { @filesw }
+      {
+        \iow_shipout_e:Nn \@auxout
+          { \token_to_str:N \postnote at addtocounteraux { #1 } }
+      }
+    \@esphack
+  }
 \NewDocumentCommand \postnotesetup { m }
   { \keys_set:nn { postnotes/setup } {#1} }
 \newcounter { postnote }
@@ -431,6 +536,9 @@
 \tl_new:N \l_postnotes_note_id_tl
 \tl_set:Nn \l_postnotes_note_id_tl { \int_use:N \g__postnotes_note_id_int }
 \seq_new:N \g__postnotes_queue_seq
+\int_new:N \l__postnotes_counteraux_step_int
+\tl_new:N \l__postnotes_mark_typeset_tl
+\tl_new:N \l__postnotes_note_set_labels_tl
 \NewDocumentCommand \postnote { O { } +m }
   { \__postnotes_note:nn {#1} {#2} }
 \NewHook { postnotes/note/begin }
@@ -437,40 +545,71 @@
 \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
-      {
-        \int_gincr:N \g__postnotes_note_id_int
-        \tl_if_empty:NT \l__postnotes_mark_tl
-          {
-            \stepcounter { postnote }
-            \tl_set:Ne \l__postnotes_mark_tl { \thepostnote }
-          }
-        \seq_gput_right:Ne \g__postnotes_queue_seq
-          { \l_postnotes_note_id_tl }
-        \UseHook { postnotes/note/begin }
-        \cs_set:Npn \@currentcounter { postnote }
-        \cs_set:Npe \@currentlabel { \p at postnote \l__postnotes_mark_tl }
-        \MakeLinkTarget* { postnote. \l_postnotes_note_id_tl .mark }
-        \__postnotes_set_mark_page_label:e { \l_postnotes_note_id_tl }
-        \__postnotes_set_user_labels:
-        \__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
-          }
-      }
+      \keys_set:nn { postnotes/note } {#1}
+      \bool_if:NT \l__postnotes_nomark_bool { \@bsphack }
+      \__postnotes_inhibit_note:F
+        {
+          \int_gincr:N \g__postnotes_note_id_int
+          \tl_if_empty:NTF \l__postnotes_mark_tl
+            {
+              \stepcounter { postnote }
+              \int_set:Nn \l__postnotes_counteraux_step_int { 1 }
+              \bool_if:NT \g__postnotes_counteraux_bool
+                {
+                  \exp_args:NNe \prop_gpop:NnNT \g__postnotes_counteraux_prop
+                    { \l_postnotes_note_id_tl } \l__postnotes_tmpa_tl
+                    { \int_set:Nn \c at postnote { \l__postnotes_tmpa_tl } }
+                  \tl_clear:N \l__postnotes_tmpa_tl
+                }
+              \tl_set:Ne \l__postnotes_mark_tl { \thepostnote }
+            }
+            { \int_set:Nn \l__postnotes_counteraux_step_int { 0 } }
+          \UseHook { postnotes/note/begin }
+          \seq_gput_right:Ne \g__postnotes_queue_seq
+            { \l_postnotes_note_id_tl }
+          \cs_set:Npn \@currentcounter { postnote }
+          \cs_set:Npe \@currentlabel { \p at postnote \l__postnotes_mark_tl }
+          \__postnotes_store:nn { \l_postnotes_note_id_tl } {#2}
+          \tl_set_eq:NN \l__postnotes_mark_typeset_tl \l__postnotes_mark_tl
+          \bool_lazy_or:nnT
+            { \g__postnotes_counteraux_bool }
+            { \l__postnotes_maybe_multi_bool }
+            {
+              \bool_lazy_and:nnT
+                { ! \g__postnotes_firstrun_bool }
+                {
+                  ! \cs_if_exist_p:c
+                    { \c__postnotes_ref_prefix_tl @ mark @ \l_postnotes_note_id_tl }
+                }
+                { \__postnotes_get_label_if_exist:N \l__postnotes_mark_typeset_tl }
+            }
+          \tl_set:Nn \l__postnotes_note_set_labels_tl
+            {
+              \MakeLinkTarget* { postnote. \l_postnotes_note_id_tl .mark }
+              \__postnotes_set_mark_page_label:ee { \l_postnotes_note_id_tl }
+                { \int_use:N \l__postnotes_counteraux_step_int }
+              \__postnotes_set_user_labels:
+            }
+          \bool_if:NTF \l__postnotes_nomark_bool
+            {
+              \tag_socket_use:n { postnotes/nomark/begin }
+              \l__postnotes_note_set_labels_tl
+              \tag_socket_use:n { postnotes/nomark/end }
+            }
+            {
+              \__postnotes_typeset_mark:eVN
+                { \l_postnotes_note_id_tl } \l__postnotes_mark_typeset_tl
+                \l__postnotes_note_set_labels_tl
+            }
+        }
+      \bool_if:NT \l__postnotes_nomark_bool { \@esphack }
     \group_end:
   }
 \tl_new:N \l__postnotes_mark_tl
 \bool_new:N \l__postnotes_nomark_bool
 \fp_new:N \l__postnotes_sort_num_fp
-\tl_new:N \l__postnotes_note_label_tl
+\str_new:N \l__postnotes_note_label_str
 \bool_new:N \l__postnotes_manual_sortnum_bool
-\bool_new:N \l__postnotes_maybe_multi_bool
 \keys_define:nn { postnotes/note }
   {
     markstr .tl_set:N = \l__postnotes_mark_tl ,
@@ -489,8 +628,10 @@
     mark .value_required:n = true ,
     nomark .bool_set:N = \l__postnotes_nomark_bool ,
     nomark .default:n = true ,
-    label .tl_set:N = \l__postnotes_note_label_tl ,
+    label .str_set:N = \l__postnotes_note_label_str ,
     label .value_required:n = true ,
+    maybemulti .bool_set:N = \l__postnotes_maybe_multi_bool ,
+    maybemulti .default:n = true ,
   }
 \bool_new:N \l__postnotes_inhibit_note_bool
 \bool_new:N \l__postnotes_print_plain_mark_bool
@@ -502,29 +643,36 @@
     \bool_set_false:N \l__postnotes_print_plain_mark_bool
     \bool_set_false:N \l__postnotes_print_plain_mark_stepcounter_bool
     \UseHook { postnotes/note/inhibit }
-    \bool_if:NT \l__postnotes_print_plain_mark_bool
+    \bool_lazy_all:nT
       {
-        \tl_if_empty:NT \l__postnotes_mark_tl
+        { \l__postnotes_inhibit_note_bool }
+        { \l__postnotes_print_plain_mark_bool }
+        { ! \l__postnotes_nomark_bool }
+      }
+      {
+        \tl_if_empty:NTF \l__postnotes_mark_tl
           {
             \bool_if:NTF \l__postnotes_print_plain_mark_stepcounter_bool
               {
                 \stepcounter { postnote }
-                \tl_set:Ne \l__postnotes_mark_tl { \thepostnote }
+                \tl_set:Ne \l__postnotes_mark_typeset_tl { \thepostnote }
               }
               {
                 \group_begin:
-                \int_incr:N \c at postnote
-                \exp_args:NNNe
-                  \group_end:
-                  \tl_set:Nn \l__postnotes_mark_tl { \thepostnote }
+                  \int_incr:N \c at postnote
+                  \exp_args:NNNe
+                    \group_end:
+                    \tl_set:Nn \l__postnotes_mark_typeset_tl { \thepostnote }
               }
+            \__postnotes_get_label_if_exist:N \l__postnotes_mark_typeset_tl
           }
+          { \tl_set_eq:NN \l__postnotes_mark_typeset_tl \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 { } { } }
-          { } { }
+          \socket_assign_plug:nn { tagsupport/postnotes/multisep/begin } { noop }
+          \socket_assign_plug:nn { tagsupport/postnotes/multisep/end } { noop }
+          \__postnotes_typeset_mark_wrapper:nnn
+            { \__postnotes_make_mark:Vnn \l__postnotes_mark_typeset_tl { } { } }
+            { } { }
         \group_end:
       }
     \bool_if:NTF \l__postnotes_inhibit_note_bool
@@ -531,10 +679,47 @@
       { \prg_return_true:  }
       { \prg_return_false: }
   }
-\cs_new_protected:Npn \__postnotes_typeset_mark:nn #1#2
+\cs_new_protected:Npn \__postnotes_get_label_if_exist:N #1
   {
+    \str_if_empty:NTF \l__postnotes_note_label_str
+      {
+        \str_if_empty:NF \l__postnotes_note_zlabel_str
+          {
+            \exp_args:NV \zref at ifrefundefined \l__postnotes_note_zlabel_str
+              { }
+              {
+                \exp_args:NV \zref at ifrefcontainsprop
+                  \l__postnotes_note_zlabel_str
+                  { postnote at mark }
+                  {
+                    \exp_args:NNNo \exp_args:NNo \tl_set:Nn #1
+                      {
+                        \zref at extract
+                          { \l__postnotes_note_zlabel_str } { postnote at mark }
+                      }
+                  }
+                  { }
+              }
+          }
+      }
+      {
+        \exp_args:Ne \property_if_recorded:nnT
+          { postnotes@ \l__postnotes_note_label_str }
+          { postnotes/mark }
+          {
+            \tl_set:Ne #1
+              {
+                \property_ref:ee
+                  { __postnotes_ \l__postnotes_note_label_str } { postnotes/mark }
+              }
+          }
+      }
+  }
+\cs_new_protected:Npn \__postnotes_typeset_mark:nnN #1#2#3
+  {
     \__postnotes_typeset_mark_wrapper:nnn
       {
+        #3
         \bool_if:NTF \l__postnotes_hyperlink_bool
           {
             \__postnotes_make_mark:nnn {#2}
@@ -546,7 +731,7 @@
       { \tag_socket_use:n { postnotes/mark/begin } }
       { \tag_socket_use:n { postnotes/mark/end }   }
   }
-\cs_generate_variant:Nn \__postnotes_typeset_mark:nn { eV }
+\cs_generate_variant:Nn \__postnotes_typeset_mark:nnN { eVN }
 \tl_new:N \l__postnotes_saved_spacefactor_tl
 \cs_new_protected:Npn \__postnotes_typeset_mark_wrapper:nnn #1#2#3
   {
@@ -558,9 +743,9 @@
         \__postnotes_multiple_check:
         \nobreak
       }
-    #2 % begin tagging function
+    #2 % begin tagging socket
     #1 % mark
-    #3 % end tagging function
+    #3 % end tagging socket
     \__postnotes_multiple_prepare:
     \mode_if_horizontal:T
       { \spacefactor \l__postnotes_saved_spacefactor_tl }
@@ -568,11 +753,16 @@
   }
 \cs_new_protected:Npn \__postnotes_set_user_labels:
   {
-    \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
-      { \exp_args:NV \zlabel \l__postnotes_note_zlabel_tl }
+    \str_if_empty:NF \l__postnotes_note_label_str
+      {
+        \exp_args:NV \label \l__postnotes_note_label_str
+        \property_record:ee { __postnotes_ \l__postnotes_note_label_str }
+          { postnotes/mark }
+      }
+    \str_if_empty:NF \l__postnotes_note_zlabel_str
+      { \exp_args:NV \zlabel \l__postnotes_note_zlabel_str }
   }
+\property_new:nnnn { postnotes/mark } { now } { } { \l__postnotes_mark_tl }
 \NewDocumentCommand \postnoteref { s m }
   { \__postnotes_note_ref:nn {#1} {#2} }
 \tl_new:N \l__postnotes_note_ref_label_tl
@@ -579,47 +769,41 @@
 \cs_new_protected:Npn \__postnotes_note_ref:nn #1#2
   {
     \group_begin:
-    \tl_set:Nn \l__postnotes_note_ref_label_tl {#2}
-    \__postnotes_typeset_mark_wrapper:nnn
-      {
-        \bool_lazy_and:nnTF
-          { ! #1 }
-          { \l__postnotes_hyperlink_bool }
-          {
-            \hyperref [#2]
-              { \__postnotes_make_mark:nnn { \ref*{#2} } { } { } }
-          }
-          { \__postnotes_make_mark:nnn { \ref*{#2} } { } { } }
-      }
-      { \tag_socket_use:n { postnotes/postnoteref/begin } }
-      { \tag_socket_use:n { postnotes/postnoteref/end }   }
+      \tl_set:Nn \l__postnotes_note_ref_label_tl {#2}
+      \__postnotes_typeset_mark_wrapper:nnn
+        {
+          \bool_lazy_and:nnTF
+            { ! #1 }
+            { \l__postnotes_hyperlink_bool }
+            {
+              \hyperref [#2]
+                { \__postnotes_make_mark:nnn { \ref*{#2} } { } { } }
+            }
+            { \__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 }
-  { \__postnotes_section:nn {#1} {#2} }
-\NewDocumentCommand \postnotesectionx { O { } +m }
   {
-    % NOTE Command deprecated in 2022-12-27 for v0.2.0.
-    \msg_warning:nn { postnotes } { postnotesectionx-deprecated }
-    \postnotesection [ #1 , exp ] {#2}
+    \@bsphack
+    \__postnotes_section:nn {#1} {#2}
+    \@esphack
   }
-\msg_new:nnn { postnotes } { postnotesectionx-deprecated }
-  {
-    '\iow_char:N\\postnotesectionx'~is~deprecated~\msg_line_context:.~
-    Use~the~'exp'~option~of~'\iow_char:N\\postnotesection'~instead.
-  }
 \int_new:N \g__postnotes_sectid_int
 \cs_new_protected:Npn \__postnotes_section:nn #1#2
   {
     \group_begin:
-    \int_gincr:N \g__postnotes_sectid_int
-    \int_gincr:N \g__postnotes_note_id_int
-    \seq_gput_right:Ne \g__postnotes_queue_seq { \l_postnotes_note_id_tl }
-    \tl_gclear:N \g__postnotes_section_name_tl
-    \keys_set:nn { postnotes/section } {#1}
-    \bool_if:NTF \l__postnotes_section_exp_bool
-      { \__postnotes_store_section:ne { \l_postnotes_note_id_tl } {#2} }
-      { \__postnotes_store_section:nn { \l_postnotes_note_id_tl } {#2} }
+      \int_gincr:N \g__postnotes_sectid_int
+      \int_gincr:N \g__postnotes_note_id_int
+      \seq_gput_right:Ne \g__postnotes_queue_seq { \l_postnotes_note_id_tl }
+      \tl_gclear:N \g__postnotes_section_name_tl
+      \keys_set:nn { postnotes/section } {#1}
+      \__postnotes_set_section_page_label:e { \l_postnotes_note_id_tl }
+      \bool_if:NTF \l__postnotes_section_exp_bool
+        { \__postnotes_store_section:ne { \l_postnotes_note_id_tl } {#2} }
+        { \__postnotes_store_section:nn { \l_postnotes_note_id_tl } {#2} }
     \group_end:
   }
 \tl_new:N \g__postnotes_section_name_tl
@@ -641,10 +825,12 @@
 \tl_new:N \pnthesectionnextnote
 \tl_new:N \pnthepage
 \int_new:N \g__postnotes_print_postnotes_int
+\seq_new:N \g__postnotes_print_queue_seq
 \tl_new:N \l_postnotes_print_note_id_tl
 \tl_new:N \l__postnotes_print_note_id_next_tl
 \tl_new:N \l__postnotes_print_counter_tl
 \tl_new:N \l__postnotes_print_mark_tl
+\tl_new:N \l__postnotes_print_typeset_mark_tl
 \tl_new:N \l__postnotes_print_type_curr_tl
 \tl_new:N \l__postnotes_print_type_next_tl
 \tl_new:N \l__postnotes_print_type_prev_tl
@@ -658,144 +844,182 @@
 \cs_new_protected:Npn \__postnotes_print_notes:
   {
     \group_begin:
-    \int_gincr:N \g__postnotes_print_postnotes_int
-    \seq_if_empty:NTF \g__postnotes_queue_seq
-      { \msg_warning:nn { postnotes } { empty-printpostnotes } }
-      {
-        \pnheading
-        \UseHook { postnotes/print/begin }
-        \tl_set:Nn \l__postnotes_print_type_prev_tl { open }
-        \seq_set_eq:NN \l__postnotes_clear_queue_seq \g__postnotes_queue_seq
-        \__postnotes_verify_multipass:N \g__postnotes_queue_seq
-        \bool_if:NT \l__postnotes_sort_bool
-          { \__postnotes_sort_queue:N \g__postnotes_queue_seq }
-        \bool_gset_true:N \g__postnotes_header_vars_next_bool
-        \__postnotes_get_headers_data:N \g__postnotes_queue_seq
-        \__postnotes_set_headers_vars_first:
-        \bool_if:NF \l__postnotes_print_as_list_bool
-          {
-            \cs_set_eq:NN \@afterindentfalse \@afterindenttrue
-            \@afterindenttrue
-          }
-        \bool_until_do:nn { \seq_if_empty_p:N \g__postnotes_queue_seq }
-          {
-            \seq_gpop_left:NN \g__postnotes_queue_seq
-              \l_postnotes_print_note_id_tl
-            \__postnotes_prop_get:nnN { \l_postnotes_print_note_id_tl }
-              { type } \l__postnotes_print_type_curr_tl
-            \tl_if_eq:NnTF \l__postnotes_print_type_curr_tl { section }
-              { % type_curr = `section'
-                \seq_if_empty:NTF \g__postnotes_queue_seq
-                  {
-                    \tl_set:Nn \l__postnotes_print_note_id_next_tl { noid }
-                    \tl_set:Nn \l__postnotes_print_type_next_tl { close }
-                  }
-                  {
-                    \seq_get_left:NN \g__postnotes_queue_seq
-                      \l__postnotes_print_note_id_next_tl
+      \int_gincr:N \g__postnotes_print_postnotes_int
+      \__postnotes_split_labelseq:
+      \bool_lazy_and:nnTF
+        { \g__postnotes_counteraux_bool }
+        { ! \g__postnotes_firstrun_bool }
+        {
+          \seq_gset_eq:NN \g__postnotes_print_queue_seq
+            \g__postnotes_print_labelseq_queue_seq
+        }
+        {
+          \seq_gset_eq:NN \g__postnotes_print_queue_seq
+            \g__postnotes_queue_seq
+        }
+      \seq_set_eq:NN \l__postnotes_clear_queue_seq \g__postnotes_print_queue_seq
+      \seq_gclear:N \g__postnotes_queue_seq
+      \__postnotes_set_pre_print_label:e
+        { \int_use:N \g__postnotes_print_postnotes_int }
+      \seq_if_empty:NTF \g__postnotes_print_queue_seq
+        { \msg_warning:nn { postnotes } { empty-printpostnotes } }
+        {
+          \pnheading
+          \UseHook { postnotes/print/begin }
+          \tl_set:Nn \l__postnotes_print_type_prev_tl { open }
+          \__postnotes_check_duplicates:N \g__postnotes_print_queue_seq
+          \__postnotes_sort_queue:N \g__postnotes_print_queue_seq
+          \__postnotes_check_floats:N \g__postnotes_print_queue_seq
+          \bool_gset_true:N \g__postnotes_header_vars_next_bool
+          \__postnotes_get_headers_data:N \g__postnotes_print_queue_seq
+          \__postnotes_set_headers_vars_first:
+          \bool_if:NF \l__postnotes_print_as_list_bool
+            {
+              \cs_set_eq:NN \@afterindentfalse \@afterindenttrue
+              \@afterindenttrue
+            }
+          \bool_until_do:nn { \seq_if_empty_p:N \g__postnotes_print_queue_seq }
+            {
+              \seq_gpop_left:NN \g__postnotes_print_queue_seq
+                \l_postnotes_print_note_id_tl
+              \__postnotes_prop_get:nnN { \l_postnotes_print_note_id_tl }
+                { type } \l__postnotes_print_type_curr_tl
+              \tl_if_eq:NnTF \l__postnotes_print_type_curr_tl { section }
+                { % type_curr = `section'
+                  \seq_if_empty:NTF \g__postnotes_print_queue_seq
+                    {
+                      \tl_set:Nn \l__postnotes_print_note_id_next_tl { noid }
+                      \tl_set:Nn \l__postnotes_print_type_next_tl { close }
+                    }
+                    {
+                      \seq_get_left:NN \g__postnotes_print_queue_seq
+                        \l__postnotes_print_note_id_next_tl
+                      \__postnotes_prop_get:nnN
+                        { \l__postnotes_print_note_id_next_tl }
+                        { type } \l__postnotes_print_type_next_tl
+                    }
+                  \tl_if_eq:NnT \l__postnotes_print_type_next_tl { note }
+                    {
+                      \stepcounter { postnotesection }
+                      \group_begin:
+                        \__postnotes_prop_get:nnN
+                          { \l_postnotes_print_note_id_tl }
+                          { thechapter } \pnthechapter
+                        \__postnotes_prop_get:nnN
+                          { \l_postnotes_print_note_id_tl }
+                          { thesection } \pnthesection
+                        \tl_set:NV \pnidnextnote
+                          \l__postnotes_print_note_id_next_tl
+                        \__postnotes_prop_get:nnN
+                          { \l__postnotes_print_note_id_next_tl }
+                          { thechapter } \pnthechapternextnote
+                        \__postnotes_prop_get:nnN
+                          { \l__postnotes_print_note_id_next_tl }
+                          { thesection } \pnthesectionnextnote
+                        \__postnotes_prop_get:nnN
+                          { \l_postnotes_print_note_id_tl }
+                          { content } \l__postnotes_print_content_tl
+                        \l__postnotes_print_content_tl
+                      \group_end:
+                      \tl_set:NV \l__postnotes_print_type_prev_tl
+                        \l__postnotes_print_type_curr_tl
+                    }
+                }
+                { % type_curr = `note'
+                  \seq_if_empty:NTF \g__postnotes_print_queue_seq
+                    {
+                      \tl_set:Nn \l__postnotes_print_note_id_next_tl { noid }
+                      \tl_set:Nn \l__postnotes_print_type_next_tl { close }
+                    }
+                    {
+                      \seq_get_left:NN \g__postnotes_print_queue_seq
+                        \l__postnotes_print_note_id_next_tl
+                      \__postnotes_prop_get:nnN
+                        { \l__postnotes_print_note_id_next_tl }
+                        { type } \l__postnotes_print_type_next_tl
+                    }
+                  \tl_if_eq:NnF \l__postnotes_print_type_prev_tl { note }
+                    {
+                      \bool_if:NTF \l__postnotes_print_as_list_bool
+                        { \exp_args:NV \begin \l__postnotes_print_env_tl }
+                        { \group_begin: }
+                      \tag_socket_use:n { postnotes/printlist/begin }
+                      \l__postnotes_print_format_tl
+                    }
+                  \group_begin:
+                    \UseHook { postnotes/print/note/begin }
+                    \__postnotes_get_pageref:Ne \pnthepage
+                      { mark@ \l_postnotes_print_note_id_tl }
                     \__postnotes_prop_get:nnN
-                      { \l__postnotes_print_note_id_next_tl }
-                      { type } \l__postnotes_print_type_next_tl
-                  }
-                \tl_if_eq:NnT \l__postnotes_print_type_next_tl { note }
-                  {
-                    \stepcounter { postnotesection }
-                    \group_begin:
-                    \__postnotes_prop_get:nnN
                       { \l_postnotes_print_note_id_tl }
-                      { thechapter } \pnthechapter
+                      { mark } \l__postnotes_print_mark_tl
                     \__postnotes_prop_get:nnN
                       { \l_postnotes_print_note_id_tl }
-                      { thesection } \pnthesection
-                    \tl_set:NV \pnidnextnote \l__postnotes_print_note_id_next_tl
+                      { counter } \l__postnotes_print_counter_tl
                     \__postnotes_prop_get:nnN
-                      { \l__postnotes_print_note_id_next_tl }
-                      { thechapter } \pnthechapternextnote
-                    \__postnotes_prop_get:nnN
-                      { \l__postnotes_print_note_id_next_tl }
-                      { thesection } \pnthesectionnextnote
-                    \__postnotes_prop_get:nnN
                       { \l_postnotes_print_note_id_tl }
                       { content } \l__postnotes_print_content_tl
+                    \cs_set:Npn \@currentcounter { postnotetext }
+                    \int_set:Nn \c at postnotetext
+                      { \l__postnotes_print_counter_tl }
+                    \cs_set:Npe \@currentlabel
+                      { \p at postnote \l__postnotes_print_mark_tl }
+                    \tl_set:Nn \l__postnotes_print_typeset_mark_tl
+                      {
+                        \tag_socket_use:n { postnotes/printmark/begin }
+                        \MakeLinkTarget*
+                          { postnote. \l_postnotes_print_note_id_tl .text }
+                        \__postnotes_set_text_page_label:e
+                          { \l_postnotes_print_note_id_tl }
+                        \l__postnotes_pre_textmark_tl
+                        \__postnotes_typeset_text_mark:eV
+                          { \l_postnotes_print_note_id_tl }
+                          \l__postnotes_print_mark_tl
+                        \l__postnotes_post_textmark_tl
+                        \tag_socket_use:n { postnotes/printmark/end }
+                      }
+                    \bool_if:NTF \l__postnotes_print_as_list_bool
+                      {
+                        \item
+                          [
+                            \tag_socket_use:n { postnotes/printnote/begin }
+                            \l__postnotes_print_typeset_mark_tl
+                          ]
+                        \mode_leave_vertical:
+                      }
+                      {
+                        \mode_leave_vertical:
+                        \tag_socket_use:n { postnotes/printnote/begin }
+                        \l__postnotes_print_typeset_mark_tl
+                      }
+                    \tag_socket_use:n { postnotes/printtext/begin }
                     \l__postnotes_print_content_tl
-                    \group_end:
-                    \tl_set:NV \l__postnotes_print_type_prev_tl
-                      \l__postnotes_print_type_curr_tl
-                  }
-              }
-              { % type_curr = `note'
-                \tl_if_eq:NnF \l__postnotes_print_type_prev_tl { note }
-                  {
-                    \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:
-                \UseHook { postnotes/print/note/begin }
-                \__postnotes_get_pageref:Ne \pnthepage
-                  { mark@ \l_postnotes_print_note_id_tl }
-                \__postnotes_prop_get:nnN
-                  { \l_postnotes_print_note_id_tl }
-                  { mark } \l__postnotes_print_mark_tl
-                \__postnotes_prop_get:nnN
-                  { \l_postnotes_print_note_id_tl }
-                  { counter } \l__postnotes_print_counter_tl
-                \__postnotes_prop_get:nnN
-                  { \l_postnotes_print_note_id_tl }
-                  { content } \l__postnotes_print_content_tl
-                \cs_set:Npn \@currentcounter { postnotetext }
-                \int_set:Nn \c at postnotetext
-                  { \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*
-                      { postnote. \l_postnotes_print_note_id_tl .text }
-                    \__postnotes_set_text_page_label:e
-                      { \l_postnotes_print_note_id_tl }
-                    \__postnotes_typeset_text_mark:eV
-                      { \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
-                  {
-                    \tl_set:Nn \l__postnotes_print_note_id_next_tl { noid }
-                    \tl_set:Nn \l__postnotes_print_type_next_tl { close }
-                  }
-                  {
-                    \seq_get_left:NN \g__postnotes_queue_seq
-                      \l__postnotes_print_note_id_next_tl
-                    \__postnotes_prop_get:nnN
-                      { \l__postnotes_print_note_id_next_tl }
-                      { type } \l__postnotes_print_type_next_tl
-                  }
-                \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: }
-                    \par
-                  }
-                \tl_set:NV \l__postnotes_print_type_prev_tl
-                  \l__postnotes_print_type_curr_tl
-              }
-          }
-        \AddToHookNext { shipout/after }
-          { \bool_gset_false:N \g__postnotes_header_vars_next_bool }
-        \seq_map_inline:Nn \l__postnotes_clear_queue_seq
-          { \__postnotes_prop_gclear:n { ##1 } }
-      }
+                    \tag_socket_use:n { postnotes/printtext/end }
+                    \tag_socket_use:n { postnotes/printnote/end }
+                    \l__postnotes_post_printnote_tl
+                  \group_end:
+                  \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:NV \end \l__postnotes_print_env_tl
+                          \par
+                        }
+                        {
+                          \par
+                          \group_end:
+                        }
+                    }
+                  \tl_set:NV \l__postnotes_print_type_prev_tl
+                    \l__postnotes_print_type_curr_tl
+                }
+            }
+          \AddToHookNext { shipout/after }
+            { \bool_gset_false:N \g__postnotes_header_vars_next_bool }
+          \seq_map_inline:Nn \l__postnotes_clear_queue_seq
+            { \__postnotes_prop_gclear:n { ##1 } }
+        }
     \group_end:
   }
 \msg_new:nnn { postnotes } { empty-printpostnotes }
@@ -813,70 +1037,191 @@
       { \__postnotes_make_text_mark:nnn {#2} { } { } }
   }
 \cs_generate_variant:Nn \__postnotes_typeset_text_mark:nn { eV }
-\cs_new_protected:Npn \__postnotes_text_mark_wrapper:n #1
+\seq_new:N \g__postnotes_print_labelseq_queue_seq
+\cs_new_protected:Npn \__postnotes_split_labelseq:
   {
-    \bool_if:NTF \l__postnotes_print_as_list_bool
+    \group_begin:
+      \seq_clear:N \l__postnotes_tmpa_seq
+      \seq_clear:N \l__postnotes_tmpb_seq
+      \bool_if:NTF \g__postnotes_counteraux_bool
+        {
+          \tl_set:Ne \l__postnotes_tmpa_tl
+            { { preprint } { \int_use:N \g__postnotes_print_postnotes_int } }
+          \seq_if_in:NVF \g__postnotes_labelseq_seq \l__postnotes_tmpa_tl
+            { \seq_gput_right:NV \g__postnotes_labelseq_seq \l__postnotes_tmpa_tl }
+          \bool_do_until:nn
+            { \tl_if_eq_p:NN \l__postnotes_tmpb_tl \l__postnotes_tmpa_tl }
+            {
+              \seq_gpop_left:NN \g__postnotes_labelseq_seq \l__postnotes_tmpb_tl
+              \str_case:enT
+                { \tl_item:Nn \l__postnotes_tmpb_tl { 1 } }
+                {
+                  { mark }    { }
+                  { section } { }
+                }
+                {
+                  \int_compare:nNnTF
+                    { \tl_item:Nn \l__postnotes_tmpb_tl { 2 } }
+                    >
+                    { \g__postnotes_note_id_int }
+                    {
+                      \seq_put_right:Ne \l__postnotes_tmpb_seq
+                        \l__postnotes_tmpb_tl
+                    }
+                    {
+                      \seq_put_right:Ne \l__postnotes_tmpa_seq
+                        { \tl_item:Nn \l__postnotes_tmpb_tl { 2 } }
+                    }
+                }
+            }
+          \seq_gset_eq:NN \g__postnotes_print_labelseq_queue_seq
+            \l__postnotes_tmpa_seq
+          \seq_concat:NNN \l__postnotes_tmpa_seq \l__postnotes_tmpb_seq
+            \g__postnotes_labelseq_seq
+          \seq_gset_eq:NN \g__postnotes_labelseq_seq \l__postnotes_tmpa_seq
+        }
+        {
+          \seq_map_inline:Nn \g__postnotes_labelseq_seq
+            {
+              \str_case:enT
+                { \tl_item:nn { ##1 } { 1 } }
+                {
+                  { mark }    { }
+                  { section } { }
+                }
+                {
+                  \int_compare:nNnTF
+                    { \tl_item:nn { ##1 } { 2 } }
+                    >
+                    { \g__postnotes_note_id_int }
+                    { \seq_put_right:Nn \l__postnotes_tmpb_seq { ##1 } }
+                    {
+                      \seq_put_right:Ne \l__postnotes_tmpa_seq
+                        { \tl_item:nn { ##1 } { 2 } }
+                    }
+                }
+            }
+          \seq_gset_eq:NN \g__postnotes_print_labelseq_queue_seq
+            \l__postnotes_tmpa_seq
+          \seq_gset_eq:NN \g__postnotes_labelseq_seq \l__postnotes_tmpb_seq
+        }
+    \group_end:
+  }
+\cs_new_protected:Npn \__postnotes_check_duplicates:N #1
+  {
+    \bool_lazy_and:nnT
+      { ! \g__postnotes_firstrun_bool }
+      { ! \g__postnotes_counteraux_bool }
       {
-        \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:
+        \group_begin:
+          \seq_clear:N \l__postnotes_tmpa_seq
+          \seq_map_inline:Nn #1
+            {
+              \bool_lazy_or:nnTF
+                { \cs_if_exist_p:c { \c__postnotes_ref_prefix_tl @ mark @ ##1 } }
+                {
+                  \str_if_eq_p:ee
+                    { \__postnotes_prop_item:nn {##1} { type } } { section }
+                }
+                { \seq_put_right:Nn \l__postnotes_tmpa_seq {##1} }
+                {
+                  \str_if_eq:eeF
+                    { \__postnotes_prop_item:nn {##1} { multibool } }
+                    { true }
+                    {
+                      \seq_put_right:Nn \l__postnotes_tmpa_seq {##1}
+                      \bool_if:NT \l__postnotes_check_dupli_bool
+                        {
+                          \msg_warning:nne { postnotes } { possible-duplicate }
+                            { \__postnotes_prop_item:nn {##1} { mark } }
+                        }
+                    }
+                }
+            }
+          \seq_gset_eq:NN #1 \l__postnotes_tmpa_seq
+        \group_end:
       }
+  }
+\msg_new:nnn { postnotes } { possible-duplicate }
+  { Possible~duplicate~*around*~note~'#1'~\msg_line_context:. }
+\cs_new_protected:Npn \__postnotes_check_floats:N #1
+  {
+    \bool_lazy_and:nnT
+      { \l__postnotes_check_floats_bool }
+      { ! \g__postnotes_firstrun_bool }
       {
-        \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 }
+        \group_begin:
+          \seq_set_filter:NNn \l__postnotes_tmpa_seq #1
+            {
+              \bool_lazy_or_p:nn
+                { \cs_if_exist_p:c { \c__postnotes_ref_prefix_tl @ mark @ ##1 } }
+                { \cs_if_exist_p:c { \c__postnotes_ref_prefix_tl @ section @ ##1 } }
+            }
+          \tl_if_eq:NNF
+            \g__postnotes_print_labelseq_queue_seq \l__postnotes_tmpa_seq
+            { \msg_warning:nn { postnotes } { possible-shuffle } }
+        \group_end:
       }
   }
-\cs_new_protected:Npn \__postnotes_verify_multipass:N #1
+\msg_new:nnn { postnotes } { possible-shuffle }
+  { Possible~out~of~sequence~notes~due~to~floats~\msg_line_context:. }
+\cs_new_protected:Npn \__postnotes_sort_queue:N #1
   {
-    \group_begin:
-    \seq_clear:N \l__postnotes_tmpa_seq
-    \seq_map_inline:Nn #1
+    \bool_if:NT \l__postnotes_sort_bool
       {
-        \__postnotes_prop_get:nnN {##1} { multibool } \l__postnotes_tmpa_tl
-        \str_if_eq:VnTF \l__postnotes_tmpa_tl { true }
-          {
-            \cs_if_exist:cT
-              { \c__postnotes_ref_prefix_tl @ mark@ ##1 }
-              { \seq_put_right:Nn \l__postnotes_tmpa_seq {##1} }
-          }
-          { \seq_put_right:Nn \l__postnotes_tmpa_seq {##1} }
+        \group_begin:
+          \seq_gsort:Nn #1
+            {
+              \__postnotes_prop_get:nnN {##1} { pnsectid } \l__postnotes_tmpa_tl
+              \__postnotes_prop_get:nnN {##2} { pnsectid } \l__postnotes_tmpb_tl
+              \tl_if_eq:NNTF \l__postnotes_tmpa_tl \l__postnotes_tmpb_tl
+                {
+                  \__postnotes_prop_get:nnN {##1} { type } \l__postnotes_tmpa_tl
+                  \__postnotes_prop_get:nnN {##2} { type } \l__postnotes_tmpb_tl
+                  \bool_lazy_and:nnTF
+                    { \str_if_eq_p:Vn \l__postnotes_tmpa_tl { note } }
+                    { \str_if_eq_p:Vn \l__postnotes_tmpb_tl { note } }
+                    {
+                      \__postnotes_prop_get:nnN {##1}
+                        { sortnum } \l__postnotes_tmpa_tl
+                      \__postnotes_prop_get:nnN {##2}
+                        { sortnum } \l__postnotes_tmpb_tl
+                      \fp_compare:nNnTF
+                        { \l__postnotes_tmpa_tl } > { \l__postnotes_tmpb_tl }
+                        { \sort_return_swapped: }
+                        { \sort_return_same:    }
+                    }
+                    { \sort_return_same: }
+                }
+                { \sort_return_same: }
+            }
+        \group_end:
       }
-    \seq_gset_eq:NN #1 \l__postnotes_tmpa_seq
-    \group_end:
   }
-\cs_new_protected:Npn \__postnotes_sort_queue:N #1
+\AddToHook { enddocument/afterlastpage }
   {
     \group_begin:
-    \seq_gsort:Nn #1
-      {
-        \__postnotes_prop_get:nnN {##1} { pnsectid } \l__postnotes_tmpa_tl
-        \__postnotes_prop_get:nnN {##2} { pnsectid } \l__postnotes_tmpb_tl
-        \tl_if_eq:NNTF \l__postnotes_tmpa_tl \l__postnotes_tmpb_tl
-          {
-            \__postnotes_prop_get:nnN {##1} { type } \l__postnotes_tmpa_tl
-            \__postnotes_prop_get:nnN {##2} { type } \l__postnotes_tmpb_tl
-            \bool_lazy_and:nnTF
-              { \str_if_eq_p:Vn \l__postnotes_tmpa_tl { note } }
-              { \str_if_eq_p:Vn \l__postnotes_tmpb_tl { note } }
-              {
-                \__postnotes_prop_get:nnN {##1} { sortnum } \l__postnotes_tmpa_tl
-                \__postnotes_prop_get:nnN {##2} { sortnum } \l__postnotes_tmpb_tl
-                \fp_compare:nNnTF
-                  { \l__postnotes_tmpa_tl } > { \l__postnotes_tmpb_tl }
-                  { \sort_return_swapped: }
-                  { \sort_return_same:    }
-              }
-              { \sort_return_same: }
-          }
-          { \sort_return_same: }
-      }
+      \bool_if:NTF \g__postnotes_counteraux_bool
+        {
+          \seq_set_filter:NNn \l__postnotes_tmpa_seq \g__postnotes_labelseq_seq
+            { \str_if_eq_p:ee { \tl_item:nn {#1} { 1 } } { mark } }
+        }
+        {
+          \seq_set_filter:NNn \l__postnotes_tmpa_seq \g__postnotes_queue_seq
+            { \str_if_eq_p:ee { \__postnotes_prop_item:nn {#1} { type } } { note } }
+        }
+      \seq_if_empty:NF \l__postnotes_tmpa_seq
+        {
+          \msg_warning:nne { postnotes } { stray-notes }
+            { \seq_count:N \l__postnotes_tmpa_seq }
+        }
     \group_end:
   }
+\msg_new:nnn { postnotes } { stray-notes }
+  {
+    There~are~'#1'~stray~notes~after~the~last~'\iow_char:N\\printpostnotes'~
+    \msg_line_context:.~At~this~point,~they~are~lost.
+  }
 \tl_new:N \pnhdpagefirst
 \tl_new:N \pnhdpagelast
 \tl_new:N \pnhdchapfirst
@@ -906,169 +1251,169 @@
 \cs_new_protected:Npn \__postnotes_get_headers_data:N #1
   {
     \group_begin:
-    \tl_gclear:N \pnhdpagefirst
-    \tl_gclear:N \pnhdpagelast
-    \tl_gclear:N \pnhdchapfirst
-    \tl_gclear:N \pnhdchaplast
-    \tl_gclear:N \pnhdsectfirst
-    \tl_gclear:N \pnhdsectlast
-    \tl_gclear:N \pnhdnamefirst
-    \tl_gclear:N \pnhdnamelast
-    \prop_gclear:N \g__postnotes_header_page_first_prop
-    \prop_gclear:N \g__postnotes_header_page_last_prop
-    \prop_gclear:N \g__postnotes_header_chap_first_prop
-    \prop_gclear:N \g__postnotes_header_chap_last_prop
-    \prop_gclear:N \g__postnotes_header_sect_first_prop
-    \prop_gclear:N \g__postnotes_header_sect_last_prop
-    \prop_gclear:N \g__postnotes_header_name_first_prop
-    \prop_gclear:N \g__postnotes_header_name_last_prop
-    \tl_gclear:N \g__postnotes_header_prev_last_page_tl
-    \tl_gclear:N \g__postnotes_header_prev_last_chap_tl
-    \tl_gclear:N \g__postnotes_header_prev_last_sect_tl
-    \tl_gclear:N \g__postnotes_header_prev_last_name_tl
-    \tl_clear:N \l__postnotes_prev_text_page_tl
-    \tl_clear:N \l__postnotes_curr_text_page_tl
-    \tl_clear:N \l__postnotes_prev_mark_page_tl
-    \tl_clear:N \l__postnotes_prev_mark_chap_tl
-    \tl_clear:N \l__postnotes_prev_mark_sect_tl
-    \tl_clear:N \l__postnotes_prev_mark_name_tl
-    \seq_map_inline:Nn #1
-      {
-        \exp_args:Ne \tl_if_eq:nnT
-          { \__postnotes_prop_item:nn {##1} { type } }
-          { note }
-          {
-            \__postnotes_get_pageref:Nn
-              \l__postnotes_curr_text_page_tl { text@ ##1 }
-            \tl_if_empty:NF \l__postnotes_curr_text_page_tl
-              {
-                \tl_if_eq:NNTF
-                  \l__postnotes_prev_text_page_tl
-                  \l__postnotes_curr_text_page_tl
-                  {
-                    \__postnotes_get_pageref:Nn
-                      \l__postnotes_prev_mark_page_tl { mark@ ##1 }
-                    \__postnotes_prop_get:nnN {##1} { thechapter }
-                      \l__postnotes_prev_mark_chap_tl
-                    \__postnotes_prop_get:nnN {##1} { thesection }
-                      \l__postnotes_prev_mark_sect_tl
-                    \__postnotes_prop_get:nnN {##1} { pnsectname }
-                      \l__postnotes_prev_mark_name_tl
-                  }
-                  {
-                    \tl_if_empty:NF \l__postnotes_prev_text_page_tl
-                      {
-                        \prop_gput:Nee \g__postnotes_header_page_last_prop
-                          { \l__postnotes_prev_text_page_tl }
-                          { \l__postnotes_prev_mark_page_tl }
-                        \prop_gput:Nee \g__postnotes_header_chap_last_prop
-                          { \l__postnotes_prev_text_page_tl }
-                          { \l__postnotes_prev_mark_chap_tl }
-                        \prop_gput:Nee \g__postnotes_header_sect_last_prop
-                          { \l__postnotes_prev_text_page_tl }
-                          { \l__postnotes_prev_mark_sect_tl }
-                        \prop_gput:Nee \g__postnotes_header_name_last_prop
-                          { \l__postnotes_prev_text_page_tl }
-                          { \l__postnotes_prev_mark_name_tl }
-                      }
-                    \prop_gput:Nee \g__postnotes_header_page_first_prop
-                      { \l__postnotes_curr_text_page_tl }
-                      { \__postnotes_extract_pageref:n { mark@ ##1 } }
-                    \prop_gput:Nee \g__postnotes_header_chap_first_prop
-                      { \l__postnotes_curr_text_page_tl }
-                      { \__postnotes_prop_item:nn {##1} { thechapter } }
-                    \prop_gput:Nee \g__postnotes_header_sect_first_prop
-                      { \l__postnotes_curr_text_page_tl }
-                      { \__postnotes_prop_item:nn {##1} { thesection } }
-                    \prop_gput:Nee \g__postnotes_header_name_first_prop
-                      { \l__postnotes_curr_text_page_tl }
-                      { \__postnotes_prop_item:nn {##1} { pnsectname } }
-                    \__postnotes_get_pageref:Nn
-                      \l__postnotes_prev_mark_page_tl { mark@ ##1 }
-                    \__postnotes_prop_get:nnN {##1} { thechapter }
-                      \l__postnotes_prev_mark_chap_tl
-                    \__postnotes_prop_get:nnN {##1} { thesection }
-                      \l__postnotes_prev_mark_sect_tl
-                    \__postnotes_prop_get:nnN {##1} { pnsectname }
-                      \l__postnotes_prev_mark_name_tl
-                    \tl_set:NV \l__postnotes_prev_text_page_tl
-                      \l__postnotes_curr_text_page_tl
-                  }
-              }
-          }
-      }
-    \tl_if_empty:NF \l__postnotes_prev_text_page_tl
-      {
-        \prop_gput:Nee \g__postnotes_header_page_last_prop
-          { \l__postnotes_prev_text_page_tl }
-          { \l__postnotes_prev_mark_page_tl }
-        \prop_gput:Nee \g__postnotes_header_chap_last_prop
-          { \l__postnotes_prev_text_page_tl }
-          { \l__postnotes_prev_mark_chap_tl }
-        \prop_gput:Nee \g__postnotes_header_sect_last_prop
-          { \l__postnotes_prev_text_page_tl }
-          { \l__postnotes_prev_mark_sect_tl }
-        \prop_gput:Nee \g__postnotes_header_name_last_prop
-          { \l__postnotes_prev_text_page_tl }
-          { \l__postnotes_prev_mark_name_tl }
-      }
+      \tl_gclear:N \pnhdpagefirst
+      \tl_gclear:N \pnhdpagelast
+      \tl_gclear:N \pnhdchapfirst
+      \tl_gclear:N \pnhdchaplast
+      \tl_gclear:N \pnhdsectfirst
+      \tl_gclear:N \pnhdsectlast
+      \tl_gclear:N \pnhdnamefirst
+      \tl_gclear:N \pnhdnamelast
+      \prop_gclear:N \g__postnotes_header_page_first_prop
+      \prop_gclear:N \g__postnotes_header_page_last_prop
+      \prop_gclear:N \g__postnotes_header_chap_first_prop
+      \prop_gclear:N \g__postnotes_header_chap_last_prop
+      \prop_gclear:N \g__postnotes_header_sect_first_prop
+      \prop_gclear:N \g__postnotes_header_sect_last_prop
+      \prop_gclear:N \g__postnotes_header_name_first_prop
+      \prop_gclear:N \g__postnotes_header_name_last_prop
+      \tl_gclear:N \g__postnotes_header_prev_last_page_tl
+      \tl_gclear:N \g__postnotes_header_prev_last_chap_tl
+      \tl_gclear:N \g__postnotes_header_prev_last_sect_tl
+      \tl_gclear:N \g__postnotes_header_prev_last_name_tl
+      \tl_clear:N \l__postnotes_prev_text_page_tl
+      \tl_clear:N \l__postnotes_curr_text_page_tl
+      \tl_clear:N \l__postnotes_prev_mark_page_tl
+      \tl_clear:N \l__postnotes_prev_mark_chap_tl
+      \tl_clear:N \l__postnotes_prev_mark_sect_tl
+      \tl_clear:N \l__postnotes_prev_mark_name_tl
+      \seq_map_inline:Nn #1
+        {
+          \exp_args:Ne \tl_if_eq:nnT
+            { \__postnotes_prop_item:nn {##1} { type } }
+            { note }
+            {
+              \__postnotes_get_pageref:Nn
+                \l__postnotes_curr_text_page_tl { text@ ##1 }
+              \tl_if_empty:NF \l__postnotes_curr_text_page_tl
+                {
+                  \tl_if_eq:NNTF
+                    \l__postnotes_prev_text_page_tl
+                    \l__postnotes_curr_text_page_tl
+                    {
+                      \__postnotes_get_pageref:Nn
+                        \l__postnotes_prev_mark_page_tl { mark@ ##1 }
+                      \__postnotes_prop_get:nnN {##1} { thechapter }
+                        \l__postnotes_prev_mark_chap_tl
+                      \__postnotes_prop_get:nnN {##1} { thesection }
+                        \l__postnotes_prev_mark_sect_tl
+                      \__postnotes_prop_get:nnN {##1} { pnsectname }
+                        \l__postnotes_prev_mark_name_tl
+                    }
+                    {
+                      \tl_if_empty:NF \l__postnotes_prev_text_page_tl
+                        {
+                          \prop_gput:Nee \g__postnotes_header_page_last_prop
+                            { \l__postnotes_prev_text_page_tl }
+                            { \l__postnotes_prev_mark_page_tl }
+                          \prop_gput:Nee \g__postnotes_header_chap_last_prop
+                            { \l__postnotes_prev_text_page_tl }
+                            { \l__postnotes_prev_mark_chap_tl }
+                          \prop_gput:Nee \g__postnotes_header_sect_last_prop
+                            { \l__postnotes_prev_text_page_tl }
+                            { \l__postnotes_prev_mark_sect_tl }
+                          \prop_gput:Nee \g__postnotes_header_name_last_prop
+                            { \l__postnotes_prev_text_page_tl }
+                            { \l__postnotes_prev_mark_name_tl }
+                        }
+                      \prop_gput:Nee \g__postnotes_header_page_first_prop
+                        { \l__postnotes_curr_text_page_tl }
+                        { \__postnotes_extract_pageref:n { mark@ ##1 } }
+                      \prop_gput:Nee \g__postnotes_header_chap_first_prop
+                        { \l__postnotes_curr_text_page_tl }
+                        { \__postnotes_prop_item:nn {##1} { thechapter } }
+                      \prop_gput:Nee \g__postnotes_header_sect_first_prop
+                        { \l__postnotes_curr_text_page_tl }
+                        { \__postnotes_prop_item:nn {##1} { thesection } }
+                      \prop_gput:Nee \g__postnotes_header_name_first_prop
+                        { \l__postnotes_curr_text_page_tl }
+                        { \__postnotes_prop_item:nn {##1} { pnsectname } }
+                      \__postnotes_get_pageref:Nn
+                        \l__postnotes_prev_mark_page_tl { mark@ ##1 }
+                      \__postnotes_prop_get:nnN {##1} { thechapter }
+                        \l__postnotes_prev_mark_chap_tl
+                      \__postnotes_prop_get:nnN {##1} { thesection }
+                        \l__postnotes_prev_mark_sect_tl
+                      \__postnotes_prop_get:nnN {##1} { pnsectname }
+                        \l__postnotes_prev_mark_name_tl
+                      \tl_set:NV \l__postnotes_prev_text_page_tl
+                        \l__postnotes_curr_text_page_tl
+                    }
+                }
+            }
+        }
+      \tl_if_empty:NF \l__postnotes_prev_text_page_tl
+        {
+          \prop_gput:Nee \g__postnotes_header_page_last_prop
+            { \l__postnotes_prev_text_page_tl }
+            { \l__postnotes_prev_mark_page_tl }
+          \prop_gput:Nee \g__postnotes_header_chap_last_prop
+            { \l__postnotes_prev_text_page_tl }
+            { \l__postnotes_prev_mark_chap_tl }
+          \prop_gput:Nee \g__postnotes_header_sect_last_prop
+            { \l__postnotes_prev_text_page_tl }
+            { \l__postnotes_prev_mark_sect_tl }
+          \prop_gput:Nee \g__postnotes_header_name_last_prop
+            { \l__postnotes_prev_text_page_tl }
+            { \l__postnotes_prev_mark_name_tl }
+        }
     \group_end:
   }
 \cs_new_protected:Npn \__postnotes_set_headers_vars:n #1
   {
     \group_begin:
-    \prop_get:NnNTF \g__postnotes_header_page_first_prop
-      {#1} \l__postnotes_tmpa_tl
-      { \tl_gset:NV \pnhdpagefirst \l__postnotes_tmpa_tl }
-      { \tl_gset:NV \pnhdpagefirst \g__postnotes_header_prev_last_page_tl }
-    \prop_get:NnNTF \g__postnotes_header_page_last_prop
-      {#1} \l__postnotes_tmpa_tl
-      {
-        \tl_gset:NV \pnhdpagelast \l__postnotes_tmpa_tl
-        \tl_gset:NV \g__postnotes_header_prev_last_page_tl
-          \l__postnotes_tmpa_tl
-      }
-      { \tl_gset:NV \pnhdpagelast \g__postnotes_header_prev_last_page_tl }
-    \prop_get:NnNTF \g__postnotes_header_chap_first_prop
-      {#1} \l__postnotes_tmpa_tl
-      { \tl_gset:NV \pnhdchapfirst \l__postnotes_tmpa_tl }
-      { \tl_gset:NV \pnhdchapfirst \g__postnotes_header_prev_last_chap_tl }
-    \prop_get:NnNTF \g__postnotes_header_chap_last_prop
-      {#1} \l__postnotes_tmpa_tl
-      {
-        \tl_gset:NV \pnhdchaplast \l__postnotes_tmpa_tl
-        \tl_gset:NV \g__postnotes_header_prev_last_chap_tl
-          \l__postnotes_tmpa_tl
-      }
-      { \tl_gset:NV \pnhdchaplast \g__postnotes_header_prev_last_chap_tl }
-    \prop_get:NnNTF \g__postnotes_header_sect_first_prop
-      {#1} \l__postnotes_tmpa_tl
-      { \tl_gset:NV \pnhdsectfirst \l__postnotes_tmpa_tl }
-      { \tl_gset:NV \pnhdsectfirst \g__postnotes_header_prev_last_sect_tl }
-    \prop_get:NnNTF \g__postnotes_header_sect_last_prop
-      {#1} \l__postnotes_tmpa_tl
-      {
-        \tl_gset:NV \pnhdsectlast \l__postnotes_tmpa_tl
-        \tl_gset:NV \g__postnotes_header_prev_last_sect_tl
-          \l__postnotes_tmpa_tl
-      }
-      { \tl_gset:NV \pnhdsectlast \g__postnotes_header_prev_last_sect_tl }
-    \prop_get:NnNTF \g__postnotes_header_name_first_prop
-      {#1} \l__postnotes_tmpa_tl
-      { \tl_gset:NV \pnhdnamefirst \l__postnotes_tmpa_tl }
-      { \tl_gset:NV \pnhdnamefirst \g__postnotes_header_prev_last_name_tl }
-    \prop_get:NnNTF \g__postnotes_header_name_last_prop
-      {#1} \l__postnotes_tmpa_tl
-      {
-        \tl_gset:NV \pnhdnamelast \l__postnotes_tmpa_tl
-        \tl_gset:NV \g__postnotes_header_prev_last_name_tl
-          \l__postnotes_tmpa_tl
-      }
-      { \tl_gset:NV \pnhdnamelast \g__postnotes_header_prev_last_name_tl }
+      \prop_get:NnNTF \g__postnotes_header_page_first_prop
+        {#1} \l__postnotes_tmpa_tl
+        { \tl_gset:NV \pnhdpagefirst \l__postnotes_tmpa_tl }
+        { \tl_gset:NV \pnhdpagefirst \g__postnotes_header_prev_last_page_tl }
+      \prop_get:NnNTF \g__postnotes_header_page_last_prop
+        {#1} \l__postnotes_tmpa_tl
+        {
+          \tl_gset:NV \pnhdpagelast \l__postnotes_tmpa_tl
+          \tl_gset:NV \g__postnotes_header_prev_last_page_tl
+            \l__postnotes_tmpa_tl
+        }
+        { \tl_gset:NV \pnhdpagelast \g__postnotes_header_prev_last_page_tl }
+      \prop_get:NnNTF \g__postnotes_header_chap_first_prop
+        {#1} \l__postnotes_tmpa_tl
+        { \tl_gset:NV \pnhdchapfirst \l__postnotes_tmpa_tl }
+        { \tl_gset:NV \pnhdchapfirst \g__postnotes_header_prev_last_chap_tl }
+      \prop_get:NnNTF \g__postnotes_header_chap_last_prop
+        {#1} \l__postnotes_tmpa_tl
+        {
+          \tl_gset:NV \pnhdchaplast \l__postnotes_tmpa_tl
+          \tl_gset:NV \g__postnotes_header_prev_last_chap_tl
+            \l__postnotes_tmpa_tl
+        }
+        { \tl_gset:NV \pnhdchaplast \g__postnotes_header_prev_last_chap_tl }
+      \prop_get:NnNTF \g__postnotes_header_sect_first_prop
+        {#1} \l__postnotes_tmpa_tl
+        { \tl_gset:NV \pnhdsectfirst \l__postnotes_tmpa_tl }
+        { \tl_gset:NV \pnhdsectfirst \g__postnotes_header_prev_last_sect_tl }
+      \prop_get:NnNTF \g__postnotes_header_sect_last_prop
+        {#1} \l__postnotes_tmpa_tl
+        {
+          \tl_gset:NV \pnhdsectlast \l__postnotes_tmpa_tl
+          \tl_gset:NV \g__postnotes_header_prev_last_sect_tl
+            \l__postnotes_tmpa_tl
+        }
+        { \tl_gset:NV \pnhdsectlast \g__postnotes_header_prev_last_sect_tl }
+      \prop_get:NnNTF \g__postnotes_header_name_first_prop
+        {#1} \l__postnotes_tmpa_tl
+        { \tl_gset:NV \pnhdnamefirst \l__postnotes_tmpa_tl }
+        { \tl_gset:NV \pnhdnamefirst \g__postnotes_header_prev_last_name_tl }
+      \prop_get:NnNTF \g__postnotes_header_name_last_prop
+        {#1} \l__postnotes_tmpa_tl
+        {
+          \tl_gset:NV \pnhdnamelast \l__postnotes_tmpa_tl
+          \tl_gset:NV \g__postnotes_header_prev_last_name_tl
+            \l__postnotes_tmpa_tl
+        }
+        { \tl_gset:NV \pnhdnamelast \g__postnotes_header_prev_last_name_tl }
     \group_end:
   }
 \cs_generate_variant:Nn \__postnotes_set_headers_vars:n { e }
-\AddToHook { shipout/before } [ postnotes/header ]
+\AddToHook { shipout/before } [ ./header ]
   { \__postnotes_set_headers_vars_next: }
 \bool_new:N \g__postnotes_header_vars_next_bool
 \cs_new_protected:Npn \__postnotes_set_headers_vars_next:
@@ -1093,30 +1438,29 @@
       { \pnhdnotes{} ~ \pnhdtopages{} ~ \pnhdpagefirst -- \pnhdpagelast }
   }
 \tl_new:N \l__postnotes_restore_tmp_tl
-\AddToHook { postnotes/note/begin } [ postnotes ]
+\AddToHook { postnotes/note/begin } [ ./compat/caption ]
+  { \cs_if_exist:NT \@captype { \postnotesetup { maybemulti } } }
+\AddToHook { package/biblatex/after } [ ./compat/biblatex ]
   {
-    \cs_if_exist:NT \@captype
-      { \bool_set_true:N \l__postnotes_maybe_multi_bool }
-  }
-\AddToHook { package/biblatex/after }
-  {
-    \AddToHook { postnotes/print/begin } [ postnotes ]
+    \AddToHook { postnotes/print/begin } [ postnotes/compat/biblatex ]
       { \toggletrue { blx at footnote } }
-    \AddToHook { begindocument/before } [ postnotes/mkbibendnote ]
+    \AddToHook { begindocument/before } [ postnotes/compat/biblatex ]
       {
         \cs_set:Npn \blx at theendnote { \postnote }
-        \cs_set:Npn \blx at theendnotetext
-          { \blx at err@endnote \footnotetext }
+        \cs_set:Npn \blx at theendnotetext { \blx at err@endnote \footnotetext }
       }
   }
-\tl_new:N \l__postnotes_note_zlabel_tl
-\AddToHook { package/zref-user/after }
+\str_new:N \l__postnotes_note_zlabel_str
+\AddToHook { package/zref-user/after } [ ./compat/zref-user ]
   {
     \keys_define:nn { postnotes/note }
       {
-        zlabel .tl_set:N = \l__postnotes_note_zlabel_tl ,
+        zlabel .str_set:N = \l__postnotes_note_zlabel_str ,
         zlabel .value_required:n = true ,
       }
+    \zref at newprop { postnote at mark } [] { \l__postnotes_mark_tl }
+    \AddToHook { postnotes/note/begin }  [ postnotes/compat/zref-user ]
+      { \zref at localaddprop { main } { postnote at mark } }
     \NewDocumentCommand \postnotezref { s m }
       { \__postnotes_note_zref:nn {#1} {#2} }
     \tl_new:N \l__postnotes_note_zref_zlabel_tl
@@ -1123,31 +1467,31 @@
     \cs_new_protected:Npn \__postnotes_note_zref:nn #1#2
       {
         \group_begin:
-        \tl_set:Nn \l__postnotes_note_zref_zlabel_tl {#2}
-        \__postnotes_typeset_mark_wrapper:nnn
-          {
-            \bool_lazy_all:nTF
-              {
-                { ! #1 }
-                { \l__postnotes_hyperlink_bool }
-                { \l__postnotes_zrefhyperref_bool }
-              }
-              {
-                \hyperlink
-                  { \zref at extractdefault {#2} { anchor } { } }
-                  { \__postnotes_make_mark:nnn { \zref{#2} } { } { } }
-              }
-              { \__postnotes_make_mark:nnn { \zref{#2} } { } { } }
-          }
-          { \tag_socket_use:n { postnotes/postnotezref/begin } }
-          { \tag_socket_use:n { postnotes/postnotezref/end }   }
+          \tl_set:Nn \l__postnotes_note_zref_zlabel_tl {#2}
+          \__postnotes_typeset_mark_wrapper:nnn
+            {
+              \bool_lazy_all:nTF
+                {
+                  { ! #1 }
+                  { \l__postnotes_hyperlink_bool }
+                  { \l__postnotes_zrefhyperref_bool }
+                }
+                {
+                  \hyperlink
+                    { \zref at extractdefault {#2} { anchor } { } }
+                    { \__postnotes_make_mark:nnn { \zref{#2} } { } { } }
+                }
+                { \__postnotes_make_mark:nnn { \zref{#2} } { } { } }
+            }
+            { \tag_socket_use:n { postnotes/postnotezref/begin } }
+            { \tag_socket_use:n { postnotes/postnotezref/end }   }
         \group_end:
       }
   }
 \bool_new:N \l__postnotes_zrefhyperref_bool
-\AddToHook { package/zref-hyperref/after }
+\AddToHook { package/zref-hyperref/after } [ ./compat/zref-hyperref ]
   { \bool_set_true:N \l__postnotes_zrefhyperref_bool }
-\AddToHook { package/zref-clever/after }
+\AddToHook { package/zref-clever/after } [ ./compat/zref-clever ]
   {
     \zcsetup
       {
@@ -1154,14 +1498,14 @@
         countertype = { postnote = endnote } ,
         countertype = { postnotetext = endnote } ,
       }
-    \AddToHook { postnotes/print/begin } [ postnotes ]
+    \AddToHook { postnotes/print/begin } [ postnotes/compat/zref-clever ]
       { \zcsetup { counterresetby = { postnotetext = postnotesection } } }
   }
-\AddToHook { package/zref-check/after }
+\AddToHook { package/zref-check/after } [ ./compat/zref-check ]
   {
     \IfPackageAtLeastTF { zref-check } { 2022-07-05 }
       {
-        \AddToHook { postnotes/note/store } [ postnotes ]
+        \AddToHook { postnotes/note/store } [ postnotes/compat/zref-check ]
           {
             \prop_gput:cne { \__postnotes_data_name:e { \l_postnotes_note_id_tl } }
               { zref-check at abschap } { \int_use:N \c at zc@abschap }
@@ -1168,7 +1512,7 @@
             \prop_gput:cne { \__postnotes_data_name:e { \l_postnotes_note_id_tl } }
               { zref-check at abssec } { \int_use:N \c at zc@abssec }
           }
-        \AddToHook { postnotes/print/note/begin } [ postnotes ]
+        \AddToHook { postnotes/print/note/begin } [ postnotes/compat/zref-check ]
           {
             \__postnotes_prop_get:nnN { \l_postnotes_print_note_id_tl }
               { zref-check at abschap } \l__postnotes_restore_tmp_tl
@@ -1180,9 +1524,9 @@
       }
       { }
   }
-\AddToHook { package/amsmath/after }
+\AddToHook { package/amsmath/after } [ ./compat/amsmath ]
   {
-    \AddToHook { postnotes/note/inhibit } [ postnotes ]
+    \AddToHook { postnotes/note/inhibit } [ postnotes/compat/amsmath ]
       {
         \legacy_if:nT { measuring@ }
           {
@@ -1191,18 +1535,15 @@
             \bool_set_true:N \l__postnotes_print_plain_mark_stepcounter_bool
           }
       }
-    \AddToHook { postnotes/note/begin } [ postnotes ]
-      {
-        \legacy_if:nF { firstchoice@ }
-          { \bool_set_true:N \l__postnotes_maybe_multi_bool }
-      }
+    \AddToHook { postnotes/note/begin } [ postnotes/compat/amsmath ]
+      { \legacy_if:nF { firstchoice@ } { \postnotesetup { maybemulti } } }
   }
-\AddToHook { package/csquotes/after }
+\AddToHook { package/csquotes/after } [ ./compat/csquotes ]
   {
     \bool_new:N \l__postnotes_csquotes_measuring_bool
     \BlockquoteDisable
       { \bool_set_true:N \l__postnotes_csquotes_measuring_bool }
-    \AddToHook { postnotes/note/inhibit } [ postnotes ]
+    \AddToHook { postnotes/note/inhibit } [ postnotes/compat/csquotes ]
       {
         \bool_if:NT \l__postnotes_csquotes_measuring_bool
           {
@@ -1212,15 +1553,15 @@
           }
       }
   }
-\AddToHook { package/tabularx/after }
+\AddToHook { package/tabularx/after } [ ./compat/tabularx ]
   {
     \bool_new:N \l__postnotes_tabularx_inside_env_bool
-    \AddToHook { env/tabularx/begin } [ postnotes ]
+    \AddToHook { env/tabularx/begin } [ postnotes/compat/tabularx ]
       {
         \bool_set_true:N \l__postnotes_tabularx_inside_env_bool
         \cs_set_eq:NN \__postnotes_tabularx_saved_write:Nn \write
       }
-    \AddToHook { postnotes/note/inhibit } [ postnotes ]
+    \AddToHook { postnotes/note/inhibit } [ postnotes/compat/tabularx ]
       {
         \bool_lazy_and:nnT
           { \l__postnotes_tabularx_inside_env_bool }
@@ -1231,12 +1572,20 @@
             \bool_set_true:N \l__postnotes_print_plain_mark_stepcounter_bool
           }
       }
+    \AddToHook { package/xltabular/after } [ postnotes/compat/xltabular ]
+      {
+        \AddToHook { env/xltabular/begin } [ postnotes/compat/xltabular ]
+          {
+            \bool_set_true:N \l__postnotes_tabularx_inside_env_bool
+            \cs_set_eq:NN \__postnotes_tabularx_saved_write:Nn \write
+          }
+      }
   }
-\AddToHook { package/tabularray/after }
+\AddToHook { package/tabularray/after } [ ./compat/tabularray ]
   {
-    \bool_if_exist:NTF \lTblrMeasuringBool
+    \bool_if_exist:NT \lTblrMeasuringBool
       {
-        \AddToHook { postnotes/note/inhibit } [ postnotes ]
+        \AddToHook { postnotes/note/inhibit } [ postnotes/compat/tabularray ]
           {
             \bool_if:NT \lTblrMeasuringBool
               {
@@ -1246,23 +1595,13 @@
               }
           }
       }
-      {
-        \clist_map_inline:nn
-          {
-            tblr , longtblr , talltblr , booktabs ,
-            longtabs , talltabs , +array
-          }
-          {
-            \AddToHook { env/#1/begin } [ postnotes ]
-              { \bool_set_true:N \l__postnotes_maybe_multi_bool }
-          }
-      }
   }
 \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/nomark/begin }{ 0 }
+\socket_new:nn { tagsupport/postnotes/nomark/end }{ 0 }
+\socket_new:nn { tagsupport/postnotes/multisep/begin }{ 0 }
+\socket_new:nn { tagsupport/postnotes/multisep/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 }
@@ -1300,15 +1639,15 @@
           }
         \__postnotes_tagsup_store_sctructnum:nN
           { postnotemark } \l_postnotes_note_id_tl
-        \tag_mc_begin:n{}
+        \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{}
+        \tag_mc_begin_pop:n { }
       }
-    \socket_new_plug:nnn { tagsupport/postnotes/mark/nomark } { default }
+    \socket_new_plug:nnn { tagsupport/postnotes/nomark/begin } { default }
       {
         \tag_struct_begin:n
           {
@@ -1318,23 +1657,25 @@
           }
         \__postnotes_tagsup_store_sctructnum:nN
           { postnotemark } \l_postnotes_note_id_tl
-        \tag_struct_end: % NonStruct
       }
+    \socket_new_plug:nnn { tagsupport/postnotes/nomark/end } { default }
+      { \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 }
+    \socket_assign_plug:nn { tagsupport/postnotes/nomark/begin } { default }
+    \socket_assign_plug:nn { tagsupport/postnotes/nomark/end } { default }
+    \socket_new_plug:nnn { tagsupport/postnotes/multisep/begin } { default }
       {
         \tag_mc_end_push:
         \tag_mc_begin:n { artifact }
       }
-    \socket_new_plug:nnn { tagsupport/postnotes/multsep/end } { default }
+    \socket_new_plug:nnn { tagsupport/postnotes/multisep/end } { default }
       {
         \tag_mc_end:
-        \tag_mc_begin_pop:n{}
+        \tag_mc_begin_pop:n { }
       }
-    \socket_assign_plug:nn { tagsupport/postnotes/multsep/begin } { default }
-    \socket_assign_plug:nn { tagsupport/postnotes/multsep/end } { default }
+    \socket_assign_plug:nn { tagsupport/postnotes/multisep/begin } { default }
+    \socket_assign_plug:nn { tagsupport/postnotes/multisep/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 }
@@ -1366,18 +1707,18 @@
     \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 }
-         }
+          {
+            \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
-         }
+          {
+            \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 }
@@ -1397,13 +1738,13 @@
             \tag_struct_begin:n { tag=text-unit }
             \tag_struct_begin:n { tag=text }
             \tag_tool:n { para/tagging=true }
-            \tag_mc_begin:n{}
+            \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{}
+            \tag_mc_begin:n { }
           }
       }
     \socket_new_plug:nnn { tagsupport/postnotes/printtext/end } { default }
@@ -1505,11 +1846,11 @@
       }
     \AddToHook { postnotes/note/store } [ postnotes/tagsup ]
       {
-        \tl_if_empty:NF \l__postnotes_note_label_tl
+        \str_if_empty:NF \l__postnotes_note_label_str
           {
             \prop_gput:cnV
               { \__postnotes_data_name:e { \l_postnotes_note_id_tl } }
-              { label } \l__postnotes_note_label_tl
+              { label } \l__postnotes_note_label_str
           }
       }
     \AddToHook { package/zref-user/after } [ postnotes/tagsup ]
@@ -1516,11 +1857,11 @@
       {
         \AddToHook { postnotes/note/store } [ postnotes/tagsup ]
           {
-            \tl_if_empty:NF \l__postnotes_note_zlabel_tl
+            \str_if_empty:NF \l__postnotes_note_zlabel_str
               {
                 \prop_gput:cnV
                   { \__postnotes_data_name:e { \l_postnotes_note_id_tl } }
-                  { zlabel } \l__postnotes_note_zlabel_tl
+                  { zlabel } \l__postnotes_note_zlabel_str
               }
           }
       }
@@ -1611,13 +1952,13 @@
               }
               { \tag_struct_begin:n { tag = endnotemark } }
           }
-        \tag_mc_begin:n{}
+        \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{}
+        \tag_mc_begin_pop:n { }
       }
     \socket_assign_plug:nn { tagsupport/postnotes/postnoteref/begin } { default }
     \socket_assign_plug:nn { tagsupport/postnotes/postnoteref/end } { default }
@@ -1666,13 +2007,13 @@
                   }
                   { \tag_struct_begin:n { tag = endnotemark } }
               }
-            \tag_mc_begin:n{}
+            \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{}
+            \tag_mc_begin_pop:n { }
           }
         \socket_assign_plug:nn { tagsupport/postnotes/postnotezref/begin } { default }
         \socket_assign_plug:nn { tagsupport/postnotes/postnotezref/end } { default }
@@ -1757,7 +2098,6 @@
 \__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.