上一篇我們學會了用 iffalse 的語法來編譯出不同的檔案 - 顯示或不顯示解答, 但這些解答都還是在答案卷裡, 一旦改變題序或增刪題目就會全數重做, 即使複製貼上也是要花許多工夫。
因此這篇要來介紹利用 label 和 ref 的功能, 用文字對應的方式, 只要先設定好答案卷格式, 解答直接寫在題目上, 就可以編譯出純題目卷、含解答的題目卷、空白答案卷以及含解答的答案卷四種卷子, 非常好用, 趕快來學。
因為這篇文章幾乎結合了之前的所有語法, 所以語法的理解需要花較多的時間, 若有不懂, 歡迎留言討論。
先介紹 text label 的用法。
一般而言, label 和 ref 大都用在圖、表和文章章節上, 而在這裡, 因為我們想將寫在文章中的某段文字, 重複在文章的其他地方顯示, 並且即使這段文字經過修改, 其他地方的文字也會顯示修改後的最新文字, 我們將此稱為 text label。
......
\usepackage[colorlinks=true, linkcolor=black]{hyperref}
\makeatletter
\newcommand{\textlabel}[2]{%
\protected@write \@auxout {}{\string \newlabel {#1}{{#2}{\thepage}{#2}{#1}{}}}%
\hypertarget{#1}{#2}}
\makeatother
......
\begin{document}
\textlabel{foo}{這段文字想放在哪, 就放在哪}
\ref{foo}
\end{document}
\usepackage[colorlinks=true, linkcolor=black]{hyperref} 這個套件是在 label 和 ref 之間在編譯出來的 PDF 檔上加入超連結, 如果不用的話必須修改 \makeatletter 的整段語法, 有興趣可以留言跟我拿。
語法看不太懂沒關係, 只要知道 \textlabel 的用法是 \textlabel{標籤}{文字}就可以了。要顯示的地方只要加上
\ref{標籤} 即可。
行文至此, 我們可以想像, 在題目卷打上答案之後, 可以把答案直接用 ref 放到答案卷的表格中。而題目卷上的答案和答案卷表格中的答案都可以利用 iffalse 來決定是否要顯示。
這裡衍生出另一個問題是: 如果每個答案都要手動標籤 (label) 再手動對應 (ref), 那麼一旦改變題序, 就要再手動調整, 因此我們結合計數器, 讓 latex 幫我們在每個解答上按著順序自動編上標籤, 並且自動對應到答案卷的表格中。
接下來的語法需結合前面所有的語法, 所以請直接下載範例檔來研究, 這裡只解釋自動編號的做法。
......
%填充題答案, 直接在格子中填入 \ansfis 即可
\newcounter{fillans}\setcounter{fillans}{1}
\newcommand{\ansfis}{\ansis{\ref{fill\thefillans}}\stepcounter{fillans}}
%題目卷上的答案 用\onlyquestiontrue顯示題目卷, 反之顯示答案
\newif\ifonlyquestion
\usepackage[colorlinks=true, linkcolor=black]{hyperref}%
%填充題解答與標籤(自動) \ansf{<answer>} (放在要填入的位置上) 要有hyperref套件
\newcounter{filllabel}\setcounter{filllabel}{1}
\makeatletter
\newcommand{\ansf}[1]{%
\ifonlyquestion
\protected@write \@auxout {}{\string \newlabel {fill\thefilllabel}{{#1}{\thepage}{#1}{fill\thefilllabel}{}}}%
\hypertarget{fill\thefilllabel}{\ansfill} \stepcounter{filllabel}
\else
\protected@write \@auxout {}{\string \newlabel {fill\thefilllabel}{{#1}{\thepage}{#1}{f\thefilllabel}{}}}%
\hypertarget{fill\thefilllabel}{\underline{\hspace{0.2cm}{\bf\boldmath{#1}}\hspace{0.2cm}}} \stepcounter{filllabel}
\fi }
\makeatother
......
\begin{document}
\showanswertrue
\onlyquestiontrue
\題目卷上的題目與答案
\begin{enumerate}
\item 令 $F$ 是抛物線 $\Gamma$: $y^2=4cx$ 的焦點, $A$、$B$ 是 $\Gamma$ 上相異兩點且 $A$、$B$、$F$三點共線。若 $\overline{AF}=8$、$\overline{BF}=6$, 則 $c=$\ansf{$\pm\frac{24}{7}$}。
\item 已知 $P$ 點為雙曲線 $\frac{x^2}{4}-\frac{y^2}{3}=1$ 上的任意點, $F_1$, $F_2$ 為此雙曲線的兩焦點, 若 $\triangle PF_1F_2$ 恰為等腰三角形, 則 $\triangle PF_1F_2$ 的周長為\ansf{$6\sqrt{7}\pm4$}。
\item 設圓 $C$: $(x+4)^2+y^2=16$, 則通過點 $A(2,0)$且與圓 $C$ 相切之圓的圓心所形成的圖形方程式為\ansf{$\frac{(x+1)^2}{4}-\frac{y^2}{5}=1$}。
\item 設 $P$ 為橢圓$\frac{x^2}{16}+\frac{y^2}{9}=1$上一動點, 則當 $(x,y)=$\ansf{$\left(\frac{16}{5}, \frac{9}{5}\right)$} 時, $x+y$ 有最大值\ansf{$5$}。
\end{enumerate}
%答案卷的表格
\begin{tabularx}{\linewidth}{|X|X|X|X|X|}
\hline
(\no) \ansfis &(\no) \ansfis &(\no) \ansfis \rowvs\\
\hline
(\no) \ansfis &(\no) \ansfis &\blank \rowvs\\
\hline
\end{tabularx}
\end{document}
我設定了一個 \ifonlyquestion 來控制題目卷是否顯示解答, 這樣能和答案卷是否顯示解答分開控制, 如果不想分開, 改成之前的 \ifshowanswer 即可。
\newcounter{filllabel}\setcounter{filllabel}{1} 設定新的計數器 filllabel。
{fill\thefilllabel} 這裡的語法就是標籤, 會依 \ansf 的順序自動以 {fill1}{fill2}{fill3}...設定標籤。
\newcounter{fillans}\setcounter{fillans}{1} 設定答案卷 ref 要用的計數器。
\newcommand{\ansfis}{\ansis{\ref{fill\thefillans}}\stepcounter{fillans}} 用 ref 將剛剛的 label 顯示出來。
上述都是填充題的標籤, 因為在題目卷上的解答格式不同, 我把選擇題和填充題的計數器及標籤分開設定。
如範例所示, 題目和答案在打字時直接寫在一起即可。另外只要在答案卷的表格中, 每個打上 \ansfis 就可以了顯示答案了。也就是說, 答案卷只要算好格子, 其他的語法完全不用變動就可以自動編譯出答案卷了。
article_用latex做數學考卷6-3.tex
article_用latex做數學考卷6-3(純題目與空白卷).pdf
article_用latex做數學考卷6-3(題目和含解答的答案卷).pdf
article_用latex做數學考卷6-3(含解答的題目卷和答案卷).pdf