將當前計數器值傳遞給堆疊資料結構

將當前計數器值傳遞給堆疊資料結構

我正在嘗試將堆疊資料結構與\newcounter{}定義結合起來,以便我可以自動將分散在文字中的點的集合配對在一起。

每個點都標記為 an\openbracket或 a \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;實際上它可能會導致不合時宜的擴張(不是在這種情況下)。

相關內容