%\iffalse meta-comment
% ======================================================================
% marginnote.dtx
% Copyright © 2005—2026 Markus Kohm
%
% This file is part of the work marginnote.
%
% This work may be distributed and/or modified under the conditions of
% the LaTeX Project Public License, version 1.3c of the license.
% 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 2005/12/01 or later and of this work.
%
% This work has the LPPL maintenance status "unmaintained".
% If you want to become the new maintainer please contact the author.
%
% This work consists of the files marginnote.dtx, README.md,
% LICENSE.md, and optionally the unpacked files marginnote.pdf and
% and marginnote.sty.
% ----------------------------------------------------------------------
% Note: This file is not only the source but also the docstrip batch
%       file.  To unpack marginnote.sty from the source, run:
%
%         tex marginnote.dtx
%
%       as usual.  You can replace tex by pdftex, luatex or xetex.
%       Usage of latex, pdflatex, lualatex or xelatex produces the
%       manual marginnote.pdf.
% ======================================================================
%
%<*dtx>
\ifx\ProvidesFile\undefined\def\ProvidesFile#1[#2]{}\fi
\ProvidesFile{marginnote.dtx}[%
%</dtx>
%<package>\NeedsTeXFormat{LaTeX2e}[2025/06/01]
%<package>\ProvidesPackage{marginnote}[%
%<*package|dtx>
  2026-06-15 1.5 non floating margin notes for LaTeX
%<*dtx>
  (source + documentation)
%</dtx>
]
%</package|dtx>
%<*dtx>
\ifx\documentclass\undefined
  \input docstrip.tex

  \keepsilent
  \askforoverwritefalse
  \usedir{tex/latex/marginnote}

  \generate{%
    \file{marginnote.sty}{\from{marginnote.dtx}{package}}%
  }

  \ifToplevel{%
    \Msg{*********************************************************************}
    \Msg{*}
    \Msg{* marginnote}
    \Msg{* ==========}
    \Msg{*}
    \Msg{* To finish the installation run}
    \Msg{* \space\space pdflatex marginnote.dtx}
    \Msg{* \space\space mkindex marginnote}
    \Msg{* \space\space pdflatex marginnote.dtx}
    \Msg{* \space\space mkindex marginnote}
    \Msg{* \space\space pdflatex marginnote.dtx}
    \Msg{* After this copy}
    \Msg{* \space\space marginnote.sty to .../tex/latex/marginnote/}
    \Msg{* \space\space marginnote.pdf to .../doc/latex/marginnote/}
    \Msg{* \space\space marginnote.dtx to .../source/latex/marginnote/}
    \Msg{* \space\space README.md
      \space\space\space\space\space to 
      .../doc/latex/marginnote/}
    \Msg{* \space\space LICENSE.md
      \space\space\space\space to 
      .../doc/latex/marginnote/}
    \Msg{* where .../ is your local TDS tree}
    \Msg{*}
    \Msg{*********************************************************************}
  }
\else
  \let\endbatchfile\relax
\fi
\endbatchfile
\documentclass{ltxdoc}
\usepackage{hvlogos}
\usepackage{marginnote}
\CodelineIndex
\RecordChanges
\begin{document}
\DocInput{marginnote.dtx}
\end{document}
%</dtx>
%\fi
%
% \GetFileInfo{marginnote.sty}
% \let\pkgversion\fileversion
% \let\pkgdate\filedate
% \GetFileInfo{marginnote.dtx}
%
% \title{Non-Floating Margin Notes with \textsf{marginnote}
%   Package\thanks{This file has version \fileversion, last revised
%     \filedate. \textsf{marginnote} is version \pkgversion, last revised
%     \pkgdate.}}
% \author{Markus Kohm \textcolor{red}{(inactive)}\thanks{From version 1.4b the
%     package is unmaintained. But there is a public repository with issue
%     tracker at \url{https://codeberg.org/komascript/marginnote/issues}. So
%     everybody can contribute and reported issues will not be lost, if a new
%     maintainer will be found.}%
%     \thanks{Support for tagging was added by Ulrike Fischer in version 1.4e
%     on June 13, 2026.}%
%   }
% \maketitle
%
% \begin{abstract}
%   In \LaTeX{} the command \cs{marginpar}\oarg{left}\marg{right} can be used
%   to create a note in the margin. But there is a problem with this command:
%   It creates a special kind of float. So it cannot be used on floats or
%   footnotes. The \textsl{marginnote} package supports another command
%   \cs{marginnote} to create notes in the margin. This does not use any kind
%   of float and therefore does not have the disadvantage of
%   \cs{marginpar}. But there may be other problems \dots
% \end{abstract}
%
% \tableofcontents
%
% \changes{v1.0b}{2006/14/03}{spelling fixes}
% \changes{v1.2b}{2017/10/14}{spelling fixes (by Thomas Reuben)}
% \changes{v1.4c}{2023/09/07}{some documentation corrections only}
% \changes{v1.4e}{2026/06/13}{added tagging support}
% \section{How to Use \textsf{marginnote} Package}
%
% First of all you have to load the package. You can use:
% \begin{verbatim}
% \usepackage{marginnote}
% \end{verbatim}\vskip-\baselineskip
% to do so. You can also use one of the following options to globally change
% the behaviour of \textsf{marginnote}:
% \begin{description}
% \item[\texttt{fulladjust}] adjusts the margin note to the height and depth
%   of the current line. Note that this may sometimes add an extra height and
%   depth to the current line, but gives the best vertical alignment. This is
%   the default.
% \item[\texttt{heightadjust}] adjusts the margin note to the height of the
%   current line, but not the depth. Note that this can sometimes result in
%   extra height and vertical offset of the current line.
% \item[\texttt{depthadjust}] adjusts the margin note to the depth of the
%   current line, but not the height. Note that this can sometimes result in
%   extra depth and vertical offset of the current line.
% \item[\texttt{noadjust}] does not adjust the margin note to the height or
%   depth of the current line. line. Note that this often results in vertical
%   offsets, but rarely in vertical extra space before or after the current
%   line.
% \item[\texttt{parboxrestore}] uses a reduced \cs{@parboxrestore} to restore
%   the definition of \cs{par} and \cmd\\ and some other commands, and sets
%   \cs{parindent} to 0, \cs{parfillskip} to 0\,pt plus 1\,fil and
%   \cs{lineskip} to \cs{normallineskip}, \cs{baselineskip} to
%   \cs{normalbaselineskip} and enables \cs{sloppy} for every margin
%   note. This is the default since the 1.4b release of
%   \textsf{marginnote}. Release 1.4 and 1.4a also set \cs{parskip} to 0, but
%   this caused a vertical placement problem, e.g., inside lists like
%   \texttt{itemize}.
% \item[\texttt{noparboxrestore}] does not restore any definition for the
%   margin notes. This was the behaviour before the 1.4 release.
% \end{description}
%
% \DescribeMacro{\marginnote}
% The command \cs{marginnote}\oarg{left}\marg{right}\oarg{voffset} can be used
% to set a margin note using the \textsf{marginnote} package. The first
% optional argument and the mandatory argument are the same as for
% \cs{marginpar} from the \LaTeX{} kernel. Even \cs{reversemarginpar} is taken
% into account. The note \meta{left} or \meta{right} is set to the current
% vertical position. The second optional argument \meta{voffset} can be used
% to adjust the vertical position of the margin note. Use a negative dimension
% to move it up or a positive dimension to move it down.
%
% \DescribeMacro{\marginnotetextwidth}
% The \textsl{marginnote} package needs to know the real width of the text
% area to find the right margin. While some environments (e.g., of the
% \textsl{framed} package) change \cs{textwidth}, \textsl{marginnote} defines
% its own text width macro. If you change the text area after
% \cs{begin\{document\}} you should add
% \begin{verbatim}
%   \edef\marginnotetextwidth{\the\textwidth}
% \end{verbatim}\vskip-\baselineskip
% after changing the text area. You may want to do this globally using
% \verb|\xdef| instead of \verb|\edef|. Most users will never need to change
% \cs{marginnotetextwidth}.
%
% \DescribeMacro{\marginnotevadjust}
% In some environments the vertical adjustment of the margin note is
% incorrect, e.g., one baseline too low. In this case, you can use the
% additional optional argument of \cs{marginnote} each time \cs{marginnote} is
% used, or redefine \cs{marginnotevadjust} at the beginning of the
% environment. The default definition is \texttt{0pt}.
%
% \DescribeMacro{\raggedleftmarginnote}
% \DescribeMacro{\raggedrightmarginnote}
% These macros define how the margin note is aligned. The defaults are
% \begin{itemize}
% \item align margin notes at the left margin right to the margin,
% \item align margin notes at the right margin left to the margin.
% \end{itemize}
% You can change this using \cs{renewcommand}, e.g., use^^A
% \changes{v1.0a}{2006/02/06}{Example to macros \cs{raggedleftmarginnote} and
%   \cs{raggedrightmarginnote} at documentation fixed [thanks to Susumu
%   Tanimura].}
% \begin{verbatim}
% \renewcommand*{\raggedleftmarginnote}{}
% \renewcommand*{\raggedrightmarginnote}{\centering}
% \end{verbatim}\vskip-\baselineskip
% to get justified text on the left and centered text on the right margin.
%
% \DescribeMacro{\marginfont}
% This macro sets the font to be used for margin notes. The
% default is \cs{normalcolor}. You may can \cs{renewcommand} to change this,
% e.g., use
% \begin{verbatim}
% \renewcommand*{\marginfont}{\color{red}\sffamily}
% \end{verbatim}\vskip-\baselineskip
% to get red colored margin notes in the sans serif font family. Don't forget:
% You need to load the \textsf{color} package or the \textsf{xcolor} package
% to use \cs{color}.
%
%
% \section{Issues Using \textsf{marginnote}}
%
% Some known issues are listed below. For new issues, it is recommended to
% either discuss them in a public \LaTeX{} forum or report them in
% \href{https://codeberg.org/komascript/marginnote}{the project's} issue
% tracker on Codeberg.
% \begin{itemize}
% \item Currently, the package lacks a new maintainer. The author no longer
%   maintains the package anymore, as it was originally intended to be used as
%   a small hack for for a few cases. But over the years it has grown and
%   become a conglomerate of of hacks that hack hacks that are very widely
%   used. A break with a complete overhaul of the design would be
%   necessary. But nothing I can or want to do at the moment. If you want to
%   do it, please \href{email:komascript@gmx.info}{contact the
%   author}. But even without taking over maintenance, you can contribute,
%   e.g. by participating in the issue tracker of the package.
% \item You cannot use paragraphs with \cs{par} or empty lines inside a margin
%   note. In my opinion this would note make sense. However, if you really
%   need paragraphs you can try using \cs{endgraf} instead of \cs{par}.
% \item From version 1.4a, a workaround is available for double-sided
%   documents with consecutive odd or even pages. However, it is not advisable
%   to use double-sided documents with such page sequences as printing such
%   documents can be problematic. The \textsf{marginnote} package displays a
%   warning message whenever it detects those page sequences.
% \item From version 1.3, the \texttt{marginnote} package no longer support
%   \TeX{} engines that lack primitives \cs{pdfsavepos} and \cs{pdflastxpos},
%   or \cs{savepos} and \cs{lastxpos}. The previous fallback option for manual
%   adjustment has been removed. You will receive an error message if you try
%   to use a \TeX{} engine without these primitives, and $\varepsilon$-\TeX{}
%   primitves are also required. Nonetheless, this should not be an issue with
%   current, free \TeX{} distributions like MiK\TeX{} or \TeX Live.
% \item When using double-side layout, such as with using the \texttt{twoside}
%   class option, \cs{marginnote} requires page number information to
%   determine if a page is odd or even, and therefore wich margin to
%   use\,---\,left or right. \LaTeX{} operates using asynchronous
%   output. Because of this, the counter \texttt{page} should not be used to
%   obtain the current page number, unless at the header or footer of the
%   page. To resolve the issue, the \textsf{marginnote} package employs a
%   mechanism akin to labels. However, this implies that the accurate margin
%   will not be determined during this \LaTeX{} run, but in the
%   next. Therefore, after making any changes to the margin notes or page
%   breaks, two \LaTeX{} runs are necessary to ensure all margins are correct.
% \item The \cs{marginnote} command utilizes \cs{strut} and \cs{vadjust} to
%   position the margin note accurately. However, it may fail under certain
%   circumstances. You may adjust the vertical position of the margin note
%   using the second optional argument of \cs{marginnote}. Sometimes, the use
%   of \cs{marginnote} command can cause the text outside to shift
%   unnecessarily.  You can choose from the package options
%   \texttt{fulladjust}, \texttt{heightadjust}, \texttt{depthajust}, or
%   \texttt{noajust} to globally adjust, or locally redefine |\mn@strut| or
%   |\mn@zbox|.
% 
%   Note: The margin note always will be placed at the current vertical
%   line. This means, if you are using two \cs{marginnote} commands at the
%   same line, they will be put on the same place. This is not a bug but a
%   feature!
% \item From version~1.1b, \cs{marginnote} commands inserted between
%   paragraphs (or in \TeX terms: \emph{in vertical mode}) will result in the
%   note being placed between the paragraphs instead of at the end of the
%   preceding paragraph. You may use \cs{leavevmode} or the third optional
%   argument of \cs{marginnote} to place it differently.
% \item No page break can occur within a margin note created using the
%   \cs{marginnote} command.
% \item The use of \cs{marginnote} immediately after \cs{item} results in a
%   different behavior compared to \cs{marginpar}. This is not a bug, but
%   rather a deliberate feature!
% \item With math, using the \cs{marginnote} command may work or not work,
%   depending on the math environment.
% \item If the horizontal position of the margin note is not correct, try
%   another \LaTeX{} run.
% \item Sometimes lines may stretch vertically when using \cs{marginnote},
%   particularly if you use \cs{marginnote} within a list \emph{and} upper
%   case umlauts like ``\"U'', or if you have \verb|\lineskiplimit>0pt|. To
%   resolve this issue, you can set \verb|\lineskiplimit=0pt| or
%   \verb|\lineskiplimit=-\maxdimen| or use other available package options.
% \item You should not use \cs{marginnote} within the optional argument of
%   \cs{item}.
% \item If \cs{if@twocolumn} is \cs{iftrue}, e.g., because you are using the
%   |twocolumn| class option or the |\twocolumn| command, \cs{marginnote}
%   decides whether the note should be placed to the left or right the columns
%   by comparing the current horizontal position with \emph{left
%   margin}|+\columnwidth+.5\columnsep|. If the current horizontal position is
%   somewhere on the left column, the note is placed in the left margin. If
%   the current horizontal position is somewhere right of the left column and
%   therefore on the right column, the note is placed in the right
%   margin. However, supporting twocolumn mode is as problematic as supporting
%   reverse margin notes. It is not preferred. It may be revised in the
%   future. The current support for twocolumn mode has only been implemented
%   due to a feature request from Florent Chervet.
% \end{itemize}
% 
% \StopEventually{\PrintIndex\PrintChanges}
%
% \section{Implementation}
%
% \iffalse
%<*package>
% \fi
%
% \changes{v1.3}{2018/04/13}{$\varepsilon$-\TeX{} removed}
% \changes{v1.3}{2018/04/13}{early \cs{pdfsavepos}/\cs{savepos} test}
%
% \begin{macro}{\mn@savepos}
% \changes{v1.3}{2018/04/13}{new internal command}
% \begin{macro}{\mn@lastxpos}
% \changes{v1.3}{2018/04/13}{new internal command}
% Since version 1.3 \texttt{marginnote} does need either \cs{pdfsavepos} and
% \cs{pdflastxpos} or \cs{savepos} and \cs{lastxpos} and does not longer
% support engines without these primitives. All these engines also provide
% $\varepsilon$-\TeX{} extensions. So we do not longer need an explicite
% $\varepsilon$-\TeX{} test.
%    \begin{macrocode}
\begingroup
  \@ifundefined{pdfsavepos}{%
    \@ifundefined{savepos}{%
      \PackageError{marginnote}{%
        neither \string\pdfsavepos\space nor \string\savepos\space
        available
      }{%
        Package `marginnote' depends on extended features of
        PDFLaTeX,\MessageBreak
        LuaLaTeX or XeLaTeX. It does not work without those
        feature.\MessageBreak
        If you'd continue the package will not provide any feature.
      }%
      \aftergroup\endinput
    }{%
      \@ifundefined{lastxpos}{%
        \PackageError{marginnote}{%
          \string\savepos\space but not \string\lastxpos\space
          available
        }{%
          Package `marginnote' depends on extended features of
          PDFLaTeX,\MessageBreak
          LuaLaTeX or XeLaTeX. It does not work without those
          feature.\MessageBreak
          If you'd continue the package will not provide any feature.
        }%
        \aftergroup\endinput
      }{%
        \global\let\mn@savepos\savepos
        \global\let\mn@lastxpos\lastxpos
        \global\let\mn@pagewidth\pagewidth
      }%
    }%
  }{%
    \@ifundefined{pdflastxpos}{%
      \PackageError{marginnote}{%
        \string\pdfsavepos\space but not \string\pdflastxpos\space
        available
      }{%
        Package `marginnote' depends on extended features of
        PDFLaTeX,\MessageBreak
        LuaLaTeX or XeLaTeX. It does not work without those
        feature.\MessageBreak
        If you'd continue the package will not provide any feature.
      }%
      \aftergroup\endinput
    }{%
      \global\let\mn@savepos\pdfsavepos
      \global\let\mn@lastxpos\pdflastxpos
      \global\let\mn@pagewidth\pdfpagewidth
    }%
  }%
\endgroup
%    \end{macrocode}
% \end{macro}
% \end{macro}
% 
% Next declare and process the options.
%
% \begin{macro}{\if@mn@verbose}
% Use verbose output mode by default. But you may change this using option
% \texttt{quiet}.
%    \begin{macrocode}
\newif\if@mn@verbose\@mn@verbosetrue
\DeclareOption{verbose}{\@mn@verbosetrue}
\DeclareOption{quiet}{\@mn@verbosefalse}
%    \end{macrocode}
% \end{macro}
%
% \changes{v1.1e}{2009/06/06}{new options \texttt{fulladjust},
%   \texttt{heightadjust}, \texttt{depthadjust}, and \texttt{noadjust}}
% \begin{macro}{\mn@strut}
% \changes{v1.1e}{2009/06/06}{new (semi internal)}
% The package needs to adjust the margin note at the current line. Sometimes
% this causes extra vertical line spacing. To avoid this you may redefine
% \cs{mn@strut}. The default value is \cs{strut}.
%    \begin{macrocode}
\newcommand*{\mn@strut}{}
%    \end{macrocode}
% \begin{macro}{\mn@zbox}
%   \changes{v1.1b}{2009/02/16}{new (internal)}
%   \changes{v1.4e}{2026-06-13}{Avoid execution of para hooks.}
% This macro is used to set a horizontal box without height, depth and width.
%    \begin{macrocode}
\newcommand{\mn@zbox}[1]{}
%    \end{macrocode}
% The options do redefine both, \cs{mn@strut} and \cs{mn@zbox}.
%    \begin{macrocode}
\DeclareOption{fulladjust}{%
  \renewcommand*{\mn@strut}{\strut}%
  \renewcommand{\mn@zbox}[1]{%
    \bgroup
%    \end{macrocode}
% Avoid the execution of the para/end hooks here (e.g. wrong for tagging):
%    \begin{macrocode}
      \setbox\@tempboxa\vbox{#1\RawParEnd}%
      \ht\@tempboxa\ht\strutbox
      \dp\@tempboxa\dp\strutbox
      \wd\@tempboxa\z@
      \box\@tempboxa
    \egroup
  }%
}
\DeclareOption{heightadjust}{%
  \renewcommand*{\mn@strut}{\begingroup\dp\strutbox\z@\strut\endgroup}%
  \renewcommand{\mn@zbox}[1]{%
    \bgroup
%    \end{macrocode}
% Avoid the execution of the para/end hooks here, this is wrong for tagging:
%    \begin{macrocode}    
      \setbox\@tempboxa\vbox{#1\RawParEnd}%
      \ht\@tempboxa\ht\strutbox
      \dp\@tempboxa\dp\z@
      \wd\@tempboxa\z@
      \box\@tempboxa
    \egroup
  }%
}
\DeclareOption{depthadjust}{%
  \renewcommand*{\mn@strut}{\begingroup\ht\strutbox\z@\strut\endgroup}%
  \renewcommand{\mn@zbox}[1]{%
    \bgroup
%    \end{macrocode}
% Avoid the execution of the para/end hooks here, this is wrong for tagging:
%    \begin{macrocode}    
      \setbox\@tempboxa\vbox{#1\RawParEnd}%
      \ht\@tempboxa\ht\z@
      \dp\@tempboxa\dp\strutbox
      \wd\@tempboxa\z@
      \box\@tempboxa
    \egroup
  }%
}
\DeclareOption{noadjust}{%
  \renewcommand*{\mn@strut}{\relax}%
  \renewcommand{\mn@zbox}[1]{%
    \bgroup
%    \end{macrocode}
% Avoid the execution of the para/end hooks here, this is wrong for tagging:
%    \begin{macrocode}        
      \setbox\@tempboxa\vbox{\kern-\ht\strutbox #1\RawParEnd}%
      \ht\@tempboxa\ht\z@
      \dp\@tempboxa\dp\z@
      \wd\@tempboxa\z@
      \box\@tempboxa
    \egroup
  }%
}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \changes{v1.4}{2018/07/01}{new options \texttt{parboxrestore} (default) and
%   \texttt{noparboxrestore}}^^A
% \begin{macro}{\mn@parboxrestore}
% \changes{v1.4}{2018/07/01}{new internal command}^^A
% We can either use \cs{@parboxrestore} inside the margin notes or don't use
% it. I would recommend to use it, so this will be the new default.
% \changes{v1.4e}{2026-06-13}{Added tagging socket.}
%    \begin{macrocode}
\newcommand*{\mn@parboxrestore}{}
\DeclareOption{parboxrestore}{%
  \renewcommand*{\mn@parboxrestore}{%
%    \end{macrocode}
% Add tagging support (perhaps not really needed but safer):
%    \begin{macrocode}
    \UseTaggingSocket{para/restore}%
    \@tempskipa\parskip
    \@parboxrestore
    \parskip\@tempskipa
  }%
}
\DeclareOption{noparboxrestore}{%
  \renewcommand*{\mn@parboxrestore}%
%    \end{macrocode}
% Tagging should better restore:
%    \begin{macrocode}
    {\UseTaggingSocket{para/restore}}%
}
%    \end{macrocode}
% \end{macro}
%
%    \begin{macrocode}
\ExecuteOptions{verbose,fulladjust,parboxrestore}
\ProcessOptions\relax
%    \end{macrocode}
%
% \begin{macro}{\newmarginnote}
% We need a macro to define a new note at the \texttt{aux} file. This will
% be done using the mechanism of \LaTeX{} that is used for
% \cs{newlabel}. But we use another prefix. This will result in the usual
% ``Labels(s) may have changed. Rerun to get cross-references right.'' if a
% margin note is new or have moved to another page.
%    \begin{macrocode}
\newcommand*{\newmarginnote}{\@newl@bel{mn}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\if@mn@pdfmode}
% \changes{v1.1}{2006/10/23}{new switch}^^A
% \changes{v1.1a}{2008/11/10}{PDF\TeX\ since 1.40 allows \cs{pdfsavepos} in
%   DVI mode too}^^A
% \changes{v1.1b}{2009/02/16}{if level fixed}^^A
% \changes{v1.1c}{2009/02/26}{\protect\XeTeX has working \cs{pdflastxpos}^^A
%   but no \cs{pdftexversion}}^^A
% \changes{v1.2}{2016/06/02}{addition for lua\TeX{} from 0.85}^^A
% \changes{v1.3}{2018/04/13}{removed}^^A
% \begin{macro}{\@mn@mode@prefix}
% \changes{v1.2}{2016/06/02}{(new (internal)}^^A
% \changes{v1.3}{2018/04/13}{removed}^^A
% \end{macro}
% \end{macro}
%
% \begin{macro}{\marginnotetextwidth}
% \changes{v1.1}{2006/10/23}{new macro}
% Some environments change \cs{textwidth}. But at PDF mode we need to know the
% real text width to find the right margin. So we use our own text width
% macro. Sometimes it may be useful if the user can set it up. Because of
% this it is a user command.
%    \begin{macrocode}
\newcommand*{\marginnotetextwidth}{}
\let\marginnotetextwidth\textwidth
\AtBeginDocument{\edef\marginnotetextwidth{\the\textwidth}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\@mn@margintest}
% \changes{v1.1}{2006/10/23}{new PDF mode feature}
% \begin{macro}{\@mn@thispage}
% \begin{macro}{\@mn@atthispage}
% \begin{macro}{\@mn@currpage}
% \changes{v1.1}{2006/10/23}{new (internal)}
% \begin{macro}{\@mn@currxpos}
% \changes{v1.1}{2006/10/23}{new (internal)}
% \begin{macro}{\mn@abspage}
% Macro \cs{@mn@margintest} does the complete test, which margin to use. The
% result may be found at \cs{if@tempswa}. To avoid changes on the last page
% if there is a new note on the first page, try to count the notes by
% page. We know that this can not be successful, but never the less it may
% be a good try. \cs{@mn@thispage} saves the page number of the last usage
% of \cs{@mn@margintest}. \cs{@mn@atthispage} saves the number of margin
% note at this page. But we need to know the absolut page number to do
% this. So we increase the absolut page number \texttt{mn@abspage} at every
% \cs{@outputpage}. \cs{@mn@currpage} is the page from the page label if
% found. \cs{@mn@currxpos} is the real $x$ position may be written with the
% page label and used to calculate the correct horizontal offset.
%    \begin{macrocode}
\newcommand*{\@mn@thispage}{}
\newcommand*{\@mn@currpage}{}
\newcommand*{\@mn@currxpos}{}
\newcounter{mn@abspage}
\AtBeginDocument{\setcounter{mn@abspage}{1}%
  \g@addto@macro\@outputpage{%
    \stepcounter{mn@abspage}%
%    \end{macrocode}
%   \changes{v1.4a}{2018/07/21}{workaround for screwball page order}^^A
%   \changes{v1.4d}{2026/01/05}{info only in verbose mode}^^A
%   From version 1.4a there is a workaround for consecutive odd pages or
%   consecutive even pages in a twoside document.
%    \begin{macrocode}
    \ifodd\value{mn@abspage}%
      \ifodd\value{page}%
      \else
        \if@twoside
          \begingroup
            \advance\c@page\m@ne
            \PackageWarningNoLine{marginnote}{%
              Consecutive odd pages found.\MessageBreak
              Note, it is not recommended to use consecutive\MessageBreak
              odd pages in a double-ended document.\MessageBreak
              The pages of your document should always\MessageBreak
              be a sequence: odd-even-odd-even-...\MessageBreak
              Maybe you've forgotten a
              \@ifundefined{KOMAClassName}%
                           {\string\cleardoublepage}%
                           {\string\cleardoubleoddpage}
              before\MessageBreak 
              changing the page numbering on page \thepage
            }%
          \endgroup
        \fi
        \if@mn@verbose
          \PackageInfo{marginnote}{Using workaround for absolute page number}%
        \fi
        \stepcounter{mn@abspage}%
      \fi
    \else
      \ifodd\value{page}%
        \if@twoside
          \begingroup
            \advance\c@page\m@ne
            \PackageWarningNoLine{marginnote}{%
              Consecutive even pages found.\MessageBreak
              Note, it is not recommended to use consecutive\MessageBreak
              even pages in a double-ended document.\MessageBreak
              The pages of your document should always\MessageBreak
              be a sequence: odd-even-odd-even-...\MessageBreak
              Maybe you've forgotten a
              \@ifundefined{KOMAClassName}%
                           {\string\cleardoublepage}%
                           {\string\cleardoubleevenpage}
              before\MessageBreak 
              changing the page numbering on page \thepage
            }%
          \endgroup
        \fi
        \if@mn@verbose
          \PackageInfo{marginnote}{Using workaround for absolute page number}%
        \fi
        \stepcounter{mn@abspage}%
      \fi
    \fi   
  }%
}
\newcommand*{\@mn@margintest}{%
%    \end{macrocode}
% \changes{v1.2}{2016/06/02}{addition for lua\TeX{} from 0.85}^^A
%   Number of the next margin note at this page.
%    \begin{macrocode}
  \expandafter\ifx\csname @mn@thispage\endcsname\@empty
    \gdef\@mn@atthispage{1}%
  \else\expandafter\ifnum \@mn@thispage=\value{mn@abspage}%
      \begingroup
        \@tempcnta\@mn@atthispage\advance\@tempcnta by \@ne
        \xdef\@mn@atthispage{\the\@tempcnta}%
      \endgroup
    \else
      \gdef\@mn@atthispage{1}%
    \fi
  \fi
  \xdef\@mn@thispage{\themn@abspage}%
%    \end{macrocode}
% Use the number of the page and the number of the margin note at this page
% to save the real number of this page at the \texttt{aux} file. At PDF mode
% save the current $x$ position too.
% \changes{v1.3}{2018/04/13}{use new internals \cs{mn@savepos} and
%   \cs{mn@lastxpos}}^^A
% \changes{v1.3}{2018/04/13}{non PDF mode removed}^^A
%    \begin{macrocode}
  \let\@mn@currpage\relax
  \let\@mn@currxpos\relax
  \mn@savepos
  \protected@write\@auxout{\let\themn@abspage\relax}{%
    \string\newmarginnote{note.\@mn@thispage.\@mn@atthispage}{%
      {\themn@abspage}{\noexpand\number\mn@lastxpos sp}}%
  }%
%    \end{macrocode}
% If the margin note label was not defined, it seems to be new. In this case
% the absolut page number will be used for the test instead of the saved
% real page number.
%    \begin{macrocode}
  \expandafter\ifx\csname mn@note.\@mn@thispage.\@mn@atthispage\endcsname\relax
%    \end{macrocode}
% If we are not in two side mode, we are on a odd page.
%    \begin{macrocode}
    \if@twoside
      \if@mn@verbose
        \PackageInfo{marginnote}{Suggest that margin
          note \@mn@thispage.\@mn@atthispage\space will be on\MessageBreak
          absolute page \themn@abspage.\MessageBreak
          This may be wrong}%
      \fi
      \ifodd\value{mn@abspage}\@tempswatrue\else\@tempswafalse\fi
    \else
      \if@mn@verbose
        \PackageInfo{marginnote}{right page because not two side mode}%
      \fi
      \@tempswatrue
    \fi
  \else
    \edef\@mn@currpage{\csname
      mn@note.\@mn@thispage.\@mn@atthispage\endcsname}%
    \edef\@mn@currxpos{\expandafter\@secondoftwo\@mn@currpage}%
%    \end{macrocode}
% \changes{v1.1d}{2009/05/06}{take care of \cs{hoffset}}^^A
% Ulrike Fischer suggested a simple change to take care of \cs{hoffset},
% e.g., using package \textsf{crop}.
% \changes{v1.1d}{2009/05/06}{take care of \cs{pdfhorigin}}^^A
% We use this occasion to take care of \cs{pdfhorigin}, too.
% \changes{v1.2a}{2016/10/21}{redefine \cs{@mn@currxpos} only if not empty}^^A
% If \cs{@mn@currxpos} is not empty here, it should be corrected by
% \cs{hoffset} and maybe by \cs{pdfhorigin}.
%    \begin{macrocode}
    \ifx\@mn@currxpos\@empty\else
      \edef\@mn@currxpos{\the\dimexpr \@mn@currxpos -\hoffset\relax}%
      \begingroup\expandafter\expandafter\expandafter\endgroup
      \expandafter\ifx\csname pdfhorigin\endcsname\relax\else
        \begingroup\expandafter\expandafter\expandafter\endgroup
        \expandafter\ifx\csname pdfoutput\endcsname\relax
          \begingroup\expandafter\expandafter\expandafter\endgroup
          \expandafter\ifx\csname outputmode\endcsname\relax\else
            \ifnum \outputmode=1 %
              \edef\@mn@currxpos{\the\dimexpr \@mn@currxpos -\pdfhorigin
                +1in\relax}%
            \fi
          \fi
        \else
          \ifnum \pdfoutput=1 %
            \edef\@mn@currxpos{\the\dimexpr \@mn@currxpos -\pdfhorigin 
              +1in\relax}%
          \fi
        \fi
      \fi
%    \end{macrocode}
% \changes{v1.2b}{2017/04/22}{\textsf{bidi} code added}^^A
% \changes{v1.3}{2018/04/13}{\texttt{twocolumn} test added}^^A
% \changes{v1.4d}{2026/01/02}{column detection fixed by cabohah}^^A
% \changes{v1.4d}{2026/01/05}{info only in verbose mode}^^A
% If you are using package \textsf{bidi} and RTL mode is active, the position
% is from right instead of left. So we have to substract \cs{@mn@currxpos}
% from \cs{pdfpagewidth} (or \cs{pagewidth} using Lua\TeX, but this cannot be,
% because \textsf{bidi} is not Lua\TeX-compatible).
%    \begin{macrocode}
      \ifdefined\mn@pagewidth
        \@mn@if@RTL{%
          \if@mn@verbose
            \PackageInfo{marginnote}{Margin note
              \@mn@thispage.\@mn@atthispage\space in RTL mode}%
          \fi
          \edef\@mn@currxpos{%
            \the\dimexpr\mn@pagewidth-\@mn@currxpos\relax
          }%
        }{}%
      \fi
    \fi
    \edef\@mn@currpage{\expandafter\@firstoftwo\@mn@currpage}%
    \if@mn@verbose
      \PackageInfo{marginnote}{Margin note \@mn@thispage.\@mn@atthispage\space
        is on absolute page \@mn@currpage}%
    \fi
    \if@twoside
      \ifodd\@mn@currpage\relax
        \@tempswatrue
        \if@twocolumn
          \ifdim \@mn@currxpos
                 < \dimexpr 1in+\oddsidemargin+\columnwidth+.5\columnsep\relax
            \@tempswafalse
          \fi
        \fi
      \else
        \@tempswafalse
        \if@twocolumn
          \ifdim\@mn@currxpos>\dimexpr 1in+\evensidemargin+.5\columnwidth\relax
            \@tempswatrue
          \fi
        \fi  
      \fi
    \else
      \if@mn@verbose
        \PackageInfo{marginnote}{right page because not two side mode}%
      \fi
      \@tempswatrue
      \if@twocolumn
        \ifdim \@mn@currxpos
               < \dimexpr 1in+\oddsidemargin+\columnwidth+.5\columnsep\relax
          \@tempswafalse
        \fi
      \fi
    \fi  
  \fi
}
%    \end{macrocode}
% \begin{macro}{@mn@ifRTL}
% \changes{v1.2b}{2017/04/22}{new internal}
% Test, whether or not \cs{if@RTL} exists and is true or false.
%    \begin{macrocode}
\newcommand*{\@mn@if@RTL}{%
  \begingroup\expandafter\expandafter\expandafter\endgroup
  \expandafter\ifx\csname if@RTL\endcsname\iftrue
    \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi
}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\marginnote}
% \begin{macro}{\@mn@marginnote}
% \begin{macro}{\@mn@@marginnote}
% \changes{v1.1g}{2011/04/11}{missing \cs{long} added}
% \begin{macro}{\@mn@@@marginnote}
% \changes{v1.1}{2006/10/23}{new PDF mode feature}
% \changes{v1.1g}{2011/04/11}{missing \cs{long} added}
% Command \cs{marginnote} is the main macro of the package. The others are
% helpers to manage the optional arguments.
% \changes{v1.4e}{2026-06-13}{Added tagging sockets.}
%    \begin{macrocode}
\newcommand*{\marginnote}{%
  \@dblarg\@mn@marginnote
}
\newcommand{\@mn@marginnote}[2][]{%
  \ifhmode
    \@bsphack
    \begingroup
    \ifdim\@savsk>\z@\else
      \def\:{\@xifnch}\expandafter\def\: { \futurelet\@let@token\@ifnch}%
    \fi
  \else
    \begingroup
  \fi
  \@ifnextchar [{\@mn@@marginnote[{#1}]{#2}}{\@mn@@marginnote[{#1}]{#2}[\z@]}%
}
\newcommand{\@mn@@marginnote}{}
\long\def\@mn@@marginnote[#1]#2[#3]{%
  \endgroup
%    \end{macrocode}
% Tagging support:
%    \begin{macrocode}
\UseTaggingSocket{marginpar/begin}%
%    \end{macrocode}
% In horizontal mode the space hack of the \LaTeX{} kernel will be used. In
% vertical mode this should not be used.
%    \begin{macrocode}
  \ifhmode
    \@mn@@@marginnote[{#1}]{#2}[{#3}]%
    \@esphack
  \else
    \@mn@@@marginnote[{#1}]{#2}[{#3}]%
  \fi
%    \end{macrocode}
% Tagging support:
%    \begin{macrocode}
  \UseTaggingSocket{marginpar/end}%  
}
\newcommand{\@mn@@@marginnote}{}
\long\def\@mn@@@marginnote[#1]#2[#3]{%
%    \end{macrocode}
% \changes{v1.1b}{2009/02/16}{use \cs{mn@vadjust} instead of \cs{vadjust}}%
% \changes{v1.1e}{2009/06/06}{use \cs{mn@strut} instead of \cs{strut}}%
% All changes (but change of counters that are global because of using the
% \LaTeX{} commands to change them an \cs{gdef} and \cs{xdef}) should be
% local. In h-mode a \cs{strut} will be used to fix base line. The margin
% note will be put to vertical list using \cs{vadjust}. This also means that
% wie are one line to deep. This will be corrected later using negative kern.
% In v-mode wie use a special kind of vbox to simply set everything. Math
% mode should behave like v-mode. And if we are just after an item we have
% to leave v-mode first.
%    \begin{macrocode}
  \begingroup
    \ifmmode\mn@strut\let\@tempa\mn@vadjust\else
      \if@inlabel\leavevmode\fi
      \ifhmode\mn@strut\let\@tempa\mn@vadjust\else\let\@tempa\mn@vlap\fi
    \fi
    \@tempa{%
%    \end{macrocode}
% Everything will be put upwards using a \cs{vbox} with zero height and depth
% and \cs{vss}. At this box the margin test will be done. If
% \cs{reversemarginpar} was used, the logic reverses. Then the note will be
% places to the margin.
%    \begin{macrocode}
      \vbox to\z@{%
        \vss
        \@mn@margintest
        \if@reversemargin\if@tempswa
            \@tempswafalse
          \else
            \@tempswatrue
        \fi\fi
        \if@tempswa
          \rlap{%
%    \end{macrocode}
% If \cs{@mn@currxpos} is neither \cs{relax} nor empty it is the real 
% current $x$ position of the last PDF\LaTeX{} run and may be used to
% calculate the real horizontal offset.
%    \begin{macrocode}
            \if@mn@verbose
              \PackageInfo{marginnote}{xpos seems to be \@mn@currxpos}%
            \fi
            \begingroup
              \ifx\@mn@currxpos\relax\else\ifx\@mn@currxpos\@empty\else
                  \kern-\dimexpr\@mn@currxpos\relax
              \fi\fi
              \ifx\@mn@currpage\relax
                \let\@mn@currpage\@ne
              \fi
              \if@twoside\ifodd\@mn@currpage\relax
                  \kern\oddsidemargin
                \else
                  \kern\evensidemargin
                \fi
              \else
                \kern\oddsidemargin
              \fi
              \kern 1in
            \endgroup
            \kern\marginnotetextwidth\kern\marginparsep
            \vbox to\z@{\kern\marginnotevadjust\kern #3
              \vbox to\z@{%
                \hsize\marginparwidth
%    \end{macrocode}
% \changes{v1.1g}{2011/04/11}{set \cs{linewidth}}
%    \begin{macrocode}
                \linewidth\hsize
%    \end{macrocode}
% Here's the correction of the vertical position. The remain is simple.
% \changes{v1.1i}{2012/03/29}{\cs{strut} moved to fix hyphenation (thanks to
%   Ulrike Fischer)}
% \changes{v1.1i}{2012/03/29}{\cs{ignorespaces} added}^^A
% \changes{v1.4}{2018/07/01}{\cs{mn@parboxrestore} added}^^A
%    \begin{macrocode}
                \kern-\parskip
                \mn@parboxrestore
                \marginfont\raggedrightmarginnote\strut\hspace{\z@}%
                \ignorespaces#2\endgraf
                \vss}%
              \vss}%
          }%
        \else
%    \end{macrocode}
% Using the left margin.
% \changes{v1.1f}{2010/01/05}{missing usage of \cs{marginnotevadjust} on
%   left margin fixed}
%    \begin{macrocode}
          \llap{%
            \vbox to\z@{\kern\marginnotevadjust\kern #3
              \vbox to\z@{%
                \hsize\marginparwidth
%    \end{macrocode}
% \changes{v1.1g}{2011/04/11}{set \cs{linewidth}}
%    \begin{macrocode}
                \linewidth\hsize
%    \end{macrocode}
% Same like above for left margins.
%    \begin{macrocode}
                \kern-\parskip
                \mn@parboxrestore
                \marginfont\raggedleftmarginnote\strut\hspace{\z@}%
                \ignorespaces#1\endgraf
                \vss
              }%
              \vss
            }%
            \if@mn@verbose
              \PackageInfo{marginnote}{xpos seems to be \@mn@currxpos}%
            \fi
            \begingroup
              \ifx\@mn@currxpos\relax\else\ifx\@mn@currpos\@empty\else
                  \kern\@mn@currxpos
              \fi\fi
              \ifx\@mn@currpage\relax
                \let\@mn@currpage\@ne
              \fi
              \if@twoside\ifodd\@mn@currpage\relax
                  \kern-\oddsidemargin
                \else
                  \kern-\evensidemargin
                \fi
              \else
                \kern-\oddsidemargin
              \fi
              \kern-1in
            \endgroup
            \kern\marginparsep
          }%
        \fi
      }%
    }%
  \endgroup
}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\marginnoterightadjust}
% \changes{v1.3}{2018/04/13}{removed}^^A
% \begin{macro}{\marginnoteleftadjust}
% \changes{v1.3}{2018/04/13}{removed}^^A
% \end{macro}
% \end{macro}
%
% \begin{macro}{\marginnotevadjust}
% This may be used to define an automatic vertical adjust. The defaul tis
% zero. Values greater than zero will move the margin note down, values less
% than zero will move the margin note up.
%    \begin{macrocode}
\newcommand*{\marginnotevadjust}{}
\let\marginnotevadjust\z@
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\mn@vlap}
% This macro is used to set a vertical box without size at vertical mode.
%    \begin{macrocode}
\newcommand{\mn@vlap}[1]{%
  \setbox\@tempboxa\vbox to \ht\strutbox{#1\vss}%
  \box\@tempboxa\vskip-\baselineskip
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\mn@vadjust}
% \changes{v1.1b}{2009/02/16}{new (internal)}
% \changes{v1.4e}{2026-06-13}{Avoid execution of para hooks.}
% This macro is used to set a vertical box at horizontal mode.
%    \begin{macrocode}
\newcommand{\mn@vadjust}[1]{%
  \mn@zbox{\kern-\parskip
%    \end{macrocode}
% Avoid the execution of the para hooks here (wrong e.g. with tagging): 
%    \begin{macrocode}
    \RawIndent
    \vadjust{#1}%
    \kern\parskip
  }%
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\marginfont}
% \changes{v1.0a}{2006/02/06}{Use \cs{providecommand} to define it.}
% \begin{macro}{\raggedleftmarginnote}
% \begin{macro}{\raggedrightmarginnote}
%   These are very simple. A class may also define \cs{marginfont}. Use this
%   if available. I don't use \cs{let} for the definitions of the ragged
%   macros, so the meaning may change loading e.g. package \textsf{ragged2e}.
%    \begin{macrocode}
\providecommand*{\marginfont}{}
\newcommand*{\raggedleftmarginnote}{\raggedleft}
\newcommand*{\raggedrightmarginnote}{\raggedright}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \Finale
%
\endinput
%
% end of `marginnote.dtx'
%
% Local Variables:
% mode: doc-tex
% TeX-master: t
% End:
