This question led to a new package:
multiple-choice
We can have three types of column typeset. See the image below:
The above image was created using the LaTeX code below:
\documentclass{article}
\usepackage{ifthen}
\usepackage{calc}
\setlength\parindent{0pt}
%usage \choice{ }{ }{ }{ }
%(A)(B)(C)(D)
\newcommand{\fourch}[4]{
\par
\begin{tabular}{*{4}{@{}p{0.23\textwidth}}}
(A)~#1 & (B)~#2 & (C)~#3 & (D)~#4
\end{tabular}
}
%(A)(B)
%(C)(D)
\newcommand{\twoch}[4]{
\par
\begin{tabular}{*{2}{@{}p{0.46\textwidth}}}
(A)~#1 & (B)~#2
\end{tabular}
\par
\begin{tabular}{*{2}{@{}p{0.46\textwidth}}}
(C)~#3 & (D)~#4
\end{tabular}
}
%(A)
%(B)
%(C)
%(D)
\newcommand{\onech}[4]{
\par
(A)~#1 \par (B)~#2 \par (C)~#3 \par (D)~#4
}
\newlength\widthcha
\newlength\widthchb
\newlength\widthchc
\newlength\widthchd
\newlength\widthch
\newlength\tabmaxwidth
\setlength\tabmaxwidth{0.96\textwidth}
\newlength\fourthtabwidth
\setlength\fourthtabwidth{0.25\textwidth}
\newlength\halftabwidth
\setlength\halftabwidth{0.5\textwidth}
\newcommand{\choice}[4]{
\settowidth\widthcha{AM.#1}\setlength{\widthch}{\widthcha}
\settowidth\widthchb{BM.#2}
\ifthenelse{\widthch<\widthchb}{\setlength{\widthch}{\widthchb}}{}
\settowidth\widthchb{CM.#3}
\ifthenelse{\widthch<\widthchb}{\setlength{\widthch}{\widthchb}}{}
\settowidth\widthchb{DM.#4}
\ifthenelse{\widthch<\widthchb}{\setlength{\widthch}{\widthchb}}{}
\ifthenelse{\widthch<\fourthtabwidth}{\fourch{#1}{#2}{#3}{#4}}
{\ifthenelse{\widthch<\halftabwidth\and\widthch>\fourthtabwidth}{\twoch{#1}{#2}{#3}{#4}}
{\onech{#1}{#2}{#3}{#4}}}
}
\begin{document}
Question:
\choice{apple}{banana}{orange}{pear}
\par
Another Question:
\choice{apple}{banana}{orang, eeeeeeeee}{pear}
\par
Third Question:
\choice{apple}{banana}{orange, eeeeeeeee, eeeeeeeee, eeeeeeeee}{pear}
\end{document}
Then main algorithm checks the longest width of the choices, if it is larger than 0.5\textwidth
, then we should use the one column style. If the largest choice is larger than 0.25\textwidth
, then we can put them in the two column style. Otherwise, all the choices can be put on one line.
But I'm not satisfied with the code above. I would like to use the code snippet like below:
\begin{question}
What do you like best?
\begin{choices}
\choice0 apple
\choice1 banana
\choice0 orange
\choice0 pear
\end{choices}
\end{question}
==>
What do you like best?..................................(B)
A. apple B. banana C. orange D. pear
\begin{question}
What do you like best?
\begin{choices}
\choice0 apple
\choice1 banana
\choice0 orang, eeeeeeeee
\choice0 pear
\end{choices}
\end{question}
==>
What do you like best?..................................(B)
A. apple B. banana
C. orange, eeeeeeeee D. pear
\begin{question}
What do you like best?
\begin{choices}
\choice0 apple
\choice1 banana
\choice0 orange, eeeeeeeee, eeeeeeeee, eeeeeeeee
\choice0 pear
\end{choices}
\end{question}
==>
What do you like best?..................................(B)
A. apple
B. banana
C. orange, orange, eeeeeeeee, eeeeeeeee, eeeeeeeee
D. pear
In this code, an environment is used instead of a new command. An issue is that the answer can be automatically put at the end of the question line. It is better to have the answers 'show/hide' option.
Addendum: I have a general approach in mind, which is:
When the LaTeX parser see a \choice0
or \choice1
, it can put the later text in a token list, then all the four token list will be typeset according to their lengths when leaving the question or choices environment, but sorry I'm not familiar with LaTeX programming. (The exam
package does not have such feature I wanted, so that's the reason I asked here.)
Edit: since egreg give me the answer for align the four choices in a compact way. I sill see some improve in putting a dotted line after the question title, and optionally put the correct answer or a blank brace there. So, for egreg's source, if I wrote this:
\begin{choices}
This is the question.\par
\choice0 apple
\choice1 banana
\choice0 orange
\choice0 pear
\end{choices}
Or, it is better to put the question before the choices environment.
This is the question.
\begin{choices}
\choice0 apple
\choice1 banana
\choice0 orange
\choice0 pear
\end{choices}
I would suggest that the output should be:
This is the question...................................( )
A. apple B. banana
C. orange, eeeeeeeee D. pear
Or if need to show the correct answer
This is the question...................................(B)
A. apple B. banana
C. orange, eeeeeeeee D. pear
Thanks.
EDIT2:
As minthao_2011 said in the comments, the code below has some issue, the long choice will not wrap the line, see the image shot below.
\documentclass{article}
\usepackage{environ}
\newlength{\choiceslen}
\newif\ifshowcorrect
\newcounter{choices}
\newcommand{\choicefinal}[1]{%
\ifnum\value{choices}>0 \hfill\fi\egroup
\hspace{0pt}%
\hbox to\choiceslen
\bgroup
\stepcounter{choices}%
\ifcase#1\relax
(\Alph{choices})%
\else
\ifshowcorrect
\expandafter\underline
\fi
{(\Alph{choices})}%
\fi\space}
\newcommand{\choicetemp}[1]{\stepcounter{choices}\space(\Alph{choices})\cr}
\NewEnviron{choices}
{\setcounter{choices}{0}%
\let\choice\choicetemp
\settowidth{\choiceslen}{\vbox{\halign{##\hfil\cr\BODY\crcr}}}
\ifdim\choiceslen>.5\textwidth
\setlength{\choiceslen}{\textwidth}%
\else
\ifdim\choiceslen>.25\textwidth
\setlength{\choiceslen}{.5\textwidth}%
\else
\setlength{\choiceslen}{.25\textwidth}%
\fi
\fi
\let\choice\choicefinal
\setcounter{choices}{0}%
\begin{flushleft}
\bgroup\BODY\hfill\egroup
\end{flushleft}}
\begin{document}
\begin{choices}
\choice0 apple
\choice1 banana
\choice0 orange
\choice0 pear
\end{choices}
\begin{choices}
\choice0 apple
\choice1 banana
\choice0 orang, eeeeeeeee
\choice0 pear
\end{choices}
\showcorrecttrue
\begin{choices}
\choice0 apple
\choice1 banana
\choice0 orange, eeeeeeeee, eeeeeeeee, eeeeeeeee
\choice0 pear
\end{choices}
\begin{choices}
\choice0 This is a very long question. This is a very long question. This is a very long question. This is a very long question.
\choice1 This is a very long question. This is a very long question. This is a very long question. This is a very long question.
\choice0 This is a very long question. This is a very long question. This is a very long question. This is a very long question.
\choice0 This is a very long question. This is a very long question. This is a very long question. This is a very long question.
\end{choices}
\end{document}