0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【家庭教師】LaTeXで家庭教師用の数学問題集を作ってみた:授業用と復習用を1ソースで管理するマクロとディレクトリ構成

0
Last updated at Posted at 2026-05-05

こんにちは。Nafu0819です。
本記事では、僕が大学の学部生時代にLaTeXで家庭教師用の数学の問題集を作った事例を、実際に作ったマクロなどを交えつつ紹介したいと思います。

環境

不足があれば教えて下さい。

  • OS macOS Tahoe 26.4.1
  • LaTeX LuaLaTeX (on LuaHBTeX)
  • 開発環境 VScode

また、この記事のコードではパッケージとして

  • import
  • standalone
  • etoolbox
  • xparse
  • xstring
  • fancyhdr
  • tcolorbox
  • multicol
  • xcolor

などを前提にしています。コードのサンプルに見出しなど自作マクロが入っていることが多々あり、できる限りコメントをつけていますが、多分漏れています。申し訳ございません。

ページ例

先に、軽くページを見せておきます。本記事では、「これらのページをどう組み合わせて1つのpdfファイルとして出力するか」ということを主眼に置いて紹介し、個々のページのデザインなどは割愛します。枠のデザインなどが気になる方は、本記事下部の「参考」がきっと役に立ちます。

構想

僕は学部時代にアルバイトとして家庭教師をしていたのですが、その指導で使う問題とその解説を中心にまとめるため、この問題集を作ることになりました。掲載した問題は計5章81問です。
授業で配布するプリントの他に復習用のまとめを作りたかったので、各回の.texファイルに直書きせずに賢い設計を考えることになりました。

ドキュメントの種類

  • 各問題には、「問題」「解説」「解答」の3種類のドキュメントがあります。問題によっては「研究」もつきます。これらをまとめて「問題セット」と呼ぶことにします。
  • 問題セットの種類は、基本的な「問題」と応用的な「補充問題」を用意します。
  • 問題セットによっては、ドキュメントに画像を添付する場合があります。

出力

以下の3種類の出力を前提としました。

授業用ファイル lesson?.tex, lesson?.pdf
授業の各回で配布するファイルです。問題のみをまとめたpdflesson_q.pdfと、問題と解説を載せたpdflesson_a.pdfを生成します。また、計算問題のような授業でそこまで扱わない問題に関しては 、問題のみのファイルで問題を灰色にして表示したいです。目次も用意します。
計9回で、1回ごとに10問弱を掲載しました。
章ごとのファイル section?.tex, section?.pdf
問題・解説を章(「極限」「微分」などの、問題の内容的な区切りです)ごとにまとめた、復習用のファイルです。問題のみのpdfは必要ないのですが、先頭に目次を置きたいです。
1章につき16問程度を掲載しました。
全ての問題と解説 all.tex, all.pdf
講義で使用した全問題を載せた、復習用のファイルです。こちらもpdfは1種類のみでいいのですが、「1部:問題編」「2部:解説編」の構成にして、2部のみに目次が欲しいです。また, 各ページに載せた重要事項をまとめた重要事項索引が欲しいです。
texファイルとその出力pdfの内容をまとめると以下のようになります。
lesson?.tex
   ├── lesson?_q.pdf  問題(扱わない問題は灰色)
   └── lesson?_a.pdf  目次+問題セット

section?.tex
   └── section?.pdf   目次+問題セット 

all.tex
   └── all.pdf
          ├──  第1部   問題(扱わなかった問題は灰色)
          ├──  第2部   目次+問題セット
          └──  重要事項索引

設計

ここからは、構想をもとにしてシステムの実際の設計を追っていきます。

実際のファイル構成

鉄緑会蓑田先生の記事を参考に、以下の構成を考えました。

ProjectRoot/
│
├── .latexmkrc       
│
├── common/               <-- 共通設定
│   ├── preamble.tex      (基本的なパッケージ読み込み、スイッチ定義)
│   ├── macros.tex        (ページデザイン、ページ読み込みなどのマクロ)
│   └── SetGreyScope.tex  (灰色に指定する問題の、カンマ区切りのリスト)
│
├── problems/             <-- 問題集データベース(1問題1フォルダ)
│   ├── 01_bibun/
│   │   ├── prob01/
│   │   │   ├── q.tex     (問題)
│   │   │   ├── expl.tex  (解説)
│   │   │   ├── a.tex     (解答)
│   │   │  (├── study.tex (補足などがあれば置く))
│   │   │  (└── fig*.png  (画像がある場合ここに置く))
│   │   │
│   │   ├── supl01/       (補充問題)
│   │   │   └── ...
│   │   └── ...
│   └── ...
│
├── sheets/               <-- 構成ファイル(授業回ごと・用途ごとに作成)
│   ├── lesson?.tex       (授業ごとのファイル)
│   ├── section?.tex      (章ごとのファイル)
│   └── all.tex           (全部)
│
└── build/                <-- 生成ファイルは全部ここへ
    ├── *.pdf             
    ├── *.syntax.gz
    └── *.toq            

問題セットに関するドキュメントを、各章??_*ディレクトリ下の1つのディレクトリprob[0-9]{1,2}(問題)supl[0-9]{1,2}(補充問題) にまとめ、それらを読み込むコマンドをsheet側のtexファイルで管理します。

実際に載せるドキュメントはproblemsフォルダに.texで記述し, sheetsフォルダの.texファイルにそれらのドキュメントを読み込むよう記述します。

この構成にすると, 以下のメリットがあります。

  • 修正が容易
  • 構成ファイル側の設定のみで, ページに載せるコンテンツの管理が可能

記述例

構成を見た上で、ここでは「個々のファイルに対して、実際にどのようなコーディングがなされるのか」を例示します。コードブロックのタイトルにはProjectRootから見たそのファイルのパスを書いています。

問題セット

まず、問題セットのドキュメントなどは以下のようにして書きます。これらは上に紹介した「完成品」の部分の抜粋です。

q.tex

ProjectRoot/problems/05_sekibun_taiseki/supl15/q.tex
\begin{enumerate}
    \item[(ア)] $x\geqq 0, \: x^2 + y^2 \leqq 1, \: 0 \leqq z \leqq y^2$で表される立体の体積$V$を求めよ. \hfill (有名問題)
    \item[(イ)] 半径$1$, 高さ$2$の直円柱を底面の直径を含み, 底面と$\frac{\pi}{4}$の角をなす平面で切断するとき, 平面より下方にある立体の体積$V$を求めよ. \hfill (有名問題)
\end{enumerate}

expl.tex

ProjectRoot/problems/05_sekibun_taiseki/supl15/expl.tex(抜粋)
\documentclass[class=ltjsreport, crop=false, b5paper, 9pt]{standalone}
\input{../../../common/preamble} % 相対パスで共通設定を読み込む
\input{../../../common/macros}

\begin{document}
\begin{multicols*}{2}
\sisin % 見出しマクロです

入試問題では, この問題のように断面をとる平面が与えられていない場合が多い. このような時は, \textbf{断面の取り方}をちゃんと考える必要がある. これが計算の難度や計算量に大きく直結することが多い. 

\begin{keybox}{断面の取り方}[yomi=だんめんのとりかた]
   求積問題で断面を自分で取る必要があるときは, 
   \begin{itemize}
       \item 断面が不等式で表されているときは, \underline{面倒なものを固定}できるように取る.
       \item 立体が与えられているときは, \underline{実際に断面を考えて}みて, 断面積の面積を計算しやすいもので取る. 
   \end{itemize}
   また, 断面をとる平面は\textbf{座標軸に平行}なものを選ぶのが基本.
\end{keybox}

\midasi{(ア)} % 見出しマクロです
どの平面を考えると断面積を計算しやすいだろうか. ここで大事なのは, 立体の平面による断面積は, \textbf{立体を与える不等式と, 断面を表す式を連立したものが, 断面を表す不等式になる}ことである. 例えば, この立体の$z = t$による断面は, 3つの不等式
\[
   x \geqq 0, \quad x^2 + y^2 \leqq 1, \quad t \leqq y^2
\]
を満たす領域となる. この解が存在する$t$の範囲が, 立体が存在する領域. 実際に$xy$平面に図示してみると以下のようになる. 
(後略)
\end{document}

a.tex

ProjectRoot/problems/05_sekibun_taiseki/supl15/a.tex(抜粋)
\midasi{(ア)} % 見出しマクロです
\begin{minipage}[h]{0.6\columnwidth}
    求める立体の$y=t$における断面は, 
    \[x\geqq 0, x^2 + t^2 \leqq 1, 0 \leqq z \leqq t^2\]
    として表される領域である. これを$xz$平面に図示すると右図斜線部.(境界含む)
\end{minipage}
\hfill
\begin{minipage}[h]{0.39\columnwidth}
    \begin{center}
        \scalebox{0.8}{
        \begin{tikzpicture}[scale=2]
            (省略)
        \end{tikzpicture}
        }
    \end{center}  
\end{minipage}

ゆえに, この断面積$S(t)$\[
    S(t) = t^2\sqrt{1-t^2} 
\]
また, $1-t^2 \geqq 0$より, この立体は$-1 \leqq t \leqq 1$の範囲で存在する.

以上より, 求める体積は(後略)

本来これらは単体のビルドを想定していないのでプリアンブルはいらないのですが、expl.texだけは記述が長いので、それ単体でビルドするためにプリアンブルをつけています。

読み込み側

また、読み込む側(構成ファイル)は以下のように書きます。多数のマクロが登場しますが、重要なものは後で解説するので、随時読み飛ばしてください。

授業用ファイル

ProjectRoot/sheets/lesson9.tex(抜粋)
\documentclass[9pt, b5paper]{ltjsarticle}

\input{../common/preamble}
% titletext, 必須ではないがhead左とかtitleに適用される
\def\titletext{第9回 (非回転体の体積、曲線の長さ)}
\TeacherModetrue %スイッチ
\input{../common/macros}
\input{../common/SetGrayScope.tex}

\begin{document}
    \maketitle
    \section{非回転体の体積}
    \LoadProblem{q5-14}{../problems/05_sekibun_taiseki/prob14}
    \LoadProblem{q5-s15}{../problems/05_sekibun_taiseki/supl15}
    %(以下、\Loadproblemが並ぶ。割愛)
\end{document}
  • \Teachermodeは、出力を「問題のみにする+扱わない問題を灰色に」「問題+解答+解説」に切り替えるスイッチです。この切り替えで、1つの.texファイルから2種類の出力を得ることを実現しています。1
  • \LoadProblemは各問題を読み込むマクロです。

章ごとのまとめ

ProjectRoot/sheets/section?.tex(抜粋)
\documentclass[9pt, b5paper]{ltjsarticle}

\input{../common/preamble}
\def\titletext{5章 積分(体積) まとめ}
\TeacherModetrue
\input{../common/macros}
\input{../common/SetGrayScope.tex}

\setcounter{qchapter}{5} %目次のパラメーターを変更

% ヘッダーの編集
\fancyhf{}
\fancyhead[L]{\rightmark}
\fancyhead[C]{5章 積分法(体積) まとめ}
\fancyhead[R]{\thepage}

\begin{document}
    \maketitle
    \tableofq %目次出力用マクロ

    \clearpage
    \qtocsection{$x$軸回転体} % 目次出力用マクロ
    %(中略)
    \qtocsection{非回転体} % 目次出力用マクロ
    \LoadProblem{q5-14}{../problems/05_sekibun_taiseki/prob14}[通過領域の体積]
    \LoadProblem{q5-s15}{../problems/05_sekibun_taiseki/supl15}[断面の選び方]
    %(中略)
\end{document}

目次出力は、LaTeX標準のものを用いれば良かったのですが、別の計画があったのでコマンドを一新しています。2

全ての問題と解説

ProjectRoot/sheets/all.tex
\documentclass[9pt, b5paper, oneside]{ltjsbook}

\input{../common/preamble}
\def\titletext{全問題 解答}
\TeacherModetrue
\Indexmodetrue %さくいんを作成するスイッチ

\input{../common/macros}
\input{../common/SetGrayScope.tex}

\begin{document}
% titlepage
\thispagestyle{empty}
\fancyhf{}
\fancyhead[C]{問題編}
\fancyhead[R]{\thepage}
\null\vfill
\begin{center}
    \Huge 家庭教師用数学問題集
\end{center}
\vfill\null
\chapter*{はじめに}
(省略)

\part{問題編}
    \TeacherModefalse
    \input{q_all.tex} 
    %q_all.texは、\qtocchapter{}や\qtocsection{}を挟みつつ\LoadProblemを並べたファイルです
    \TeacherModetrue
\clearpage
% -------
\thispagestyle{empty}
\fancyhf{}
\fancyhead[L]{\rightmark}
\fancyhead[C]{解答・解説編}
\fancyhead[R]{\thepage}
\part{解答・解説編}
\markright{目次}
\begin{multicols*}{2}
    \tableofq % 目次マクロ
    \tableofsupplements % 「研究」のページのみの目次
\end{multicols*}
\clearpage
\input{q_all.tex}
\clearpage
% ------
\qtocchapter*{さくいん}% 目次出力用マクロ
\markright{さくいん}
\printkeyindex %重要事項さくいんの出力
\end{document}

全ての問題を\LoadPloblemで読み込むq_all.texを、スイッチ\Teachermodeを切り替えて2回読み込むことで、1つのpdfファイルに「問題のみ+灰色」「問題セット全て」の2種類を表示することを実現しています。

マクロ解説

ここからは、以上の設計を実現するために組んだマクロの勘所を解説していきます。

読み込みマクロ

このシステムの核となるのが, macros.texで定義したファイル読み込みのマクロです。\LoadProblem{問題ラベル}{問題セットのディレクトリまでの相対パス}[サブタイトル]のように使います。

\LoadProblem
\NewDocumentCommand{\LoadProblem}{m m o}{%
% \newcommand{\LoadProblem}[3][]{%
    % パスを解析
    \AnalyzePath{#2}%
    
    % 表示ラベルの作成
    \ifx\TypeLabel\empty
        \def\NumberLabel{\ChapNum.\ProbNum}%
    \else
        \def\NumberLabel{\TypeLabel~\ChapNum.\ProbNum}%
    \fi
    
    % --- タイトルの有無判定 ---
    \ReadTitleContent{#2}

    % --- 本質 ---
    \ifTeacherMode
        % 枠はすべて黒
        \def\TextColor{black}%
        % --- 問題ボックス描画 ---
        \IfValueTF{#3}{%
            \begin{qbox}[#3]{\NumberLabel}[4][colupper=\TextColor, coltitle=\TextColor]
                \subimport{#2}{q.tex}
            \end{qbox}
        }{
            \begin{qbox}{\NumberLabel}[4][colupper=\TextColor, coltitle=\TextColor]
                \subimport{#2}{q.tex}
            \end{qbox}
        }
        % 問題目次を追加
        \IfValueTF{#3}{%
            \qtoclabel{\NumberLabel \quad(#3)}
        }{%
            \qtoclabel{\NumberLabel}
        }%
        
        \markright{\NumberLabel}
        % expl:解説
        \IfFileExists{#2/expl.tex}{%
            \subimport{#2}{expl.tex}
        }{}%
        \IfFileExists{#2/a.tex}{%
            \Ansgeometry % 解答ページ用に別で定義したページスタイルです
            \kaitou
            \subimport{#2}{a.tex}
            \restoregeometry
        }{}%
        %study:研究
        \IfFileExists{#2/study.tex}{%
            \subimport{#2}{study.tex}
        \clearpage
        }{}%
    \else
                % --- 色の判定 ---
        \xifinlist{#1}{\GrayList}{%
            \def\TextColor{gray!60}%
        }{%
            \def\TextColor{black}%
        }%

            % --- 問題ボックス描画 ---
        \ifx\SubTitleText\relax
            \begin{qbox}{\NumberLabel}[4][colupper=\TextColor, coltitle=\TextColor]
                \subimport{#2}{q.tex}
            \end{qbox}
        \else
            \begin{qbox}[\SubTitleText]{\NumberLabel}[4][colupper=\TextColor, coltitle=\TextColor]
                \subimport{#2}{q.tex}
            \end{qbox}
        \fi
    \fi
    \setcounter{equation}{0}
}

長いので、順々に分けて解説していきます。

パスの解析

まず、\AnalyzePath{}というマクロで、第2引数の相対パスを解析します。

\AnalyzePath
\newcommand{\AnalyzePath}[1]{%
    % --- 初期値(エラー回避のため0にしておく) ---
    \def\ChapNum{0}%
    \def\ProbNum{0}%
    \def\TypeLabel{Error}%

    % --- A. "problems/" より後ろを切り出す ---
    \StrBehind{#1}{problems/}[\TempPathBody]%

    % --- B. 章番号の取得 ---
    % 切り出した部分の先頭から "_" までを取得
    \StrBefore{\TempPathBody}{_}[\TempChapString]%
    \ifdefempty{\TempChapString}{}{%
        \def\ChapNum{\the\numexpr\TempChapString\relax}%
    }%

    % --- C. フォルダ種類の判定と番号抽出 ---
    % 切り出した TempPathBody の中だけで検索します
    
    % === 設定1: "prob" (通常問題) ===
    \IfSubStr{\TempPathBody}{/prob}{%
        \def\TypeLabel{問題}% 
        \StrBehind{\TempPathBody}{/prob}[\TempStringB]% "8/" または "8" が入る
        % 末尾にスラッシュがあるか確認して分岐
        \IfSubStr{\TempStringB}{/}{%
             \StrBefore{\TempStringB}{/}[\TempProbString]%
        }{%
             \let\TempProbString\TempStringB%
        }%
        % 空でなければ数値化
        \ifdefempty{\TempProbString}{}{%
            \def\ProbNum{\the\numexpr\TempProbString\relax}%
        }%
    }{}%

    % === 設定2: "supl" (補充問題) ===
    \IfSubStr{\TempPathBody}{/supl}{%
        \def\TypeLabel{補充問題}%
        \StrBehind{\TempPathBody}{/supl}[\TempStringB]%
        \IfSubStr{\TempStringB}{/}{%
             \StrBefore{\TempStringB}{/}[\TempProbString]%
        }{%
             \let\TempProbString\TempStringB%
        }%
        \ifdefempty{\TempProbString}{}{%
            \def\ProbNum{\the\numexpr\TempProbString\relax}%
        }%
    }{}%
}

これを用いて、対象の問題セットの

  • 問題なのか、補充問題なのか
  • 章番号
  • 問題番号

を取得します。ここから、問題のボックスの左上にある「問題?.?」というラベルを作成します。

問題ボックスのタイトルの作成

マクロ\ReadTitleContentを用いて、タイトルを読み込みます。

\ReadTitleContent
\makeatletter
  \newcommand{\ReadTitleContent}[1]{%
      \directlua{
          local path = "#1/title.tex"
          local f = io.open(path, "r")
          if f then
              local content = f:read("*a")
              f:close()
              content = content:gsub("\string\n", " ")
              tex.print([[\string\def\string\SubTitleText{]] .. content .. [[}]])
          else
              tex.print([[\string\let\string\SubTitleText\string\relax]])
          end
      }%
  }
\makeatother

問題セットのドキュメント読み込み

ここからがこの記事の本質です。読み込み側にTeachermodeなるスイッチ(デフォルトはFalse)を用意して、問題を読み込む際に

  • 問題のほかに解答・解説も(・あれば研究も)表示する(True)
  • 問題のみ読み込み、一部の問題を灰色にする(False)

を選択します。

まずはTrueの場合から見ていきます。

\LoadProblem(抜粋)
  \ifTeacherMode
      % 枠はすべて黒
      \def\TextColor{black}%
      % --- 問題ボックス描画 ---
      \IfValueTF{#3}{%
          \begin{qbox}[#3]{\NumberLabel}[4][colupper=\TextColor, coltitle=\TextColor]
              \subimport{#2}{q.tex}
          \end{qbox}
      }{
          \begin{qbox}{\NumberLabel}[4][colupper=\TextColor, coltitle=\TextColor]
              \subimport{#2}{q.tex}
          \end{qbox}
      }
      % 問題目次を追加
      \IfValueTF{#3}{%
          \qtoclabel{\NumberLabel \quad(#3)}
      }{%
          \qtoclabel{\NumberLabel}
      }%
      
      % ヘッダーに問題ラベルを書き込み
      \markright{\NumberLabel}
      % expl:解説
      \IfFileExists{#2/expl.tex}{%
          \subimport{#2}{expl.tex}
      }{}%
      \IfFileExists{#2/a.tex}{%
          \Ansgeometry %解答用のページレイアウト
          \kaitou % ページ上部の「解答」の見出し
          \subimport{#2}{a.tex}
          \restoregeometry
      }{}%
      %study:研究
      \IfFileExists{#2/study.tex}{%
          \subimport{#2}{study.tex}
      \clearpage
      }{}%

qbox環境は, tcolorboxで定義した問題ボックスです。「完成品」の画像のところの「補充問題5.15」「断面の選び方」などは、\begin{qbox}[#3]{\NumberLabel}[4]のところの引数により入力されます。その後、「解説の読み込み」「(a.texがあれば)解答の読み込み」と続いていきます。

  • 画像ファイルなど「読み込む対象のドキュメントに相対パスがある場合」があるので、ファイルの読み込みに\subimportを利用しています
  • 計算問題など、「解説が極端に短くなるのでexpl.texに解答ごと載せたい」「複数の問題に対して一度に解説を書きたい」といったことがあるので、\IfFileExistsを挟んでいます

\qtoclabelについては後述します。目次を生成するためのマクロです。

次に、Falseの場合も見てみましょう。

\Loadproblem(抜粋)
  \else
      % --- 色の判定 ---
      \xifinlist{#1}{\GrayList}{%
          \def\TextColor{gray!60}%
      }{%
          \def\TextColor{black}%
      }%

      % --- 問題ボックス描画 ---
      \ifx\SubTitleText\relax
          \begin{qbox}{\NumberLabel}[4][colupper=\TextColor, coltitle=\TextColor]
              \subimport{#2}{q.tex}
          \end{qbox}
      \else
          \begin{qbox}[\SubTitleText]{\NumberLabel}[4][colupper=\TextColor, coltitle=\TextColor]
              \subimport{#2}{q.tex}
          \end{qbox}
      \fi
  \fi

Trueの場合とは違い、問題のみを描画しています。違いは、\GreyListによって問題を灰色で表示するかどうか判定しているところです。

\newcommand{\GrayList}{} 
\newcommand{\SetGrayScope}[1]{%
  \renewcommand{\GrayList}{}%
  \forcsvlist{\listadd\GrayList}{#1}%
}

これにより、読み込む側の.texファイル冒頭で、common.texの読み込みより下部に\input{../common/SetGrayScope.tex}と書けば、SetGrayScopeに書かれた問題が灰色に表示される、という仕組みです。3

また、SetGreyScope.texは以下のようになっています。

ProjectRoot/common/SetGreyScope.tex
\SetGrayScope{q1-1, q1-2, q1-3, q1-4, q1-5, q1-10, q2-1, q2-2, q2-5, q2-8, q3-1, q3-2, q3-3, q3-4, q3-5, q3-6, q3-7, q3-8, q3-12, q3-14, q3-15, q3-16, q3-20, q4-1, q4-5, q5-1, q5-2, q5-3}

\LoadProblemに入力したタグが\SetGreyScopeの引数のうちどれかと完全一致すれば、その問題が灰色で表示されます。
スクリーンショット 2026-05-06 2.45.05.png

目次

あとは軽めに書いていきます。あまり特別なことはしていません。強いて言えば、問題の見出しと研究の見出し(コラム見出し)は別で出力するようにしています。

\makeatletter

%  1. カウンタの定義
\newcounter{qchapter}               % 章のカウンタ (n)
\newcounter{qsection}[qchapter]     % セクションのカウンタ (m) 章が変わるとリセット

%  2. 目次出力コマンド \tableofq
\newcommand{\tableofq}{%
    \section*{問題一覧}
    \@starttoc{toq}%
}

%   3. 大見出しのデザイン
%  コマンド: カウンタを進めて "n章 タイトル" の形式で目次に追加
\NewDocumentCommand{\qtocchapter}{ s m }{%
    \ifTeacherMode
    \IfBooleanTF{#1}{%
        % --- ★ 星付き (*) の場合 ---
        % カウンタを進めず、番号なしで目次に追加
        \addcontentsline{toq}{qchapter}{#2}%
    }{%
        % --- 通常の場合 ---
        % カウンタを進めて、番号付きで目次に追加
        \refstepcounter{qchapter}%
        \addcontentsline{toq}{qchapter}{\theqchapter 章~~#2}%
    }%
    \else\fi
}

%  デザイン: \l@qchapter
%  特大・太字・余白大
\newcommand{\l@qchapter}[2]{%
    \addvspace{2.5em plus 1pt}%
    \begingroup
        \parindent \z@ \rightskip \@pnumwidth
        \parfillskip -\@pnumwidth
        \leavevmode
        \Large\bfseries 
        #1\nobreak\hfil \nobreak\hb@xt@\@pnumwidth{\hss #2}\par
    \endgroup
}
%   4. 中見出しのデザイン
%   コマンド: カウンタを進めて "n.m タイトル" の形式で目次に追加
\newcommand{\qtocsection}[1]{%
    \ifTeacherMode
    \refstepcounter{qsection}%
    \addcontentsline{toq}{qsection}{\theqchapter.\theqsection~~#1}%
    \else\fi
}

%   デザイン: \l@qsection
%   大・太字・余白中
\newcommand{\l@qsection}[2]{%
    \addvspace{1.5em plus 1pt}%
    \begingroup
        \parindent \z@ \rightskip \@pnumwidth
        \parfillskip -\@pnumwidth
        \leavevmode
        \large\bfseries 
        #1\nobreak\hfil \nobreak\hb@xt@\@pnumwidth{\hss #2}\par
    \endgroup
}

%  5. 小見出し (問題) の設定

% デザイン: \l@problem
% 通常サイズ・インデントあり
\newcommand{\l@problem}[2]{%
    \@dottedtocline{1}{1.5em}{10em}{#1}{#2}%
}

% コマンド: \qtoclabel
% 問題番号のみ、または問題番号+タイトルを目次に追加
\newcommand{\qtoclabel}[1]{%
\ifTeacherMode
    \ifx\SubTitleText\relax
        \addcontentsline{toq}{problem}{\protect\numberline{#1}}%
    \else
        \addcontentsline{toq}{problem}{\protect\numberline{#1}\SubTitleText}%
    \fi
\else\fi
}
% =========================================================
%  補足記事(コラム)用の独立した目次
% 1. 目次出力コマンド \tableofsupplements
%    .tos (Table of Supplements) ファイルを使用します
\newcommand{\tableofsupplements}{%
    \section*{コラム}
    \@starttoc{tos}%
}

% 2. リストのデザイン定義 \l@supplement
%    \@dottedtocline{レベル}{インデント}{ラベル幅}{タイトル}{ページ}
%    インデント0、タイトル幅を広めにとっています
\newcommand{\l@supplement}[2]{%
    \@dottedtocline{1}{1.5em}{10em}{#1}{#2}%
}

% 3. 目次に追加するコマンド \supltoclabel
%    使い方: \supltoclabel{記事のタイトル}
%    例: \supltoclabel{コラム:微分の歴史}
\newcommand{\supltoclabel}[1]{%
    \addcontentsline{tos}{supplement}{#1}%
}

\makeatother

\qtoclabelは先述したように\LoadProblemに仕込んであります。あとは、\qtocchapter\qtocsectionを読み込み側の出したい位置に書いておくと、このような目次が得られます。

all_目次1.png
all_目次2.png

さくいん

これも特別なことはしていません。common.texに以下を書いて、重要事項を書くボックスの中に仕込んでupmendexを叩くだけです。

\ifIndexmode
        % --------------------------------------------------
        % 1. 索引作成の設定 (imakeidx)
        \usepackage[noautomatic]{imakeidx}
        % \makeindex[title=索引]
        \makeindex[name=key, title=さくいん]

        % --------------------------------------------------
        % 2. 索引のデザイン定義 (footbook.ist 対応)
        \usepackage{needspace} % 見出しの分離防止

        \makeatletter
        % ltjsarticle の theindex 環境を再定義(multicols*で囲い直すため)
            \renewenvironment{theindex}{%
                % 1. まずページ設定をリセット
                \if@twocolumn\onecolumn\fi
                \clearpage
                
                % 2. タイトルを表示
                \section*{\indexname}%

                % 3. ここで multicols* を開始
                \begin{multicols*}{2}
                    % 4. multicols の中で設定を行う(重要!)
                    %    multicolsは開始時に \item をリセットするため、
                    %    必ずこの内側で \item を索引仕様に上書きします。
                    \parindent\z@
                    \parskip\z@ \relax
                    \let\item\@idxitem
                    \normalsize % 文字サイズ
            }{%
                % 環境終了時に multicols も閉じる
                \end{multicols*}
            }
        % リーダー(点線)
        \newcommand\idxdelim{\nobreak{\reset@font\scriptsize\space
        \leaders\hbox to .3333\zw{\hss\hbox{.}\hss}\hfill\space}\nobreak}

        % 記号見出し名
        \newcommand*{\symbolindexname}{記号・数字}

        % インデント調整
        \renewcommand{\@idxitem}{\par\leavevmode\hangindent1\zw\inhibitglue}
        \renewcommand{\subitem}{\@idxitem\hangindent2\zw\hspace*{1\zw}\inhibitglue}
        \renewcommand{\subsubitem}{\@idxitem\hangindent3\zw\hspace*{2\zw}\inhibitglue}
        \renewcommand{\indexspace}{\par\vskip\baselineskip\relax}
        \makeatother

    % -----------------------------------------------
    % 3. 出力用コマンド
    \newcommand{\printmainindex}{\printindex}
    \newcommand{\printkeyindex}{\printindex[key]}

\else
    % === OFF の場合 ===
    \usepackage{imakeidx} 
    \renewcommand{\index}[2][]{}
    \newcommand{\printmainindex}{}
    \newcommand{\printkeyindex}{}
\fi

以下のような出力になります。
all_さくいん.png

おわりに

意外とこのような作例を紹介している記事が無かったので、就活の一環として書いてみました。この記事があなたの問題集作成ライフに少しでも貢献できたならば幸いです。

自分の文章を世に出すのは久しぶりですし、自分が書いたコードを世に出すのは初めての試みなので緊張しています。こんな拙い文書と酷く絡まったスパゲティコードを最後まで読んでいただきありがとうございました。

あまりやる気はないのですが、もし時間が有り余って仕方なくなったら実際に用いたコードをGitHubにアップロードするかもしれません。もし手伝っていただける方がいましたら教えてください。

Special thanks to Gemini 3.1 Pro Preview

参考

鉄緑会蓑田先生の記事です。ファイル構成などはかなりこの記事をパクってからインスピレーションを得ています。

参考書に使いやすいtcolorboxの作例がごまんと載っています。無人島に1つだけ何かを持っていけるとしたら僕はこれを選ぶかもしれないくらい便利です。本当に誰にも教えたくない

  1. 手動でスイッチを切り替えてビルドし直すことを想定しています。ビルドは2回必要です。ファイル名もlatex側から操作する術はない(はず)ので、手動で_q_aをつけることを想定しています。
    どちらも詳細は以下の「読み込みマクロ」で解説します。

  2. セクション見出しなどを別の用途に使うかもしれないと考えていたのですが、そうでもありませんでした。今考えると、標準のものを編集した方が楽だった気がします。反省ポイントです。

  3. (もしかしたらcommon.tex\SetGrayScopeより下部でSetGrayScope.texを読み込むだけでもうまくいくかもしれません。未検証)

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?