# Can't implement new command in latex (under beamer)

I'm trying to create a new command that will ease on reference placement under beamer. This is an example file:

\documentclass[bigger]{beamer}
\usepackage[absolute,overlay]{textpos}
\tolerance=1000

\newcommand{\myref}[3]{
\begin{textblock*}{100mm}(0.07\textwidth,.93\textheight)
{\footnotesize #1, {\emph #2}, #3}
\end{textblock*}}

\begin{document}

\begin{frame}
\myref{must, write, something}
\end{frame}

\end{document}


When I try to run it through pdflatex I get:

tionary/translator-theorem-dictionary-English.dict) (./error.nav)
! Argument of \end has an extra }.
<inserted text>
\par
l.14 \end{frame}

Runaway argument?
! Paragraph ended before \end was complete.
\par
l.14 \end{frame}

! LaTeX Error: \begin{beamer@framepauses} on input line 14 ended by \end{docume
nt}.

See the LaTeX manual or LaTeX Companion for explanation.
Type  H <return>  for immediate help.
...

l.17 \end{document}

(./error.aux)
! You can't use \end' in internal vertical mode.
\enddocument ... \endgroup \deadcycles \z@ \@@end

l.17 \end{document}

! LaTeX Error: \begin{beamer@framepauses} on input line 14 ended by \end{docume
nt}.

See the LaTeX manual or LaTeX Companion for explanation.
Type  H <return>  for immediate help.
...

l.17 \end{document}

)
! Emergency stop.
<*> \nonstopmode\input error.tex

!  ==> Fatal error occurred, no output PDF file produced!
Transcript written on error.log.
[yotam@myhost Res.Prop.Exam]\$


I couldn't find my missing } can you? *note that my tex file is named Error.tex

-
You've defined \myref to have three arguments, but have only given one. So TeX grabs \end as #2 and document as #3, and then all sorts of issues arise. – Joseph Wright Apr 17 '12 at 8:26
(actually, it grabs frame as #3, leaving \end{document} as the closure of \begin{frame} which is why the error is \begin{beamer@framepauses} ... ended by \end{document}) – Andrew Stacey Apr 17 '12 at 8:28
So I should call it through \myref{must}{write}{something}? – Yotam Apr 17 '12 at 8:29
@AndrewStacey Oh yes, so it does – Joseph Wright Apr 17 '12 at 8:30
@Yotam: Yes you should. – Andrew Stacey Apr 17 '12 at 8:32
show 1 more comment

The problem here is that the command is defined with three arguments but only one is give. Two possible solutions are available: use three arguments or use one and parse the comma-separated input. The first case is just

\myref{must}{write}{something}


For the second case, I would use xparse

\documentclass[bigger]{beamer}
\usepackage{xparse}
\usepackage[absolute,overlay]{textpos}
\tolerance=1000

\NewDocumentCommand{\myref}{>{\SplitArgument{2}{,}}m}{%
\myrefaux#1%
}
\newcommand{\myrefaux}[3]{%
\begin{textblock*}{100mm}(0.07\textwidth,.93\textheight)
{\footnotesize #1, {\em #2}, #3}
\end{textblock*}
}

\begin{document}

\begin{frame}
\myref{must, write, something}
\end{frame}

\end{document}


There are many ways of setting up a comma-separated list parser, but this one is pretty easy. The auxiliary function will get three arguments in all cases, even if you mess up and forget a comma or something similar.

-

As Andrew Stacey mentioned in his comment you must write \myref{must}{write}{something}. If you want the syntax: \myref{must, write, something} you can do the following:

\newcommand{\myref}[1]{\myrefI#1\nil}
\def\myrefI#1,#2,#3\nil{%
\begin{textblock*}{100mm}(0.07\textwidth,.93\textheight)
{\footnotesize #1, {\emph #2}, #3}
\end{textblock*}%
}


The complete MWE:

\documentclass[bigger]{beamer}
\usepackage[absolute,overlay]{textpos}
\tolerance=1000

\newcommand{\myref}[1]{\myrefI#1\nil}
\def\myrefI#1,#2,#3\nil{%
\begin{textblock*}{100mm}(0.07\textwidth,.93\textheight)
{\footnotesize #1, {\emph #2}, #3}
\end{textblock*}%
}

\begin{document}

\begin{frame}
\myref{must, write, something}

\end{frame}

\end{document}
`
-