在 LaTeX 中自动排版选项

前言

LaTeX\LaTeX 中排版选择题的选项可能的方法有:

也可以参考在知乎上的问题《用LaTeX怎样排版选择题?》。

之前排选项的时候都是用不同的表格去排的,需要人工判断用哪个命令,非常繁琐,所以弄一个自动判断用哪个命令的代码就很有必要了。

正文

我参考 bhcexam 文档类后,写出了自己的一套排版选项的代码。

% \usepackage{calc,ifthen}

\newlength{\choicelengtha}
\newlength{\choicelengthb}
\newlength{\choicelengthc}
\newlength{\choicelengthd}
\newlength{\maxlength}

\makeatletter
\newcommand{\fourch}[4]{
\par
\settowidth{\choicelengtha}{A.#1}
\settowidth{\choicelengthb}{B.#2}
\settowidth{\choicelengthc}{C.#3}
\settowidth{\choicelengthd}{D.#4}
\ifthenelse{\lengthtest{\choicelengtha>\choicelengthb}}{\setlength{\maxlength}{\choicelengtha}}{\setlength{\maxlength}{\choicelengthb}}
\ifthenelse{\lengthtest{\choicelengthc>\maxlength}}{\setlength{\maxlength}{\choicelengthc}}{}
\ifthenelse{\lengthtest{\choicelengthd>\maxlength}}{\setlength{\maxlength}{\choicelengthd}}{}
\ifthenelse{\lengthtest{\maxlength>0.8\linewidth}}
{%
\noindent%
\begin{tabular}{@{}p{\linewidth}@{}}
\setlength\tabcolsep{0pt}
\@hangfrom{\textsf A.}#1 \\
\@hangfrom{\textsf B.}#2 \\
\@hangfrom{\textsf C.}#3 \\
\@hangfrom{\textsf D.}#4 \\
\end{tabular}
}%
{%
\ifthenelse{\lengthtest{\maxlength>0.22\linewidth}}
{%
\noindent%
\begin{tabular}{@{}p{0.48\linewidth}@{\hspace*{0.04\linewidth}}p{0.48\linewidth}@{}}
\setlength\tabcolsep{0pt}
\@hangfrom{\textsf A.}#1 & \@hangfrom{\textsf B.}#2 \\
\@hangfrom{\textsf C.}#3 & \@hangfrom{\textsf D.}#4 \\
\end{tabular}
}%
{%
\noindent%
\begin{tabular}{@{}*{3}{p{0.22\linewidth}@{\hspace*{0.04\linewidth}}}p{0.22\linewidth}@{}}
\setlength\tabcolsep{0pt}
\@hangfrom{\textsf A.}#1 & \@hangfrom{\textsf B.}#2 & \@hangfrom{\textsf C.}#3 & \@hangfrom{\textsf D.}#4 \\
\end{tabular}
}%
}%
\unskip \unskip
}
\makeatother

分析

逐条去解释命令的作用

  • 新增长度变量,为后面长度比较做铺垫
    \newlength{\choicelengtha}
    \newlength{\choicelengthb}
    \newlength{\choicelengthc}
    \newlength{\choicelengthd}
    \newlength{\maxlength}
  • \makeatletter\makeatother 中将 @ 作为一个字母看待
    \makeatletter
    ...
    \makeatother
  • 读取 A、B、C、D 及其选项的总长度
    \settowidth{\choicelengtha}{A.#1}
    \settowidth{\choicelengthb}{B.#2}
    \settowidth{\choicelengthc}{C.#3}
    \settowidth{\choicelengthd}{D.#4}
  • 作判断,谁长取谁为最大值
    \ifthenelse{\lengthtest{\choicelengtha>\choicelengthb}}{\setlength{\maxlength}{\choicelengtha}}{\setlength{\maxlength}{\choicelengthb}}
    \ifthenelse{\lengthtest{\choicelengthc>\maxlength}}{\setlength{\maxlength}{\choicelengthc}}{}
    \ifthenelse{\lengthtest{\choicelengthd>\maxlength}}{\setlength{\maxlength}{\choicelengthd}}{}
  • 如果最大值的长度大于 0.8\linewidth 就执行后面括号里的命令
    \ifthenelse{\lengthtest{\maxlength>0.8\linewidth}}{...}
  • 每个选项单独排一行
    \noindent%
    \begin{tabular}{@{}p{\linewidth}@{}}
    \setlength\tabcolsep{0pt}
    \@hangfrom{\textsf A.}#1 \\
    \@hangfrom{\textsf B.}#2 \\
    \@hangfrom{\textsf C.}#3 \\
    \@hangfrom{\textsf D.}#4 \\
    \end{tabular}
    • tabular 环境的表格项前后的间距为 0pt

      \setlength\tabcolsep{0pt}

    • 取消前后多余的间距

      @{}p{\linewidth}@{}

    • 产生悬挂缩进的效果

      \@hangfrom

完整的例子

\documentclass{ctexart}
\usepackage{calc,ifthen}

\newlength{\choicelengtha}
\newlength{\choicelengthb}
\newlength{\choicelengthc}
\newlength{\choicelengthd}
\newlength{\choicelengthe}
\newlength{\maxlength}

\makeatletter
\newcommand{\fourch}[4]{
\par
\settowidth{\choicelengtha}{A.#1}
\settowidth{\choicelengthb}{B.#2}
\settowidth{\choicelengthc}{C.#3}
\settowidth{\choicelengthd}{D.#4}
\ifthenelse{\lengthtest{\choicelengtha>\choicelengthb}}{\setlength{\maxlength}{\choicelengtha}}{\setlength{\maxlength}{\choicelengthb}}
\ifthenelse{\lengthtest{\choicelengthc>\maxlength}}{\setlength{\maxlength}{\choicelengthc}}{}
\ifthenelse{\lengthtest{\choicelengthd>\maxlength}}{\setlength{\maxlength}{\choicelengthd}}{}
\ifthenelse{\lengthtest{\maxlength>0.8\linewidth}}
{%
\noindent%
\begin{tabular}{@{}p{\linewidth}@{}}
\setlength\tabcolsep{0pt}
\@hangfrom{\textsf A.}#1 \\
\@hangfrom{\textsf B.}#2 \\
\@hangfrom{\textsf C.}#3 \\
\@hangfrom{\textsf D.}#4 \\
\end{tabular}
}%
{%
\ifthenelse{\lengthtest{\maxlength>0.22\linewidth}}
{%
\noindent%
\begin{tabular}{@{}p{0.48\linewidth}@{\hspace*{0.04\linewidth}}p{0.48\linewidth}@{}}
\setlength\tabcolsep{0pt}
\@hangfrom{\textsf A.}#1 & \@hangfrom{\textsf B.}#2 \\
\@hangfrom{\textsf C.}#3 & \@hangfrom{\textsf D.}#4 \\
\end{tabular}
}%
{%
\noindent%
\begin{tabular}{@{}*{3}{p{0.22\linewidth}@{\hspace*{0.04\linewidth}}}p{0.22\linewidth}@{}}
\setlength\tabcolsep{0pt}
\@hangfrom{\textsf A.}#1 & \@hangfrom{\textsf B.}#2 & \@hangfrom{\textsf C.}#3 & \@hangfrom{\textsf D.}#4 \\
\end{tabular}
}%
}%
\unskip\unskip
}
\makeatother

\begin{document}
\fourch{劳仑衣普桑,认至将指点效则机,最你更枝。想极整月正进好志次回总般,段然取向使张规军证回,世市总李率英茄持伴。用阶千样响领交出,器程办管据家元写,名其直金团。}{test}{test}{test}

\fourch{劳仑衣普桑,认至将指点效则机,最你效则机,最你指点}{test}{test}{test}

\fourch{劳仑衣普桑,认至将指点效则机,最你效则机,最你指}{test}{test}{test}

\fourch{劳仑衣普桑}{test}{test}{test}
\end{document}

效果图:

文章作者: sikouhjw
文章链接: https://sikouhjw.gitee.io/2020/06/24/2020-06-24-Auto-choice/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 sikouhjw.gitee.io