免費論壇 繁體 | 簡體
Sclub交友聊天~加入聊天室當版主
分享
返回列表 发帖

之前选择题选项排版的 bug 及改进

话说昨天网友问我选择题选项怎么排版,我就给了《撸题集》里的相关代码。
那段代码依赖两个宏包:calc、ifthen,后来想到,既然作为“零件”使用,代码应尽量不依赖宏包才好,于是决定改写一下。
然而改写完在测试的时候,却发现原先的设计其实存在 bug,只不过一般碰不到,所以在撸题集用这么久都没发现。
请看以下示例:
  1. \documentclass{article}
  2. \usepackage{calc,ifthen}
  3. \newlength\lxxa
  4. \newlength\lxxb
  5. \newlength\lxxc
  6. \newlength\lxxd
  7. \newlength\lxxmax
  8. \newlength\lhalf
  9. \newlength\lhalfhalf
  10. \newcommand\xx[4]{%
  11. \settowidth\lxxa{A. #1}%
  12. \settowidth\lxxb{B. #2}%
  13. \settowidth\lxxc{C. #3}%
  14. \settowidth\lxxd{D. #4}%
  15. \ifthenelse{
  16.     \lengthtest{\lxxa > \lxxb}
  17. }{%
  18.     \setlength\lxxmax\lxxa
  19. }{%
  20.     \setlength\lxxmax\lxxb
  21. }%
  22. \ifthenelse{
  23.     \lengthtest{\lxxmax < \lxxc}
  24. }{%
  25.     \setlength\lxxmax\lxxc
  26. }{}%
  27. \ifthenelse{
  28.     \lengthtest{\lxxmax < \lxxd}
  29. }{%
  30.     \setlength\lxxmax\lxxd
  31. }{}%
  32. \addtolength\lxxmax{1.5em}%
  33. \setlength\lhalf{(\linewidth-\parindent)/2}%
  34. \setlength\lhalfhalf{\lhalf/2}%
  35. \ifthenelse{
  36.     \lengthtest{\lxxmax > \lhalf}
  37. }{%
  38. A. #1 \par B. #2 \par C. #3 \par D. #4%
  39. }{%
  40.     \ifthenelse{
  41.         \lengthtest{\lxxmax > \lhalfhalf}
  42.     }{%
  43.         \begin{minipage}{\lhalf}
  44.         A. #1
  45.         \end{minipage}%
  46.         \begin{minipage}{\lhalf}
  47.         B. #2
  48.         \end{minipage}\par
  49.         \begin{minipage}{\lhalf}
  50.         C. #3
  51.         \end{minipage}%
  52.         \begin{minipage}{\lhalf}
  53.         D. #4
  54.         \end{minipage}%
  55.     }{%
  56.         \begin{minipage}{\lhalfhalf}
  57.         A. #1
  58.         \end{minipage}%
  59.         \begin{minipage}{\lhalfhalf}
  60.         B. #2
  61.         \end{minipage}%
  62.         \begin{minipage}{\lhalfhalf}
  63.         C. #3
  64.         \end{minipage}%
  65.         \begin{minipage}{\lhalfhalf}
  66.         D. #4
  67.         \end{minipage}%
  68.     }%
  69. }}

  70. \begin{document}

  71. \rule{0.3\linewidth}{1ex}

  72. \xx{\rule{0.3\linewidth}{1ex}}234

  73. \end{document}
复制代码
结果:
QQ截图20170611145949.png
2017-6-11 16:04


考考大家,为什么同样的 rule 在选项里却变短了呢?


幸好修正它也不难,顺便地,我决定将“四图选项”命令 \fourtuxx 也改写下(原先的只能一行)。
  1. \documentclass{article}
  2. \usepackage{graphicx}%纯粹为演示图形选项

  3. %选项自动排版,不依赖宏包
  4. %用法 \xx{选项}{选项}{选项}{选项},会自动判断排版方式
  5. \newlength\lxxa
  6. \newlength\lxxb
  7. \newlength\lxxc
  8. \newlength\lxxd
  9. \newlength\lxxmax
  10. \newlength\lhalf
  11. \newlength\lhalfhalf
  12. \newsavebox\xxboxa
  13. \newsavebox\xxboxb
  14. \newsavebox\xxboxc
  15. \newsavebox\xxboxd

  16. \newcommand\getboxsandmax[4]{%
  17. \sbox\xxboxa{#1}%
  18. \sbox\xxboxb{#2}%
  19. \sbox\xxboxc{#3}%
  20. \sbox\xxboxd{#4}%
  21. \settowidth\lxxa{\usebox\xxboxa}%
  22. \settowidth\lxxb{\usebox\xxboxb}%
  23. \settowidth\lxxc{\usebox\xxboxc}%
  24. \settowidth\lxxd{\usebox\xxboxd}%
  25. \ifdim\lxxa>\lxxb
  26. \lxxmax\lxxa
  27. \else
  28. \lxxmax\lxxb
  29. \fi
  30. \ifdim\lxxmax<\lxxc
  31. \lxxmax\lxxc
  32. \fi
  33. \ifdim\lxxmax<\lxxd
  34. \lxxmax\lxxd
  35. \fi
  36. }

  37. \newcommand\xx[4]{%
  38. \getboxsandmax{A. #1}{B. #2}{C. #3}{D. #4}%
  39. \addtolength\lxxmax{1em}%
  40. \setlength\lhalf{\dimexpr(\linewidth-\parindent)/2\relax}%
  41. \setlength\lhalfhalf{.5\lhalf}%
  42. \ifdim\lxxmax>\lhalf
  43.     \usebox\xxboxa \par
  44.     \usebox\xxboxb \par
  45.     \usebox\xxboxc \par
  46.     \usebox\xxboxd
  47. \else
  48.     \ifdim\lxxmax>\lhalfhalf
  49.         \begin{minipage}{\lhalf}
  50.         \usebox\xxboxa
  51.         \end{minipage}%
  52.         \begin{minipage}{\lhalf}
  53.         \usebox\xxboxb
  54.         \end{minipage}\par
  55.         \begin{minipage}{\lhalf}
  56.         \usebox\xxboxc
  57.         \end{minipage}%
  58.         \begin{minipage}{\lhalf}
  59.         \usebox\xxboxd
  60.         \end{minipage}%
  61.     \else
  62.         \begin{minipage}{\lhalfhalf}
  63.         \usebox\xxboxa
  64.         \end{minipage}%
  65.         \begin{minipage}{\lhalfhalf}
  66.         \usebox\xxboxb
  67.         \end{minipage}%
  68.         \begin{minipage}{\lhalfhalf}
  69.         \usebox\xxboxc
  70.         \end{minipage}%
  71.         \begin{minipage}{\lhalfhalf}
  72.         \usebox\xxboxd
  73.         \end{minipage}%
  74.     \fi
  75. \fi
  76. }

  77. %四图选项自动排版,不依赖宏包,图不得太宽
  78. \newcommand\fourtuxx[4]{%
  79. \vspace{2ex}%
  80. \getboxsandmax{#1}{#2}{#3}{#4}%
  81. \addtolength\lxxmax{1em}%
  82. \setlength\lhalf{.5\linewidth}%
  83. \setlength\lhalfhalf{.5\lhalf}%
  84. \ifdim\lxxmax>\lhalf
  85. images too big! please change width to less than 0.5linewidth-1em.
  86. \else
  87.     \ifdim\lxxmax>\lhalfhalf
  88.         \noindent
  89.         \begin{minipage}[b]{\lhalf}
  90.         \centering
  91.         \usebox\xxboxa\par A
  92.         \end{minipage}%
  93.         \begin{minipage}[b]{\lhalf}
  94.         \centering
  95.         \usebox\xxboxb\par B
  96.         \end{minipage}\par\vspace{2ex}%
  97.         \noindent
  98.         \begin{minipage}[b]{\lhalf}
  99.         \centering
  100.         \usebox\xxboxc\par C
  101.         \end{minipage}%
  102.         \begin{minipage}[b]{\lhalf}
  103.         \centering
  104.         \usebox\xxboxd\par D
  105.         \end{minipage}%
  106.     \else
  107.         \noindent
  108.         \begin{minipage}[b]{\lhalfhalf}
  109.         \centering
  110.         \usebox\xxboxa\par A
  111.         \end{minipage}%
  112.         \begin{minipage}[b]{\lhalfhalf}
  113.         \centering
  114.         \usebox\xxboxb\par B
  115.         \end{minipage}%
  116.         \begin{minipage}[b]{\lhalfhalf}
  117.         \centering
  118.         \usebox\xxboxc\par C
  119.         \end{minipage}%
  120.         \begin{minipage}[b]{\lhalfhalf}
  121.         \centering
  122.         \usebox\xxboxd\par D
  123.         \end{minipage}%
  124.     \fi
  125. \fi
  126. }


  127. \begin{document}

  128. \newcommand\test{test test test test test test test test test test test test test test test test test test test test test test}

  129. \rule{0.15\linewidth}{1ex} \test

  130. \xx{\rule{0.15\linewidth}{1ex}}234

  131. \rule{0.3\linewidth}{1ex} \test

  132. \xx{\rule{0.3\linewidth}{1ex}}234

  133. \rule{0.5\linewidth}{1ex} \test

  134. \xx{\rule{0.5\linewidth}{1ex}}234


  135. \begin{itemize}
  136. \item\rule{0.15\linewidth}{1ex} \test

  137. \xx{\rule{0.15\linewidth}{1ex}}234

  138. \item\rule{0.3\linewidth}{1ex} \test

  139. \xx{\rule{0.3\linewidth}{1ex}}234

  140. \item\rule{0.5\linewidth}{1ex} \test

  141. \xx{\rule{0.5\linewidth}{1ex}}234

  142. \begin{itemize}
  143. \item\rule{0.15\linewidth}{1ex} \test

  144. \xx{\rule{0.15\linewidth}{1ex}}234

  145. \item\rule{0.3\linewidth}{1ex} \test

  146. \xx{\rule{0.3\linewidth}{1ex}}234

  147. \item\rule{0.5\linewidth}{1ex} \test

  148. \xx{\rule{0.5\linewidth}{1ex}}234
  149. \end{itemize}
  150. \end{itemize}


  151. \test

  152. \fourtuxx
  153. {\includegraphics[width=0.2\linewidth]{example-image-a}}
  154. {\includegraphics[width=0.2\linewidth]{example-image-b}}
  155. {\includegraphics[width=0.2\linewidth]{example-image-c}}
  156. {\includegraphics[width=0.2\linewidth]{example-grid-100x100pt}}

  157. \test

  158. \fourtuxx
  159. {\includegraphics[width=\dimexpr0.5\linewidth-1em\relax]{example-image-a}}
  160. {\includegraphics[width=\dimexpr0.5\linewidth-1em\relax]{example-image-b}}
  161. {\includegraphics[width=\dimexpr0.5\linewidth-1em\relax]{example-image-c}}
  162. {\includegraphics[width=0.45\linewidth]{example-grid-100x100pt}}

  163. the above image width is max, try more 0.01pt will get:

  164. \fourtuxx
  165. {\includegraphics[width=\dimexpr0.5\linewidth-1em+0.01pt\relax]{example-image-a}}
  166. {}{}{}

  167. \end{document}
复制代码
代码仍在测试中,效果见:https://www.texide.com/project/593ba4bbde33274f5f5ed540
分享到: QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
这名字我喜欢

看着就头大,这代码不友好,长。

TOP

回复 2# isee

那不过是因为有四个选项,每次总要重复四次才显得长啊,其实原理是很好理解的。

TOP

回复  isee

那不过是因为有四个选项,每次总要重复四次才显得长啊,其实原理是很好理解的。 ...
色k 发表于 2017-6-11 17:13


有曾看到过四选自动排列的代码,相对要短些,可惜,现在找不到了。。。。

TOP

本帖最后由 色k 于 2017-6-11 18:01 编辑

回复 4# isee

相信原理都差不多的,肯定不会比我改进前的代码短多少。
重点是原理,上面的代码其实要改短也完全可以,比如将 minipage 环境改成 \parbox ,三行变一行,就会短很多,但我懒得改
习惯了用 minipage,尽管和 \parbox 几乎无区别。

TOP

话说昨天网友问我选择题选项怎么排版,我就给了《撸题集》里的相关代码。
那段代码依赖两个宏包:calc、ift ...
色k 发表于 2017-6-11 16:04


对了,这是不是最终版了?若是想拿来就用了。。
哈哈,虽然一般不超过二十道选择题,手控。。。。

TOP

回复 6# isee

嗯,发完这帖后就没改过了(而且也没实际用过了,已经好久没录入过什么了,懒得要死……)

TOP

回复 7# kuing


    你自己写了个“宏包”。。。。。先标记。。。。

TOP

返回列表 回复 发帖