texlive[63099] Master: postnotes (21apr22)

commits+karl at tug.org commits+karl at tug.org
Thu Apr 21 22:14:47 CEST 2022


Revision: 63099
          http://tug.org/svn/texlive?view=revision&revision=63099
Author:   karl
Date:     2022-04-21 22:14:47 +0200 (Thu, 21 Apr 2022)
Log Message:
-----------
postnotes (21apr22)

Modified Paths:
--------------
    trunk/Master/tlpkg/bin/tlpkg-ctan-check
    trunk/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc

Added Paths:
-----------
    trunk/Master/texmf-dist/doc/latex/postnotes/
    trunk/Master/texmf-dist/doc/latex/postnotes/CHANGELOG.md
    trunk/Master/texmf-dist/doc/latex/postnotes/DEPENDS.txt
    trunk/Master/texmf-dist/doc/latex/postnotes/README.md
    trunk/Master/texmf-dist/doc/latex/postnotes/postnotes-code.pdf
    trunk/Master/texmf-dist/doc/latex/postnotes/postnotes-code.tex
    trunk/Master/texmf-dist/doc/latex/postnotes/postnotes.pdf
    trunk/Master/texmf-dist/doc/latex/postnotes/postnotes.tex
    trunk/Master/texmf-dist/source/latex/postnotes/
    trunk/Master/texmf-dist/source/latex/postnotes/postnotes.dtx
    trunk/Master/texmf-dist/source/latex/postnotes/postnotes.ins
    trunk/Master/texmf-dist/tex/latex/postnotes/
    trunk/Master/texmf-dist/tex/latex/postnotes/postnotes.sty
    trunk/Master/tlpkg/tlpsrc/postnotes.tlpsrc

Added: trunk/Master/texmf-dist/doc/latex/postnotes/CHANGELOG.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/postnotes/CHANGELOG.md	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/latex/postnotes/CHANGELOG.md	2022-04-21 20:14:47 UTC (rev 63099)
@@ -0,0 +1,13 @@
+# Changelog
+
+## [Unreleased](https://github.com/gusbrs/postnotes/compare/v0.1.1...HEAD)
+
+## [v0.1.1](https://github.com/gusbrs/postnotes/compare/v0.1.0...v0.1.1) (2022-04-21)
+
+### Fixed
+- Adjusted for CTAN release requirements.
+
+## [v0.1.0](https://github.com/gusbrs/postnotes/releases/tag/v0.1.0) (2022-04-20)
+
+### Added
+- Initial release.


Property changes on: trunk/Master/texmf-dist/doc/latex/postnotes/CHANGELOG.md
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/latex/postnotes/DEPENDS.txt
===================================================================
--- trunk/Master/texmf-dist/doc/latex/postnotes/DEPENDS.txt	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/latex/postnotes/DEPENDS.txt	2022-04-21 20:14:47 UTC (rev 63099)
@@ -0,0 +1 @@
+soft hyperref


Property changes on: trunk/Master/texmf-dist/doc/latex/postnotes/DEPENDS.txt
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/latex/postnotes/README.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/postnotes/README.md	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/latex/postnotes/README.md	2022-04-21 20:14:47 UTC (rev 63099)
@@ -0,0 +1,24 @@
+# postnotes
+
+**Endnotes for LaTeX**
+
+Author: Gustavo Barros
+Maintainer: Gustavo Barros
+
+`postnotes` is an endnotes package for LaTeX.  Its user interface provides
+means to print multiple sections of notes along the document, and to subdivide
+them either automatically -- by chapter, by section -- or at manually
+specified places, thus being able to easily handle both numbered and
+unnumbered headings.  The package also provides infrastructure for setting up
+contextual running headers for printed notes.  The default is a simple but
+useful one, in the form "Notes to pages N--M", but more elaborate ones can
+be built.  When `hyperref` is loaded, `postnotes` provides hyperlinked
+notes, including back links.
+
+License: LPPL Version 1.3c
+
+Repository: https://github.com/gusbrs/postnotes
+
+Bug tracker: https://github.com/gusbrs/postnotes/issues
+
+CTAN: https://ctan.org/pkg/postnotes


Property changes on: trunk/Master/texmf-dist/doc/latex/postnotes/README.md
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/latex/postnotes/postnotes-code.pdf
===================================================================
(Binary files differ)

Index: trunk/Master/texmf-dist/doc/latex/postnotes/postnotes-code.pdf
===================================================================
--- trunk/Master/texmf-dist/doc/latex/postnotes/postnotes-code.pdf	2022-04-21 20:13:21 UTC (rev 63098)
+++ trunk/Master/texmf-dist/doc/latex/postnotes/postnotes-code.pdf	2022-04-21 20:14:47 UTC (rev 63099)

Property changes on: trunk/Master/texmf-dist/doc/latex/postnotes/postnotes-code.pdf
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/pdf
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/latex/postnotes/postnotes-code.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/postnotes/postnotes-code.tex	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/latex/postnotes/postnotes-code.tex	2022-04-21 20:14:47 UTC (rev 63099)
@@ -0,0 +1,53 @@
+% \iffalse meta-comment
+%
+% File: postnotes-code.tex
+%
+% This file is part of the LaTeX package "postnotes".
+%
+% Copyright (C) 2022  Gustavo Barros
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version.  The latest version
+% of this license is in the file:
+%
+%    https://www.latex-project.org/lppl.txt
+%
+% and version 1.3 or later is part of all distributions of LaTeX
+% version 2005/12/01 or later.
+%
+%
+% This work is "maintained" (as per LPPL maintenance status) by
+% Gustavo Barros.
+%
+% This work consists of the files postnotes.dtx,
+%                                 postnotes.ins,
+%                                 postnotes.tex,
+%                                 postnotes-code.tex,
+%                   and the files generated from them.
+%
+% The released version of this package is available from CTAN.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the package can be found at
+%
+%    https://github.com/gusbrs/postnotes
+%
+% for those people who are interested.
+%
+% -----------------------------------------------------------------------
+%
+% \fi
+
+\documentclass{l3doc}
+
+% Have \GetFileInfo pick up date and version data and used in the
+% documentation.
+\usepackage{postnotes}
+
+\begin{document}
+
+\DocInput{postnotes.dtx}
+
+\end{document}


Property changes on: trunk/Master/texmf-dist/doc/latex/postnotes/postnotes-code.tex
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/latex/postnotes/postnotes.pdf
===================================================================
(Binary files differ)

Index: trunk/Master/texmf-dist/doc/latex/postnotes/postnotes.pdf
===================================================================
--- trunk/Master/texmf-dist/doc/latex/postnotes/postnotes.pdf	2022-04-21 20:13:21 UTC (rev 63098)
+++ trunk/Master/texmf-dist/doc/latex/postnotes/postnotes.pdf	2022-04-21 20:14:47 UTC (rev 63099)

Property changes on: trunk/Master/texmf-dist/doc/latex/postnotes/postnotes.pdf
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/pdf
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/latex/postnotes/postnotes.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/postnotes/postnotes.tex	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/latex/postnotes/postnotes.tex	2022-04-21 20:14:47 UTC (rev 63099)
@@ -0,0 +1,972 @@
+% \iffalse meta-comment
+%
+% File: postnotes.tex
+%
+% This file is part of the LaTeX package "postnotes".
+%
+% Copyright (C) 2022  Gustavo Barros
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version.  The latest version
+% of this license is in the file:
+%
+%    https://www.latex-project.org/lppl.txt
+%
+% and version 1.3 or later is part of all distributions of LaTeX
+% version 2005/12/01 or later.
+%
+%
+% This work is "maintained" (as per LPPL maintenance status) by
+% Gustavo Barros.
+%
+% This work consists of the files postnotes.dtx,
+%                                 postnotes.ins,
+%                                 postnotes.tex,
+%                                 postnotes-code.tex,
+%                   and the files generated from them.
+%
+% The released version of this package is available from CTAN.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the package can be found at
+%
+%    https://github.com/gusbrs/postnotes
+%
+% for those people who are interested.
+%
+% -----------------------------------------------------------------------
+%
+% \fi
+
+\documentclass{l3doc}
+
+% The package itself *must* be loaded so that \GetFileInfo can pick up date
+% and version data.
+\usepackage{postnotes}
+\postnotesetup{
+  heading={
+    \section*{\pntitle}
+    \markright{\pnheaderdefault}
+    \addcontentsline{toc}{section}{\pntitle}
+  } ,
+}
+
+\usepackage[T1]{fontenc}
+
+\usepackage[sc]{mathpazo}
+\linespread{1.05}
+\usepackage[scale=.88]{tgheros} % sans
+\usepackage[varqu,scaled=1.03]{inconsolata} % tt
+\usepackage{microtype}
+
+\hypersetup{hidelinks}
+
+\usepackage{zref-clever}
+\zcsetup{
+  cap,
+  check,
+  titleref,
+  countertype = { pnexample = example } ,
+}
+
+\usepackage{listings}
+\lstdefinestyle{code}{
+  language=[LaTeX]TeX,
+  alsoletter = {_:},
+  moretexcs={
+    \chapter ,
+    \@mkboth ,
+    \@textsuperscript ,
+    \AddToHook ,
+    \counterwithin ,
+    \tableofcontents ,
+    \ExplSyntaxOn ,
+    \ExplSyntaxOff ,
+    \NewDocumentCommand ,
+    \tl_if_eq:NNTF ,
+    \bool_case_true:nF ,
+    \str_if_eq_p:ee ,
+    \prg_replicate:nn ,
+    \lipsum ,
+    \addto ,
+    \gappto ,
+    \extras ,
+    \captions ,
+  }
+}
+\lstdefinestyle{postnotes}{
+  style=code,
+  moretexcs={
+    \postnote ,
+    \postnoteref ,
+    \postnotesection ,
+    \printpostnotes ,
+    \postnotesetup ,
+    \pntitle ,
+    \pnhdnotes ,
+    \pnhdtopage ,
+    \pnhdtopages ,
+    \pnheaderdefault ,
+    \pnthechapter ,
+    \pnthesection ,
+    \pnthechapternextnote ,
+    \pnthesectionnextnote ,
+    \pnhdpagefirst ,
+    \pnhdpagelast ,
+    \pnhdchapfirst ,
+    \pnhdchaplast ,
+    \pnhdsectfirst ,
+    \pnhdsectlast ,
+    \pnhdnamefirst ,
+    \pnhdnamelast ,
+    \mypnheader ,
+    \demochapter ,
+  }
+}
+\lstset{
+  style=postnotes,
+  basicstyle=\ttfamily\small,
+  columns=fullflexible,
+  keepspaces,
+  xleftmargin=\leftmargin,
+  xrightmargin=.5\leftmargin,
+}
+% Setup inspired by https://tex.stackexchange.com/a/4068. For how to use these
+% environments in a .dtx context see https://tex.stackexchange.com/a/31026.
+\newcounter{pnexample}
+\lstnewenvironment{pnexample}[1][]{%
+  \renewcommand{\lstlistingname}{Example}%
+  \renewcommand*\theHlstlisting{ht.\thelstlisting}%
+  \lstset{#1}%
+  \setcounter{lstlisting}{\value{pnexample}}%
+}{}
+\lstnewenvironment{pnsnippet}[1][]{%
+  \renewcommand{\lstlistingname}{Example}%
+  \lstset{#1}%
+}{}
+\ExplSyntaxOn
+\makeatletter
+\lst at AddToHook { PreInit }
+  {
+    \cs_if_exist:cT { c@ \lstenv at name }
+      { \exp_args:Nx \refstepcounter { \lstenv at name } }
+  }
+\makeatother
+\ExplSyntaxOff
+
+\NewDocumentCommand\opt{m}{\texttt{#1}}
+
+\begin{document}
+
+\GetFileInfo{postnotes.sty}
+
+\title{%
+  The \pkg{postnotes} package%
+  \thanks{This file describes \fileversion, released \filedate.}%
+  \texorpdfstring{\\{}\medskip{}}{ - }%
+  User manual%
+  \texorpdfstring{\medskip{}}{}%
+}
+
+\author{%
+  Gustavo Barros%
+  \thanks{\url{https://github.com/gusbrs/postnotes}}%
+}
+
+\date{\filedate}
+
+\maketitle
+
+\begin{center}
+  {\bfseries \abstractname\vspace{-.5em}\vspace{0pt}}
+\end{center}
+
+\begin{quotation}
+  \pkg{postnotes} is an endnotes package for \LaTeX{}.  Its user interface
+  provides means to print multiple sections of notes along the document, and
+  to subdivide them either automatically -- by chapter, by section -- or at
+  manually specified places, thus being able to easily handle both numbered
+  and unnumbered headings.  The package also provides infrastructure for
+  setting up contextual running headers for printed notes.  The default is a
+  simple but useful one, in the form ``Notes to pages N--M'', but more
+  elaborate ones can be built.  When \pkg{hyperref} is loaded, \pkg{postnotes}
+  provides hyperlinked notes, including back links.
+\end{quotation}
+
+\clearpage{}
+
+\tableofcontents
+
+\clearpage{}
+
+\section{Introduction}
+
+\pkg{postnotes} is an endnotes package for \LaTeX{}.  Its user interface
+provides means to print multiple sections of notes along the document, and to
+subdivide them either automatically -- by chapter, by section -- or at
+manually specified places, thus being able to easily handle both numbered and
+unnumbered headings.  The package also provides infrastructure for setting up
+contextual running headers for printed notes.  The default is a simple but
+useful one, in the form ``Notes to pages N--M'', but more elaborate ones can
+be built.  When \pkg{hyperref} is loaded, \pkg{postnotes} provides hyperlinked
+notes, including back links.
+
+Though this feature set is mostly (albeit not completely) available in one or
+another of the existing endnotes packages for \LaTeX{}, subsets of it exist in
+individual packages, not necessarily compatible with each other.
+\pkg{postnotes} brings these features together in one place, with no external
+dependencies except an up-to-date kernel.
+
+On the technical side, \pkg{postnotes} is peculiar among existing \LaTeX{}
+packages in this area of functionality by the fact that it does not use an
+external file to store the notes.  Both the notes' contents and its metadata
+are stored in variables which are later retrieved at the time of printing.  In
+particular, the content of the note is stored and retrieved with ``no
+manipulation'' (as in \texttt{expl3}'s \texttt{N}/\texttt{n} function
+signatures) and only gets to be expanded at the time it is meant to be
+typeset.  The \file{.aux} file is leveraged to set page labels for the notes,
+since that particular information has to be retrieved asynchronously but,
+other than that, variables are employed to pass information around.
+
+This has some advantages.  First, as is well known, sending arbitrary content
+to a file to be read later is not a noiseless process in \LaTeX{}.  Thus, not
+doing so makes things smoother.  Second, the external file approach is
+strictly linear: the notes which were written to the file get printed as such,
+in the order they were written.  Having the notes available as a set of
+variables allows for some more flexibility than that, through the possibility
+of pre-processing the notes before printing.  It also brings some extra
+degrees of freedom in storing note metadata, and in restoring part of the
+environment where the note is called to where the note's content is printed.
+
+
+\section{Loading the package}
+
+\pkg{postnotes} can be loaded with the usual:
+
+\begin{pnsnippet}
+\usepackage{postnotes}
+\end{pnsnippet}
+
+The package does not accept load-time options, package options must be set
+using \cs{postnotesetup} (see \zcref{sec:options},
+\zcref[ref=title,noname]{sec:package-options}).
+
+\section{User interface}
+
+\begin{function}{\postnote}
+  \begin{syntax}
+    \cs{postnote}\oarg{options}\marg{text}
+  \end{syntax}
+\end{function}
+Sets a postnote with content \meta{text}.  A note ``mark'' is typeset at the
+place \cs{postnote} is called, and \meta{text} is stored to be typeset later,
+on the next call to \cs{printpostnotes}.  The mark is usually determined by
+the printed representation of the main counter, \texttt{postnote}, but can be
+manually set too.  \cs{postnote} can receive a number of \meta{options}, which
+are presented in \zcref{sec:options},
+\zcref[ref=title,noname]{sec:note-options}.
+
+\begin{function}{\postnotesection}
+  \begin{syntax}
+    \cs{postnotesection}\oarg{options}\marg{text}
+  \end{syntax}
+\end{function}
+Sets a postnote section with content \meta{text}.  This is the basic interface
+for making notes subdivisions, and it places \meta{text} between the notes
+where it occurs, at the point the notes are printed by \cs{printpostnotes}.
+For more details and some examples, see \zcref{sec:notes-sections}.  Its
+\meta{options} are presented in \zcref{sec:options},
+\zcref[ref=title,noname]{sec:section-options}.
+
+\begin{function}{\printpostnotes}
+  \begin{syntax}
+    \cs{printpostnotes}
+  \end{syntax}
+\end{function}
+Prints the \cs{postnotes} set since the last call of \cs{printpostnotes}, or
+since the beginning of the document.  For two basic usage illustrations, see
+\zcref{ex:sect:basic,ex:x:multi-print}.
+
+\begin{function}{\postnoteref}
+  \begin{syntax}
+    \cs{postnoteref}\meta{*}\marg{label}
+  \end{syntax}
+\end{function}
+Typesets a postnote reference to \meta{label}.  Of course, \meta{label} must
+have been set to a particular postnote, which can be done by the standard
+\cs{label} command.  The starred version of the command inhibits hyperlinking.
+When the \pkg{zref-user} package is loaded, a corresponding \cs{postnotezref}
+is also provided.
+
+
+\section{Options}
+\zlabel{sec:options}
+
+\subsection*{Package options}
+\zlabel{sec:package-options}
+
+\begin{function}{\postnotesetup}
+  \begin{syntax}
+    \cs{postnotesetup}\oarg{options}
+  \end{syntax}
+\end{function}
+Package options can be configured by means of \cs{postnotesetup}, which
+receives options and values in \texttt{key=value} fashion.
+
+\bigskip{}
+
+\DescribeOption{heading} %
+\DescribeOption{\cs{pnheading}} %
+The \opt{heading} option sets the heading for the printed notes or, more
+generally put, that which is printed at the beginning of \cs{printpostnotes}.
+Its default value depends on the document class in use.  If \cs{chapter} is
+defined, the default is:
+\begin{pnsnippet}
+\chapter*{\pntitle}
+\@mkboth{\pnheaderdefault}{\pnheaderdefault}
+\end{pnsnippet}
+but otherwise, it is:
+\begin{pnsnippet}
+\section*{\pntitle}
+\@mkboth{\pnheaderdefault}{\pnheaderdefault}
+\end{pnsnippet}
+where \cs{pntitle} is localizable string, which by default contains ``Notes''
+(see \zcref{sec:localization}), and \cs{pnheaderdefault} is a function which
+takes no arguments, but processes a number of variables, to set a contextual
+running header for the printed notes (see \zcref{sec:headers}).
+\cs{pnheaderdefault} produces a header in the form ``Notes to pages N--M'',
+according to the notes in each page.  If you prefer, you can redefine
+\cs{pnheading} instead of using the \opt{heading} option, to the same effect.
+
+\DescribeOption{format} %
+The \opt{format} option stores formatting instructions for printing the
+notes.  It is called at \cs{printpostnotes}, every time a block of notes is
+about to start.  The default value is \cs{small}.
+
+\DescribeOption{listenv} %
+The \opt{listenv} option sets the list environment inside which the notes are
+printed in \cs{printpostnotes}.  This must be the name of an existing list
+environment, and \pkg{postnotes} provides two suitable ones for convenience:
+\env{postnoteslist}, which is the default, and \env{postnoteslisthang} which
+typesets the notes with a hanging indent.  You can also create your own, with
+\pkg{enumitem} or otherwise, of course.  \opt{listenv} can also receive the
+special value \texttt{none}, in which case the notes blocks are not wrapped in
+a list environment, but rather typeset as plain paragraphs.
+\texttt{\opt{listenv}=none} already sets \opt{postprintnote} to \cs{par} for
+that reason but, when using \texttt{none}, you'll probably also want to set
+\opt{maketextmark}, \opt{pretextmark}, or \opt{posttextmark} to values
+different than the defaults.
+
+\DescribeOption{makemark} %
+\DescribeOption{maketextmark} %
+\DescribeOption{\cs{pnthepage}} %
+The \opt{makemark} and \opt{maketextmark} options control how the mark is to
+be typeset, at the point \cs{postnote} is called and at the point the note's
+text is printed at \cs{printpostnotes}, respectively.  They both can receive
+three arguments: \texttt{\#1} is the mark itself, and arguments \texttt{\#2}
+and \texttt{\#3} are, respectively, the start and the end of the hyperlink
+(hence they must be used in this order, and always in pair).  Their default
+values are:
+\begin{pnsnippet}
+makemark = {#2\hbox{\@textsuperscript{\normalfont#1}}#3} ,
+maketextmark = {#2#1.#3} ,
+\end{pnsnippet}
+At the point \opt{maketextmark} gets typeset, the \cs{pnthepage} variable
+contains the value of \cs{thepage} where its corresponding note was set.
+
+\DescribeOption{pretextmark} %
+\DescribeOption{posttextmark} %
+\DescribeOption{postprintnote} %
+The options \opt{pretextmark}, \opt{posttextmark}, and \opt{postprintnote}
+allow to insert additional material in \cs{printpostnotes}, respectively,
+right before the mark, right after the mark, and after the note's content.
+All in all, when \opt{listenv} is not \texttt{none}, each note in the list is
+laid out in the form:
+\begin{pnsnippet}[escapeinside=`']
+\item[`\meta{pretextmark}'`\meta{mark}'`\meta{posttextmark}']`\meta{note content}'`\meta{postprintnote}'
+\end{pnsnippet}
+and when \opt{listenv} is \texttt{none}, each note is laid out in the form:
+\begin{pnsnippet}[escapeinside=`']
+`\meta{pretextmark}'`\meta{mark}'`\meta{posttextmark}'`\meta{note content}'`\meta{postprintnote=\textbackslash{}\textbf{par}}'
+\end{pnsnippet}
+
+\DescribeOption{style} %
+\opt{style} is just a convenience ``meta'' option which sets a number of
+``base'' options -- such as \opt{listenv}, \opt{format}, \opt{maketextmark},
+etc.\ -- in order to emulate known styles of printing the notes.  It accepts
+the values \texttt{endnotes} or \texttt{pagenote} so that \cs{printpostnotes}
+works as its counterparts in each of these packages.
+
+\DescribeOption{hyperref} %
+\DescribeOption{backlink} %
+The \opt{hyperref} option controls the use of \pkg{hyperref} by
+\pkg{postnotes} and takes values \opt{auto}, \opt{true} or \opt{false}.  The
+default value, \opt{auto}, makes \pkg{postnotes} use \pkg{hyperref} if it is
+loaded.  \opt{true} does the same thing, but warns if \pkg{hyperref} is not
+loaded (\pkg{hyperref} is never loaded for you).  \opt{false} means not to use
+\pkg{hyperref} regardless of its availability.  The \opt{backlink} option
+controls whether only a link from the note to is respective text at
+\cs{printpostnotes} is created, or if a back link from the text at
+\cs{printpostnotes} back to where the note's mark is placed is also made
+available.  It is a boolean option, defaults to \texttt{true}, and is only
+operational if \opt{hyperref} is not \texttt{false}.  These are both preamble
+only options.
+
+\DescribeOption{sort} %
+The \opt{sort} option controls whether the notes queue is sorted or not at
+\cs{printpostnotes}.  Normally, the order the notes should be printed is the
+one in which the notes were placed along the document.  However, in cases
+where some manual intervention was required, sorting the notes can be quite
+useful, and difficult to handle in its absence.  Two typical examples are: a
+note inside a float which disturbed the sequence of the \texttt{postnote}
+counter (see \zcref{ex:x:float} in \zcref{sec:further-examples} for an
+illustration) and a manually set mark, in which case \pkg{postnotes} also
+allows to manually set a sort value with the \opt{sortnum} option of
+\cs{postnote}.  Sorting does not cross boundaries of notes sections, as set by
+\cs{postnotesection}, in other words, if notes sections exist, sorting is only
+ever carried out within the boundaries of each section.  This may be a
+restriction for cases in which floats cross sections' boundaries, but it's the
+only reasonable thing to do.  \opt{sort} is a boolean option, and defaults to
+\texttt{true}.
+
+
+\subsection*{Note options}
+\zlabel{sec:note-options}
+
+The options accepted by \cs{postnote}\oarg{options}\marg{text} are the
+following:
+
+\bigskip{}
+
+\DescribeOption{mark} %
+By default, the mark generated by \cs{postnote} is determined by the printed
+representation of the \texttt{postnote} counter, \cs{thepostnote}, which is
+stepped when \cs{postnote} is called.  But the \opt{mark} option allows you to
+manually set it, in case you want, or need, to do so.  When \opt{mark} is
+manually set, the \texttt{postnote} counter is not stepped.  Note that,
+differently from the optional argument of \cs{footnote}, this does not need to
+be a number, it can receive some text as value, which is directly used as the
+mark.
+
+\DescribeOption{sortnum} %
+Normally, the sort value used for sorting the notes queue (see the \opt{sort}
+package option above) is determined by the value of the \texttt{postnote}
+counter (that is, by \cs{the}\cs{c at postnote}, and not by its printed
+representation, \cs{thepostnote}).  But you may specify this sort value
+manually with the \opt{sortnum} option, typically, when you have also manually
+specified the mark.  It receives a floating point number as value.  So, for
+example, if one needed to insert a note between notes 2 and 3, without
+disturbing the numbering of other notes, one could use
+\texttt{\cs{postnote}[mark=2*,sortnum=2.5]\marg{text}}.
+
+\DescribeOption{nomark} %
+The \opt{nomark} option makes \cs{postnote} inhibit the typesetting of the
+mark.  Of course, normally, we do want the visual cue of the mark, but the
+intended use case for this option is for a \cs{postnote} with \opt{nomark} to
+be paired with a \cs{postnoteref}, so as to be able to typeset a note in
+places where doing so directly may be problematic.  For a practical example
+and an illustration on how to use it, see \zcref{ex:x:caption} in
+\zcref{sec:further-examples}.
+
+\DescribeOption{label} %
+The \opt{label} option sets a standard \cs{label} named with the value given
+to the option.  When the \pkg{zref-user} package is loaded, a corresponding
+\opt{zlabel} option is also provided.  See \zcref{sec:cross-references} for
+details about cross-referencing.
+
+
+\subsection*{Section options}
+\zlabel{sec:section-options}
+
+The options accepted by \cs{postnotesection}\oarg{options}\marg{text} are the
+following:
+
+\bigskip{}
+
+\DescribeOption{name} %
+For the purposes of building running headers, each \cs{postnotesection} can be
+identified by its \opt{name}.  This is mainly intended to support unnumbered
+headings, but its mechanism is general.  The name of a note section is made
+available for the first and last note on a given page through the variables
+\cs{pnhdnamefirst} and \cs{pnhdnamelast} at the moment the header of the page
+is typeset.  For details on how to use these variables, see
+\zcref{sec:headers}.
+
+
+\section{Notes sections}
+\zlabel{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
+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
+\cs{postnotesection} is skipped at \cs{printpostnotes} if it contains no
+notes.  In other words, if two (or more) calls of \cs{postnotesection} occur
+in immediate sequence, with no \cs{postnote} in between, the latter call takes
+precedence over the former, instead of being accumulated in the queue.  This
+is intended to facilitate the automation of the subdivision of the notes.  So,
+one can, for example, use a hook to \cs{chapter} and not have to worry if a
+chapter with no notes will generate an empty section inside
+\cs{printpostnotes}, e.g., by the call to \cs{chapter*} at the table of
+contents, and so on.  Or, one can use the heading number for the automated
+case, but be able to override it manually for an occasional unnumbered one.
+For this reason, a more semantic name was chosen for it, instead of the
+generic ``add to''.
+
+\DescribeOption{\cs{pnthechapter}} %
+\DescribeOption{\cs{pnthesection}} %
+\DescribeOption{\cs{pnthechapternextnote}} %
+\DescribeOption{\cs{pnthesectionnextnote}} %
+Just like with \cs{postnote}, the contents of \cs{postnotesection} are not
+expanded in place, but rather stored with ``no manipulation'' to be typeset
+later at \cs{printpostnotes}.  For this reason, some contextual information is
+stored at the place \cs{postnotesection} is called, and made available at the
+point it's content gets expanded by means of some variables.  When the content
+of a notes section gets typeset, \cs{pnthechapter} contains the value of
+\cs{thechapter} where \cs{postnotesection} was originally called.  Similarly,
+\cs{pnthesection} contains the value of \cs{thesection}.
+\cs{pnthechapternextnote} and \cs{pnthesectionnextnote} are meant to support
+the automation of the notes subdivision by using hooks to sectioning commands,
+which is a quite natural way to do this.  However, since it may be problematic
+to hook \emph{after} sectioning commands -- \cs{section}, for example, figures
+prominently in the documentation of \pkg{ltcmdhooks} as a case of ``look
+ahead'' command for which the \texttt{after} hook is not supported -- we will
+typically want to hook \emph{before} them.  But, at this point the values of
+the \texttt{chapter} or \texttt{section} counters have not yet been stepped,
+therefore \cs{thechapter} and \cs{thesection} do not correspond to what we
+would like to refer to.  For this reason, \cs{pnthechapternextnote} contains
+the value of \cs{thechapter} at the point the ``next note'' is placed (a
+\cs{postnote}, that is), the first in the chapter, and already inside it, thus
+with an expected value of the \texttt{chapter} counter.  Similarly,
+\cs{pnthesectionnextnote} contains the value of \cs{thesection} for the ``next
+note''.  Of course, the ``next note'' variables are \emph{proxies}, but they
+are meant to support the automation of the subdivision of the notes through
+the use of \texttt{before} hooks to the document's sectioning commands, in
+which case the subdivision of the notes will correspond to the document's
+structure and, given empty notes sections are skipped, the values will be the
+ones we are interested in.  But more complex use cases may require something
+different.  Either way, it is up to the user to judge whether the \emph{proxy}
+is a good one for their use case, the variables just do what they say, and
+contain the values of interest for the ``next note''.
+
+This is meant to be simple.  Some examples might make things more concrete.
+At its most basic, \cs{postnotesection} can just be set manually:
+
+\begin{pnexample}[caption={Basic usage},label={ex:sect:basic}]
+\documentclass{book}
+\usepackage{postnotes}
+\usepackage{hyperref}
+\begin{document}
+\chapter{First chapter}
+\postnotesection{\section*{Notes to chapter \pnthechapter}}
+Foo.\postnote{Foo note.}
+Bar.\postnote{Bar note.}
+\chapter{Second chapter}
+\postnotesection{\section*{Notes to chapter \pnthechapter}}
+\setcounter{postnote}{0}
+Baz.\postnote{Baz note.}
+Boo.\postnote{Boo note.}
+\printpostnotes
+\end{document}
+\end{pnexample}
+
+The document in \zcref{ex:sect:basic} resets the \texttt{postnote} counter for each
+chapter, and manually sets notes sections by chapter, which results in
+\cs{printpostnotes} being correspondingly subdivided.  But it is easy to make
+this automatic:
+
+\begin{pnexample}[caption={Automating notes subdivision with a hook},label={ex:sect:auto}]
+\documentclass{book}
+\usepackage{postnotes}
+\AddToHook{cmd/chapter/before}{%
+  \postnotesection{\section*{Notes to chapter \pnthechapternextnote}}}
+\counterwithin*{postnote}{chapter}
+\usepackage{hyperref}
+\begin{document}
+\tableofcontents
+\chapter{First chapter}
+Foo.\postnote{Foo note.}
+Bar.\postnote{Bar note.}
+\chapter{Second chapter}
+Baz.\postnote{Baz note.}
+Boo.\postnote{Boo note.}
+\printpostnotes
+\end{document}
+\end{pnexample}
+
+\zcref{ex:sect:auto} uses the \texttt{cmd/chapter/before} hook, and thus
+\cs{pnthechapternextnote} to retrieve the correct chapter number for
+\cs{postnotesection}, as explained above.  The counter is reset every chapter
+by means of \cs{counterwithin*}.  Note that the call to \cs{chapter*} inside
+\cs{tableofcontents} does not generate a spurious notes section at
+\cs{printpostnotes} (as long as you don't place a note in a sectioning command
+with no short argument, which you shouldn't do anyway).  But what if we have,
+among mostly numbered chapters, an ocasional unnumbered one?
+\cs{pnthechapternextnote} wouldn't possibly work in this case.  Since
+immediately successive calls to \cs{postnotesection} override the previous
+ones, it is straightforward to just manually adjust the exception:
+
+\begin{pnexample}[caption={Fine-tuning automation},label={ex:sect:fine-auto}]
+\documentclass{book}
+\usepackage{postnotes}
+\AddToHook{cmd/chapter/before}{%
+  \postnotesection{\section*{Notes to chapter \pnthechapternextnote}}}
+\counterwithin*{postnote}{chapter}
+\usepackage{hyperref}
+\begin{document}
+\tableofcontents
+\chapter*{Introduction}
+\postnotesection{\section*{Notes to the introduction}}
+Intro.\postnote{Intro note.}
+\chapter{First chapter}
+Foo.\postnote{Foo note.}
+Bar.\postnote{Bar note.}
+\chapter{Second chapter}
+Baz.\postnote{Baz note.}
+Boo.\postnote{Boo note.}
+\printpostnotes
+\end{document}
+\end{pnexample}
+
+\section{Headers}
+\zlabel{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
+some infrastructure for users to build more elaborate ones.
+
+The default headers are generated by the function \cs{pnheaderdefault} which,
+as we saw in \zcref{sec:section-options} is used to set the headers in option
+\opt{heading} (with \cs{@mkboth}).  So, the default headers are enabled
+through that particular setting.
+
+Examining the definition of \cs{pnheaderdefault} is possibly the most direct
+way to explore how the feature is meant to work.
+
+\begin{pnsnippet}
+\ExplSyntaxOn
+\NewDocumentCommand \pnheaderdefault {}
+  {
+    \tl_if_eq:NNTF \pnhdpagefirst \pnhdpagelast
+      { \pnhdnotes{} ~ \pnhdtopage{} ~ \pnhdpagefirst }
+      { \pnhdnotes{} ~ \pnhdtopages{} ~ \pnhdpagefirst -- \pnhdpagelast }
+  }
+\ExplSyntaxOff
+\end{pnsnippet}
+
+\cs{pnhdnotes}, \cs{pnhdtopage}, and \cs{pnhdtopages} are localizable strings,
+which by default respectively contain ``Notes'', ``to page'', and ``to pages''
+(see \zcref{sec:localization}).  Let's replace them to examine the interesting
+part of the definition:
+
+\begin{pnsnippet}
+\ExplSyntaxOn
+\NewDocumentCommand \pnheaderdefault {}
+  {
+    \tl_if_eq:NNTF \pnhdpagefirst \pnhdpagelast
+      { Notes~to~page~ \pnhdpagefirst }
+      { Notes~to~pages~ \pnhdpagefirst -- \pnhdpagelast }
+  }
+\ExplSyntaxOff
+\end{pnsnippet}
+
+\DescribeOption{\cs{pnhdpagefirst}} %
+\DescribeOption{\cs{pnhdpagelast}} %
+\DescribeOption{\cs{pnhdchapfirst}} %
+\DescribeOption{\cs{pnhdchaplast}} %
+\DescribeOption{\cs{pnhdsectfirst}} %
+\DescribeOption{\cs{pnhdsectlast}} %
+\DescribeOption{\cs{pnhdnamefirst}} %
+\DescribeOption{\cs{pnhdnamelast}} %
+\cs{pnhdpagefirst} and \cs{pnhdpagelast} store the value of \cs{thepage} for
+the first and the last notes (where these notes were originally placed) of the
+current page (at the point they are being printed).  These variables are
+updated every page along the span of \cs{printpostnotes} to the values
+corresponding to their respective first and last note (which start on that
+page), so that these values are available at the moment the headers get to be
+typeset.  Hence, what the definition of \cs{pnheaderdefault} does is to use
+these variables to build a rule in the form: ``if the page of the first and
+last notes are equal, write a singular form and just one value but, if they
+are different, write a plural form and a range of both values''.
+\cs{pnhdchapfirst}, \cs{pnhdchaplast}, \cs{pnhdsectfirst}, and
+\cs{pnhdsectfirst} provide the same for \cs{thechapter} and \cs{thesection}.
+\cs{pnhdnamefirst} and \cs{pnhdnamelast} contain the name of the notes
+section, the one given with the \opt{name} option of \cs{postnotesection} (and
+are empty in case no \opt{name} was provided).
+
+With that in hand, fancier headers can be built.  For example, if we'd like
+headers in the form ``Notes to chapters A--C, pages N--M'', we could define:
+\begin{pnsnippet}
+\ExplSyntaxOn
+\NewDocumentCommand \mypnheader {}
+  {
+    \tl_if_eq:NNTF \pnhdchapfirst \pnhdchaplast
+      { Notes~to~chapter~\pnhdchapfirst,~ }
+      { Notes~to~chapters~\pnhdchapfirst -- \pnhdchaplast,~ }
+    \tl_if_eq:NNTF \pnhdpagefirst \pnhdpagelast
+      { page~\pnhdpagefirst }
+      { pages~\pnhdpagefirst -- \pnhdpagelast }
+  }
+\ExplSyntaxOff
+\end{pnsnippet}
+and then set \opt{heading} to use \cs{mypnheader} instead of
+\cs{pnheaderdefault}.  This definition should work well as long as all the
+chapters (containing notes) are numbered, but if unnumbered ones come into
+play, again we can fine-tune the automation, adjusting for the exception.
+That's the purpose of the \opt{name} option for \cs{postnotesection}, and of
+\cs{pnhdnamefirst} and \cs{pnhdnamelast}.  \zcref{ex:hd:fancy} illustrates
+their use (of course, the use of \pkg{lipsum} is just for demonstration):
+
+\begin{pnexample}[caption={Fancy headers},label={ex:hd:fancy}]
+\documentclass{book}
+\usepackage{postnotes}
+\postnotesetup{
+  heading = {%
+    \chapter*{\pntitle}
+    \markboth{\mypnheader}{\mypnheader}%
+  } ,
+}
+\counterwithin*{postnote}{chapter}
+\AddToHook{cmd/chapter/before}{%
+  \postnotesection{\section*{Notes to chapter \pnthechapternextnote}}%
+}
+\ExplSyntaxOn
+\NewDocumentCommand \mypnheader {}
+  {
+    \bool_case_true:nF
+      {
+        {
+          \str_if_eq_p:ee { \pnhdnamefirst } { intro } &&
+          \str_if_eq_p:ee { \pnhdnamelast } { intro }
+        }
+        { Notes~to~the~introduction,~ }
+        {
+          \str_if_eq_p:ee { \pnhdnamefirst } { intro } &&
+          ! \str_if_eq_p:ee { \pnhdnamelast } { intro }
+        }
+        { Notes~to~the~introduction~and~chapter~\pnhdchaplast{},~ }
+      }
+      {
+        \tl_if_eq:NNTF \pnhdchapfirst \pnhdchaplast
+          { Notes~to~chapter~\pnhdchapfirst{},~ }
+          { Notes~to~chapters~\pnhdchapfirst{} -- \pnhdchaplast{},~ }
+      }
+    \tl_if_eq:NNTF \pnhdpagefirst \pnhdpagelast
+      { page~\pnhdpagefirst{} }
+      { pages~\pnhdpagefirst{} -- \pnhdpagelast{} }
+  }
+\ExplSyntaxOff
+\usepackage{hyperref}
+\usepackage{lipsum}
+\ExplSyntaxOn
+\NewDocumentCommand \demochapter { m }
+  { \prg_replicate:nn { #1 } { \lipsum[1-2]\postnote{\lipsum[3]}\par } }
+\ExplSyntaxOff
+\begin{document}
+\tableofcontents
+\chapter*{Introduction}
+\postnotesection[name=intro]{\section*{Notes to the introduction}}
+\demochapter{12}
+\chapter{Chapter 1}
+\demochapter{15}
+\chapter{Chapter 2}
+\demochapter{15}
+\printpostnotes
+\end{document}
+\end{pnexample}
+
+
+\section{Cross-references}
+\zlabel{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
+note.  One can either set a label with the \opt{label} option of
+\cs{postnote}, or one can directly set it with the standard \cs{label} as part
+of the note's content.  They are both valid, but they are not equivalent, they
+have different meanings and, accordingly, behave differently.
+
+The label set with the \opt{label} option is set at the place where
+\cs{postnote} is.  The label set with \cs{label} in the note's content, is
+just stored, and only gets expanded when this content gets to be typeset, at
+\cs{printpostnotes}.  In short, the \opt{label} option belongs to the
+``mark'', while the \cs{label} set in the content belongs to the ``text''.
+
+Of course, the data stored in each label will correspond to this difference.
+Even if the plain \cs{ref} to both will get the same value (the mark), a
+\cs{pageref} will be different, the links to either will point to different
+places, etc.
+
+
+\section{Localization}
+\zlabel{sec:localization}
+
+\DescribeOption{\cs{pntitle}} %
+\DescribeOption{\cs{pnhdnotes}} %
+\DescribeOption{\cs{pnhdtopage}} %
+\DescribeOption{\cs{pnhdtopages}} %
+\pkg{postnotes} uses a few localized strings, stored in the variables
+\cs{pntitle}, \cs{pnhdnotes}, \cs{pnhdtopage}, and \cs{pnhdtopages}.  The
+first one is used in the default value of the \opt{heading} option and
+defaults to ``Notes''.  The remaining three are used in \cs{pnheaderdefault}
+(and thus, indirectly also in the \opt{heading} option) and their respective
+defaults are: ``Notes'', ``to page'', and ``to pages''.  So, if you changed
+the default value of \opt{heading} and is not using \cs{pnheaderdefault}, you
+don't have to worry about them.
+
+These strings will automatically adjust to the document language, set either
+by \pkg{babel} or by \pkg{polyglossia}, \emph{if} the language is supported by
+\pkg{postnotes}.  Currently supported are English and Portuguese, and their
+variants.  Either way, you can always change these variables to the values of
+your preference.  If you are not using either \pkg{babel} or
+\pkg{polyglossia}, you can do so directly, for example, with:
+\begin{pnsnippet}
+\renewcommand*{\pntitle}{My title}
+\end{pnsnippet}
+However, with \pkg{babel} or \pkg{polyglossia}, and specially in a multi
+language document, you must use the appropriate hooks of your language package
+for this, otherwise, the next call to \cs{selectlanguage} will override your
+settings.  For \pkg{babel} you should use:
+\begin{pnsnippet}[escapeinside=`']
+\addto\extras`\meta{language}'{\renewcommand*{\pntitle}{My title}}
+\end{pnsnippet}
+and for \pkg{polyglossia}:
+\begin{pnsnippet}[escapeinside=`']
+\gappto\captions`\meta{language}'{\renewcommand*{\pntitle}{My title}}
+\end{pnsnippet}
+
+
+\section{Further examples}
+\zlabel{sec:further-examples}
+
+This section collects some further usage examples which did not fit into the
+previous sections, but might still be of interest.
+
+\bigskip{}
+
+\zcref{ex:x:multi-print} illustrates a basic procedure of how to obtain a note
+section for each chapter of a book, by calling \cs{printpostnotes} at the end
+of each chapter:
+
+\begin{pnexample}[caption={Notes for each chapter},label={ex:x:multi-print}]
+\documentclass{book}
+\usepackage{postnotes}
+\postnotesetup{heading={\section*{\pntitle}}}
+\usepackage{hyperref}
+\begin{document}
+\chapter{First chapter}
+Foo.\postnote{Foo note.}
+Bar.\postnote{Bar note.}
+\printpostnotes
+\chapter{Second chapter}
+\setcounter{postnote}{0}
+Baz.\postnote{Baz note.}
+Boo.\postnote{Boo note.}
+\printpostnotes
+\end{document}
+\end{pnexample}
+
+\zcref{ex:x:float} shows a case of a float which disturbs the order of the
+notes.  It demonstrates a (traditional) technique to deal with the situation,
+by setting a manual mark and adjusting the counter where appropriate.  It also
+illustrates the role the sorting of notes can have, by producing not only
+correctly ordered note marks (as a result of the manual adjustments), but also
+correctly ordered printed notes (as a result of sorting):
+
+\begin{pnexample}[caption={Sorting and floats},label={ex:x:float}]
+\documentclass{book}
+\usepackage{postnotes}
+\usepackage{hyperref}
+\begin{document}
+\chapter{First chapter}
+\postnote{1}
+\postnote{2}
+\begin{table}[p]
+  \caption{Table}
+  Table.\postnote[mark=5,sortnum=5]{3}
+\end{table}
+\postnote{4}
+\postnote{5}
+\stepcounter{postnote}
+\clearpage
+\postnote{6}
+\printpostnotes
+\end{document}
+\end{pnexample}
+
+\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
+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:
+
+\begin{pnexample}[caption={Long caption},label={ex:x:caption}]
+\documentclass{article}
+\usepackage[textwidth=8cm]{geometry}
+\usepackage{postnotes}
+\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.}}
+\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}}
+\end{figure}
+\printpostnotes
+\end{document}
+\end{pnexample}
+
+
+\section{Acknowledgments}
+
+Some people have kindly contributed to \pkg{postnotes}.  Suggestions, ideas,
+insightful comments, solutions to problems, bug reports were generously
+provided by (in chronological order):
+  Ulrike Fischer,
+  % 2022-03-22: https://chat.stackexchange.com/transcript/message/60708390#60708390
+  % 2022-03-28: https://chat.stackexchange.com/transcript/message/60754383#60754383
+  % 2022-03-31: https://github.com/latex3/hyperref/issues/230
+  % 2022-04-09: https://github.com/latex3/hyperref/issues/229
+  David Carlisle,
+  % 2022-03-28: https://chat.stackexchange.com/transcript/message/60754383#60754383
+  % 2022-04-08: https://tex.stackexchange.com/a/640035 (comments)
+  and Moritz Wemheuer.
+  % 2022-04-05: https://tex.stackexchange.com/q/597359#comment1594585_597389
+
+If I have inadvertently left anyone off the list I apologize, and please let
+me know, so that I can correct the oversight.
+
+Thank you all very much!
+
+
+\section{Change history}
+
+A change log with relevant changes for each version, eventual upgrade
+instructions, and upcoming changes, is maintained in the package's repository,
+at \url{https://github.com/gusbrs/postnotes/blob/main/CHANGELOG.md}.  The
+change log is also distributed with the package's documentation through CTAN
+upon release so, most likely, \texttt{texdoc postnotes/changelog} should
+provide easy local access to it.  An archive of historical versions of the
+package is also kept at \url{https://github.com/gusbrs/postnotes/releases}.
+
+\end{document}


Property changes on: trunk/Master/texmf-dist/doc/latex/postnotes/postnotes.tex
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/source/latex/postnotes/postnotes.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/postnotes/postnotes.dtx	                        (rev 0)
+++ trunk/Master/texmf-dist/source/latex/postnotes/postnotes.dtx	2022-04-21 20:14:47 UTC (rev 63099)
@@ -0,0 +1,2587 @@
+% \iffalse meta-comment
+%
+% File: postnotes.dtx
+%
+% This file is part of the LaTeX package "postnotes".
+%
+% Copyright (C) 2022  Gustavo Barros
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version.  The latest version
+% of this license is in the file:
+%
+%    https://www.latex-project.org/lppl.txt
+%
+% and version 1.3 or later is part of all distributions of LaTeX
+% version 2005/12/01 or later.
+%
+%
+% This work is "maintained" (as per LPPL maintenance status) by
+% Gustavo Barros.
+%
+% This work consists of the files postnotes.dtx,
+%                                 postnotes.ins,
+%                                 postnotes.tex,
+%                                 postnotes-code.tex,
+%                   and the files generated from them.
+%
+% The released version of this package is available from CTAN.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the package can be found at
+%
+%    https://github.com/gusbrs/postnotes
+%
+% for those people who are interested.
+%
+% -----------------------------------------------------------------------
+%
+% \fi
+%
+% \iffalse
+%<*driver>
+\documentclass{l3doc}
+
+% Have \GetFileInfo pick up date and version data and used in the
+% documentation.
+\usepackage{postnotes}
+
+\begin{document}
+
+\DocInput{postnotes.dtx}
+
+\end{document}
+%</driver>
+%
+% \fi
+%
+% \DoNotIndex{\\}
+%
+% \NewDocumentCommand\githubissue{m}{^^A
+%   issue~\href{https://github.com/gusbrs/postnotes/issues/#1}{\##1}}
+%
+% \NewDocumentCommand\githubPR{m}{^^A
+%   PR~\href{https://github.com/gusbrs/postnotes/pull/#1}{\##1}}
+%
+% ^^A Currently just for keeping semantic markup on this.
+% \NewDocumentCommand\contributor{m}{#1}
+%
+% \NewDocumentCommand\opt{m}{\texttt{#1}}
+%
+% \pdfstringdefDisableCommands{^^A
+%   \def\opt#1{#1}
+% }
+%
+% \AddToHook{env/macro/after}{\medskip{}}
+% \AddToHook{env/variable/after}{\medskip{}}
+% \AddToHook{env/function/after}{\medskip{}}
+%
+%
+% ^^A Have the Index at 'section' level rather than 'part'.  Otherwise it is
+% ^^A just the same definition from 'l3doc.cls'.
+% \IndexPrologue{^^A
+%   \section*{Index}
+%   \markboth{Index}{Index}
+%   \addcontentsline{toc}{section}{Index}
+%   The italic numbers denote the pages where the corresponding entry is
+%   described, numbers underlined point to the definition, all others indicate
+%   the places where it is used.^^A
+% }
+%
+%
+% \GetFileInfo{postnotes.sty}
+%
+% \title{^^A
+%   The \pkg{postnotes} package^^A
+%   \thanks{This file describes \fileversion, released \filedate.}^^A
+%   \texorpdfstring{\\{}\medskip{}}{ - }^^A
+%   Code documentation^^A
+%   \texorpdfstring{\medskip{}}{}^^A
+% }
+%
+% \author{^^A
+%   Gustavo Barros^^A
+%   \thanks{\url{https://github.com/gusbrs/postnotes}}^^A
+% }
+%
+% \date{\filedate}
+%
+% \maketitle
+%
+%
+% \tableofcontents
+%
+%
+% \clearpage{}
+%
+% \section{Initial setup}
+% Start the \pkg{DocStrip} guards.
+%    \begin{macrocode}
+%<*package>
+%    \end{macrocode}
+%
+% Identify the internal prefix (\LaTeX3 \pkg{DocStrip} convention).
+%    \begin{macrocode}
+%<@@=postnotes>
+%    \end{macrocode}
+%
+%
+% Require the new syntax for file/package hooks (\texttt{ltnews34},
+% \texttt{ltfilehook}).
+%
+%    \begin{macrocode}
+\providecommand\IfFormatAtLeastTF{\@ifl at t@r\fmtversion}
+\IfFormatAtLeastTF{2021-11-15}
+  {}
+  {%
+    \PackageError{postnotes}{LaTeX kernel too old}
+      {%
+        'postnotes' requires a LaTeX kernel 2021-11-15 or newer.%
+        \MessageBreak Loading will abort!%
+      }%
+    \endinput
+  }%
+%    \end{macrocode}
+%
+%
+%    \begin{macrocode}
+\ProvidesExplPackage {postnotes} {2022-04-21} {0.1.1}
+  {Endnotes for LaTeX}
+%    \end{macrocode}
+%
+%
+% \section{Data}
+%
+%
+% \begin{macro}[EXP]{\@@_data_name:n}
+%   Returns the name of the property list variable which stores the data of
+%   the \cs{postnote} with \meta{note id} number.
+%     \begin{syntax}
+%       \cs{@@_data_name:n} \Arg{note id}
+%     \end{syntax}
+%    \begin{macrocode}
+\cs_new:Npn \@@_data_name:n #1
+  { g_@@_ #1 _data_prop }
+\cs_generate_variant:Nn \@@_data_name:n { e }
+%    \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\@@_store:nn}
+%   Stores the metadata and \meta{note content} of \cs{postnote} with ID
+%   \meta{note id}, from where it is called.  The
+%   \texttt{postnotes/store/note} hook is intended to add further data to the
+%   note, when required to support packages with specific needs.
+%     \begin{syntax}
+%       \cs{@@_store:nn} \Arg{note id} \Arg{note content}
+%     \end{syntax}
+%    \begin{macrocode}
+\NewHook { postnotes/store/note }
+\cs_new_protected:Npn \@@_store:nn #1#2
+  {
+    \prop_new:c { \@@_data_name:e {#1} }
+    \prop_gput:cnn { \@@_data_name:e {#1} } { type } { note }
+    \prop_gput:cnx { \@@_data_name:e {#1} } { mark }
+      { \l_@@_mark_tl }
+    \prop_gput:cnx { \@@_data_name:e {#1} } { counter }
+      { \int_use:N \c at postnote }
+    \prop_gput:cnx { \@@_data_name:e {#1} } { sortnum }
+      {
+        \bool_if:NTF \l_@@_manual_sortnum_bool
+          { \fp_use:N \l_@@_sort_num_fp }
+          { \int_use:N \c at postnote }
+      }
+    \cs_if_exist:cT { chapter }
+      {
+        \prop_gput:cnx { \@@_data_name:e {#1} }
+          { thechapter } { \thechapter }
+      }
+    \prop_gput:cnx { \@@_data_name:e {#1} } { thesection }
+      { \thesection }
+    \prop_gput:cnx { \@@_data_name:e {#1} } { pnsectname }
+      { \g_@@_section_name_tl }
+    \prop_gput:cnx { \@@_data_name:e {#1} } { pnsectid }
+      { \int_use:N \g_@@_sectid_int }
+    \prop_gput:cnx { \@@_data_name:e {#1} } { multibool }
+      { \bool_to_str:N \l_@@_maybe_multi_bool }
+    \prop_gput:cnn { \@@_data_name:e {#1} } { content } {#2}
+    \UseHook { postnotes/store/note }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\@@_store_section:nn}
+%   Stores the metadata and \meta{note content} of \cs{postnotesection} with
+%   ID \meta{note id}, from where it is called.
+%     \begin{syntax}
+%       \cs{@@_store_section:nn} \Arg{note id} \Arg{note content}
+%     \end{syntax}
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_store_section:nn #1#2
+  {
+    \prop_new:c { \@@_data_name:e {#1} }
+    \prop_gput:cnn { \@@_data_name:e {#1} } { type } { section }
+    \cs_if_exist:cT { chapter }
+      {
+        \prop_gput:cnx { \@@_data_name:e {#1} }
+          { thechapter } { \thechapter }
+      }
+    \prop_gput:cnx { \@@_data_name:e {#1} } { thesection }
+      { \thesection }
+    \prop_gput:cnn { \@@_data_name:e {#1} } { content } {#2}
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}
+%   {
+%     \@@_prop_get:nnN ,
+%     \@@_prop_item:nn ,
+%     \@@_prop_gclear:n ,
+%   }
+%   Convenience functions to retrieve and clear data from a note based on the
+%   ID number.
+%     \begin{syntax}
+%       \cs{@@_prop_get:nnN} \Arg{note id} \Arg{property} \Arg{tl var to set}
+%       \cs{@@_prop_item:nn} \Arg{note id} \Arg{property}
+%       \cs{@@_prop_gclear:n} \Arg{note id}
+%     \end{syntax}
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_prop_get:nnN #1#2#3
+  {
+    \prop_get:cnNF { \@@_data_name:e {#1} } {#2} #3
+      { \tl_clear:N #3 }
+  }
+\cs_new:Npn \@@_prop_item:nn #1#2
+  { \prop_item:cn { \@@_data_name:e {#1} } {#2} }
+\cs_new_protected:Npn \@@_prop_gclear:n #1
+  { \prop_gclear:c { \@@_data_name:e {#1} } }
+%    \end{macrocode}
+% \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{syntax}
+%       \cs{post at note} \Arg{label name} \Arg{label content}
+%     \end{syntax}
+%    \begin{macrocode}
+\tl_const:Nn \c_@@_ref_prefix_tl { postnote at r }
+\cs_new_protected:Npx \post at note #1#2
+  { \exp_not:N \@newl at bel { \c_@@_ref_prefix_tl } {#1} {#2} }
+%    \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}
+%   {
+%     \@@_set_mark_page_label:n ,
+%     \@@_set_text_page_label:n ,
+%     \@@_set_print_page_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
+%   the \texttt{page}.
+%     \begin{syntax}
+%       \cs{@@_set_mark_page_label:n} \Arg{label name}
+%       \cs{@@_set_text_page_label:n} \Arg{label name}
+%       \cs{@@_set_print_page_label:n} \Arg{label name}
+%     \end{syntax}
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_set_mark_page_label:n #1
+  {
+    \iow_shipout_x:Nn \@auxout
+      { \post at note { mark@ #1 } { \thepage } }
+  }
+\cs_generate_variant:Nn \@@_set_mark_page_label:n { x }
+\cs_new_protected:Npn \@@_set_text_page_label:n #1
+  {
+    \iow_shipout_x:Nn \@auxout
+      { \post at note { text@ #1 } { \int_use:N \c at page } }
+  }
+\cs_generate_variant:Nn \@@_set_text_page_label:n { x }
+\cs_new_protected:Npn \@@_set_print_page_label:n #1
+  {
+    \iow_shipout_x:Nn \@auxout
+      { \post at note { print@ #1 } { \int_use:N \c at page } }
+  }
+\cs_generate_variant:Nn \@@_set_print_page_label:n { x }
+%    \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}
+%   {
+%     \@@_get_pageref:Nn ,
+%     \@@_extract_pageref:n ,
+%   }
+%   Reference data extraction functions.
+%     \begin{syntax}
+%       \cs{@@_get_pageref:Nn} \Arg{tl var to set} \Arg{label name}
+%       \cs{@@_extract_pageref:n} \Arg{label name}
+%     \end{syntax}
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_get_pageref:Nn #1#2
+  {
+    \cs_if_exist:cTF { \c_@@_ref_prefix_tl @ #2 }
+      { \tl_set:Nv #1 { \c_@@_ref_prefix_tl @ #2 } }
+      { \tl_clear:N #1 }
+  }
+\cs_generate_variant:Nn \@@_get_pageref:Nn { Nx }
+\cs_new:Npn \@@_extract_pageref:n #1
+  {
+    \cs_if_exist:cTF { \c_@@_ref_prefix_tl @ #1 }
+      { \exp_not:v { \c_@@_ref_prefix_tl @ #1 } }
+      { \c_empty_tl }
+  }
+\cs_generate_variant:Nn \@@_extract_pageref:n { e }
+%    \end{macrocode}
+% \end{macro}
+%
+%
+% \section{Options}
+%
+% \subsection*{\opt{heading} option}
+%
+%    \begin{macrocode}
+\keys_define:nn { postnotes/setup }
+  {
+    heading .cs_set_protected:Np = \pnheading ,
+    heading .value_required:n = true ,
+  }
+%    \end{macrocode}
+%
+% \begin{macro}[int]{\pnheading}
+%   Provide default value for \cs{pnheading}.
+%    \begin{macrocode}
+\cs_if_exist:cTF { chapter }
+  {
+    \cs_new_protected:Npn \pnheading
+      {
+        \chapter*{\pntitle}
+        \@mkboth{\pnheaderdefault}{\pnheaderdefault}
+      }
+  }
+  {
+    \cs_new_protected:Npn \pnheading
+      {
+        \section*{\pntitle}
+        \@mkboth{\pnheaderdefault}{\pnheaderdefault}
+      }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+%
+% \subsection*{\opt{format} option}
+%
+%    \begin{macrocode}
+\tl_new:N \l_@@_print_format_tl
+\keys_define:nn { postnotes/setup }
+  {
+    format .tl_set:N = \l_@@_print_format_tl ,
+    format .initial:n = { \small } ,
+    format .value_required:n = true ,
+  }
+%    \end{macrocode}
+%
+%
+% \subsection*{\opt{listenv} option}
+%
+%    \begin{macrocode}
+\tl_new:N \l_@@_print_env_tl
+\bool_new:N \l_@@_print_as_list_bool
+\keys_define:nn { postnotes/setup }
+  {
+    listenv .code:n =
+      {
+        \tl_if_eq:nnTF {#1} { none }
+          {
+            \bool_set_false:N \l_@@_print_as_list_bool
+            \tl_set:Nn \l_@@_post_printnote_tl { \par }
+%    \end{macrocode}
+% A sensible default just in case.  It should not get to be used though.
+%    \begin{macrocode}
+            \tl_set:Nn \l_@@_print_env_tl { itemize }
+          }
+          {
+            \bool_set_true:N \l_@@_print_as_list_bool
+            \tl_set:Nn \l_@@_print_env_tl {#1}
+          }
+      } ,
+    listenv .initial:n = { postnoteslist } ,
+    listenv .value_required:n = true ,
+  }
+%    \end{macrocode}
+%
+%
+% A couple of built-in list environments provided for convenience, and
+% \texttt{postnoteslist} as default.  The horizontal setup of the label in
+% these lists is based on the \texttt{description} environment of the standard
+% classes (see the \emph{The \LaTeX{} Companion}).
+%
+%    \begin{macrocode}
+\NewDocumentEnvironment { postnoteslist } { }
+  {
+    \list { }
+      {
+        \setlength { \leftmargin }    { 0pt }
+        \setlength { \labelwidth }    { 0pt }
+        \setlength { \itemindent }    { .5\parindent }
+        \cs_set_eq:NN \makelabel \@@_list_makelabel:n
+        \setlength { \rightmargin }   { 0pt }
+        \setlength { \listparindent } { \parindent }
+        \setlength { \parsep }    { \parskip }
+        \setlength { \itemsep }   { 0pt }
+        \setlength { \topsep }    { .5\topsep }
+        \setlength { \partopsep } { .5\partopsep }
+      }
+  }
+  { \endlist }
+\NewDocumentEnvironment { postnoteslisthang } { }
+  {
+    \list { }
+      {
+        \setlength { \leftmargin }    { 1em }
+        \setlength { \labelwidth }    { -\leftmargin }
+        \setlength { \itemindent }    { -2\leftmargin }
+        \cs_set_eq:NN \makelabel \@@_list_makelabel:n
+        \setlength { \rightmargin }   { 0pt }
+        \setlength { \listparindent } { \parindent }
+        \setlength { \parsep }    { \parskip }
+        \setlength { \itemsep }   { 0pt }
+        \setlength { \topsep }    { .5\topsep }
+        \setlength { \partopsep } { .5\partopsep }
+      }
+  }
+  { \endlist }
+\cs_new:Npn \@@_list_makelabel:n #1
+  { \hspace { \labelsep } \normalfont ~ #1 }
+%    \end{macrocode}
+%
+%
+% \subsection*{\opt{makemark} and \opt{maketextmark} options}
+%
+% The arguments are: \texttt{\#1} is the mark, \texttt{\#2} and \texttt{\#3}
+% are, respectively, the start and the end of the backlink.
+%
+%    \begin{macrocode}
+\keys_define:nn { postnotes/setup }
+  {
+    makemark .cs_set:Np = \@@_make_mark:nnn #1#2#3 ,
+    makemark .value_required:n = true ,
+%    \end{macrocode}
+% From the default kernel definition of \cs{@makefnmark}.
+%    \begin{macrocode}
+    makemark .initial:n =
+      { #2 \hbox { \@textsuperscript { \normalfont #1 } } #3 } ,
+    maketextmark .cs_set:Np = \@@_make_text_mark:nnn #1#2#3  ,
+    maketextmark .value_required:n = true ,
+    maketextmark .initial:n = { #2 #1 . #3 } ,
+  }
+%    \end{macrocode}
+%
+%
+% \subsection*{\opt{pretextmark}, \opt{posttextmark}, \opt{postprintnote} options}
+%
+%    \begin{macrocode}
+\tl_new:N \l_@@_pre_textmark_tl
+\tl_new:N \l_@@_post_textmark_tl
+\tl_new:N \l_@@_post_printnote_tl
+\keys_define:nn { postnotes/setup }
+  {
+    pretextmark .tl_set:N = \l_@@_pre_textmark_tl ,
+    pretextmark .value_required:n = true ,
+    posttextmark .tl_set:N = \l_@@_post_textmark_tl ,
+    posttextmark .value_required:n = true ,
+    postprintnote .tl_set:N = \l_@@_post_printnote_tl ,
+    postprintnote .value_required:n = true ,
+  }
+%    \end{macrocode}
+%
+%
+% \subsection*{\opt{hyperref} and \opt{backlink} options}
+%
+%    \begin{macrocode}
+\bool_new:N \l_@@_hyperlink_bool
+\bool_new:N \l_@@_hyperref_warn_bool
+\bool_new:N \l_@@_backlink_bool
+\keys_define:nn { postnotes/setup }
+  {
+    hyperref .choice: ,
+    hyperref / auto .code:n =
+      {
+        \bool_set_true:N \l_@@_hyperlink_bool
+        \bool_set_false:N \l_@@_hyperref_warn_bool
+      } ,
+    hyperref / true .code:n =
+      {
+        \bool_set_true:N \l_@@_hyperlink_bool
+        \bool_set_true:N \l_@@_hyperref_warn_bool
+      } ,
+    hyperref / false .code:n =
+      {
+        \bool_set_false:N \l_@@_hyperlink_bool
+        \bool_set_false:N \l_@@_hyperref_warn_bool
+      } ,
+    hyperref .initial:n = auto ,
+    hyperref .default:n = true ,
+    backlink .bool_set:N = \l_@@_backlink_bool ,
+    backlink .initial:n = true ,
+    backlink .default:n = true ,
+  }
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+\AddToHook { begindocument }
+  {
+    \IfPackageLoadedTF { hyperref }
+      { }
+      {
+        \bool_if:NT \l_@@_hyperref_warn_bool
+          { \msg_warning:nn { postnotes } { missing-hyperref } }
+        \bool_set_false:N \l_@@_hyperlink_bool
+      }
+    \keys_define:nn { postnotes/setup }
+      {
+        hyperref .code:n =
+          {
+            \msg_warning:nnn { postnotes }
+              { option-preamble-only } { hyperref }
+          } ,
+        backlink .code:n =
+          {
+            \msg_warning:nnn { postnotes }
+              { option-preamble-only } { backlink }
+          } ,
+      }
+  }
+\msg_new:nnn { postnotes } { option-preamble-only }
+  { Option~'#1'~only~available~in~the~preamble~\msg_line_context:. }
+\msg_new:nnn { postnotes } { missing-hyperref }
+  { Missing~'hyperref'~package.~Setting~'hyperref=false'. }
+%    \end{macrocode}
+%
+%
+% \subsection*{\opt{sort} option}
+%
+%    \begin{macrocode}
+\bool_new:N \l_@@_sort_bool
+\keys_define:nn { postnotes/setup }
+  {
+    sort .bool_set:N = \l_@@_sort_bool ,
+    sort .initial:n = true ,
+    sort .default:n = true ,
+  }
+%    \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 }
+          } ,
+        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{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 = { \par\noindent } ,
+        maketextmark = { { \normalfont ##2 ##1 . ##3 } } ,
+        posttextmark = { ~ } ,
+      } ,
+  }
+%    \end{macrocode}
+%
+%
+% \subsection*{\cs{postnotesetup}}
+%
+%
+% \begin{macro}[int]{\postnotesetup}
+%   Provide \cs{postnotesetup}.
+%   \begin{syntax}
+%     \cs{postnotesetup}\marg{options}
+%   \end{syntax}
+%    \begin{macrocode}
+\NewDocumentCommand \postnotesetup { m }
+  { \keys_set:nn { postnotes/setup } {#1} }
+%    \end{macrocode}
+% \end{macro}
+%
+%
+% \section{\cs{postnote}}
+%
+% Different from the traditional \cs{footnotemark} / \cs{footnotetext} system,
+% in the context of end notes, the functionality which corresponds to
+% \cs{footnotetext} is simply to store the data to be typeset later.  Hence,
+% some of the problems that afflict footnotes do not apply to end notes.
+% Namely, and as far as I can tell, they can be used in ``inner horizontal
+% mode'' (\cs{mbox} etc.), and in math mode, and if the ``text'' will be
+% typeset in the same page as the ``mark'' is of little concern.
+%
+% However, the separation between ``mark'' and ``text'' is still useful in
+% other contexts: floats and contexts where multiple typesetting passes are
+% performed.  \contributor{David Carlisle} and \contributor{Ulrike Fischer}
+% shared some thoughts on the matter at the TeX.SX chat:
+% \url{https://chat.stackexchange.com/transcript/message/60754383#60754383}.
+%
+% The interesting questions here are: if they are replaceable in their roles
+% in these contexts and how much would we lose by providing them.  In
+% analyzing this, we have to distinguish two situations: when
+% \cs{footnotemark} is called with no argument (and thus steps the counter),
+% and when it is called with the optional argument (and thus refrains from
+% stepping the counter).
+%
+% For floats, the problem they pose is that they may disturb the
+% \emph{ordering} of the notes.  This particular issue can be solved by using
+% \cs{footnotemark} without argument, and manually adjusting the counter on
+% subsequent calls to \cs{footnotetext}.  A good example of the technique is
+% \url{https://tex.stackexchange.com/a/43694}.  True, a user may wish to
+% specify the mark explicitly, but doesn't necessarily need to do it to solve
+% the ordering issue.
+%
+% Multiple typesetting passes of content are much harder.  And they abound:
+% the standard classes' \cs{caption} typesets the caption once, if it is
+% short, but twice if it is longer than a line; \pkg{amsmath}'s math
+% environments perform a measuring pass before actually typesetting the
+% equations; \pkg{amsmath}'s \cs{text} macro runs the contents through
+% \cs{mathchoice} (which typesets the contents four times) when in math mode;
+% \pkg{tabularx} and \pkg{tabularray} also perform measuring passes of their
+% tables; so does \pkg{csquotes}' blockquotes; and certainly more that I'm
+% unaware.  A number of these places offer some one or another way to mitigate
+% the issue: \pkg{amsmath}, \pkg{tabularx}, \pkg{csquotes} and (optionally)
+% \pkg{tabularray} restore counter values after measuring steps; \pkg{amsmath}
+% offers a boolean to indicate when it is a measuring pass; \pkg{csquotes}
+% offers further handles.  But the standard \cs{caption} offers none, and
+% neither does \pkg{amsmath}'s \cs{text} macro.  Well, the pkg{caption}
+% package has can disable the multiple passes for \cs{caption} with the option
+% \opt{singlelinecheck}, but it is not reasonable to require it for our
+% purposes, so we must assume the worst case.
+%
+% Enrico Gregorio is categorical in stating that \cs{endnotemark} and
+% \cs{endnotetext} are required for \pkg{enotez} to handle \cs{caption}, which
+% apparently it didn't offer originally: ``The package should implement
+% \cs{endnotemark} and \cs{endnotetext} for this case.  According to the
+% documentation, the author deems them to not be needed: he's wrong.''
+% (\url{https://tex.stackexchange.com/a/314937}).  See also
+% \url{https://tex.stackexchange.com/a/43794} and
+% \url{https://tex.stackexchange.com/a/358207}.
+%
+% In this scenario, when there's no way around the multiple passes,
+% \cs{footnotemark} can only handle the general case if used with an argument,
+% precisely because it inhibits the stepping of the counter.  Otherwise the
+% counter is stepped multiple times, and we'd get the wrong number (and mark).
+% In some circumstances, if we know the number of passes is deterministic, we
+% might get away by adjusting the counter manually (\cs{caption} may be dealt
+% with this way: if we know it to be two lines, we can decrement the counter
+% before it and get correct results, even hyperlinked).  But in cases which
+% adjusting the counter is sufficient, end notes can be dealt with in the same
+% way, and doesn't need the separation between ``mark'' and ``text''.  So,
+% what is distinctive of the kernel's footnote apparatus, which allows it as
+% much flexibility as one would like, is receiving an arbitrary number as
+% argument and not stepping the counter.  And as far as \cs{footnotemark} and
+% \cs{footnotetext}) are concerned, the main point of the optional argument is
+% really to ``manually establish the relation'' between the two of them.  So,
+% if \emph{not stepping the counter} is what is needed to handle the general
+% case, is it viable to do so? What would we loose in so doing?
+%
+% When receiving an arbitrary number as argument, as the kernel functionality
+% for footnotes and other endnotes packages do, this value is expected to the
+% printed as such, hence it must correspond to the \texttt{postnote} counter
+% (in our case).  But this counter is in the hands of the user, and can be
+% reset along the document, thus its uniqueness cannot be ensured.  But not
+% stepping \texttt{postnote} is perfectly viable, as it just aims at storing
+% how the mark is to be typeset.  However, not stepping the ID counter would
+% complicate things considerably.  Not doing so implies we'd lose the
+% connection we have between the ``mark'' and the corresponding ``text''.  We
+% might add the ``text'' to the queue, but all the metadata would be lost,
+% including the \pkg{hyperref} anchor, but really the set of data without
+% which the kind of functionality offered would be nonviable, or severely
+% hampered.  Not stepping \texttt{postnote} but stepping the ID counter also
+% is not sufficient, because we'd get a note in duplicity.  We could naively
+% think that a gap in the ID is not a problem, and just not add the duplicate
+% to the queue.  But how could we tell the difference between a legitimate and
+% an illegitimate step of the ID counter?
+%
+% I have not been able to devise a way to ``reconnect'' ``text'' and ``mark''
+% in the absence of the unique ID counter.  The most promising idea was to
+% have mandatory arguments to \cs{postnotemark} and \cs{postnotetext}
+% receiving a \meta{label} which we could use to identify their counterparts,
+% but I was not able to go through with this, and the attempts all increased
+% complexity considerably.  It is not just a label/ref system, there's got to
+% be a one-to-one correspondence between the sets, uniqueness has to be
+% ensured on both sides, and there cannot be ``lone'' marks or texts (a
+% bijection).  Besides, this label based system of identification would have
+% to live side-by-side with the one based on the counter.  So, even if we'd
+% have unique IDs, we wouldn't know beforehand in what form it comes.
+% Considering the ID is used to build the variable name in which we store the
+% note's information, this would also complicate things.
+%
+% Besides, there are ways to get things working with multiple passes without
+% the ``mark''/``text'' partition.  As mentioned, there are a number of cases
+% which offer some kind of ``handle'' or way to identify the multiple passes.
+% \pkg{csquotes} has a dedicated hook that can be used.  \pkg{amsmath} sets
+% the \texttt{measuring@} boolean (which \pkg{hyperref} also defines).  So,
+% not all cases are as tricky as \cs{caption} or \cs{text}, and even that can
+% be decently dealt with without a separation between ``mark'' and ``text''.
+% Besides, in difficult cases, the package offers a \opt{nomark} option to
+% \cs{postnote} to place a note, but typeset no mark. Than we can typeset a
+% mark with \cs{postnoteref} referring to a \cs{label} in the note of
+% interest.  This would result in a correct mark without duplicity, and in a
+% correct link from there to the note's text at \cs{printpostnotes}.  The
+% drawback is that the placement of \cs{postnote} would be important, and
+% results sensitive to it.  All the metadata is collected at the point of
+% \cs{postnote}, anchor included, not at the point of \cs{postnoteref}.  So
+% the consequences are a slightly off backlink, possibly imprecise metadata,
+% etc.  Considering \pkg{hyperref} itself shies away completely from linking
+% \cs{footnotemark} with an argument, I'd say there's some gain.
+%
+% The truth is there are some trade-offs, there's no ``ideal'' solution.
+% Still, all in all, my judgment is that the unique ID counter is worth more
+% than the inconveniences of an ocasional \texttt{\cs{postnote}[nomark]}
+% referenced with \cs{postnoteref}, and even that should not be needed much.
+% So, for the time being, until something else shakes this balance, I won't be
+% offering \cs{postnotemark} and \cs{postnotetext}.
+%
+% \bigskip{}
+%
+% For the \pkg{hyperref} support for cross-references in \cs{postnote}, I've
+% moved back and forth quite a lot.  One of the ideas I fancied was using
+% \cs{refstepcounter} and let \pkg{hyperref} do its job.  But, since I want to
+% have control of the anchor/destination name on both ``sides'', I'd have to
+% set \cs{theHpostnote} locally before calling \cs{refstepcounter}, otherwise
+% results might sensitive to user calls to \cs{counterwithin} (see
+% \url{https://github.com/latex3/hyperref/issues/230}, thanks
+% \contributor{Ulrike Fischer}).  However, even if that worked well for the
+% default case, we still had to setup things manually, in case of a manually
+% supplied mark.  All in all, I'm just calling \cs{stepcounter}, setting the
+% relevant cross-reference variables once and setting the anchor manually.
+%
+%
+% \bigskip{}
+%
+% \texttt{postnote} is the public, user facing, counter for \cs{postnote}.  It
+% determines how the note's mark gets to be typeset.  It can be reset, set,
+% and have its printed representation changed.  Of course, whether those are
+% meaningful is up to the user.
+%
+%    \begin{macrocode}
+\newcounter { postnote }
+%    \end{macrocode}
+%
+% \begin{macro}
+%   {
+%     \g_@@_note_id_int ,
+%     \l_@@_note_id_tl ,
+%     \g_@@_queue_seq ,
+%   }
+%   \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
+%   the connection between each note and its data, including the content,
+%   which is stored in a property list named according to \cs{@@_data_name:n}
+%   and the ID number.  \cs{l_@@_note_id_tl} is a convenience variable storing
+%   the counter's value.  \cs{g_@@_queue_seq} stores the sequence of notes'
+%   IDs that to be processed by the next call of \cs{printpostnotes}.
+%    \begin{macrocode}
+\int_new:N \g_@@_note_id_int
+\tl_new:N \l_@@_note_id_tl
+\tl_set:Nn \l_@@_note_id_tl { \int_use:N \g_@@_note_id_int }
+\seq_new:N \g_@@_queue_seq
+%    \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}[int]{\postnote}
+%   Provide \cs{postnote}.
+%   \begin{syntax}
+%     \cs{postnote} \oarg{options} \marg{note text}
+%   \end{syntax}
+%    \begin{macrocode}
+\NewDocumentCommand \postnote { O { } +m }
+  { \@@_note:nn {#1} {#2} }
+%    \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\@@_note:nn}
+%   The internal version of \cs{postnote}.  The \texttt{postnotes/note/begin}
+%   hook is meant to provide a place from where some additional setup for the
+%   note can be performed.  This is being used for adding support for some
+%   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}
+%   \end{syntax}
+%    \begin{macrocode}
+\NewHook { postnotes/note/begin }
+\cs_new_protected:Npn \@@_note:nn #1#2
+  {
+    \group_begin:
+    \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:Nx \l_@@_mark_tl { \thepostnote }
+          }
+        \seq_gput_right:Nx \g_@@_queue_seq
+          { \l_@@_note_id_tl }
+        \UseHook { postnotes/note/begin }
+        \cs_set:Npn \@currentcounter { postnote }
+        \cs_set:Npx \@currentlabel { \p at postnote \l_@@_mark_tl }
+        \@@_hyperref_make_currentHref:n
+          { postnote. \l_@@_note_id_tl .mark }
+        \@@_set_mark_page_label:x { \l_@@_note_id_tl }
+        \@@_set_user_labels:
+        \bool_if:NTF \l_@@_nomark_bool
+          {
+            \bool_if:NT \l_@@_hyperlink_bool
+              {
+                \@@_hyperref_set_anchor:n
+                  { postnote. \l_@@_note_id_tl .mark }
+              }
+          }
+          {
+            \@@_typeset_mark:xV
+              { \l_@@_note_id_tl } \l_@@_mark_tl
+          }
+        \@@_store:nn { \l_@@_note_id_tl } {#2}
+      }
+    \group_end:
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+%
+% Options for \cs{postnote}.
+%
+%    \begin{macrocode}
+\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
+\bool_new:N \l_@@_manual_sortnum_bool
+\bool_new:N \l_@@_maybe_multi_bool
+\keys_define:nn { postnotes/note }
+  {
+    mark .tl_set:N = \l_@@_mark_tl ,
+    mark .value_required:n = true ,
+    nomark .bool_set:N = \l_@@_nomark_bool ,
+    nomark .default:n = true ,
+    sortnum .code:n =
+      {
+        \fp_set:Nn \l_@@_sort_num_fp {#1}
+        \bool_set_true:N \l_@@_manual_sortnum_bool
+      } ,
+    sortnum .value_required:n = true ,
+    label .tl_set:N = \l_@@_note_label_tl ,
+    label .value_required:n = true ,
+  }
+%    \end{macrocode}
+%
+%
+% \begin{macro}{\@@_inhibit_note:TF}
+%   In contexts of multiple passes of content, it may be needed, or preferred,
+%   to inhibit the note altogether to avoid side effects and duplicity.  This
+%   conditional, obviously, will always return the true branch unless
+%   something is done in the \texttt{postnotes/note/inhibit} hook.  This hook
+%   is meant to handle support for packages or features which may justify note
+%   inhibition, and the code there should set \cs{l_@@_inhibit_note_bool} and
+%   \cs{l_@@_print_plain_mark_bool} as appropriate to the case.
+%    \begin{macrocode}
+\bool_new:N \l_@@_inhibit_note_bool
+\bool_new:N \l_@@_print_plain_mark_bool
+\NewHook { postnotes/note/inhibit }
+\prg_new_protected_conditional:Npnn \@@_inhibit_note: { F }
+  {
+    \bool_set_false:N \l_@@_inhibit_note_bool
+    \bool_set_false:N \l_@@_print_plain_mark_bool
+    \UseHook { postnotes/note/inhibit }
+%    \end{macrocode}
+% Printing a plain mark here may be needed because, if we are inhibiting the
+% note in a ``measuring context'' and omit it completely, the measuring being
+% performed will be off by the size of the mark.  So, to ensure the measuring
+% can be done correctly, we place the mark.  Since we'd only print this mark
+% in case of inhibition, when we don't actually step the counter, to typeset
+% correctly the mark that would be printed if the 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
+      {
+        \tl_if_empty:NT \l_@@_mark_tl
+          {
+            \group_begin:
+            \int_incr:N \c at postnote
+            \exp_args:NNNx
+              \group_end:
+              \tl_set:Nn \l_@@_mark_tl { \thepostnote }
+          }
+        \@@_typeset_mark_wrapper:n
+          { \@@_make_mark:nnn { \l_@@_mark_tl } { } { } }
+      }
+    \bool_if:NTF \l_@@_inhibit_note_bool
+      { \prg_return_true:  }
+      { \prg_return_false: }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}
+%   {
+%     \@@_typeset_mark:nn ,
+%     \@@_typeset_mark_wrapper:n ,
+%   }
+%   Auxiliary functions for mark typesetting in \cs{@@_note:nn}.
+%   \cs{@@_typeset_mark_wrapper:n} is based on the definition of
+%   \cs{@footnotemark} in the kernel.
+%   \begin{syntax}
+%     \cs{@@_typeset_mark:nn} \Arg{note id} \Arg{mark}
+%     \cs{@@_typeset_mark_wrapper:n} \Arg{mark}
+%   \end{syntax}
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_typeset_mark:nn #1#2
+  {
+    \@@_typeset_mark_wrapper:n
+      {
+        \bool_if:NTF \l_@@_hyperlink_bool
+          {
+            \@@_hyperref_set_anchor:n { postnote. #1 .mark }
+            \@@_make_mark:nnn {#2}
+              { \hyper at linkstart { link } { postnote. #1 .text } }
+              { \hyper at linkend }
+          }
+          { \@@_make_mark:nnn {#2} { } { } }
+      }
+  }
+\cs_generate_variant:Nn \@@_typeset_mark:nn { xV }
+\tl_new:N \l_@@_saved_spacefactor_tl
+\cs_new_protected:Npn \@@_typeset_mark_wrapper:n #1
+  {
+    \mode_leave_vertical:
+    \mode_if_horizontal:T
+      {
+        \tl_set:Nx \l_@@_saved_spacefactor_tl { \the\spacefactor }
+        \nobreak
+      }
+    #1
+    \mode_if_horizontal:T
+      { \spacefactor \l_@@_saved_spacefactor_tl }
+    \scan_stop:
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\@@_set_user_labels:}
+%   Auxiliary function for user label setting in \cs{@@_note:nn}.  Supports
+%   the \opt{label} and \opt{zlabel} options of \cs{postnote}.
+%    \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 }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+%
+% \section{\cs{postnoteref}}
+%
+% \begin{macro}[int]{\postnoteref}
+%   Provide \cs{postnoteref}.
+%   \begin{syntax}
+%     \cs{postnoteref}\meta{*}\marg{label}
+%   \end{syntax}
+%    \begin{macrocode}
+\NewDocumentCommand \postnoteref { s m }
+  { \@@_note_ref:nn {#1} {#2} }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_note_ref:nn}
+%   The internal version of \cs{postnoteref}.
+%   \begin{syntax}
+%     \cs{@@_note_ref:nn} \Arg{star bool} \Arg{label}
+%   \end{syntax}
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_note_ref:nn #1#2
+  {
+    \group_begin:
+    \@@_typeset_mark_wrapper:n
+      {
+        \bool_lazy_and:nnTF
+          { ! #1 }
+          { \l_@@_hyperlink_bool }
+          {
+            \hyperref [#2]
+              { \@@_make_mark:nnn { \ref*{#2} } { } { } }
+          }
+          { \@@_make_mark:nnn { \@@_ref_star:n {#2} } { } { } }
+      }
+    \group_end:
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+%
+% \section{\cs{postnotesection}}
+%
+% \begin{macro}[int]{\postnotesection}
+%   Provide \cs{postnotesection}.
+%   \begin{syntax}
+%     \cs{postnotesection}\oarg{options}\marg{section content}
+%   \end{syntax}
+%    \begin{macrocode}
+\NewDocumentCommand \postnotesection { O { } +m }
+  { \@@_section:nn {#1} {#2} }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_section:nn}
+%   The internal version of \cs{postnotesection}.
+%   \begin{syntax}
+%     \cs{@@_section:nn} \Arg{options} \Arg{content}
+%   \end{syntax}
+%    \begin{macrocode}
+\int_new:N \g_@@_sectid_int
+\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:Nx \g_@@_queue_seq { \l_@@_note_id_tl }
+    \tl_gclear:N \g_@@_section_name_tl
+    \keys_set:nn { postnotes/section } {#1}
+    \@@_store_section:nn { \l_@@_note_id_tl } {#2}
+    \group_end:
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+%
+% Options for \cs{postnotesection}.  Actually, I would have preferred to use
+% ``label'' for the \opt{name} option, but I feared I might need it further
+% down the road for the traditional meaning.
+%
+%    \begin{macrocode}
+\tl_new:N \g_@@_section_name_tl
+\keys_define:nn { postnotes/section }
+  {
+    name .tl_gset:N = \g_@@_section_name_tl ,
+    name .value_required:n = true ,
+  }
+%    \end{macrocode}
+%
+%
+% \section{\cs{printpostnotes}}
+%
+% \begin{macro}[int]{\printpostnotes}
+%   Provide \cs{printpostnotes}.
+%   \begin{syntax}
+%     \cs{printpostnotes}
+%   \end{syntax}
+%    \begin{macrocode}
+\NewDocumentCommand \printpostnotes { }
+  { \@@_print_notes: }
+%    \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}[int]
+%   {
+%     \pnthechapter ,
+%     \pnthesection ,
+%     \pnthechapternextnote ,
+%     \pnthesectionnextnote ,
+%     \pnthepage ,
+%   }
+%   User facing variables, aimed at making available some of the notes' and
+%   sections' metadata for the user at specific contexts.
+%    \begin{macrocode}
+\tl_new:N \pnthechapter
+\tl_new:N \pnthesection
+\tl_new:N \pnthechapternextnote
+\tl_new:N \pnthesectionnextnote
+\tl_new:N \pnthepage
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+%   {
+%     \g_@@_print_postnotes_int ,
+%     \l_@@_print_note_id_tl ,
+%     \l_@@_print_note_id_next_tl ,
+%     \l_@@_print_counter_tl ,
+%     \l_@@_print_mark_tl ,
+%     \l_@@_print_type_curr_tl ,
+%     \l_@@_print_type_next_tl ,
+%     \l_@@_print_type_prev_tl ,
+%     \l_@@_print_content_tl ,
+%     \l_@@_clear_queue_seq ,
+%   }
+%   Auxiliary variables for \cs{@@_print_notes:}.
+%    \begin{macrocode}
+\int_new:N \g_@@_print_postnotes_int
+\tl_new:N \l_@@_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_type_curr_tl
+\tl_new:N \l_@@_print_type_next_tl
+\tl_new:N \l_@@_print_type_prev_tl
+\tl_new:N \l_@@_print_content_tl
+\seq_new:N \l_@@_clear_queue_seq
+%    \end{macrocode}
+% \end{macro}
+%
+%
+% \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
+% been processed.  The \texttt{postnotes/print/eachnote} hook is run once for
+% each note, at the point where environment variables are being set or
+% restored, before the typesetting of either the mark or the text, but within
+% a group of its own of each note.
+%
+%    \begin{macrocode}
+\NewHook { postnotes/print/begin }
+\NewHook { postnotes/print/eachnote }
+%    \end{macrocode}
+%
+%
+% The \texttt{postnotetext} is a counter used to restore the original value of
+% \texttt{postnote} at the time of printing, for the purposes of
+% cross-referencing, it should be different from \texttt{postnote} if a note
+% may occur inside \cs{printpostnotes}.  The \texttt{postnotesection} is a
+% counter which is stepped for every postnote section which gets to be
+% actually typeset.  It's aim is to provide a valid ``enclosing counter'' to
+% \texttt{postnote} in the context of \cs{printpostnotes}.  Since we don't
+% know where \texttt{postnote} may have been reset along the document, in the
+% general case, we can't rely on any other preexisting counter.  This means
+% that the particular value of \texttt{postnotesection} is of little practical
+% meaning, it really is just meant to provide recognizable ``bounds'' for
+% \texttt{postnote} along the printing of the notes.  Indeed, it is
+% initialized to a very high value, so that ``marks'' and ``texts'' don't mix
+% in the same reference list, which would occur if the enclosing counters of
+% both belonged to the same range, and with somewhat arbitrary results, since
+% we cannot ensure the step of the enclosing counter along the document
+% matches \texttt{postnotesection}.  This is actually a tricky problem from
+% the cross-referencing standpoint: two different things, which should be of
+% the same type, are reset along the document, but shouldn't really be mixed
+% together.  They are both \LaTeXe{} counters, since they may be required
+% externally.  Their main intended use case is to support \pkg{zref-clever},
+% but in principle they can be of general use.
+%
+%    \begin{macrocode}
+\newcounter { postnotetext }
+\newcounter { postnotesection }
+\setcounter { postnotesection } { 10000 }
+%    \end{macrocode}
+%
+%
+% \begin{macro}{\@@_print_notes:}
+%   The internal version of \cs{printpostnotes}.
+%   \begin{syntax}
+%     \cs{@@_print_notes:}
+%   \end{syntax}
+%    \begin{macrocode}
+\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:
+%    \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.
+% Enrico Gregorio is correct, though, in criticizing it at
+% \url{https://tex.stackexchange.com/q/575905#comment1450213_575915}, and
+% 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_@@_print_note_id_tl
+            \@@_prop_get:nnN { \l_@@_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
+                  }
+%    \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:
+                    \@@_prop_get:nnN
+                      { \l_@@_print_note_id_tl }
+                      { thechapter } \pnthechapter
+                    \@@_prop_get:nnN
+                      { \l_@@_print_note_id_tl }
+                      { thesection } \pnthesection
+                    \@@_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_@@_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'
+                \tl_if_eq:NnF \l_@@_print_type_prev_tl { note }
+                  {
+                    \bool_if:NTF \l_@@_print_as_list_bool
+                      { \exp_args:Nx \begin { \l_@@_print_env_tl } }
+                      { \group_begin: }
+                    \l_@@_print_format_tl
+                  }
+                \group_begin:
+                \UseHook { postnotes/print/eachnote }
+                \@@_get_pageref:Nx \pnthepage
+                  { mark@ \l_@@_print_note_id_tl }
+                \@@_prop_get:nnN
+                  { \l_@@_print_note_id_tl }
+                  { mark } \l_@@_print_mark_tl
+                \@@_prop_get:nnN
+                  { \l_@@_print_note_id_tl }
+                  { counter } \l_@@_print_counter_tl
+                \@@_prop_get:nnN
+                  { \l_@@_print_note_id_tl }
+                  { content } \l_@@_print_content_tl
+                \cs_set:Npn \@currentcounter { postnotetext }
+                \int_set:Nn \c at postnotetext
+                  { \int_eval:n { \l_@@_print_counter_tl } }
+                \cs_set:Npx \@currentlabel
+                  { \p at postnote \l_@@_print_mark_tl }
+                \@@_hyperref_make_currentHref:n
+                  { postnote. \l_@@_print_note_id_tl .text }
+                \@@_text_mark_wrapper:n
+                  {
+                    \@@_set_text_page_label:x
+                      { \l_@@_print_note_id_tl }
+                    \@@_typeset_text_mark:eV
+                      { \l_@@_print_note_id_tl }
+                      \l_@@_print_mark_tl
+                  }
+                \l_@@_print_content_tl
+                \l_@@_post_printnote_tl
+                \group_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 }
+                  {
+                    \bool_if:NTF \l_@@_print_as_list_bool
+                      { \exp_args:Nx \end { \l_@@_print_env_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
+              }
+          }
+        \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 } }
+      }
+    \group_end:
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+%    \begin{macrocode}
+\msg_new:nnn { postnotes } { empty-printpostnotes }
+  { Empty~'\iow_char:N\\printpostnotes'~\msg_line_context:. }
+%    \end{macrocode}
+%
+%
+% \begin{macro}
+%   {
+%     \@@_typeset_text_mark:nn ,
+%     \@@_text_mark_wrapper:n ,
+%   }
+%   Auxiliary functions 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
+  {
+    \bool_if:NTF \l_@@_hyperlink_bool
+      {
+        \@@_hyperref_set_anchor:n { postnote. #1 .text }
+        \bool_if:NTF \l_@@_backlink_bool
+          {
+            \@@_make_text_mark:nnn {#2}
+              { \hyper at linkstart { link } { postnote. #1 .mark } }
+              { \hyper at linkend }
+          }
+          { \@@_make_text_mark:nnn {#2} { } { } }
+      }
+      { \@@_make_text_mark:nnn {#2} { } { } }
+  }
+\cs_generate_variant:Nn \@@_typeset_text_mark:nn { eV }
+\cs_new_protected:Npn \@@_text_mark_wrapper:n #1
+  {
+    \bool_if:NTF \l_@@_print_as_list_bool
+      {
+        \item
+          [ \l_@@_pre_textmark_tl #1 \l_@@_post_textmark_tl ]
+      }
+      { \l_@@_pre_textmark_tl #1 \l_@@_post_textmark_tl }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+%
+% \subsection*{Print auxiliary}
+%
+% \cs{@@_verify_multipass: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
+% 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
+% implication of this procedure is that, if there are any new notes marked as
+% \texttt{multibool}, (at least) three rounds of compilation will be needed,
+% since the 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{syntax}
+%     \cs{@@_verify_multipass:N} \meta{\cs{g_@@_queue_seq}}
+%   \end{syntax}
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_verify_multipass:N #1
+  {
+    \group_begin:
+    \seq_clear:N \l_tmpa_seq
+    \seq_map_inline:Nn #1
+      {
+        \@@_prop_get:nnN {##1} { multibool } \l_tmpa_tl
+        \tl_if_eq:NnTF \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} }
+      }
+    \seq_gset_eq:NN #1 \l_tmpa_seq
+    \group_end:
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\@@_sort_queue:N}
+%   Sorting function for \cs{@@_print_notes:}.
+%   \begin{syntax}
+%     \cs{@@_sort_queue:N} \meta{\cs{g_@@_queue_seq}}
+%   \end{syntax}
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_sort_queue:N #1
+  {
+    \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:
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+%
+% \section{Headers}
+%
+% The headers infrastructure of \pkg{postnotes} is comprised of three basic
+% parts:
+%
+% \begin{enumerate}
+% \item For each \cs{postnote}, labels are set storing the \texttt{page} where
+%   the note occurs.  Each note actually generates a pair of such labels, once
+%   when \cs{postnote} is called (with the mark), and another where the note
+%   is printed (in \cs{printpostnotes}).  The former ones store \cs{thepage},
+%   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},
+%   \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.
+% \item This information set is processed by \cs{@@_get_headers_data:N} at the
+%   beginning of \cs{@@_print_notes:} to identify the first and last note of
+%   each page in \cs{printpostnotes}, and to generate a mapping from these
+%   first and last notes on each page to the pages where their corresponding
+%   marks occur.  We also take the opportunity to enrich this mapping with
+%   other metadata of each note.  So we get also mappings from the first and
+%   last note on each page to \cs{thechapter}, \cs{thesection}, and the
+%   \opt{name} of the section in which they occur.  These mappings are stored
+%   in property lists \cs[no-index]{g_@@_header_\meta{info}_first_prop} and
+%   \cs[no-index]{g_@@_header_\meta{info}_last_prop} where the \texttt{key} is
+%   the page in \cs{printpostnotes} where their note's content is typeset (or
+%   rather where it starts to be typeset, it is the page where the text's mark
+%   is printed).
+% \item Based on these mappings, along the span of notes section we run
+%   \cs{@@_set_headers_vars_next:} at each \texttt{shipout/before} hook to set
+%   user facing variables for the \emph{next} page, which will be available
+%   when their heading gets typeset.  Given that at \texttt{shipout} we can
+%   rely on a correct value of the \texttt{page} counter, we use it as
+%   \texttt{key} to query the property lists generated in the previous step.
+%   These user facing variables are called \cs[no-index]{pnhd\meta{info}first}
+%   and \cs[no-index]{pnhd\meta{info}last}.  Since we cannot rely on the
+%   shipout hook for the first page of \cs{printpostnotes},
+%   \cs{@@_set_headers_vars_first:} is run at its beginning to ensure correct
+%   values are in place on the first page of the notes section.
+% \end{enumerate}
+%
+% These \cs[no-index]{pnhd\meta{info}first} and
+% \cs[no-index]{pnhd\meta{info}last} variables can then be used to build
+% simple functions which can be passed to mark commands to achieve rich
+% contextual running headers.
+%
+%
+% \begin{macro}[int]
+%   {
+%     \pnhdpagefirst ,
+%     \pnhdpagelast ,
+%     \pnhdchapfirst ,
+%     \pnhdchaplast ,
+%     \pnhdsectfirst ,
+%     \pnhdsectlast ,
+%     \pnhdnamefirst ,
+%     \pnhdnamelast ,
+%   }
+%   User facing variables, aimed at making available header data for the user.
+%   Setting these variables with correct values at the moment the header gets
+%   typeset is \emph{the} objective of the whole headers infrastructure of the
+%   package.
+%    \begin{macrocode}
+\tl_new:N \pnhdpagefirst
+\tl_new:N \pnhdpagelast
+\tl_new:N \pnhdchapfirst
+\tl_new:N \pnhdchaplast
+\tl_new:N \pnhdsectfirst
+\tl_new:N \pnhdsectlast
+\tl_new:N \pnhdnamefirst
+\tl_new:N \pnhdnamelast
+%    \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}
+%   {
+%     \g_@@_header_page_first_prop ,
+%     \g_@@_header_page_last_prop ,
+%     \g_@@_header_chap_first_prop ,
+%     \g_@@_header_chap_last_prop ,
+%     \g_@@_header_sect_first_prop ,
+%     \g_@@_header_sect_last_prop ,
+%     \g_@@_header_name_first_prop ,
+%     \g_@@_header_name_last_prop ,
+%     \g_@@_header_prev_last_page_tl ,
+%     \g_@@_header_prev_last_chap_tl ,
+%     \g_@@_header_prev_last_sect_tl ,
+%     \g_@@_header_prev_last_name_tl ,
+%     \l_@@_prev_text_page_tl ,
+%     \l_@@_curr_text_page_tl ,
+%     \l_@@_prev_mark_page_tl ,
+%     \l_@@_prev_mark_chap_tl ,
+%     \l_@@_prev_mark_sect_tl ,
+%     \l_@@_prev_mark_name_tl ,
+%   }
+%   Auxiliary variables for the headers infrastructure.
+%    \begin{macrocode}
+\prop_new:N \g_@@_header_page_first_prop
+\prop_new:N \g_@@_header_page_last_prop
+\prop_new:N \g_@@_header_chap_first_prop
+\prop_new:N \g_@@_header_chap_last_prop
+\prop_new:N \g_@@_header_sect_first_prop
+\prop_new:N \g_@@_header_sect_last_prop
+\prop_new:N \g_@@_header_name_first_prop
+\prop_new:N \g_@@_header_name_last_prop
+\tl_new:N \g_@@_header_prev_last_page_tl
+\tl_new:N \g_@@_header_prev_last_chap_tl
+\tl_new:N \g_@@_header_prev_last_sect_tl
+\tl_new:N \g_@@_header_prev_last_name_tl
+\tl_new:N \l_@@_prev_text_page_tl
+\tl_new:N \l_@@_curr_text_page_tl
+\tl_new:N \l_@@_prev_mark_page_tl
+\tl_new:N \l_@@_prev_mark_chap_tl
+\tl_new:N \l_@@_prev_mark_sect_tl
+\tl_new:N \l_@@_prev_mark_name_tl
+%    \end{macrocode}
+% \end{macro}
+%
+%
+% \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}}
+%   \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:Nx \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
+                  }
+                  {
+%    \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
+% \cs{l_@@_prev_text_page_tl} is initialized to empty).
+%
+% Set `last' values for previous page, based on the last valid
+% \texttt{prev_mark} stored ones.  There is no previous page to the first one
+% of \cs{printpostnotes}, so we don't set `last' values for it (conditioning
+% 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:Nxx \g_@@_header_page_last_prop
+                          { \l_@@_prev_text_page_tl }
+                          { \l_@@_prev_mark_page_tl }
+                        \prop_gput:Nxx \g_@@_header_chap_last_prop
+                          { \l_@@_prev_text_page_tl }
+                          { \l_@@_prev_mark_chap_tl }
+                        \prop_gput:Nxx \g_@@_header_sect_last_prop
+                          { \l_@@_prev_text_page_tl }
+                          { \l_@@_prev_mark_sect_tl }
+                        \prop_gput:Nxx \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:Nxx \g_@@_header_page_first_prop
+                      { \l_@@_curr_text_page_tl }
+                      { \@@_extract_pageref:n { mark@ ##1 } }
+                    \prop_gput:Nxx \g_@@_header_chap_first_prop
+                      { \l_@@_curr_text_page_tl }
+                      { \@@_prop_item:nn {##1} { thechapter } }
+                    \prop_gput:Nxx \g_@@_header_sect_first_prop
+                      { \l_@@_curr_text_page_tl }
+                      { \@@_prop_item:nn {##1} { thesection } }
+                    \prop_gput:Nxx \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
+%    \end{macrocode}
+%
+% Set \cs{l_@@_prev_text_page_tl} for the next page
+% (\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
+                  }
+              }
+          }
+      }
+%    \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}
+% 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:Nxx \g_@@_header_page_last_prop
+          { \l_@@_prev_text_page_tl }
+          { \l_@@_prev_mark_page_tl }
+        \prop_gput:Nxx \g_@@_header_chap_last_prop
+          { \l_@@_prev_text_page_tl }
+          { \l_@@_prev_mark_chap_tl }
+        \prop_gput:Nxx \g_@@_header_sect_last_prop
+          { \l_@@_prev_text_page_tl }
+          { \l_@@_prev_mark_sect_tl }
+        \prop_gput:Nxx \g_@@_header_name_last_prop
+          { \l_@@_prev_text_page_tl }
+          { \l_@@_prev_mark_name_tl }
+      }
+    \group_end:
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+%
+% The sequence of pages processed in \cs{@@_get_headers_data:N} is not ensured
+% to be continuous, since not every page of \cs{printpostnotes} starts a note.
+% There may be notes that fill whole pages, or the last page of the notes may
+% end with a note that started on the penultimate page.  We must handle this
+% case at \cs{@@_set_headers_vars:n}.  For every page for which there is
+% information provided by \cs{@@_get_headers_data:N} we store a
+% \texttt{header_prev_last} (the last value of the previous header) for each
+% of the variables of interest.  If the next page is skipped in the sequence
+% (no notes starting on it), we can use these stored values to set both
+% `first' and `last' variables based on them for that page.
+%
+%
+% \begin{macro}{\@@_set_headers_vars:n}
+%   Set user facing variables based on data generated by
+%   \cs{@@_get_headers_data:N}.
+%   \begin{syntax}
+%     \cs{@@_set_headers_vars:n} \Arg{page number}
+%   \end{syntax}
+%    \begin{macrocode}
+\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 }
+    \group_end:
+  }
+\cs_generate_variant:Nn \@@_set_headers_vars:n { x }
+%    \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}
+%   {
+%     \@@_set_headers_vars_next: ,
+%     \@@_set_headers_vars_first: ,
+%   }
+%   The functions that actually call \cs{@@_set_headers_vars:n} at the
+%   appropriate contexts with appropriate page values.  Though we set
+%   \cs{@@_set_headers_vars_next:} to run at every \texttt{shipout/before}
+%   hook of the document, it is made no-op by \cs{g_@@_header_vars_next_bool}
+%   which only has a \texttt{true} value inside \cs{printpostnotes}.
+%   \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 ]
+  { \@@_set_headers_vars_next: }
+\bool_new:N \g_@@_header_vars_next_bool
+\cs_new_protected:Npn \@@_set_headers_vars_next:
+  {
+    \bool_if:NT \g_@@_header_vars_next_bool
+      { \@@_set_headers_vars:x { \int_eval:n { \c at page + 1 } } }
+  }
+\cs_new_protected:Npn \@@_set_headers_vars_first:
+  {
+    \@@_set_print_page_label:x
+      { \int_use:N \g_@@_print_postnotes_int }
+    \@@_set_headers_vars:x
+      {
+        \@@_extract_pageref:e
+          { print@ \int_use:N \g_@@_print_postnotes_int }
+      }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}[int]{\pnheaderdefault}
+%   A basic header function to be used as default in the \opt{heading} option.
+%   It produces a header in the form ``Notes to pages N--M'', with a text
+%   which can be localized (see Section~\ref{sec:languages}).
+%   \begin{syntax}
+%     \cs{pnheaderdefault}
+%   \end{syntax}
+%    \begin{macrocode}
+\NewDocumentCommand \pnheaderdefault {}
+  {
+    \tl_if_eq:NNTF \pnhdpagefirst \pnhdpagelast
+      { \pnhdnotes{} ~ \pnhdtopage{} ~ \pnhdpagefirst }
+      { \pnhdnotes{} ~ \pnhdtopages{} ~ \pnhdpagefirst -- \pnhdpagelast }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+%
+% \section{Compatibility}
+%
+% \subsection*{\cs{caption}}
+%
+% For \cs{caption}'s possible two passes.  This catches more than just
+% captions, of course, but is not overkill.
+%
+% 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) call
+% \texttt{\textbackslash{}postnote[nomark]\{\textbackslash{}label\{mynote\}...\}}
+% right before the caption, 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 }
+  }
+%    \end{macrocode}
+%
+%
+% \subsection*{\pkg{hyperref}}
+%
+%    \begin{macrocode}
+\bool_new:N \g_@@_hyperref_loaded_bool
+\AddToHook { package/hyperref/after }
+  { \bool_gset_true:N \g_@@_hyperref_loaded_bool }
+%    \end{macrocode}
+%
+% \begin{macro}
+%   {
+%     \@@_hyperref_make_currentHref:n ,
+%     \@@_hyperref_set_anchor:n ,
+%     \@@_ref_star:n ,
+%   }
+%   Auxiliary functions for \pkg{hyperref} support.
+%   \begin{syntax}
+%     \cs{@@_hyperref_make_currentHref:n} \Arg{anchor/destination}
+%     \cs{@@_hyperref_set_anchor:n} \Arg{anchor/destination}
+%     \cs{@@_ref_star:n} \Arg{label}
+%   \end{syntax}
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_hyperref_make_currentHref:n #1
+  {
+    \bool_if:NT \g_@@_hyperref_loaded_bool
+      { \Hy at MakeCurrentHref {#1} }
+  }
+\cs_new_protected:Npn \@@_hyperref_set_anchor:n #1
+  {
+    \bool_if:NT \g_@@_hyperref_loaded_bool
+      { \Hy at raisedlink { \hyper at anchor {#1} } }
+  }
+\cs_new_protected:Npn \@@_ref_star:n #1
+  {
+    \bool_if:NTF \g_@@_hyperref_loaded_bool
+      { \ref*{#1} }
+      { \ref{#1} }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+%
+% \subsection*{\pkg{biblatex}}
+%
+% Thanks \contributor{Moritz Wemheuer}:
+% \url{https://tex.stackexchange.com/q/597359#comment1594585_597389}.
+%
+% We can make \pkg{biblatex}'s \texttt{refsegment}s and \texttt{refcontext}s
+% work, but \texttt{refsection}s are more complicated.  Currently,
+% \texttt{refsection}s are only supported if \cs{printpostnotes} is called
+% within each \texttt{refsection}, one cannot ``accumulate'' the notes from
+% all \texttt{refsection}s and print them at the end.  Well, one can, but they
+% will be considered part of the current \texttt{refsection} of wherever
+% \cs{printpostnotes} is placed (unless they were also cited in the original
+% \texttt{refsection} out of a \cs{postnote} which, of course, is not
+% something to rely on).
+%
+% Note that support for these features of \pkg{biblatex} is
+% \emph{experimental}.
+%
+%    \begin{macrocode}
+\AddToHook { package/biblatex/after }
+  {
+%    \end{macrocode}
+% Store \pkg{biblatex} variables for each note.
+%    \begin{macrocode}
+    \AddToHook { postnotes/store/note } [ postnotes ]
+      {
+        \prop_gput:cnx { \@@_data_name:e { \l_@@_note_id_tl } }
+          { biblatex at refsection } { \int_use:N \c at refsection }
+        \prop_gput:cnx { \@@_data_name:e { \l_@@_note_id_tl } }
+          { biblatex at refsegment } { \int_use:N \c at refsegment }
+        \prop_gput:cnx { \@@_data_name:e { \l_@@_note_id_tl } }
+          { biblatex at refcontextbool }
+          { \iftoggle { blx at refcontext } { true } { false } }
+        \prop_gput:cnV { \@@_data_name:e { \l_@@_note_id_tl } }
+          { biblatex at refcontext } \blx at refcontext@context
+      }
+%    \end{macrocode}
+% \pkg{biblatex} setup, once for \cs{printpostnotes} call.
+%    \begin{macrocode}
+    \AddToHook { postnotes/print/begin } [ postnotes ]
+      {
+        \@@_biblatex_endrefcontext_local:
+        \@@_biblatex_citereset_local:
+%    \end{macrocode}
+% Let \pkg{biblatex} know we are in a ``notes'' context.  See
+% \url{https://tex.stackexchange.com/a/304464}, including comments.
+%    \begin{macrocode}
+        \toggletrue { blx at footnote }
+      }
+%    \end{macrocode}
+% Restore \pkg{biblatex} variables for each note.
+%    \begin{macrocode}
+    \tl_new:N \l_@@_biblatex_restore_tl
+    \AddToHook { postnotes/print/eachnote } [ postnotes ]
+      {
+        \@@_prop_get:nnN { \l_@@_print_note_id_tl }
+          { biblatex at refsection } \l_@@_biblatex_restore_tl
+        \int_set:Nn \c at refsection { \l_@@_biblatex_restore_tl }
+        \@@_prop_get:nnN { \l_@@_print_note_id_tl }
+          { biblatex at refsegment } \l_@@_biblatex_restore_tl
+        \int_set:Nn \c at refsegment { \l_@@_biblatex_restore_tl }
+        \@@_prop_get:nnN { \l_@@_print_note_id_tl }
+          { biblatex at refcontextbool } \l_@@_biblatex_restore_tl
+        \use:c { toggle \l_@@_biblatex_restore_tl } { blx at refcontext }
+        \@@_prop_get:nnN { \l_@@_print_note_id_tl }
+          { biblatex at refcontext } \l_@@_biblatex_restore_tl
+        \blx at edef@refcontext { \l_@@_biblatex_restore_tl }
+      }
+%    \end{macrocode}
+% Make \pkg{biblatex}'s \cs{mkbibendnote} use \cs{postnote}.  This is very
+% likely desired in most cases, but may occasionally not be, so we add it to
+% an individually labeled hook, which can be disabled with
+% \texttt{\textbackslash{}RemoveFromHook\{begindocument/before\}[postnotes/mkbibendnote]}
+% in the preamble.
+%    \begin{macrocode}
+    \AddToHook { begindocument/before } [ postnotes/mkbibendnote ]
+      {
+        \cs_set_nopar:Npn \blx at theendnote { \postnote }
+        \cs_set_nopar:Npn \blx at theendnotetext
+          { \blx at err@endnote \footnotetext }
+      }
+%    \end{macrocode}
+% Auxiliary functions.
+%
+% \begin{macro}{\@@_biblatex_endrefcontext_local:}
+%   Replicate the job of \cs{endrefcontext}, but with local effects,
+%   restrained to the group of \cs{printpostnotes}.
+%    \begin{macrocode}
+    \cs_new_protected:Npn \@@_biblatex_endrefcontext_local:
+      {
+        \togglefalse { blx at refcontext }
+        \tl_clear:N \blx at refcontext@labelprefix
+        \tl_clear:N \blx at refcontext@labelprefix at real
+        \tl_set:Nx \blx at refcontext@sortingtemplatename { \blx at sorting }
+        \tl_set:Nn \blx at refcontext@sortingnamekeytemplatename { global }
+        \tl_set:Nn \blx at refcontext@uniquenametemplatename { global }
+        \tl_set:Nn \blx at refcontext@labelalphanametemplatename { global }
+        \blx at edef@refcontext
+          {
+            \blx at refcontext@sortingtemplatename /
+            \blx at refcontext@sortingnamekeytemplatename /
+            /
+            \blx at refcontext@uniquenametemplatename /
+            \blx at refcontext@labelalphanametemplatename
+          }
+      }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_biblatex_citereset_local:}
+%   Replicate the job of \cs{citereset}, but with local effects, restrained to
+%   the group of \cs{printpostnotes}.
+%    \begin{macrocode}
+    \cs_new_protected:Npn \@@_biblatex_citereset_local:
+      {
+%    \end{macrocode}
+% \noindent
+% {\em\scriptsize\verb|\global\cslet{blx at bsee@\the\c at refsection}\@empty|} \\
+% {\em\scriptsize\verb|\global\cslet{blx at fsee@\the\c at refsection}\@empty|}
+%    \begin{macrocode}
+        \tl_clear:c { blx at bsee@ \int_use:N \c at refsection }
+        \tl_clear:c { blx at fsee@ \int_use:N \c at refsection }
+%    \end{macrocode}
+% {\em\scriptsize\verb|\blx at ibidreset@force|}
+%    \begin{macrocode}
+        \undef \blx at lastkey@text
+        \undef \blx at lastkey@foot
+%    \end{macrocode}
+% {\em\scriptsize\verb|\blx at idemreset@force|}
+%    \begin{macrocode}
+        \undef \blx at lasthash@text
+        \undef \blx at lasthash@foot
+%    \end{macrocode}
+% {\em\scriptsize\verb|\blx at opcitreset@force|}
+%    \begin{macrocode}
+        \clist_map_inline:Nn \blx at trackhash@text
+          { \csundef { blx at lastkey@text@ ##1 } }
+        \tl_clear:N \blx at trackhash@text
+        \clist_map_inline:Nn \blx at trackhash@foot
+          { \csundef { blx at lastkey@foot@ ##1 } }
+        \tl_clear:N \blx at trackhash@foot
+%    \end{macrocode}
+% {\em\scriptsize\verb|\blx at loccitreset@force|}
+%    \begin{macrocode}
+        \clist_map_inline:Nn \blx at trackkeys@text
+          { \csundef { blx at lastnote@text@ ##1 } }
+        \tl_clear:N \blx at trackkeys@text
+        \clist_map_inline:Nn \blx at trackkeys@foot
+          { \csundef { blx at lastnote@foot@ ##1 } }
+        \tl_clear:N \blx at trackkeys@foot
+%    \end{macrocode}
+% {\em\scriptsize{}and all of them do:}
+%    \begin{macrocode}
+        \cs_set_eq:NN \blx at lastmpfn \z@
+      }
+%    \end{macrocode}
+% \end{macro}
+%
+%    \begin{macrocode}
+  }
+%    \end{macrocode}
+%
+% \pkg{biblatex}'s \texttt{refsections}, contrary to \texttt{refsegment}s and
+% \texttt{refcontext}s which are handled in the \LaTeX{} side of things (as
+% far as I can tell), need to go through \texttt{biber}, and must have correct
+% corresponding citation data written to the \file{.bcf} file.  And the way
+% \cs{refsection} is implemented presumes each section is only ever begun once
+% (fair\dots{}), thus making it difficult to ``reopen'' it, or append new
+% citations to it later on, when the notes are printed.  Given the complexity
+% of this machinery, it would be madness not to use \pkg{biblatex}'s
+% infrastructure directly, and try to ``emulate'' it.  The start of a
+% \texttt{refsection} must be registered on the \file{.bcf} file, and this is
+% done by \cs{refsection} (and its auxiliary functions).  However, a number of
+% its characteristics make things particularly difficult for the purpose at
+% hand: i) it unconditionally sets a label for the section which, of course,
+% cannot be done twice; and, critically, ii) the optional argument of the
+% environment (which receives the \meta{resources}) is used to set a local
+% assignment to \cs{blx at bibfiles}, based on which the relevant information is
+% written to the \file{.bcf} file, and when the group closes the information
+% is gone.  My best attempt is below (excluded from the package) but it is not
+% good.  It feels a wrong approach to ``go around'' the intended use of
+% \cs{refsection} so much, and it can't handle at all its optional argument,
+% for the reasons above.  It's also incomplete, since it does not handle
+% restoring \cs{l_@@_biblatex_orig_refsection_tl}.
+%
+%    \begin{macrocode}
+%<*gobble>
+\AddToHook { package/biblatex/after }
+  {
+    \tl_new:N \l_@@_biblatex_orig_refsection_tl
+    \tl_new:N \g_@@_biblatex_prev_refsection_tl
+    \AddToHook { postnotes/print/begin } [ postnotes ]
+      {
+        \tl_set:Nx \l_@@_biblatex_orig_refsection_tl
+          { \int_use:N \c at refsection }
+        \tl_gset:Nx \g_@@_biblatex_prev_refsection_tl
+          \l_@@_biblatex_orig_refsection_tl
+     }
+    \AddToHook { postnotes/print/eachnote } [ postnotes ]
+      {
+        \@@_prop_get:nnN { \l_@@_print_note_id_tl }
+          { biblatex at refsection } \l_@@_biblatex_restore_tl
+        \tl_if_eq:NNF
+          \l_@@_biblatex_restore_tl
+          \g_@@_biblatex_prev_refsection_tl
+          {
+            \int_set:Nn \c at blx@maxsection
+              { \l_@@_biblatex_restore_tl - 1 }
+            \tl_gset_eq:NN \g_@@_biblatex_prev_refsection_tl
+              \l_@@_biblatex_restore_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
+            \group_end:
+          }
+      }
+  }
+%</gobble>
+%    \end{macrocode}
+%
+%
+% \subsection*{\pkg{zref-user}}
+%
+% \begin{macro}{\l_@@_note_zlabel_tl}
+%   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:}.
+%    \begin{macrocode}
+\tl_new:N \l_@@_note_zlabel_tl
+%    \end{macrocode}
+% \end{macro}
+%
+%    \begin{macrocode}
+\AddToHook { package/zref-user/after }
+  {
+%    \end{macrocode}
+% Provide \opt{zlabel} option.
+%    \begin{macrocode}
+    \keys_define:nn { postnotes/note }
+      {
+        zlabel .tl_set:N = \l_@@_note_zlabel_tl ,
+        zlabel .value_required:n = true ,
+      }
+%    \end{macrocode}
+%
+% \begin{macro}[int]{\postnotezref}
+%   Provide \cs{postnotezref}.
+%   \begin{syntax}
+%     \cs{postnotezref}\meta{*}\marg{label}
+%   \end{syntax}
+%    \begin{macrocode}
+    \NewDocumentCommand \postnotezref { s m }
+      { \@@_note_zref:nn {#1} {#2} }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_note_zref:nn}
+%   The internal version of \cs{postnotezref}.
+%   \begin{syntax}
+%     \cs{@@_note_zref:nn} \Arg{star bool} \Arg{label}
+%   \end{syntax}
+%    \begin{macrocode}
+    \cs_new_protected:Npn \@@_note_zref:nn #1#2
+      {
+        \group_begin:
+        \@@_typeset_mark_wrapper:n
+          {
+            \bool_lazy_and:nnTF
+              { ! #1 }
+              { \l_@@_hyperlink_bool }
+              {
+                \hyperlink
+                  { \zref at extractdefault {#2} { anchor } { } }
+                  { \@@_make_mark:nnn { \zref{#2} } { } { } }
+              }
+              { \@@_make_mark:nnn { \zref{#2} } { } { } }
+          }
+        \group_end:
+      }
+%    \end{macrocode}
+% \end{macro}
+%
+%    \begin{macrocode}
+  }
+%    \end{macrocode}
+%
+%
+% \subsection*{\pkg{zref-clever}}
+%
+%    \begin{macrocode}
+\AddToHook { package/zref-clever/after }
+  {
+    \zcsetup
+      {
+        countertype = { postnote = endnote } ,
+        countertype = { postnotetext = endnote } ,
+      }
+    \AddToHook { postnotes/print/begin } [ postnotes ]
+      { \zcsetup { counterresetby = { postnotetext = postnotesection } } }
+  }
+%    \end{macrocode}
+%
+%
+% \subsection*{\pkg{amsmath}}
+%
+%    \begin{macrocode}
+\AddToHook { package/amsmath/after }
+  {
+%    \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 ]
+      {
+        \legacy_if:nT { measuring@ }
+          {
+            \bool_set_true:N \l_@@_inhibit_note_bool
+            \bool_set_true:N \l_@@_print_plain_mark_bool
+          }
+      }
+%    \end{macrocode}
+% However, the \cs{text} macro, defined by \pkg{amstext} (required by
+% \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.
+%    \begin{macrocode}
+    \AddToHook { postnotes/note/begin } [ postnotes ]
+      {
+        \legacy_if:nF { firstchoice@ }
+          { \bool_set_true:N \l_@@_maybe_multi_bool }
+      }
+  }
+%    \end{macrocode}
+%
+%
+% \subsection*{\pkg{csquotes}}
+%
+%    \begin{macrocode}
+\AddToHook { package/csquotes/after }
+  {
+    \bool_new:N \l_@@_csquotes_measuring_bool
+    \BlockquoteDisable
+      { \bool_set_true:N \l_@@_csquotes_measuring_bool }
+    \AddToHook { postnotes/note/inhibit } [ postnotes ]
+      {
+        \bool_if:NT \l_@@_csquotes_measuring_bool
+          {
+            \bool_set_true:N \l_@@_inhibit_note_bool
+            \bool_set_true:N \l_@@_print_plain_mark_bool
+          }
+      }
+  }
+%    \end{macrocode}
+%
+%
+% \subsection*{\pkg{tabularx}}
+%
+% For the identification of the trial passes in \pkg{tabularx}, see
+% \url{https://tex.stackexchange.com/a/640035} (including discussion in the
+% comments, thanks \contributor{David Carlisle}), and also
+% \url{https://tex.stackexchange.com/a/227155} and
+% \url{https://tex.stackexchange.com/a/352134}.
+%
+%    \begin{macrocode}
+\AddToHook { package/tabularx/after }
+  {
+    \bool_new:N \l_@@_tabularx_inside_env_bool
+    \AddToHook { env/tabularx/begin } [ postnotes ]
+      {
+        \bool_set_true:N \l_@@_tabularx_inside_env_bool
+        \cs_set_eq:NN \@@_tabularx_saved_write:Nn \write
+      }
+    \AddToHook { postnotes/note/inhibit } [ postnotes ]
+      {
+        \bool_lazy_and:nnT
+          { \l_@@_tabularx_inside_env_bool }
+          { ! \cs_if_eq_p:NN \write \@@_tabularx_saved_write:Nn }
+          {
+            \bool_set_true:N \l_@@_inhibit_note_bool
+            \bool_set_true:N \l_@@_print_plain_mark_bool
+          }
+      }
+  }
+%    \end{macrocode}
+%
+%
+% \subsection*{\pkg{tabularray}}
+%
+% I've tried, but I could not find any ``handle'' to distinguish in
+% \pkg{tabularray} a trial/measure pass from the final one.  So we use
+% \cs{@@_verify_multipass:N} for it.
+%
+%    \begin{macrocode}
+\AddToHook { package/tabularray/after }
+  {
+    \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}
+%
+%
+% \section{Languages}
+% \label{sec:languages}
+%
+% \begin{macro}[int]
+%   {
+%     \pntitle ,
+%     \pnhdnotes ,
+%     \pnhdtopage ,
+%     \pnhdtopages ,
+%   }
+%   Set of language specific user variables.  They are used in the default
+%   value of the \opt{heading} option and in \cs{pnheaderdefault} which,
+%   ultimately, is also used in the same place.
+%    \begin{macrocode}
+\tl_new:N \pntitle
+\tl_new:N \pnhdnotes
+\tl_new:N \pnhdtopage
+\tl_new:N \pnhdtopages
+\tl_set:Nn \pntitle { Notes }
+\tl_set:Nn \pnhdnotes { Notes }
+\tl_set:Nn \pnhdtopage { to~page }
+\tl_set:Nn \pnhdtopages { to~pages }
+%    \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\@@_define_language:nn}
+%   Defines language specific values for \meta{postnote language} by storing a
+%   set of assignments for the language specific variables in \meta{setup}.
+%   \meta{postnote language} is an internal name, typically the ``main'' name
+%   of the language, based on which we can set specific \pkg{babel} or
+%   \pkg{polyglossia} languages or variants.
+%     \begin{syntax}
+%       \cs{@@_define_language:nn} \Arg{postnote language} \Arg{setup}
+%     \end{syntax}
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_define_language:nn #1#2
+  {
+    \tl_new:c { g_@@_language_ #1 _tl }
+    \tl_gset:cn { g_@@_language_ #1 _tl } {#2}
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+%
+% For \pkg{babel} we use the new hook system, it's clean, and avoids the
+% \cs{addto} pitfalls.  The appropriate hook to use is
+% \texttt{babel/\meta{language}/beforeextras} so that users can override it
+% with a traditional
+% \texttt{\textbackslash{}addto\textbackslash{}extras\meta{language}}.
+%
+% Note that, for \pkg{babel}, the captions are currently handled in two
+% different ways -- the ``old way'' and the ``new way'' -- and which of them
+% is used depends on the language.  Most still use the ``old way'', but the
+% problem is that it is not universal.  And the ``new way'' uses a different
+% naming scheme -- \texttt{\textbackslash{}\meta{language}\meta{caption}},
+% which is meant to be set with \cs{setlocalecaption}, and not suitable for
+% our needs.  The \texttt{\textbackslash{}extras\meta{language}} macros are
+% meant for ``arbitrary'' code to be run when the language is selected, which
+% is what we want.  The captions used to work in the same way, but no longer
+% for languages which use the ``new way''.
+%
+% Note also that there seems to exist some qualms about \pkg{babel}'s
+% \cs{addto}.  A number of packages define their own versions of it.  Do so at
+% least \pkg{varioref} (probably the original), \pkg{backref}, and
+% \pkg{cleveref}.  The latter comments that \cs{addto} is ``flawed''.
+% \pkg{babel} itself comments the definition recognizing that there is an
+% ``inconsistency'': depending on the case, the operation will be either local
+% or global.  This is documented in the manual, which explains this
+% inconsistent behavior is preserved for backward compatibility, and
+% recommends \pkg{etoolbox}'s facilities if available.  \pkg{polyglossia} also
+% recommends \pkg{etoolbox}'s \cs{gappto}.  All in all, if there's need to use
+% the traditional way instead of the new hooks, just rely on \texttt{expl3}
+% and use \cs{tl_gput_right:Nn}.
+%
+% \begin{macro}{\@@_set_babel_language:nn}
+%   Sets \meta{babel language} to execute the setup defined by
+%   \cs{@@_define_language:nn} for \meta{postnote language} at the
+%   \texttt{babel/\meta{language}/beforeextras} hook.
+%     \begin{syntax}
+%       \cs{@@_set_babel_language:nn} \Arg{babel language} \Arg{postnote language}
+%     \end{syntax}
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_set_babel_language:nn #1#2
+  {
+    \ActivateGenericHook { babel/#1/beforeextras }
+    \exp_args:Nnv \AddToHook { babel/#1/beforeextras }
+      { g_@@_language_ #2 _tl }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+%
+% \pkg{polyglossia} uses a similar set of macros for setting up languages as
+% \pkg{babel} does.  However, the
+% \texttt{\textbackslash{}blockextras@\meta{language}} macros are
+% unfortunately internal (despite what the manual says, that's what the code
+% does), thus requiring \cs{makeatletter}/\cs{makeatother} for user
+% configuration, which would be an inconvenience.  On the other hand,
+% \pkg{polyglossia}'s \texttt{\textbackslash{}captions\meta{language}} works
+% as in \pkg{babel}'s ``old way'', meaning it is just a ``hook'' to which we
+% can append some code.  So we use
+% \texttt{\textbackslash{}captions\meta{language}} for \pkg{polyglossia}.
+% Things may complicate here if there's need to set up different values for
+% different language variants, since the hooks available are all necessarily
+% internal, but I doubt we'll ever need variants for these simple strings.
+%
+% \begin{macro}{\@@_set_polyglossia_language:nn}
+%   Sets \meta{polyglossia language} to execute the setup defined by
+%   \cs{@@_define_language:nn} for \meta{postnote language} at the
+%   \pkg{polyglossia} \texttt{\textbackslash{}captions\meta{language}} hook.
+%     \begin{syntax}
+%       \cs{@@_set_polyglossia_language:nn} \Arg{polyglossia language}
+%       ~~\Arg{postnote language}
+%     \end{syntax}
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_set_polyglossia_language:nn #1#2
+  {
+    \AddToHook { package/polyglossia/after }
+      {
+        \exp_args:Nnv \csgappto { captions #1 }
+          { g_@@_language_ #2 _tl }
+      }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+%
+% \subsection*{English}
+%
+%    \begin{macrocode}
+\@@_define_language:nn { english }
+  {
+    \tl_set:Nn \pntitle     { Notes }
+    \tl_set:Nn \pnhdnotes   { Notes }
+    \tl_set:Nn \pnhdtopage  { to~page }
+    \tl_set:Nn \pnhdtopages { to~pages }
+  }
+\@@_set_babel_language:nn { english }    { english }
+\@@_set_babel_language:nn { british }    { english }
+\@@_set_babel_language:nn { american }   { english }
+\@@_set_babel_language:nn { canadian }   { english }
+\@@_set_babel_language:nn { australian } { english }
+\@@_set_babel_language:nn { newzealand } { english }
+\@@_set_babel_language:nn { UKenglish }  { english }
+\@@_set_babel_language:nn { USenglish }  { english }
+\@@_set_polyglossia_language:nn { english } { english }
+%    \end{macrocode}
+%
+%
+% \subsection*{Portuguese}
+%
+%    \begin{macrocode}
+\@@_define_language:nn { portuguese }
+  {
+    \tl_set:Nn \pntitle     { Notas }
+    \tl_set:Nn \pnhdnotes   { Notas }
+    \tl_set:Nn \pnhdtopage  { da~página }
+    \tl_set:Nn \pnhdtopages { das~páginas }
+  }
+\@@_set_babel_language:nn { portuguese } { portuguese }
+\@@_set_babel_language:nn { brazilian }  { portuguese }
+\@@_set_babel_language:nn { portuges }   { portuguese }
+\@@_set_babel_language:nn { brazil }     { portuguese }
+\@@_set_polyglossia_language:nn { portuguese } { portuguese }
+%    \end{macrocode}
+%
+%
+%    \begin{macrocode}
+%</package>
+%    \end{macrocode}
+%
+%
+% \PrintIndex
+%
+%


Property changes on: trunk/Master/texmf-dist/source/latex/postnotes/postnotes.dtx
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/source/latex/postnotes/postnotes.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/postnotes/postnotes.ins	                        (rev 0)
+++ trunk/Master/texmf-dist/source/latex/postnotes/postnotes.ins	2022-04-21 20:14:47 UTC (rev 63099)
@@ -0,0 +1,94 @@
+% \iffalse meta-comment
+%
+% File: postnotes.ins
+%
+% This file is part of the LaTeX package "postnotes".
+%
+% Copyright (C) 2022  Gustavo Barros
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version.  The latest version
+% of this license is in the file:
+%
+%    https://www.latex-project.org/lppl.txt
+%
+% and version 1.3 or later is part of all distributions of LaTeX
+% version 2005/12/01 or later.
+%
+%
+% This work is "maintained" (as per LPPL maintenance status) by
+% Gustavo Barros.
+%
+% This work consists of the files postnotes.dtx,
+%                                 postnotes.ins,
+%                                 postnotes.tex,
+%                                 postnotes-code.tex,
+%                   and the files generated from them.
+%
+% The released version of this package is available from CTAN.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the package can be found at
+%
+%    https://github.com/gusbrs/postnotes
+%
+% for those people who are interested.
+%
+% -----------------------------------------------------------------------
+%
+% \fi
+
+\input l3docstrip.tex
+
+\keepsilent
+
+\askforoverwritefalse
+
+\preamble
+
+This file was generated from file(s) of the LaTeX package "postnotes".
+
+Copyright (C) 2022  Gustavo Barros
+
+It may be distributed and/or modified under the conditions of the
+LaTeX Project Public License (LPPL), either version 1.3c of this
+license or (at your option) any later version.  The latest version
+of this license is in the file:
+
+   https://www.latex-project.org/lppl.txt
+
+and version 1.3 or later is part of all distributions of LaTeX
+version 2005/12/01 or later.
+
+
+This work is "maintained" (as per LPPL maintenance status) by
+  Gustavo Barros.
+
+This work consists of the files postnotes.dtx,
+                                postnotes.ins,
+                                postnotes.tex,
+                                postnotes-code.tex,
+                  and the files generated from them.
+
+The released version of this package is available from CTAN.
+
+-----------------------------------------------------------------------
+
+The development version of the package can be found at
+
+   https://github.com/gusbrs/postnotes
+
+for those people who are interested.
+
+-----------------------------------------------------------------------
+
+\endpreamble
+
+\postamble
+\endpostamble
+
+\generate{\file{postnotes.sty}{\from{postnotes.dtx}{package}}}
+
+\endbatchfile

Added: trunk/Master/texmf-dist/tex/latex/postnotes/postnotes.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/postnotes/postnotes.sty	                        (rev 0)
+++ trunk/Master/texmf-dist/tex/latex/postnotes/postnotes.sty	2022-04-21 20:14:47 UTC (rev 63099)
@@ -0,0 +1,1212 @@
+%%
+%% This is file `postnotes.sty',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% postnotes.dtx  (with options: `package')
+%% 
+%% This file was generated from file(s) of the LaTeX package "postnotes".
+%% 
+%% Copyright (C) 2022  Gustavo Barros
+%% 
+%% It may be distributed and/or modified under the conditions of the
+%% LaTeX Project Public License (LPPL), either version 1.3c of this
+%% license or (at your option) any later version.  The latest version
+%% of this license is in the file:
+%% 
+%%    https://www.latex-project.org/lppl.txt
+%% 
+%% and version 1.3 or later is part of all distributions of LaTeX
+%% version 2005/12/01 or later.
+%% 
+%% 
+%% This work is "maintained" (as per LPPL maintenance status) by
+%%   Gustavo Barros.
+%% 
+%% This work consists of the files postnotes.dtx,
+%%                                 postnotes.ins,
+%%                                 postnotes.tex,
+%%                                 postnotes-code.tex,
+%%                   and the files generated from them.
+%% 
+%% The released version of this package is available from CTAN.
+%% 
+%% -----------------------------------------------------------------------
+%% 
+%% The development version of the package can be found at
+%% 
+%%    https://github.com/gusbrs/postnotes
+%% 
+%% for those people who are interested.
+%% 
+%% -----------------------------------------------------------------------
+%% 
+\providecommand\IfFormatAtLeastTF{\@ifl at t@r\fmtversion}
+\IfFormatAtLeastTF{2021-11-15}
+  {}
+  {%
+    \PackageError{postnotes}{LaTeX kernel too old}
+      {%
+        'postnotes' requires a LaTeX kernel 2021-11-15 or newer.%
+        \MessageBreak Loading will abort!%
+      }%
+    \endinput
+  }%
+\ProvidesExplPackage {postnotes} {2022-04-21} {0.1.1}
+  {Endnotes for LaTeX}
+\cs_new:Npn \__postnotes_data_name:n #1
+  { g__postnotes_ #1 _data_prop }
+\cs_generate_variant:Nn \__postnotes_data_name:n { e }
+\NewHook { postnotes/store/note }
+\cs_new_protected:Npn \__postnotes_store:nn #1#2
+  {
+    \prop_new:c { \__postnotes_data_name:e {#1} }
+    \prop_gput:cnn { \__postnotes_data_name:e {#1} } { type } { note }
+    \prop_gput:cnx { \__postnotes_data_name:e {#1} } { mark }
+      { \l__postnotes_mark_tl }
+    \prop_gput:cnx { \__postnotes_data_name:e {#1} } { counter }
+      { \int_use:N \c at postnote }
+    \prop_gput:cnx { \__postnotes_data_name:e {#1} } { sortnum }
+      {
+        \bool_if:NTF \l__postnotes_manual_sortnum_bool
+          { \fp_use:N \l__postnotes_sort_num_fp }
+          { \int_use:N \c at postnote }
+      }
+    \cs_if_exist:cT { chapter }
+      {
+        \prop_gput:cnx { \__postnotes_data_name:e {#1} }
+          { thechapter } { \thechapter }
+      }
+    \prop_gput:cnx { \__postnotes_data_name:e {#1} } { thesection }
+      { \thesection }
+    \prop_gput:cnx { \__postnotes_data_name:e {#1} } { pnsectname }
+      { \g__postnotes_section_name_tl }
+    \prop_gput:cnx { \__postnotes_data_name:e {#1} } { pnsectid }
+      { \int_use:N \g__postnotes_sectid_int }
+    \prop_gput:cnx { \__postnotes_data_name:e {#1} } { multibool }
+      { \bool_to_str:N \l__postnotes_maybe_multi_bool }
+    \prop_gput:cnn { \__postnotes_data_name:e {#1} } { content } {#2}
+    \UseHook { postnotes/store/note }
+  }
+\cs_new_protected:Npn \__postnotes_store_section:nn #1#2
+  {
+    \prop_new:c { \__postnotes_data_name:e {#1} }
+    \prop_gput:cnn { \__postnotes_data_name:e {#1} } { type } { section }
+    \cs_if_exist:cT { chapter }
+      {
+        \prop_gput:cnx { \__postnotes_data_name:e {#1} }
+          { thechapter } { \thechapter }
+      }
+    \prop_gput:cnx { \__postnotes_data_name:e {#1} } { thesection }
+      { \thesection }
+    \prop_gput:cnn { \__postnotes_data_name:e {#1} } { content } {#2}
+  }
+\cs_new_protected:Npn \__postnotes_prop_get:nnN #1#2#3
+  {
+    \prop_get:cnNF { \__postnotes_data_name:e {#1} } {#2} #3
+      { \tl_clear:N #3 }
+  }
+\cs_new:Npn \__postnotes_prop_item:nn #1#2
+  { \prop_item:cn { \__postnotes_data_name:e {#1} } {#2} }
+\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:Npx \post at note #1#2
+  { \exp_not:N \@newl at bel { \c__postnotes_ref_prefix_tl } {#1} {#2} }
+\cs_new_protected:Npn \__postnotes_set_mark_page_label:n #1
+  {
+    \iow_shipout_x:Nn \@auxout
+      { \post at note { mark@ #1 } { \thepage } }
+  }
+\cs_generate_variant:Nn \__postnotes_set_mark_page_label:n { x }
+\cs_new_protected:Npn \__postnotes_set_text_page_label:n #1
+  {
+    \iow_shipout_x:Nn \@auxout
+      { \post at note { text@ #1 } { \int_use:N \c at page } }
+  }
+\cs_generate_variant:Nn \__postnotes_set_text_page_label:n { x }
+\cs_new_protected:Npn \__postnotes_set_print_page_label:n #1
+  {
+    \iow_shipout_x:Nn \@auxout
+      { \post at note { print@ #1 } { \int_use:N \c at page } }
+  }
+\cs_generate_variant:Nn \__postnotes_set_print_page_label:n { x }
+\cs_new_protected:Npn \__postnotes_get_pageref:Nn #1#2
+  {
+    \cs_if_exist:cTF { \c__postnotes_ref_prefix_tl @ #2 }
+      { \tl_set:Nv #1 { \c__postnotes_ref_prefix_tl @ #2 } }
+      { \tl_clear:N #1 }
+  }
+\cs_generate_variant:Nn \__postnotes_get_pageref:Nn { Nx }
+\cs_new:Npn \__postnotes_extract_pageref:n #1
+  {
+    \cs_if_exist:cTF { \c__postnotes_ref_prefix_tl @ #1 }
+      { \exp_not:v { \c__postnotes_ref_prefix_tl @ #1 } }
+      { \c_empty_tl }
+  }
+\cs_generate_variant:Nn \__postnotes_extract_pageref:n { e }
+\keys_define:nn { postnotes/setup }
+  {
+    heading .cs_set_protected:Np = \pnheading ,
+    heading .value_required:n = true ,
+  }
+\cs_if_exist:cTF { chapter }
+  {
+    \cs_new_protected:Npn \pnheading
+      {
+        \chapter*{\pntitle}
+        \@mkboth{\pnheaderdefault}{\pnheaderdefault}
+      }
+  }
+  {
+    \cs_new_protected:Npn \pnheading
+      {
+        \section*{\pntitle}
+        \@mkboth{\pnheaderdefault}{\pnheaderdefault}
+      }
+  }
+\tl_new:N \l__postnotes_print_format_tl
+\keys_define:nn { postnotes/setup }
+  {
+    format .tl_set:N = \l__postnotes_print_format_tl ,
+    format .initial:n = { \small } ,
+    format .value_required:n = true ,
+  }
+\tl_new:N \l__postnotes_print_env_tl
+\bool_new:N \l__postnotes_print_as_list_bool
+\keys_define:nn { postnotes/setup }
+  {
+    listenv .code:n =
+      {
+        \tl_if_eq:nnTF {#1} { none }
+          {
+            \bool_set_false:N \l__postnotes_print_as_list_bool
+            \tl_set:Nn \l__postnotes_post_printnote_tl { \par }
+            \tl_set:Nn \l__postnotes_print_env_tl { itemize }
+          }
+          {
+            \bool_set_true:N \l__postnotes_print_as_list_bool
+            \tl_set:Nn \l__postnotes_print_env_tl {#1}
+          }
+      } ,
+    listenv .initial:n = { postnoteslist } ,
+    listenv .value_required:n = true ,
+  }
+\NewDocumentEnvironment { postnoteslist } { }
+  {
+    \list { }
+      {
+        \setlength { \leftmargin }    { 0pt }
+        \setlength { \labelwidth }    { 0pt }
+        \setlength { \itemindent }    { .5\parindent }
+        \cs_set_eq:NN \makelabel \__postnotes_list_makelabel:n
+        \setlength { \rightmargin }   { 0pt }
+        \setlength { \listparindent } { \parindent }
+        \setlength { \parsep }    { \parskip }
+        \setlength { \itemsep }   { 0pt }
+        \setlength { \topsep }    { .5\topsep }
+        \setlength { \partopsep } { .5\partopsep }
+      }
+  }
+  { \endlist }
+\NewDocumentEnvironment { postnoteslisthang } { }
+  {
+    \list { }
+      {
+        \setlength { \leftmargin }    { 1em }
+        \setlength { \labelwidth }    { -\leftmargin }
+        \setlength { \itemindent }    { -2\leftmargin }
+        \cs_set_eq:NN \makelabel \__postnotes_list_makelabel:n
+        \setlength { \rightmargin }   { 0pt }
+        \setlength { \listparindent } { \parindent }
+        \setlength { \parsep }    { \parskip }
+        \setlength { \itemsep }   { 0pt }
+        \setlength { \topsep }    { .5\topsep }
+        \setlength { \partopsep } { .5\partopsep }
+      }
+  }
+  { \endlist }
+\cs_new:Npn \__postnotes_list_makelabel:n #1
+  { \hspace { \labelsep } \normalfont ~ #1 }
+\keys_define:nn { postnotes/setup }
+  {
+    makemark .cs_set:Np = \__postnotes_make_mark:nnn #1#2#3 ,
+    makemark .value_required:n = true ,
+    makemark .initial:n =
+      { #2 \hbox { \@textsuperscript { \normalfont #1 } } #3 } ,
+    maketextmark .cs_set:Np = \__postnotes_make_text_mark:nnn #1#2#3  ,
+    maketextmark .value_required:n = true ,
+    maketextmark .initial:n = { #2 #1 . #3 } ,
+  }
+\tl_new:N \l__postnotes_pre_textmark_tl
+\tl_new:N \l__postnotes_post_textmark_tl
+\tl_new:N \l__postnotes_post_printnote_tl
+\keys_define:nn { postnotes/setup }
+  {
+    pretextmark .tl_set:N = \l__postnotes_pre_textmark_tl ,
+    pretextmark .value_required:n = true ,
+    posttextmark .tl_set:N = \l__postnotes_post_textmark_tl ,
+    posttextmark .value_required:n = true ,
+    postprintnote .tl_set:N = \l__postnotes_post_printnote_tl ,
+    postprintnote .value_required:n = true ,
+  }
+\bool_new:N \l__postnotes_hyperlink_bool
+\bool_new:N \l__postnotes_hyperref_warn_bool
+\bool_new:N \l__postnotes_backlink_bool
+\keys_define:nn { postnotes/setup }
+  {
+    hyperref .choice: ,
+    hyperref / auto .code:n =
+      {
+        \bool_set_true:N \l__postnotes_hyperlink_bool
+        \bool_set_false:N \l__postnotes_hyperref_warn_bool
+      } ,
+    hyperref / true .code:n =
+      {
+        \bool_set_true:N \l__postnotes_hyperlink_bool
+        \bool_set_true:N \l__postnotes_hyperref_warn_bool
+      } ,
+    hyperref / false .code:n =
+      {
+        \bool_set_false:N \l__postnotes_hyperlink_bool
+        \bool_set_false:N \l__postnotes_hyperref_warn_bool
+      } ,
+    hyperref .initial:n = auto ,
+    hyperref .default:n = true ,
+    backlink .bool_set:N = \l__postnotes_backlink_bool ,
+    backlink .initial:n = true ,
+    backlink .default:n = true ,
+  }
+\AddToHook { begindocument }
+  {
+    \IfPackageLoadedTF { hyperref }
+      { }
+      {
+        \bool_if:NT \l__postnotes_hyperref_warn_bool
+          { \msg_warning:nn { postnotes } { missing-hyperref } }
+        \bool_set_false:N \l__postnotes_hyperlink_bool
+      }
+    \keys_define:nn { postnotes/setup }
+      {
+        hyperref .code:n =
+          {
+            \msg_warning:nnn { postnotes }
+              { option-preamble-only } { hyperref }
+          } ,
+        backlink .code:n =
+          {
+            \msg_warning:nnn { postnotes }
+              { option-preamble-only } { backlink }
+          } ,
+      }
+  }
+\msg_new:nnn { postnotes } { option-preamble-only }
+  { Option~'#1'~only~available~in~the~preamble~\msg_line_context:. }
+\msg_new:nnn { postnotes } { missing-hyperref }
+  { Missing~'hyperref'~package.~Setting~'hyperref=false'. }
+\bool_new:N \l__postnotes_sort_bool
+\keys_define:nn { postnotes/setup }
+  {
+    sort .bool_set:N = \l__postnotes_sort_bool ,
+    sort .initial:n = true ,
+    sort .default: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 }
+          } ,
+        pretextmark = { \par } ,
+        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 = { \par\noindent } ,
+        maketextmark = { { \normalfont ##2 ##1 . ##3 } } ,
+        posttextmark = { ~ } ,
+      } ,
+  }
+\NewDocumentCommand \postnotesetup { m }
+  { \keys_set:nn { postnotes/setup } {#1} }
+\newcounter { postnote }
+\int_new:N \g__postnotes_note_id_int
+\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
+\NewDocumentCommand \postnote { O { } +m }
+  { \__postnotes_note:nn {#1} {#2} }
+\NewHook { postnotes/note/begin }
+\cs_new_protected:Npn \__postnotes_note:nn #1#2
+  {
+    \group_begin:
+    \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:Nx \l__postnotes_mark_tl { \thepostnote }
+          }
+        \seq_gput_right:Nx \g__postnotes_queue_seq
+          { \l__postnotes_note_id_tl }
+        \UseHook { postnotes/note/begin }
+        \cs_set:Npn \@currentcounter { postnote }
+        \cs_set:Npx \@currentlabel { \p at postnote \l__postnotes_mark_tl }
+        \__postnotes_hyperref_make_currentHref:n
+          { postnote. \l__postnotes_note_id_tl .mark }
+        \__postnotes_set_mark_page_label:x { \l__postnotes_note_id_tl }
+        \__postnotes_set_user_labels:
+        \bool_if:NTF \l__postnotes_nomark_bool
+          {
+            \bool_if:NT \l__postnotes_hyperlink_bool
+              {
+                \__postnotes_hyperref_set_anchor:n
+                  { postnote. \l__postnotes_note_id_tl .mark }
+              }
+          }
+          {
+            \__postnotes_typeset_mark:xV
+              { \l__postnotes_note_id_tl } \l__postnotes_mark_tl
+          }
+        \__postnotes_store:nn { \l__postnotes_note_id_tl } {#2}
+      }
+    \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
+\bool_new:N \l__postnotes_manual_sortnum_bool
+\bool_new:N \l__postnotes_maybe_multi_bool
+\keys_define:nn { postnotes/note }
+  {
+    mark .tl_set:N = \l__postnotes_mark_tl ,
+    mark .value_required:n = true ,
+    nomark .bool_set:N = \l__postnotes_nomark_bool ,
+    nomark .default:n = true ,
+    sortnum .code:n =
+      {
+        \fp_set:Nn \l__postnotes_sort_num_fp {#1}
+        \bool_set_true:N \l__postnotes_manual_sortnum_bool
+      } ,
+    sortnum .value_required:n = true ,
+    label .tl_set:N = \l__postnotes_note_label_tl ,
+    label .value_required:n = true ,
+  }
+\bool_new:N \l__postnotes_inhibit_note_bool
+\bool_new:N \l__postnotes_print_plain_mark_bool
+\NewHook { postnotes/note/inhibit }
+\prg_new_protected_conditional:Npnn \__postnotes_inhibit_note: { F }
+  {
+    \bool_set_false:N \l__postnotes_inhibit_note_bool
+    \bool_set_false:N \l__postnotes_print_plain_mark_bool
+    \UseHook { postnotes/note/inhibit }
+    \bool_if:NT \l__postnotes_print_plain_mark_bool
+      {
+        \tl_if_empty:NT \l__postnotes_mark_tl
+          {
+            \group_begin:
+            \int_incr:N \c at postnote
+            \exp_args:NNNx
+              \group_end:
+              \tl_set:Nn \l__postnotes_mark_tl { \thepostnote }
+          }
+        \__postnotes_typeset_mark_wrapper:n
+          { \__postnotes_make_mark:nnn { \l__postnotes_mark_tl } { } { } }
+      }
+    \bool_if:NTF \l__postnotes_inhibit_note_bool
+      { \prg_return_true:  }
+      { \prg_return_false: }
+  }
+\cs_new_protected:Npn \__postnotes_typeset_mark:nn #1#2
+  {
+    \__postnotes_typeset_mark_wrapper:n
+      {
+        \bool_if:NTF \l__postnotes_hyperlink_bool
+          {
+            \__postnotes_hyperref_set_anchor:n { postnote. #1 .mark }
+            \__postnotes_make_mark:nnn {#2}
+              { \hyper at linkstart { link } { postnote. #1 .text } }
+              { \hyper at linkend }
+          }
+          { \__postnotes_make_mark:nnn {#2} { } { } }
+      }
+  }
+\cs_generate_variant:Nn \__postnotes_typeset_mark:nn { xV }
+\tl_new:N \l__postnotes_saved_spacefactor_tl
+\cs_new_protected:Npn \__postnotes_typeset_mark_wrapper:n #1
+  {
+    \mode_leave_vertical:
+    \mode_if_horizontal:T
+      {
+        \tl_set:Nx \l__postnotes_saved_spacefactor_tl { \the\spacefactor }
+        \nobreak
+      }
+    #1
+    \mode_if_horizontal:T
+      { \spacefactor \l__postnotes_saved_spacefactor_tl }
+    \scan_stop:
+  }
+\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 }
+  }
+\NewDocumentCommand \postnoteref { s m }
+  { \__postnotes_note_ref:nn {#1} {#2} }
+\cs_new_protected:Npn \__postnotes_note_ref:nn #1#2
+  {
+    \group_begin:
+    \__postnotes_typeset_mark_wrapper:n
+      {
+        \bool_lazy_and:nnTF
+          { ! #1 }
+          { \l__postnotes_hyperlink_bool }
+          {
+            \hyperref [#2]
+              { \__postnotes_make_mark:nnn { \ref*{#2} } { } { } }
+          }
+          { \__postnotes_make_mark:nnn { \__postnotes_ref_star:n {#2} } { } { } }
+      }
+    \group_end:
+  }
+\NewDocumentCommand \postnotesection { O { } +m }
+  { \__postnotes_section:nn {#1} {#2} }
+\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:Nx \g__postnotes_queue_seq { \l__postnotes_note_id_tl }
+    \tl_gclear:N \g__postnotes_section_name_tl
+    \keys_set:nn { postnotes/section } {#1}
+    \__postnotes_store_section:nn { \l__postnotes_note_id_tl } {#2}
+    \group_end:
+  }
+\tl_new:N \g__postnotes_section_name_tl
+\keys_define:nn { postnotes/section }
+  {
+    name .tl_gset:N = \g__postnotes_section_name_tl ,
+    name .value_required:n = true ,
+  }
+\NewDocumentCommand \printpostnotes { }
+  { \__postnotes_print_notes: }
+\tl_new:N \pnthechapter
+\tl_new:N \pnthesection
+\tl_new:N \pnthechapternextnote
+\tl_new:N \pnthesectionnextnote
+\tl_new:N \pnthepage
+\int_new:N \g__postnotes_print_postnotes_int
+\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_type_curr_tl
+\tl_new:N \l__postnotes_print_type_next_tl
+\tl_new:N \l__postnotes_print_type_prev_tl
+\tl_new:N \l__postnotes_print_content_tl
+\seq_new:N \l__postnotes_clear_queue_seq
+\NewHook { postnotes/print/begin }
+\NewHook { postnotes/print/eachnote }
+\newcounter { postnotetext }
+\newcounter { postnotesection }
+\setcounter { postnotesection } { 10000 }
+\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
+                    \__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
+                    \__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'
+                \tl_if_eq:NnF \l__postnotes_print_type_prev_tl { note }
+                  {
+                    \bool_if:NTF \l__postnotes_print_as_list_bool
+                      { \exp_args:Nx \begin { \l__postnotes_print_env_tl } }
+                      { \group_begin: }
+                    \l__postnotes_print_format_tl
+                  }
+                \group_begin:
+                \UseHook { postnotes/print/eachnote }
+                \__postnotes_get_pageref:Nx \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
+                  { \int_eval:n { \l__postnotes_print_counter_tl } }
+                \cs_set:Npx \@currentlabel
+                  { \p at postnote \l__postnotes_print_mark_tl }
+                \__postnotes_hyperref_make_currentHref:n
+                  { postnote. \l__postnotes_print_note_id_tl .text }
+                \__postnotes_text_mark_wrapper:n
+                  {
+                    \__postnotes_set_text_page_label:x
+                      { \l__postnotes_print_note_id_tl }
+                    \__postnotes_typeset_text_mark:eV
+                      { \l__postnotes_print_note_id_tl }
+                      \l__postnotes_print_mark_tl
+                  }
+                \l__postnotes_print_content_tl
+                \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 }
+                  {
+                    \bool_if:NTF \l__postnotes_print_as_list_bool
+                      { \exp_args:Nx \end { \l__postnotes_print_env_tl } }
+                      { \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 }
+  { Empty~'\iow_char:N\\printpostnotes'~\msg_line_context:. }
+\cs_new_protected:Npn \__postnotes_typeset_text_mark:nn #1#2
+  {
+    \bool_if:NTF \l__postnotes_hyperlink_bool
+      {
+        \__postnotes_hyperref_set_anchor:n { postnote. #1 .text }
+        \bool_if:NTF \l__postnotes_backlink_bool
+          {
+            \__postnotes_make_text_mark:nnn {#2}
+              { \hyper at linkstart { link } { postnote. #1 .mark } }
+              { \hyper at linkend }
+          }
+          { \__postnotes_make_text_mark:nnn {#2} { } { } }
+      }
+      { \__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
+  {
+    \bool_if:NTF \l__postnotes_print_as_list_bool
+      {
+        \item
+          [ \l__postnotes_pre_textmark_tl #1 \l__postnotes_post_textmark_tl ]
+      }
+      { \l__postnotes_pre_textmark_tl #1 \l__postnotes_post_textmark_tl }
+  }
+\cs_new_protected:Npn \__postnotes_verify_multipass:N #1
+  {
+    \group_begin:
+    \seq_clear:N \l_tmpa_seq
+    \seq_map_inline:Nn #1
+      {
+        \__postnotes_prop_get:nnN {##1} { multibool } \l_tmpa_tl
+        \tl_if_eq:NnTF \l_tmpa_tl { true }
+          {
+            \cs_if_exist:cT
+              { \c__postnotes_ref_prefix_tl @ mark@ ##1 }
+              { \seq_put_right:Nn \l_tmpa_seq {##1} }
+          }
+          { \seq_put_right:Nn \l_tmpa_seq {##1} }
+      }
+    \seq_gset_eq:NN #1 \l_tmpa_seq
+    \group_end:
+  }
+\cs_new_protected:Npn \__postnotes_sort_queue:N #1
+  {
+    \group_begin:
+    \seq_gsort:Nn #1
+      {
+        \__postnotes_prop_get:nnN {##1} { pnsectid } \l_tmpa_tl
+        \__postnotes_prop_get:nnN {##2} { pnsectid } \l_tmpb_tl
+        \tl_if_eq:NNTF \l_tmpa_tl \l_tmpb_tl
+          {
+            \__postnotes_prop_get:nnN {##1} { type } \l_tmpa_tl
+            \__postnotes_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 } }
+              {
+                \__postnotes_prop_get:nnN {##1} { sortnum } \l_tmpa_tl
+                \__postnotes_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:
+  }
+\tl_new:N \pnhdpagefirst
+\tl_new:N \pnhdpagelast
+\tl_new:N \pnhdchapfirst
+\tl_new:N \pnhdchaplast
+\tl_new:N \pnhdsectfirst
+\tl_new:N \pnhdsectlast
+\tl_new:N \pnhdnamefirst
+\tl_new:N \pnhdnamelast
+\prop_new:N \g__postnotes_header_page_first_prop
+\prop_new:N \g__postnotes_header_page_last_prop
+\prop_new:N \g__postnotes_header_chap_first_prop
+\prop_new:N \g__postnotes_header_chap_last_prop
+\prop_new:N \g__postnotes_header_sect_first_prop
+\prop_new:N \g__postnotes_header_sect_last_prop
+\prop_new:N \g__postnotes_header_name_first_prop
+\prop_new:N \g__postnotes_header_name_last_prop
+\tl_new:N \g__postnotes_header_prev_last_page_tl
+\tl_new:N \g__postnotes_header_prev_last_chap_tl
+\tl_new:N \g__postnotes_header_prev_last_sect_tl
+\tl_new:N \g__postnotes_header_prev_last_name_tl
+\tl_new:N \l__postnotes_prev_text_page_tl
+\tl_new:N \l__postnotes_curr_text_page_tl
+\tl_new:N \l__postnotes_prev_mark_page_tl
+\tl_new:N \l__postnotes_prev_mark_chap_tl
+\tl_new:N \l__postnotes_prev_mark_sect_tl
+\tl_new:N \l__postnotes_prev_mark_name_tl
+\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:Nx \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:Nxx \g__postnotes_header_page_last_prop
+                          { \l__postnotes_prev_text_page_tl }
+                          { \l__postnotes_prev_mark_page_tl }
+                        \prop_gput:Nxx \g__postnotes_header_chap_last_prop
+                          { \l__postnotes_prev_text_page_tl }
+                          { \l__postnotes_prev_mark_chap_tl }
+                        \prop_gput:Nxx \g__postnotes_header_sect_last_prop
+                          { \l__postnotes_prev_text_page_tl }
+                          { \l__postnotes_prev_mark_sect_tl }
+                        \prop_gput:Nxx \g__postnotes_header_name_last_prop
+                          { \l__postnotes_prev_text_page_tl }
+                          { \l__postnotes_prev_mark_name_tl }
+                      }
+                    \prop_gput:Nxx \g__postnotes_header_page_first_prop
+                      { \l__postnotes_curr_text_page_tl }
+                      { \__postnotes_extract_pageref:n { mark@ ##1 } }
+                    \prop_gput:Nxx \g__postnotes_header_chap_first_prop
+                      { \l__postnotes_curr_text_page_tl }
+                      { \__postnotes_prop_item:nn {##1} { thechapter } }
+                    \prop_gput:Nxx \g__postnotes_header_sect_first_prop
+                      { \l__postnotes_curr_text_page_tl }
+                      { \__postnotes_prop_item:nn {##1} { thesection } }
+                    \prop_gput:Nxx \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:Nxx \g__postnotes_header_page_last_prop
+          { \l__postnotes_prev_text_page_tl }
+          { \l__postnotes_prev_mark_page_tl }
+        \prop_gput:Nxx \g__postnotes_header_chap_last_prop
+          { \l__postnotes_prev_text_page_tl }
+          { \l__postnotes_prev_mark_chap_tl }
+        \prop_gput:Nxx \g__postnotes_header_sect_last_prop
+          { \l__postnotes_prev_text_page_tl }
+          { \l__postnotes_prev_mark_sect_tl }
+        \prop_gput:Nxx \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_tmpa_tl
+      { \tl_gset:NV \pnhdpagefirst \l_tmpa_tl }
+      { \tl_gset:NV \pnhdpagefirst \g__postnotes_header_prev_last_page_tl }
+    \prop_get:NnNTF \g__postnotes_header_page_last_prop
+      {#1} \l_tmpa_tl
+      {
+        \tl_gset:NV \pnhdpagelast \l_tmpa_tl
+        \tl_gset:NV \g__postnotes_header_prev_last_page_tl \l_tmpa_tl
+      }
+      { \tl_gset:NV \pnhdpagelast \g__postnotes_header_prev_last_page_tl }
+    \prop_get:NnNTF \g__postnotes_header_chap_first_prop
+      {#1} \l_tmpa_tl
+      { \tl_gset:NV \pnhdchapfirst \l_tmpa_tl }
+      { \tl_gset:NV \pnhdchapfirst \g__postnotes_header_prev_last_chap_tl }
+    \prop_get:NnNTF \g__postnotes_header_chap_last_prop
+      {#1} \l_tmpa_tl
+      {
+        \tl_gset:NV \pnhdchaplast \l_tmpa_tl
+        \tl_gset:NV \g__postnotes_header_prev_last_chap_tl \l_tmpa_tl
+      }
+      { \tl_gset:NV \pnhdchaplast \g__postnotes_header_prev_last_chap_tl }
+    \prop_get:NnNTF \g__postnotes_header_sect_first_prop
+      {#1} \l_tmpa_tl
+      { \tl_gset:NV \pnhdsectfirst \l_tmpa_tl }
+      { \tl_gset:NV \pnhdsectfirst \g__postnotes_header_prev_last_sect_tl }
+    \prop_get:NnNTF \g__postnotes_header_sect_last_prop
+      {#1} \l_tmpa_tl
+      {
+        \tl_gset:NV \pnhdsectlast \l_tmpa_tl
+        \tl_gset:NV \g__postnotes_header_prev_last_sect_tl \l_tmpa_tl
+      }
+      { \tl_gset:NV \pnhdsectlast \g__postnotes_header_prev_last_sect_tl }
+    \prop_get:NnNTF \g__postnotes_header_name_first_prop
+      {#1} \l_tmpa_tl
+      { \tl_gset:NV \pnhdnamefirst \l_tmpa_tl }
+      { \tl_gset:NV \pnhdnamefirst \g__postnotes_header_prev_last_name_tl }
+    \prop_get:NnNTF \g__postnotes_header_name_last_prop
+      {#1} \l_tmpa_tl
+      {
+        \tl_gset:NV \pnhdnamelast \l_tmpa_tl
+        \tl_gset:NV \g__postnotes_header_prev_last_name_tl \l_tmpa_tl
+      }
+      { \tl_gset:NV \pnhdnamelast \g__postnotes_header_prev_last_name_tl }
+    \group_end:
+  }
+\cs_generate_variant:Nn \__postnotes_set_headers_vars:n { x }
+\AddToHook { shipout/before } [ postnotes/header ]
+  { \__postnotes_set_headers_vars_next: }
+\bool_new:N \g__postnotes_header_vars_next_bool
+\cs_new_protected:Npn \__postnotes_set_headers_vars_next:
+  {
+    \bool_if:NT \g__postnotes_header_vars_next_bool
+      { \__postnotes_set_headers_vars:x { \int_eval:n { \c at page + 1 } } }
+  }
+\cs_new_protected:Npn \__postnotes_set_headers_vars_first:
+  {
+    \__postnotes_set_print_page_label:x
+      { \int_use:N \g__postnotes_print_postnotes_int }
+    \__postnotes_set_headers_vars:x
+      {
+        \__postnotes_extract_pageref:e
+          { print@ \int_use:N \g__postnotes_print_postnotes_int }
+      }
+  }
+\NewDocumentCommand \pnheaderdefault {}
+  {
+    \tl_if_eq:NNTF \pnhdpagefirst \pnhdpagelast
+      { \pnhdnotes{} ~ \pnhdtopage{} ~ \pnhdpagefirst }
+      { \pnhdnotes{} ~ \pnhdtopages{} ~ \pnhdpagefirst -- \pnhdpagelast }
+  }
+\AddToHook { postnotes/note/begin } [ postnotes ]
+  {
+    \cs_if_exist:NT \@captype
+      { \bool_set_true:N \l__postnotes_maybe_multi_bool }
+  }
+\bool_new:N \g__postnotes_hyperref_loaded_bool
+\AddToHook { package/hyperref/after }
+  { \bool_gset_true:N \g__postnotes_hyperref_loaded_bool }
+\cs_new_protected:Npn \__postnotes_hyperref_make_currentHref:n #1
+  {
+    \bool_if:NT \g__postnotes_hyperref_loaded_bool
+      { \Hy at MakeCurrentHref {#1} }
+  }
+\cs_new_protected:Npn \__postnotes_hyperref_set_anchor:n #1
+  {
+    \bool_if:NT \g__postnotes_hyperref_loaded_bool
+      { \Hy at raisedlink { \hyper at anchor {#1} } }
+  }
+\cs_new_protected:Npn \__postnotes_ref_star:n #1
+  {
+    \bool_if:NTF \g__postnotes_hyperref_loaded_bool
+      { \ref*{#1} }
+      { \ref{#1} }
+  }
+\AddToHook { package/biblatex/after }
+  {
+    \AddToHook { postnotes/store/note } [ postnotes ]
+      {
+        \prop_gput:cnx { \__postnotes_data_name:e { \l__postnotes_note_id_tl } }
+          { biblatex at refsection } { \int_use:N \c at refsection }
+        \prop_gput:cnx { \__postnotes_data_name:e { \l__postnotes_note_id_tl } }
+          { biblatex at refsegment } { \int_use:N \c at refsegment }
+        \prop_gput:cnx { \__postnotes_data_name:e { \l__postnotes_note_id_tl } }
+          { biblatex at refcontextbool }
+          { \iftoggle { blx at refcontext } { true } { false } }
+        \prop_gput:cnV { \__postnotes_data_name:e { \l__postnotes_note_id_tl } }
+          { biblatex at refcontext } \blx at refcontext@context
+      }
+    \AddToHook { postnotes/print/begin } [ postnotes ]
+      {
+        \__postnotes_biblatex_endrefcontext_local:
+        \__postnotes_biblatex_citereset_local:
+        \toggletrue { blx at footnote }
+      }
+    \tl_new:N \l__postnotes_biblatex_restore_tl
+    \AddToHook { postnotes/print/eachnote } [ postnotes ]
+      {
+        \__postnotes_prop_get:nnN { \l__postnotes_print_note_id_tl }
+          { biblatex at refsection } \l__postnotes_biblatex_restore_tl
+        \int_set:Nn \c at refsection { \l__postnotes_biblatex_restore_tl }
+        \__postnotes_prop_get:nnN { \l__postnotes_print_note_id_tl }
+          { biblatex at refsegment } \l__postnotes_biblatex_restore_tl
+        \int_set:Nn \c at refsegment { \l__postnotes_biblatex_restore_tl }
+        \__postnotes_prop_get:nnN { \l__postnotes_print_note_id_tl }
+          { biblatex at refcontextbool } \l__postnotes_biblatex_restore_tl
+        \use:c { toggle \l__postnotes_biblatex_restore_tl } { blx at refcontext }
+        \__postnotes_prop_get:nnN { \l__postnotes_print_note_id_tl }
+          { biblatex at refcontext } \l__postnotes_biblatex_restore_tl
+        \blx at edef@refcontext { \l__postnotes_biblatex_restore_tl }
+      }
+    \AddToHook { begindocument/before } [ postnotes/mkbibendnote ]
+      {
+        \cs_set_nopar:Npn \blx at theendnote { \postnote }
+        \cs_set_nopar:Npn \blx at theendnotetext
+          { \blx at err@endnote \footnotetext }
+      }
+    \cs_new_protected:Npn \__postnotes_biblatex_endrefcontext_local:
+      {
+        \togglefalse { blx at refcontext }
+        \tl_clear:N \blx at refcontext@labelprefix
+        \tl_clear:N \blx at refcontext@labelprefix at real
+        \tl_set:Nx \blx at refcontext@sortingtemplatename { \blx at sorting }
+        \tl_set:Nn \blx at refcontext@sortingnamekeytemplatename { global }
+        \tl_set:Nn \blx at refcontext@uniquenametemplatename { global }
+        \tl_set:Nn \blx at refcontext@labelalphanametemplatename { global }
+        \blx at edef@refcontext
+          {
+            \blx at refcontext@sortingtemplatename /
+            \blx at refcontext@sortingnamekeytemplatename /
+            /
+            \blx at refcontext@uniquenametemplatename /
+            \blx at refcontext@labelalphanametemplatename
+          }
+      }
+    \cs_new_protected:Npn \__postnotes_biblatex_citereset_local:
+      {
+        \tl_clear:c { blx at bsee@ \int_use:N \c at refsection }
+        \tl_clear:c { blx at fsee@ \int_use:N \c at refsection }
+        \undef \blx at lastkey@text
+        \undef \blx at lastkey@foot
+        \undef \blx at lasthash@text
+        \undef \blx at lasthash@foot
+        \clist_map_inline:Nn \blx at trackhash@text
+          { \csundef { blx at lastkey@text@ ##1 } }
+        \tl_clear:N \blx at trackhash@text
+        \clist_map_inline:Nn \blx at trackhash@foot
+          { \csundef { blx at lastkey@foot@ ##1 } }
+        \tl_clear:N \blx at trackhash@foot
+        \clist_map_inline:Nn \blx at trackkeys@text
+          { \csundef { blx at lastnote@text@ ##1 } }
+        \tl_clear:N \blx at trackkeys@text
+        \clist_map_inline:Nn \blx at trackkeys@foot
+          { \csundef { blx at lastnote@foot@ ##1 } }
+        \tl_clear:N \blx at trackkeys@foot
+        \cs_set_eq:NN \blx at lastmpfn \z@
+      }
+  }
+\tl_new:N \l__postnotes_note_zlabel_tl
+\AddToHook { package/zref-user/after }
+  {
+    \keys_define:nn { postnotes/note }
+      {
+        zlabel .tl_set:N = \l__postnotes_note_zlabel_tl ,
+        zlabel .value_required:n = true ,
+      }
+    \NewDocumentCommand \postnotezref { s m }
+      { \__postnotes_note_zref:nn {#1} {#2} }
+    \cs_new_protected:Npn \__postnotes_note_zref:nn #1#2
+      {
+        \group_begin:
+        \__postnotes_typeset_mark_wrapper:n
+          {
+            \bool_lazy_and:nnTF
+              { ! #1 }
+              { \l__postnotes_hyperlink_bool }
+              {
+                \hyperlink
+                  { \zref at extractdefault {#2} { anchor } { } }
+                  { \__postnotes_make_mark:nnn { \zref{#2} } { } { } }
+              }
+              { \__postnotes_make_mark:nnn { \zref{#2} } { } { } }
+          }
+        \group_end:
+      }
+  }
+\AddToHook { package/zref-clever/after }
+  {
+    \zcsetup
+      {
+        countertype = { postnote = endnote } ,
+        countertype = { postnotetext = endnote } ,
+      }
+    \AddToHook { postnotes/print/begin } [ postnotes ]
+      { \zcsetup { counterresetby = { postnotetext = postnotesection } } }
+  }
+\AddToHook { package/amsmath/after }
+  {
+    \AddToHook { postnotes/note/inhibit } [ postnotes ]
+      {
+        \legacy_if:nT { measuring@ }
+          {
+            \bool_set_true:N \l__postnotes_inhibit_note_bool
+            \bool_set_true:N \l__postnotes_print_plain_mark_bool
+          }
+      }
+    \AddToHook { postnotes/note/begin } [ postnotes ]
+      {
+        \legacy_if:nF { firstchoice@ }
+          { \bool_set_true:N \l__postnotes_maybe_multi_bool }
+      }
+  }
+\AddToHook { package/csquotes/after }
+  {
+    \bool_new:N \l__postnotes_csquotes_measuring_bool
+    \BlockquoteDisable
+      { \bool_set_true:N \l__postnotes_csquotes_measuring_bool }
+    \AddToHook { postnotes/note/inhibit } [ postnotes ]
+      {
+        \bool_if:NT \l__postnotes_csquotes_measuring_bool
+          {
+            \bool_set_true:N \l__postnotes_inhibit_note_bool
+            \bool_set_true:N \l__postnotes_print_plain_mark_bool
+          }
+      }
+  }
+\AddToHook { package/tabularx/after }
+  {
+    \bool_new:N \l__postnotes_tabularx_inside_env_bool
+    \AddToHook { env/tabularx/begin } [ postnotes ]
+      {
+        \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 ]
+      {
+        \bool_lazy_and:nnT
+          { \l__postnotes_tabularx_inside_env_bool }
+          { ! \cs_if_eq_p:NN \write \__postnotes_tabularx_saved_write:Nn }
+          {
+            \bool_set_true:N \l__postnotes_inhibit_note_bool
+            \bool_set_true:N \l__postnotes_print_plain_mark_bool
+          }
+      }
+  }
+\AddToHook { package/tabularray/after }
+  {
+    \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 }
+      }
+  }
+\tl_new:N \pntitle
+\tl_new:N \pnhdnotes
+\tl_new:N \pnhdtopage
+\tl_new:N \pnhdtopages
+\tl_set:Nn \pntitle { Notes }
+\tl_set:Nn \pnhdnotes { Notes }
+\tl_set:Nn \pnhdtopage { to~page }
+\tl_set:Nn \pnhdtopages { to~pages }
+\cs_new_protected:Npn \__postnotes_define_language:nn #1#2
+  {
+    \tl_new:c { g__postnotes_language_ #1 _tl }
+    \tl_gset:cn { g__postnotes_language_ #1 _tl } {#2}
+  }
+\cs_new_protected:Npn \__postnotes_set_babel_language:nn #1#2
+  {
+    \ActivateGenericHook { babel/#1/beforeextras }
+    \exp_args:Nnv \AddToHook { babel/#1/beforeextras }
+      { g__postnotes_language_ #2 _tl }
+  }
+\cs_new_protected:Npn \__postnotes_set_polyglossia_language:nn #1#2
+  {
+    \AddToHook { package/polyglossia/after }
+      {
+        \exp_args:Nnv \csgappto { captions #1 }
+          { g__postnotes_language_ #2 _tl }
+      }
+  }
+\__postnotes_define_language:nn { english }
+  {
+    \tl_set:Nn \pntitle     { Notes }
+    \tl_set:Nn \pnhdnotes   { Notes }
+    \tl_set:Nn \pnhdtopage  { to~page }
+    \tl_set:Nn \pnhdtopages { to~pages }
+  }
+\__postnotes_set_babel_language:nn { english }    { english }
+\__postnotes_set_babel_language:nn { british }    { english }
+\__postnotes_set_babel_language:nn { american }   { english }
+\__postnotes_set_babel_language:nn { canadian }   { english }
+\__postnotes_set_babel_language:nn { australian } { english }
+\__postnotes_set_babel_language:nn { newzealand } { english }
+\__postnotes_set_babel_language:nn { UKenglish }  { english }
+\__postnotes_set_babel_language:nn { USenglish }  { english }
+\__postnotes_set_polyglossia_language:nn { english } { english }
+\__postnotes_define_language:nn { portuguese }
+  {
+    \tl_set:Nn \pntitle     { Notas }
+    \tl_set:Nn \pnhdnotes   { Notas }
+    \tl_set:Nn \pnhdtopage  { da~página }
+    \tl_set:Nn \pnhdtopages { das~páginas }
+  }
+\__postnotes_set_babel_language:nn { portuguese } { portuguese }
+\__postnotes_set_babel_language:nn { brazilian }  { portuguese }
+\__postnotes_set_babel_language:nn { portuges }   { portuguese }
+\__postnotes_set_babel_language:nn { brazil }     { portuguese }
+\__postnotes_set_polyglossia_language:nn { portuguese } { portuguese }
+%% 
+%%
+%% End of file `postnotes.sty'.


Property changes on: trunk/Master/texmf-dist/tex/latex/postnotes/postnotes.sty
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Modified: trunk/Master/tlpkg/bin/tlpkg-ctan-check
===================================================================
--- trunk/Master/tlpkg/bin/tlpkg-ctan-check	2022-04-21 20:13:21 UTC (rev 63098)
+++ trunk/Master/tlpkg/bin/tlpkg-ctan-check	2022-04-21 20:14:47 UTC (rev 63099)
@@ -632,7 +632,7 @@
     pmboxdraw pmgraph pmhanguljamo pmx pmxchords pnas2009
     poemscol poetry poetrytex poiretone polexpr polski poltawski
     polyglossia polynom polynomial
-    polytable poormanlog postage postcards poster-mac
+    polytable poormanlog postage postcards poster-mac postnotes
     powerdot powerdot-fuberlin powerdot-tuliplab
     ppr-prv pracjourn practicalreports
     prelim2e preprint prerex present

Modified: trunk/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc
===================================================================
--- trunk/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc	2022-04-21 20:13:21 UTC (rev 63098)
+++ trunk/Master/tlpkg/tlpsrc/collection-latexextra.tlpsrc	2022-04-21 20:14:47 UTC (rev 63099)
@@ -1025,6 +1025,7 @@
 depend polynomial
 depend polytable
 depend postcards
+depend postnotes
 depend poster-mac
 depend powerdot
 depend ppr-prv

Added: trunk/Master/tlpkg/tlpsrc/postnotes.tlpsrc
===================================================================


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