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?

\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
    /flux/.is family, /flux,
    position/.store in=\position,
    fluxabove/.store in=\fluxabove,
    fluxbelow/.store in=\fluxbelow,
    print/.code={node[pos=\position, above] {\fluxabove} node[pos=\position, below] {\fluxbelow}}
% \draw (0,0) -- (1,0) \testone[0.9]{another}{text}; % This doesn't work
\draw (2,0) -- (3,0) \testtwo{text}{text};
% \draw (4,0) -- (6,0) \flux{fluxabove=10.0, fluxbelow=9.0}; % This doesn't work

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?


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

\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}];

enter image description here

| improve this answer | |
  • Thank you! Just one small issue using the third method - it seems the default position is 1.0 instead of what you set as 0.6. Is this related to the position= part? I tried to delete that, but it resulted in an error. – darthbith Jan 25 '15 at 15:01
  • Actually, setting position=0.6 and deleting the position/.default=0.6 does what I want. Could there be any other effects of doing this? – darthbith Jan 25 '15 at 15:12

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.