1\NeedsTeXFormat{LaTeX2e}
2\ProvidesPackage{sphinxpackagefootnote}%
3 [2021/02/04 v1.1d footnotehyper adapted to sphinx (Sphinx team)]
4% Provides support for this output mark-up from Sphinx latex writer:
5% - footnote environment
6% - savenotes environment (table templates)
7% - \sphinxfootnotemark
8%
9%%
10%% Package: sphinxpackagefootnote
11%% Version: based on footnotehyper.sty 2021/02/04 v1.1d
12%% as available at https://www.ctan.org/pkg/footnotehyper
13%% License: the one applying to Sphinx
14%%
15%% Refer to the PDF documentation  at https://www.ctan.org/pkg/footnotehyper for
16%% the code comments.
17%%
18%% Differences:
19%% 1. a partial tabulary compatibility layer added (enough for Sphinx mark-up),
20%% 2. use of \spx@opt@BeforeFootnote from sphinx.sty,
21%% 3. use of \sphinxunactivateextrasandspace from sphinx.sty,
22%% 4. macro definition \sphinxfootnotemark,
23%% 5. macro definition \sphinxlongtablepatch
24%% 6. replaced some \undefined by \@undefined
25\newif\iffootnotehyperparse\footnotehyperparsetrue
26\DeclareOption*{\PackageWarning{sphinxpackagefootnote}{Option `\CurrentOption' is unknown}}%
27\ProcessOptions\relax
28\newbox\FNH@notes
29\newtoks\FNH@toks % 1.1c
30\newdimen\FNH@width
31\let\FNH@colwidth\columnwidth
32\newif\ifFNH@savingnotes
33\AtBeginDocument {%
34    \let\FNH@latex@footnote    \footnote
35    \let\FNH@latex@footnotetext\footnotetext
36    \let\FNH@H@@footnotetext   \@footnotetext
37    \let\FNH@H@@mpfootnotetext \@mpfootnotetext
38    \newenvironment{savenotes}
39        {\FNH@savenotes\ignorespaces}{\FNH@spewnotes\ignorespacesafterend}%
40    \let\spewnotes      \FNH@spewnotes
41    \let\footnote       \FNH@footnote
42    \let\footnotetext   \FNH@footnotetext
43    \let\endfootnote    \FNH@endfntext
44    \let\endfootnotetext\FNH@endfntext
45    \@ifpackageloaded{hyperref}
46     {\ifHy@hyperfootnotes
47         \let\FNH@H@@footnotetext\H@@footnotetext
48         \let\FNH@H@@mpfootnotetext\H@@mpfootnotetext
49      \else
50         \let\FNH@hyper@fntext\FNH@nohyp@fntext
51      \fi}%
52     {\let\FNH@hyper@fntext\FNH@nohyp@fntext}%
53}%
54\def\FNH@hyper@fntext{\FNH@fntext\FNH@hyper@fntext@i}%
55\def\FNH@nohyp@fntext{\FNH@fntext\FNH@nohyp@fntext@i}%
56\def\FNH@fntext #1{%
57  \ifx\ifmeasuring@\@undefined
58    \expandafter\@secondoftwo\else\expandafter\@firstofone\fi
59% these two lines modified for Sphinx (tabulary compatibility):
60    {\ifmeasuring@\expandafter\@gobbletwo\else\expandafter\@firstofone\fi}%
61    {\ifx\equation$\expandafter\@gobbletwo\fi #1}%$
62}%
63\long\def\FNH@hyper@fntext@i#1{%
64  \global\setbox\FNH@notes\vbox
65  {\unvbox\FNH@notes
66   \FNH@startnote
67   \@makefntext
68    {\rule\z@\footnotesep\ignorespaces
69     \ifHy@nesting\expandafter\ltx@firstoftwo
70             \else\expandafter\ltx@secondoftwo
71     \fi
72     {\expandafter\hyper@@anchor\expandafter{\Hy@footnote@currentHref}{#1}}%
73     {\Hy@raisedlink
74       {\expandafter\hyper@@anchor\expandafter{\Hy@footnote@currentHref}%
75       {\relax}}%
76      \let\@currentHref\Hy@footnote@currentHref
77      \let\@currentlabelname\@empty
78      #1}%
79     \@finalstrut\strutbox
80    }%
81   \FNH@endnote
82  }%
83}%
84\long\def\FNH@nohyp@fntext@i#1{%
85  \global\setbox\FNH@notes\vbox
86  {\unvbox\FNH@notes
87   \FNH@startnote
88   \@makefntext{\rule\z@\footnotesep\ignorespaces#1\@finalstrut\strutbox}%
89   \FNH@endnote
90  }%
91}%
92\def\FNH@startnote{%
93  \hsize\FNH@colwidth
94  \interlinepenalty\interfootnotelinepenalty
95  \reset@font\footnotesize
96  \floatingpenalty\@MM
97  \@parboxrestore
98  \protected@edef\@currentlabel{\csname p@\@mpfn\endcsname\@thefnmark}%
99  \color@begingroup
100}%
101\def\FNH@endnote{\color@endgroup}%
102\def\FNH@savenotes{%
103  \begingroup
104  \ifFNH@savingnotes\else
105    \FNH@savingnotestrue
106    \let\@footnotetext    \FNH@hyper@fntext
107    \let\@mpfootnotetext  \FNH@hyper@fntext
108    \let\H@@mpfootnotetext\FNH@nohyp@fntext
109    \FNH@width\columnwidth
110    \let\FNH@colwidth\FNH@width
111    \global\setbox\FNH@notes\box\voidb@x
112    \let\FNH@thempfn\thempfn
113    \let\FNH@mpfn\@mpfn
114    \ifx\@minipagerestore\relax\let\@minipagerestore\@empty\fi
115    \expandafter\def\expandafter\@minipagerestore\expandafter{%
116      \@minipagerestore
117      \let\thempfn\FNH@thempfn
118      \let\@mpfn\FNH@mpfn
119    }%
120  \fi
121}%
122\def\FNH@spewnotes {%
123  \if@endpe\ifx\par\@@par\FNH@toks{}\else
124     \FNH@toks\expandafter{\expandafter
125              \def\expandafter\par\expandafter{\par}\@endpetrue}%
126     \expandafter\expandafter\expandafter
127     \FNH@toks
128     \expandafter\expandafter\expandafter
129     {\expandafter\the\expandafter\FNH@toks
130      \expandafter\def\expandafter\@par\expandafter{\@par}}%
131     \expandafter\expandafter\expandafter
132     \FNH@toks
133     \expandafter\expandafter\expandafter
134     {\expandafter\the\expandafter\FNH@toks
135      \expandafter\everypar\expandafter{\the\everypar}}\fi
136  \else\FNH@toks{}\fi
137  \expandafter
138  \endgroup\the\FNH@toks
139  \ifFNH@savingnotes\else
140   \ifvoid\FNH@notes\else
141    \begingroup
142     \let\@makefntext\@empty
143     \let\@finalstrut\@gobble
144     \let\rule\@gobbletwo
145     \ifx\@footnotetext\@mpfootnotetext
146        \expandafter\FNH@H@@mpfootnotetext
147     \else
148        \expandafter\FNH@H@@footnotetext
149     \fi{\unvbox\FNH@notes}%
150    \endgroup
151   \fi
152  \fi
153}%
154\def\FNH@footnote@envname    {footnote}%
155\def\FNH@footnotetext@envname{footnotetext}%
156\def\FNH@footnote{%
157% this line added for Sphinx:
158    \spx@opt@BeforeFootnote
159    \ifx\@currenvir\FNH@footnote@envname
160        \expandafter\FNH@footnoteenv
161    \else
162        \expandafter\FNH@latex@footnote
163    \fi
164}%
165\def\FNH@footnoteenv{%
166% this line added for Sphinx (footnotes in parsed literal blocks):
167    \catcode13=5 \sphinxunactivateextrasandspace
168    \@ifnextchar[%
169      \FNH@footnoteenv@i %]
170      {\stepcounter\@mpfn
171       \protected@xdef\@thefnmark{\thempfn}%
172       \@footnotemark
173       \def\FNH@endfntext@fntext{\@footnotetext}%
174       \FNH@startfntext}%
175}%
176\def\FNH@footnoteenv@i[#1]{%
177    \begingroup
178     \csname c@\@mpfn\endcsname #1\relax
179     \unrestored@protected@xdef\@thefnmark{\thempfn}%
180    \endgroup
181    \@footnotemark
182    \def\FNH@endfntext@fntext{\@footnotetext}%
183    \FNH@startfntext
184}%
185\def\FNH@footnotetext{%
186    \ifx\@currenvir\FNH@footnotetext@envname
187        \expandafter\FNH@footnotetextenv
188    \else
189        \expandafter\FNH@latex@footnotetext
190    \fi
191}%
192\def\FNH@footnotetextenv{%
193    \@ifnextchar[%
194      \FNH@footnotetextenv@i %]
195      {\protected@xdef\@thefnmark{\thempfn}%
196       \def\FNH@endfntext@fntext{\@footnotetext}%
197       \FNH@startfntext}%
198}%
199\def\FNH@footnotetextenv@i[#1]{%
200    \begingroup
201     \csname c@\@mpfn\endcsname #1\relax
202     \unrestored@protected@xdef\@thefnmark{\thempfn}%
203    \endgroup
204    \ifFNH@savingnotes
205      \def\FNH@endfntext@fntext{\FNH@nohyp@fntext}%
206    \else
207      \def\FNH@endfntext@fntext{\FNH@H@@footnotetext}%
208    \fi
209    \FNH@startfntext
210}%
211\def\FNH@startfntext{%
212  \setbox\z@\vbox\bgroup
213    \FNH@startnote
214    \FNH@prefntext
215    \rule\z@\footnotesep\ignorespaces
216}%
217\def\FNH@endfntext {%
218    \@finalstrut\strutbox
219    \FNH@postfntext
220    \FNH@endnote
221    \egroup
222  \begingroup
223    \let\@makefntext\@empty\let\@finalstrut\@gobble\let\rule\@gobbletwo
224    \FNH@endfntext@fntext {\unvbox\z@}%
225  \endgroup
226}%
227\let\FNH@prefntext\@empty
228\let\FNH@postfntext\@empty
229\AtBeginDocument{\iffootnotehyperparse\expandafter\FNH@check\fi}%
230\def\FNH@safeif#1{%
231   \iftrue\csname if#1\endcsname\csname fi\endcsname\expandafter\@firstoftwo
232   \else\csname fi\endcsname\expandafter\@secondoftwo
233   \fi
234}%
235\def\FNH@check{%
236   \ifx\@makefntextFB\@undefined\expandafter\FNH@check@
237                           \else\expandafter\FNH@frenchb@
238   \fi
239}%
240\def\FNH@frenchb@{%
241   \def\FNH@prefntext{%
242     \localleftbox{}%
243     \let\FBeverypar@save\FBeverypar@quote
244     \let\FBeverypar@quote\relax
245     \FNH@safeif{FB@koma}%
246       {\FNH@safeif{FBFrenchFootnotes}%
247          {\ifx\footnote\thanks
248             \let\@@makefnmark\@@makefnmarkTH
249             \@makefntextTH{} % space as in french.ldf
250           \else
251             \let\@@makefnmark\@@makefnmarkFB
252             \@makefntextFB{} % space as in french.ldf
253             \fi
254          }{\let\@@makefnmark\@@makefnmarkORI
255             \@makefntextORI{}% no space as in french.ldf
256          }%
257       }%
258       {\FNH@safeif{FBFrenchFootnotes}%
259          {\@makefntextFB{}}%
260          {\@makefntextORI{}}%
261       }%
262   }%
263   \def\FNH@postfntext{%
264     \let\FBeverypar@quote\FBeverypar@save
265     \localleftbox{\FBeveryline@quote}%
266   }%
267}%
268\def\FNH@check@{%
269    \expandafter\FNH@check@a\@makefntext{1.2!3?4,}%
270                \FNH@@@1.2!3?4,\FNH@@@\relax
271}%
272\long\def\FNH@check@a #11.2!3?4,#2\FNH@@@#3{%
273    \ifx\relax#3\expandafter\FNH@checkagain@
274    \else
275      \def\FNH@prefntext{#1}\def\FNH@postfntext{#2}%
276      \expandafter\FNH@check@b
277    \fi
278}%
279\def\FNH@checkagain@{%
280    \expandafter\FNH@checkagain@a
281    \detokenize\expandafter{\@makefntext{1.2!3?4,}}\relax\FNH@@@
282}%
283\edef\FNH@temp{\noexpand\FNH@checkagain@a ##1\string{1.2!3?4,\string}}%
284\expandafter\def\FNH@temp#2#3\FNH@@@{%
285    \ifx\relax#2%
286      \def\FNH@prefntext{\@makefntext{}}%
287    \else\FNH@bad@makefntext@alert
288    \fi
289}%
290\def\FNH@check@b #1\relax{%
291    \expandafter\expandafter\expandafter\FNH@check@c
292    \expandafter\meaning\expandafter\FNH@prefntext
293    \meaning\FNH@postfntext1.2!3?4,\FNH@check@c\relax
294}%
295\def\FNH@check@c #11.2!3?4,#2#3\relax{%
296    \ifx\FNH@check@c#2\else\FNH@bad@makefntext@alert\fi
297}%
298% slight reformulation for Sphinx
299\def\FNH@bad@makefntext@alert{%
300  \PackageWarningNoLine{sphinxpackagefootnote}%
301    {Footnotes will be sub-optimal, sorry. This is due to the document class or^^J
302  some package modifying macro \string\@makefntext.^^J
303  You can try to report this incompatibility at^^J
304  https://github.com/sphinx-doc/sphinx with this info:}%
305    \typeout{\meaning\@makefntext}%
306    \let\FNH@prefntext\@empty\let\FNH@postfntext\@empty
307}%
308% this macro from original footnote.sty is not used anymore by Sphinx
309% but for simplicity sake let's just keep it as is
310\def\makesavenoteenv{\@ifnextchar[\FNH@msne@ii\FNH@msne@i}%]
311\def\FNH@msne@i #1{%
312  \expandafter\let\csname FNH$#1\expandafter\endcsname %$
313                  \csname #1\endcsname
314  \expandafter\let\csname endFNH$#1\expandafter\endcsname %$
315                  \csname end#1\endcsname
316  \FNH@msne@ii[#1]{FNH$#1}%$
317}%
318\def\FNH@msne@ii[#1]#2{%
319  \expandafter\edef\csname#1\endcsname{%
320    \noexpand\savenotes
321    \expandafter\noexpand\csname#2\endcsname
322  }%
323  \expandafter\edef\csname end#1\endcsname{%
324    \expandafter\noexpand\csname end#2\endcsname
325    \noexpand\expandafter
326    \noexpand\spewnotes
327    \noexpand\if@endpe\noexpand\@endpetrue\noexpand\fi
328  }%
329}%
330%
331% some extras for Sphinx :
332% \sphinxfootnotemark: usable in section titles and silently removed from TOCs.
333\def\sphinxfootnotemark [#1]%
334   {\ifx\thepage\relax\else\sphinxfootref{#1}\fi}%
335% \sphinxfootref:
336% - \spx@opt@BeforeFootnote is from BeforeFootnote sphinxsetup option
337% - \ref:
338%     the latex.py writer inserts a \phantomsection\label{<scope>.<num>}
339%     whenever
340%     - the footnote was explicitly numbered in sources,
341%     - or it was in restrained context and is rendered using footnotetext
342%
343%     These are the two types of footnotes that \sphinxfootnotemark must
344%     handle. But for explicitly numbered footnotes the same number
345%     can be found in document. So a secondary part in  <scope> is updated
346%     at each novel such footnote to know what is the target from then on
347%     for \sphinxfootnotemark and already encountered [1], or [2],...
348%
349% LaTeX package varioref is not supported by hyperref (from its doc: "There
350% are too many problems with varioref. Nobody has time to sort them out.
351% Therefore this package is now unsupported.") So we will simply use our own
352% macros to access the page number of footnote text and decide whether to print
353% it. \pagename is internationalized by latex-babel.
354\def\spx@thefnmark#1#2{%
355  % #1=label for reference, #2=page where footnote was printed
356  \ifx\spx@tempa\spx@tempb
357     % same page
358     #1%
359  \else
360    \sphinxthefootnotemark{#1}{#2}%
361  \fi
362}%
363\def\sphinxfootref@get #1#2#3#4#5\relax{%
364    \def\sphinxfootref@label{#1}%
365    \def\sphinxfootref@page {#2}%
366    \def\sphinxfootref@Href {#4}%
367}%
368\protected\def\sphinxfootref#1{% #1 always explicit number in Sphinx usage
369  \spx@opt@BeforeFootnote
370  \ltx@ifundefined{r@\thesphinxscope.#1}%
371    {\gdef\@thefnmark{?}\H@@footnotemark}%
372    {\expandafter\expandafter\expandafter\sphinxfootref@get
373                 \csname r@\thesphinxscope.#1\endcsname\relax
374     \edef\spx@tempa{\thepage}\edef\spx@tempb{\sphinxfootref@page}%
375     \protected@xdef\@thefnmark{\spx@thefnmark{\sphinxfootref@label}{\sphinxfootref@page}}%
376     \let\spx@@makefnmark\@makefnmark
377     \def\@makefnmark{%
378       \hyper@linkstart{link}{\sphinxfootref@Href}%
379       \spx@@makefnmark
380       \hyper@linkend
381     }%
382     \H@@footnotemark
383     \let\@makefnmark\spx@@makefnmark
384    }%
385}%
386\AtBeginDocument{%
387   % let hyperref less complain
388   \pdfstringdefDisableCommands{\def\sphinxfootnotemark [#1]{}}%
389   % to obtain hyperlinked footnotes in longtable environment we must replace
390   % hyperref's patch of longtable's patch of \@footnotetext by our own
391   \let\LT@p@ftntext\FNH@hyper@fntext
392   % this *requires* longtable to be used always wrapped in savenotes environment
393}%
394\endinput
395%%
396%% End of file `sphinxpackagefootnote.sty'.
397