# Why is my macro not expanded inside of \special{…}?

I am writing my first LaTeX/TeX macro and not going anywhere with it. Could you please tell me what I am doing wrong in the code below.

I have the following definitions.

\def\defcolor#1#2{%
\expandafter\def\csname #1\endcsname{#2}}

\def\colortext#1#2{%
\special{ts: text fillcolor \csname#1\endcsname}{#2}%
}


I use them in my LaTeX file as follows:

\defcolor{red}{1.0,0.0,0.0}


Now when I use \red I see 1.0,0.0,0.0 in the text. Which is what I am expecting and happy to see! The problem is the \colortext command. When I call the \colortext command like the following

\colortext{red}{sometext}


I see the following output in my .dvi file

ts: text fillcolor \red


ts: text fillcolor 1.0,0.0,0.0


The \red macro is not getting expanded inside the replacement text of the \colortext macro. How do I fix this problem?

-
 I'm not familar with the specials. But it works fine for me---I get ts: text fillcolor 1.0,0.0,0.0 in dvi file. – Leo Liu Feb 5 '11 at 18:02

First make sure that \red is defined before you use \colortext, because \csname UndefinedMacro\endcsname will expand only so far till \UndefinedMacro, not further.

You could add a test for this:

\makeatletter
\def\colortext#1#2{%
\@ifundefined{#1}
{\PackageError{yourpackage}{Color '#1' not defined yet!}{}}
{\special{ts: text fillcolor \csname#1\endcsname}{#2}}%
}
\makeatother


If this isn't the problem expand it manually:

\makeatletter
\def\colortext#1#2{%
\@ifundefined{#1}
{\PackageError{yourpackage}{Color '#1' not defined yet!}{}}
{{\edef\@tempa{\noexpand\special{ts: text fillcolor \csname#1\endcsname}}\@tempa{#2}}%
}
\makeatother


You can then debug it by adding \show\@tempa after its definition.

Note the second { } to keep \@tempa local. I assume here that \special doesn't mind the group

-
Thanks for answering my question! I tried the first suggestion. It says #1 is not defined. I have \defcolor{red}... before this command and I can use \red in the text. So why is \red (or #1) remaining undefined inside the macro? In the second suggestion, there is a missing closing }. After inserting an additional } it still does not work. – mahes25 Feb 5 '11 at 18:31
Could it be that you define \red inside a group? You might want to change \def to \gdef inside \defcolor to make color definitions global by default or use \global\defcolor{red}{...}, at least for testing. – Martin Scharrer Feb 5 '11 at 18:33
@mahes25: It works fine in my tests. Please see the grouping issue in my last comment and if this doesn't fix it, post a minimal example which shows the error. – Martin Scharrer Feb 5 '11 at 18:59
You are right! I used the \gdef and it worked! Thanks a lot for your help. – mahes25 Feb 5 '11 at 19:06
I see a harmless \noexpand by \special, but \special isn't expandable. – Ahmed Musa Mar 30 '11 at 4:19

try it this way

\documentclass{article}

\makeatletter
\def\defcolor#1#2{\@namedef{#1}{#2}}%
\def\colortext#1#2{\special{ts: text fillcolor \@nameuse{#1}}{#2}}
\makeatother
\begin{document}

\defcolor{red}{1.0,0.0,0.0}

\colortext{red}{sometext}

\end{document}

-
This is helpful. I did not know about \@namedef and \@nameuse. – mahes25 Feb 5 '11 at 19:24
@mahes25: Also the etoolbox package gives you \csdef and \csuse which don't require \makeatletter. The \@namedef and \csdef macros can be prefixed with \global to make the definitions global. – Martin Scharrer Mar 29 '11 at 15:13
I just want to confirm if you actually tested your solution. – Ahmed Musa Mar 30 '11 at 4:18