スタック データ構造と\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
上記のポイントは、自動的に 4 つの閉じた括弧のペアにペアリングされます\openbracket
\closebracket
。1 つの第 1 層の括弧には 2 つの第 2 層の括弧が含まれ、最初の括弧 (A) には 1 つの第 3 層の括弧が含まれます。私の 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
後は拡張が続かないためです。次に、を の拡張 (1 レベルのみ) を含むように\the
設定します。#2
\tmp
\ignorespaces
の呼び出しで\push
が見つかることから、は不要であることに注意してください\tikzmark
。実際には、 は予期しない展開を引き起こす可能性があります (この場合はそうではありません)。