クラスのオプションと自作

既製のクラスで足りなくなったら、自分でクラスを書けます。このページは クラスを作る側 の話です。まずクラスがふつう受け取る標準オプション(文字サイズ・用紙・段組など)を押さえ、次に .cls.sty ファイルの中身——\ProvidesClass で名乗り、\DeclareOption でオプションを宣言し、\ProcessOptions で実行し、\LoadClass で既存クラスを土台にする——という骨格を、article を拡張する完成例まで一通り組み立てます。オプションを文書側で 使う 話は「ドキュメントクラスとプリアンブル」を参照してください。

クラスか、パッケージか

作り始める前に、クラス(.clsパッケージ(.sty のどちらを書くのかを決めます。クラスは文書の種類そのものを定義するもので、\documentclass一つだけ 読み込みます。論文・書籍・スライドといった全体の骨格や既定の体裁を与えるのがクラスです。一方パッケージは \usepackageいくつでも 重ねて読み込み、文書の種類によらず機能を足します(数式の amsmath、図の graphicx など)。

公式の手引き clsguide の言い方を借りれば、判断基準はこうです——「その機能がどんな文書クラスでも使えるならパッケージにし、そうでなければクラスにする」。体裁を丸ごと定義したいならクラス、機能だけ足したいならパッケージ、と覚えておけば迷いません。書く中身の作法はほとんど共通で、命令の名前が Class 用と Package 用に分かれているだけです(\ProvidesClass\ProvidesPackage\LoadClass\RequirePackage\PassOptionsToClass\PassOptionsToPackage)。

自作クラスが受け取る標準オプション

利用者は自作クラスにも、標準クラスと同じ感覚でオプションを渡してきます。最低限そろえておきたいのは次の顔ぶれです。本文の基準サイズを選ぶ 10pt / 11pt / 12pt、用紙の a4paper / letterpaper、段組の onecolumn / twocolumn、面付けの oneside / twoside、そして下書き表示の draft(行あふれを黒い印で示す。対は final)。これらをいちいち自前で実装する必要はありません——下の「土台クラスに丸投げする」で見るように、article などの土台クラスへ そのまま受け渡す のが定石です。

オプション意味既定
10pt / 11pt / 12pt本文の基準文字サイズ10pt
a4paper / letterpaper用紙サイズ(b5paper legalpaper 等も)letterpaper
onecolumn / twocolumn1 段組/2 段組onecolumn
oneside / twoside片面/両面のレイアウトonesidebook のみ twoside
draft / finalあふれた行を黒い印で表示するかfinal

これらのオプションを文書の \documentclass[...] 側で 指定して使う 具体例や、book 特有の openright などは、姉妹ページ「ドキュメントクラスとプリアンブル」で扱っています。ここから先は、それらを 受け取る側のクラスをどう書くか に集中します。

ファイルの先頭で名乗る

クラスファイル(myclass.cls)の最初の二行は、ほぼ定型です。まず \NeedsTeXFormat{LaTeX2e} で、このファイルが LaTeX2e 用であることを宣言します(古いフォーマットで読み込もうとすると警告が出ます)。続いて \ProvidesClass{myclass}[2026/01/01 v1.0 ...] で、クラス名・リリース日・バージョン・説明を名乗ります。角括弧の中は省略できますが、書いておくと 日付(YYYY/MM/DD 形式) をもとに利用者が \documentclass{...}[2026/01/01] のように最低バージョンを要求でき、ログにも記録されます。

パッケージを書くなら、対応する命令は \ProvidesPackage{mypackage}[2026/01/01 v1.0 ...] です。\NeedsTeXFormat は両者で共通。なお \ProvidesClass / \ProvidesPackage名前は実際のファイル名と一致させる のが鉄則で、myclass.cls の中では必ず \ProvidesClass{myclass} と書きます。

latex
\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{myclass}[2026/01/01 v1.0 My example class]

オプションを宣言する — \DeclareOption

クラスが受け取れるオプションは、\DeclareOption{オプション名}{コード} で一つずつ宣言します。利用者がそのオプションを指定すると、後述の \ProcessOptions の時点で コード が実行されます。たとえば自前のスイッチ draft を用意して、真偽フラグを立てるといった具合です。

宣言していないオプションが渡されたときの受け皿が、星付きの \DeclareOption*{コード}(catch-all)です。この中では \CurrentOption が「いま処理しようとしているオプション名」に展開されます。自作クラスで最もよく使うのが、未知のオプションを土台クラスへ そのまま転送する 次の一文です。これがあるおかげで、10pta4paper のような標準オプションを自分で宣言しなくても、利用者は当たり前のように渡せます。

latex
% pass anything we do not handle ourselves on to article
\DeclareOption*{\PassOptionsToClass{\CurrentOption}{article}}

パッケージを書く場合は、同じ役割の \PassOptionsToPackage{\CurrentOption}{base} を使います。なお \ProcessOptions の前に既定値を流し込みたいときは \ExecuteOptions{a4paper,11pt} のように書くと、利用者が何も指定しなくてもそのオプションのコードが先に実行されます。

オプションを実行し、土台クラスに丸投げする

宣言だけでは何も起きません。\ProcessOptions を呼んで初めて、各オプションのコードが実行されます。実務ではほぼ常に \ProcessOptions\relax と書きます。これは星付きの \ProcessOptions* という別形が存在するため、末尾の \relax で「星なしのほう」を確実に選ぶための定石です。星なしの \ProcessOptions宣言した順 にオプションを処理し、星付きは 呼び出し側で指定された順 に処理します。

ゼロからレイアウトを組むのは大変なので、ほとんどの自作クラスは既存クラスを土台にします。それが \LoadClass[オプション]{article} で、article.cls の命令・体裁を丸ごと読み込みます(角括弧で twocolumn などを渡すことも可能)。\LoadClass はクラスファイルの中でだけ 使える命令です。重要なのは順序——利用者が \documentclass[...] で渡したオプションを土台クラスへ効かせるため、\LoadClass はオプション処理(\ProcessOptions)の後に置きます。先に転送設定をしておき、\ProcessOptions で振り分け、そのうえで土台を読み込む、という流れです。

土台クラスへ「自分が受け取ったのと同じオプションを、そっくり渡したい」だけなら、\LoadClassWithOptions{article} が便利です(クラスのグローバルオプションをそのまま引き継ぎます)。パッケージを書くときは \LoadClass の代わりに \RequirePackage(プリアンブルの \usepackage に相当)、そっくり渡すなら \RequirePackageWithOptions を使います。

\LoadClass の後ろが、いよいよ このクラスらしさ を書く場所です。\renewcommand で見出しの体裁を変えたり、\setlength で余白を調整したり、新しい命令や環境を \newcommand / \newenvironment で定義したり——必要な追加パッケージは \RequirePackage でここから読み込みます。

完成例:article を拡張する最小クラス

以上を一つにまとめると、次のような最小の .cls になります。article を土台に、独自の draft オプションを足し、未知のオプションは article へ転送し、最後に余白を整えて自前の命令を一つ定義しています。これを myclass.cls として保存し、文書側で \documentclass[11pt,a4paper]{myclass} と書けば使えます。

latex
\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{myclass}[2026/01/01 v1.0 My example class]

% --- declare options ---
\newif\ifmy@draft
\DeclareOption{draft}{\my@drafttrue}
% forward everything else to article
\DeclareOption*{\PassOptionsToClass{\CurrentOption}{article}}

% --- execute and load the base class ---
\ExecuteOptions{a4paper}      % a default if the user gives none
\ProcessOptions\relax
\LoadClass{article}

% --- this class's own setup ---
\RequirePackage[margin=25mm]{geometry}
\setlength{\parindent}{0pt}
\newcommand{\version}{v1.0}
\ifmy@draft \RequirePackage{draftwatermark}\fi

\endinput

末尾の \endinput は、ここから先を読み込まないことを LaTeX に伝える区切りで、慣習として付けます。パッケージを書く場合は、先頭を \ProvidesPackage に、\LoadClass\RequirePackage に置き換えれば、同じ骨格がそのまま .sty になります。

新しい流儀:キー・バリュー方式(expl3)

ここまでの \DeclareOption は今も完全に有効ですが、扱えるのは「あるかないか」のスイッチ型オプションが中心です。name=value のような キー・バリュー 型のオプションを素直に書きたい新規コードでは、LaTeX カーネルが備える \DeclareKeys でキーを宣言し、\ProcessKeyOptions で処理する方式が、現在の推奨アプローチです。これは expl3(LaTeX3)の l3keys を土台にした仕組みで、近年の LaTeX に標準で組み込まれています。

かつては同じことを l3keys2e パッケージで行っていましたが、その機能の中核は今ではカーネルに取り込まれており、新規コードではパッケージを読み込まずに \ProcessKeyOptions を直接使えます。とはいえ既存の解説や多くのパッケージはまだ \DeclareOption 流が主流なので、本ページの骨格を理解しておくことは引き続き重要です。キー・バリュー方式へ進むときは、最新の clsguide(「LaTeX2e for class and package writers」)の該当節を参照してください。

配布前に試す最小テスト

クラスは読み込まれた瞬間に文書全体へ影響するので、本文を書き始める前に小さなテスト文書で挙動を固めます。まず 10pt11pta4paperdraft などの標準オプションが土台クラスへ届くか、自分の独自オプションだけが自作コードで処理されるかを確認します。ここでエラーが出るなら、たいてい \ProcessOptions / \ProcessKeyOptions の位置、未知オプションの転送、または \LoadClass の順序が原因です。

latex
\documentclass[11pt,a4paper,draft]{myclass}
\begin{document}
\section{Smoke test}
本文の基準サイズ、用紙、下書き表示、見出し、余白を確認する。
\end{document}
  • ログに名乗りが出るか。 \ProvidesClass の日付・バージョンが .log に出ることを確認します。ファイル名とクラス名が違うと後で混乱します。
  • 標準オプションを壊していないか。 11pttwocolumn が無視されるなら、未知オプションを土台へ渡す処理を見直します。
  • 本文用マクロをプリアンブルで暴発させないか。 見出し・注・図表など、実際の文書で最初に触る要素を1つずつ置いてコンパイルします。
  • 配布前に \endinput 以降を空にする。 末尾にメモやサンプルを書き残すと、思わぬ文字列が読み込まれる原因になります。

配布する形まで考える

自作クラスは、動いた瞬間ではなく、他人が別の環境で読んだ瞬間に真価が問われます。最低限、.cls、短いサンプル文書、README、変更履歴を同じディレクトリに置き、サンプルがそのまま通ることを確認します。土台クラスへ転送するオプションと、自作クラスだけが受け取るオプションを README に分けて書くと、利用者は 11pta4paper がどこで効いているのかを追いやすくなります。サンプルには見出し、箇条書き、図表、参考文献を一つずつ置き、クラスが最初に壊しがちな要素をまとめて確認します。

terminal
myclass/
  myclass.cls
  sample.tex
  README.md
  CHANGELOG.md

配布前のテストでは、サンプルに \listfiles を入れてログへ読み込まれたファイルとバージョンを出します。これで、利用者が古い myclass.cls をローカルに置いていないか、必要なパッケージが想定どおり読まれているかを確認できます。クラスは文書全体の土台なので、本文マクロを足すよりも、読み込み順・オプション処理・ログの情報を丁寧にする方が、長く使う文書では効きます。