我有一个关于如何使用卑鄙的tikzmark
TikZ 库将节点放在预先打包的盒子周围,具体来说(但不限于)令人敬畏的 AMSMath 包在组装环境时使用的盒子,例如,align
为了gather
对方程组执行扩展listings
对tikzmark
代码所做的事情:在许多有用的地方放置标记。
查看 AMSMath 代码,这些环境是通过将每个“部件”放入一个盒子中,\z@
然后将其组装到一个中来构建的halign
。我想要做的是假装该框是 TikZ/PGF 节点的文本框,并在拆箱之前保存其位置和尺寸。
具体来说,在拆箱之前,我会做以下事情:
- 将 a 放置
\pgfmark
在当前位置(这是定义的各种标记系统中侵入性最小的tikzmark
;它只是调用适合所涉及的 TeX 引擎的低级“记住该点的坐标”代码并将几行写入文件aux
)。 - 测量盒子并做一系列与结果该盒子是一个 PGF 节点,但没有设置 TikZ 环境或任何东西。
- 然后拆开包装盒。
除了 AMSMath 代码使用相同的框之外一切(包括根和标签),在我公认的基本测试中,这似乎不会引起任何问题。
所以我的问题是:这可能会导致什么问题,我应该怎么做才能对这段代码进行稳健的测试?
(请注意,如果它真的进入了实际的tikzmark
包中,那么我几乎肯定会使它成为一个必须明确加载的额外的东西,而不是自动包含的东西,而且我不认为我会让它自动为所有这样的盒子打开,而是让它可以在需要时选择切换。)
(此外,我确实想到 LaTeX3 中可能存在一些有用的钩子,可以将数学运算放在页面上,我可以使用它,但我的搜索——诚然有限——没有找到任何结果。)
以下是一些代码,供想要测试或查看更多细节的人使用。这应该绝对不是可以将其视为剪切并粘贴到明天要交的论文中的东西!
\documentclass{article}
\usepackage{amsmath}
\usepackage{tikz}
\usetikzlibrary{tikzmark,fit}
\makeatletter
\def\tikzmark@box#1#2{%
\begingroup
\pgfmark{#1}%
\let\pgfnodeparttextbox=#2%
\edef\pgfpictureid{pgfid\the\pgf@picture@serial@count}%
\def\tikz@fig@name{#1}%
\pgfpointorigin
\advance\pgf@x by .5\wd\pgfnodeparttextbox%
\advance\pgf@y by .5\ht\pgfnodeparttextbox%
\advance\pgf@y by -.5\dp\pgfnodeparttextbox%
\pgftransformshift{}%
\setbox\@tempboxa=\hbox\bgroup
{%
\tikzset{inner sep=0pt, minimum size=0pt, outer sep=0pt, anchor=base}%
\let\pgf@sh@savedmacros=\pgfutil@empty% MW
\let\pgf@sh@savedpoints=\pgfutil@empty%
\def\pgf@sm@shape@name{rectangle}% CJ % TT added prefix!
\pgf@sh@s@rectangle%
\pgf@sh@savedpoints%
\pgf@sh@savedmacros% MW
\pgftransformshift{%
\pgf@sh@reanchor{rectangle}{center}%
\pgf@x=-\pgf@x%
\pgf@y=-\pgf@y%
}%
\expandafter\pgfsavepgf@process\csname pgf@sh@sa@\tikz@fig@name\endcsname{%
\pgf@sh@reanchor{rectangle}{center}% FIXME : this is double work!
}%
% Save the saved points and the transformation matrix
\edef\pgf@node@name{\tikz@fig@name}%
\ifx\pgf@node@name\pgfutil@empty%
\else%
\expandafter\xdef\csname pgf@sh@ns@\pgf@node@name\endcsname{rectangle}%
\edef\pgf@sh@@temp{%
\noexpand\gdef\expandafter\noexpand\csname pgf@sh@np@\pgf@node@name\endcsname}%
\expandafter\pgf@sh@@temp\expandafter{%
\pgf@sh@savedpoints}%
\edef\pgf@sh@@temp{%
\noexpand\gdef\expandafter\noexpand\csname pgf@sh@ma@\pgf@node@name\endcsname}% MW
\expandafter\pgf@sh@@temp\expandafter{\pgf@sh@savedmacros}% MW
\pgfgettransform\pgf@temp
\expandafter\xdef\csname pgf@sh@nt@\pgf@node@name\endcsname{\pgf@temp}%
\expandafter\xdef\csname pgf@sh@pi@\pgf@node@name\endcsname{\pgfpictureid}%
\fi%
}%
\egroup
\box\pgfnodeparttextbox%
\endgroup
}
\let\tikz@boxz@=\boxz@
\newcounter{tikzmarkequation}
\def\boxz@{%
\stepcounter{tikzmarkequation}%
\tikzmark@box{equation \the\c@tikzmarkequation}{\z@}}
\makeatother
\begin{document}
\begin{gather}
a = b + c \\
d = e + f
\end{gather}
\begin{align*}
a &= b + c \\
d &= e + f
\end{align*}
\begin{align}
a &= b + c & g&= h + i \\
d &= e + f
\end{align}
\begin{gather}
a^2 = b^2 + c^2 \\
\end{gather}
\begin{gather}
a = \sqrt[2]{b^2 + c^2}
\end{gather}
\begin{tikzpicture}[remember picture, overlay]
\foreach \k in {1,...,\value{tikzmarkequation}} {
\draw[red] (pic cs:equation \k) -- ++({\k*(180-360/\the\value{tikzmarkequation})}:1) node[draw,red,circle,font=\tiny] {\k};
\node[draw,green,fit=(equation \k),inner sep=0pt] {};
}
\end{tikzpicture}
\end{document}
(注:原始代码中有\refstepcounter
。感谢评论,我现在将其更改为\stepcounter
。)