% \iffalse meta-comment
%
% Copyright (C) 2022 by Anton Vrba
%
% Home Page: https://github.com/anton-vrba/sidenotesplus
%    Issues: https://github.com/anton-vrba/sidenotesplus/issues
%
%
% LaTeX Package: sidenotesplus
%
%
% This work 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.
%
% This work was inspired by: https://ctan.org/pkg/sidenotes by: Andy Thomas
%
%
% This work has the LPPL maintenance status `maintained'.
%
% The Current Maintainer of this work is Anton Vrba.
%
% This work consists of the files sidenotesplus.dtx and sidenotesplus.ins
% and the derived filebase sidenotesplus.sty.
%
% \fi
%
% \iffalse
%<*driver>
\ProvidesFile{sidenotesplus.dtx}
%</driver>
%<package>\NeedsTeXFormat{LaTeX2e}[2020/10/01]
%<package>\ProvidesPackage{sidenotesplus}
%<*package>
    [2022/07/09 1.02 rich text marginal notes, tables and figures ]
%</package>
%<package>\RequirePackage{marginnote} % provides an offset option for the marginals instead of a float
%<package>\RequirePackage{caption} % handles the captions (in the margin)
%<package>\RequirePackage{xparse} % new LaTeX3 syntax to define macros and environments
%<package>\RequirePackage{calc}
%<package>\RequirePackage{etoolbox} % provides \patchcmd
%<package>\RequirePackage{l3keys2e}
%<package>\RequirePackage{ifoddpage}
%<package>\RequirePackage{mparhack} % get marginpar right
%<package>\RequirePackage{xspace}
%<package>\RequirePackage[strict]{changepage}
%<*driver>
\documentclass{ltxdoc}
\usepackage{tabularx}
\usepackage{xspace}
\setlength{\textheight}{9.25in}
\setlength{\headsep}{-0.25in}
\EnableCrossrefs
%\CodelineIndex
\RecordChanges
\begin{document}
  \DocInput{sidenotesplus.dtx}
%  \PrintIndex
  \PrintChanges
\end{document}
%</driver>
% \fi
%
%
% \CharacterTable
%  {Upper-case    \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
%   Lower-case    \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
%   Digits        \0\1\2\3\4\5\6\7\8\9
%   Exclamation   \!     Double quote  \"     Hash (number) \#
%   Dollar        \$     Percent       \%     Ampersand     \&
%   Acute accent  \'     Left paren    \(     Right paren   \)
%   Asterisk      \*     Plus          \+     Comma         \,
%   Minus         \-     Point         \.     Solidus       \/
%   Colon         \:     Semicolon     \;     Less than     \<
%   Equals        \=     Greater than  \>     Question mark \?
%   Commercial at \@     Left bracket  \[     Backslash     \\
%   Right bracket \]     Circumflex    \^     Underscore    \_
%   Grave accent  \`     Left brace    \{     Vertical bar  \|
%   Right brace   \}     Tilde         \~}
%
%
%
%
% \GetFileInfo{sidenotesplus.dtx}
% \title{The \textsf{sidenotesplus} package}
% \author{Anton Vrba\\\small%
% Home Page: \url{https://github.com/anton-vrba/sidenotesplus} \\\small
%    Issues: \url{https://github.com/anton-vrba/sidenotesplus/issues }}
% \date{Version \fileversion\xspace from \filedate}
%
% \maketitle
%
% \changes{1.0}{2022/05/15}{Initial Release}
% \changes{1.01}{2022/05/31}{Environment text* improved}
% \changes{1.02}{2022/07/09}{added Ragged option}
%
% \begin{abstract}
%  \noindent A package to manage the margin notes, figures, tables and captions.
%  Also body text can be extended into the margin for wide figures, tables and equation.
%  Twoside symmetry is preserved. For biblatex users, routines for side references are
%  included.
% \end{abstract}
%
% \paragraph*{Note:} Margin notes, figures and tables placements require up to
%  three compilations to be as intended.
%%
% \paragraph*{Note:} This package is inspired by the package |sidenotes| authored by
% Andy Thomas and has many features in common. But, compatibility is
% not maintained between the two.
%
% \section{Usage}
% \subsection{Package options}
% Below the options that can be passed to the package |sidenotesplus|
% with the package defaults listed first.
%
% ~
%
% \begin{tabularx}{\textwidth}{ r X }
%  |mark=| & |alph, Alph, arabic, roman, Roman, fnsymbol| \\
%  |font=| & |rm, sf|\\
%  |size=| & |footnote, normal, small, script| \\
%  |shape=| & | up, it, sl|\\
%  |ragged| & switches to ragged outer margins\\
%  |Ragged| & switches to ragged outer margins but uses ragged2e package\\
%  |classic| & switches to a classic look\\
%  |sepdiff=| & |1em|, or a valid length within reason \\
%  |alerton| & switches on the rendering of the margin alerts \\
% \end{tabularx}
%
% ~
%
% The normal page style is that margin notes are left-right justified with the
% last line ragged to the outer edge. The option |ragged| or |Ragged| changes this
% style to ragged-outer, that is the left page's marginal notes are |\raggedleft|
% and the right page's are |\raggedright|.
% If you opt to use |Ragged| the package |ragged2e| is loaded and |RaggedLeft/Right|
% is used instead of |raggedleft/right|. Load package |ragged2e| with required
% options before |sidenotesplus| is loaded, otherwise |sidenotesplus| loads
% |ragged2e| without any options.
%
% The marginal note's reference number or mark is placed in the margin separator,
% that is on the left page the mark is on the right hand side of the note.
% The option |classic| always places the mark to the left of the marginal note.
% This requires that the margin separator on the left page is slightly reduced if not
% enough space is availabe to the page outer edge.
%
% \subsection{Modified \LaTeX\xspace commands}
%
% \DescribeMacro{\marginpar}
% The LaTex command |marginpar{abc}| with only one
% parameter it is modified to
% |\marginpar[left styled abc]{right styled abc}|
% maintaining page symmetry.
% If called with two parameters nothing is changed
%
% \subsection{Marginal note commands}
%
% All marginal note commands have five options followed by the side note text
% enclosed in braces. Each option has its own enclosing symbols. The option
% sequence is fixed but not used options are omitted entirely, including their
% enclosing sequence. The option sequence is \verb"*, ||, <>, (), !!" plus |{}|.
%
% ~
%
% % \begin{tabularx}{\textwidth}{ r X }
%   |*| & margin note reference labels is omitted \\
%   \verb+|float offset|+ & floating offset, negative is towards page top\\
%   |<fixed offsett>| & fixed offset, negative is towards page top \\
%   |(custom mark)| & any custom mark\\
%   |!colour!|& any valid colour\\
%   |{content}|& margin note content
% \end{tabularx}
%
% ~
%
%  \noindent Note: All marginals placed with a fixed offset, that is with the |<fixed offset>|
%  option can be overwritten by the marginals that float.
%
% ~
%
%
% \DescribeMacro{\sidenote}
% The |\sidenote| has five options
%  \verb+*|offset|<offsett>(custom mark)!colour!+
% all preceding the note |{content}|.
% The options are defined by their enclosures \verb+*||,<>,(),!!+
% and must be in the order listed above.
%
% Example: \verb"\sitenote|10pt|($\bigstar$){text}" is valid
%
% but \verb"\sitenote($\bigstar$)|10pt|{text}" will give an error
%
% ~
%
% \DescribeMacro{\sidenotetext}
% \DescribeMacro{\sidenotemark}
% \DescribeMacro{\sidenotetextbefore}  Similar to |\footnotemark|
% and |\footnotetext| the macros |\sidenotemark|, |\sidenotetext|
% and |\sidenotetextbefore| are provided, the latter two have the same
% options as |\sidenote|. This is useful in placing margin notes in
% environments where the |\sidenote| is not permitted.
% The margin note is not positioned by the |\sidenotemark|, but rather it
% is positioned relative to |\sidenotetext| or |\sidenotetextbefore|
%
%% ~
%
% \DescribeMacro{\sidealert}
% These are temporary margin notes rendered in red
% or by the user's defined |!colour!|. The package option |alerton| needs to be
% specified in the document preamble. The alert mark has zero width so it does not
% alter the main text layout and is also rendered in colour. The alert mark is
% either numeric arabic (default), or alphabetic if the side note mark is set to
% arabic
%
%
% ~
%
% \DescribeMacro{\sidepar} Starts a new paragraph in the side note,
% whereas |\\| begins a new line without indentation.
%
% ~
%
%\DescribeMacro{\sidecaption}
% The \verb"\sidecaption*<offset>[short form]{long form}"
% macro can be used from within figure or table environment and
% the caption is placed in the margin adjacent to the figure or table
% The float \verb+||+ is not an option here. Therefore, the caption might
% overlap with other marginals. Then, these marginals have to be adjusted with
% offset parameters. The formatting of the caption is done by the \emph{caption}
% package by defining a \emph{sidecaption} style. Please refer to the
% documentation of the caption package for information on styles. The macro can
% be starred, which is analog to the regular starred caption (no numbering, no
% tof entry). Use |\raggedinner| within the figure, or table, environment
% to place these near the caption.
%
% ~
%
% \DescribeMacro{\raggedinner}
% \DescribeMacro{\raggedouter} Are raggedleft or raggedright modes depending if
% document is one or two sided and if the page is even or odd.
%
% ~
%
% \DescribeEnv{marginfigure}
% The |marginfigure| environment puts a figure and its caption in the margin.
% Instead of |\begin{figure}[htbp]| use \verb"\begin{marginfigure}|offset|<offset>".
% Again, using an offset value switches the behaviour from float to fixed
% position. The marginfigure has its own caption style named \emph{marginfigure}.
%
% ~
%
% \DescribeEnv{margintable}
% The |margintable| environment works similar to marginfigure, but with table
% environments. Use \verb"\begin{marginfigure}|offset|<offset>" instead of
% |\begin{table}[htbp]|, its caption style is named \emph{margintable}.
%
% ~
%
% \DescribeMacro{\margincaption}
% The |\margincaption| macro is used only in the two above environments
% (|marginfigure| and |marginfigure|) and it is not to be confused with |\sidecaption|.
% It as the same options as |\caption|
%
% ~
%
% \DescribeEnv{figure*}
% The |figure*| environment is used to position figures across the full
% page, i.e. the text width plus the margin. The algorithm has to distinguish
% between recto and verso (left and right) pages and might need up to three
% \LaTeX{} runs to provide the desired result. The corresponding caption style
% is called \emph{widefigure}.
% \DescribeEnv{table*}
% The sister environment for tables is |table*|. Use \emph{widetable} to
% change its caption style.
%
%
% \DescribeEnv{text*}
% The |text*| environment is used to render text across up to
% the full page width. Page breaks are not permitted within this environment.
% This environment is useful when extra width for equations is required.
% The environment |\begin{text*}[0.5]| extends the text width by
% |0.5*(\marginparwidth+\marginparsep)|,  omitting the option is equivalent
% to specifying the option |[1]|,
%
%
% \DescribeMacro{\sidecite}
% \DescribeMacro{\sidecitet}
% \DescribeMacro{\sidecitet*}
% The |\sidecite|, |\sidecitet| and |\sidecitet*| provide citing
% references in the margin and uses the package |biblatex| which has to be setup
% outside the |sitenotesplus| package.
% Example settings  in the document preamble:
%
% ~~~~|\usepackage[english]{babel}|
%
% ~~~~|\usepackage[backend=biber,style=nature]{biblatex}|
%
% ~~~~|\addbibresource{mybibfile.bib}|
% \\The above three cite-commands use the same options as sidenote followed by the two
% options of the |biblatex|'s |\fullcite| command. Margin citations are always with marks,
% hence the |*| takes new meaning here.
% The command |\sidecite{BibReference}| and |\sidecite*{BibReference}| are
% equivalent, and both place a side note mark
% and the citation reference in the side margin. |\sidecitet{BibReference}|
% renders:  Author\textsuperscript{a}, where 'a' is side note mark, whereas |\sidecitet*{BibReference}|
% is the possessive version and renders:  Author's\textsuperscript{a}.
%
%
% \subsection{Packages loaded}
%
%   \begin{description}
%     \item[marginnote]
%        supports an alternative to \verb+\marginpar+ and creates non floating
%        notes in the margin.
%     \item[mparhack] to get \verb+\marginpar+ right
%     \item[caption]
%        allows to set figure and table captions in the margin and allows
%        easier formatting of these captions. Please refer to the
%        \emph{caption} manual for details on styles.
%     \item[xparse] is used to take advantage of the improved \LaTeX3 syntax.
%        All macros and environments are defined using this package.
%     \item[l3keys2e] provides a key/value mechanism
%     \item[xspace] provides the command |\xspace|
%     \item[changepage] is used to correctly shift figure* and table*. It has
%        to use the option [strict] to work properly. This might lead to an
%        option clash, if the same package is loaded without this option.
%     \item[ifoddpage] provides the command |\ifoddpage|
%     \item[etoolbox]  provides the command |\patchcmd|
%     \item[calc] provides calculation such as adding lengths
%     \item[ragged2e] if |Ragged| option is used, and provides hyphenation
%     to prevent very short lines
%
%  \end{description}%

%
% \StopEventually{}
%
% \section{Implementation}
%
% \iffalse
%<*package>
% \fi
%
%    \begin{macrocode}
\newcommand \snptest {{\upshape Figure \thefigure:} And some text\xspace}

\ExplSyntaxOn
\DeclareExpandableDocumentCommand{\IfNoValueOrEmptyTF}{ m m m }
{
 \IfNoValueTF{#1}
  {#2}
  {\tl_if_empty:nTF {#1} {#2} {#3}}
}
\setcounter{topnumber}{4}
\setcounter{bottomnumber}{4}
\setcounter{totalnumber}{8}
%    \end{macrocode}
%
% \begin{macro}{\snp@sidenoteformat}
% --
%
%    \begin{macrocode}
\NewDocumentCommand \snp@sidenoteformat {} {%
   \snp@size\snp@shape\snp@font\leavevmode%
   \lineskip=0pt \lineskiplimit=0pt %
   \tolerance=2000 \hyphenpenalty=300 \exhyphenpenalty=300%
   \doublehyphendemerits=300%
   \finalhyphendemerits=\doublehyphendemerits
   }
\NewDocumentCommand \snp@sideformat {} {}
\NewDocumentCommand \snp@sidecolor {} {}

%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{-}
% --
%   \begin{macrocode}
\NewDocumentCommand \snp@symbol {} {\alph}
\NewDocumentCommand \snp@alertsymbol {} {\arabic}
\NewDocumentCommand \snp@font {} {}
\NewDocumentCommand \snp@shape{} {\itshape}
\NewDocumentCommand \snp@size {} {\footnotesize}
\NewDocumentCommand \snp@leftmarginstyle{} {}
\NewDocumentCommand \snp@rightmarginstyle{} {}
%
%
\bool_new:N \l@snp@margincaption
\bool_new:N \l@snp@alerton
\bool_new:N \l@snp@alertmarkon
\bool_new:N \l@snp@ragged
\bool_new:N \l@snp@Ragged
\bool_new:N \l@snp@symmetric
\bool_new:N \l@snp@page

\bool_set_false:N \l@snp@margincaption
\bool_set_false:N \l@snp@alerton
\bool_set_false:N \l@snp@alertmarkon
\bool_set_false:N \l@snp@ragged
\bool_set_false:N \l@snp@Ragged
\bool_set_true:N \l@snp@symmetric


%
\newlength{\snp@marginsepdiff}
\setlength{\snp@marginsepdiff}{1ex}
%    \end{macrocode}
%\end{macro}

%   \begin{macrocode}
\keys_define:nn { sidenoteplus }
{
 mark .code:n = \str_case:nn {#1}%
     {  {fnsymbol}{\RenewDocumentCommand \snp@symbol {}{\fnsymbol}}%
        {Alph}{\RenewDocumentCommand \snp@symbol {}{\Alph}}%
        {arabic}{\RenewDocumentCommand \snp@symbol {}{\arabic}
                 \RenewDocumentCommand \snp@alertsymbol {} {\alph}}%
        {Roman}{\RenewDocumentCommand \snp@symbol {}{\Roman}}%
        {roman}{\RenewDocumentCommand \snp@symbol {}{\roman}}%
        {Other}{}  },
 font .code:n = \str_case:nn {#1}%
      {  {sf}{\RenewDocumentCommand \snp@font {}{\sffamily}}%
        {Other}{} },
 size .code:n = \str_case:nn {#1}%
      {  {small}{\RenewDocumentCommand \snp@size {}{\small}}%
         {script}{\RenewDocumentCommand \snp@size {}{\scriptsize}}%
         {normal}{\RenewDocumentCommand \snp@size {}{\normalsize}}%
        {Other}{} },
 shape .code:n = \str_case:nn {#1}%
      {  {sl}{\RenewDocumentCommand \snp@shape{}{\slshape}}%
         {up}{\RenewDocumentCommand \snp@shape{}{\upshape}}%
         {it}{\RenewDocumentCommand \snp@shape{}{\itshape}}%
        {Other}{} },
 sepdiff .code:n = \setlength{\snp@marginsepdiff}{#1},
 classic .code:n = \bool_set_false:N \l@snp@symmetric,
 ragged .code:n = { \RenewDocumentCommand \snp@leftmarginstyle {}{\raggedleft}
                    \RenewDocumentCommand \snp@rightmarginstyle {}{\raggedright}
                    \bool_set_true:N \l@snp@ragged  },
 Ragged .code:n = { \RenewDocumentCommand \snp@leftmarginstyle {}{\RaggedLeft}
                    \RenewDocumentCommand \snp@rightmarginstyle {}{\RaggedRight}
                    \bool_set_true:N \l@snp@Ragged
                    \bool_set_true:N \l@snp@ragged  },
 alerton .code:n = {\bool_set_true:N \l@snp@alerton},
}
\ProcessKeysOptions { sidenoteplus }
\bool_if:NTF \l@snp@Ragged
     {
        \@ifpackageloaded{ragged2e}
        {\relax}{\RequirePackage{ragged2e}}
     }
     {\relax}
\bool_if:NTF \l@snp@ragged
     {\setlength{\snp@marginsepdiff}{0pt} \bool_set_false:N \l@snp@symmetric}
     {\relax}
\bool_if:NTF \l@snp@symmetric {\setlength{\snp@marginsepdiff}{0pt}}{\relax}
 \newcounter{sidenote}[page] % make a counter
\setcounter{sidenote}{0} % init the counter
 \newcounter{sidealert}[page] % make a counter
\setcounter{sidealert}{0} % init the counter
%    \end{macrocode}
%
% \begin{macro}{\snp@putmarkintext}
% --
%
%    \begin{macrocode}
\NewDocumentCommand \snp@putmarkintext { m }
{
    \leavevmode
    \ifhmode
        \edef \x@sf {\the \spacefactor }
        \nobreak
    \fi
    \bool_if:NTF \l@snp@alertmarkon
    {\makebox[0pt]{\raisebox{0.3ex}{\textsuperscript {\normalfont \bf ---~{#1}~---\kern-0.6ex }}}}
    {\hbox {\textsuperscript {\normalfont #1 }}}
    \ifhmode
        \spacefactor \x@sf
    \fi
    \relax
}
%    \end{macrocode}
% \end{macro}
%
%
%
% \begin{macro}{\snp@multisign}
% --
%
%    \begin{macrocode}
\NewDocumentCommand \snp@multisign { } {3sp}
%    \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\snp@multimarker}
% --
%
%    \begin{macrocode}
\NewDocumentCommand \snp@multimarker { }
{
  \kern-\snp@multisign
  \kern\snp@multisign\relax
}
%    \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\snp@multichecker}
% --
%
%    \begin{macrocode}
\NewDocumentCommand \snp@multichecker { }
{
  \dim_compare:nNnTF \lastkern = \snp@multisign
  {\snp@putmarkintext{,}}
  {}
}
%    \end{macrocode}
% \end{macro}
%
%
% \begin{environment}{@snp@llr}
% --
%
%    \begin{macrocode}
\NewDocumentEnvironment{@snp@llr} {}%
{
  \setlength{\parindent}{0pt}
  \setlength{\leftskip}{0pt plus 1fil}
  \setlength{\rightskip}{0pt plus -1fil}
}{\par}
%    \end{macrocode}
% \end{environment}
%
%
% \begin{macro}{\marginpar}
%    \begin{macrocode}
\let\oldmarginpar\marginpar
\renewcommand{\marginpar}[2][]{
   \if\relax\detokenize{#1}\relax
      \oldmarginpar[\snp@leftmarginstyle\snp@sidenoteformat{#2}]%
                   {\snp@rightmarginstyle\snp@sidenoteformat{#2}}%
   \else%two parameters, let them use their styling
      \oldmarginpar[{#1}]{#2}%
   \fi%
}
%    \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\snp@placemarginal}
% --
%
%    \begin{macrocode}
\renewcommand*{\raggedleftmarginnote}{}
\renewcommand*{\raggedrightmarginnote}{}
\renewcommand*{\marginfont}{}

\NewDocumentCommand \snp@placemarginal {d!! m m }
{
   \IfNoValueOrEmptyTF{#1}
   {
     \if@twoside
        \snp@isoddpage
        {
           \IfNoValueOrEmptyTF{#2}
           {\marginpar{  #3 }}
           {\marginnote{\snp@sidenoteformat #3}[#2]}
        }
        {
        \bool_if:NTF \l@snp@symmetric
        {
           \IfNoValueOrEmptyTF{#2}
           {\marginpar{\begin{@snp@llr} #3\end{@snp@llr}}}
           {\marginnote{\begin{@snp@llr}\snp@sidenoteformat #3\end{@snp@llr}}[#2]}
        }

        {
           \IfNoValueOrEmptyTF{#2}
           {\marginpar{ #3}}
           {\marginnote{\snp@sidenoteformat #3}[#2]}
        }
        }
     \else
        \IfNoValueOrEmptyTF{#2}
        {\marginpar{ #3}}
        {\marginnote{\snp@sidenoteformat #3}[#2]}
     \fi
   }
   {
     \if@twoside
        \snp@isoddpage
        {
           \IfNoValueOrEmptyTF{#2}
           {\marginpar{  \textcolor{#1}{#3} }}
           {\marginnote{\snp@sidenoteformat  \textcolor{#1}{#3}}[#2]}
        }
        {
        \bool_if:NTF \l@snp@symmetric
        {
           \IfNoValueOrEmptyTF{#2}
           {\marginpar{\begin{@snp@llr} \textcolor{#1}{#3}\end{@snp@llr}}}
           {\marginnote{\begin{@snp@llr}\snp@sidenoteformat  \textcolor{#1}{#3}\end{@snp@llr}}[#2]}
        }
        {
           \IfNoValueOrEmptyTF{#2}
           {\marginpar{\textcolor{#1}{#3}}}
           {\marginnote{ \snp@sidenoteformat  \textcolor{#1}{#3}}[#2]}
        }
        }
     \else
        \IfNoValueOrEmptyTF{#2}
        {\marginpar{ \textcolor{#1}{#3}}}
        {\marginnote{ \snp@sidenoteformat  \textcolor{#1}{#3}}[#2]}
     \fi
   }
}
%    \end{macrocode}
% \end{macro}
%
%
%
% \begin{macro}{\sidepar}
% --
%    \begin{macrocode}
\NewDocumentCommand \sidepar {}
{
  \\\makebox[1em]{}
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\sidenote}
% --
%
%    \begin{macrocode}
\NewDocumentCommand \sidenote {s d|| d<> d() d!! m  }
{
  \IfBooleanTF{#1}
  { % starred
  \snp@sidenotemark*(#4)
  \snp@sidenotetext[*]|#2|<#3>(#4)!#5!{#6}
  }{ % unstarred
\IfNoValueOrEmptyTF{#5} {
  \snp@sidenotemark(#4)
  \snp@sidenotetext[]|#2|<#3>(#4)!#5!{#6}
  \snp@multimarker }
  {
  \snp@sidenotemark(#4)!#5!
  \snp@sidenotetext[]|#2|<#3>(#4)!#5!{#6}
  \snp@multimarker }

  }
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\sidealert}
% --
%
%    \begin{macrocode}
\NewDocumentCommand \sidealert {s d|| d<> d() d!! m  }
{
   \bool_if:NTF \l@snp@alerton
     {
     \bool_set_true:N \l@snp@alertmarkon
      \IfNoValueOrEmptyTF{#5}
      {
        \IfBooleanTF{#1}
        { % starred
          \snp@sidenotemark*(#4)
          \snp@sidenotetext[*]|#2|<#3>(#4)!Red!{#6}
        }{ % unstarred
          \snp@sidenotemark(#4)!Red!{}
          \snp@sidenotetext[]|#2|<#3>(#4)!Red!{#6}
          \snp@multimarker
        }
      }{ \IfBooleanTF{#1}
         { % starred
           \snp@sidenotemark*(#4)
           \snp@sidenotetext[*]|#2|<#3>(#4)!#5!{#6}
         }{ % unstarred
           \snp@sidenotemark(#4)!#5!{}
           \snp@sidenotetext[]|#2|<#3>(#4)!#5!{#6}
           \snp@multimarker
         }
      }
   }
   {\relax}
   \bool_set_false:N \l@snp@alertmarkon
}
%    \end{macrocode}
% \end{macro}
%
%
%
%
% \begin{macro}{\sidenotemark}
% --
%
%    \begin{macrocode}
\NewDocumentCommand \sidenotemark {s d() d!! }
{
  \IfBooleanTF{#1}
  { % starred
    \relax}
  {% unstarred
     \IfNoValueOrEmptyTF{#3}
       {\snp@sidenotemark (#2)}
       {\snp@sidenotemark !#3!( #2)}
  }
  \xspace
}
%    \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\snp@sidenotemark}
% --
%
%    \begin{macrocode}
\NewDocumentCommand \snp@symbolnoteoralert {}{}
\NewDocumentCommand \snp@sidenotemark {s d() d!! }
{
  \IfBooleanTF{#1}
  { % starred
    \relax}
  {% unstarred
     \snp@multichecker
     \bool_if:NTF \l@snp@alertmarkon
        { \refstepcounter{sidealert}
          \RenewDocumentCommand \snp@symbolnoteoralert {}{\snp@alertsymbol{sidealert}} }
       { \refstepcounter{sidenote}
          \RenewDocumentCommand \snp@symbolnoteoralert {}{\snp@symbol{sidenote}} }
     \IfNoValueOrEmptyTF{#3}
     {
       \IfNoValueOrEmptyTF{#2}
         { \snp@putmarkintext{\snp@symbolnoteoralert } }
         { \snp@putmarkintext{#2} }
     }{
        \IfNoValueOrEmptyTF{#2}
          { \textcolor{#3} {\snp@putmarkintext{\snp@symbolnoteoralert}} }
          { \textcolor{#3} {\snp@putmarkintext{#2}} }
     }
     \snp@multimarker
  }
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\snp@onelineup}
% --
%
%    \begin{macrocode}
\NewDocumentCommand{\snp@onelineup}{}
   {\par \vspace*{-1\baselineskip}}
\NewDocumentCommand{\snp@onexlineup}{}
   {\par \vspace*{-1.5\baselineskip}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\snp@leftnotelabel}
% --
%
%    \begin{macrocode}
\NewDocumentCommand{\snp@leftnotelabel}{ m }
   {\makebox[0em][l]{\hspace*{0.9ex}#1}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\snp@rightnotelabel}
% --
%
%    \begin{macrocode}
\NewDocumentCommand{\snp@rightnotelabel}{ m }
   {\makebox[0em][r]{#1\hspace*{0.9ex}}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\snp@justifiedleftnotelabel}
% --
%
%    \begin{macrocode}
\NewDocumentCommand{\snp@justifiedleftnotelabel}{ m }
   {\makebox[0em][l]{\hspace*{\marginparwidth+0.9ex}#1}}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\sidenotetext}
% --
%
%    \begin{macrocode}
\NewDocumentCommand \sidenotetext {s d|| d<> d() d!! m  } {
   \IfBooleanTF{#1}
      { \snp@sidenotetext[*]|#2|<#3>(#4)!#5!{#6} }
      { \snp@sidenotetext[]|#2|<#3>(#4)!#5!{#6} }
}
%    \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\sidenotetextbefore}
% --
%
%    \begin{macrocode}
\NewDocumentCommand \sidenotetextbefore {s d|| d<> d() d!! m  } {
   \refstepcounter{sidenote}
   \IfBooleanTF{#1}
      { \snp@sidenotetext[*]|#2|<#3>(#4)!#5!{#6} }
      { \snp@sidenotetext[]|#2|<#3>(#4)!#5!{#6} }
    \addtocounter{sidenote}{-1}
}
%    \end{macrocode}
% \end{macro}
%
%    \begin{macrocode}
\DeclareExpandableDocumentCommand{\IfsTF}{ m m m }
{
 \IfNoValueTF{#1}
  {#2}
  {\tl_if_empty:nTF {#1} {#2} {#3}}
}
%    \end{macrocode}
% --
%
%    \begin{macrocode}
 \newlength{\d@snp@offset}
%    \end{macrocode}
%
% \begin{macro}{\snp@sidenotetext}
% --
%
%    \begin{macrocode}
\NewDocumentCommand \snp@sidenotesymbol {}{}
\NewDocumentCommand \snp@sidenotetext {o d|| d<> d() d!! m } {
  \bool_if:NTF \l@snp@alertmarkon
  {
  \IfNoValueOrEmptyTF{#4}
     {\RenewDocumentCommand \snp@sidenotesymbol {}{-~\snp@alertsymbol{sidealert}~-}}
     {\RenewDocumentCommand \snp@sidenotesymbol {}{-~#4~-}}
  }
  {
  \IfNoValueOrEmptyTF{#4}
     {\RenewDocumentCommand \snp@sidenotesymbol {}{\snp@symbol{sidenote}}}
     {\RenewDocumentCommand \snp@sidenotesymbol {}{#4}}
  }
  \IfNoValueOrEmptyTF{#2}
     {\relax}
     {\setlength{\d@snp@offset}{#2} \vspace*{ \d@snp@offset }}
   \bool_if:NTF \l@snp@ragged
   {
   \if@twoside
     \snp@isoddpage
     {%odd page
       {  \snp@placemarginal!#5!{#3}%--
              {\snp@rightnotelabel{%
                  \normalfont\IfsTF{#1}{\snp@sidenotesymbol}{\relax}}#6}
       }
     }
     {%even page
        {\snp@placemarginal!#5!{#3}%--
             {\snp@justifiedleftnotelabel{\normalfont%
                    \IfsTF{#1}{\snp@sidenotesymbol}{\relax}}
                    \hspace*{\marginparwidth}  \snp@onelineup#6}
        }
     }
   \else %not twoside
     {\snp@placemarginal!#5!{#3}%--
          {\snp@rightnotelabel{\normalfont%
              \IfsTF{#1}{\snp@sidenotesymbol}{\relax}}#6}
     }
   \fi % ends if@twoside
   }
   {
   \if@twoside
     \snp@isoddpage
     {%odd page
          {\snp@placemarginal!#5!{#3}%--
               {\snp@rightnotelabel{
                   \normalfont\IfsTF{#1}{\snp@sidenotesymbol}{\relax}}#6}
          }
     }
     {%even page
        \bool_if:NTF \l@snp@symmetric
           {
             {\snp@placemarginal!#5!{#3}%--
                  {\snp@justifiedleftnotelabel{
                         \normalfont\IfsTF{#1}{\snp@sidenotesymbol}{\relax} }
                   \hspace*{\marginparwidth}\snp@onelineup#6
                  }
             }
          }
          {
             {  \snp@placemarginal!#5!{#3}%--
                    {\snp@rightnotelabel{
                      \normalfont\IfsTF{#1}{\snp@sidenotesymbol}{\relax}}#6 }
             }
          }
     }
   \else
       {   \snp@placemarginal!#5!{#3}%--
           {\snp@rightnotelabel{
               \normalfont\IfsTF{#1}{\snp@sidenotesymbol}{\relax}}#6}
       }
   \fi
   }
  \IfNoValueOrEmptyTF{#2}
     {\relax}
     { \setlength{\d@snp@offset}{#2 *(-1)} \vspace*{{\d@snp@offset}}}
}
%    \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\snp@raggedcaption}
% --
%    \begin{macrocode}

\NewDocumentCommand \snp@raggedcaption {m }
{
   \if@twoside
      \snp@isoddpage {#1}
         {\bool_if:NTF \l@snp@symmetric {\begin{@snp@llr}#1\end{@snp@llr}} {#1}}
   \else #1 \fi
}
%    \end{macrocode}
% \end{macro}
%
%
%
%    \begin{macrocode}
\DeclareCaptionStyle{sidecaption}{font=footnotesize}
%    \end{macrocode}
%
% \begin{macro}{\sidecaption}
% --
%
%    \begin{macrocode}
\NewDocumentCommand \snp@entrycap {} {}
\NewDocumentCommand \snp@offsetcap {} {}
\NewDocumentCommand \sidecaption {s d|| d<> d!! o m} {
  \captionsetup{style=sidecaption}
  \IfBooleanTF{#1}
  { %starred
  \marginnote{\caption*{\snp@raggedcaption{#6}}}
          [\IfNoValueOrEmptyTF{#3} {0pt} {#3}]
  }
  { %unstarred
  \marginnote{\caption[\IfNoValueOrEmptyTF{#5} {#6} {#5}]
                      {\snp@raggedcaption{#6}}}
          [\IfNoValueOrEmptyTF{#3} {0pt} {#3}]
  }
}
%    \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\istwosided}
% --
%
%    \begin{macrocode}
\NewDocumentCommand \istwosided {m m} {
\if@twoside #1 \else #2 \raggedleft \fi
}
%    \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\raggedinner}
% --
%
%    \begin{macrocode}
\NewDocumentCommand \raggedinner {} {
\if@twoside
     \snp@isoddpage {\raggedleft}{\raggedright}
\else
     \raggedleft
\fi
}
%    \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\raggedouter}
% --
%
%    \begin{macrocode}
\NewDocumentCommand \raggedouter {} {
\if@twoside
     \snp@isoddpage {\raggedright}{\raggedleft}
\else
     \raggedleft
\fi
}
%    \end{macrocode}
% \end{macro}
%

% \begin{macro}{\margincaption}
% --
%    \begin{macrocode}
\newlength \l@snp@belowcaption
\NewDocumentCommand \margincaption {s o m }
{
\setlength \l@snp@belowcaption \belowcaptionskip
\setlength{\belowcaptionskip}{1ex plus 0.3ex minus -0.1ex}
  \IfBooleanTF{#1}
  { %starred
    \if@twoside
        \snp@isoddpage
        {
          \IfNoValueOrEmptyTF{#2} {\caption*{#3}} {\caption*[#2]{#3}}
        }
        {
        \bool_if:NTF \l@snp@symmetric
        {
          \IfNoValueOrEmptyTF{#2}
            {\caption*[#3]{\begin{@snp@llr}#3\end{@snp@llr}}}
            {\caption*[#2]{\begin{@snp@llr}#3\end{@snp@llr}}}
        }
        {
           \IfNoValueOrEmptyTF{#2} {\caption*{#3}} {\caption*[#2]{#3}}
        }
        }
    \else
        \IfNoValueOrEmptyTF{#2} {\caption*{#3}} {\caption*[#2]{#3}}
    \fi
  }
  { %unstarred
    \if@twoside
        \snp@isoddpage
        {
          \IfNoValueOrEmptyTF{#2} {\caption{#3}} {\caption[#2]{#3}}
        }
        {
        \bool_if:NTF \l@snp@symmetric
        {
          \IfNoValueOrEmptyTF{#2}
            {\caption[#3]{\begin{@snp@llr}#3\end{@snp@llr}}}
            {\caption[#2]{\begin{@snp@llr}#3\end{@snp@llr}}}
        }
        {
           \IfNoValueOrEmptyTF{#2} {\caption{#3}} {\caption[#2]{#3}}
        }
        }
    \else
        \IfNoValueOrEmptyTF{#2} {\caption{#3}} {\caption[#2]{#3}}
    \fi
  }
\setlength \belowcaptionskip \l@snp@belowcaption
}
%    \end{macrocode}
% \end{macro}

%    \begin{macrocode}
 \newsavebox{\b@snp@marginfigurebox}
\DeclareCaptionStyle{marginfigure}{font=footnotesize,skip=1ex}
%    \end{macrocode}
%
% \begin{environment}{marginfigure}
% --
%
%    \begin{macrocode}
\NewDocumentEnvironment{marginfigure} { d|| d<> }
{ % begin{} part
  \begin{lrbox}{\b@snp@marginfigurebox}
    \begin{minipage}{\marginparwidth}
      \captionsetup{type=figure,style=marginfigure}
}
%    \end{macrocode}
% \end{environment}
%
%    \begin{macrocode}
{ % end{} part
    \end{minipage}%
  \end{lrbox}%

   \IfNoValueOrEmptyTF{#1}
      {\relax}
      {\setlength{\d@snp@offset}{#1} \vspace*{ \d@snp@offset }}
  \snp@placemarginal{#2}{\usebox{\b@snp@marginfigurebox} }
  %~\snp@onexlineup \snptest }
  \IfNoValueOrEmptyTF{#1}
     {\relax}
     { \setlength{\d@snp@offset}{#1 *(-1)} \vspace*{{\d@snp@offset}}}
}
%    \end{macrocode}
% --
%
%   \upshape Figure \begin{macrocode}
\newsavebox{\b@snp@margintablebox}
\DeclareCaptionStyle{margintable}{font=footnotesize}
%    \end{macrocode}
%
% \begin{environment}{margintable}
% --
%
%    \begin{macrocode}
\NewDocumentEnvironment{margintable} { d|| d<> d() }
{ % begin part
  \begin{lrbox}{\b@snp@margintablebox}
     \snp@sidenoteformat
    \begin{minipage}{\marginparwidth}
      \captionsetup{type=table,style=margintable}
}
%    \end{macrocode}
% \end{environment}
%
%    \begin{macrocode}
{ % end part
    \end{minipage}
  \end{lrbox}
   \IfNoValueOrEmptyTF{#1}
      {\relax}
      {\setlength{\d@snp@offset}{#1} \vspace*{ \d@snp@offset }}
  \snp@placemarginal{#2}{\usebox{\b@snp@margintablebox} }
  \IfNoValueOrEmptyTF{#1}
    {\relax}
    {\setlength{\d@snp@offset}{#1 *(-1)} \vspace*{{\d@snp@offset}}}
%

%
}
%    \end{macrocode}
% --
%
%    \begin{macrocode}
\AtBeginDocument{%
\newlength{\d@snp@extrawidth}
\setlength{\d@snp@extrawidth}{\marginparwidth}
\addtolength{\d@snp@extrawidth}{\marginparsep}  }
%    \end{macrocode}
%
% \begin{macro}{\snp@isoddpage}
% --
%
%    \begin{macrocode}
\NewDocumentCommand \snp@isoddpage {m m}
      { \checkoddpage\ifoddpage #1 \else #2 \fi }
%    \end{macrocode}
% \end{macro}
%
% \begin{environment}{@snp@autoadjustwidth}
% --
%
%    \begin{macrocode}
\NewDocumentEnvironment{@snp@autoadjustwidth}{ m m }%
{ % begin part
\begin{adjustwidth}{0pt}{0pt}
  \if@twoside
     \snp@isoddpage{\begin{adjustwidth}{#1}{-#2}}%
        {\begin{adjustwidth}{-#2}{#1}}
  \else
     \begin{adjustwidth}{#1}{-#2}
  \fi
}
%    \end{macrocode}
% \end{environment}
%
%    \begin{macrocode}
{ % end part
   \end{adjustwidth}\end{adjustwidth}
}
%    \end{macrocode}
%
%
%
% \begin{environment}{text*}
% --
%
% \changes{v1.01}{2022/5/31}{added newsavebox and minipage}
%
%    \begin{macrocode}
\newsavebox{\b@snp@textbox}
\NewDocumentEnvironment{text*}{ o }%
{ % begin part
 \begin{adjustwidth}{0pt}{0pt}
 \IfNoValueOrEmptyTF{#1}
 {
  \if@twoside
     \snp@isoddpage{\begin{adjustwidth}{0pt}{-\d@snp@extrawidth}}%
        {\begin{adjustwidth}{-\d@snp@extrawidth}{0pt}}
  \else
     \begin{adjustwidth}{0pt}{-\d@snp@extrawidth}
  \fi
  }
  {
  \if@twoside
     \snp@isoddpage{\begin{adjustwidth}{0pt}{-#1\d@snp@extrawidth}}%
        {\begin{adjustwidth}{-#1\d@snp@extrawidth}{0pt}}
  \else
     \begin{adjustwidth}{0pt}{-#1\d@snp@extrawidth}
  \fi
  }
  \begin{lrbox}{\b@snp@textbox}
  \begin{minipage}[]{\linewidth+1ex}
}
%    \end{macrocode}
% \end{environment}
%
%    \begin{macrocode}
{  % end part
\end{minipage}
\end{lrbox}
\usebox{\b@snp@textbox}
\end{adjustwidth}\end{adjustwidth} \snp@placemarginal{}{}
}
%    \end{macrocode}
%
% \begin{environment}{figure*}
%    \begin{macrocode}
\RenewDocumentEnvironment{figure*}{ O{htbp} }
{
   \begin{figure}[#1]
   \begin{@snp@autoadjustwidth}{}{\d@snp@extrawidth}
   \begin{minipage}[c]{\linewidth}
   \centering
   \captionsetup{ margin={\d@snp@extrawidth/2,\d@snp@extrawidth/2}}
}{  % end part
   \end{minipage}
   \end{@snp@autoadjustwidth}
   \end{figure}
    \snp@placemarginal{}{}
  }
%    \end{macrocode}
% \end{environment}
%
% \begin{environment}{table*}
%    \begin{macrocode}
\RenewDocumentEnvironment{table*}{O{htbp} }
{
   \begin{table}[#1]
   \begin{@snp@autoadjustwidth}{}{\d@snp@extrawidth}
   \begin{minipage}[c]{\linewidth}
   \centering
   \captionsetup{ margin={\d@snp@extrawidth/2,\d@snp@extrawidth/2}}
}{  % end part
   \end{minipage}
   \end{@snp@autoadjustwidth}
    \end{table}
}
%    \end{macrocode}
% \end{environment}
%
% \begin{macro}{\sidecite}
% --
%
%    \begin{macrocode}
\NewDocumentCommand \snp@before {} {}
\NewDocumentCommand \snp@after {} {}
\NewDocumentCommand \sidecite {s d|| d<> d() d!! o o m }
%    \end{macrocode}
% \end{macro}
%
%    \begin{macrocode}
{ \IfNoValueOrEmptyTF{#6}
  {\RenewDocumentCommand \snp@before {} {}}
  {\RenewDocumentCommand \snp@before {} {#6}}
  \IfNoValueOrEmptyTF{#7}
  {\RenewDocumentCommand \snp@after {} {}}
  {\RenewDocumentCommand \snp@after {} {#7}}
  \sidenote|#2|<#3>(#4)!#5!{\kern-2.3pt\upshape\fullcite[\snp@before][\snp@after]{#8}}
}
%    \end{macrocode}
%
% \begin{macro}{\sidecitet}
% --
%
%    \begin{macrocode}
\NewDocumentCommand \sidecitet {s d|| d<> d() d!! o o m }
{ \IfNoValueOrEmptyTF{#6}
  {\RenewDocumentCommand \snp@before {} {}}
  {\RenewDocumentCommand \snp@before {} {#6}}
  \IfNoValueOrEmptyTF{#7}
  {\RenewDocumentCommand \snp@after {} {}}
  {\RenewDocumentCommand \snp@after {} {#7}}
   \IfBooleanTF{#1}
   {
      \citeauthor{#8}'s\sidenote|#2|<#3>(#4)!#5!
          {\kern-2.3pt\upshape\fullcite[\snp@before][\snp@after]{#8}}
   }
   {
      \citeauthor{#8}\sidenote|#2|<#3>(#4)!#5!
          {\kern-2.3pt\upshape\fullcite[\snp@before][\snp@after]{#8}}
   }
}
%    \end{macrocode}
% \end{macro}
%
\ExplSyntaxOff
%
%%
%    \begin{macrocode}
\newlength\snp@marginparsepodd
\newlength\snp@marginparsepeven


\setlength{\snp@marginparsepodd}{\marginparsep}
\setlength{\snp@marginparsepeven}{\marginparsep-\snp@marginsepdiff}

\makeatletter
\patchcmd{\@addmarginpar}                 % In this command
         {\mph@orig@addmarginpar}         % ... replace this...
         {\if@twoside\ifodd\c@page\relax  % ... with this
              \marginparsep=\snp@marginparsepodd  % Page is odd
            \else
              \marginparsep=\snp@marginparsepeven  % Page is even
            \fi
          \else
            \marginparsep=\snp@marginparsepodd
          \fi
          \mph@orig@addmarginpar}
         {}                                           % success
         {\message{Error! Couldn't hook into command  % failure
             `\string\@addmarginpar'}}

{%% Group to keep patching commands local
  %
  % Here we use a little trick to repeatedly patch the \@mn@@@marginnote
  % command, replacing all instances of \kern\marginparsep with a
  % conditional. We call \patch recursively each time on success, and stop
  % when the patch fails (because all instances have been replaced).  If the
  % patch fails the first time, we show an error message.
  \def\patcherr{%
    \message{Error! Couldn't hook into command `\string\@mn@@@marginnote'}}
  \def\patchok{%
    \let\patcherr\relax % Only display error if first patch fails
    \patch              % Now patch again.
  }
  \def\patch{
    \patchcmd{\@mn@@@marginnote}                   % In this command
             {\kern\marginparsep}                  % ... replace this...
             {\ifx\@mn@currpage\relax\else         % ... with this
                \if@twoside\ifodd\@mn@currpage\relax
                    \kern\snp@marginparsepodd
                  \else
                    \kern\snp@marginparsepeven
                  \fi
                \else
                  \kern\snp@marginparsepodd
                \fi
              \fi}
             {\message{Patched!}\patchok}          % success (recurse)
             {\patcherr}                           % fail
  }
  \message{Patching `\string\@mn@@@marginnote`!}
  \patch
  \global\let\@mn@@@marginnote\@mn@@@marginnote    % Make patch global
}
\makeatother
\endinput
%    \end{macrocode}
%
% \iffalse
%</package>
% \fi
%
% \Finale
\endinput
