Referece internal nodes of pdf images generated by tikz in another tikz document

Referece internal nodes of pdf images generated by tikz in another tikz document

Suppose I have two images generated using tikz and saved as pdf files. Both had internal nodes that could be referenced at that time. My question is: is there a way to reference those internal nodes if I'm including them in a third document as PDF images?

Of course this mechanism is not needed for the MWE below, however the actual target is a more complex structure.

%% 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 and friends could be a solution if they preserve the internal node references when transformations are applied (such as rotate or scale), which is not the case as far as I was able to test.

답변1

Update 2019-12-16: This ended up being merged into the tikzmark package. The code below works almost as-is with one change: \usetikzlibrary{tikzmark} instead of \usetikzlibrary{savenodes}.


(2018-02-18: Update to take into account node transformations)

While attempting a solution to this, I came across some code I'd written for How to save and restore the nodes between tikzpictures? about saving node information between tikz pictures. To transfer this information between documents just needs some way to save and load it, and then a bit of thought about bounding boxes.

As this code is essentially in use in two answers, I've put it into a separate file and uploaded it to github. You can download it from this github repository. At the moment, it's just a single file.

Here's an example based on your code. I use lualatex by default, I've indicated the changes if you use pdflatex. Note that I'm using the filecontents package to generate all of the files from one base file, if you're generating your files by a different method then you don't need these parts and you don't need the \immediate\write18 lines. This example needs running with the --shell-escape option because of this.

Here's the current example code:

\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}

The interface is now via TikZ keys. The ones defined are:

  • save nodes to file on a scope, this says that any nodes marked to be saved in the scope should be saved to a file (called \jobname.nodes). This is a boolean. One of this or the next keys should be given (or both) to trigger the saving mechanism.
  • set node group=<group name> on a scope, if not saving to a file then nodes are saved as a "node group", this sets the name.
  • save node on a node, this marks that node as one to be saved (either to a file or a list).
  • restore nodes from file=<file name>, this loads in the nodes saved from the given file.
  • restore nodes from list=<group name>, this loads in the nodes saved from the given group.
  • transform saved nodes, this means that the restored nodes are transformed with the last node's transformation (usually, this should be used if the restore nodes from ... is used on a node).
  • name prefix=... this isn't a new key, but is a useful one. The restored nodes pick up the name prefix and name suffix from TikZ's node naming system, so putting this key is a useful way to automatically add a prefix (or suffix) to each restored node name. Note that if this is used with transform saved nodes then the order matters: this must come after transform saved nodes.

Result:

Loading node information

The red nodes are overlaid on top of the original nodes.

관련 정보