# [Xy-pic] Using macros in xymatrix

Ross Moore ross at ics.mq.edu.au
Sat Jul 28 03:40:11 CEST 2007

Hi Andrew,

On 27/07/2007, at 1:22 AM, Andrew Clegg wrote:

> Hi,
>
> I'm using xymatrix to do various kinds of linguistic diagram, and it's
> producing some great results. One thing I would like to do is define
> some standard designs for common elements of the diagrams so that I
> don't have to type them in each time I use them -- this would make the
> xymatrix definitions quicker to write and much easier to read.
>
> For example, one style that I use a lot is a word in fixed-space font
> with a bit of extra spacing and a rectangular frame around it, like
> this:
>
> *+[F]\txt{\tt sometext}
>
> So I defined a macro called \lab (as in label) to represent this:
>
> \newcommand{\lab}[1]{*+[F]\txt{\tt #1}}

This cannot work, as it does not turn on Xy-pic parsing.
The * is a shorthand for \drop , within an Xy-pic parsing context,
so you need to define this macro as either:

\newcommand{\lab}[1]{\drop+[F]\txt{\tt #1}}

or as

\newcommand{\lab}[1]{\POS *+[F]\txt{\tt #1}}

>
> I've also done the same for different arrow styles, e.g. arrows with
> thicker lines:
>
> \newcommand{\arr}[1]{\ar@*{[|(2)]}[#1]}
>
> So then you can say for example
>
> \lab{foo} \arr{r}
>
> for "foo" in a nice box with a thick arrow coming out the right side.
> Works fine, and much simpler than the full xy syntax. However, I'd
> also like to be able to use the style macros in labels on the arrows
> themselves:
>
> \lab{foo} \arr{r}|\lab{bar}

No, this cannot work, as Xy-pic parsing ceases when the \lab is
encountered.
The macro will not be expanded into directives for placing the label.

Simply extend your \arr  macro above to a variant having a 2nd argument:

\newcommand{\arrlab}[2]{\ar@*{[|(2)]}[#1]|+[F]\txt{\tt #2}}

Use it, for the above examples, as:

\lab{foo} \arr{r}
\arrlab{r}{bar}

>
> But this doesn't work! I get an "Argument of \lab has an extra }"
> message as if something fragile is getting expanded improperly. I
> tried to protect it:
>
> \lab{foo} \arr{r}|\protect\lab{bar}

No. This doesn't help.
Xy-pic parsing is a completely different concept to "fragile" macros in
LaTeX
(which is the purpose of the  \protect  macro).

>
> but even more bizarrely, this results in an unbroken arrow with no
> label at all.
>
> Does anyone have a workaround, or a better way to solve the problem
> without using \newcommand?

Again, you are associating the difficulty with the wrong concept.
There is no problem in using LaTeX's  \newcommand or TeX's  \def  to
define
a macro.  You need to decide just what you want that macro to be doing,
and ensure that it completely encapsulates the work that Xy-pic is
supposed
to perform, in interpreting characters as shorthands for parameters and
commands that ultimately result in the creation of graphical objects.

Your  \lab  needs to know where to place the label, within the picture
and
along the arrow;  alternatively, the \lab {...} macro needs to have been
expanded so that its contents are available for interpretation within a
wider
context.

& \lab{foo} \arr{r}|\lab{bar} &

how should a program decide that the \lab{bar} is meant to be placed
on the arrow, and does not mean to place the string "*+[F]" followed
by  'bar'  set in italics, as part of the contents of the current cell?
(This is what should happen, without the \drop or \POS described above.)

By the way, you are lucky that the first \lab *does* get expanded
within an
Xy-pic parsing context . It was a design-choice for \xymatrix to allow
the first
token in each cell to be expanded. (This is allows \omit to be
detected, as an
override mechanism for alignment templates in TeX's  \halign
structures.)

If you had used something like:   & X \lab{foo} \arr{r}|\lab{bar} & Y
then neither \lab would show as you intended.

>
> Many thanks,

Hope this helps,

Ross Moore

>
> Andrew.