LaTeXで試験問題を作成しているのですが、採点のために解答も同じファイルに記述しておきたいです。問題と解答でファイルを二つ用意すると監理が面倒ですし、ファイルを開けて書き直すことも面倒です。そこで、LaTeXで処理することで問題用紙と採点用の解答付きの2種類の文書を作成する方法を検討しました。
外部の処理がないと作れない
LaTeXはオプションも環境変数も内部では参照できないので、何らか外部の処理に頼る必要があります。そこで、ファイルを書き換えないで済むように Make を利用することにしました。
pLaTeX でファイルでなく、二重引用符でコードが書けました
pLaTeX を使っています。
$ platex -version
e-pTeX 3.14159265-p3.8.2-190908-2.6 (utf8.euc) (TeX Live 2019/Debian)
kpathsea version 6.3.1
ptexenc version 1.3.7
Copyright 2019 D.E. Knuth.
(以下略)
platex ファイル名
でなく、二重引用符でコードを処理できることを ChatGPT で知りました。
$ platex "\documentclass{jarticle} \begin{document}Hello World!\end{document}"
This is e-pTeX, Version 3.14159265-p3.8.2-190908-2.6 (utf8.euc) (TeX Live 2019/Debian) (preloaded format=platex)
restricted \write18 enabled.
entering extended mode
pLaTeX2e <2020-02-02>+2 (based on LaTeX2e <2020-02-02> patch level 2)
L3 programming layer <2020-02-14>
(/usr/share/texlive/texmf-dist/tex/platex/base/jarticle.cls
Document Class: jarticle 2020/01/03 v1.8e Standard pLaTeX class
(/usr/share/texlive/texmf-dist/tex/platex/base/jsize10.clo))
(/usr/share/texlive/texmf-dist/tex/latex/l3backend/l3backend-dvips.def)
No file texput.aux.
[1] (./texput.aux)
Output written on texput.dvi (1 page, 268 bytes).
Transcript written on texput.log.
これを利用することにします。
処理の方法
LaTeX文書内で、引数を2つとる適当なコマンドを用意し、1つ目の引数は問題用紙用、2つ目の引数は解答にします。これを用いてファイルを作成しますが、このコマンドの定義はファイルには書きません。Makefile で書きます。
文書本体のファイルは以下のようにします。
\documentclass{jarticle}
\begin{document}
次の方程式を満たす$x$を求めよ。
\[
x + 3 = 5
\]
\kaito{%
\vspace*{40mm} % 解答を書くためのスペース
}{%
\textbf{解)}
\[
x = 2
\]
}
\end{document}
このコマンドは二重引用符内で定義します。定義してから main.tex
をinputします。Makefileは以下のようになります。make
で二つのファイルができます。(tex → dvi → ps → pdf と作成しています)
all: mondai.pdf kaito.pdf
.PHONY: all
%.pdf: %.ps
ps2pdf $<
mondai.ps: main.tex
platex "\newcommand{\kaito}[2]{#1}\input{main.tex}"
dvips main.dvi -o $@ # このときは出力ファイル名が main.dvi になった
kaito.ps: main.tex
platex "\newcommand{\kaito}[2]{#2}\input{main.tex}"
dvips main.dvi -o $@ # このときは出力ファイル名が main.dvi になった
LaTeXでは出力ファイル名を指定できなさそうなので、dvipsで出力ファイル名を分けました。
まとめ
platex で二重引用符のコードが書けることを利用して、一つのファイルから二種類の文書の作成を Makefile で処理するようにしました。
将来的には一問ずつ区切った問題&解答ファイルから、ランダムで問題を選択して問題&解答ファイルを作りたいです。(項目反応理論を用いて難易度を毎度合わせるなど)