\footnote コマンドに追加してパッチを適用する際に問題が発生しました。「挿入された \endcsname がありません」

\footnote コマンドに追加してパッチを適用する際に問題が発生しました。「挿入された \endcsname がありません」

マクロが (a) コマンドの外側にあるか (b)\footnoteコマンドの内側にあるかをテストしたいのですが、これは (i) で尋ねられていることと同様です。現在脚注にいるかどうかをテストする方法、(ii)私が ? にいるかどうかを検出します\footnote、(iii)脚注ブール値: 現在脚注内にあるかどうかを確認する方法、および(iv)本文にXを出力し、脚注にYを出力する同じコマンド

一般的な手法は、(1) ブール値を定義し、デフォルトで false に設定する、(2)\footnote開始時にブール値を true に設定し、終了時に false にリセットするように再定義することです。これには、元のコマンドの先頭と末尾に追加する必要があります\footnote

私の質問が上記の (i)~(iii) の回答と異なるのは、それらはすべて を使って再定義を行うという点です\let。しかし、忘れられがちですが、\footnoteコマンドはオプションの引数(脚注の番号)を取ります。(例:\footnoteLaTeX2e 非公式リファレンスマニュアル (2018 年 10 月)) この事実により、使用は\let不適切であると考えられます。(例: 「覚えておいてほしいのは、一度もないオプションの引数で定義されている\let\ORIxyz\xzy場合は、古いトリックを使用します。"\xyzxpatchドキュメンテーション

((iv)の答えは\footnotetextではなくを再定義しますが\footnote、これは理解できません。)

そこで、パッケージの\footnoteコマンド\xpretocmdとコマンドを使用して再定義したいと思います(それぞれ先頭と末尾に追加します)。(\xapptocmdxpatchエンリコの役立つ説明

以下の MWE は、この問題を解決するための私の試みです。

追加\xapptocmd{\footnote}{\togglefalse{inFootnoteCommand}}{}{}コマンドをコメント アウトすると、正常に動作します (ただし、ブール値が false にリセットされず、終了した後も実行中であると認識されるという明らかな問題は除きます\footnote)。次の出力を参照してください。

ここに画像の説明を入力してください

しかし、追加コマンドをコメントアウトせずに残すと、(a) ブール値のリセットに失敗し、(b) 本文と脚注テキストの両方で出力が崩れ、(c) コマンド\footnote自体に関連するエラーが発生します。

挿入されていない \endcsname があります。 \unskip I.38 \footnote [ここに脚注があります:\amIInAFootnote] マークされた制御シーケンスは、\csname と \endcsname の間に出現してはなりません。

出力は次のとおりです。 ここに画像の説明を入力してください

どこが間違っているのでしょうか?

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}

答え1

定義を見ると\footnote、次のことがわかります。

> \footnote=macro:
->\@ifnextchar [\@xfootnote {\stepcounter \@mpfn \protected@xdef \@thefnmark {\
thempfn }\@footnotemark \@footnotetext }.

これは、 fottnote テキストを引数として処理しようとせず、単に に委譲することを意味します\@footnotetext。 にパッチを適用すると\footnote、 が引数\togglefalseとなり\@footnotetext、問題が発生します。これを修正するには、 に直接パッチを適用するだけで十分です\@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}

結果:

ここに画像の説明を入力してください

答え2

追加すると

\show\footnote

パッチを当てた後に

> \footnote=\protected macro:
->\toggletrue {inFootnoteCommand}\@ifnextchar [\@xfootnote {\stepcounter \@mpfn
 \protected@xdef \@thefnmark {\thempfn }\@footnotemark \@footnotetext }\togglefalse {inFootnoteCommand}.

\@ifnextcharつまり、脚注引数が表示される前にトグルをtrueとfalseに設定し、常に表示されるオプション引数の先読みを中断します。\togglefalse

最後にリセットする必要はなく、グループ内でトグルを設定するだけです。または、footnotesize に設定されているテキストが脚注のみである一般的なケースでは、トグルはまったく必要なく、フォント サイズをテストするだけで済みます。

ここに画像の説明を入力してください

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

関連情報