# Get tokens between two commands

I'm trying to create a screenplay-like class that uses a very simple syntax to create the dialogue, and dumps it as a plain text file for use in subtitles. To divide the subtitle sections I use &, ^ sets a new speaker, like that:

\documentclass{article}
\catcode\^=13
\def^#1: {\par \textbf{#1:}}
\catcode\&=13
\def&{\par \hspace{10pt}}
\begin{document}
^Alice: &Hello Bob. &What's up?
^Bob: &Nothing, really. &Goodbye.
\end{document}


Now I would like to get at the text between &...& (i.e. from & to just before the next &, so &a&b&c should expand to \foo{a}\foo{b}\foo{c}) to save it with a running index to my text file. So I tried \bgroup/egroup as in:

\documentclass{article}
\usepackage{color}
\def\testcommand{\textcolor{blue}}
\catcode\^=13
\def^#1: {\egroup \par \textbf{#1:} \bgroup}
\catcode\&=13
\def&{\egroup \par \hspace{10pt} \testcommand\bgroup}
\begin{document}
\bgroup
^Alice: &Hello Bob. &What's up?
^Bob: &Nothing, really. &Goodbye.
\egroup
\end{document}

And it seems to work, since \textcolor doesn't just colorize the next letter but the whole line, but when I use \def\testcommand#1{(#1)} it is called with an empty argument (produces () Hello Bob. () What…).

I guess this has something to do with the fact that when I use \begingroup/\endgroup with my \testcommand nothing changes but \textcolor breaks with Extra }, or forgotten \endgroup on the first &.

In color.sty they use \def\textcolor#1# which I have never seen before (and when I use it with my testcommand it breaks with \begin{document} ended by \end{)}. What magic is that? Very difficult to google…

My other attempt \def&#1&{ \testcommand{#1} } doesn't work either because it eats the next &… (is there some kind of lookahead? So I could use \def& and eat tokens until the next one would be & or ^?)

Any pointers appreciated!

-
Would the »sffms« class be an option for you? –  Thorsten Donig Jan 13 '11 at 18:01
No, because I want to be able to render multiple versions of the script from the same source (only dialogue/one character highlighted/plain text dumped for subtitles etc). So I have to redefine all commands I use anyway for each output type, and I want a very simple syntax for easy conversion. The other packages are 'too TeXy', but maybe I'll use them as one backend for mine… –  pascal Jan 13 '11 at 18:25
Your code "works for me" doesn't compile (but it does if lines 3 and 4 are interchanged). Moreover, your should post solutions in an answer, not in the question. Yes! It is quite OK if you answer your own question. –  Hendrik Vogt Jan 14 '11 at 9:24

Your post somehow gives a too many questions overflow error. Let me try and answer a bit: You just can't pass an argument to a macro by using \testcommand\bgroup <argument>\egroup. This will only pass \bgroup to your \testcommand.

And yes, your definition \def&#1&{ \testcommand{#1} } does exactly this: It looks for the text between the & signs, and &<some text>& will be replaced with  \testcommand{#1} . Maybe you're looking for something like this:

\documentclass{article}
\def\testcommand#1{(#1)}
\catcode\^=13
\def^#1: {\par \textbf{#1:}}
\catcode\&=13
\def&#1&{\ifx\relax#1\relax\else
\par \hspace{10pt} \testcommand{#1} \expandafter&\fi}
\begin{document}
^Alice: &Hello Bob. &What's up?
^Bob: &Nothing, really. &Goodbye. &&
\end{document}


Note that I used && to indicate the end of the script.

As for your question about \def\textcolor#1#, this makes \textcolor a macro that takes one argument delimited by {. Since the definition is

\def\textcolor#1#{\@textcolor{#1}}


this means that you can use \textcolor<color-model>{..., and this will expand to \@textcolor{<color-model>}{.... Note that <color-model> acts as an optional argument that mustn't contain {.

-
(Since I don't really know what I'm talking about I wanted to be very detailed, hence the length) But that doesn't work with an odd number of &'s. And it applies the \testcommand only to every other line. –  pascal Jan 13 '11 at 18:39
@pascal: Yes, that's what is supposed to happen in my code. I wasn't sure what you wanted to achieve. Now I understand. The problem: You probably do not want to get the text between subsequent & signs. In my modified answer, see what happens if you do that. –  Hendrik Vogt Jan 13 '11 at 18:46
Ah, yes, that's what I wanted. Thanks! Adjusted my question. –  pascal Jan 13 '11 at 19:00
@pascal: If you add && after What's up?, do you then get what you want? –  Hendrik Vogt Jan 13 '11 at 19:05
Yes, I adjusted my definition of ^ to add it before the next ^. –  pascal Jan 13 '11 at 19:11

This works for me:

\documentclass{article}
\catcode\^=13
\catcode\&=13
\def^#1: #2\\{\par \textbf{#1:} #2 &&}
\def\testcommand#1{(#1)}
\def&#1&{%
\ifx\relax#1\else%
\par\hspace{10pt}%
\testcommand{#1}%
\expandafter&%
\fi%
}

\begin{document}
^Alice: &Hello Bob. &What's up?\\
^Bob: &Nothing, really. &Goodbye.\\
\end{document}
-