TeXのカスタマイズをnewcommandでのりきる方法


$\TeX$のマクロが難しい。
@とかあるけどよくわからない。簡潔に済ましたい。

そんな絶望と希望から模索して編み出した方法です。

はじめに

$\TeX$の最も簡単なマクロはおそらく、\newcommandを使う方法ではないでしょうか。なので、一度は使ったことのある人(内容がわからなくても、コピペで使用した人)はかなりいるかと思います。もちろん派生した\renewcommandも含めてです。

\newcommandは自分で新たに$\TeX$のコマンドを定義することができるコマンドです。非常に単純なコマンドであるため、使用に対する壁は低いと思います。この記事や、この記事を見ることで、\newcommandについて詳しく記述されています。

この\newcommandをプログラムの関数の様に使うのが今回の趣旨です。プログラムの関数はユーザーにより呼び出されれば、その内容が実行され、プログラムの結果に反映されます。\newcommandをこの関数のように呼び出し、$\TeX$の環境そのものに影響を与えようというものです。

\newcommand

まずは...

少しだけ\newcommandについておさらいです1。使い方は以下の通りが基本です。

\newcommand{New Command Name}[Number of Arguments]{Definition}

New Command Nameのところに新しいコマンドの名前を入れ、何個引数をとるのかをNumber of Argumentsの部分に書き込み、最後にコマンドが実行された時にどんな挙動をするのかをDefinitionに書きます。

例えば、以下のように定義したとします2。定義場所は、\begin{document}3にしましょう。

Letter.tex
\newcommand{\Letter}[2]{#1さんから#2さんへお手紙が届きました。}

引数は#番号Definitionのなかで扱います。
そして、以下のように使います4

Letter.tex
\Letter{Alice}{Bob}

すると、以下のように出力されます5

これで\newcommandについては完璧です。と、言いたいところですが後一つ知っておくと便利でしょう。上の例で、手紙がいつ届いたのかを記録したいとします。そんな時は、

Letter_v2.tex
\newcommand{\Letter}[3][\today]{#1 #2さんから#3さんへお手紙が届きました。}

としましょう。2つ目のオプション部分に\todayコマンドが入っています6。これは1番目の引数のデフォルト値となり、\Letterコマンドが実行された時は、#1の部分に\todayの結果が帰ってきます。

以下2つのコマンドを実行して見ます。

Letter_v2.tex
\Letter[April 11, 2019]{Mallory}{Bob}

\Letter{Alice}{Bob}

デフォルト引数への値の渡し方はコマンドのオプションの様にします。
この結果は、以下の様になります7

さっそく実践

この\newcommandをどの様にすれば、$\TeX$をカスタマイズできるのか。
答えは単純です。この\newcommand内で色々な処理をしてしまえばいいのです。

例えば、タイトルについて考えて見ましょう。デフォルトの場合は、

maketitle.tex
\documentclass{article}

\title{Secret Protocol}
\author{Alice and Bob}
\date{\today}

\begin{document}
\maketitle
\end{document}

とすれば、

の様に表示してくれます。これをもう少し違った形にしたいと思います。

タイトルの表示は太字でもう少し大きく表示させ、著者については右寄せで表示しましょう。日付は著者の前につける様にします。この場合、

MyTitle.tex
\documentclass{article}
\newcommand{\mytitle}[2]
{%
\begin{center}
{\LARGE\bf#1}
\end{center}
\begin{flushright}
\today\ \ #2
\end{flushright}
}%
\begin{document}
\mytitle{Secret Protocol}{Alice and Bob}
\end{document}

とすれば、

となります。この操作は\renewcommandやより複雑なマクロにより簡潔に行うことができるのでしょうが、上に示した例の場合、自分が理解できる範囲で$\TeX$で用意された形式を変更することができます。

さらに、chapterやsectionといった用意されたコマンドではなく、Markdownの様にわかりやすい見出しをつけたい場合も有効です。例えば、

MyHeading.tex
\documentclass{article}
\newcommand{\HeadingOne}[1]
{
\noindent
\rule[-0.7zw]{1zw}{2.3zw}
{\Large \bf #1}

\vspace{-1zw}\rule[0.03zw]{\linewidth}{0.1zw}

}
\begin{document}
\HeadingOne{Interference by Mallory}
Bob has received an e-mail from Mallory. The e-mail is dangerous. Therefore, Alice has warned to him today.
\end{document}

とすれば89

と表すことができます。

最後に

\newcommand内のスペースや、改行は有効であることから、この様なことが実現できるのです10。この様なオリジナルの\newcommandをスタイルファイルに保存して、\usepackageで呼び出せば111回限りの使用ではなく、何回でも使い続けることができます12

どうでしょうか13


  1. 少しだけと言いながらほぼ全てを説明。知ってるよって人は次の章へ。 

  2. このコマンドは、おそらく事務で郵便を管理している人には便利かもしれませんね!! 

  3. \begin{document}より前をプリアンブル(preamble)と呼んでいる。 

  4. 当たり前ですが、\begin{document}より後で使うことを想定しています。 

  5. LaTeXITで表示するのが便利ですね。簡単にプリアンブルを編集でき、画像の出力をしてくれるので、こんな表現あったっけと思ったときや、テストしてみようと思ったときは使ってみるといいです。「標準で日本語でないよ!」という方は、環境設定→プログラムで、latex+dvipdf出力にし、LaTeXをplatexへ、dvipdfをdvipdfmxに変更すると良いでしょう。さらにプリアンブルにデフォルトで入っているinputenc packageはコメントアウトするか、消し去ってしまえばOkです。 

  6. タイプセットした日の日付を出力してくれる。 

  7. 「え?Bob危ない奴から手紙もらってるな!」と思った方は、その道の方なんですね。「何言ってるの?」という人はコチラ 

  8. \ruleってなんぞ、と思った方へ。このコマンドは\rule[Height to Insert]{Height}{Width}とすることで、好きな高さ(Height to Insert)に好きな太さ(Height)で好きな長さ(Width)の線を引けます。ちなみにzwという単位は、和文1文字文の幅です(zhは高さ)。そして、\linewidthは文字がかける領域の横幅の長さを表します(よく図の貼り付けで、横いっぱいに図を表示したいときに使う)。 

  9. \vspaceってなんぞ、と思った方へ。高さを調節するコマンドであり、\vspace{Height}Height分だけ縦方向にスペースを下に空けます。「あれ、例ではマイナスついてるけど。。。?」と思った方、マイナスをつけるということは"マイナス分下に空ける" = "その分上に戻す"ということになります。 

  10. とは言え、この方法が推奨されているかどうかは知りませんし、コンパイル時間がこれにより長くなって文句を言われても知りません。 

  11. 「え?どうやるの」って方へ。例えば、上の例で出したMyHeading.texのプリアンブルに記述された\newcommandの内容をMyHeading.styとか適当に名前つけたファイルに保存します。このファイルを$\TeX$ファイルで\usepackage{MyHeading}で呼び出せば、\HeadingOne{}は有効になります。注意としては、\usepackageが探せる範囲が限られていることです。一般的なスタイルファイルと同じところ(環境によってどこにあるか違うから自分で探してください→参考)か、コンパイルしたい$\TeX$ファイルと同じところにおけば大丈夫です。 

  12. なんか、CSSみたい。 

  13. この記事に書かれている内容を"カスタマイズ"と呼ぶかどうかは議論中です。