I'm trying to write a macro \mappingto which, basically, called after an arrow has been drawn, should add another one below clarifying what elements are mapped to.
e.g. in an easy situation, I'd like
\xymatrix{%
A \ar[rr]^{f}
\mappingto{x}{f(x)}
&& B}
to expand to
\xymatrix{%
A \ar[rr]^{f}
\ar@{|->}[]!/:a(-90) 3ex/*{x};[rr]!/:a(-90) 3ex/*{f(x)}
&& B}
The main problem I have is how to get the source and target of the previous arrow? I naively thought that
\newcommand{\mappingto}[2]{%
\POS c="target"
\POS p="source"
\ar@{|->}"source"!/:a(-90) 3ex/*{#1};"target"!/:a(-90) 3ex/*{#2}
}
would do the trick, but it obviously doesn't : both items get typeset at the same place, namely below A. I tried all switching of c and p, including c=..., c=... and p=..., p=..., in case the <coord>=<"Id"> does update c and p, but none did change anything.
I'm pretty convinced now, even though I couldn't find confirmation in the reference manual, that arrows and paths save the xy state before being drawn, and restore it afterwards.
So here is my question : is there any way to recover the target of the last drawn arrow? (Since c is always the source, recovering the source isn't a problem)
I also have considered the following solutions :
- pass the direction again as a parameter : it would work, but I don't really like it, in the idea of logical coding
- pass the direction as a parameter and make the
\mappingtomacro draw both macros : I'd like to be able to use the\mappingtomacro with any specific shape, label, position for the "regular" arrow, so it would need a lot of more parameters - pass the code of the previous arrow as a parameter : Just calling it and saving c and p before or after wouldn't do the trick, because I can already do that.
I could actually do something with the code of the macro : extract the direction : from
"\ar[rr]^{f}", get"rr". I can almost do it usingxstring, but it seemsxy-piccan't expand macros inside[ ], so I'm back to step one.
Do you guys see any solution? (preferably in a logical programming mood, aka if I could have a way not forcing me to pass direction or previous arrow to the macro, it would be even nicer ^^)
Thanks in advance
Minimal example for those who want to experiment:
\documentclass{article}
\usepackage[all]{xy}
\usepackage{xstring}
% Clean code version
\newcommand{\mappingtoI}[2]{%
\POS c="target"
\POS p="source"
\ar@{|->}"source"!/:a(-90) 3ex/*{#1};"target"!/:a(-90) 3ex/*{#2}
}
% Dirty version
\newcommand{\mappingtoII}[3]{% % First argument is now the first arrow
\StrBetween{#1}{[}{]}[\direction]
% Now \direction expands to the direction of the arrow
#1% % We draw the first arrow...
\ar@{|->}[]!/:a(-90) 3ex/*{#2};[\direction]!/:a(-90) 3ex/*{#3}
% ... and then we try to draw the second one.
}
\begin{document}
% % Uncomment this part to see the expected output.
% Expected output :
% \xymatrix{%
% A \ar[rr]^{f}
% \ar@{|->}[]!/:a(-90) 3ex/*{x};[rr]!/:a(-90) 3ex/*{f(x)}
% && B
% }
What the basic macro gives :
\xymatrix{%
A \ar[rr]^{f}
\mappingtoI{x}{f(x)}
&& B
}
What the "string processing" macro gives :
% Won't compile, comment this matrix out if you are trying to get an output!
\xymatrix{%
A \mappingtoII{\ar[rr]^{f}}
{x}{f(x)}
&& B
}
\end{document}
Edit :
It seems I was wrong stating that xy-pic couldn't expand the macros inside direction definition. Now I think xy-pic tries to evaluate \ar inside macros arguments. :/
Actually, the following macro
\newcommand{\mappingtoTest}[3]{%
\StrBetween[1]{#1}{[}{]}[\direction]
\direction
}
which should just print the direction of the entered macro, returns an error message
!Argument of \next has an extra }.
Funny enough, the following macro doesn't return an error :
\newcommand{\mappingtoTest}[3]{}
Adding \protect before \ar doesn't help, and I tried to play with xstring options, finally getting to this macro, which is the most likely to work at the moment, but still doesn't :
\newcommand{\mappingtoTest}[3]{% % First argument is now the first arrow
\noexpandarg
\StrBetween{#1}{[}{]}[\direction]
% Now \direction expands to the direction of the arrow
\fullexpandarg
#1% % We draw the first arrow...
\ar@{|->}[]!/:a(-90) 3ex/*{#2};[\direction]!/:a(-90) 3ex/*{#3}
% ... and then we try to draw the second one.
}
The noexpandarg makes a difference though, because
\newcommand{\mappingtoTest}[3]{% % First argument is now the first arrow
\noexpandarg
\StrBetween{#1}{[}{]}[\direction]}
does compile, while the same without noexpandarg didn't. If I try to print \direction, I get an obscure xy error again, though. :/

\documentclassand the appropriate packages so that those trying to help don't have to recreate it. – Peter Grill Nov 22 '11 at 23:25\mappingto1and\mappingto2since they contain numerals. Moreover, use (say) thearticledocument class rather thanminimal, since the latter declares very little in terms of usage for a document to play with. – Werner Nov 23 '11 at 3:40\ar[r]and not\ar[rr]– Matsaya Nov 25 '11 at 13:55