通过附加到 \footnote 命令来修补问题。“缺少 \endcsname 插入”

通过附加到 \footnote 命令来修补问题。“缺少 \endcsname 插入”

我想测试宏是否 (a) 在命令之外或 (b) 在\footnote命令之内,类似于 (i) 中要求的如何测试我当前是否在脚注中(二)检测我是否处于\footnote(三)脚注布尔值:如何检查当前是否在脚注中,以及(四)相同的命令,在主体中输出 X,在脚注中输出 Y

通用方法是 (1) 定义一个布尔值,默认为 false;(2) 重新定义\footnote,以便在进入时将布尔值设置为 true,并在退出时将其重置为 false。这需要在原始命令前面添加和后面添加\footnote

我的问题与上述 (i)–(iii) 的答案不同之处在于,它们都使用 进行重新定义\let。然而,尽管经常被遗忘,但该\footnote命令带有一个可选参数(用于脚注的编号)。(例如,参见\footnoteLaTeX2e 非官方参考手册(2018 年 10 月))这一事实使得使用\let不合适。(例如,“记住,必须绝不使用老技巧\let\ORIxyz\xzy...如果\xyz已经用可选参数定义。”xpatch文档

((iv)中的答案重新定义了\footnotetext而不是\footnote,我不明白。)

因此,我想使用包中的\footnote命令\xpretocmd和命令重新定义(分别添加到前面和附加到后面)。(参见\xapptocmdxpatchEnrico 的有益解释

下面的 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}.

也就是说,在看到脚注参数之前,您要将切换设置为 true 和 false,并打破对可选参数的前瞻,就像\@ifnextchar总是会看到的那样\togglefalse

您不需要在最后重置,只需在组内设置切换,或者在常见情况下,在脚注大小设置的唯一文本是脚注,您根本不需要切换,您可以简单地测试字体大小。

在此处输入图片描述

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

相关内容