Robert Homann | 13 Jun 15:08
Picon
Picon

Macros with optional parameters in paths

Hi!

Currently, I am trying to write some macros for drawing parse trees, based on
TikZ. Each of these macros corresponds to an operator, and they are designed to
embed each other in order to generate nodes on a path. So, inside a tikzpicture
environment, I start drawing with a \path command, followed by some of my
macros that emit "node" and "child" commands, and stop with a semicolon.

This works all well, but now I would like my macros to accept optional
parameters. Unfortunately, it seems like \path is choking on the \@ifnextchar
command that is used to handle the []-brackets.

Could someone please take a look at the artificial example below that
illustrates my problem?

---
\listfiles
\documentclass[11pt,a4paper]{scrartcl}
\usepackage{tikz}

\makeatletter

\def\Works{\@ifnextchar[{\@Works}{\@Works[]}}
\def\@Works[#1]#2#3#4{\path[draw] (0,#2) node[draw] {#3} -- (2,#2) node[draw#1] {#4};}

\def\Fails{\@ifnextchar[{\@Fails}{\@Fails[]}}
\def\@Fails[#1]#2#3#4{(0,#2) node[draw] {#3} -- (2,#2) node[draw#1] {#4}}

\makeatother

(Continue reading)

Mark Wibrow | 13 Jun 15:29
Picon
Picon
Favicon

Re: Macros with optional parameters in paths

Hi,

The solution is to use \pgfextra...\endpgfextra.
So, for the problem you sketch

\def\Fails{\pgfextra\@ifnextchar[{\@Fails}{\@Fails[]}}
\def\@Fails[#1]#2#3#4{\endpgfextra(0,#2) node[draw] {#3} -- (2,#2)
node[draw#1] {#4}}

Should produce the required results. The problem is because
\@ifnextchar uses \futurelet. The precise reasons (and a better
explanation than I can manage) are discussed here:

http://sourceforge.net/forum/forum.php?thread_id=1567864&forum_id=477363

Regards

Mark

Robert Homann wrote:
> Hi!
>
> Currently, I am trying to write some macros for drawing parse trees, based
> on
> TikZ. Each of these macros corresponds to an operator, and they are
> designed to
> embed each other in order to generate nodes on a path. So, inside a
> tikzpicture
> environment, I start drawing with a \path command, followed by some of my
> macros that emit "node" and "child" commands, and stop with a semicolon.
(Continue reading)

Robert Homann | 13 Jun 18:01
Picon
Picon

Re: Macros with optional parameters in paths

On Wed, 13 Jun 2007, Mark Wibrow wrote:

> Hi,

Hi!

> The solution is to use \pgfextra...\endpgfextra.

Great, it works now! Thank you! :)

...But there is one more issue left...

Basically, I am trying to set options for the "child" commands in my
macros, most notably the "sibling distance" option. I use the xkeyval
package and \setkeys for this, and define some macro, say \Mydistance, to
the value of a given key. Then, I would just like to say
"child[sibling distance=\Mydistance]" in case \Mydistance has been set,
and only "child" (or "child[]") otherwise.

Thus, I need either a conditional inside the \path, like

  child\ifx\Mydistance\empty\else[sibling distance=\Mydistance]\fi

or another macro that is defined beforehand depending on the value of
\Mydistance, like

  \ifx\Mydistance\empty\def\Myopts{}
  \else\def\Myopts{sibling distance=\Mydistance}\fi
  ...
  child[\Myopts]
(Continue reading)

Mark Wibrow | 14 Jun 08:12
Picon
Picon
Favicon

Re: Macros with optional parameters in paths

Another, not-quite-as-hacky solution could be

\tikzoption{MyOpts}[]{%
  \ifx\MyDistance\empty%
  \else%
    \pgfmathsetlength\tikzsiblingdistance{\MyDistance}%
  \fi%
}

\begin{tikzpicture}
  \def\MyDistance{}
  \node at (0,0) {A} child [MyOpts] {node{B}}  child [MyOpts] node{C}};
  \def\MyDistance{3cm}
  \node at (3,0) {A} child [MyOpts] {node{B}}  child [MyOpts] {node{C}};
\end{tikzpicture}

-Mark

Robert Homann wrote:
> On Wed, 13 Jun 2007, Mark Wibrow wrote:
>
>> Hi,
>
> Hi!
>
>> The solution is to use \pgfextra...\endpgfextra.
>
> Great, it works now! Thank you! :)
>
> ...But there is one more issue left...
(Continue reading)

Mark Wibrow | 13 Jun 18:47
Picon
Picon
Favicon

Re: Macros with optional parameters in paths

Hello again!

I'm sure I had a nice clean simple solution to this, but I can neither
find it, nor recreate it. So, an ugly, hacky solution:

\makeatletter
\def\MyDistanceTest{%
	\ifx\MyDistance\empty%
		\tikz <at> style{MyOpts}{}%
	\else%
		\tikz <at> style{MyOpts}{sibling distance=\MyDistance}%
	\fi}

\begin{tikzpicture}
	\def\MyDistance{}
	\MyDistanceTest
	\node at (0,0) {A} child [MyOpts] {node{B}}  child [MyOpts] {node{C}};

	\def\MyDistance{3cm}
	\MyDistanceTest
	\node at (3,0) {A} child [MyOpts] {node{B}}  child [MyOpts] {node{C}};
\end{tikzpicture}

Hope this helps.

Mark

Robert Homann wrote:
> On Wed, 13 Jun 2007, Mark Wibrow wrote:
>
(Continue reading)

Robert Homann | 15 Jun 15:47
Picon
Picon

Re: Macros with optional parameters in paths

On Wed, 13 Jun 2007, Mark Wibrow wrote:

> Hello again!

Hi!

> I'm sure I had a nice clean simple solution to this, but I can neither
> find it, nor recreate it. So, an ugly, hacky solution:
> [..]

Ah, the joy of undocumented features! ;)

I didn't think of using styles for my problem, but I consider it a great
idea. After trying a bit more, I ended up with something similar to the
following code (shown in full length for future reference).

----
\listfiles
\documentclass[11pt,a4paper]{scrartcl}
\usepackage{tikz}

\makeatletter

\tikzstyle{leaf}=[draw,fill=white]
\tikzstyle{inner}=[draw,fill=black!20,inner sep=0.5ex]

\define <at> key{Concatkeys}{left}{\def\Concatleft{#1}}
\define <at> key{Concatkeys}{right}{\def\Concatright{#1}}
\presetkeys{Concatkeys}{left={},right={}}{}

(Continue reading)


Gmane