Pasar el valor del contador actual a la estructura de datos de la pila

Pasar el valor del contador actual a la estructura de datos de la pila

Estoy intentando combinar una estructura de datos de pila con una \newcounter{}definición para poder emparejar automáticamente una colección de puntos dispersos por todo mi texto.

Cada punto se marca como \openbracketo \closebrackety se empareja automáticamente con un punto definido de manera opuesta para formar \openbracketpares \closebracket. Los pares cerrados pueden anidarse dentro de otros pares de corchetes cerrados, y cada par de puntos abiertos/cerrados están marcados con los nodos tikz \node(openX) {};y \node(closeX) {};respectivamente [donde X es un número entero definido por un contador externo].

Por ejemplo:

\openbraket First tier
    \openbraket Second tier A
        \openbraket Third tier
        \closebracket 
    \closebracket 
    \openbracket Second tier B
    \closebracket 
\closebracket 

debería emparejar automáticamente los \openbracket \closebracketpuntos anteriores en 4 pares de corchetes cerrados; un grupo de primer nivel, que contiene dos grupos de segundo nivel, el primero (A) de los cuales contiene un único grupo de tercer nivel. Mi MWE también debería extraer datos de la estructura de la pila para que los nodos tikz en el ejemplo anterior se definan como:

(open0) First tier (open1) Second tier A (open2) Third tier 
(close2) (close1) (open3)  Second tier B (close3) (close0)

Usando la ayuda de¿Empujar/pop o guardar una longitud/dimensión?,Guardar el valor actual del contador en un comando, yPasar datos de la pila a nombres de nodos tikz, Logré definir una estructura de datos de pila funcional y descubrí un método con el cual pasar correctamente los datos de la pila a mi \tikzmarkmacro.

Sin embargo, el MWE a continuación no inserta explícitamente el valor actual de bracketpairingcounteren bracketpairingstacke inserta la cadena de comando textual en lugar del número entero requerido. Por lo tanto, cuando cada \node(closeX) {};marca tikz se extrae de la pila de datos, cada número de nodo se evalúa con el último valor de bracketpairingcounter, en lugar de los diferentes números enteros insertados secuencialmente en la pila.

Espero que el problema de numeración pueda solucionarse obligando de alguna manera a mi código LaTeX a evaluar inmediatamente el valor de \openbracketnameabajo, pero no puedo por mi vida conseguir \expandaftero \edef{}trabajar en este caso...

MWE

\documentclass[openany]{article}
\usepackage{tikz}

%Define stack data structure commands (\push, \pop, \splitstack)
\newtoks\braketpairingstack
\braketpairingstack={\empty}

    \def\push#1#2{%
        \def\tmp{{#1}}% 
        \expandafter\expandafter\expandafter%
        #2\expandafter\expandafter\expandafter{\expandafter\tmp\the#2}%
    \ignorespaces}

    \def\pop#1#2{%
        \expandafter\splitstack\the#1\stop{#1}{#2}%
    }

    \def\splitstack#1#2\stop#3#4{% 
        \def\tmp{#1}
        \ifx\tmp\empty 
        \else
            \def#4{#1}\global#3={#2}%
        \fi
    } 

%Define \tikzmark command
\def\tikzmark#1{%
    \tikz[remember picture, overlay]\node[red](#1) {#1};%
}

%Define bracket pair counting commands (\openbracket, \closebracket)
\newcounter{bracketpairingcounter}

    \newcommand{\openbraket}{%
        \expandafter\edef\csname openbracketname\endcsname{\thebracketpairingcounter}%
        \push{\openbracketname}{\braketpairingstack}%
        \tikzmark{open\openbracketname}%
        \stepcounter{bracketpairingcounter}%
    }

    \newcommand{\closebraket}{%
        \pop{\braketpairingstack}{\closebracketname}%
        \tikzmark{close\closebracketname}%
    }

%Begin MWE document
\begin{document}
    \openbraket Open first bracket.\\ %Correctly marked as open0
    \openbraket Open second bracket.\\ %Correctly marked as open1

    Close second bracket. \closebraket\\ %Correctly marked as close1 
    Close first bracket. \closebraket\\ %Incorrectly marked as close1
\end{document}

Respuesta1

Quieres hacerlo , pero también \edef\temp{{#1}}puedes simplificar la definición y otras partes del código.\push

\documentclass[openany]{article}
\usepackage{tikz}

%Define stack data structure commands (\push, \pop, \splitstack)
\newtoks\braketpairingstack
\braketpairingstack={\empty}

\def\push#1#2{%
  \edef\tmp{{#1}\the#2}%
  #2=\expandafter{\tmp}%
}

\def\pop#1#2{%
  \expandafter\splitstack\the#1\stop{#1}{#2}%
}

\def\splitstack#1#2\stop#3#4{% 
  \def\tmp{#1}%
  \ifx\tmp\empty
  \else
    \def#4{#1}\global#3={#2}%
  \fi
} 

%Define \tikzmark command
\def\tikzmark#1{%
  \tikz[remember picture, overlay]\node[red](#1) {#1};%
}

%Define bracket pair counting commands (\openbracket, \closebracket)
\newcounter{bracketpairingcounter}

\newcommand{\openbraket}{%
   \edef\openbracketname{\thebracketpairingcounter}%
   \push{\openbracketname}{\braketpairingstack}%
   \tikzmark{open\openbracketname}%
   \stepcounter{bracketpairingcounter}%
}

\newcommand{\closebraket}{%
  \pop{\braketpairingstack}{\closebracketname}%
  \tikzmark{close\closebracketname}%
}

%Begin MWE document
\begin{document}

\openbraket Open first bracket. %Correctly marked as open0

\openbraket Open second bracket. %Correctly marked as open1

Close second bracket. \closebraket %Correctly marked as close1 

Close first bracket. \closebraket %Correctly marked as close0
\end{document}

ingrese la descripción de la imagen aquí

Con \edef\tmp{{#1}\the#2}expandimos #1y agregamos completamente el contenido no expandido del registro de token #2, ya que \the\tokenregisterno continúa expandiéndose después de \thehaber actuado para entregar el contenido del registro. Luego configuramos #2para contener la expansión (solo un nivel) de \tmp.

Tenga en cuenta que \ignorespaceses innecesario, ya que la llamada de \pushwill find \tikzmark; de hecho podría provocar ampliaciones inoportunas (no en este caso).

información relacionada