[Tex/LaTex] How to use optional arguments in newcommand with TikZ in the middle of a path

pgfkeystikz-pgf

I am trying to define a new command that will enable me to automatically format certain parts of my diagram. These parts consist of two nodes added above and below a path. I have a default value that I want for the pos key of the nodes, but I'd like to be able to adjust this on the fly if needed with an optional argument. I usually use my new command at the end of my path so that the nodes are placed along the path.

Unfortunately, my naive approach (and the more advanced approach from Optional arguments in pgfkeys?) causes a Did you forget a semicolon? error from TikZ, so I suspect I'm not going about this in the right way. How can I specify an optional argument to my newcommand to change the position of the nodes, or alternatively, how can I use the facilities of TikZ to assign a default value for a key that I can override later?

\documentclass[tikz]{standalone}
\newcommand*{\testone}[3][0.6]{node[pos={#1}, above] {#2} node[pos={#1}, below] {#3}}
\newcommand*{\testtwo}[2]{node[pos=0.6, above] {#1} node[pos=0.6, below] {#2}}
\newcommand*{\testthr}[2][test]{\node {#1 + #2}}
\newcommand*{\flux}[1]{\pgfkeys{/flux,position,fluxabove,fluxbelow,#1,print}} % https://tex.stackexchange.com/q/39834/32374
\pgfkeys{
    /flux/.is family, /flux,
    position/.default=0.6,
    position/.store in=\position,
    fluxabove/.store in=\fluxabove,
    fluxbelow/.store in=\fluxbelow,
    print/.code={node[pos=\position, above] {\fluxabove} node[pos=\position, below] {\fluxbelow}}
}
\begin{document}
\begin{tikzpicture}
% \draw (0,0) -- (1,0) \testone[0.9]{another}{text}; % This doesn't work
\draw (2,0) -- (3,0) \testtwo{text}{text};
\testthr{another};
% \draw (4,0) -- (6,0) \flux{fluxabove=10.0, fluxbelow=9.0}; % This doesn't work
\end{tikzpicture}
\end{document}

Related questions:
TikZ: \newcommand with optional TikZ options
Is it possible to set a default value for an argument in a TikZ style?
Optional arguments in pgfkeys?

Best Answer

Stuff defined using \newcommand is always going to be problematic inside a TikZ path because of the way TikZ parses path commands.

In this case I think the best way forward is to use keys and in particular the insert path key:

\documentclass[tikz, border=5]{standalone}
\tikzset{%
  test 1/.style args={#1#2#3}{insert path={
    node[pos={#1}, above] {#2} node[pos={#1}, below] {#3}
  }},
  test 2/.style 2 args={insert path={
      node[pos=0.6, above] {#1} node[pos=0.6, below] {#2}
  }},
  flux/.style={flux/.cd,#1, print},
  flux/.cd,
    position/.store in=\position,
    position/.default=0.6, position=,
    fluxabove/.store in=\fluxabove,
    fluxbelow/.store in=\fluxbelow,
    print/.style={/tikz/.cd, insert path={
      node [pos=\position, above] {\fluxabove} node[pos=\position, below] {\fluxbelow}
    }}
 }

\begin{document}
\begin{tikzpicture}
\draw (0,0) -- (1,0) [test 1={0.9}{another}{text}]; 
\draw (2,0) -- (3,0) [test 2={text}{text}];
\draw (4,0) -- (6,0) [flux={fluxabove=10.0, fluxbelow=9.0}];
\end{tikzpicture}
\end{document}

enter image description here

Related Question