# Active characters inside commands

I'm trying to ease my typesetting of phonetics with tipa by creating a custom command myipa which is supposed to substitute some common characters for the corresponding tipacodes. A much simplified example follows below, which replaces all as with @s (which is the tipa code for a schwa):

\documentclass{article}
\usepackage{tipa}

\newcommand*\mytransform[1]{
\begingroup%
\catcode\a=\active%
\def a{@}%
#1%
\endgroup%
}

\newcommand*\myipa[1]{\textipa{\mytransform{#1}}}

\begin{document}

\myipa{blabla}

\end{document}


However, all I get is Missing control sequence inserted \myipa{blabla}. This is my first time experimenting with active characters, so there is a high probability that I have completely misunderstood some important central idea, so feel free to fill me in.

## 1 Answer

Using active characters is not recommended for this application: you lose the possibility of having any control sequence with an a in its name inside the argument of \myipa.

How could you do it? Here's what's necessary.

\documentclass{article}
\usepackage{tipa}

\newcommand\myipa{%
\begingroup\catcode\a=\active
\begingroup\lccode~=a
\lowercase{\endgroup\def~}{@}%
\innermyipa
}
\newcommand*{\innermyipa}[1]{\textipa{#1}\endgroup}

\begin{document}

\myipa{blabla}

\end{document}


The definition of a as active character has to be done indirectly; there are other ways, but this one is good because it sets the meaning of the active a only locally. The most important thing is not to absorb the argument before activating the character.

The disadvantage is that \myipa can't be used in the argument of another command, so \section{Here is \myipa{blabla}} would die horribly.

A different approach is to do a string substitution. You can use the xstring package or expl3 with xparse.

\documentclass{article}
\usepackage{tipa}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\myipa}{sm}
{
\IfBooleanTF{#1}
{ \textipa{ #2 } }
{ \gaussler_myipa:n { #2 } }
}

\tl_new:N \l__gaussler_input_tl

\cs_new_protected:Npn \gaussler_myipa:n #1
{
\tl_set:Nn \l__gaussler_input_tl { #1 }
% change each a' into @'
\tl_replace_all:Nnn \l__gaussler_input_tl { a } { @ }
\textipa{ \l__gaussler_input_tl }
}
\ExplSyntaxOff

\begin{document}

\section{Here is \myipa{blabla}}

\myipa{blabla}

\myipa*{blabla}
\end{document}


This command can be used in arguments; I also added a *-variant that doesn't do any substitution.