
Ich möchte testen, ob sich ein Makro (a) außerhalb oder (b) innerhalb eines \footnote
Befehls befindet, ähnlich wie in (i) gefragt.Wie kann ich testen, ob ich mich gerade in einer Fußnote befinde oder nicht?, (ii)Erkennen, ob ich mich in einem befinde \footnote
?, (iii)Fußnote Boolean: So überprüfen Sie, ob sich derzeit eine Fußnote befindetund (iv)derselbe Befehl mit Ausgabe X im Hauptteil und Y in der Fußnote.
Die allgemeine Vorgehensweise besteht darin, (1) einen Booleschen Wert zu definieren, der standardmäßig auf „false“ gesetzt ist; (2) ihn \footnote
so umzudefinieren, dass er den Booleschen Wert beim Eintritt auf „true“ setzt und beim Verlassen auf „false“ zurücksetzt. Dies erfordert ein Voranstellen und Anhängen an den ursprünglichen \footnote
Befehl.
Meine Frage unterscheidet sich von den Antworten zu (i)–(iii) oben darin, dass sie alle die Neudefinition mit einem durchführen \let
. Allerdings, obwohl es oft vergessen wird, \footnote
nimmt der Befehl ein optionales Argument an (für die Nummer der Fußnote). (Siehe z. B." \footnote
"vonInoffizielles Referenzhandbuch für LaTeX2e (Oktober 2018).) Diese Tatsache sollte die Verwendung von \let
unangemessen machen. (Zum Beispiel: „Denken Sie daran, dass manniemalsverwenden Sie den alten Trick \let\ORIxyz\xzy
… wenn \xyz
mit einem optionalen Argument definiert wurde."xpatch
Dokumentation)
(Die Antwort in (iv) definiert \footnotetext
neu statt \footnote
, was ich nicht verstehe.)
Daher möchte ich \footnote
using die Befehle \xpretocmd
und \xapptocmd
aus dem xpatch
Paket neu definieren (um jeweils voranzustellen und anzuhängen). (SieheEnricos hilfreiche Erklärung.)
Das folgende MWE ist mein Versuch, dieses Problem zu lösen.
Wenn ich den Anfügebefehl auskommentiere \xapptocmd{\footnote}{\togglefalse{inFootnoteCommand}}{}{}
, funktioniert es einwandfrei (mit Ausnahme des offensichtlichen Problems, dass der Boolesche Wert nicht auf „false“ zurückgesetzt wird und daher \footnote
nach dem Beenden denkt, er befinde sich im geraden Zustand). Sehen Sie sich diese Ausgabe an:
Aber wenn ich den Anfügebefehl unkommentiert lasse, (a) schlägt das Zurücksetzen des Booleschen Werts fehl, (b) fällt die Ausgabe sowohl im Haupttext als auch im Fußnotentext auseinander und (c) erhalte ich den mit dem \footnote
Befehl selbst verknüpften Fehler:
Fehlendes \endcsname eingefügt. \unskip I.38 \footnote [Hier ist die Fußnote:\amIInAFootnote] Die markierte Steuersequenz sollte nicht zwischen \csname und \endcsname erscheinen.
Was mache ich falsch?
Hier ist das MWE:
\documentclass{article}
\usepackage{xcolor}
\usepackage{xpatch}
\usepackage{etoolbox}
\newtoggle{inFootnoteCommand}
\togglefalse{inFootnoteCommand}
\newcommand{\amIInAFootnote}{%
\iftoggle{inFootnoteCommand}{%
\textcolor{blue}{You are in a footnote.}
}{%
\textcolor{red}{You are NOT in a footnote.}
}%
}
\parindent=0pt
\begin{document}
This line intentionally left blank %To move the text closer to the footnote
\vspace{400pt}
\xpretocmd{\footnote}{\toggletrue{inFootnoteCommand}}{SUCCESS\\}{FAIL\\}
\xapptocmd{\footnote}{\togglefalse{inFootnoteCommand}}{SUCCESS\\}{FAIL\\}
Before a footnote: \amIInAFootnote.
At the end of this sentence is a footnote:%
\footnote{Here’s the footnote: \amIInAFootnote}
Now, I'm back from the footnote: \amIInAFootnote
\end{document}
Antwort1
Wenn Sie sich die Definition ansehen \footnote
, werden Sie Folgendes feststellen:
> \footnote=macro:
->\@ifnextchar [\@xfootnote {\stepcounter \@mpfn \protected@xdef \@thefnmark {\
thempfn }\@footnotemark \@footnotetext }.
Das bedeutet, dass es nie versucht, den Fußnotentext als Argument zu verarbeiten, sondern dies einfach an delegiert \@footnotetext
. Wenn Sie patchen \footnote
, \togglefalse
wird Ihr zum \@footnotetext
Argument und bringt alles durcheinander. Um das zu beheben, reicht es aus, Ihre Patches direkt auf anzuwenden \@footnotetext
:
\documentclass{article}
\usepackage{xcolor}
\usepackage{xpatch}
\usepackage{etoolbox}
\newtoggle{inFootnoteCommand}
\togglefalse{inFootnoteCommand}
\newcommand{\amIInAFootnote}{%
\iftoggle{inFootnoteCommand}{%
\textcolor{blue}{You are in a footnote.}
}{%
\textcolor{red}{You are NOT in a footnote.}
}%
}
\parindent=0pt
\begin{document}
This line intentionally left blank %To move the text closer to the footnote
\vspace{400pt}
\makeatletter
\xpretocmd{\@footnotetext}{\toggletrue{inFootnoteCommand}}{SUCCESS\\}{FAIL\\}
\xapptocmd{\@footnotetext}{\togglefalse{inFootnoteCommand}}{SUCCESS\\}{FAIL\\}
\makeatother
Before a footnote: \amIInAFootnote.
At the end of this sentence is a footnote:%
\footnote{Here’s the footnote: \amIInAFootnote}
Now, I'm back from the footnote: \amIInAFootnote
\end{document}
Das Ergebnis:
Antwort2
Wenn Sie hinzufügen
\show\footnote
nach Ihren Patches finden Sie
> \footnote=\protected macro:
->\toggletrue {inFootnoteCommand}\@ifnextchar [\@xfootnote {\stepcounter \@mpfn
\protected@xdef \@thefnmark {\thempfn }\@footnotemark \@footnotetext }\togglefalse {inFootnoteCommand}.
Das heißt, Sie setzen den Schalter auf true und false, bevor das Fußnotenargument angezeigt wird, und unterbrechen die Vorausschau für ein optionales Argument, wie \@ifnextchar
es immer angezeigt wird\togglefalse
Sie müssen am Ende kein Zurücksetzen durchführen, sondern können den Umschalter einfach innerhalb der Gruppe festlegen. Im häufigen Fall, dass der einzige auf Fußnotengröße festgelegte Text Fußnoten sind, benötigen Sie überhaupt keinen Umschalter, sondern können einfach die Schriftgröße testen.
\documentclass{article}
\usepackage{xcolor}
\usepackage{etoolbox}
\newtoggle{inFootnoteCommand}
\togglefalse{inFootnoteCommand}
\makeatletter
\let\saved@makefntext\@makefntext
\def\@makefntext#1{\saved@makefntext{\toggletrue{inFootnoteCommand}#1}}
\parindent=0pt
\begin{document}
This line intentionally left blank %To move the text closer to the footnote
\vspace{400pt}
\newcommand{\amIInAFootnote}{%
\iftoggle{inFootnoteCommand}{%
\textcolor{blue}{You are in a footnote.}%%%
}{%
\textcolor{red}{You are NOT in a footnote.}%%%
}%
}
Before a footnote: \amIInAFootnote.
At the end of this sentence is a footnote:%
\footnote{Here’s the footnote: \amIInAFootnote}
Now, I'm back from the footnote: \amIInAFootnote
\end{document}