4

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!

pascal
  • 2,122
  • 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 09:24

2 Answers2

3

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 {.

Hendrik Vogt
  • 37,935
  • (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
  • @pascal: I don't quite see how you're doing that, but I'm glad that I could help. – Hendrik Vogt Jan 13 '11 at 19:38
  • updated the question with my solution. & now nested in ^ which appends the && (makes more sense in my greater context) – pascal Jan 14 '11 at 03:55
  • Ah but a new problem came up: I only write the text captured between & to my output file. The text that isn't captured for example ^foo: bar\\ gets set into the normal output, which I don't want. My attempt at wrapping it all in an \edef failed (I thought it would be expanded, thus written to the file, and the resulting stray characters stored in my dummy macro I never call) Is there some kind of \ignore{...} command? All the solutions I came up with were very nasty, like shoving it to the end and cutting of the junk pages it generates …Or should I put that in a separate question? – pascal Jan 14 '11 at 04:31
  • @pascal: I'm really not sure what you're trying to do. In ^Alice: &Hello Bob. &What's up?\\, the Alice: also isn't captured: Is that intended or not? And in ^foo: bar\\, what do you want to capture? Only the bar? Then put & in front of it! – Hendrik Vogt Jan 14 '11 at 09:29
  • Posted it http://tex.stackexchange.com/questions/8981/ here as a seperate question, and I even found a strange answer – pascal Jan 14 '11 at 21:32
1

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}
pascal
  • 2,122