# Random form letter text

I want to randomize some of the text contained within some letters. For e.g.:

\random{Dear \name,}{Hello \name,}{Greetings \name,}{Hi \name,}{To \name,}
\random{You are invited to}{You are welcome to}{I would like to invite you to}{This is an invitation to}{You may want to} attend...


When compiled, this would randomly select one of the phrases to use, so that each of the letters is a bit different. How can this be done?

-
–  Joseph Wright Dec 25 '11 at 12:19

Here an implementation for four arguments based on Marc's answer. It uses \ifcase instead of \ifodd. Because random(4) returns 1--4, but \ifcase starts from 0, the first case is actually kept empty. If more than four arguments are wanted simple change [4] and (4) to a higher number and add \or#5 etc. However, more than 9 arguments needs extra work.

\documentclass{article}

\usepackage{pgf}
\newcommand*{\random}[4]{%
\pgfmathparse{random(4)}%
\ifcase\pgfmathresult\relax
\or#1\or#2\or#3\or#4%
\fi%
}

\begin{document}
% Tests:
\random{1}{2}{3}{4}

\random{1}{2}{3}{4}

\random{1}{2}{3}{4}

\random{1}{2}{3}{4}

\random{1}{2}{3}{4}

\random{1}{2}{3}{4}

\random{1}{2}{3}{4}

\random{1}{2}{3}{4}

\random{1}{2}{3}{4}

\random{1}{2}{3}{4}

\random{1}{2}{3}{4}

\random{1}{2}{3}{4}

\end{document}

-

Using the very experimental l3rand package (currently in the l3trial directory of the LaTeX3 code repository, which means it is really not stable), you can do the following.

\documentclass{article}
\usepackage{l3rand,xparse}
\ExplSyntaxOn
\rand_seed_from_time:
\cs_generate_variant:Nn \tl_item:nn { nf }
\DeclareDocumentCommand {\random} {m}
{
\tl_item:nf {#1} { \rand_range:nn {0} { \tl_length:n {#1} - 1 } }
\rand_clean:
}
\ExplSyntaxOff
\begin{document}
\newcommand{\name}{Dave}
\random { {Dear \name,} {Hello \name,} {Greetings \name,} {Hi \name,} {To \name,} }
\random { {You are invited to} {You are welcome to} {I would like to invite you to} {This is an invitation to} {You may want to} }
attend...
\end{document}


Currently, \rand_range:nn {<begin>} {<end>} produces a random number between <begin> and <end> inclusive, hence the need to subtract 1. This may very well be changed later. Also, \rand_seed_from_time: might be renamed by the time this solution is used by anyone.

I added braces around the whole argument of \random, otherwise TeX has no easy way of knowing where it ends.

-
You need to define \newcommand*{\name}{Dave} :-) –  Joseph Wright Dec 25 '11 at 13:10
@JosephWright Thanks. Why Dave? Also, should l3rand initialize with a random seed by default, letting the user override it with \rand_seed:n { <int> }, or should it favor reproducibility, with the user typing \rand_seed_from_time: explicitly if he wants random initialization? –  Bruno Le Floch Dec 25 '11 at 13:13
Now \tl_length:n should be replaced by \tl_count:n (not doing the change now, since this would bump the answer on the front page, and l3rand is still as experimental as always). –  Bruno Le Floch Jul 18 at 16:04

The following should do the trick. For some reason I cannot get it to work without loading the entire tikz package (pgfmath should have sufficed).

\usepackage{tikz}
\newcommand*{\random}[2]{%
\pgfmathparse{random(2)}%
\ifodd\pgfmathresult\relax#1\else#2\fi%
}

-
Welcome to TeX.sx! You don't have to sign with your name since it automatically appears in the lower right corner of your post. –  Joseph Wright Dec 25 '11 at 13:11
See Is it possible to load pgfmath without loading the full pgf package? for an explanation about the issues with loading pgfmath alone. These are fixed in the current develop version. As a workaround loading the pgf package is enough, no need to load the full higher-level tikz layer. –  Martin Scharrer Dec 25 '11 at 13:13
@joseph Thanks for your comment. I'm still learning the interface. –  Marc van Dongen Dec 25 '11 at 13:18
Your solution has a flaw: \ifodd will expand all tokens behind it until it finds something which is not part of a number. Because \pgfmathresult holds a single digit only the content of #1 is searched for a potential rest of this number. This leads to that e.g. \random{1 always}{never} always picks the first argument, because the 1 is appended to the result, making it always odd. You need to terminate the numerical input of \ifodd explicitly either using a \relax or a \space behind \pgfmathresult. –  Martin Scharrer Dec 25 '11 at 13:22