Problembehebung durch Anhängen an den \footnote-Befehl. „Fehlender \endcsname eingefügt“

Problembehebung durch Anhängen an den \footnote-Befehl. „Fehlender \endcsname eingefügt“

Ich möchte testen, ob sich ein Makro (a) außerhalb oder (b) innerhalb eines \footnoteBefehls 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 \footnoteso 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 \footnoteBefehl.

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, \footnotenimmt 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 \letunangemessen machen. (Zum Beispiel: „Denken Sie daran, dass manniemalsverwenden Sie den alten Trick \let\ORIxyz\xzy… wenn \xyzmit einem optionalen Argument definiert wurde."xpatchDokumentation)

(Die Antwort in (iv) definiert \footnotetextneu statt \footnote, was ich nicht verstehe.)

Daher möchte ich \footnoteusing die Befehle \xpretocmdund \xapptocmdaus dem xpatchPaket 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 \footnotenach dem Beenden denkt, er befinde sich im geraden Zustand). Sehen Sie sich diese Ausgabe an:

Bildbeschreibung hier eingeben

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 \footnoteBefehl 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.

Hier ist die Ausgabe: Bildbeschreibung hier eingeben

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, \togglefalsewird Ihr zum \@footnotetextArgument 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:

Bildbeschreibung hier eingeben

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 \@ifnextchares 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.

Bildbeschreibung hier eingeben

\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}

verwandte Informationen