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 therestore 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 thename prefix
andname 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 withtransform saved nodes
then the order matters: this must come aftertransform saved nodes
.
Result:
The red nodes are overlaid on top of the original nodes.