texlive[74070] branches/branch2024.final/Master: marginalia (branch)
commits+karl at tug.org
commits+karl at tug.org
Mon Feb 17 21:48:11 CET 2025
Revision: 74070
https://tug.org/svn/texlive?view=revision&revision=74070
Author: karl
Date: 2025-02-17 21:48:10 +0100 (Mon, 17 Feb 2025)
Log Message:
-----------
marginalia (branch) (17feb25)
Modified Paths:
--------------
branches/branch2024.final/Master/tlpkg/tlpsrc/collection-luatex.tlpsrc
Added Paths:
-----------
branches/branch2024.final/Master/texmf-dist/doc/lualatex/marginalia/
branches/branch2024.final/Master/texmf-dist/doc/lualatex/marginalia/README.md
branches/branch2024.final/Master/texmf-dist/doc/lualatex/marginalia/marginalia-doc-example.tex
branches/branch2024.final/Master/texmf-dist/doc/lualatex/marginalia/marginalia-doc-ysep-explanation.pdf
branches/branch2024.final/Master/texmf-dist/doc/lualatex/marginalia/marginalia-doc.pdf
branches/branch2024.final/Master/texmf-dist/source/lualatex/marginalia/
branches/branch2024.final/Master/texmf-dist/source/lualatex/marginalia/marginalia.dtx
branches/branch2024.final/Master/texmf-dist/source/lualatex/marginalia/marginalia.ins
branches/branch2024.final/Master/texmf-dist/tex/lualatex/marginalia/
branches/branch2024.final/Master/texmf-dist/tex/lualatex/marginalia/marginalia.lua
branches/branch2024.final/Master/texmf-dist/tex/lualatex/marginalia/marginalia.sty
branches/branch2024.final/Master/tlpkg/tlpsrc/marginalia.tlpsrc
Added: branches/branch2024.final/Master/texmf-dist/doc/lualatex/marginalia/README.md
===================================================================
--- branches/branch2024.final/Master/texmf-dist/doc/lualatex/marginalia/README.md (rev 0)
+++ branches/branch2024.final/Master/texmf-dist/doc/lualatex/marginalia/README.md 2025-02-17 20:48:10 UTC (rev 74070)
@@ -0,0 +1,16 @@
+# `marginalia` - Non-floating marginal content with automatic placement for LuaLaTeX
+
+## Description
+
+This LuaLaTeX package allows the placement of marginal content anywhere, without `\marginpar`'s limits, and
+automatically adjusts positions to prevent overlaps or content being pushed off the page. In short, it tries to combine
+the best features from the packages `marginnote`, `marginfix` and `marginfit` with key--value settings that allow
+fine-grained customization.
+
+## Author
+
+This package is by Alan J. Cain: a.j.cain (AT) gmail.com
+
+## Licence
+
+Released under the LaTeX Project Public License v1.3c or later: https://www.latex-project.org/lppl.txt
Property changes on: branches/branch2024.final/Master/texmf-dist/doc/lualatex/marginalia/README.md
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: branches/branch2024.final/Master/texmf-dist/doc/lualatex/marginalia/marginalia-doc-example.tex
===================================================================
--- branches/branch2024.final/Master/texmf-dist/doc/lualatex/marginalia/marginalia-doc-example.tex (rev 0)
+++ branches/branch2024.final/Master/texmf-dist/doc/lualatex/marginalia/marginalia-doc-example.tex 2025-02-17 20:48:10 UTC (rev 74070)
@@ -0,0 +1,17 @@
+\documentclass[11pt]{article}
+
+\usepackage{marginalia}
+
+\begin{document}
+
+Here is some body text.\marginalia{Here is a marginal note.} Some more
+body text.\marginalia[style=\footnotesize\itshape\raggedright]{Here is another
+ marginal note, set in smaller text and italics, whose position has been been
+ adjusted automatically.}
+
+Some final body text.\marginalia[pos=left, valign=b, style=\sffamily\raggedleft,
+width=35mm]{This note is placed on the left side of the page, wider, in sans
+ serif, ragged left, and bottom-aligned.}
+
+\end{document}
+LUACODE
Property changes on: branches/branch2024.final/Master/texmf-dist/doc/lualatex/marginalia/marginalia-doc-example.tex
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: branches/branch2024.final/Master/texmf-dist/doc/lualatex/marginalia/marginalia-doc-ysep-explanation.pdf
===================================================================
(Binary files differ)
Index: branches/branch2024.final/Master/texmf-dist/doc/lualatex/marginalia/marginalia-doc-ysep-explanation.pdf
===================================================================
--- branches/branch2024.final/Master/texmf-dist/doc/lualatex/marginalia/marginalia-doc-ysep-explanation.pdf 2025-02-17 20:47:38 UTC (rev 74069)
+++ branches/branch2024.final/Master/texmf-dist/doc/lualatex/marginalia/marginalia-doc-ysep-explanation.pdf 2025-02-17 20:48:10 UTC (rev 74070)
Property changes on: branches/branch2024.final/Master/texmf-dist/doc/lualatex/marginalia/marginalia-doc-ysep-explanation.pdf
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/pdf
\ No newline at end of property
Added: branches/branch2024.final/Master/texmf-dist/doc/lualatex/marginalia/marginalia-doc.pdf
===================================================================
(Binary files differ)
Index: branches/branch2024.final/Master/texmf-dist/doc/lualatex/marginalia/marginalia-doc.pdf
===================================================================
--- branches/branch2024.final/Master/texmf-dist/doc/lualatex/marginalia/marginalia-doc.pdf 2025-02-17 20:47:38 UTC (rev 74069)
+++ branches/branch2024.final/Master/texmf-dist/doc/lualatex/marginalia/marginalia-doc.pdf 2025-02-17 20:48:10 UTC (rev 74070)
Property changes on: branches/branch2024.final/Master/texmf-dist/doc/lualatex/marginalia/marginalia-doc.pdf
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/pdf
\ No newline at end of property
Added: branches/branch2024.final/Master/texmf-dist/source/lualatex/marginalia/marginalia.dtx
===================================================================
--- branches/branch2024.final/Master/texmf-dist/source/lualatex/marginalia/marginalia.dtx (rev 0)
+++ branches/branch2024.final/Master/texmf-dist/source/lualatex/marginalia/marginalia.dtx 2025-02-17 20:48:10 UTC (rev 74070)
@@ -0,0 +1,1931 @@
+% \iffalse meta-comment
+%
+% Copyright (C) 2025 Alan J. Cain
+%
+% This file may be distributed and/or modified under the conditions of the LaTeX Project Public License, either version
+% 1.3c of this license or (at your option) any later version. The latest version of this license is in:
+%
+% http://www.latex-project.org/lppl.txt
+%
+% and version 1.3c or later is part of all distributions of LaTeX version 2008-05-04 or later.
+%
+% \fi
+%
+% \iffalse
+%<*driver>
+\PassOptionsToPackage{inline}{enumitem}
+\documentclass{l3doc}
+
+
+\makeatletter
+\ExplSyntaxOn
+
+\cs_gset:Npn \l at subsection { \@dottedtocline{2}{2.5em}{2.8em} } % #2 = 1.5em
+\cs_gset:Npn \l at subsubsection { \@dottedtocline{3}{5.3em}{3.5em} } % #2 = 1.5em
+\cs_gset:Npn \l at paragraph { \@dottedtocline{4}{8.8em}{3.2em} } % #2 = 1.5em
+
+\ExplSyntaxOff
+\makeatother
+
+
+\usepackage{xcolor}
+
+\definecolor{linkcolor}{rgb}{0.0,0.4,0.7}
+\colorlet{citecolor}{linkcolor}
+\colorlet{urlcolor}{linkcolor}
+
+\hypersetup{
+ linkcolor=linkcolor,%
+ citecolor=citecolor,%
+ urlcolor=urlcolor,%
+}
+
+
+\newcommand*\fullref[2]{%
+ \hyperref[#2]{#1\penalty 200\ \ref*{#2}}%
+}
+
+
+\setcounter{tocdepth}{7}
+\numberwithin{figure}{section}
+
+
+
+\usepackage{marginalia}
+
+
+\marginaliasetup{
+ ysep=0pt,
+ ysep page top=10mm,
+ ysep page bottom=5mm,
+}
+\renewcommand*\marginpar[1]{\marginalia[pos=left]{#1}}
+
+
+\usepackage{titleps}
+
+\newpagestyle{sideheadings}[\normalfont]{
+ \sethead{%
+ \smash{%
+ \marginalia[
+ pos=left,
+ valign=b,
+ yshift={-\topskip-2\baselineskip},
+ type=optfixed,
+ xsep=2em,
+ ysep={2\baselineskip},
+ column=one,
+ width=40mm,
+ ]{%
+ \raggedleft
+ \itshape
+ \large
+ \sectiontitle
+ }%
+ }%
+ }
+ {}
+ {}
+ \setfoot{}
+ {\thepage}
+ {}
+}
+
+
+
+
+
+\usepackage{booktabs}
+\usepackage{graphicx}
+
+
+\newlist{vallist}{description}{1}
+\setlist[vallist]{
+ leftmargin=3em,
+ style=unboxed,
+ labelsep=1em,
+ font=\descriptionitemcolon,
+ nosep,
+}
+
+\newcommand*{\descriptionitemcolon}[1]{\kern 1em #1:}
+
+
+\usepackage{siunitx}
+\sisetup{
+ mode=match,
+}
+\DeclareSIUnit\inch{in}
+\DeclareSIUnit\point{pt}
+
+
+\usepackage{tikz}
+\usetikzlibrary{decorations.pathmorphing}
+
+
+\newrobustcmd*\examplelabel[1]{%
+ \smash{%
+ \begin{tikzpicture}[baseline=(labelnode.base)]
+ \node[node font=\sffamily\footnotesize] (labelnode) at (0,0) {#1};
+ \draw[gray] (labelnode.center) circle (5pt);
+ \end{tikzpicture}%
+ }%
+}
+
+
+\usepackage{mathtools}
+
+\DeclarePairedDelimiter{\abs}{\lvert}{\rvert}
+\DeclarePairedDelimiter{\set}{\lbrace}{\rbrace}
+
+
+\newcommand*\key[1]{\texttt{#1}}
+\newcommand*\val[1]{\texttt{#1}}
+\newcommand*\keyvalue[2]{\texttt{#1=#2}}
+
+\NewDocumentCommand{\default}{ m }{(\textit{Default:} #1)}
+
+
+\newcommand*\luafunc[1]{\texttt{#1}}
+\newcommand*\luavar[1]{\texttt{#1}}
+
+
+\usepackage{listings}
+
+\lstset{
+ language=[LaTeX]TeX,
+ basicstyle=\small\ttfamily,
+ basewidth=0.5em,
+}
+
+
+
+\newcounter{sidenote}
+\newcommand*\sidenote[1]{%
+ \stepcounter{sidenote}%
+ \textsuperscript{\thesidenote}%
+ \marginalia[
+ pos=left,
+ style={\raggedright\footnotesize},
+ width=33mm,
+ xsep=1em,
+ ]{%
+ \leavevmode\strut\llap{\thesidenote~}#1\strut%
+ }%
+}
+
+
+
+\begin{document}
+
+\DocInput{\jobname.dtx}
+
+\PrintIndex
+
+\end{document}
+%</driver>
+% \fi
+%
+%
+%
+% \GetFileInfo{marginalia.sty}
+%
+%
+%
+% \title{^^A
+% \pkg{marginalia} ^^A
+% --- Non-floating marginal content with automatic placement for Lua\LaTeX^^A
+% \thanks{This file describes \fileversion, last revised \filedate.}^^A
+% }
+%
+% \author{^^A
+% Alan J. Cain^^A
+% }
+%
+% \date{Released \filedate}
+%
+% \maketitle
+%
+%
+%
+% \begin{abstract}
+% This Lua\LaTeX\ package allows the placement of marginal content anywhere, without \cs{marginpar}'s limits, and
+% automatically adjusts positions to prevent overlaps or content being pushed off the page. In short, it tries to
+% combine the best features from the packages \pkg{marginnote}, \pkg{marginfix} and \pkg{marginfit} with key--value
+% settings that allow fine-grained customization.
+% \end{abstract}
+%
+%
+%
+% \tableofcontents
+%
+%
+%
+% \begin{documentation}
+%
+%
+%
+% \section{Introduction}
+% \pagestyle{sideheadings}
+%
+% The \LaTeX\ \cs{marginpar} command is the basic method for placing content in the margin. For purposes such as drawing
+% attention to particular points in the text, it functions well. Its main limitation is that \cs{marginpar} works via
+% the \LaTeX\ float mechanism and so cannot be used to create marginal content next to a figure, table, or other float,
+% or next to a footnote, or to place running heads in the margin, such as are found in the left-hand margin of this
+% document except for the `implementation' section. (Bringhurst called this style `running shoulder\-heads'
+% \cite[p.~65]{bringhurst_elements}, but the term may be non-standard.)
+%
+% Trying to set many separate pieces of marginal content using \cs{marginpar} can lead to other problems. If two
+% \texttt{marginpar}s would clash, \LaTeX\ shifts the second item downward. But the cumulative effect can lead to
+% \texttt{marginpar}s being shifted downward off the bottom of the page. Further, the asynchronous nature of \TeX's
+% page-breaking can cause:
+% \begin{enumerate*}[label={(\arabic*)}]
+% \item a \texttt{marginpar} to be placed in the wrong margin;
+% \item the topmost \texttt{marginpar} on a page to be unnecessarily shifted downward because of a hypothetical clash
+% that would have occured with the previous \texttt{marginpar}, had they been on the same page.
+% \end{enumerate*}
+%
+% Packages like \pkg{mparhack}\sidenote{\textsc{url:} \url{https://ctan.org/pkg/mparhack}} (Tom Sgouros \& Stefan
+% Ulrich), \pkg{marginnote}\sidenote{\textsc{url}: \url{https://ctan.org/pkg/marginnote}} (Markus Kohm),
+% \pkg{marginfix}\sidenote{\textsc{url:} \url{https://ctan.org/pkg/marginfix}} (Stephen Hicks) and
+% \pkg{marginfit}\sidenote{\textsc{url:} \url{https://ctan.org/pkg/marginfit}} (Maurice Leclaire) were created to avoid
+% these limitations and problems. \pkg{mparhack} only ensures that each \texttt{marginpar} appears on the correct side
+% of the page. \pkg{marginnote} allows marginal content to be placed anywhere, but does not adjust positions to avoid
+% clashes. \pkg{marginfix} adjusts positions, but the unadjusted vertical positioning can be slightly off, and the
+% package still uses floats. \pkg{marginfit} gets positions exactly right, but uses the insert mechanism and so marginal
+% content cannot appear next to floats or footnotes.
+%
+% This Lua\LaTeX\ package, \pkg{marginalia}, provides a \cs{marginalia} command that attempts to avoid these
+% limitations. Marginal content is placed, not via floats or inserts, but by a calculated per-item horizontal shift
+% inside an (invisible) \cs{rlap} or \cs{llap} from the position where the \cs{marginalia} command was issued (which is
+% similar to the technique used by \pkg{marginnote}), plus a calculated per-item vertical shift to avoid clashes with
+% other content. The vertical shift is usually downward, but may be upward when necessary to prevent content from being
+% shifted off the bottom of the page (which is similar to the vertical shifts performed by \pkg{marginfix} and
+% \pkg{marginfit}).
+%
+% The calculation of the horizontal and vertical shifts uses information written to the \file{.aux} file during the
+% previous Lua\LaTeX\ run. It thus takes at least two runs for all content to appear in the correct places. The package
+% reports any changes from the previous run and any problems encountered.
+%
+% \bigskip
+%
+% \noindent\emph{Caveat:} \pkg{marginalia} was written to typeset running heads in the margin, sidenote references,
+% side-captions for floats, and small marginal figures in the author's book \textit{Form \& Number: A History of
+% Mathematical Beauty} \cite{cain_formandnumber_ebook_large}.\sidenote{\textit{Form \& Number} is freely available on
+% the Internet Archive under a Creative Commons licence.
+% \textsc{url}:~\url{https://archive.org/details/cain_formandnumber_ebook_large}} Thus the basic functionality has been
+% tested extensively, and it has performed correctly.
+%
+%
+%
+% \paragraph*{Licence.} \noindent\pkg{marginalia} is released under the \LaTeX\ Project Public Licence v1.3c or
+% later.\footnote{\textsc{url}: \url{https://www.latex-project.org/lppl.txt}}
+%
+%
+%
+% \section{Requirements}
+%
+% \pkg{marginalia} requires
+% \begin{enumerate*}[label={(\arabic*)}]
+% \item Lua\LaTeX,
+% \item a recent \LaTeX\ kernel with \pkg{expl3} support (any kernel version since 2020-02-02 should suffice).
+% \end{enumerate*}
+% It does not depend on any other packages.
+%
+%
+%
+% \section{Installation}
+%
+% To install \pkg{marginalia} manually, run \texttt{luatex marginalia.ins} and copy \texttt{marginalia.sty} and
+% \texttt{marginalia.lua} to somewhere Lua\LaTeX\ can find them.
+%
+%
+%
+% \section{Getting started}
+%
+% \pkg{marginalia} works `out of the box'. Load the package (there are no package options) and use the main
+% \cs{marginalia} command to place marginal content. \fullref{Figure}{fig:getting-started} shows the source code for a
+% small demonstration and the resulting document. \emph{The source code must be processed \textsl{twice} by Lua\LaTeX\
+% for the marginal content to be placed correctly.} (See \fullref{Section}{sec:usage} for discussion of the need for
+% multiple runs.)
+%
+% \begin{figure}[t]
+% \lstinputlisting{marginalia-doc-example.tex}
+% \begin{tikzpicture}
+% \pgfmathsetmacro{\s}{(\textwidth+.4pt)/210mm}
+% \pgfmathsetlengthmacro{\w}{\s*210mm}
+% \pgfmathsetlengthmacro{\h}{\s*100mm}
+% \path[save path=\outline] (0,0) -| ++(\w,-\h) -| cycle;
+% \begin{scope}
+% \clip[use path=\outline];
+% \node[anchor=north west,inner sep=0] at (0,0) {\includegraphics[scale=\s]{marginalia-doc-example.pdf}};
+% \end{scope}
+% \draw[gray,use path=\outline];
+% \end{tikzpicture}
+%
+% \caption{A small demonstration of \pkg{marginalia}.}
+% \label{fig:getting-started}
+% \end{figure}
+%
+% Turn to \fullref{Section}{sec:commands} for a detailed description of the available user commands, and
+% \fullref{Section}{sec:options} for the various options (such as \keyvalue{style}{\meta{code}}) than can be used to
+% change the placement and formatting of the marginal content.
+%
+%
+%
+% \section{User commands}
+% \label{sec:commands}
+%
+% \begin{function}{\marginalia}
+% \begin{syntax}
+% \cs{marginalia}\oarg{options}\marg{content}
+% \end{syntax}
+% This is the basic command for placing marginal content. The \meta{content} can, roughly speaking, be anything: text,
+% mathematics, included graphics, Ti\textit{k}Z. The optional argument \meta{options} is a key--value list that
+% specifies how the content is typeset. The keys are described in \fullref{Subsection}{sec:options}.
+% \end{function}
+%
+%
+%
+% \begin{function}{\marginaliasetup}
+% \begin{syntax}
+% \cs{marginaliasetup}\marg{options}
+% \end{syntax}
+% This command is used to set options globally. The argument \meta{options} is the same kind of key--value list as the
+% \meta{options} argument for the \cs{marginalia} command, and are described in \fullref{Subsection}{sec:options}.
+% \end{function}
+%
+%
+%
+% \begin{function}{\marginalianewgeometry}
+% \begin{syntax}
+% \cs{marginalianewgeometry}
+% \end{syntax}
+% This command signals to \pkg{marginalia} that the page layout has been changed, for instance by using the
+% \cs{newgeometry} command from the \pkg{geometry} package,\sidenote{\textsc{url}:
+% \url{https://ctan.org/pkg/geometry}} or by using the \LaTeX\ command \cs{twocolumn} to switch to two-column mode. It
+% should be issued immediately after such a change, and certainly before the first page with the new layout has been
+% shipped out. There is no harm in using it unnecessarily.
+% \end{function}
+%
+%
+%
+% \subsection{Access to page and column}
+%
+% Two counters available within the \meta{content} of \cs{marginalia} specify the actual page and column in which the
+% call to \cs{marginalia} appears. These counters can be used to select different actions depending on the page on which
+% the content appears or (in two-column mode) whether it pertains to the left or right column. It is best to use the
+% variants of the \key{style} and \key{width} keys if marginal content should have different widths or styles depending
+% on whether they appear on a recto/verso page or pertain to a particular column. These counters are made available for
+% purposes not covered by the \key{style} and \key{width} variants.
+%
+% \begin{variable}{\marginaliapage}
+% A counter register, available within the \meta{content} of \cs{marginalia}, that holds the actual page on which the
+% marginal content appears. The value is based on the previous Lua\LaTeX\ run and will default to \(1\).
+% \end{variable}
+%
+% \begin{variable}{\marginaliacolumn}
+% A counter register, available within the \meta{content} of \cs{marginalia}, that holds the actual column to which
+% the marginal content pertains. The value is \(1\) for the left column, \(2\) for the right column. In one-column
+% mode, the value is always \(0\). (If the key \key{column} is used to manually specify the column to which the
+% content pertains, the value of \cs{marginaliacolumn} will change accordingly.) The value is based on the previous
+% Lua\LaTeX\ run and will default to \(0\).
+% \end{variable}
+%
+%
+%
+% \section{Options}
+% \label{sec:options}
+%
+% The description of keys in this section, which are summarized in \fullref{Table}{tbl:keys-summary}, should be read in
+% conjunction with the discussion of how marginal content is placed in \fullref{Section}{sec:placement}. In particular,
+% the variants of the keys \key{width} and \key{style} follow the terminology shown in
+% \fullref{Figure}{fig:terminology}.
+%
+% \begin{table}[p]
+% \centering
+% \caption{Summary of keys that can be set using \cs{marginaliasetup} or passed in the optional argument to
+% \cs{marginalia}.}
+% \label{tbl:keys-summary}
+% \begin{tabular}{lll}
+% \toprule
+% Key name & Value & Default \\
+% \midrule
+% \key{type} & \(\set{\val{normal},\val{fixed},\val{optfixed}}\) & \val{normal} \\
+% \midrule
+% \key{pos} & \parbox[t]{40mm}{\raggedright\hangindent=2em\(\set{\val{auto},\val{reverse},\val{left},\allowbreak
+% \val{right},\val{nearest}}\)\strut} & \val{auto} \\
+% \key{column} & \(\set{\val{auto},\val{one},\val{left},\val{right}}\) & \val{auto} \\
+% \key{xsep} & Dimension & \val{\cs{marginparwidth}} \\
+% \key{xsep outer} & Dimension & \val{\cs{marginparwidth}} \\
+% \key{xsep inner} & Dimension & \val{\cs{marginparwidth}} \\
+% \key{xsep between} & Dimension & \val{\cs{marginparwidth}} \\
+% \key{xsep recto outer} & Dimension & \val{\cs{marginparwidth}} \\
+% \key{xsep recto inner} & Dimension & \val{\cs{marginparwidth}} \\
+% \key{xsep verso outer} & Dimension & \val{\cs{marginparwidth}} \\
+% \key{xsep verso inner} & Dimension & \val{\cs{marginparwidth}} \\
+% \key{xsep right between} & Dimension & \val{\cs{marginparwidth}} \\
+% \key{xsep left between} & Dimension & \val{\cs{marginparwidth}} \\
+% \midrule
+% \key{valign} & \(\set{\val{t},\val{b}}\) & \val{t} \\
+% \key{yshift} & Dimension & \qty{0}{\point} \\
+% \key{ysep} & Dimension & \val{\cs{marginparpush}} \\
+% \key{ysep above} & Dimension & \val{\cs{marginparpush}} \\
+% \key{ysep below} & Dimension & \val{\cs{marginparpush}} \\
+% \key{ysep page top} & Dimension & \val{\cs{marginparpush}} \\
+% \key{ysep page top} & Dimension & \val{\cs{marginparpush}} \\
+% \midrule
+% \key{width} & Dimension & \val{\cs{marginparwidth}} \\
+% \key{width outer} & Dimension & \val{\cs{marginparwidth}} \\
+% \key{width inner} & Dimension & \val{\cs{marginparwidth}} \\
+% \key{width between} & Dimension & \val{\cs{marginparwidth}} \\
+% \key{width recto outer} & Dimension & \val{\cs{marginparwidth}} \\
+% \key{width recto inner} & Dimension & \val{\cs{marginparwidth}} \\
+% \key{width verso outer} & Dimension & \val{\cs{marginparwidth}} \\
+% \key{width verso inner} & Dimension & \val{\cs{marginparwidth}} \\
+% \key{width right between} & Dimension & \val{\cs{marginparwidth}} \\
+% \key{width left between} & Dimension & \val{\cs{marginparwidth}} \\
+% \key{style} & \LaTeX\ code & [Empty] \\
+% \key{style recto outer} & \LaTeX\ code & [Empty] \\
+% \key{style recto inner} & \LaTeX\ code & [Empty] \\
+% \key{style verso outer} & \LaTeX\ code & [Empty] \\
+% \key{style verso inner} & \LaTeX\ code & [Empty] \\
+% \key{style right between} & \LaTeX\ code & [Empty] \\
+% \key{style left between} & \LaTeX\ code & [Empty] \\
+% \bottomrule
+% \end{tabular}
+% \end{table}
+%
+%
+%
+% \subsection{Type}
+%
+% \DescribeOption{type} The \key{type} of an item of marginal content can be set to one of the following three values:
+% \begin{vallist}
+% \item[\val{normal}] The vertical position of the item will be changed automatically if necessary to prevent a clash
+% with another item of content.
+% \item[\val{fixed}] The vertical position of the item will \emph{never} be changed automatically from the position
+% specified by \key{yshift}, even if there is a clash with another item. (The type \val{fixed} was designed for
+% setting float captions in the margin, since a caption should not move away from the float with which it is
+% associated.)
+% \item[\val{optfixed}] The vertical position of the item will \emph{never} be changed automatically from the position
+% specified by \key{yshift}, even if there is a clash with another item. But an \val{optfixed} item will not appear in
+% the document if it would clash with a \val{fixed} item. (The type \val{optfixed} was designed for setting running
+% heads in the margin, which should not appear if they would clash with a figure caption set in the margin.)
+% \end{vallist}
+% \default{\val{normal}}
+%
+%
+%
+% \subsection{Horizontal placement}
+%
+% \DescribeOption{pos} The position in which an item of marginal content should be placed. It can be set to one of the
+% the following four values:
+% \begin{vallist}
+% \item[\val{auto}] Place the item in the default position as described in \fullref{Section}{sec:placement}: the outer
+% margin in single-column mode, and on the opposite side from the other column in two-column mode.
+% \item[\val{reverse}] Place the item on the opposite side of the text block (in one-column mode) or column (in
+% two-column mode) from \val{auto}.
+% \item[\val{left}] The left side of the text block or column.
+% \item[\val{right}] The right side of the text block of column.
+% \item[\val{nearest}] The side of the text block or column nearest to which \cs{marginalia} was called.
+% \end{vallist}%
+% \default{\val{auto}}
+%
+%
+% \medskip\goodbreak
+%
+%
+% \DescribeOption{column} In two-column mode, \pkg{marginalia} tries to determine to which column an item of marginal
+% content pertains using the position of the call to \cs{marginalia}. If the call is to the left of the mid-point
+% between the columns, the item is assumed to pertain to the left column; otherwise, it is assumed to pertain to the
+% right column. In certain situations, this might lead to undesired placement of the item. In particular, any call to
+% \cs{marginalia} in a full-width float in two-column mode would be handled as if it were a call from one of the columns
+% and might thus be set in the wrong place. Similarly, an overfull hbox or a piece of \cs{rlap}-ped text might carry a
+% call to \cs{marginalia} from the left column text into the area of the page occupied by the right column.
+%
+% The key \key{column} can be used to specify which column \pkg{marginalia} should place the item in. It can be set to
+% one of four values:
+% \begin{vallist}
+% \item[\val{auto}] Automatically determine which column an item of marginal content is placed in.
+% \item[\val{one}] Treat the item as being called from one-column mode.
+% \item[\val{left}] Treat the item as pertaining to the left column.
+% \item[\val{right}] Treat the item as pertaining to the right column.
+% \end{vallist}
+% The value of \key{column} has no effect in one-column mode. \default{\val{auto}}
+%
+%
+% \medskip\goodbreak
+%
+%
+% \DescribeOption{xsep}
+% \DescribeOption{xsep outer}
+% \DescribeOption{xsep inner}
+% \DescribeOption{xsep between}
+% \DescribeOption{xsep recto outer}
+% \DescribeOption{xsep recto inner}
+% \DescribeOption{xsep verso outer}
+% \DescribeOption{xsep verso inner}
+% \DescribeOption{xsep right between}
+% \DescribeOption{xsep left between}
+% These keys specify the horizontal separation between an item of marginal content and the text block next
+% to which it is placed. Which separation is used will depend on where the item is typeset. The terminology is as
+% in \fullref{Figure}{fig:terminology}.
+% \begin{vallist}
+% \item[\key{xsep recto outer}] used for an item in the outer margin of a recto page.
+% \item[\key{xsep recto inner}] used for an item in the inner margin of a recto page.
+% \item[\key{xsep verso outer}] used for an item in the outer margin of a verso page.
+% \item[\key{xsep verso inner}] used for an item in the inner margin of a verso page.
+% \item[\key{xsep right between}] used for an item set from the right column between the columns.
+% \item[\key{xsep left between}] used for an item set from the left column between the columns.
+% \item[\key{xsep outer}] a shorthand for setting the keys \key{xsep recto outer} and \key{xsep verso outer}
+% simultaneously to the same value.
+% \item[\key{xsep inner}] a shorthand for setting the keys \key{xsep recto inner} and \key{xsep verso inner}
+% simultaneously to the same value.
+% \item[\key{xsep between}] a shorthand for setting the keys \key{xsep right between} and \key{xsep left between}
+% simultaneously to the same value.
+% \item[\key{xsep}] a shorthand for setting all of these keys simultaneously.
+% \end{vallist}
+% (The shorthands \key{xsep outer} and \key{xsep inner} exist because page geometry is usually symmetrical between recto
+% and verso pages as regards outer and inner margins. The shorthand \key{xsep between} exists because the space between
+% columns, if used at all for marginal content, will often be shared equally.) Each of these keys must be set to a valid
+% dimension. \default{value of \cs{marginparsep} when the package is loaded}
+%
+%
+%
+% \subsection{Vertical placement}
+%
+% \DescribeOption{valign} The option \key{valign} can be either \val{t} or \val{b}. In the former case, the baseline of
+% the marginal content item is the baseline of the topmost box in its contents; in the latter case, its baseline is the
+% baseline of the bottommost box in its contents. (Essentially, \cs{vtop} and \cs{vbox} are used to set the two options)
+% \default{\val{t}}
+%
+%
+% \medskip\goodbreak
+%
+%
+% \DescribeOption{yshift}
+% The key \key{yshift} is used to shift the default position of the marginal content item up (positive) or
+% down (negative) from its normal position, which is to have its baseline aligned with the baseline of the callout
+% position. It must be set to a valid dimension. Note that if \keyvalue{type}{normal}, then the vertical
+% position may be adjusted from that specified by \key{yshift}. If this is not desired, specify a different \key{type}.
+% \default{0pt}.
+%
+%
+% \medskip\goodbreak
+%
+%
+% \DescribeOption{ysep}
+% \DescribeOption{ysep above}
+% \DescribeOption{ysep below}
+% \DescribeOption{ysep page top}
+% \DescribeOption{ysep page bottom}
+% These keys specify the minimum vertical separation above and below an item of marginal content
+% \begin{vallist}
+% \item[\key{ysep above}] the minimum vertical separation between an item and the one above.
+% \item[\key{ysep below}] the minimum vertical separation between an item and the one below.
+% \item[\key{ysep page top}] the minimum vertical separation between an item and top of the page.
+% \item[\key{ysep page bottom}] the minimum vertical separation between an item and bottom of the page.
+% \item[\key{ysep}] is a shorthand for setting all of these keys simultaneously to the same value.
+% \end{vallist}
+% (See \fullref{Figure}{fig:ysep-explanation}.) Each of these keys must be set to a valid dimension. \default{value of
+% \cs{marginparpush} when the package is loaded}.
+%
+% \begin{figure}[t]
+% \centering
+% \includegraphics{marginalia-doc-ysep-explanation.pdf}
+% \caption{(Illustration of \key{ysep}) The length \examplelabel{1} is at least the value of \key{ysep below}
+% specified (locally or globally) for marginal content item \examplelabel{A} and at least the value of \key{ysep
+% above} specified for item \examplelabel{B}. In this example diagram, \examplelabel{B} has been automatically moved
+% down from its natural position to maintain the required distance. Similarly, the length \examplelabel{2} is at least
+% the value of \key{ysep below} specified for \examplelabel{C} and at least the value of \key{ysep above} specified
+% for \examplelabel{D}, and the length \examplelabel{3} is at least the value of \key{ysep page bottom} specified for
+% \examplelabel{D}. In this example, to maintain the required distances, \examplelabel{C} and \examplelabel{D} have
+% been automatically moved (respectively) up and down from their natural positions.}
+% \label{fig:ysep-explanation}
+% \end{figure}
+%
+%
+%
+% \subsection{Appearance}
+%
+% An item of marginal content that appears in the inner margin might be narrower than one that appears in the outer
+% margin, and an item appearing in the outer margin of a recto page might be set ragged right, while an item appearing
+% in the outer margin of a verso page might be set ragged left. And since it is not known where an item will appear
+% until the page is assembled, the keys in this subsection, dealing with the width and style of an item, have variants
+% that apply depending on where the item appears on the page.
+%
+%
+% \medskip\goodbreak
+%
+%
+% \DescribeOption{width}
+% \DescribeOption{width outer}
+% \DescribeOption{width inner}
+% \DescribeOption{width between}
+% \DescribeOption{width recto outer}
+% \DescribeOption{width recto inner}
+% \DescribeOption{width verso outer}
+% \DescribeOption{width verso inner}
+% \DescribeOption{width right between}
+% \DescribeOption{width left between}
+% These keys specify the width of the an item of marginal content (or, more precisely, the \cs{hsize} of the box into
+% which the item is typeset). Which width is chosen will depend on the where the item is typeset. The terminology is as
+% in \fullref{Figure}{fig:terminology}.
+% \begin{vallist}
+% \item[\key{width recto outer}] used for an item in the outer margin of a recto page.
+% \item[\key{width recto inner}] used for an item in the inner margin of a recto page.
+% \item[\key{width verso outer}] used for an item in the outer margin of a verso page.
+% \item[\key{width verso inner}] used for an item in the inner margin of a verso page.
+% \item[\key{width right between}] used for an item set from the right column and placed between the columns.
+% \item[\key{width left between}] used for an item set from the right column and placed between the columns.
+% \item[\key{width outer}] a shorthand for setting the keys \key{width recto outer} and \key{width verso outer}
+% simultaneously to the same value.
+% \item[\key{width inner}] a shorthand for setting the keys \key{width recto inner} and \key{width verso inner}
+% simultaneously to the same value.
+% \item[\key{width between}] a shorthand for setting the keys \key{width right between} and \key{width left between}
+% simultaneously to the same value.
+% \item[\key{width}] a shorthand for setting all of these keys simultaneously.
+% \end{vallist}
+% (The shorthands \key{width outer} and \key{width inner} exist because page geometry is usually symmetrical between
+% recto and verso pages as regards outer and inner margins. The shorthand \key{width between} exists because the space
+% between columns, if used at all for marginal content, will often be shared equally.) Each of these keys must be set to
+% a valid dimension. \default{value of \cs{marginparwidth} when the package is loaded}
+%
+%
+% \medskip\goodbreak
+%
+%
+% \DescribeOption{style}
+% \DescribeOption{style recto outer}
+% \DescribeOption{style recto inner}
+% \DescribeOption{style verso outer}
+% \DescribeOption{style verso inner}
+% \DescribeOption{style right between}
+% \DescribeOption{style left between}
+% These keys specify the style with which an item of marginal content is typeset. Which style is chosen will depend on
+% where the item is typeset. The terminology is as in \fullref{Figure}{fig:terminology}.
+% \begin{vallist}
+% \item[\key{style recto outer}] used for an item in the outer margin of a recto page.
+% \item[\key{style recto inner}] used for an item in the inner margin of a recto page.
+% \item[\key{style verso outer}] used for an item in the outer margin of a verso page.
+% \item[\key{style verso inner}] used for an item in the inner margin of a verso page.
+% \item[\key{style right between}] used for an item set from the right column between the columns.
+% \item[\key{style left between}] used for an item set from the right column between the columns.
+% \item[\key{style}] a shorthand for setting all of these keys simultaneously.
+% \end{vallist}
+% Each of these keys should be set to \LaTeX\ code that specifies the style. \default{[Empty]}
+%
+%
+%
+% \section{Placement}
+% \label{sec:placement}
+%
+% The placement of an item of marginal content depends on where the call to \cs{marginalia} appears in the finished
+% document. Both horizontal and vertical placement can be complicated.
+%
+%
+%
+% \subsection{Horizontal placement}
+%
+% To understand the horizontal placement, first recall some terminology: a recto page is an odd-numbered page in
+% two-sided mode, or any page in one-sided mode; a verso page is an even-numbered page in two-sided mode. The
+% description in the paragraphs that follow is summarized in \fullref{Figure}{fig:terminology}.
+%
+% \begin{figure}[t]
+% \centering
+% \begin{tikzpicture}[
+% x={.45*\textwidth},
+% y={sqrt(2)*.45*\textwidth},
+% ]
+%
+% \begin{scope}[
+% every node/.style ={
+% node font=\footnotesize\scshape,
+% align=center,
+% }
+% ]
+% \begin{scope}
+% \clip[decorate,decoration={snake,amplitude=1mm,segment length=5mm}] (-1,0) -- (1,0) -- (1,.5) -| cycle;
+% \begin{scope}[fill=lightgray]
+% \fill (-.7,-.35) rectangle (-.2,.35);
+% \node at (-.45,.175) {one\\column};
+% \fill (.7,-.35) rectangle (.2,.35);
+% \node at (.45,.175) {one\\column};
+% \end{scope}
+% \end{scope}
+%
+% \begin{scope}
+% \clip[decorate,decoration={snake,amplitude=1mm,segment length=5mm}] (-1,0) -- (1,0) -- (1,-.5) -| cycle;
+% \begin{scope}[fill=lightgray]
+% \fill (-.85,-.35) rectangle (-.65,.35);
+% \node at (-.75,-.175) {left\\column};
+% \fill (-.35,-.35) rectangle (-.15,.35);
+% \node at (-.25,-.175) {right\\column};
+% \fill (.35,-.35) rectangle (.15,.35);
+% \node at (.25,-.175) {left\\column};
+% \fill (.85,-.35) rectangle (.65,.35);
+% \node at (.75,-.175) {right\\column};
+% \end{scope}
+% \end{scope}
+%
+% \end{scope}
+%
+% \pgfresetboundingbox
+%
+% \draw[white,line width=1pt,decorate,decoration={snake,amplitude=1mm,segment length=5mm}] (-1,0) -- (1,0);
+%
+% \draw (0,-.5) -- (0,.5);
+% \draw (-1,-.5) rectangle (1,.5);
+%
+% \begin{scope}[
+% every node/.style={
+% node font=\footnotesize\ttfamily,
+% inner xsep=3pt,
+% }
+% ]
+% \node[anchor=north west,align=left] at (.7,.35) {auto\\right};
+% \node[anchor=north east,align=right] at (.2,.35) {reverse\\left};
+%
+% \node[anchor=south east,align=right] at (.15,-.35) {auto\\left};
+% \node[anchor=north,shift={(.03,0)},align=left] at (.35,-.35) {reverse\\right};
+% \node[anchor=north,shift={(-.03,0)},align=right] at (.65,-.35) {reverse\\left};
+% \node[anchor=south west,align=left] at (.85,-.35) {auto\\\strut\smash{right}};
+%
+% \node[anchor=north east,align=right] at (-.7,.35) {auto\\left};
+% \node[anchor=north west,align=left] at (-.2,.35) {reverse\\right};
+%
+% \node[anchor=south east,align=right] at (-.85,-.35) {auto\\left};
+% \node[anchor=north,shift={(.03,0)},align=left] at (-.65,-.35) {reverse\\right};
+% \node[anchor=north,shift={(-.03,0)},align=right] at (-.35,-.35) {reverse\\left};
+% \node[anchor=south west,align=left] at (-.15,-.35) {auto\\right};
+%
+% \end{scope}
+%
+% \begin{scope}[
+% every node/.style={
+% node font=\small\ttfamily,
+% inner xsep=6pt,
+% }
+% ]
+% \node[rotate=90,anchor=north] at (-1,0) {verso outer};
+% \node[rotate=90,anchor=north east,align=right] at (-.65,0) {left\\[-1pt]between};
+% \node[rotate=-90,anchor=north west,align=left] at (-.35,0) {right\\[-1pt]between};
+% \node[rotate=-90,anchor=north] at (0,0) {verso inner};
+% \node[rotate=90,anchor=north] at (0,0) {recto inner};
+% \node[rotate=90,anchor=north east,align=right] at (.35,0) {left\\[-1pt]between};
+% \node[rotate=-90,anchor=north west,align=left] at (.65,0) {right\\[-1pt]between};
+% \node[rotate=-90,anchor=north] at (1,0) {recto outer};
+% \end{scope}
+%
+% \end{tikzpicture}
+% \caption{Summary of the positioning of marginal content using \key{pos}, and terminology used in \key{width} and
+% \key{style} keys, on recto and verso pages, in both one-column and two-column mode.}
+% \label{fig:terminology}
+% \end{figure}
+%
+%
+% In one-column mode, marginal content is placed by default in the outer margin: right on recto pages, left on verso
+% pages. If \keyvalue{pos}{reverse} is applied, it is placed in the inner margin: left on recto pages, right on verso
+% pages.
+%
+% In two-column mode, the default placement is next to the column in which the call to \cs{marginalia} appears, on the
+% side opposite to the other column. Thus, if the call to \cs{marginalia} was in the left column, the marginal content
+% item is placed by default on the left: on a recto page, the inner margin, on a verso page, the outer margin. If
+% \keyvalue{pos}{reverse} is applied, it is placed between the two columns, adjacent to the left column. If the call to
+% \cs{marginalia} was in the right column, the item is placed by default on the right: on a recto page, the
+% outer margin, on a verso page, the inner margin. If \keyvalue{pos}{reverse} is applied, it is placed between the two
+% columns, adjacent to the right column.
+%
+% \keyvalue{pos}{left} specifies that the item is to be placed on the left of the text block or column
+% containing the call to \cs{marginalia}.
+%
+% \keyvalue{pos}{right} similarly specifies that the item is to be placed on the right of the text block or column
+% containing the call to \cs{marginalia}.
+%
+% \pkg{marginalia} determines in which column the call to \cs{marginalia} was made using its horizontal position. As
+% discussed in the description of key \key{column}, there are situations where this can go wrong and which
+% necessitate a manual specification of a particular column.
+%
+%
+%
+% \subsection{Vertical placement}
+% \label{subsec:vertical-placement}
+%
+% \pkg{marginalia} tries by default to place the each item of marginal content with its baseline shifted by the value of
+% \key{yshift} (by default, \qty{0}{\point}) from the baseline where \cs{marginalia} was called. The actual vertical
+% placement is calculated by the procedure described below, carried out for the items appearing in a particular
+% horizontal location. (As shown in \fullref{Figure}{fig:terminology}, in one-column mode the possible locations are in
+% outer and inner margins; in two-column mode the possible locationd are the outer and inner margins and on the left and
+% right sides of the space between the columns.) A \emph{clash} exists when two items are closer than specified by
+% \key{ysep below} for the upper item or \key{ysep above} for the lower item, whichever is greater.
+%
+% For the items in each horizontal location, the procedure is as follows:
+% \begin{enumerate}
+% \item Place the items appearing in a given horizontal location on the page into a list.
+% \item Set the vertical shift of each item to the one specified by \key{yshift}.
+% \item For each \keyvalue{type}{optfixed} item, if it clashes with any \keyvalue{type}{fixed} item, delete it from
+% the list of items that appear on the page.
+% \item Sort the list by the position of the call to \cs{marginalia}, top-to-bottom, left-to-right, breaking ties
+% by the order of calls. (Because of floats, footnotes, etc., the sorted order of the list is not necessarily
+% the same as the order of appearance of \cs{marginalia} commands in the source code.)
+% \item Pass through the list of items in sorted order. For each \keyvalue{type}{normal} item, if necessary shift it
+% in a negative (downward) direction so that it
+% \begin{enumerate*}[label={(\arabic*)}]
+% \item does not reach closer to the top of the page than specified by \texttt{ysep page top}, and
+% \item does not clash with the previous (above) item.
+% \end{enumerate*}
+% (After this stage, it is possible for an assigned vertical shift to push a \keyvalue{type}{normal} item off
+% the bottom of the page.)
+% \item Pass through the list of items in the reverse of the sorted order. For each \keyvalue{type}{normal} item, if
+% necessary shift it in a positive (upward) direction so that it
+% \begin{enumerate*}[label={(\arabic*)}]
+% \item does not reach closer to the bottom of the page than specified by \texttt{ysep page bottom}, and
+% \item does not clash with the next (below) item.
+% \end{enumerate*}
+% \end{enumerate}
+% During this process, it may be found that it is impossible to prevent clashes or items reaching beyong the limits
+% (e.g. fixed items clash with each other; a fixed item conflicts with \texttt{ysep page top} or \texttt{ysep page
+% bottom}, or there are simply too many items of marginal content to fit (in which case, the top of some of them will be
+% above the limit specified by \texttt{ysep page top} or will clash with fixed items)). In these cases, warnings are
+% issued at the end of the Lua\LaTeX\ run.
+%
+%
+%
+% \section{Usage notes}
+% \label{sec:usage}
+%
+% \pkg{marginalia} requires a minimum of two Lua\LaTeX\ runs, and often more, to place items of marginal content
+% correctly. On the first pass, information about items, including their vertical size, is written to the \file{.aux}
+% file, and this information is used to position them correctly on the next run. However, because \key{width} and
+% \key{style} have variants dependent on the margin in which the item is placed, an item may only be typeset at the
+% correct size on this second run. Thus the vertical size of the item may have changed and so the information written to
+% the \file{.aux} file on the previous run may be out of date. In this case a third run may be needed for correct
+% placement.
+%
+% More runs may be needed if the position of the call to \cs{marginalia} changes between runs. Provided the main text
+% stabilizes, the placement of items using \cs{marginalia} should be correct two runs later.
+%
+% At the end of the Lua\LaTeX\ run, \pkg{marginalia} reports any problems encountered in the vertical placement of items
+% (as decribed at the end of \fullref{Subsection}{subsec:vertical-placement}). These problems are based on calculations
+% made on the basis of information from the previous written to the \file{.aux} file on the previous run, and may not
+% arise if item positions or sizes (i.e. height or depth) have changed. \pkg{marginalia} also reports any changes in
+% positions or sizes compared to the previous run.
+%
+% In these reports, a page number refers to a visible page number if it is prefixed with `\texttt{p}'; it otherwise
+% refers to the absolute page number of the output.
+%
+%
+%
+% \section{Incompatibilities}
+%
+% Using \pkg{marginalia} alongside \cs{marginpar} or packages like \pkg{mparhak}, \pkg{marginnote}, \pkg{marginfix}, or
+% \pkg{marginfit} should not produce any errors, but \pkg{marginalia} will ignore marginal content not created using
+% \cs{marginalia}; for example, an item of marginal content created using \cs{marginalia} might overlap with one created
+% using \cs{marginpar}.
+%
+%
+%
+% \section{Limitations}
+% \label{sec:limitations}
+%
+% As noted in the introduction, \pkg{marginalia} was originally written to typeset a particular kind of book. It thus
+% has several limitations. Three of these are:
+% \begin{description}
+% \item[Lua\LaTeX only] Most of the code for deciding the placement of items of marginal content is written in Lua.
+% In principle, the it could be replaced with a pure \LaTeX\ solution.
+% \item[No support for `moving past' fixed items] The adjustment of vertical positions will never cause a
+% \keyvalue{type}{normal} item to be shifted past a \keyvalue{type}{fixed} one, even when there is space on
+% the other side. It may be desirable to have this available as an option.
+% \item[No support for nested content items] Nesting might be desirable for typesetting editions of manuscripts
+% which sometimes contain marginal glosses, and then glosses upon those glosses.
+% \end{description}
+%
+% The lack of any built-in facility for producing (for example) numbered sidenotes is a conscious design choice. This is
+% properly the concern of a command that merely uses \cs{marginalia} to place the notes correctly.
+%
+%
+%
+% ^^A\bibliography{\jobname}
+% ^^A\bibliographystyle{alphaabbrv}
+%
+% \begin{thebibliography}{Cai24}
+%
+% \bibitem[Bri04]{bringhurst_elements}
+% R.~Bringhurst.
+% \newblock {\em {T}he {E}lements of {T}ypographic {S}tyle}.
+% \newblock Hartley {\&} Marks, version 3.0, 2004.
+%
+% \bibitem[Cai24]{cain_formandnumber_ebook_large}
+% A.~J. Cain.
+% \newblock {\em {F}orm {\&} {N}umber: {A} {H}istory of {M}athematical {B}eauty}.
+% \newblock Lisbon, 2024.
+% \newblock {\sc url:}
+% \href{https://archive.org/details/cain_formandnumber_ebook_large}{\nolinkurl{https://archive.org/details/cain_formandnumber_ebook_large}}.
+%
+% \end{thebibliography}
+%
+%
+%
+% \end{documentation}
+%
+%
+%
+% \iffalse
+%<*example>
+\documentclass[11pt]{article}
+
+\usepackage{marginalia}
+
+\begin{document}
+
+Here is some body text.\marginalia{Here is a marginal note.} Some more
+body text.\marginalia[style=\footnotesize\itshape\raggedright]{Here is another
+ marginal note, set in smaller text and italics, whose position has been been
+ adjusted automatically.}
+
+Some final body text.\marginalia[pos=left, valign=b, style=\sffamily\raggedleft,
+width=35mm]{This note is placed on the left side of the page, wider, in sans
+ serif, ragged left, and bottom-aligned.}
+
+\end{document}
+%</example>
+% \fi
+%
+%
+%
+% \clearpage
+% \begin{implementation}
+%
+%
+%
+% \section{Implementation (\LaTeX\ package)}
+%
+% \begin{macrocode}
+%<*package>
+%<@@=marginalia>
+% \end{macrocode}
+%
+%
+%
+% \subsection{Initial set-up}
+%
+% Package identification/version information.
+% \begin{macrocode}
+\NeedsTeXFormat{LaTeX2e}[2020-02-02]
+\ProvidesExplPackage{marginalia}{2025-02-17}{0.80.1}
+ {Non-floating marginal content for LuaLaTeX}
+% \end{macrocode}
+% Check that Lua\TeX\ is in use.
+% \begin{macrocode}
+\sys_if_engine_luatex:F
+ {
+ \msg_new:nnn{marginalia}{lualatex_required}
+ {LuaLaTeX~required.~Package~loading~will~abort.}
+ \msg_critical:nn{marginalia}{lualatex_required}
+ }
+% \end{macrocode}
+%
+%
+%
+% \subsection{Options}
+%
+% Set up the key--value options and the variables in which the settings will be stored.
+%
+%
+%
+% \subsubsection{Type}
+%
+% \begin{macro}{
+% \l_@@_type_int,
+% }
+% A key to store the type of the marginal content item. The setting is held in an integer variable:
+% \(1 = \key{normal}\), \(2 = \key{fixed}\), \(3 = \key{optfixed}\).
+% \begin{macrocode}
+\int_new:N\l_@@_type_int
+\keys_define:nn { marginalia }
+{
+ type .choices:nn = {normal,fixed,optfixed}{
+ \int_set:Nn\l_@@_type_int{\l_keys_choice_int}
+ },
+ type .initial:n = normal,
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \subsubsection{Horizontal placement}
+%
+% \begin{macro}{
+% \l_@@_pos_int,
+% }
+% A key to store the specified position of the marginal content item. The setting is held in an integer variable:
+% \(1 = \key{auto}\), (the outer margin in one-column mode; left margin in left column, right margin in right column
+% in two-column mode) \(2 = \key{reverse}\) (inner margin in one-column mode; between the columns in two-column mode),
+% \(3 = \key{left}\), \(4 = \key{right}\), \(5 = \key{nearest}\).
+% \begin{macrocode}
+\int_new:N\l_@@_pos_int
+\keys_define:nn { marginalia }
+{
+ pos .choices:nn = {auto,reverse,left,right,nearest}{
+ \int_set:Nn\l_@@_pos_int{\l_keys_choice_int}
+ },
+ pos .initial:n = auto
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{
+% \l_@@_column_int,
+% }
+% A key to force the marginal content item to be treated in one-column mode or as being set from the left or right
+% column. The setting is held in an integer variable: \(-1 = \key{auto}\) (automatic), \(0 = \key{one}\) (one-column
+% mode), \(1 = \key{left}\) (left column) \(2 = \key{right}\) (right column).
+% \begin{macrocode}
+\int_new:N\l_@@_column_int
+\keys_define:nn { marginalia }
+{
+ column .choices:nn = {auto,one,left,right}{
+ \int_set:Nn\l_@@_column_int{\l_keys_choice_int-2}
+ },
+ column .initial:n = auto,
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{
+% \l_@@_xsep_recto_outer_dim,
+% \l_@@_xsep_recto_inner_dim,
+% \l_@@_xsep_verso_outer_dim,
+% \l_@@_xsep_verso_inner_dim,
+% \l_@@_xsep_right_between_dim,
+% \l_@@_xsep_left_between_dim,
+% }
+% Dimension keys to hold the separation between the marginal content item and the main text, which can be dependent on
+% where it appears on the page.
+% \begin{macrocode}
+\keys_define:nn { marginalia }
+{
+ xsep~recto~outer .dim_set:N = \l_@@_xsep_recto_outer_dim,
+ xsep~recto~inner .dim_set:N = \l_@@_xsep_recto_inner_dim,
+ xsep~verso~outer .dim_set:N = \l_@@_xsep_verso_outer_dim,
+ xsep~verso~inner .dim_set:N = \l_@@_xsep_verso_inner_dim,
+ xsep~right~between .dim_set:N = \l_@@_xsep_right_between_dim,
+ xsep~left~between .dim_set:N = \l_@@_xsep_left_between_dim,
+ xsep .code:n = {
+ \keys_set:nn{ marginalia }{
+ xsep~recto~outer=#1,
+ xsep~recto~inner=#1,
+ xsep~verso~outer=#1,
+ xsep~verso~inner=#1,
+ xsep~right~between=#1,
+ xsep~left~between=#1,
+ }
+ },
+ xsep~outer .code:n = {
+ \keys_set:nn{ marginalia }{
+ xsep~recto~outer=#1,
+ xsep~verso~outer=#1,
+ }
+ },
+ xsep~inner .code:n = {
+ \keys_set:nn{ marginalia }{
+ xsep~recto~inner=#1,
+ xsep~verso~inner=#1,
+ }
+ },
+ xsep~between .code:n = {
+ \keys_set:nn{ marginalia }{
+ xsep~right~between=#1,
+ xsep~left~between=#1,
+ }
+ },
+ xsep .initial:n = \marginparsep,
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \subsubsection{Vertical placement}
+%
+% \begin{macro}{
+% \l_@@_valign_int,
+% }
+% A key to store the vertical alignment of the marginal content item. The setting is held in a integer variable:
+% \(1 = \key{t}\) (aligned at the baseline of the topmost line of the item), \(2 = \key{b}\) (aligned at the baseline
+% of the bottommost line of the item).
+% \begin{macrocode}
+\int_new:N\l_@@_valign_int
+\keys_define:nn { marginalia }
+{
+ valign .choices:nn = {t,b}{
+ \int_set_eq:NN\l_@@_valign_int\l_keys_choice_int
+ },
+ valign .initial:n = t,
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{
+% \l_@@_default_yshift_dim,
+% }
+% Dimension key to hold the default vertical shift of the marginal content item from its natural position.
+% \begin{macrocode}
+\keys_define:nn { marginalia }
+{
+ yshift .dim_set:N = \l_@@_default_yshift_dim,
+ yshift .initial:n = 0pt,
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{
+% \l_@@_ysep_above_dim,
+% \l_@@_ysep_below_dim,
+% \l_@@_ysep_page_top_dim,
+% \l_@@_ysep_page_bottom_dim
+% }
+% Dimension keys to hold the the minimum vertical spacing between a marginal content item and (respectively) the item
+% above, the item below, the page top, and the page bottom.
+% \begin{macrocode}
+\keys_define:nn { marginalia }
+{
+ ysep~above .dim_set:N = \l_@@_ysep_above_dim,
+ ysep~below .dim_set:N = \l_@@_ysep_below_dim,
+ ysep~page~top .dim_set:N = \l_@@_ysep_page_top_dim,
+ ysep~page~bottom .dim_set:N = \l_@@_ysep_page_bottom_dim,
+ ysep .code:n = {
+ \keys_set:nn{ marginalia }{
+ ysep~below=#1,
+ ysep~above=#1,
+ ysep~page~top=#1,
+ ysep~page~bottom=#1,
+ }
+ },
+ ysep .initial:n = \marginparpush,
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \subsubsection{Appearance}
+%
+% \begin{macro}{
+% \l_@@_width_recto_outer_dim,
+% \l_@@_width_recto_inner_dim,
+% \l_@@_width_verso_outer_dim,
+% \l_@@_width_verso_inner_dim,
+% \l_@@_width_right_between_dim,
+% \l_@@_width_left_between_dim,
+% }
+% Dimension keys to hold the width of the marginal content item, which can be dependent on where it appears on the
+% page.
+% \begin{macrocode}
+\keys_define:nn { marginalia }
+{
+ width~recto~outer .dim_set:N = \l_@@_width_recto_outer_dim,
+ width~recto~inner .dim_set:N = \l_@@_width_recto_inner_dim,
+ width~verso~outer .dim_set:N = \l_@@_width_verso_outer_dim,
+ width~verso~inner .dim_set:N = \l_@@_width_verso_inner_dim,
+ width~right~between .dim_set:N = \l_@@_width_right_between_dim,
+ width~left~between .dim_set:N = \l_@@_width_left_between_dim,
+ width .code:n = {
+ \keys_set:nn{ marginalia }{
+ width~recto~outer=#1,
+ width~recto~inner=#1,
+ width~verso~outer=#1,
+ width~verso~inner=#1,
+ width~right~between=#1,
+ width~left~between=#1,
+ }
+ },
+ width~outer .code:n = {
+ \keys_set:nn{ marginalia }{
+ width~recto~outer=#1,
+ width~verso~outer=#1,
+ }
+ },
+ width~inner .code:n = {
+ \keys_set:nn{ marginalia }{
+ width~recto~inner=#1,
+ width~verso~inner=#1,
+ }
+ },
+ width~between .code:n = {
+ \keys_set:nn{ marginalia }{
+ width~right~between=#1,
+ width~left~between=#1,
+ }
+ },
+ width .initial:n = \marginparwidth,
+}
+% \end{macrocode}
+% \end{macro}
+%
+%% \begin{macro}{
+% \l_@@_style_recto_outer_tl,
+% \l_@@_style_recto_inner_tl,
+% \l_@@_style_verso_outer_tl,
+% \l_@@_style_verso_inner_tl,
+% \l_@@_style_right_between_tl,
+% \l_@@_style_left_between_tl,
+% }
+% Token list keys to hold the style with which a marginal content item is typeset, which can be dependent on where it
+% appears on the page.
+% \begin{macrocode}
+\keys_define:nn { marginalia }
+{
+ style~recto~outer .tl_set:N = \l_@@_style_recto_outer_tl,
+ style~recto~inner .tl_set:N = \l_@@_style_recto_inner_tl,
+ style~verso~outer .tl_set:N = \l_@@_style_verso_outer_tl,
+ style~verso~inner .tl_set:N = \l_@@_style_verso_inner_tl,
+ style~right~between .tl_set:N = \l_@@_style_right_between_tl,
+ style~left~between .tl_set:N = \l_@@_style_left_between_tl,
+ style .code:n = {
+ \keys_set:nn{ marginalia }{
+ style~recto~outer=#1,
+ style~recto~inner=#1,
+ style~verso~outer=#1,
+ style~verso~inner=#1,
+ style~right~between=#1,
+ style~left~between=#1,
+ }
+ },
+ style .initial:n = {},
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \subsection{Lua backend and interface}
+%
+% Load the Lua backend.
+% \begin{macrocode}
+ \lua_now:n{
+ marginalia = require('marginalia')
+ }
+% \end{macrocode}
+%
+% The following 9 macros interface between \LaTeX\ and Lua code. Each control sequence \cs[no-index]{@@_lua_XYZ}
+% simply calls the corresponding Lua function \luafunc{marginalia.XYZ}.
+% \begin{macro}{
+% \@@_lua_store_default_page_data:,
+% \@@_lua_store_page_data:n,
+% \@@_lua_check_page_data:n,
+% \@@_lua_store_item_data:n,
+% \@@_lua_check_item_data:n,
+% \@@_lua_compute_items:,
+% \@@_lua_write_problem_report:,
+% \@@_lua_write_item_change_report:,
+% }
+% The first 8 macros do not require expansion of parameters: they either have none, or process data not containing
+% control sequences (read from the \file{.aux} file); hence \cs{lua_now:n} is used.
+% \begin{macrocode}
+\cs_new:Npn\@@_lua_store_default_page_data:
+ {
+ \lua_now:n{ marginalia.store_default_page_data() }
+ }
+\cs_new:Npn\@@_lua_store_page_data:n #1
+ {
+ \lua_now:n{ marginalia.store_page_data('#1') }
+ }
+\cs_new:Npn\@@_lua_check_page_data:n #1
+ {
+ \lua_now:n{ marginalia.check_page_data('#1') }
+ }
+\cs_new:Npn\@@_lua_write_page_change_report:
+ {
+ \lua_now:n{ marginalia.write_page_change_report() }
+ }
+\cs_new:Npn\@@_lua_store_item_data:n #1
+ {
+ \lua_now:n{ marginalia.store_item_data('#1') }
+ }
+\cs_new:Npn\@@_lua_check_item_data:n #1
+ {
+ \lua_now:n{ marginalia.check_item_data('#1') }
+ }
+\cs_new:Npn\@@_lua_compute_items:
+ {
+ \lua_now:n{ marginalia.compute_items() }
+ }
+\cs_new:Npn\@@_lua_write_problem_report:
+ {
+ \lua_now:n{ marginalia.write_problem_report() }
+ }
+\cs_new:Npn\@@_lua_write_item_change_report:
+ {
+ \lua_now:n{ marginalia.write_item_change_report() }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{
+% \@@_lua_load_item_data:n,
+% }
+% The last macro will receive a control sequence parameter and so requires expansion; hence
+% \cs{lua_now:e} is used.
+% \begin{macrocode}
+\cs_new:Npn\@@_lua_load_item_data:n #1
+ {
+ \lua_now:e{ marginalia.load_item_data('#1') }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \subsection{Processing data from the \texorpdfstring{\file{.aux}}{.aux} file}
+%
+% \begin{macro}[int]{
+% \marginalia at pagedata,
+% }
+% This command is used to store page data in the \file{.aux} file.
+% \begin{macrocode}
+\NewDocumentCommand{\marginalia at pagedata}{ m }{
+ \@@_process_page_data:n{#1}
+}
+% \end{macrocode}
+% Initially \cs{@@_process_page_data:n} is set to \cs{@@_lua_store_page_data:n}. Thus, when the \file{.aux} file is
+% read, \cs{marginalia at pagedata} will pass the page data to the Lua backend to be stored.
+% \begin{macrocode}
+\cs_set_eq:NN
+ \@@_process_page_data:n
+ \@@_lua_store_page_data:n
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[int]{
+% \marginalia at itemdata,
+% }
+% This command is used to store data for each marginal content item in the \file{.aux} file.
+% \begin{macrocode}
+\DeclareDocumentCommand{\marginalia at itemdata}{ m }{
+ \@@_process_item_data:n{#1}
+}
+% \end{macrocode}
+% \end{macro}
+% Initially \cs{@@_process_item_data:n} is set to \cs{@@_lua_store_item_data:n}. Thus, when the \file{.aux} file is
+% read, \cs{marginalia at itemdata} will pass the item data to the Lua backend to be stored.
+% \begin{macrocode}
+\cs_set_eq:NN
+ \@@_process_item_data:n
+ \@@_lua_store_item_data:n
+% \end{macrocode}
+% At the \texttt{begindocument} hook, the \file{.aux} file has been read and closed. The Lua backend now stores the
+% geometry and computes the vertical shift for each item. Then the handle for the main \file{.aux} file is stored for
+% use in this package.
+% \begin{macrocode}
+\AddToHook{begindocument}{
+ \@@_lua_store_default_page_data:
+ \@@_lua_compute_items:
+ \cs_set_eq:NN\l_@@_aux_iow\@mainaux
+}
+% \end{macrocode}
+% The \texttt{enddocument/afterlastpage} hook is before the \file{.aux} file is read back, so this is where
+% \cs{@@_process_page_data:n} and \cs{@@_process_item_data:n} are set, respectively, to \cs{@@_lua_check_page_data:n}
+% and \cs{@@_lua_check_item_data:n}. Thus, when the \file{.aux} file is read back, \cs{marginalia at pagedata} and
+% \cs{marginalia at itemdata} will pass data to the Lua backend to be checked for changes.
+% \begin{macrocode}
+\AddToHook{enddocument/afterlastpage}{
+ \cs_set_eq:NN
+ \@@_process_page_data:n
+ \@@_lua_check_page_data:n
+ \cs_set_eq:NN
+ \@@_process_item_data:n
+ \@@_lua_check_item_data:n
+ }
+% \end{macrocode}
+% \begin{macro}{\@@_write_reports:}
+% All the reports of changes and/or problems are assembled in the Lua backend. This macro will write the reports as
+% package warnings, using the following three messages, to which the Lua-assembled reports are passed as parameters:
+% \begin{macrocode}
+\msg_new:nnn{marginalia}{placement_problem}
+ { Problems~in~placement.~#1 }
+\msg_new:nnn{marginalia}{item_change}
+ { Changes~in~item~data.~#1 }
+\msg_new:nnn{marginalia}{page_change}
+ { Changes~in~page~data.~#1 }
+\cs_new:Npn\@@_write_reports:
+ {
+ \group_begin:
+ \tl_set:Ne\l_tmpa_tl{\@@_lua_write_problem_report:}
+ \tl_if_blank:VF\l_tmpa_tl
+ {
+ \msg_warning:nne{marginalia}{placement_problem}{\tl_use:N\l_tmpa_tl}
+ }
+ \tl_set:Ne\l_tmpa_tl{\@@_lua_write_item_change_report:}
+ \tl_if_blank:VF\l_tmpa_tl
+ {
+ \msg_warning:nne{marginalia}{item_change}{\tl_use:N\l_tmpa_tl}
+ }
+ \tl_set:Ne\l_tmpa_tl{\@@_lua_write_page_change_report:}
+ \tl_if_blank:VF\l_tmpa_tl
+ {
+ \msg_warning:nne{marginalia}{page_change}{\tl_use:N\l_tmpa_tl}
+ }
+ \group_end:
+ }
+% \end{macrocode}
+% \end{macro}
+% Use the \texttt{enddocument/info} hook to write the reports of changes and/or problems.
+% \begin{macrocode}
+\AddToHook{enddocument/info}{
+ \@@_write_reports:
+}
+% \end{macrocode}
+%
+%
+%
+% \subsection{Writing page data to the \texorpdfstring{\file{.aux}}{.aux} file}
+%
+% To compute the positions of marginal content items, certain page layout data is required. And since all the
+% computation takes place at the beginning of the document, it is necessary to write this information to the \file{.aux}
+% file.
+%
+% \begin{macro}{\g_@@_pagedatano_int}
+% Global integer variable to index page data items written to the \file{.aux} file.
+% \begin{macrocode}
+\int_new:N\g_@@_pagedatano_int
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_write_page_data}
+% This command will be used to write the current page data to the \file{.aux} file. It is initially defined to do
+% nothing, so that the use of \cs{marginalianewgeometry} in the preamble does not cause errors (because the
+% \file{.aux} file is not available for writing until \texttt{begindocument/end}).
+% \begin{macrocode}
+\cs_set_eq:NN\@@_write_page_data:\prg_do_nothing:
+\cs_new:Npn\@@_write_page_data_real:
+ {
+ \int_gincr:N\g_@@_pagedatano_int
+ \iow_now:Ne\l_@@_aux_iow{
+ \token_to_str:N\marginalia at pagedata{
+ pagedatano=\int_value:w\g_@@_pagedatano_int,
+ abspageno=\int_eval:n{\g_shipout_readonly_int+1},
+ hoffset=\int_value:w\hoffset,
+ voffset=\int_value:w\voffset,
+ paperheight=\int_value:w\paperheight,
+ oddsidemargin=\int_value:w\oddsidemargin,
+ evensidemargin=\int_value:w\evensidemargin,
+ textwidth=\int_value:w\textwidth,
+ columncount=\int_value:w\col at number,
+ columnwidth=\int_value:w\columnwidth,
+ columnsep=\int_value:w\columnsep,
+ twoside=\bool_to_str:n{\legacy_if_p:n{@twoside}},
+ }
+ }
+ }
+% \end{macrocode}
+% At the \texttt{begindocument/end} hook, the \file{.aux} file has been opened for writing, and so the macro
+% \cs{@@_write_page_data:} is enabled and the initial page data is written out.
+% \begin{macrocode}
+\AddToHook{begindocument/end}
+ {
+ \cs_set_eq:NN
+ \@@_write_page_data:
+ \@@_write_page_data_real:
+ \@@_write_page_data:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \subsection{Marginal content item processing}
+%
+% \subsubsection{Variables}
+%
+% \paragraph{Variables set by \LaTeX.}
+%
+% \begin{macro}{\g_@@_itemno_int}
+% Global integer variable to index marginal content items.
+% \begin{macrocode}
+\int_new:N\g_@@_itemno_int
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\l_@@_item_box}
+% Box variable to hold the typeset marginal content item.
+% \begin{macrocode}
+\box_new:N\l_@@_item_box
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{
+% \l_@@_item_height_dim,
+% \l_@@_item_depth_dim,
+% }
+% Dimension variables to hold the height and depth of the typeset margin content item.
+% \begin{macrocode}
+\dim_new:N\l_@@_item_height_dim
+\dim_new:N\l_@@_item_depth_dim
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \paragraph{Variables set by Lua.}
+%
+% The following variables will be set by the Lua backend via \texttt{tex.count} and \texttt{tex.dimen} when
+% \cs{@@_lua_load_item_data:n} is called.
+%
+% \begin{macro}{\l_@@_page_int}
+% Integer variable for the page on which the marginal content item appears. This variable will be
+% made available via \cs{marginaliapage} within the \meta{content} of \cs{marginalia}.
+% \begin{macrocode}
+\int_new:N\l_@@_page_int
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\l_@@_column_computed_int}
+% Integer variable for the column next to which the marginal content item appears. This variable will be
+% will be made available via \cs{marginaliacolumn} within the \meta{content} of \cs{marginalia}.
+% \begin{macrocode}
+\int_new:N\l_@@_column_computed_int
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{
+% \l_@@_xshift_computed_dim,
+% \l_@@_yshift_computed_dim,
+% }
+% Dimension variables to hold the differences in \(x\) and \(y\) coordinates between the call to \cs{marginalia} and
+% the position where the marginal content item should appear.
+% \begin{macrocode}
+\dim_new:N\l_@@_xshift_computed_dim
+\dim_new:N\l_@@_yshift_computed_dim
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\l_@@_side_computed_int}
+% Integer variable to indicate the side of the text block or column on which the marginal content item should be
+% placed: \(0 = \textrm{right}\) and \(1 = \textrm{left}\).
+% \begin{macrocode}
+\int_new:N\l_@@_side_computed_int
+% \end{macrocode}
+% (This variable could be a boolean, but an integer is used because there is no canonical access to booleans from
+% Lua.)
+% \end{macro}
+%
+% \begin{macro}{\l_@@_marginno_computed_int}
+% Integer variable to indicate in which margin the content will be be placed, to enable quick selection of width and
+% style: \(0 = \textrm{recto outer}\), \(1 = \textrm{recto inner}\), \(2 = \textrm{verso outer}\), \(3 = \textrm{verso
+% inner}\), \(4 = \textrm{right between}\), \(5 = \textrm{left between}\).
+% \begin{macrocode}
+\int_new:N\l_@@_marginno_computed_int
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\l_@@_enabled_computed_int}
+% Integer variable to indicate whether the marginal content item is enabled: \(0 = \textrm{disabled}\),
+% \(1 = \textrm{enabled}\).
+% \begin{macrocode}
+\int_new:N\l_@@_enabled_computed_int
+% \end{macrocode}
+% (This variable could be a boolean, but an integer is used because there is no canonical access to booleans from
+% Lua.)
+% \end{macro}
+%
+%
+%
+% \subsubsection{Core macro}
+%
+% \begin{macro}{\@@_process_item:nn}
+% This macro does most of the work in setting the marginal content item. The first parameter is \meta{options}, the
+% second is \meta{content}.
+% \begin{macrocode}
+\cs_new:Npn\@@_process_item:nn #1#2
+ {
+% \end{macrocode}
+% First, increment the index, then enter a group where all the action will happen.
+% \begin{macrocode}
+ \int_gincr:N\g_@@_itemno_int
+ \group_begin:
+% \end{macrocode}
+% Process \meta{options}. These settings apply locally inside the group.
+% \begin{macrocode}
+ \keys_set:nn{marginalia}{ #1 }
+% \end{macrocode}
+% Get item data from the Lua backend: the integer variables \cs{l_@@_page_int}, \cs{l_@@_column_computed_int},
+% \cs{l_@@_side_computed_int}, \cs{l_@@_enabled_computed_int}, and the dimension variables
+% \cs{l_@@_xshift_computed_dim}, and \cs{l_@@_yshift_computed_dim} are set by Lua via \texttt{tex.count} and
+% \texttt{tex.dimen}. If no data is available (if, for instance, no data has been stored from a previous run), default
+% values will be set by Lua. On later runs, the Lua backend will supply the values computed from the data written to
+% the \file{.aux} file on the previous run.
+% \begin{macrocode}
+ \@@_lua_load_item_data:n
+ { \int_value:w\g_@@_itemno_int }
+% \end{macrocode}
+% Choose the correct auxiliary function for typesetting, depending on which mode \TeX\ is in.
+% \begin{macrocode}
+ \mode_if_math:TF
+ {
+ \cs_set_eq:NN
+ \@@_typeset:n
+ \@@_typeset_mmode:n
+ }
+ {
+ \legacy_if:nT{@inlabel}
+ { \leavevmode }
+ \mode_if_horizontal:TF
+ {
+ \cs_set_eq:NN
+ \@@_typeset:n
+ \@@_typeset_hmode:n
+ }
+ {
+ \cs_set_eq:NN
+ \@@_typeset:n
+ \@@_typeset_vmode:n
+ }
+ }
+% \end{macrocode}
+% Choose the correct box in which to typeset the item. \cs{l_@@_valign_int} can only be \(1\) or \(2\), so take \(2\)
+% to signify bottom-aligned, anything else signifies top-aligned.
+% \begin{macrocode}
+ \int_compare:nNnTF{\l_@@_valign_int}={2}
+ {
+ \cs_set_eq:NN\@@_item_box_set:Nn\vbox_set:Nn
+ }
+ {
+ \cs_set_eq:NN\@@_item_box_set:Nn\vbox_set_top:Nn
+ }
+% \end{macrocode}
+% Choose the correct horizontal separation, width, and style for the item.
+% \begin{macrocode}
+ \@@_set_xsep_width_style:
+% \end{macrocode}
+% Typeset the \meta{content} into \cs{l_@@_item_box}. Use \cs{@parboxrestore} for brevity, even though \cs{hsize} and
+% \cs{linewidth} are subsequently set to \cs{l_@@_width_dim}. Make available \cs{marginaliapage} and
+% \cs{marginaliacolumn}.
+% \begin{macrocode}
+ \@@_item_box_set:Nn\l_@@_item_box{
+ \@parboxrestore
+ \normalfont\normalsize
+
+ \tl_use:N\l_@@_style_tl
+ \dim_set_eq:NN\hsize\l_@@_width_dim
+ \dim_set_eq:NN\linewidth\hsize
+
+ \cs_set_eq:NN\marginaliapage\l_@@_page_int
+ \cs_set_eq:NN\marginaliacolumn\l_@@_column_computed_int
+
+ \group_begin:
+ \ignorespaces
+ #2
+ \par
+ \group_end:
+ }
+% \end{macrocode}
+% Measure \cs{l_@@_item_box}.
+% \begin{macrocode}
+ \dim_set:Nn\l_@@_item_height_dim
+ {\box_ht:N\l_@@_item_box}
+ \dim_set:Nn\l_@@_item_depth_dim
+ {\box_dp:N\l_@@_item_box}
+% \end{macrocode}
+% Everything is now ready to place the item on the page and write the necessary data to the \file{.aux} file. Use the
+% chosen auxiliary function for typesetting, and immediately use \cs{savepos} to store the callout position.
+% \begin{macrocode}
+ \@@_typeset:n{
+ \savepos
+% \end{macrocode}
+% Write the item data to the \file{.aux} file. All tokens that will change for future items, and which are currently
+% meaningful, are expanded now; the remainder will be expanded at shipout time, when \emph{they} are meaningful.
+% \begin{macrocode}
+ \iow_shipout_e:Ne\l_@@_aux_iow{
+ \token_to_str:N\marginalia at itemdata{
+ itemno=\int_value:w\g_@@_itemno_int,
+ abspageno=\exp_not:N\int_eval:n{\g_shipout_readonly_int},
+ pageno=\exp_not:N\int_value:w\c at page,
+ type=\str_use:N\int_value:w\l_@@_type_int,
+ xpos=\exp_not:N\int_value:w\lastxpos,
+ ypos=\exp_not:N\int_value:w\lastypos,
+ height=\int_value:w\l_@@_item_height_dim,
+ depth=\int_value:w\l_@@_item_depth_dim,
+ pos=\int_value:w\l_@@_pos_int,
+ column=\int_value:w\l_@@_column_int,
+ yshift=\int_value:w\l_@@_default_yshift_dim,
+ ysep~above=\int_value:w\l_@@_ysep_above_dim,
+ ysep~below=\int_value:w\l_@@_ysep_below_dim,
+ ysep~page~top=\int_value:w\l_@@_ysep_page_top_dim,
+ ysep~page~bottom=\int_value:w\l_@@_ysep_page_bottom_dim,
+ }
+ }
+% \end{macrocode}
+% Finally, if the item is enabled, typeset it onto the page: shift the item by
+% \[
+% \abs[\big]{\cs{l_@@_xshift_computed_dim}} + \abs[\big]{\cs{l_@@_xsep_dim}}
+% \]
+% to the right in an \cs{rlap} or to the left in an \cs{llap}, depending on \cs{l_@@_side_computed_int}, then use
+% \cs{@@_place_item_box} for the vertical placement.
+% \begin{macrocode}
+ \int_if_zero:nF{\l_@@_enabled_computed_int}
+ {
+ \int_if_zero:nTF{\l_@@_side_computed_int}
+ {
+ \rlap{
+ \kern\l_@@_xshift_computed_dim
+ \kern\l_@@_xsep_dim
+ \@@_place_item_box:
+ }
+ }
+ {
+ \llap{
+ \@@_place_item_box:
+ \kern\l_@@_xsep_dim
+ \kern-\l_@@_xshift_computed_dim
+ }
+ }
+ }
+ }
+% \end{macrocode}
+% Close the group started near the beginning of \cs{@@_process_item:nn}.
+% \begin{macrocode}
+ \group_end:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \subsubsection{Width and style selection}
+%
+% \begin{macro}{\@@_set_xsep_width_style}
+% Set \cs{l_@@_xsep_dim}, \cs{l_@@_width_dim}, and \cs{l_@@_style_tl}, based on \cs{l_@@_marginno_computed_int}.
+% \begin{macrocode}
+\cs_new:Npn\@@_set_xsep_width_style:
+ {
+ \int_case:nn{\l_@@_marginno_computed_int}
+ {
+ {0}
+ {
+ \cs_set_eq:NN\l_@@_xsep_dim
+ \l_@@_xsep_recto_outer_dim
+ \cs_set_eq:NN\l_@@_width_dim
+ \l_@@_width_recto_outer_dim
+ \cs_set_eq:NN\l_@@_style_tl
+ \l_@@_style_recto_outer_tl
+ }
+ {1}
+ {
+ \cs_set_eq:NN\l_@@_xsep_dim
+ \l_@@_xsep_recto_inner_dim
+ \cs_set_eq:NN\l_@@_width_dim
+ \l_@@_width_recto_inner_dim
+ \cs_set_eq:NN\l_@@_style_tl
+ \l_@@_style_recto_inner_tl
+ }
+ {2}
+ {
+ \cs_set_eq:NN\l_@@_xsep_dim
+ \l_@@_xsep_verso_outer_dim
+ \cs_set_eq:NN\l_@@_width_dim
+ \l_@@_width_verso_outer_dim
+ \cs_set_eq:NN\l_@@_style_tl
+ \l_@@_style_verso_outer_tl
+ }
+ {3}
+ {
+ \cs_set_eq:NN\l_@@_xsep_dim
+ \l_@@_xsep_verso_inner_dim
+ \cs_set_eq:NN\l_@@_width_dim
+ \l_@@_width_verso_inner_dim
+ \cs_set_eq:NN\l_@@_style_tl
+ \l_@@_style_verso_inner_tl
+ }
+ {4}
+ {
+ \cs_set_eq:NN\l_@@_xsep_dim
+ \l_@@_xsep_right_between_dim
+ \cs_set_eq:NN\l_@@_width_dim
+ \l_@@_width_right_between_dim
+ \cs_set_eq:NN\l_@@_style_tl
+ \l_@@_style_right_between_tl
+ }
+ {5}
+ {
+ \cs_set_eq:NN\l_@@_xsep_dim
+ \l_@@_xsep_left_between_dim
+ \cs_set_eq:NN\l_@@_width_dim
+ \l_@@_width_left_between_dim
+ \cs_set_eq:NN\l_@@_style_tl
+ \l_@@_style_left_between_tl
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \subsubsection{Auxiliary placement macros}
+%
+% \begin{macro}{\@@_place_item_box:}
+% Place the item that has been set in \cs{l_@@_item_box}, vertically shifted by \cs{l_@@_yshift_computed_dim} and
+% \cs{smash}ed to avoid altering vertical spacing in the main text.
+% \begin{macrocode}
+\cs_new:Npn\@@_place_item_box:
+ {
+ \smash
+ {
+ \box_move_up:nn{\l_@@_yshift_computed_dim}
+ {
+ \box_use:N\l_@@_item_box
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \begin{macro}{
+% \@@_typeset_mmode:n,
+% \@@_typeset_hmmode:n,
+% \@@_typeset_vmode:n,
+% }
+% These three macros handle typsetting in math mode, horizontal mode, and vertical mode. Nothing special needs to be
+% done in math mode. In horizontal mode, \cs{@bsphack}\ldots\cs{@bsphack} avoids double spacing. In vertical mode, a
+% new paragraph containing only a \cs{strut} is started, the item is typeset, the paragraph is ended, and then a
+% vertical skip of \(-\cs{baselineskip}\) should `hide' that invisible paragraph.
+% \begin{macrocode}
+\cs_new:Npn\@@_typeset_mmode:n #1
+ {
+ #1
+ }
+\cs_new:Npn\@@_typeset_hmode:n #1
+ {
+ \@bsphack
+ #1
+ \@esphack
+ }
+\cs_new:Npn\@@_typeset_vmode:n #1
+ {
+ \nobreak\noindent\strut #1\par
+ \skip_vertical:n{-\baselineskip}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \subsection{User commands}
+%
+% Finally, set up the commands for the user.
+%
+% \begin{macro}{\marginalia}
+% This is the main user command for creating a marginal content item. This macro does nothing but hand off to
+% \cs{@@_process_item:nn}.
+% \begin{macrocode}
+\NewDocumentCommand{\marginalia}{ O{} +m }
+ {
+ \@@_process_item:nn{#1}{#2}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \begin{macro}{\marginaliasetup}
+% The user command to set the configuration.
+% \begin{macrocode}
+\NewDocumentCommand{\marginaliasetup}{ m }
+{
+ \keys_set:nn{marginalia}{ #1 }
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \begin{macro}{\marginalianewgeometry}
+% The user command to signal that the page geometry has been changed.
+% \begin{macrocode}
+\NewDocumentCommand{\marginalianewgeometry}{}
+{
+ \@@_write_page_data:
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+%
+%
+%
+LUACODE
+%
+%
+%
+% \clearpage
+% \end{implementation}
Property changes on: branches/branch2024.final/Master/texmf-dist/source/lualatex/marginalia/marginalia.dtx
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: branches/branch2024.final/Master/texmf-dist/source/lualatex/marginalia/marginalia.ins
===================================================================
--- branches/branch2024.final/Master/texmf-dist/source/lualatex/marginalia/marginalia.ins (rev 0)
+++ branches/branch2024.final/Master/texmf-dist/source/lualatex/marginalia/marginalia.ins 2025-02-17 20:48:10 UTC (rev 74070)
@@ -0,0 +1,67 @@
+%%
+%% Copyright (C) 2025 Alan J. Cain
+%%
+%% This file may be distributed and/or modified under the
+%% conditions of the LaTeX Project Public License, either
+%% version 1.3c of this license or (at your option) any later
+%% version. The latest version of this license is in:
+%%
+%% http://www.latex-project.org/lppl.txt
+%%
+%% and version 1.3c or later is part of all distributions of
+%% LaTeX version 2008-05-04 or later.
+%%
+\input l3docstrip.tex
+\askforoverwritefalse
+\nopostamble
+
+
+\preamble
+
+This is a generated file.
+
+Copyright (C) 2025 Alan J. Cain
+
+This file may be distributed and/or modified under the
+conditions of the LaTeX Project Public License, either
+version 1.3c of this license or (at your option) any later
+version. The latest version of this license is in:
+
+http://www.latex-project.org/lppl.txt
+
+and version 1.3c or later is part of all distributions of
+LaTeX version 2008-05-04 or later.
+
+\endpreamble
+
+\generate{\file{marginalia.sty}{\from{marginalia.dtx}{package}}}
+
+\nopreamble
+\generate{\file{marginalia-doc-example.tex}{\from{marginalia.dtx}{example}}}
+
+
+
+\def\MetaPrefix{--}
+
+\preamble
+
+This is a generated file.
+
+Copyright (C) 2025 Alan J. Cain
+
+This file may be distributed and/or modified under the
+conditions of the LaTeX Project Public License, either
+version 1.3c of this license or (at your option) any later
+version. The latest version of this license is in:
+
+http://www.latex-project.org/lppl.txt
+
+and version 1.3c or later is part of all distributions of
+LaTeX version 2008-05-04 or later.
+
+\endpreamble
+
+\generate{\file{marginalia.lua}{\from{marginalia.dtx}{lua}}}
+
+
+\endbatchfile
Added: branches/branch2024.final/Master/texmf-dist/tex/lualatex/marginalia/marginalia.lua
===================================================================
--- branches/branch2024.final/Master/texmf-dist/tex/lualatex/marginalia/marginalia.lua (rev 0)
+++ branches/branch2024.final/Master/texmf-dist/tex/lualatex/marginalia/marginalia.lua 2025-02-17 20:48:10 UTC (rev 74070)
@@ -0,0 +1,23 @@
+--
+-- This is file `marginalia.lua',
+-- generated with the docstrip utility.
+--
+-- The original source files were:
+--
+-- marginalia.dtx (with options: `lua')
+--
+-- This is a generated file.
+--
+-- Copyright (C) 2025 Alan J. Cain
+--
+-- This file may be distributed and/or modified under the
+-- conditions of the LaTeX Project Public License, either
+-- version 1.3c of this license or (at your option) any later
+-- version. The latest version of this license is in:
+--
+-- http://www.latex-project.org/lppl.txt
+--
+-- and version 1.3c or later is part of all distributions of
+-- LaTeX version 2008-05-04 or later.
+--
+LUACODE
Property changes on: branches/branch2024.final/Master/texmf-dist/tex/lualatex/marginalia/marginalia.lua
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: branches/branch2024.final/Master/texmf-dist/tex/lualatex/marginalia/marginalia.sty
===================================================================
--- branches/branch2024.final/Master/texmf-dist/tex/lualatex/marginalia/marginalia.sty (rev 0)
+++ branches/branch2024.final/Master/texmf-dist/tex/lualatex/marginalia/marginalia.sty 2025-02-17 20:48:10 UTC (rev 74070)
@@ -0,0 +1,515 @@
+%%
+%% This is file `marginalia.sty',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% marginalia.dtx (with options: `package')
+%%
+%% This is a generated file.
+%%
+%% Copyright (C) 2025 Alan J. Cain
+%%
+%% This file may be distributed and/or modified under the
+%% conditions of the LaTeX Project Public License, either
+%% version 1.3c of this license or (at your option) any later
+%% version. The latest version of this license is in:
+%%
+%% http://www.latex-project.org/lppl.txt
+%%
+%% and version 1.3c or later is part of all distributions of
+%% LaTeX version 2008-05-04 or later.
+%%
+\NeedsTeXFormat{LaTeX2e}[2020-02-02]
+\ProvidesExplPackage{marginalia}{2025-02-17}{0.80.1}
+ {Non-floating marginal content for LuaLaTeX}
+\sys_if_engine_luatex:F
+ {
+ \msg_new:nnn{marginalia}{lualatex_required}
+ {LuaLaTeX~required.~Package~loading~will~abort.}
+ \msg_critical:nn{marginalia}{lualatex_required}
+ }
+\int_new:N\l__marginalia_type_int
+\keys_define:nn { marginalia }
+{
+ type .choices:nn = {normal,fixed,optfixed}{
+ \int_set:Nn\l__marginalia_type_int{\l_keys_choice_int}
+ },
+ type .initial:n = normal,
+}
+\int_new:N\l__marginalia_pos_int
+\keys_define:nn { marginalia }
+{
+ pos .choices:nn = {auto,reverse,left,right,nearest}{
+ \int_set:Nn\l__marginalia_pos_int{\l_keys_choice_int}
+ },
+ pos .initial:n = auto
+}
+\int_new:N\l__marginalia_column_int
+\keys_define:nn { marginalia }
+{
+ column .choices:nn = {auto,one,left,right}{
+ \int_set:Nn\l__marginalia_column_int{\l_keys_choice_int-2}
+ },
+ column .initial:n = auto,
+}
+\keys_define:nn { marginalia }
+{
+ xsep~recto~outer .dim_set:N = \l__marginalia_xsep_recto_outer_dim,
+ xsep~recto~inner .dim_set:N = \l__marginalia_xsep_recto_inner_dim,
+ xsep~verso~outer .dim_set:N = \l__marginalia_xsep_verso_outer_dim,
+ xsep~verso~inner .dim_set:N = \l__marginalia_xsep_verso_inner_dim,
+ xsep~right~between .dim_set:N = \l__marginalia_xsep_right_between_dim,
+ xsep~left~between .dim_set:N = \l__marginalia_xsep_left_between_dim,
+ xsep .code:n = {
+ \keys_set:nn{ marginalia }{
+ xsep~recto~outer=#1,
+ xsep~recto~inner=#1,
+ xsep~verso~outer=#1,
+ xsep~verso~inner=#1,
+ xsep~right~between=#1,
+ xsep~left~between=#1,
+ }
+ },
+ xsep~outer .code:n = {
+ \keys_set:nn{ marginalia }{
+ xsep~recto~outer=#1,
+ xsep~verso~outer=#1,
+ }
+ },
+ xsep~inner .code:n = {
+ \keys_set:nn{ marginalia }{
+ xsep~recto~inner=#1,
+ xsep~verso~inner=#1,
+ }
+ },
+ xsep~between .code:n = {
+ \keys_set:nn{ marginalia }{
+ xsep~right~between=#1,
+ xsep~left~between=#1,
+ }
+ },
+ xsep .initial:n = \marginparsep,
+}
+\int_new:N\l__marginalia_valign_int
+\keys_define:nn { marginalia }
+{
+ valign .choices:nn = {t,b}{
+ \int_set_eq:NN\l__marginalia_valign_int\l_keys_choice_int
+ },
+ valign .initial:n = t,
+}
+\keys_define:nn { marginalia }
+{
+ yshift .dim_set:N = \l__marginalia_default_yshift_dim,
+ yshift .initial:n = 0pt,
+}
+\keys_define:nn { marginalia }
+{
+ ysep~above .dim_set:N = \l__marginalia_ysep_above_dim,
+ ysep~below .dim_set:N = \l__marginalia_ysep_below_dim,
+ ysep~page~top .dim_set:N = \l__marginalia_ysep_page_top_dim,
+ ysep~page~bottom .dim_set:N = \l__marginalia_ysep_page_bottom_dim,
+ ysep .code:n = {
+ \keys_set:nn{ marginalia }{
+ ysep~below=#1,
+ ysep~above=#1,
+ ysep~page~top=#1,
+ ysep~page~bottom=#1,
+ }
+ },
+ ysep .initial:n = \marginparpush,
+}
+\keys_define:nn { marginalia }
+{
+ width~recto~outer .dim_set:N = \l__marginalia_width_recto_outer_dim,
+ width~recto~inner .dim_set:N = \l__marginalia_width_recto_inner_dim,
+ width~verso~outer .dim_set:N = \l__marginalia_width_verso_outer_dim,
+ width~verso~inner .dim_set:N = \l__marginalia_width_verso_inner_dim,
+ width~right~between .dim_set:N = \l__marginalia_width_right_between_dim,
+ width~left~between .dim_set:N = \l__marginalia_width_left_between_dim,
+ width .code:n = {
+ \keys_set:nn{ marginalia }{
+ width~recto~outer=#1,
+ width~recto~inner=#1,
+ width~verso~outer=#1,
+ width~verso~inner=#1,
+ width~right~between=#1,
+ width~left~between=#1,
+ }
+ },
+ width~outer .code:n = {
+ \keys_set:nn{ marginalia }{
+ width~recto~outer=#1,
+ width~verso~outer=#1,
+ }
+ },
+ width~inner .code:n = {
+ \keys_set:nn{ marginalia }{
+ width~recto~inner=#1,
+ width~verso~inner=#1,
+ }
+ },
+ width~between .code:n = {
+ \keys_set:nn{ marginalia }{
+ width~right~between=#1,
+ width~left~between=#1,
+ }
+ },
+ width .initial:n = \marginparwidth,
+}
+%% \begin{macro}{
+\keys_define:nn { marginalia }
+{
+ style~recto~outer .tl_set:N = \l__marginalia_style_recto_outer_tl,
+ style~recto~inner .tl_set:N = \l__marginalia_style_recto_inner_tl,
+ style~verso~outer .tl_set:N = \l__marginalia_style_verso_outer_tl,
+ style~verso~inner .tl_set:N = \l__marginalia_style_verso_inner_tl,
+ style~right~between .tl_set:N = \l__marginalia_style_right_between_tl,
+ style~left~between .tl_set:N = \l__marginalia_style_left_between_tl,
+ style .code:n = {
+ \keys_set:nn{ marginalia }{
+ style~recto~outer=#1,
+ style~recto~inner=#1,
+ style~verso~outer=#1,
+ style~verso~inner=#1,
+ style~right~between=#1,
+ style~left~between=#1,
+ }
+ },
+ style .initial:n = {},
+}
+ \lua_now:n{
+ marginalia = require('marginalia')
+ }
+\cs_new:Npn\__marginalia_lua_store_default_page_data:
+ {
+ \lua_now:n{ marginalia.store_default_page_data() }
+ }
+\cs_new:Npn\__marginalia_lua_store_page_data:n #1
+ {
+ \lua_now:n{ marginalia.store_page_data('#1') }
+ }
+\cs_new:Npn\__marginalia_lua_check_page_data:n #1
+ {
+ \lua_now:n{ marginalia.check_page_data('#1') }
+ }
+\cs_new:Npn\__marginalia_lua_write_page_change_report:
+ {
+ \lua_now:n{ marginalia.write_page_change_report() }
+ }
+\cs_new:Npn\__marginalia_lua_store_item_data:n #1
+ {
+ \lua_now:n{ marginalia.store_item_data('#1') }
+ }
+\cs_new:Npn\__marginalia_lua_check_item_data:n #1
+ {
+ \lua_now:n{ marginalia.check_item_data('#1') }
+ }
+\cs_new:Npn\__marginalia_lua_compute_items:
+ {
+ \lua_now:n{ marginalia.compute_items() }
+ }
+\cs_new:Npn\__marginalia_lua_write_problem_report:
+ {
+ \lua_now:n{ marginalia.write_problem_report() }
+ }
+\cs_new:Npn\__marginalia_lua_write_item_change_report:
+ {
+ \lua_now:n{ marginalia.write_item_change_report() }
+ }
+\cs_new:Npn\__marginalia_lua_load_item_data:n #1
+ {
+ \lua_now:e{ marginalia.load_item_data('#1') }
+ }
+\NewDocumentCommand{\marginalia at pagedata}{ m }{
+ \__marginalia_process_page_data:n{#1}
+}
+\cs_set_eq:NN
+ \__marginalia_process_page_data:n
+ \__marginalia_lua_store_page_data:n
+\DeclareDocumentCommand{\marginalia at itemdata}{ m }{
+ \__marginalia_process_item_data:n{#1}
+}
+\cs_set_eq:NN
+ \__marginalia_process_item_data:n
+ \__marginalia_lua_store_item_data:n
+\AddToHook{begindocument}{
+ \__marginalia_lua_store_default_page_data:
+ \__marginalia_lua_compute_items:
+ \cs_set_eq:NN\l__marginalia_aux_iow\@mainaux
+}
+\AddToHook{enddocument/afterlastpage}{
+ \cs_set_eq:NN
+ \__marginalia_process_page_data:n
+ \__marginalia_lua_check_page_data:n
+ \cs_set_eq:NN
+ \__marginalia_process_item_data:n
+ \__marginalia_lua_check_item_data:n
+ }
+\msg_new:nnn{marginalia}{placement_problem}
+ { Problems~in~placement.~#1 }
+\msg_new:nnn{marginalia}{item_change}
+ { Changes~in~item~data.~#1 }
+\msg_new:nnn{marginalia}{page_change}
+ { Changes~in~page~data.~#1 }
+\cs_new:Npn\__marginalia_write_reports:
+ {
+ \group_begin:
+ \tl_set:Ne\l_tmpa_tl{\__marginalia_lua_write_problem_report:}
+ \tl_if_blank:VF\l_tmpa_tl
+ {
+ \msg_warning:nne{marginalia}{placement_problem}{\tl_use:N\l_tmpa_tl}
+ }
+ \tl_set:Ne\l_tmpa_tl{\__marginalia_lua_write_item_change_report:}
+ \tl_if_blank:VF\l_tmpa_tl
+ {
+ \msg_warning:nne{marginalia}{item_change}{\tl_use:N\l_tmpa_tl}
+ }
+ \tl_set:Ne\l_tmpa_tl{\__marginalia_lua_write_page_change_report:}
+ \tl_if_blank:VF\l_tmpa_tl
+ {
+ \msg_warning:nne{marginalia}{page_change}{\tl_use:N\l_tmpa_tl}
+ }
+ \group_end:
+ }
+\AddToHook{enddocument/info}{
+ \__marginalia_write_reports:
+}
+\int_new:N\g__marginalia_pagedatano_int
+\cs_set_eq:NN\__marginalia_write_page_data:\prg_do_nothing:
+\cs_new:Npn\__marginalia_write_page_data_real:
+ {
+ \int_gincr:N\g__marginalia_pagedatano_int
+ \iow_now:Ne\l__marginalia_aux_iow{
+ \token_to_str:N\marginalia at pagedata{
+ pagedatano=\int_value:w\g__marginalia_pagedatano_int,
+ abspageno=\int_eval:n{\g_shipout_readonly_int+1},
+ hoffset=\int_value:w\hoffset,
+ voffset=\int_value:w\voffset,
+ paperheight=\int_value:w\paperheight,
+ oddsidemargin=\int_value:w\oddsidemargin,
+ evensidemargin=\int_value:w\evensidemargin,
+ textwidth=\int_value:w\textwidth,
+ columncount=\int_value:w\col at number,
+ columnwidth=\int_value:w\columnwidth,
+ columnsep=\int_value:w\columnsep,
+ twoside=\bool_to_str:n{\legacy_if_p:n{@twoside}},
+ }
+ }
+ }
+\AddToHook{begindocument/end}
+ {
+ \cs_set_eq:NN
+ \__marginalia_write_page_data:
+ \__marginalia_write_page_data_real:
+ \__marginalia_write_page_data:
+ }
+\int_new:N\g__marginalia_itemno_int
+\box_new:N\l__marginalia_item_box
+\dim_new:N\l__marginalia_item_height_dim
+\dim_new:N\l__marginalia_item_depth_dim
+\int_new:N\l__marginalia_page_int
+\int_new:N\l__marginalia_column_computed_int
+\dim_new:N\l__marginalia_xshift_computed_dim
+\dim_new:N\l__marginalia_yshift_computed_dim
+\int_new:N\l__marginalia_side_computed_int
+\int_new:N\l__marginalia_marginno_computed_int
+\int_new:N\l__marginalia_enabled_computed_int
+\cs_new:Npn\__marginalia_process_item:nn #1#2
+ {
+ \int_gincr:N\g__marginalia_itemno_int
+ \group_begin:
+ \keys_set:nn{marginalia}{ #1 }
+ \__marginalia_lua_load_item_data:n
+ { \int_value:w\g__marginalia_itemno_int }
+ \mode_if_math:TF
+ {
+ \cs_set_eq:NN
+ \__marginalia_typeset:n
+ \__marginalia_typeset_mmode:n
+ }
+ {
+ \legacy_if:nT{@inlabel}
+ { \leavevmode }
+ \mode_if_horizontal:TF
+ {
+ \cs_set_eq:NN
+ \__marginalia_typeset:n
+ \__marginalia_typeset_hmode:n
+ }
+ {
+ \cs_set_eq:NN
+ \__marginalia_typeset:n
+ \__marginalia_typeset_vmode:n
+ }
+ }
+ \int_compare:nNnTF{\l__marginalia_valign_int}={2}
+ {
+ \cs_set_eq:NN\__marginalia_item_box_set:Nn\vbox_set:Nn
+ }
+ {
+ \cs_set_eq:NN\__marginalia_item_box_set:Nn\vbox_set_top:Nn
+ }
+ \__marginalia_set_xsep_width_style:
+ \__marginalia_item_box_set:Nn\l__marginalia_item_box{
+ \@parboxrestore
+ \normalfont\normalsize
+
+ \tl_use:N\l__marginalia_style_tl
+ \dim_set_eq:NN\hsize\l__marginalia_width_dim
+ \dim_set_eq:NN\linewidth\hsize
+
+ \cs_set_eq:NN\marginaliapage\l__marginalia_page_int
+ \cs_set_eq:NN\marginaliacolumn\l__marginalia_column_computed_int
+
+ \group_begin:
+ \ignorespaces
+ #2
+ \par
+ \group_end:
+ }
+ \dim_set:Nn\l__marginalia_item_height_dim
+ {\box_ht:N\l__marginalia_item_box}
+ \dim_set:Nn\l__marginalia_item_depth_dim
+ {\box_dp:N\l__marginalia_item_box}
+ \__marginalia_typeset:n{
+ \savepos
+ \iow_shipout_e:Ne\l__marginalia_aux_iow{
+ \token_to_str:N\marginalia at itemdata{
+ itemno=\int_value:w\g__marginalia_itemno_int,
+ abspageno=\exp_not:N\int_eval:n{\g_shipout_readonly_int},
+ pageno=\exp_not:N\int_value:w\c at page,
+ type=\str_use:N\int_value:w\l__marginalia_type_int,
+ xpos=\exp_not:N\int_value:w\lastxpos,
+ ypos=\exp_not:N\int_value:w\lastypos,
+ height=\int_value:w\l__marginalia_item_height_dim,
+ depth=\int_value:w\l__marginalia_item_depth_dim,
+ pos=\int_value:w\l__marginalia_pos_int,
+ column=\int_value:w\l__marginalia_column_int,
+ yshift=\int_value:w\l__marginalia_default_yshift_dim,
+ ysep~above=\int_value:w\l__marginalia_ysep_above_dim,
+ ysep~below=\int_value:w\l__marginalia_ysep_below_dim,
+ ysep~page~top=\int_value:w\l__marginalia_ysep_page_top_dim,
+ ysep~page~bottom=\int_value:w\l__marginalia_ysep_page_bottom_dim,
+ }
+ }
+ \int_if_zero:nF{\l__marginalia_enabled_computed_int}
+ {
+ \int_if_zero:nTF{\l__marginalia_side_computed_int}
+ {
+ \rlap{
+ \kern\l__marginalia_xshift_computed_dim
+ \kern\l__marginalia_xsep_dim
+ \__marginalia_place_item_box:
+ }
+ }
+ {
+ \llap{
+ \__marginalia_place_item_box:
+ \kern\l__marginalia_xsep_dim
+ \kern-\l__marginalia_xshift_computed_dim
+ }
+ }
+ }
+ }
+ \group_end:
+ }
+\cs_new:Npn\__marginalia_set_xsep_width_style:
+ {
+ \int_case:nn{\l__marginalia_marginno_computed_int}
+ {
+ {0}
+ {
+ \cs_set_eq:NN\l__marginalia_xsep_dim
+ \l__marginalia_xsep_recto_outer_dim
+ \cs_set_eq:NN\l__marginalia_width_dim
+ \l__marginalia_width_recto_outer_dim
+ \cs_set_eq:NN\l__marginalia_style_tl
+ \l__marginalia_style_recto_outer_tl
+ }
+ {1}
+ {
+ \cs_set_eq:NN\l__marginalia_xsep_dim
+ \l__marginalia_xsep_recto_inner_dim
+ \cs_set_eq:NN\l__marginalia_width_dim
+ \l__marginalia_width_recto_inner_dim
+ \cs_set_eq:NN\l__marginalia_style_tl
+ \l__marginalia_style_recto_inner_tl
+ }
+ {2}
+ {
+ \cs_set_eq:NN\l__marginalia_xsep_dim
+ \l__marginalia_xsep_verso_outer_dim
+ \cs_set_eq:NN\l__marginalia_width_dim
+ \l__marginalia_width_verso_outer_dim
+ \cs_set_eq:NN\l__marginalia_style_tl
+ \l__marginalia_style_verso_outer_tl
+ }
+ {3}
+ {
+ \cs_set_eq:NN\l__marginalia_xsep_dim
+ \l__marginalia_xsep_verso_inner_dim
+ \cs_set_eq:NN\l__marginalia_width_dim
+ \l__marginalia_width_verso_inner_dim
+ \cs_set_eq:NN\l__marginalia_style_tl
+ \l__marginalia_style_verso_inner_tl
+ }
+ {4}
+ {
+ \cs_set_eq:NN\l__marginalia_xsep_dim
+ \l__marginalia_xsep_right_between_dim
+ \cs_set_eq:NN\l__marginalia_width_dim
+ \l__marginalia_width_right_between_dim
+ \cs_set_eq:NN\l__marginalia_style_tl
+ \l__marginalia_style_right_between_tl
+ }
+ {5}
+ {
+ \cs_set_eq:NN\l__marginalia_xsep_dim
+ \l__marginalia_xsep_left_between_dim
+ \cs_set_eq:NN\l__marginalia_width_dim
+ \l__marginalia_width_left_between_dim
+ \cs_set_eq:NN\l__marginalia_style_tl
+ \l__marginalia_style_left_between_tl
+ }
+ }
+ }
+\cs_new:Npn\__marginalia_place_item_box:
+ {
+ \smash
+ {
+ \box_move_up:nn{\l__marginalia_yshift_computed_dim}
+ {
+ \box_use:N\l__marginalia_item_box
+ }
+ }
+ }
+\cs_new:Npn\__marginalia_typeset_mmode:n #1
+ {
+ #1
+ }
+\cs_new:Npn\__marginalia_typeset_hmode:n #1
+ {
+ \@bsphack
+ #1
+ \@esphack
+ }
+\cs_new:Npn\__marginalia_typeset_vmode:n #1
+ {
+ \nobreak\noindent\strut #1\par
+ \skip_vertical:n{-\baselineskip}
+ }
+\NewDocumentCommand{\marginalia}{ O{} +m }
+ {
+ \__marginalia_process_item:nn{#1}{#2}
+ }
+\NewDocumentCommand{\marginaliasetup}{ m }
+{
+ \keys_set:nn{marginalia}{ #1 }
+}
+\NewDocumentCommand{\marginalianewgeometry}{}
+{
+ \__marginalia_write_page_data:
+}
+LUACODE
Property changes on: branches/branch2024.final/Master/texmf-dist/tex/lualatex/marginalia/marginalia.sty
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Modified: branches/branch2024.final/Master/tlpkg/tlpsrc/collection-luatex.tlpsrc
===================================================================
--- branches/branch2024.final/Master/tlpkg/tlpsrc/collection-luatex.tlpsrc 2025-02-17 20:47:38 UTC (rev 74069)
+++ branches/branch2024.final/Master/tlpkg/tlpsrc/collection-luatex.tlpsrc 2025-02-17 20:48:10 UTC (rev 74070)
@@ -82,6 +82,7 @@
depend luavlna
depend luaxml
depend lutabulartools
+depend marginalia
depend minim
depend minim-math
depend minim-mp
Added: branches/branch2024.final/Master/tlpkg/tlpsrc/marginalia.tlpsrc
===================================================================
More information about the tex-live-commits
mailing list.