About
Shop
LaTeX
Software
Books
Gallery
News
Contact
Blog
Settings

Exercise 30: Simple Form Class with Check Boxes (Solution)

This is a solution to Exercise 30.
\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{simple-form}[2014/10/13]

\DeclareOption*{\PassOptionsToClass{\CurrentOption}{article}}

\ProcessOptions

\LoadClass[a4paper,12pt]{article}

\RequirePackage{etoolbox}
\RequirePackage{wasysym}

\newcommand*{\form@fillin}[2]{%
  \makebox[#1][l]{\rlap{#2}\hrulefill}%
}

\newcommand*{\form@checked}{\XBox}
\newcommand*{\form@unchecked}{\Square}

\newcommand*{\form@layout@checkbox}[2]{#1 #2}
\newcommand*{\form@layout@fillin}[3]{#3: \form@fillin{#1}{#2}}

\newcommand*{\reset@element}[2]{%
  \csdef{#2@#1}{\form@unchecked}%
}

\newcommand*{\set@element}[2]{%
  \ifcsdef{#2@#1}%
  {\csdef{#2@#1}{\form@checked}}%
  {%
    \ClassError{simple-form}{Unknown #2 `#1'}{}%
  }%
}

\newcommand*{\use@element}[2]{%
  \ifcsdef{#2@#1}{\csuse{#2@#1}}{\form@unchecked}%
}

\newcommand*{\for@block}[3]{%
  \ifcsdef{@#2list}%
  {%
    \expandafter\@for\expandafter
      #1\expandafter:\expandafter=\csname @#2list\endcsname\do{#3}%
  }%
  {%
    \ClassError{simple-form}{Unknown block `#2'}{}%
  }%
}

\newcommand*{\reset@block}[1]{%
  \for@block{\this@element}{#1}{%
    \reset@element{\expandafter\@firstoftwo\this@element}{#1}%
  }%
}

\newcount\form@columncount

\newcommand*{\form@block}[2]{%
  \def\form@columnargs{}%
  \form@columncount=0\relax
  \loop
   \appto\form@columnargs{l}%
   \advance\form@columncount by 1\relax
  \ifnum\form@columncount<#2
  \repeat
  \def\form@precolumn{}%
  \form@columncount=1\relax
  \begin{tabular}{\form@columnargs}
  \for@block\this@element{#1}%
  {%
    \global\let\this@element\this@element
    \form@precolumn
    \form@layout@checkbox
      {\use@element{\expandafter\@firstoftwo\this@element}{#1}}%
      {\expandafter\@secondoftwo\this@element}%
    \global\advance\form@columncount by 1\relax
    \ifnum\form@columncount>#2\relax
      \global\form@columncount=1\relax
      \gdef\form@precolumn{\\}%
    \else
      \gdef\form@precolumn{&}%
    \fi
  }%
  \end{tabular}%
}

\newcommand*{\@name}{}
\newcommand*{\name}[1]{%
  \renewcommand*{\@name}{#1}%
}

\newcommand*{\@genderlist}{{male}{Male},{female}{Female}}

\newcommand*{\gender}[1]{%
  \reset@block{gender}%
  \set@element{#1}{gender}%
}

\newcommand*{\@projectlist}{%
  {cookies}{Mind-Controlling Cookies},%
  {cakes}{Telepathic Cakes},%
  {chocolates}{Exploding Chocolates},%
  {raygun}{Ray Gun}%
}

\newcommand*{\project}[1]{%
  \reset@block{project}%
  \set@element{#1}{project}%
}

\newcommand*{\@icecreamlist}{%
  {vanilla}{Vanilla},%
  {mint}{Mint},%
  {toffee}{Toffee},%
  {fudge}{Fudge},%
  {guarana}{Guaran\'a},%
  {strawberry}{Strawberry},%
  {raspberry}{Raspberry Ripple},%
  {chilli}{Chilli},%
  {other}{Other}%
}

\reset@block{icecream}%

\newcommand*{\icecream}[1]{%
  \set@element{#1}{icecream}%
}

\newcommand{\makeform}{%
  \form@layout@fillin{8em}{\@name}{Name}\qquad
  \form@layout@fillin{12em}{\@date}{Date}%
  \par
  \bigskip
  \par
  \form@layout@checkbox{\gender@male}{Male}\qquad
  \form@layout@checkbox{\gender@female}{Female}%
  \par
  \bigskip
  \par
  Which project would you like to enrol on? (Tick one box.)
  \par
  \begin{center}
  \form@block{project}{2}
  \end{center}
  \par
  Which ice-cream flavours do you like? (Tick all that apply.)
  \par
  \begin{center}
  \form@block{icecream}{3}
  \end{center}
}

\endinput

The more adventurous part requires only a minor modification. First new commands in the same style as \@name and \name:
\newcommand*{\@othericecream}{}
\newcommand*{\othericecream}[1]{%
 \icecream{other}%
 \renewcommand*{\@othericecream}{#1}%
}
Note that in addition to setting \@othericecream, \othericecream also performs \icecream{other}. The fill-in area now just needs to be added to the text assigned to the other element:
\newcommand*{\@icecreamlist}{%
  {vanilla}{Vanilla},%
  {mint}{Mint},%
  {toffee}{Toffee},%
  {fudge}{Fudge},%
  {guarana}{Guaran\'a},%
  {strawberry}{Strawberry},%
  {raspberry}{Raspberry Ripple},%
  {chilli}{Chilli},%
  {other}{\form@layout@fillin{6em}{\@othericecream}{Other}}%
}

Download simple-form.cls and example document simple-form-exercise.tex or simple-form-exercise.pdf.

© 2015 Dickimaw Books. "Dickimaw", "Dickimaw Books" and the Dickimaw parrot logo are trademarks. The Dickimaw parrot was painted by Magdalene Pritchett.

Terms of Use Privacy Policy Cookies Site Map FAQs