% \iffalse meta-comment % % File: postnotes.tex % % This file is part of the LaTeX package "postnotes". % % Copyright (C) 2022-2023 gusbrs % % 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 gusbrs. % % This work consists of the files postnotes.dtx, % postnotes.ins, % postnotes-doc.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} \usepackage{zref-titleref} \usepackage{zref-check} \usepackage{listings} \lstdefinestyle{code}{ language=[LaTeX]TeX, alsoletter = {_:}, moretexcs={ \chapter , \@mkboth , \@textsuperscript , \thechapter , \AddToHook , \AddToHookNext , \counterwithin , \tableofcontents , \ExplSyntaxOn , \ExplSyntaxOff , \NewDocumentCommand , \RenewDocumentCommand , \NewCommandCopy , \IfBooleanTF , \IfNoValueTF , \tl_if_eq:NNTF , \tl_new:N , \tl_gset:Nv , \prop_new:N , \prop_gput:NeV , \prop_item:NV , \bool_case: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 , \pnidnextnote , \pnhdpagefirst , \pnhdpagelast , \pnhdchapfirst , \pnhdchaplast , \pnhdsectfirst , \pnhdsectlast , \pnhdnamefirst , \pnhdnamelast , \mypnheader , \demochapter , \origlatexchapter , \l_postnotes_note_id_tl , \g_my_currentname_tl , \g_my_names_prop , } } \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}% \zcsetup{countertype={lstlisting=example}}% \lstset{#1}% \stepcounter{pnexample}% \setcounter{lstlisting}{\value{pnexample}}% }{} \lstnewenvironment{pnsnippet}[1][]{% \renewcommand{\lstlistingname}{Example}% \lstset{#1}% }{} \setlength{\marginparsep}{2\labelsep} \NewDocumentCommand\opt{m}{\texttt{#1}} \NewDocumentCommand\username{m}{`\texttt{#1}'} \begin{document} \GetFileInfo{postnotes.sty} \title{% The \pkg{postnotes} package% \texorpdfstring{\\{}\medskip{}}{ - }% User manual% \texorpdfstring{\medskip{}}{}% } \author{% \texorpdfstring{\texttt{gusbrs}\\[0.8em] \url{https://github.com/gusbrs/postnotes}\\ \url{https://www.ctan.org/pkg/postnotes}}{gusbrs}} \date{Version \fileversion\ -- \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{postnote}s 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, and if \pkg{zref-hyperref} is also loaded, it is hyperlinked as its counterpart. \section{Options} \zlabel{sec:options} \subsection*{Package options} \zlabel{sec:package-options} \begin{function}{\postnotesetup} \begin{syntax} \cs{postnotesetup}\marg{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} % \DescribeMacro{\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} % \DescribeMacro{\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's mark to its 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} % \DescribeOption{markstr} % 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} and \opt{markstr} options allow you to manually set it, in case you want, or need, to do so. When either \opt{mark} or \opt{markstr} is manually set, the \texttt{postnote} counter is not stepped. The difference between them is that \opt{mark} must receive a number as value, and uses its value to also set the \opt{sortnum} option, while \opt{markstr}, differently from the optional argument of \cs{footnote}, can receive a string as value which is directly used as the mark, but it does not set \opt{sortnum}. \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@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}[markstr=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}. \DescribeOption{exp} % By default, \cs{postnotesection} stores its \meta{text} argument with ``no manipulation''. The \opt{exp} option allows one to fully expand (\texttt{e}-type expansion) \meta{text} in place before storing it. It is a boolean option, and the option given with no value is equivalent to \texttt{exp=true}. \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''. \DescribeMacro{\pnthechapter} % \DescribeMacro{\pnthesection} % \DescribeMacro{\pnthechapternextnote} % \DescribeMacro{\pnthesectionnextnote} % \DescribeMacro{\pnidnextnote} % 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 (you can use \cs{postnotesection}\texttt{[exp]} instead, in which case these variables are of little use). 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''. \cs{pnidnextnote}, in turn, stores the Id number of 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?\footnote{The example here counts on the lucky circumstance of having only a single initial unnumbered section. But, in general, if that's not the case, \cs{counterwithin*} is insufficient and the resetting of the \texttt{postnote} counter at unnumbered sections must be handled somehow else.} \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} If one wants to use section names/titles, the technique above (of using something similar to \cs{pnthechapternextnote}) is less useful, since if the first note in the section occurs within a subsection we would lose the information of interest. So we have a little more work to do in this case. \zcref{ex:sect:names} uses the \texttt{cmd/chapter/before} hook to store the value of \cs{@currentlabelname} in a dedicated variable after the next call to \cs{NR@gettitle} (presuming the use of \pkg{nameref}, through \pkg{hyperref}). We then store the value of this variable for each note using the \texttt{postnotes/note/store} hook and the note's Id number \cs{l_postnotes_note_id_tl}. Finally we can retrieve this stored value using \cs{pnidnextnote} inside \cs{postnotesection}. Indeed, this example is also meant to illustrate the general technique for storing/restoring variables of interest for this purpose. \begin{pnexample}[caption={Section names},label={ex:sect:names}] \documentclass{book} \usepackage{postnotes} \ExplSyntaxOn \tl_new:N \g_my_currentname_tl \prop_new:N \g_my_names_prop \AddToHook{cmd/chapter/before}{ \AddToHookNext{cmd/NR@gettitle/after}{ \tl_gset:Nv \g_my_currentname_tl { @currentlabelname } } } \AddToHook{postnotes/note/store}{ \prop_gput:NeV \g_my_names_prop { \l_postnotes_note_id_tl } \g_my_currentname_tl } \AddToHook{cmd/chapter/before}{ \postnotesection{ \section*{Notes~to~\prop_item:NV \g_my_names_prop \pnidnextnote}}} \ExplSyntaxOff \counterwithin*{postnote}{chapter} \usepackage{hyperref} \begin{document} \chapter*{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} While \pkg{postnotes} goes through great lengths to avoid tampering with sectioning commands, the fact that in general we cannot use \texttt{cmd} hooks after \cs{chapter} or \cs{section} does complicate things. And \zcref{ex:sect:names} is indeed a good illustration of how a supposedly simple task can become quite convoluted if we are not allowed to observe the variables of interest \emph{after} the sectioning commands. However, things are quite different from the perspective of a user, considering the problem at the document level. In this case, the definition of the sectioning commands is known, and unique, so that it may make sense to use of the traditional technique of storing the definition of the sectioning command, and then redefining it to do what it used to, plus something else.\footnote{\username{egreg} commonly applies the technique for the same purpose in answers using \pkg{endnotes} at TeX.SX. For example: \url{https://tex.stackexchange.com/a/62425}, \url{https://tex.stackexchange.com/a/109566}, and \url{https://tex.stackexchange.com/a/85001}. But things are somewhat simpler with \pkg{postnotes}, since there's no need to handle the case of sections with no notes, given that empty \cs{postnotesection}s are already skipped.} In which case, we can set \cs{postnotesection}s with full generality and flexibility. \begin{pnexample}[caption={Redefining sections},label={ex:sect:redefined}] \documentclass{book} \usepackage{postnotes} \counterwithin*{postnote}{chapter} \NewCommandCopy\origlatexchapter\chapter \RenewDocumentCommand{\chapter}{som}{% \IfBooleanTF{#1}{% \origlatexchapter*{#3}% \setcounter{postnote}{0}% \postnotesection{\section*{Notes to ``#3''}}% }{% \IfNoValueTF{#2}{% \origlatexchapter{#3}% }{% \origlatexchapter[#2]{#3}% }% \postnotesection{\section*{Notes to chapter \pnthechapter}}% }% } \usepackage{hyperref} \begin{document} \chapter*{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} Things could easily get fancier, of course. But that's the basic structure. \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} \DescribeMacro{\pnhdpagefirst} % \DescribeMacro{\pnhdpagelast} % \DescribeMacro{\pnhdchapfirst} % \DescribeMacro{\pnhdchaplast} % \DescribeMacro{\pnhdsectfirst} % \DescribeMacro{\pnhdsectlast} % \DescribeMacro{\pnhdnamefirst} % \DescribeMacro{\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{pnhdsectlast} 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: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} \DescribeMacro{\pntitle} % \DescribeMacro{\pnhdnotes} % \DescribeMacro{\pnhdtopage} % \DescribeMacro{\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, German, French, and Portuguese. 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]{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 % 2023-02-10: https://chat.stackexchange.com/transcript/message/62955941#62955941 (and discussion) % 2023-02-19: https://tex.stackexchange.com/q/675818#comment1678904_675818 % 2023-12-12: https://chat.stackexchange.com/transcript/message/64848034#64848034 (and discussion) David Carlisle, % 2022-03-28: https://chat.stackexchange.com/transcript/message/60754383#60754383 % 2022-04-08: https://tex.stackexchange.com/a/640035 (comments) % 2023-02-10: https://chat.stackexchange.com/transcript/message/62955941#62955941 (and discussion) % 2023-02-10: https://tex.stackexchange.com/a/674846 % 2023-12-12: https://chat.stackexchange.com/transcript/message/64848034#64848034 (and discussion) Moritz Wemheuer, % 2022-04-05: https://tex.stackexchange.com/q/597359#comment1594585_597389 Joseph Wright, % 2023-02-10: https://chat.stackexchange.com/transcript/message/62955941#62955941 (and discussion) % 2023-12-12: https://chat.stackexchange.com/transcript/message/64848034#64848034 (and discussion) \username{SwitWu}, % 2023-11-29: https://github.com/gusbrs/postnotes/pull/4 % 2023-11-30: https://github.com/gusbrs/postnotes/pull/5 and Jonathan P. Spratte (\username{Skillmon}). % 2023-12-12: https://chat.stackexchange.com/transcript/message/64848034#64848034 (and discussion) The package's language support have been provided or improved thanks to: \username{Pika78} (French) % 2022-04-25: https://github.com/gusbrs/postnotes/issues/1#issuecomment-1108634938 and Herbert Voß (German). % 2022-11-12: https://github.com/gusbrs/postnotes/issues/2 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}