将当前计数器值传递给堆栈数据结构

将当前计数器值传递给堆栈数据结构

我正在尝试将堆栈数据结构与\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 并未明确将 的当前值推送到bracketpairingcounterbracketpairingstack,而是推送逐字命令字符串而不是所需的整数。因此,当每个\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;实际上它可能会导致不合时宜的扩展(在这种情况下不是)。

相关内容