Adding fragile
should solve the problem:
\documentclass{beamer}
\begin{document}
\begin{frame}[fragile]{First slide}
\newcommand{\asdf}[1]{What is the #1 problem?}
\end{frame}
\end{document}
Your proposed definition can't work, because TeX makes no expansion to the tokens in the replacement text of a macro and #1
must be literal: it can't be given as #\value{counter}
. There are some tricks for making this possible, but I don't think they would help in your case.
Here's something that might be what you're looking for:
\documentclass{article}
\makeatletter
\newenvironment{myEnvironment}[1]
{\let\myEnv@Temp#1\relax}
{}
\newcommand\myLocalMacro[1]{%
\@tfor\next:=#1\do{\expandafter\myEnv@Temp\expandafter{\next}}%
}
\makeatother
\newcommand{\addhyphen}[1]{#1 - }
\newcommand{\addcomma}[1]{#1, }
\begin{document}
\begin{myEnvironment}{\addhyphen}
\myLocalMacro{FOOBAR1}\par
\myLocalMacro{FOOBAR2}\par
\myLocalMacro{FOOBAR3}\par
\end{myEnvironment}
\begin{myEnvironment}{\addcomma}
\myLocalMacro{TeX}\par
\myLocalMacro{abc}\par
\end{myEnvironment}
\end{document}
The argument to myEnvironment
is the formatting macro which is applied to every token in the argument to \myLocalMacro
.
A different implementation that doesn't require to define auxiliary macros:
\documentclass{article}
\makeatletter
\newenvironment{myEnvironment}[1]
{\renewcommand\myEnv@Temp[1]{#1}}
{}
\newcommand\myEnv@Temp{} % initialize
\newcommand\myLocalMacro[1]{%
\@tfor\next:=#1\do{\expandafter\myEnv@Temp\expandafter{\next}}%
}
\makeatother
\begin{document}
\begin{myEnvironment}{#1 - }
\myLocalMacro{FOOBAR1}\par
\myLocalMacro{FOOBAR2}\par
\myLocalMacro{FOOBAR3}\par
\end{myEnvironment}
\begin{myEnvironment}{#1, }
\myLocalMacro{TeX}\par
\myLocalMacro{abc}\par
\end{myEnvironment}
\end{document}
The argument to myEnvironment
is the formatting you want to apply to each token.
If you want to preserve spaces, you need a more complex approach; here's a straightforward way with expl3
:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentEnvironment{myEnvironment}{m}
{
\cs_set:Nn \pavlik_myenv_temp:n { #1 }
}
{
}
\NewDocumentCommand\myLocalMacro{m}
{
\pavlik_myenv_local:n { #1 }
}
\tl_new:N \l__pavlik_myenv_items_tl
\cs_new_protected:Nn \pavlik_myenv_local:n
{
\tl_set:Nn \l__pavlik_myenv_items_tl { #1 }
\tl_replace_all:Nnn \l__pavlik_myenv_items_tl { ~ } { \c_space_tl } % preserve spaces
\tl_map_inline:Nn \l__pavlik_myenv_items_tl
{
\pavlik_myenv_temp:n { ##1 }
}
}
\ExplSyntaxOff
\begin{document}
\begin{myEnvironment}{#1 - }
\myLocalMacro{FOO BAR1}\par
\myLocalMacro{FOOBAR2}\par
\myLocalMacro{FOOBAR3}\par
\end{myEnvironment}
\begin{myEnvironment}{#1, }
\myLocalMacro{TeX}\par
\myLocalMacro{abc}\par
\end{myEnvironment}
\end{document}
Here \tl_map_inline:Nn
is the analog of \@tfor
; before applying it, we change all spaces in the argument with \c_space_tl
, whose expansion is a space.
Best Answer
You can't accomplish this with one
\newcommand
. There you can define one optional parameter, and it has to be the first one. There is thetwoopt
package that defines\newcommandtwoopt
for two optional parameters, but I don't think it can handle what you want to achieve. I first thought you would need to use TeX's\def
, but here's a solution that's completely free of any\def
s and@
s: