Passando o valor atual do contador para empilhar a estrutura de dados

Passando o valor atual do contador para empilhar a estrutura de dados

Estou tentando combinar uma estrutura de dados de pilha com uma \newcounter{}definição para poder emparelhar automaticamente uma coleção de pontos espalhados pelo meu texto.

Cada ponto é marcado como um \openbracketou um \closebrackete automaticamente emparelhado com um ponto definido de forma oposta para formar \openbracketpares \closebracket. Pares fechados podem ser aninhados dentro de outros pares de colchetes fechados, e cada par de pontos abertos/fechados são marcados com os nós tikz \node(openX) {};e \node(closeX) {};respectivamente [onde X é um número inteiro definido por um contador externo].

Por exemplo:

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

deve emparelhar automaticamente os \openbracket \closebracketpontos acima em 4 pares de colchetes fechados; um colchete de primeiro nível, contendo dois colchetes de segundo nível, o primeiro (A) dos quais contém um único colchete de terceiro nível. Meu MWE também deve extrair dados da estrutura da pilha para que os nós tikz no exemplo acima sejam definidos como:

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

Usando a ajuda deEmpurrar/Pop ou salvar um comprimento/dimensão?,Salva o valor atual do contador em um comando, ePassando dados da pilha para nomes de nós tikz, consegui definir uma estrutura de dados de pilha funcional e descobri um método para passar corretamente os dados da pilha para minha \tikzmarkmacro.

No entanto, o MWE abaixo não envia explicitamente o valor atual de bracketpairingcounterpara bracketpairingstacke envia a string de comando literal em vez do número inteiro necessário. Assim, quando cada \node(closeX) {};marca tikz é retirada da pilha de dados, cada número de nó é avaliado no último valor de bracketpairingcounter, em vez dos diferentes números inteiros colocados sequencialmente na pilha.

Espero que o problema de numeração possa ser corrigido forçando de alguma forma meu código LaTeX a avaliar imediatamente o valor \openbracketnameabaixo, mas não consigo, de forma alguma, obter \expandafterou \edef{}trabalhar neste 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}

Responder1

Você deseja fazer isso \edef\temp{{#1}}, mas também pode simplificar a definição \pushe outras partes do código.

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

insira a descrição da imagem aqui

Com \edef\tmp{{#1}\the#2}expandimos #1e adicionamos completamente o conteúdo não expandido do registrador token #2, já que \the\tokenregisternão continua expandindo após \theter agido para entregar o conteúdo do registrador. Então definimos #2para conter a expansão (apenas um nível) de \tmp.

Observe que isso \ignorespacesé desnecessário, pois a chamada de \pushwill find \tikzmark; na verdade, isso poderia causar expansões prematuras (não neste caso).

informação relacionada