7

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?

Canageek
  • 17,935

2 Answers2

8

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.

Bordaigorl
  • 15,135
7

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

enter image description here

\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
Werner
  • 603,163