Передача текущего значения счетчика в структуру данных стека

Передача текущего значения счетчика в структуру данных стека

Я пытаюсь объединить структуру данных стека с \newcounter{}определением, чтобы иметь возможность автоматически объединять вместе набор точек, разбросанных по всему тексту.

Каждая точка либо помечена как \openbracketили \closebracket, и автоматически спаривается с противоположно определенной точкой для формирования пар \openbracket- \closebracket. Закрытые пары могут быть вложены в другие пары закрытых скобок, и каждая пара открытых/закрытых точек помечена узлами tikz \node(openX) {};и \node(closeX) {};соответственно [где X - целое число, определяемое внешним счетчиком].

Например:

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

должен автоматически объединить вышеуказанные \openbracket \closebracketточки в 4 пары закрытых скобок; одна скобка первого уровня, содержащая две скобки второго уровня, первая из которых (A) содержит одну скобку третьего уровня. Мой MWE должен также извлечь данные из структуры стека, чтобы узлы tikz в приведенном выше примере были определены как:

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

Используя помощьВставить/вытащить или сохранить длину/размер?,Сохранить текущее значение счетчика в команде, иПередача данных стека в имена узлов tikzМне удалось определить рабочую структуру данных стека и придумать метод, с помощью которого можно правильно передавать данные стека в мой \tikzmarkмакрос.

Однако MWE ниже явно не помещает текущее значение в bracketpairingcounter, bracketpairingstackа помещает дословную командную строку вместо требуемого целого числа. Таким образом, когда каждая \node(closeX) {};метка tikz выталкивается из стека данных, каждый номер узла оценивается по последнему значению bracketpairingcounter, вместо различных целых чисел, последовательно помещаемых в стек.

Я надеюсь, что проблему с нумерацией можно решить, заставив мой код LaTeX немедленно вычислять значение, \openbracketnameуказанное ниже, но я не могу заставить себя \expandafterработать \edef{}в этом случае...

МВЭ

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

решение1

Вы хотите сделать \edef\temp{{#1}}, но вы также можете упростить определение \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}

введите описание изображения здесь

С \edef\tmp{{#1}\the#2}мы полностью расширяем #1и добавляем нерасширенное содержимое регистра токена #2, так как \the\tokenregisterне продолжает расширяться после того, \theкак действовал, чтобы доставить содержимое регистра. Затем мы устанавливаем, #2чтобы содержать расширение (только один уровень) \tmp.

Обратите внимание, что это \ignorespacesне нужно, так как вызов \pushобнаружит \tikzmark; на самом деле это может привести к несвоевременным расширениям (не в этом случае).

Связанный контент