Parche de problemas agregando al comando \footnote. "Falta \endcsname insertado"

Parche de problemas agregando al comando \footnote. "Falta \endcsname insertado"

Quiero probar si una macro está (a) fuera o (b) dentro de un \footnotecomando, 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 \footnotepara que establezca el valor booleano en verdadero al ingresar y lo restablezca a falso al salir. Esto requiere anteponer y agregar al \footnotecomando 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 \footnotecomando 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 \letinapropiado. (Por ejemplo, "Recuerde que uno debenuncause el viejo truco \let\ORIxyz\xzy... si \xyzse ha definido con un argumento opcional".xpatchdocumentación)

(La respuesta en (iv) redefine \footnotetexten lugar de \footnote, lo cual no entiendo).

Por lo tanto, quiero redefinir \footnoteusando los comandos \xpretocmdy \xapptocmddesde el xpatchpaquete (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 \footnotedespués de salir). Vea este resultado:

ingrese la descripción de la imagen aquí

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

Aquí está el resultado: ingrese la descripción de la imagen aquí

¿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 \footnotedefinició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 \togglefalsese convierte en el \@footnotetextargumento 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:

ingrese la descripción de la imagen aquí

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

ingrese la descripción de la imagen aquí

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

información relacionada