LaTeXでパッケージ(スタイルファイル)を自作する

　最近$\LaTeX$で文書を書く際，自作のパッケージが必要になった．作り方もわからず，いろいろ調べて大変だったので，この記事にまとめておこうと思う(書き方に統一感がない箇所もあるが，大目に見てほしい)．なお，クラスやパッケージという言葉の定義はいくつかの文献を見て自分なりに判断したもので，正しさは保証できない．詳しく知りたい人は参考文献[4]などを読んでほしい．


##パッケージとは
　$\LaTeX$で読み込むファイルはクラスファイル(.cls)，スタイルファイル(.sty)に大別できる．前者はjsarticle.clsのように`\documentclass{jsarticle}`で読み込んで文章の体裁を設定し，後者はgraphicx.styのように`\usepackage[dvipdfmx]{graphicx}`で読み込んでコマンドを追加する．それぞれを(ドキュメント)クラス，パッケージともいう．以下ではパッケージについて述べる．


##パッケージの構成
　[4]によるとパッケージは

<dl>
  <dt>Identification</dt>
  <dd>パッケージがどのバージョンの$\LaTeX$対応かを示し，パッケージ情報を記述する．</dd>
  <dt>Preliminary declarations</dt>
  <dd>いくつかのコマンドを定義し，他のファイルを読み込むこともできる．ここで定義したり読み込んだりするコマンドはふつう，オプションを宣言する際に必要となるものだけである．</dd>
  <dt>Options</dt>
  <dd>オプションを宣言，処理する．</dd>
  <dt>More declarations</dt>
  <dd>ここがパッケージのメイン．新しい変数やコマンド，フォントを宣言したり，他のファイルを読み込んだりする．</dd>
</dl>

という構成になっている．いくつかのコマンドを定義するだけの簡単なパッケージであれば**More declarations**にコマンドの定義だけを書いて，拡張子".sty"を付けて保存すれば良い．僕の場合はオプションによってコマンドの動作を条件分岐させるようなパッケージを書きたかったので**Options**が必要になった．
　自分専用のパッケージを作る分には**Identification**は書かなくてもいいと思うが，一応それも含めて，次は各部分の具体的な書き方についてみていこう．


##パッケージの具体的な書き方

###Identification
　パッケージを書くにあたり，まずパッケージそのものの情報を記述する．これは次のように書く．

```
\NeedsTeXFormat{<latex-format>}[<date>]
\ProvidesPackage{<package>}[<date> <other information>]
```
　`\NeedsTeXFormat`コマンドは必要な$\LaTeX$のバージョンを，`\ProvidesPackage`コマンドはパッケージ情報を宣言する．[6]によればこれを書いておくと警告を出したりしてくれるらしいが，自分専用のパッケージを書く際には必要ないかもしれない．
　`<latex-format>`はパッケージを使用するのに必要な$\LaTeX$のバージョンであり，欧文用であれば`LaTeX2e`，和文用であれば`pLaTeX2e`とする．と[6]に書かれているが，とりあえず`LaTeX2e`と書いておけばいいと思う．
　`<package>`はパッケージ名である．スタイルファイル名がtest.styなら拡張子をとって"test"とつけるのが良い~~と思うが，ファイル名test.sty，パッケージ名"te"としてTeXworksで試したところエラーは出なかった(ただし`\usepackage`でパッケージを読み込む際はスタイルファイル名(今の場合"test")を用いなければならない)~~．一応警告は出ていましたが，コンパイルはしてくれました．
　`<date>`は日付であり，2020/04/20のように`YYYY/MM/DD`という形で書く．
　`<other information>` については調べても特に情報がなかったので，自分のメモ(例えば，文書を使用する分野(MathとかPhysicsとか))を書けばいいと思う．
　`<date>`と`<other information>`に関しては任意なので，書かなくてもいい．

###Preliminary declarations
他のパッケージを読み込むには次のように書く．

```
\RequirePackage[<options-list>]{<package>}[<date>]
```
　機能としては，通常のtexファイルにおける`\usepackage`と同じだから説明は省く．パッケージ自作時に必要かどうかはわからないが，他のクラスを読み込む場合には`\RequirePackage`のかわりに`\LoadClass`と書けば良い．読み込む必要がなければ書かなくていい．

###Options
　個人的にはこれが一番知りたかった．次のように書く．

```
\DeclareOption{<option>}{<code>}
\ExecuteOptions{<options-list>}
\ProcessOptions\relax
```
　texファイルからパッケージを呼び出す際に`\usepackage[<options-list>]{<package>}`のようにいくつかのオプション`<options-list>`を指定して，パッケージの動作を呼び出し側が変更することができる．`\DeclareOption`はこの`<options-list>`の各々(`<option>`)を指定した際の動作`<code>`を記述する．パッケージに複数個のオプションを設定したければ`\DeclareOption`を複数個書けばよい．
　`\ExecuteOptions`コマンドでは，`\DeclareOption`で宣言したオプションのうち，デフォルトで(`\usepackage`で読み込む際にオプションに指定しなくても)実行されるものを指定する(たぶん)．
　`\ProcessOptions\relax`は**Options**の最後に書く．これは`usepackage`で指定された`<options-list>`に対応する`<code>`を実行する．`\DeclareOption`で宣言するだけでは，オプション指定された場合でも実行されないので，これは必ず書く．

###More declarations
　ここではコマンドの定義とかを行うが，これについてはよく知られていると思う．一応書いておくと，コマンドを定義するには

```
\newcommand{\<command-name>}[<number-of-parameters>]{<definition>}
```
とする．例えば，偏微分のコマンドは

```
\newcommand{\pdiff}[2]{\frac{\partial#1}{\partial#2}}
```
と定義できる．`$\partial{f}{x}$`と書けば$\frac{\partial f}{\partial x}$と表示される．


##自作パッケージの例
　僕が作ったパッケージを例として掲載する．これは`$\arcsin x$`と書く際，オプションに"arc"を指定(`\usepackage[arc]{elementary}`)すれば$\arcsin x$のような表記，"inv"を指定(`\usepackage[inv]{elementary}`)すれば$\sin^{-1}x$のような表記となるようなパッケージである．

```elementary.sty
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{elementary}

\newif\if@arc %2値変数@arcを定義
\DeclareOption{arc}{\@arctrue}
\DeclareOption{inv}{\@arcfalse}
\ExecuteOptions{arc}
\ProcessOptions\relax

%逆三角関数のコマンドを定義
\let\oldarcsin\arcsin
\let\oldarccos\arccos
\let\oldarctan\arctan
\renewcommand{\arcsin}{\if@arc \oldarcsin \else \sin^{-1} \fi}
\renewcommand{\arccos}{\if@arc \oldarcsin \else \cos^{-1} \fi}
\renewcommand{\arctan}{\if@arc \oldarcsin \else \tan^{-1} \fi}
\newcommand{\arccsc}{\if@arc \mathrm{arccsc} \else \csc^{-1} \fi}
\newcommand{\arcsec}{\if@arc \mathrm{arcsec} \else \sec^{-1} \fi}
\newcommand{\arccot}{\if@arc \mathrm{arccot} \else \cot^{-1} \fi}
%逆双曲線関数のコマンドを定義
\newcommand{\arsinh}{\if@arc \mathrm{arsinh} \else \sinh^{-1} \fi}
\newcommand{\arcosh}{\if@arc \mathrm{arcosh} \else \cosh^{-1} \fi}
\newcommand{\artanh}{\if@arc \mathrm{artanh} \else \tanh^{-1} \fi}
\newcommand{\arcsch}{\if@arc \mathrm{arcsch} \else \mathrm{csch^{-1}} \fi}
\newcommand{\arsech}{\if@arc \mathrm{arsech} \else \mathrm{sech^{-1}} \fi}
\newcommand{\arcoth}{\if@arc \mathrm{arcoth} \else \coth^{-1} \fi}
```
　このパッケージで利用したいくつかの便利なコマンドについて説明しておく．まず

```
\newif\if@bool
```
というコマンドにより2値変数`@bool`を定義できる．この変数の値(true，false)を設定するには

```
\@booltrue
\@boolfalse
```
のようにする．この変数を用いて条件分岐を行うには

```
\if@bool <code1> \else <code2> \fi
```
とすればよい([5])．
　なお，ここでは"@"の付いた変数を使ったが，texファイルでは"@"付きの変数は`\makeatletter`と`\makeatother`の間でしか扱えない．そのため，texファイルで勝手に値を変更してほしくない変数には，パッケージ(styファイル)で"@"を付けて定義しておくとよい．styファイルでは普通に扱える．
　次に

```
\let\copycommand\command
```
という形のコマンドであるが，これは定義済のコマンド`\command`を新しいコマンド`\copycommand`にコピーする．


##おわりに
　以上でパッケージの作り方については一通り説明できたと思う．説明不足なところもあるかとは思うが，そういった箇所は**参考文献**を参照してほしい．

##参考文献
[[1] LaTeX/Creating Packages](https://en.wikibooks.org/wiki/LaTeX/Creating_Packages)
[[2] とりぷる ぷぅ 技術メモ　[TeX]Class, Package](https://triplepulu.blogspot.com/2013/05/texclass-package.html)
[[3] The LaTeX Project: Core Documentation](https://www.latex-project.org/help/documentation/)
[[4] The LaTeX Project: Core Documentation/LaTeX2e for class and package writers](https://www.latex-project.org/help/documentation/clsguide.pdf)
[[5] すぐできる！ latex で if 文による条件分岐を使う方法。](https://beiznotes.org/latex-if/)
[[6] [改訂第7版]LaTeX2ε美文書作成入門](https://www.amazon.co.jp/改訂第7版-LaTeX2ε美文書作成入門-奥村-晴彦/dp/4774187054 "Amazon")