I'm trying to combine a stack data structure with a \newcounter{}
definition so that I can automatically pair together a collection of points scattered throughout my text.
Each point is either marked as an \openbracket
or a \closebracket
, and automatically paired to an oppositely defined point in order to form \openbracket
-\closebracket
pairs. Closed pairs may be nested within other closed bracket pairs, and each pair of open/closed points are marked with the tikz nodes \node(openX) {};
and \node(closeX) {};
respectively [where X is an integer defined by an external counter].
For example:
\openbraket First tier
\openbraket Second tier A
\openbraket Third tier
\closebracket
\closebracket
\openbracket Second tier B
\closebracket
\closebracket
should automatically pair the above \openbracket
\closebracket
points into 4 closed bracket pairs; one First tier bracket, containing two Second tier brackets, the first (A) of which contains a single Third tier bracket. My MWE should also pop data from the stack structure so that the tikz nodes in the above example are defined as:
(open0) First tier (open1) Second tier A (open2) Third tier
(close2) (close1) (open3) Second tier B (close3) (close0)
Using the help of Push/Pop or save a length/dimension?, Save current value of counter in a command, and Passing stack data to tikz node names, I have managed to defined a working stack data structure and have figured out a method with which to correctly pass stack data to my \tikzmark
macro.
However, the MWE below does not explicitly push the current value of the bracketpairingcounter
onto the bracketpairingstack
, and pushes the verbatim command string instead of the required integer number. Thus when each \node(closeX) {};
tikz mark is popped from the data stack, each node number is evaluated at the last value of bracketpairingcounter
, instead of the different integers sequentially pushed onto the stack.
I'm hoping that the numbering problem can be fixed by somehow forcing my LaTeX code to immediately evaluate the value of \openbracketname
below, but I can't for the life of me get \expandafter
or \edef{}
to work in this case...
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}
\edef\temp{{#1}}
, to begin with.