# macros inside tikzpicture

I wanted to make a bit more readable the tex code I'm using and, in this respect, I wanted to somehow use a macro for the following code:

\draw (10 mm,10 mm) -- (20 mm,10 mm);


I've created the following newcommands:

\newcommand*\horizontalLineCoor[3]{  \draw (#1 mm,#2 mm) -- (#3 mm,#2 mm);   }
\newcommand*\horizontalLineLength[3]{\draw (#1 mm,#2 mm) -- (#1+#3 mm,#2 mm);}


I'm receiving this sort of errors:

! Package PGF Math Error: Unknown function mm' (in '( mm').

See the PGF Math package documentation for explanation.
Type  H <return>  for immediate help.
...

l.31 \horizontalLineLength(10
, 20, 10);
?


Can you give me hand with this macros:) Thank you! R

The test file (this should draw 2 horizontal lines):

\documentclass[a4paper,10pt,fleqn]{article}
\usepackage{tikz}
\usetikzlibrary{positioning}
\newcommand*\horizontalLineCoor[3]{  \draw (#1 mm,#2 mm) -- (#3 mm,#2 mm);   }
\newcommand*\horizontalLineLength[3]{\draw (#1 mm,#2 mm) -- (#1+#3 mm,#2 mm);}

\begin{document}
\begin{figure}
\begin{tikzpicture}[
xscale=2,
yscale=2,
virtual/.style={thin,dashed}
]
\horizontalLineCoor(10, 10, 20);    %%%\draw (10 mm,10 mm) -- (20 mm,10 mm);
\horizontalLineLength(10, 20, 10);  %%%\draw (10 mm,20 mm) -- (20 mm,20 mm);
\end{tikzpicture}
\caption{Interesting caption}
\end{figure}
\end{document}


## 3 Answers

You provided no test file but the error shows you used the syntax

\horizontalLineLength(10, 20, 10);


But you have defined the command with three TeX arguments, that supplied the ; so

\horizontalLineLength{10}{20}{10}


You can use the syntax \horizontalLineCoor(10, 10, 20) if you prefer. However, this is a bit awkward, because TeX does not treat multiple arguments like C or other programming languages; if you define

\newcommand{\foo}[3]{...}


the call should be like

\foo{x}{y}{z}


each argument enclosed in braces.

However, the syntax with parentheses can be set up using xparse, that provides fairly general methods for inputting arguments.

\documentclass[a4paper,10pt,fleqn]{article}
\usepackage{xparse}
\usepackage{tikz}
\usetikzlibrary{positioning}

\NewDocumentCommand{\horizontalLineCoor}{>{\SplitArgument{2}{,}}r()}{%
\horizontalLineCoorDo#1%
}
\NewDocumentCommand{\horizontalLineLength}{>{\SplitArgument{2}{,}}r()}{%
\horizontalLineLengthDo#1%
}
\NewDocumentCommand{\horizontalLineCoorDo}{mmm}{%
\horizontalLineDo{#1}{#2}{#3}%
}
\NewDocumentCommand{\horizontalLineLengthDo}{mmm}{%
\horizontalLineDo{#1}{#2}{#1+#3}%
}
\NewDocumentCommand{\horizontalLineDo}{mmm}{%
\draw (#1 mm,#2 mm) -- (#3 mm,#2 mm)%
}

\begin{document}

\begin{figure}[htp]
\centering

\begin{tikzpicture}[
xscale=2,
yscale=2,
virtual/.style={thin,dashed}
]
\horizontalLineCoor(10, 10, 20);    %%%\draw (10 mm,10 mm) -- (20 mm,10 mm);
\horizontalLineLength(10, 20, 10);  %%%\draw (10 mm,20 mm) -- (20 mm,20 mm);
\end{tikzpicture}
\caption{Interesting caption}

\end{figure}

\end{document}


The definition

\NewDocumentCommand{\horizontalLineCoor}{>{\SplitArgument{2}{,}}r()}{%
\horizontalLineCoorDo#1%
}


says that \horizontalLineCoor accepts one argument enclosed between parentheses; but we can tell LaTeX to split this argument at commas (there should be two of them), so at the end a call such as

\horizontalLineCoor(10, 10, 20)


results in

\horizontalLineCoorDo{10}{10}{20}


so the arguments are “TeX-normalized”. Now it's a matter of defining \horizontalLineCoorDo, which I do in an indirect fashion so as to avoid code duplication for the main code, since \horizontalLineCoor and \horizontalLineLength do very similar tasks.

This is just to remark that TikZ comes with its own means to define such abbreviations. Your commands can be represented by two styles, horizontal to and horizontal add, which do the same as what your commands should do (if I understand correctly).

\documentclass[a4paper,10pt,fleqn]{article}
\usepackage{tikz}

\begin{document}
\begin{figure}
\begin{tikzpicture}[
xscale=2,
yscale=2,
horizontal to/.style={insert path={coordinate(aux) -- (#1mm,0 |-aux)}},
horizontal add/.style={insert path={-- ++ (#1mm,0)}},
]
\draw (10mm,10mm) [horizontal to=20];
\draw (10mm,20mm) [horizontal add=10];
\end{tikzpicture}
\caption{Interesting caption.}
\end{figure}
\end{document}
`

• Eventually, the appropriate TikZ answer! (+1) Feb 3 '19 at 6:07
• @CarLaTeX I can't guess what you mean, I got a badge for my answer! Feb 3 '19 at 10:00
• @DavidCarlisle lol Feb 3 '19 at 10:06