4

I am beginner in writing macros with multi options. What I want to do, is to combine many options to one pair of brackets.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\makeatletter
\def\DLineS{%
\@ifnextchar[%
 {\DLineS@i}
 {\DLineS@i[1.25]}%
}
\def\DLineS@i[#1]{%
\@ifnextchar[%
 {\DLineS@ii{#1}}
 {\DLineS@ii{#1}[-0.25]}%
}
\def\DLineS@ii#1[#2]#3#4{%
\draw[latex-latex] ($(#3)!#2!(#4)$) -- ($(#3)!#1!(#4)$) 
}
\makeatother
\begin{document}
\begin{tikzpicture}
\coordinate[label=below:{\small $A$}] (A) at (0,0);
\coordinate[label=below:{\small $B$}] (B) at (1,1);
\filldraw (A) circle (1.5pt);
\filldraw (B) circle (1.5pt);
\DLineS[1.5][-0.75]{A}{B};
% I want this line is \DLineS[1.5,-0.75]{A}{B};
\end{tikzpicture}
\end{document}
  • You want to have a macro with two options? or just the splitting of the first [,] ? – user31729 Sep 8 '14 at 7:23
  • Maybe \DLineS[a]{A}{B}->\DLineS@ii{a}[-.25]{A}{B} while \DLineS[a,b]{A}{B}->\DLineS@ii{a}[b]{A}{B}. But \DLineS[a]{A}{B}->\DLineS@ii{a}[1-a]{A}{B} also makes sense. – Symbol 1 Sep 8 '14 at 9:07
2

It is not recommended to play with \def unless you know what you are doing. If so, you can do the following. Otherwise consider egreg's answer using xparse.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\makeatletter
\def\DLineS{\@ifnextchar[%
    {\DLineS@i}{\DLineS@i[1.25]}}
\def\DLineS@i[#1]{\@ifnextchar[%
    {\DLineS@ii{#1}}{\DLineS@iii#1,;}}
\def\DLineS@ii#1[#2]#3#4{%
    \draw[latex-latex]($(#3)!#2!(#4)$)--($(#3)!#1!(#4)$)}
\def\DLineS@iii#1,#2;#3#4{\def\temp{#2}\ifx\temp\empty%
        \DLineS@ii#1[-.25]{#3}{#4}\else\DLineS@iv[#1][#2]{#3}{#4}\fi}
\def\DLineS@iv[#1][#2,]{\DLineS@ii#1[#2]}
\makeatother
\begin{document}
\begin{tikzpicture}
    \coordinate[label=below:{\small $A$}](A)at(0,0);
    \coordinate[label=below:{\small $B$}](B)at(1,1);
    \coordinate[label=below:{\small $C$}](C)at(2,0);
    \coordinate[label=below:{\small $D$}](D)at(3,1);
    \coordinate[label=below:{\small $E$}](E)at(4,0);
    \coordinate[label=below:{\small $F$}](F)at(5,1);
    \coordinate[label=below:{\small $G$}](G)at(6,0);
    \coordinate[label=below:{\small $H$}](H)at(7,1);
    \filldraw(A)circle(1.5pt)(B)circle(1.5pt)(C)circle(1.5pt)(D)circle(1.5pt)(E)circle(1.5pt)(F)circle(1.5pt)(G)circle(1.5pt)(H)circle(1.5pt);
    \DLineS[1.5][-0.75]{A}{B};
    \DLineS[1.5,-0.75]{C}{D};
    \DLineS[1.5]{E}{F};
    \DLineS{G}{H};
\end{tikzpicture}
\end{document}
  • Yes, this is good solution. Thanks for your attention. – somkiat_t Sep 9 '14 at 0:30
2

You can do it with xparse:

\documentclass{article}
\usepackage{xparse}
\usepackage{tikz}
\usetikzlibrary{calc}

\NewDocumentCommand{\DLineS}{>{\SplitArgument{1}{,}}O{1.25,-0.25}mm}{%
  % no optional argument is like calling [1.25,-0.25]
  \DLineSaux#1{#2}{#3}%
}

\NewDocumentCommand{\DLineSaux}{mmmm}{%
  \IfNoValueTF{#2}%
    {\DLineSaux{#1}{-0.25}{#3}{#4}}% no comma in the optional argument, use -0.25
    {\draw[latex-latex] ($(#3)!#2!(#4)$) -- ($(#3)!#1!(#4)$)}%
}

\begin{document}

\begin{tikzpicture}
\coordinate[label=below:{\small $A$}] (A) at (0,0);
\coordinate[label=below:{\small $B$}] (B) at (1,1);
\filldraw (A) circle (1.5pt);
\filldraw (B) circle (1.5pt);
\DLineS[1.5,-0.75]{A}{B};
\end{tikzpicture}
\begin{tikzpicture}
\coordinate[label=below:{\small $A$}] (A) at (0,0);
\coordinate[label=below:{\small $B$}] (B) at (1,1);
\filldraw (A) circle (1.5pt);
\filldraw (B) circle (1.5pt);
\DLineS{A}{B};
\end{tikzpicture}
\begin{tikzpicture}
\coordinate[label=below:{\small $A$}] (A) at (0,0);
\coordinate[label=below:{\small $B$}] (B) at (1,1);
\filldraw (A) circle (1.5pt);
\filldraw (B) circle (1.5pt);
\DLineS[1.5]{A}{B};
\end{tikzpicture}
\end{document}

We do three steps; in the first step we just pass control to \DLineSaux after splitting the optional argument at the comma; if no optional argument is given, [1.25,-0.25] is passed; if just the first part is present (see third example), xparse passes -NoValue- to the next stage, so in this case we simply recall \DLineSaux with -0.25 as the second argument.

enter image description here

  • @eqreg: Thanks so much for your advice. This is basic knowledge for me in the future. I don't want other package (xparse). – somkiat_t Sep 9 '14 at 0:55
  • @eqreg:I do not understand how to use the command \DlineSaux. – somkiat_t Sep 9 '14 at 1:09
  • @somkiat_t You don't use it explicitly; it is just an auxiliary command run by \DLineS. – egreg Sep 9 '14 at 9:50

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.