Can I automatically draw my cards from a list?

So, I've made a format to print cards out (Shown below). Is it possible for me to fill each card environment from some sort of list, instead of having to write out \cards{foo} for each card? I could use a script to do this, but I thought it would be interesting to try it in LaTeX.

\documentclass{article}
\usepackage[margin=2cm]{geometry}

\newlength\cardheight
\newlength\cardwidth

\setlength\cardheight{0.4\textheight}
\setlength\cardwidth{0.49\textwidth}

\newcommand\cards[1]{%
\fbox{\begin{minipage}[t][\cardheight][t]{\dimexpr\cardwidth-2\fboxsep-2\fboxrule\relax}
\vspace{\baselineskip}
\huge ~ #1
\vfill
\normalsize ~ Cards Against Humanity %I should insert the CAH logo in my final version
\end{minipage}}
\hspace{1pt}}

\pagestyle{empty}

\begin{document}
\centering

\cards{%
Classicist undertones.
} %
\cards{%
A windmill full of corpses.
} %
\cards{%
A tiny horse.
} %
\cards{%
One more card.
} %

\end{document}


So, what I'd do now would be to write all the cards I want into a newline separated file, then write a quick program to wrap each line in "\cards{%\n\n}%"

Is there a way to do this all with LaTeX, so that I only have to have the one file, instead of an external card file, a conversion program and a LaTeX file?

A pure LaTeX solution (no extra package needed):

\documentclass{article}
\usepackage[margin=2cm]{geometry}

\newlength\cardheight
\newlength\cardwidth

\setlength\cardheight{0.4\textheight}
\setlength\cardwidth{0.49\textwidth}

\newcommand\card[1]{%
\fbox{\begin{minipage}[t][\cardheight][t]{\dimexpr\cardwidth-2\fboxsep-2\fboxrule\relax}
\vspace{\baselineskip}
\huge ~ #1
\vfill
\normalsize ~ Cards Against Humanity %I should insert the CAH logo in my final version
\end{minipage}}%
\hspace{1pt}}

\makeatletter
\newcommand{\cards}[1]{
\@for\@c:=#1\do{%
\card{\@c}%
}%
}
\makeatother

\pagestyle{empty}

\begin{document}
\centering

\cards{%
Classicist undertones.,%
A windmill full of corpses.,%
A tiny horse.,%
One more card.
}%

\end{document}


Here the \cards command accepts a comma separated list with the captions and loops through the list with LaTeX's \@for where in each iteration \@c will contain the current caption.

• Nice. Add a % after \end{minipage}} to avoid spurious spaces. – karlkoeller Nov 26 '13 at 14:55
• Nice. How do I escape a comma, as some of the cards have commas on them? Can I wrap them in braces like I can with etoolbox? – Canageek Nov 26 '13 at 17:21
• @Canageek yes you can: \cards{{a,b},c} will typeset two cards – Bordaigorl Nov 26 '13 at 17:49

Use any list-processing package. Here's an etoolbox version:

\documentclass{article}
\usepackage[margin=2cm]{geometry}% http://ctan.org/pkg/geometry
\usepackage{etoolbox}% http://ctan.org/pkg/etoolbox

\newlength\cardheight
\newlength\cardwidth

\setlength\cardheight{0.4\textheight}
\setlength\cardwidth{0.49\textwidth}

\newcommand{\card}[1]{%
\fbox{\begin{minipage}[t][\cardheight][t]{\dimexpr\cardwidth-2\fboxsep-2\fboxrule\relax}
\vspace{\baselineskip}
\huge ~ #1
\vfill
\normalsize ~ Cards Against Humanity %I should insert the CAH logo in my final version
\end{minipage}}%
\hspace{1pt}}
\newcommand{\cards}[1]{%
\renewcommand*{\do}[1]{\card{##1}}% How to process each item
\expandafter\docsvlist\expandafter{#1}}% Process list

\pagestyle{empty}

\begin{document}
\centering

\cards{%
Classicist undertones.,%
A windmill full of corpses.,%
A tiny horse.,%
One more card.
}%

\end{document}


The list is a comma-separated list. If an item contains a commas, then you need to wrap it in braces {..., ..}.

An equivalent LaTeX3 implementation would require the following definition of \cards:

\ExplSyntaxOn
\DeclareDocumentCommand{\cards}{ > { \SplitList { , } } m }{%
\ProcessList {#1} { \card }}% Process list
\ExplSyntaxOff