![在另一个 tikz 文档中引用 tikz 生成的 pdf 图像的内部节点](https://linux22.com/image/370716/%E5%9C%A8%E5%8F%A6%E4%B8%80%E4%B8%AA%20tikz%20%E6%96%87%E6%A1%A3%E4%B8%AD%E5%BC%95%E7%94%A8%20tikz%20%E7%94%9F%E6%88%90%E7%9A%84%20pdf%20%E5%9B%BE%E5%83%8F%E7%9A%84%E5%86%85%E9%83%A8%E8%8A%82%E7%82%B9.png)
假设我有两张使用 tikz 生成并保存为 pdf 文件的图像。两者都有当时可以引用的内部节点。我的问题是:如果我将这些内部节点作为 PDF 图像包含在第三个文档中,是否有办法引用它们?
当然,下面的 MWE 不需要这种机制,但实际目标是更复杂的结构。
%% file1.tex
\documentclass[tikz]{standalone};
\begin{document}
\begin{tikzpicture}
\node[draw](1){1};
\end{tikzpicture}
\end{document}
%% file2.tex
\documentclass[tikz]{standalone};
\begin{document}
\begin{tikzpicture}
\node[draw](2){2};
\end{tikzpicture}
\end{document}
%% file3.tex
\documentclass[tikz]{standalone};
\begin{document}
\begin{tikzpicture}
\node[]at(-2,-2){\includegraphics{file1.pdf};
\node[]at(+2,+2){\includegraphics{file2.pdf};
%% here is the catch
% \draw(1)--(2);
\end{tikzpicture}
\end{document}
savebox
和朋友如果在应用变换(例如旋转或缩放)时保留内部节点引用,那么这可能是一个解决方案,但据我测试,情况并非如此。
答案1
更新 2019-12-16:这最终被合并到tikzmark
包。下面的代码几乎可以原样有一个变化:\usetikzlibrary{tikzmark}
而不是\usetikzlibrary{savenodes}
。
(2018-02-18:更新以考虑节点转换)
在尝试解决这个问题时,我偶然发现了一些我为如何保存和恢复 tikzpictures 之间的节点?关于在 tikz 图片之间保存节点信息。要在文档之间传输此信息,只需要某种方式来保存和加载它,然后再考虑一下边界框。
由于此代码在两个答案中都有使用,我将其放入一个单独的文件中并上传到 github。您可以从这个 GitHub 存储库。目前,它只是一个文件。
这是基于您的代码的示例。我lualatex
默认使用,如果您使用,我会指出更改pdflatex
。请注意,我使用filecontents
包从一个基础文件生成所有文件,如果您通过其他方法生成文件,则不需要这些部分,也不需要这些行。因此,\immediate\write18
此示例需要使用选项运行。--shell-escape
这是当前的示例代码:
\documentclass{article}
%\url{https://tex.stackexchange.com/q/415831/86}
\usepackage{shellesc}
\usepackage{tikz}
\usetikzlibrary{savenodes}
\usepackage{filecontents}
%% file1.tex
\begin{filecontents}{\jobname-1.tex}
\RequirePackage{luatex85}
\documentclass[tikz,border=10pt]{standalone}
\usetikzlibrary{savenodes,shapes.geometric}
\begin{document}
\begin{tikzpicture}[save nodes to file]
\node[draw,rotate=-30,save node](1) at (-2,0) {1};
\draw[->] (0,0) -- (1);
\node[draw,ellipse,save node] (c) at (current bounding box.center) {};
\end{tikzpicture}
\end{document}
\end{filecontents}
%% file2.tex
\begin{filecontents}{\jobname-2.tex}
\RequirePackage{luatex85}
\documentclass[tikz,border=10pt]{standalone}
\usetikzlibrary{savenodes,shapes.geometric}
\begin{document}
\begin{tikzpicture}[save nodes to file]
\node[draw,rotate=-70,save node] (2) at (2,0) {2};
\draw[->] (0,0) -- (2);
\node[draw,ellipse,save node] (c) at (current bounding box.center) {};
\end{tikzpicture}
\end{document}
\end{filecontents}
%% file3.tex
%\immediate\write18{lualatex \jobname-1.tex}
%\immediate\write18{lualatex \jobname-2.tex}
\begin{document}
\begin{tikzpicture}
\node[draw,
rotate=30,
restore nodes from file={[transform saved nodes,name prefix=pic-1-]{\jobname-1}}
] (a-1) at (-2,-3) {\includegraphics{\jobname-1.pdf}};
\node[draw,
rotate=70,
restore nodes from file={[transform saved nodes,name prefix=pic-2-]{\jobname-2}}
] (a-2) at (+2,+2) {\includegraphics{\jobname-2.pdf}};
\draw[red] (pic-1-1.north west) -- (pic-1-1.north east) -- (pic-1-1.south east) -- (pic-1-1.south west) -- cycle;
\draw[red] (pic-2-2.north west) -- (pic-2-2.north east) -- (pic-2-2.south east) -- (pic-2-2.south west) -- cycle;
\node[red] at (pic-1-1) {1};
\node[red] at (pic-2-2) {2};
\draw (a-1) circle[radius=5pt];
\draw (a-2) circle[radius=5pt];
\draw (pic-1-1) -- (pic-2-2);
\end{tikzpicture}
\end{document}
该界面现在通过 TikZ 键进行。定义的键为:
save nodes to file
在作用域上,这表示在作用域中标记为要保存的任何节点都应保存到文件(称为\jobname.nodes
)。这是一个布尔值。应给出其中一个键或下一个键(或两者)以触发保存机制。set node group=<group name>
在范围内,如果不保存到文件,则节点将保存为“节点组”,这将设置名称。save node
在节点上,这将标记该节点为要保存的节点(保存到文件或列表)。restore nodes from file=<file name>
,这将加载从给定文件保存的节点。restore nodes from list=<group name>
,这将加载从给定组保存的节点。transform saved nodes
,这意味着恢复的节点将使用最后一个节点的变换进行变换(通常,如果restore nodes from ...
在节点上使用则应该使用此选项)。name prefix=...
这不是一个新键,但很有用。恢复的节点从 TikZ 的节点命名系统中获取name prefix
和name suffix
,因此放置此键是一种自动为每个恢复的节点名称添加前缀(或后缀)的有效方法。请注意,如果使用此键和transform saved nodes
那么顺序很重要:这必须发生后transform saved nodes
。
结果:
红色节点覆盖在原始节点之上。