
Quiero probar si una macro está (a) fuera o (b) dentro de un \footnote
comando, similar a lo que se pregunta en (i)Cómo comprobar si estoy actualmente en una nota a pie de página o no, (iii)Detectar si estoy en un \footnote
?, (iii)nota al pie booleana: cómo comprobar si actualmente hay una nota al piey (iv)Mismo comando con salida X en el cuerpo principal e Y en la nota al pie..
La técnica general es (1) definir un valor booleano, cuyo valor predeterminado es falso; (2) redefinir \footnote
para que establezca el valor booleano en verdadero al ingresar y lo restablezca a falso al salir. Esto requiere anteponer y agregar al \footnote
comando original.
Donde mi pregunta difiere de las respuestas dadas para (i) – (iii) anteriores es que todas hacen la redefinición con a \let
. Sin embargo, aunque a menudo se olvida, el \footnote
comando toma un argumento opcional (para el número de la nota al pie). (Por ejemplo, ver" \footnote
"deManual de referencia no oficial de LaTeX2e (octubre de 2018).) Este hecho debería hacer que su uso sea \let
inapropiado. (Por ejemplo, "Recuerde que uno debenuncause el viejo truco \let\ORIxyz\xzy
... si \xyz
se ha definido con un argumento opcional".xpatch
documentación)
(La respuesta en (iv) redefine \footnotetext
en lugar de \footnote
, lo cual no entiendo).
Por lo tanto, quiero redefinir \footnote
usando los comandos \xpretocmd
y \xapptocmd
desde el xpatch
paquete (anteponer y agregar, respectivamente). (VerLa útil explicación de Enrico.)
El siguiente MWE es mi intento de resolver este problema.
Si comento el \xapptocmd{\footnote}{\togglefalse{inFootnoteCommand}}{}{}
comando adjunto, funciona bien (excepto por el problema obvio de que no restablece el booleano a falso y, por lo tanto, piensa que está en par \footnote
después de salir). Vea este resultado:
Pero cuando dejo el comando adjunto sin comentar, (a) no logra restablecer el valor booleano y (b) la salida se desmorona tanto en el texto del cuerpo como en el texto de la nota al pie, y (c) aparece el error asociado con los \footnote
comandos sí mismo:
Falta \endcsname insertado. \unskip I.38 \footnote [Aquí está la nota al pie:\amIInAFootnote] La secuencia de control marcada no debe aparecer entre \csname y \endcsname.
¿Dónde me equivoco?
Aquí está el 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}
Respuesta1
Si miras la \footnote
definición, encontrarás lo siguiente:
> \footnote=macro:
->\@ifnextchar [\@xfootnote {\stepcounter \@mpfn \protected@xdef \@thefnmark {\
thempfn }\@footnotemark \@footnotetext }.
Esto significa que nunca intenta procesar el texto de la nota como argumento, sino que simplemente lo delega en \@footnotetext
. Cuando parcheas \footnote
, tu \togglefalse
se convierte en el \@footnotetext
argumento y estropea las cosas. Para solucionarlo, basta con aplicar los parches directamente a \@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}
El resultado:
Respuesta2
si agregas
\show\footnote
después de tus parches encontrarás
> \footnote=\protected macro:
->\toggletrue {inFootnoteCommand}\@ifnextchar [\@xfootnote {\stepcounter \@mpfn
\protected@xdef \@thefnmark {\thempfn }\@footnotemark \@footnotetext }\togglefalse {inFootnoteCommand}.
Es decir, está configurando el interruptor en verdadero y falso antes de que se vea el argumento de la nota al pie y rompiendo la vista previa para un argumento opcional como \@ifnextchar
siempre se verá.\togglefalse
No necesita restablecer al final, simplemente configure el interruptor dentro del grupo, o en el caso común de que el único texto establecido en el tamaño de nota al pie sean notas al pie, no necesita ningún interruptor, simplemente puede probar el tamaño de fuente.
\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}