
我想測試巨集是 (a) 外部還是 (b) 內部\footnote
命令內部,類似於 (i) 中的要求如何測試我目前是否在腳註中,(二)檢測我是否處於\footnote
?,(三)註腳布林值:如何檢查目前是否在腳註中,和(四)與主體中的輸出 X 和腳註中的 Y 相同的命令。
一般技巧是(1)定義一個boolean,預設為false; (2) 重新定義\footnote
,以便在進入時將布林值設為 true,並在退出時將其重設為 false。這需要在原始命令的前面和後面添加\footnote
。
我的問題與上面 (i)–(iii) 給出的答案不同的是,它們都使用\let
.然而,儘管它經常被遺忘,\footnote
命令帶有一個可選參數(腳註的編號)。 (例如,參見」\footnote
“的LaTeX2e 非官方參考手冊(2018 年 10 月).)這個事實應該使使用\let
不合適。 (例如,「記住,一個人必須絕不使用舊技巧\let\ORIxyz\xzy
…如果\xyz
已經用可選參數定義了。xpatch
文件)
((iv)中的答案重新定義\footnotetext
而不是\footnote
,我不明白。)
因此,我想\footnote
使用命令\xpretocmd
重新定義\xapptocmd
xpatch
命令重新定義(分別前置和附加)。 (看恩里科的有用解釋.)
下面的MWE是我嘗試解決這個問題的。
如果我註解掉附加\xapptocmd{\footnote}{\togglefalse{inFootnoteCommand}}{}{}
命令,它會很好地工作(除了一個明顯的問題,它不會將布林值重置為 false,因此,認為它在\footnote
退出後即使在)。看到這個輸出:
但是,當我不註釋附加命令時,(a)它無法重置布林值,(b)輸出在正文和腳註文字中都崩潰了,(c)我收到與命令相關的\footnote
錯誤本身:
插入缺少 \endcsname。 \unskip I.38 \腳註 [這是註腳:\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
.當你 patch 時\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}.
也就是說,您在看到腳註參數之前將切換設為 true 和 false,並打破了可選參數的前瞻,就像\@ifnextchar
總是會看到的那樣\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}