Expandir un comando dentro de otro comando

Expandir un comando dentro de otro comando

Continúo con mi saga para ampliar cosas en LaTeX usando etoolbox.

Esta vez tengo el siguiente código.

\documentclass[8pt]{book}
\usepackage{etoolbox}
\usepackage{hyperref}

\newcount\infoCounter

\newcommand{\addInfoRef}[1]{
\unexpanded{\nameref{\csuse{info#1Label}}}
\cseappto{info#1Ref}{Mentioned in %
                    \unexpanded{\unexpanded{\nameref}}{\csuse{info\currentname Label}}%
                    \unexpanded{\unexpanded{\\}}
                    }
}


\newcommand{\newInfon}[3][]{
\listxadd\listInfo{#2}
\edef\currentname{#2}
\csedef{info#2Label}{infoKey\the\infoCounter}
\advance\infoCounter by 1
\ifstrempty{#1}{}{\csedef{info#2Img}{#1}}
\csedef{info#2Cnt}{#3}
\nullfont#3\normalfont
}

\newcommand{\printInfo}[1]{%
\edef\currentName{#1}
\section{#1}\label{\expandafter\csuse{info#1Label}}%
\csuse{info#1Cnt}
\ifcsname info#1Ref\endcsname
\\\begin{tabular}{p{9cm}}
  \csuse{info#1Ref}
\end{tabular}
\fi}

\begin{document}

\chapter{Tests Result}

\newInfon{Test Case 1}{%
The result was inconclusive.}

\newInfon{Test Case 2}{%
The result was more conclusive than in \addInfoRef{Test Case 1}, but was still inconclusive.}

\newInfon{Test Case 3}{%
The result less conclusive than in \addInfoRef{Test Case 2}, but was still more conclusive than in \addInfoRef{Test Case 1}.}

\printInfo{Test Case 1}
\printInfo{Test Case 2}
\printInfo{Test Case 3}

\end{document}

El resultado deseado es... bueno, CASI lo que se genera:

ingrese la descripción de la imagen aquí

Los dos puntos rojos en la parte superior muestran que se hace referencia a algo antes de tiempo. Si intenta reordenar \printInfo{Test Case X}y notará que las "Menciones" ya no se imprimen correctamente. Por ejemplo, si reordeno:

\printInfo{Test Case 3}
\printInfo{Test Case 2}
\printInfo{Test Case 1}

yo obtengo

ingrese la descripción de la imagen aquí

Es decir, ¡algunas entradas de "Mención" están duplicadas! He considerado hacer algo como

\ifcsname info\currentname#2Switch\endcsname{\relax}{%
  \cseappto{info#2Ref}{Mentioned in...}
}
\csedef{info\currentname#2Switch}{1}

en \addInfoRef, pero eso no funcionó y no pude entender por qué.

¡Cualquier ayuda es apreciada! ¡Gracias de antemano!

Respuesta1

Aquí hay una implementación con expl3(a través de xparse). El \newInfoncomando tiene un argumento opcional que se usará si el primer argumento obligatorio contiene caracteres que no son ASCII (hice un ejemplo): el argumento opcional es solo una clave que se usará siempre que se haga una referencia al caso.

El truco consiste en hacer \addInfoRefdos cosas diferentes y ejecutarlas cuando \newInfonse realiza dentro de un cuadro, de modo que la salida finalmente se descarte.

\documentclass{book}
\usepackage[utf8]{inputenc}
\usepackage[greek,english]{babel}
\usepackage{xparse}
\usepackage{etoolbox}
\usepackage[unicode]{hyperref}

\pdfstringdefDisableCommands{\let\textgreek\relax}

\ExplSyntaxOn

\prop_new:N \g_benedict_info_items_prop
\bool_new:N \l_benedict_info_add_bool

\NewDocumentCommand{\newInfon}{O{#2}mm}
 {
  \prop_gput:Nnn \g_benedict_info_items_prop
   { #1 key }  % key
   { #2 }
  \prop_gput:Nnx \g_benedict_info_items_prop
   { #1 text } % text
   { \tl_trim_spaces:n { #3 } }
  \tl_set:Nn \l__benedict_info_temp_tl { #1 }
  \hbox_set:Nn \l_tmpa_box
   {
    \bool_set_true:N \l_benedict_info_add_bool #3
   }
 }

\NewDocumentCommand{\addInfoRef}{m}
 {
  \bool_if:NTF \l_benedict_info_add_bool
   {
    \seq_if_exist:cF { g_benedict_info_#1_seq }
     {
      \seq_new:c { g_benedict_info_#1_seq }
     }
    \seq_gput_right:cx { g_benedict_info_#1_seq }
     {
      Mentioned ~ in ~ \exp_not:N \nameref{\l__benedict_info_temp_tl label}
     }
   }
   {
    \prop_item:Nn \g_benedict_info_items_prop { #1 key }
   }
 }

\NewDocumentCommand{\printInfo}{m}
 {
  \exp_args:Nx \section {\prop_item:Nn \g_benedict_info_items_prop { #1 key }}\label{#1label}
  \prop_item:Nn \g_benedict_info_items_prop { #1 text }
  \seq_if_exist:cT { g_benedict_info_#1_seq }
   {
    \\*[\medskipamount]
    \begin{tabular}{@{} p{9cm} @{}}
    \seq_use:cn { g_benedict_info_#1_seq } { \\ }
    \end{tabular}
    \par\addvspace{\medskipamount}
   }
 }
\ExplSyntaxOff

\begin{document}

\chapter{Tests Result}

\newInfon[TC1]{Test Case (\textgreek{δοκιμή}) 1}{
  The result was inconclusive.
}

\newInfon{Test Case 2}{
  The result was more conclusive than in \addInfoRef{TC1},
  but was still inconclusive.
}

\newInfon{Test Case 3}{
  The result less conclusive than in \addInfoRef{Test Case 2},
  but was still more conclusive than in \addInfoRef{TC1}.
}

\printInfo{TC1}
\printInfo{Test Case 2}
\printInfo{Test Case 3}

\end{document}

ingrese la descripción de la imagen aquí

Respuesta2

Respondí mi propia pregunta mediante una extensa prueba y error. Básicamente, creé una printingInfovariable, la configuré en 0 y solo la configuré en 1 durante printInfo. Entonces la función addInfoRef solo realiza cseappto si esta impresiónInfo = 0.

Esta es la solución de trabajo:

\documentclass[8pt]{book}
\usepackage{etoolbox}
\usepackage{hyperref}

\newcount\infoCounter

\edef\printingInfo{0}%
\newcommand{\addInfoRef}[1]{%
\ifstrequal{\printingInfo}{0}{\unexpanded{\nameref{\csuse{info#1Label}}}}{%
\cseappto{info#1Ref}{Mentioned in %
\unexpanded{\unexpanded{\nameref}}{\csuse{info\currentname Label}}%
\unexpanded{\unexpanded{\\}}}%
}%
}


\newcommand{\newInfon}[3][]{
\edef\printingInfo{0}%
\edef\currentname{#2}
\csedef{info#2Label}{infoKey\the\infoCounter}
\advance\infoCounter by 1
\ifstrempty{#1}{}{\csedef{info#2Img}{#1}}
\csedef{info#2Cnt}{#3}
\nullfont#3\normalfont
}

\newcommand{\printInfo}[1]{%
\edef\printingInfo{1}%
\edef\currentname{#1}
\section{#1}\label{\expandafter\csuse{info#1Label}}%
\csuse{info#1Cnt}
\ifcsname info#1Ref\endcsname
\\\begin{tabular}{p{9cm}}
  \csuse{info#1Ref}
\end{tabular}
\fi}

\begin{document}

\chapter{Tests Result}

\newInfon{Test Case 1}{%
The result was inconclusive.}

\newInfon{Test Case 2}{%
The result was more conclusive than in \addInfoRef{Test Case 1}, but was still inconclusive.}

\newInfon{Test Case 3}{%
The result less conclusive than in \addInfoRef{Test Case 2}, but was still more conclusive than in \addInfoRef{Test Case 1}.}

\printInfo{Test Case 1}
\printInfo{Test Case 2}
\printInfo{Test Case 3}

\end{document}

El único problema que queda ahora es el espacio sobrante entre el "capítulo 1" y las secciones.

información relacionada