# Print name of command, defined by \csname

First off: I do not understand \expandafter and \noexpand completely which is probably the main problem. I have found a question that explains what it does, but still I cannot seem to make it work.

I simply want to print the name of a command using \csname like this:

\def\str{String}

Command: \csname str\endcsname.\par
End command.


This prints the contents of \str (String), but I want to prevent the last expansion. I thought this would work:

Command: \expandafter\noexpand\csname str\endcsname.\par


This would first expand \csname to \str, and then \noexpand should prohibit the next expansion. But apparently, this gives a blank output, which is actually very strange.

So I want to expand \csname, but not \str.

EDIT: Few things to consider I did not know they were important (or just did not thought through):

1. It's for writing to a file.
2. It also has to work for non-\csname based commands.

Thus the code changes to:

\immediate\write\file{Command: \expandafter\noexpand\csname str\endcsname}


Which works (as egreg said), but does not work with

\immediate\write\file{Command: \expandafter\noexpand\str}


This is needed because I need to make a command that shows the command. In total it should look like this:

\newcommand\writecmd[1]{
\immediate\write\file{\expandafter\noexpand#1}
}

\def\str{Blahblah}

\writecmd{\str}
\writecmd{\csname str\endcsname}


This outputs

Blahblah
\str


which is almost what I needed. If there is a workaround, that's fine too. Mind that the command \writecmd is in my program a little bit more extensive.

-
The \expandafter\noexpand method would be good for writing in a file; the command name would be followed by a space, which is not the case for \expandafter\string. – egreg Jul 24 '12 at 9:40
Oh great.. Yeah it is actually for writing to a file. I was just testing it without having to use a file.. But there seems to be another problem: it has to show the command regardless if \csname is there or just the command.. I'll update my question. – Didii Jul 24 '12 at 9:47

  Command: \expandafter\string\csname str\endcsname.\par


\noexpand prevents expansion by making the command temporarily act like \relax If you had gone

  Command: \relax\par


It would not have printed "\relax" You need

  Command: \string\relax\par


for that.

So first you want to do the csname to get the command name token then you want to use \string on that to get back to where you started, but with a backslash, so

  Command: \expandafter\string\csname str\endcsname.\par


Or of course

  Command: \@backslashchar str.\par


For your updated question, you want to test for \csname

\def\foo#1{%
\ifx\csname#1%
\expandafter\expandafter\expandafter\string
\expandafter\csname
\else
\string#1%
\fi}

\immediate\write20{\foo\fffff}

\immediate\write20{\foo\csname fff99ff\endcsname}

\bye


produces

\$ tex cs88
This is TeX, Version 3.1415926 (TeX Live 2012)
(./cs88.tex
\fffff
\fff99ff
)
No pages of output.

-
\csname @backslashchar\endcsname str.\par :) – egreg Jul 24 '12 at 9:35
Thanks, I've learned something new again :), but it was not what I needed. My question was sadly not correct. Look for the edit and comment. Thanks though. – Didii Jul 24 '12 at 9:59
Wouldn't detokenize do the job here? – percusse Jul 24 '12 at 10:08
@percusse far too modern for me:-) – David Carlisle Jul 24 '12 at 10:18
@Didii don't undo it now but actually it's better, if you decide you didn't ask the right question, to accept the answer you didn't want and ask another question on site, otherwise when people come to the site later the answers look silly and/or wrong as they are answering a question that is no longer there. – David Carlisle Jul 24 '12 at 10:20