Ich versuche, eine Stapeldatenstruktur mit einer \newcounter{}
Definition zu kombinieren, sodass ich eine Sammlung von Punkten, die über meinen Text verstreut sind, automatisch zusammenführen kann.
Jeder Punkt wird entweder als \openbracket
oder markiert \closebracket
und automatisch mit einem entgegengesetzt definierten Punkt gepaart, um \openbracket
- \closebracket
Paare zu bilden. Geschlossene Paare können in andere geschlossene Klammerpaare verschachtelt werden, und jedes Paar offener/geschlossener Punkte wird mit den Tikz-Knoten \node(openX) {};
bzw. markiert \node(closeX) {};
[wobei X eine Ganzzahl ist, die durch einen externen Zähler definiert wird].
Zum Beispiel:
\openbraket First tier
\openbraket Second tier A
\openbraket Third tier
\closebracket
\closebracket
\openbracket Second tier B
\closebracket
\closebracket
sollte die obigen Punkte automatisch \openbracket
\closebracket
in 4 geschlossene Klammerpaare zusammenfassen; eine Klammer der ersten Ebene, die zwei Klammern der zweiten Ebene enthält, von denen die erste (A) eine einzelne Klammer der dritten Ebene enthält. Mein MWE sollte auch Daten aus der Stapelstruktur herausholen, sodass die Tikz-Knoten im obigen Beispiel wie folgt definiert sind:
(open0) First tier (open1) Second tier A (open2) Third tier
(close2) (close1) (open3) Second tier B (close3) (close0)
Mithilfe vonPush/Pop oder Länge/Dimension speichern?,Aktuellen Wert des Zählers in einem Befehl speichern, UndÜbergeben von Stapeldaten an Tikz-Knotennamenist es mir gelungen, eine funktionierende Stapeldatenstruktur zu definieren und habe eine Methode herausgefunden, mit der ich Stapeldaten korrekt an mein \tikzmark
Makro übergeben kann.
Der folgende MWE überträgt jedoch nicht explizit den aktuellen Wert von bracketpairingcounter
auf den bracketpairingstack
und überträgt die wörtliche Befehlszeichenfolge anstelle der erforderlichen Ganzzahl. Wenn also jede \node(closeX) {};
Tikz-Markierung vom Datenstapel entfernt wird, wird jede Knotennummer beim letzten Wert von ausgewertet bracketpairingcounter
, anstatt die verschiedenen Ganzzahlen nacheinander auf den Stapel zu übertragen.
Ich hoffe, dass das Nummerierungsproblem behoben werden kann, indem mein LaTeX-Code irgendwie gezwungen wird, den \openbracketname
folgenden Wert sofort auszuwerten, aber ich schaffe es in diesem Fall beim besten Willen nicht, \expandafter
oder \edef{}
es funktioniert ...
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}
Antwort1
Sie möchten dies tun \edef\temp{{#1}}
, können aber \push
auch die Definition und andere Teile des Codes vereinfachen.
\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}
Mit \edef\tmp{{#1}\the#2}
erweitern wir #1
den nicht erweiterten Inhalt des Token-Registers Nr. 2 vollständig und fügen ihn hinzu, da die \the\tokenregister
Erweiterung nicht fortgesetzt wird, nachdem \the
der Inhalt des Registers bereitgestellt wurde. Dann legen wir fest, #2
dass die Erweiterung (nur eine Ebene) von enthalten ist \tmp
.
Beachten Sie, dass dies \ignorespaces
unnötig ist, da der Aufruf von \push
ergibt \tikzmark
, dass dies tatsächlich zu unzeitgemäßen Erweiterungen führen könnte (in diesem Fall nicht).