TeXで共通テスト数学の解答用紙を再現
この記事で作るものは、非公式の学習用テンプレートです。実際の試験で使用される解答用紙ではありません。ロゴや団体名は含めず、科目名なども再現用のダミーとして扱っています。
ソースコード:この記事で作成したファイルは、GitHubの TeXソース全文 と コンパイル済みPDF から確認できます。
LaTeXでマークシートを作ろうとすると、最初に思いつくのはTikZで楕円を大量に描く方法です。しかし、楕円の大きさ、文字のベースライン、選択肢間隔をすべて自前で管理すると、コードの大半が座標調整になってしまいます。
今回は、解答欄を組むためのLaTeXパッケージ KKran が備えるマークシート機能を使い、共通テスト数学の解答用紙に近い紙面を作りました。TikZは用紙上の絶対配置と、矢印・網掛けなど KKran にない装飾だけに限定しています。
完成結果がこちらです。
環境
- TeX Live 2026
- LuaLaTeX
ltjsarticle-
KKran1.2.0 -
KKsymbols2.3.0 - TikZ
日本語を含むため、コンパイルにはLuaLaTeXを使います。
lualatex -interaction=nonstopmode -halt-on-error \
qiita-common-test-math-answersheet.tex
完成ソースコード
この記事で使用したファイルは、KKTeX/Publicated-Files で公開しています。
コード片だけでなく、用紙寸法、30行分の解答欄、受験番号欄、氏名欄、科目欄、紙面配置を含む自己完結したソースを確認できます。
方針:マーク楕円を自作しない
今回の中心になるのは、KKran の次の2コマンドです。
\MarkArrayMake{配列名}{|要素1|要素2|...|要素n|}
\マークシート{配置幅}{配列格納}[正解番号]
\MarkArrayMake で選択肢の配列を登録し、\マークシート で横一列に配置します。第3引数の正解番号を省略すれば、すべて白いマークとして出力されます。
今回の解答欄は、次の15要素です。
\MarkArrayMake{解答}{|-|0|1|2|3|4|5|6|7|8|9|a|b|c|d|}
\newcommand{\CTanswerMarks}{%
{\color{ctmark}\CTfMark
\マークシート{\CTsheetW}{\解答マーク配列}}}
マークの楕円は、KKran が内部で利用する KKsymbols の記号によって出力されます。したがって、TikZで15個の楕円を描く処理はありません。
unit=1mm で寸法を直接扱う
紙面との照合ではミリ単位で調整したいため、KKran の unit を 1mm にしました。
\usepackage[
unit=1mm,
kaitouhyouji=1,
tensenoff=0pt,
wakuwidth=0.3pt,
tensenwakuwidth=0.3pt
]{KKran}
これで、たとえば \小問欄{67.5}{5.05} を「幅67.5 mm、高さ5.05 mm」の欄として扱えます。tensenoff=0pt は、左辺の点線パターンを実線として見せるための設定です。
寸法はソース冒頭へ集約しました。
\newcommand{\CTlabW}{4.35}
\newcommand{\CTmarkW}{67.5}
\newcommand{\CTsheetW}{65.5}
\newcommand{\CTrowH}{5.05}
後から画像と照合するときは、このパラメータ群だけを変更します。
解答欄1行を KKran で作る
1行は、行ラベルの \小問番号 と、マークを置く \小問欄 の組み合わせです。行末で \GoDown を呼び、次の行へ移動します。
\newcommand{\CTanswerRow}[1]{%
\小問番号[\CTlabW]{\CTrowH}
[{\CTfSmall\color{ctink}#1}]%
\小問欄{\CTmarkW}{\CTrowH}
[center={\CTanswerMarks}]%
\GoDown{\CTrowH}%
}
30行分のラベルをマクロへまとめ、3本の解答欄で使い回します。
\newcommand{\CTanswerRows}{%
\CTanswerRow{ア}\CTanswerRow{イ}\CTanswerRow{ウ}\CTanswerRow{エ}%
\CTanswerRow{オ}\CTanswerRow{カ}\CTanswerRow{キ}\CTanswerRow{ク}%
% 中略
\CTanswerRow{ヘ}\CTanswerRow{ホ}%
}
\newcommand{\CTanswerBody}{%
\KKran[\CTkkOuter]{%
\大問番号[0]{\CTblkBodyH}[]%
\CTanswerRows
}%
}
ここで \大問番号 の幅を0にしているのは、紙面上の大問番号セルを別部品として左へ張り出させるためです。マーク欄本体の罫線は KKran に任せ、大問番号の小さな独立枠だけをTikZで配置しています。
見出しとマークの中心を合わせる
マーク1個の送りは、現在の和文フォントの全角幅 \zw を基準に決まります。そこで、見出し側も同じフォントサイズで 1\zw の箱を作り、箱同士を \hfill で均等配置します。
\newcommand{\CTch}[1]{%
\makebox[1\zw]{\CTfChoice\color{ctink}#1}}
\newcommand{\CTchoiceHead}{%
{\CTfMark
\makebox[\CTsheetW mm]{%
\CTch{-}\hfill\CTch{0}\hfill\CTch{1}\hfill\CTch{2}%
% 中略
\hfill\CTch{c}\hfill\CTch{d}}}%
}
楕円と見出しを別々の座標列で管理するより、フォントの送りとglueを共有した方がずれにくくなります。
受験番号欄は「1要素のマークシート」を縦に積む
\マークシート は横一列の配置を想定した機能です。一方、受験番号欄は数字を縦に並べる必要があります。
そこで、1要素だけを持つ配列を数字ごとに登録しました。
\MarkArrayMake{単-}{|-|}
\MarkArrayMake{単0}{|0|}
\MarkArrayMake{単1}{|1|}
% 2〜9、英字も同様
\newcommand{\CTexMarkOne}[1]{%
{\color{ctmark}\CTfExMark
\マークシート{\CTexSheetW}
{\csname 単#1マーク配列\endcsname}}}
1セルごとに単要素の \マークシート を置き、それを \GoDown で縦に積みます。これなら受験番号欄でも、楕円自体は最後まで KKran の正式機能で描けます。
解答科目欄ではアンカーポイントを使う
\小問欄 のオプションでは、center、north west、south west などを指定できます。科目名は north west、下端の大きな丸は south west に置きました。
縦書き風の科目名は、固定の行間を並べるのではなく、高さを持つ parbox の中へ \vfill を入れています。2列の科目名の間には \hfill を使います。
\newcommand{\CTsubjectVGlue}{\par\vfill}
\newcommand{\CTsubjectStack}[1]{%
\parbox[t][18mm][s]{3.8mm}{%
\centering\vspace*{2.5mm}%
\CTfSubject\color{ctink}#1\par}%
}
\newcommand{\CTsubjectTopPair}[2]{%
\makebox[\CTsbColW mm][c]{%
\makebox[9mm][s]{%
\CTsubjectStack{#1}\hfill\CTsubjectStack{#2}}}%
}
たとえば「情報関係」は次のように渡します。
\CTsubjectTopPair
{基\CTsubjectVGlue 礎}
{情\CTsubjectVGlue 報\CTsubjectVGlue
関\CTsubjectVGlue 係}
旧課程列の網掛けだけは KKran の欄内アンカーだけでは全面を塗れないため、セルと同寸のTikZノードを使いました。背景だけを表の裏へ置くと KKran の白いセル箱に隠れるので、セル内で塗り、その前面へ罫線を描き直しています。
組み上げたブロックを用紙座標へ置く
解答欄、受験番号欄、氏名欄、解答科目欄は、それぞれ独立した \KKran ブロックとして作ります。最後に、A4横のTikZキャンバスへ絶対座標で配置します。
\begin{tikzpicture}[
overlay,
x=1mm,
y=1mm,
inner sep=0pt,
outer sep=0pt
]
\KKran が返す箱には描画領域の周囲に余白があるため、anchor=north west で置くと罫線が指定座標からずれます。今回は描画領域の中心を計算し、箱も anchor=center で配置しました。
\newcommand{\CTplace}[5]{%
\node[anchor=center, inner sep=0pt]
at ({#1+0.5*#3},{#2-0.5*#4}) {#5};%
}
\CTplace{\CTblkAX}{\CTgridTop}
{\CTblkW}{\CTblkHeadH}{\CTanswerHeader}
\CTplace{\CTblkAX}{\fpeval{\CTgridTop-\CTblkHeadH}}
{\CTblkW}{\CTblkBodyH}{\CTanswerBody}
3本の解答欄は、同じブロックをX座標だけ変えて配置しています。紙面全体を一枚の巨大なTikZ表として描くより、KKran の部品構造と、TikZの紙面座標を分けた方が調整しやすくなりました。
TikZに残した処理
TikZで直接描いたのは、主に次の部分です。
- 用紙の外枠と左端のタイミングマーク
- ブロック同士を結ぶ矢印
- 大問番号の独立枠
- 旧課程列の網掛け
- 記入確認欄のチェック線
- 各
KKranブロックの紙面上の配置
反対に、マーク楕円、30行の罫線、受験番号欄、氏名欄、解答科目欄の構造は KKran で作っています。
関連サービス
Evolton:入試数学の問題を解答PDFにする
Evolton は、大学入試数学の問題写真やスクリーンショットから、AIが解答を作成し、参考書のようなPDFへ清書するサービスです。
過去問データベースには13大学・4,313問が収録されており、大学・分野・難易度を指定してオーダーメイド問題集を組むこともできます。問題を解くところから、読みやすいPDFへ整えるところまでまとめて進めたい場合に便利です。
texmcp:AIと対話して日本語TeX文書を作る
日本語の学習参考書やレポートをAIと対話しながら作りたい場合は、オープンソースのリモートMCP texmcp も利用できます。
texmcp は利用者の文書をサーバーへ保存せず、スタイル一式、文書の骨組み、編集規則、既知の問題、コンパイル手順をAIへ返します。実際のTeXファイルの保存とLuaLaTeXによる組版は、利用者側のAIがローカルで行います。
Codexでは、次のコマンドで公開エンドポイントを登録できます。
codex mcp add tex64 --url https://mcp.tex64.com
設定ファイルへ直接追加する場合は次のとおりです。
[mcp_servers.tex64]
url = "https://mcp.tex64.com"
テンプレートを一から探す作業を減らし、日本語組版の構造設計からコンパイルまでAIと進めたい場合に使えます。
まとめ
KKran は記述式の解答欄だけでなく、\MarkArrayMake と \マークシート を使ってマーク式の解答用紙も構成できます。
今回の再現で重要だったのは、次の3点です。
- マーク楕円を自作せず、
KKranのマークシート機能へ任せる - 行や表の構造を
\KKran、\小問番号、\小問欄、\GoDownで組む - 完成したブロックの紙面座標だけをTikZで調整する
この分担にすると、見た目を詰めながらも、解答欄の意味構造を KKran 側へ残せます。
著者: KKTeX
