# Using tilde ~ in csname in Beamer

In beamer, I would like to be able to use the tilde character ~ in the name of a command sequence. I tried with adjusting catcodes. While this was successful with the standard article class, it failed with beamer:

Working article example:

\documentclass{article}
\begin{document}

\section{cs with tilde}

\catcode\~=12%

\expandafter\def\csname cswith~\endcsname{foo}
cs value:\csname cswith~\endcsname.

\catcode\~=13%

\end{document}


Beamer example producing Missing \endcsname inserted error:

\documentclass{beamer}
\begin{document}

\begin{frame}{cs with tilde}

\catcode\~=12%

\expandafter\def\csname cswith~\endcsname{foo}
cs value:\csname cswith~\endcsname.

\catcode\~=13%

\end{frame}
\end{document}


What am I doing wrong?

-
Does it work outside the frame? Also it's safer to do \begingroup\catcode\~=12 \expandafter … \endgroup, since this will restore the whatever catcode ~ had. –  Andrey Vihrov Mar 21 '11 at 9:59
Outside it seems to work, at least no error. But I want it to work inside the frame environment too. –  AlexG Mar 21 '11 at 10:05
I'm pretty sure the reason is the same as in this question: Conditional compilation of beamer slides. As Martin Scharrer notes there, the frame environment is a pseudo-environment, i.e. actually a macro that reads everything until \end{frame} as an argument. –  Hendrik Vogt Mar 21 '11 at 10:09
You must - as with verbatim content - use the fragile option. \begin{frame}[fragile] –  Ulrike Fischer Mar 21 '11 at 10:13
[fragile] works fine for me and beamer 2010/06/21 development version 3.10 (and it should work fine!). –  Ulrike Fischer Mar 21 '11 at 10:36

As Hendik Vogt already mentioned (by citing me) in the question comments this doesn't work because beamer actually reads the content as macro argument and therefore the catcode change comes to late.

One way to solve this is already mentioned by Ulrike Fischer: use the [fragile] option to make beamer process the frame content in a way which allows catcode changes.

You could also define all the code you require outside the frame as a macro while the catcode changes are in effect and then simply use that macro inside the frame. The catcode is important when the ~ is read not when it is executed/processed.

However, I would solve it quite simple: Use \string~ instead to get ~ as a string:

\documentclass{beamer}
\begin{document}

\begin{frame}{cs with tilde}

\expandafter\def\csname cswith\string~\endcsname{foo}%
cs value:\csname cswith\string~\endcsname.

\end{frame}
\end{document}


Note that you can also use \csdef{cswith\string~}{foo} and \csuse{cswidth\string~} if you load the etoolbox package.

Or even simpler: Redefine ~ locally to produce \string~. Then you have to type less if you need it more often. However, any normal ~ inside the frame or used by macros will not work as usual anymore.

\documentclass{beamer}
\begin{document}

\begin{frame}{cs with tilde}

\def~{\string~}%
\expandafter\def\csname cswith~\endcsname{foo}%
cs value:\csname cswith~\endcsname.

\end{frame}
\end{document}

-
Thanks for your answer. I will use the \def~{\string~} answer approach embedded into a \begingroup \endgroup bracket to limit its effect to the scope of the user command I am writing. –  AlexG Mar 21 '11 at 11:25
@Alexander: Why not use \def~{\ifincsname\string~\else\nobreak\ \fi}`? I didn't test, but I think that should do the right thing. –  TH. Mar 26 '11 at 12:24