Problem with macros and drawing rectangles

I am a beginner in LaTeX and I have a problem with the use of macros.

Let's say that I have created a macro that draws rectangles.

\documentclass[10pt,a4paper, landscape]{book}
\usepackage{tikz}
\usepackage[french]{babel}

\begin{document}

\newcommand\rect[4]{
\draw (#1,#2) rectangle (#3,#4);}

\begin{tikzpicture}
\rect{1}{2}{3}{4};
\end{tikzpicture}

\end{document}


It works. Now I would like to create a macro that join the first vertices of two rectangles. I searched on the Internet and found a way to gets the coordinate of the first vertex of a rectangle.

\documentclass[10pt,a4paper, landscape]{book}
\usepackage{tikz}
\usepackage[french]{babel}

\begin{document}

\def\generatex#1#2{%
\begingroup
\toks0={#2}%
\edef\next{\def\expandafter\noexpand\csname varx#1\endcsname{\the\toks0 }}%
\expandafter\endgroup\next}

\def\generatey#1#2{%
\begingroup
\toks0={#2}%
\edef\next{\def\expandafter\noexpand\csname vary#1\endcsname{\the\toks0 }}%
\expandafter\endgroup\next}

\newcommand\rect[5]{
\draw (#1,#2) rectangle (#3,#4);
\generatex{#5}{#1};
\generatey{#5}{#2};}

\begin{tikzpicture}

\rect{1}{2}{3}{4}{rectone};
\rect{10}{5}{2}{3}{recttwo};
\draw(\varxrectone,\varyrectone)--(\varxrecttwo,\varyrecttwo);

\end{tikzpicture}

\end{document}


This works again. But, let's say that I would like to define a general macro doing this. I tried the following but it doesn't work :

\documentclass[10pt,a4paper, landscape]{book}
\usepackage{tikz}
\usepackage[french]{babel}

\begin{document}

\def\generatex#1#2{%
\begingroup
\toks0={#2}%
\edef\next{\def\expandafter\noexpand\csname varx#1\endcsname{\the\toks0 }}%
\expandafter\endgroup\next}

\def\generatey#1#2{%
\begingroup
\toks0={#2}%
\edef\next{\def\expandafter\noexpand\csname vary#1\endcsname{\the\toks0 }}%
\expandafter\endgroup\next}

\newcommand\rect[5]{
\draw (#1,#2) rectangle (#3,#4);
\generatex{#5}{#1};
\generatey{#5}{#2};}

\newcommand\join[2]{
\draw(\varx#1,\vary#1)--(\varx#2,\vary#2);}

\begin{tikzpicture}

\rect{1}{2}{3}{4}{rectone};
\rect{10}{5}{2}{3}{recttwo};
\join{rectone}{recttwo};

\end{tikzpicture}
\end{document}


Any idea ? I am new to LaTeX and I am sure that all I wrote is terrible, but don't judge me please ! Thanks !!

• Welcome to TeX.SX! – Philipp Imhof May 4 at 11:43
• Thank you ! Any idea for my problem ? – Henry May 4 at 12:44
• All of this is already included in the TikZ system. If you make those rectangles nodes, then the coordinates of the corners are stored in anchors. Internally this looks a bit like what you are doing here, but is IMHO way simpler. – user194703 May 4 at 14:23

\newcommand\join[2]{
\draw(\varx#1,\vary#1)--(\varx#2,\vary#2);}


you need to use \csname ... \endcsname to construct a control sequence from its name. For example, \csname varx#1\endcsname.

LaTeX2e' internal macro \@nameuse{<csname>} is helpful when you need to use the \csname ... \endcsname structure frequently. Say, you can write

\makeatletter
\newcommand\join[2]{
\draw(\@nameuse{varx#1},\@nameuse{vary#1})--(\@nameuse{varx#2},\@nameuse{vary#2});}
\makeatother


A further simplified example:

\documentclass[10pt,a4paper, landscape]{book}
\usepackage{tikz}
\usepackage[french]{babel}

\newcommand\rect[5]{
\draw (#1,#2) rectangle (#3,#4);
% store #1 in macro \varx<#5>
\expandafter\def\csname varx#5\endcsname{#1};
% store #2 in macro \vary<#5>
\expandafter\def\csname vary#5\endcsname{#2};}

\newcommand{\useCoords}[1]{\useCoordX{#1}, \useCoordY{#1}}
\newcommand{\useCoordX}[1]{\csname varx#1\endcsname}
\newcommand{\useCoordY}[1]{\csname vary#1\endcsname}

\newcommand\join[2]{
\draw (\useCoords{#1}) -- (\useCoords{#2});}

\begin{document}
\begin{tikzpicture}
\rect{1}{2}{3}{4}{rectone};
\rect{10}{5}{2}{3}{recttwo};
\join{rectone}{recttwo};
\end{tikzpicture}
\end{document}


If open to use LaTeX2e internals (doc macros2e gives nice intro to them), you can use

• \@namedef{<cmd>} ... to replace \expandafter\def\csname <cmd>\endcsname ... and
• \@nameuse{<cmd>} to replace \csname <cmd>\endcsname.
• Thank you ! It works very well :) – Henry May 4 at 15:29

All these mechanisms are already part of TikZ. For instance, the rectangle connections are as simple as

\documentclass[tikz,border=3mm]{standalone}
\begin{document}
\begin{tikzpicture}
\draw[local bounding box=A] (1,2) rectangle (3,4);
\draw[local bounding box=B] (10,5) rectangle (2,3);
\draw (A.south west) -- (B.south west);
\end{tikzpicture}
\end{document}


There is a plethora of shapes with anchors. For the purposes you are describing there already exist built-in tools in TikZ.

• Actually, it was rather a way to understand how to store the argument of a macro, than the need to join my two rectangles... But thank you for your help !! – Henry May 4 at 15:31
• @Henry I was assuming that. This answer is also to tell you that TikZ is "one step ahead". You could think it is a good idea to store, for a shape named A, the x and y coordinates in some macros \shapeAx and \shapeAy, which is similar to what you propose. But what if some user has a sharp called Ax? That's why pgf has mechanisms which schematically defines a macro \def\coordsA{\pgf@x=<x>\pgf@y=<y>} with two dimensions \pgf@x and \pgf@y. With that mechanism you can store an arbitrary amount of attributes without running out of name space. – user194703 May 4 at 19:37
• Ok I understand. Thank you for your help and your explanations ! – Henry May 4 at 21:18