% \iffalse meta-comment % % Copyright (C) 2022/23 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} % %\NeedsTeXFormat{LaTeX2e}[2020/10/01] %\ProvidesPackage{sidenotesplus} %<*package> [2023/12/19 1.04 rich text marginal notes, tables and figures ] % %\RequirePackage{marginnote} % provides an offset option for the marginals instead of a float %\RequirePackage{caption} % handles the captions (in the margin) %\RequirePackage{xparse} % new LaTeX3 syntax to define macros and environments %\RequirePackage{calc} %\RequirePackage{etoolbox} % provides \patchcmd %\RequirePackage{l3keys2e} %\RequirePackage{ifoddpage} %\RequirePackage{mparhack} % get marginpar right %\RequirePackage{xspace} %\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} % % \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} % \changes{1.03}{2023/10/05}{added commands sidecitebefore, sideciteafter and sidcitemark} % \changes{1.04}{2023/12/19}{fixed bug in the sidecite commands (Trailing comma replaced by trailing period} % % \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 available 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 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 || % option can be overwritten by the marginals that float. % % ~ % % % \DescribeMacro{\sidenote} % The |\sidenote| has five options % \verb+*|offset|(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*[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|". % 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|" 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{\sidecitebefore} % % \DescribeMacro{\sidecitemark} % \DescribeMacro{\sideciteafter} % \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. % Use |sidecitebefore| or |sideciteafter| to place the marginalia reference % before or after the |sidenotemark| % 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} { \DeclareDelimFormat{postnotedelim}{\addperiod} \RenewDocumentCommand \snp@after {} {}} { \DeclareDelimFormat{postnotedelim}{\addcomma\space} \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} { \DeclareDelimFormat{postnotedelim}{\addperiod} \RenewDocumentCommand \snp@after {} {}} { \DeclareDelimFormat{postnotedelim}{\addcomma\space} \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} % % \begin{macro}{\sidecitebefore} % -- % % \begin{macrocode} \NewDocumentCommand \sidecitebefore {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} { \DeclareDelimFormat{postnotedelim}{\addperiod} \RenewDocumentCommand \snp@after {} {}} { \DeclareDelimFormat{postnotedelim}{\addcomma\space} \RenewDocumentCommand \snp@after {} { #7}} \sidenotetextbefore|#2|<#3>(#4)!#5!{\kern-2.3pt\upshape\fullcite[\snp@before][\snp@after]{#8}} } % \end{macrocode} % % \begin{macro}{\sideciteafter} % -- % % \begin{macrocode} \NewDocumentCommand \sideciteafter {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} { \DeclareDelimFormat{postnotedelim}{\addperiod} \RenewDocumentCommand \snp@after {} {}} { \DeclareDelimFormat{postnotedelim}{\addcomma\space} \RenewDocumentCommand \snp@after {} { #7}} \sidenotetext|#2|<#3>(#4)!#5!{\kern-2.3pt\upshape\fullcite[\snp@before][\snp@after]{#8}} } % \end{macrocode} % % % \begin{macro}{\sidecitemark} % -- % % \begin{macrocode} \NewDocumentCommand \sidecitemark {s d() d!! } { \IfBooleanTF{#1} { % starred \relax} {% unstarred \IfNoValueOrEmptyTF{#3} {\snp@sidenotemark (#2)} {\snp@sidenotemark !#3!( #2)} } \xspace } % \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 % % \fi % % \Finale \endinput