7

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

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}
| improve this answer | |
5

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.

enter image description here

| improve this answer | |
3

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}

enter image description here

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.