LaTeXで定理や命題などのスペシャルな環境を作る

超はじめに

この記事のLaTeX文書にはバグがあります.具体的には相互参照の際に番号の表示がうまくいっていないというものです.
バグを解消し,コードを簡潔にし,機能を増やしたものを開発しましたので後日新しく記事にいたします.


はじめに

この記事ではLaTeXにて以下の9つの要請を実現できるコードの解説をします.使い方に関する記事は別で作ります.

(1)以下のような見た目の定理や命題,補題などの枠を作る.

最終的な見た目

(2)枠を作るソースコードは以下のようにしたい.(LaTeXでは\begin{}…\end{}みたいなやつを"環境"といいます.)

\begin{環境の名前}[labelの名前]{ステートメントの種類}{ステートメントの名前}
 主張など
\end{環境の名前}

「labelの名前」はいわゆる\labelコマンドに相当するものであとから\refなどのコマンドで相互参照ができるように名前を付けるもの.相互参照に要請する詳しい機能については後の(7)~(9)を見てほしい.
「ステートメントの種類」とは定理とか公理とか補題とかのこと.ここに既定のコマンド,例えばaxiomなどと入れれば(1)の画像の赤枠のようにAxiom 1.1のように表示される.そしてステートメントの番号が現れる.
「ステートメントの名前」とは(1)の画像の赤枠の(選択公理)の部分のことである.ここに入れた文言が枠の題名の横に表れる.

(3)枠のデザインは自由に一括で設定できるようにしたい.決まったパッケージで決まった枠を使うのではなく,自分で見た目を設定しようということである.また,枠の色やそもそも枠にするのではなく左だけに線を引くとか文末には決まった記号を置きたいとか薄くドラえもんの絵を印字したいとか,自由度を高めたい.しかもデザインの変更は容易であってほしい.例えば公理の部分の色は赤じゃなくて灰色にしたい,となった場合はプリアンブルの一部をいじるだけで文書内の公理枠は全部灰色に変更できるようであってほしい.Axiomではなく公理と表示させたい場合も同様.

(4)番号はセクション番号をn,そのセクション内での順番をmとしたときにn.mのように表示したい.ただしmはステートメントの種類によらずに通し番号にしたい.つまり「公理1.1→公理1.2→定義1.3→命題1.4→定理1.5→定義2.1→補題2.2→注意2.3→…」のようなカウントをしてほしい.しかも自動で.つまり命題を途中に差し込んだ場合でも自動で番号が振られ直されるようであってほしい.

(5)セクション番号がないただの主張のための枠も欲しい.つまり以下のようなものが欲しい.

ただしこの場合は番号を表示しないだけでなく番号は増減しないでほしい.

(6)Page Break,つまり(5)の画像のようにページをまたいでも枠がちゃんと表示されてほしい.

(7)相互参照において,(2)のソースコード中の[]オプションで,例えばchoiceと打てば自動で「axiom:choice」という名前のラベルが生成されてほしい.より具体的には公理環境を使った場合には指定したラベルの名前の前に「axiom:」とついてほしい,定理環境なら「th:」など.ソースコードでいえば

\begin{環境の名前}[choice]{axiom}{選択公理}
 数式のコード
\end{環境の名前}

と打てば「axiom:choice」という名前のラベルが作られて,あとから参照系のコマンドで参照できるようになっていてほしい.こうすることで以下のように\ref{axiom:}まで打った段階で予測変換にaxiom系統のラベルしか出てこないので探すのが楽になる.

(8)(7)において,参照系のコマンドはただ1通りであってほしい.つまり公理を参照するときは公理専用の参照用コマンド「\axiomref{}」などを用いるのではなく,全部1つの\refコマンドで参照したい.

(9)\refの出力形式は参照先のラベルが公理のラベルなら「\ref{axiom:choice}」などと打っただけで「Axiom 1.1」などと表示されてほしい.しかし参照先が補題なら「\ref{lem:zorn}」で「Lem 1.2」などと表示されてほしい.

要請の実現に向けて

実現に向けて行うことをスピーディかつ簡単に解説します.早く書き方を教えてくれ,という人はここは飛ばしてもいいでしょう.

枠の実装

(1)と(3)の要請のように枠を自作してしかもPage Breakも実装するためにtcolorboxパッケージを使います.プリアンブル(\documentclass…から\begin{document}の間の部分のこと)に以下のように書くのです.

\usepackage[many]{tcolorbox}

オプションのmanyはよくわかりませんがなにやらうれしい機能をこれ1つでたくさん付加してくれるようなのでテキトーに入れときます.

他にmdframedパッケージを使って枠を作るやり方もあります.しかしこれには以下のデメリットがあります.

  • Page Breakの設定が面倒

  • パッケージの最終更新が10年以上前(tcolorboxは2024年現在でも更新され続けている)

  • シンプルに使い方がムズイ

はじめ私はこちらで実装しました.うまくいくにはいきましたがPage Breakはどうしてもバグってしまいました.一方tcolorboxならほぼ何も考えずPage Breakしてくれます.Page Breakしないという設定も可能.


カウンターの実装

(4)の要請のようにカウンターを作るために自分でカウンターを定義します.しかし通し番号にしないといけない点やcleverefパッケージ(後述)による相互参照などの観点からここに少し工夫がいります.LaTeXでは

\newcounter{カウンターの名前}[親カウンター]

とすることで「カウンターの名前」という名前のカウンターが,既定の「親カウンター」の番号が上がると1にリセットされるようなカウンターとして作成できます.これを用いて今回は次のようにカウンターをたくさん定義します.

\newcounter{statementnum}[section]
\newcounter{axiomnum}[statementnum]
\newcounter{defnum}[statementnum]
\newcounter{thnum}[statementnum]
\newcounter{propnum}[statementnum]
\newcounter{lemnum}[statementnum]
\newcounter{cornum}[statementnum]
\newcounter{remnum}[statementnum]
\newcounter{exnum}[statementnum]
\newcounter{questnum}[statementnum]
\newcounter{prednum}[statementnum]

section,というのはLaTeX標準のセクション番号のカウンター名です.何もしなくてもsectionというカウンターはすでにデフォルトで定義されています.そこにまずstatementnumという名前のカウンターを定義します.まあ名前はなんでもいいですが.それを親カウンターとするように他のステートメント環境専用のカウンターを別個に定義します.statementnumというカウンターだけでいいんじゃないの?と思われるかもしれませんが,これは後述のcleverefパッケージによる相互参照の実装をするときに必要なのです.本当はこんなことしたくないのでstatementnumだけでうまくやる方法があれば教えてほしいです.

相互参照の実装

(7)と(8)の要請のように相互参照をするにはまずcleverefパッケージを使います.このパッケージを導入すると\cref{ラベルの名前}とコマンドを打つことで参照の出力形式を参照先のラベルによって変更することができます.細かい仕様は後程ソースコードをお見せしながら説明いたします.cleverefパッケージについて,以下を参照しました.

実装の手順

まずはプリアンブルの完成系をお見せします.長いのでここにはソースコードを貼らないでおきます.かわりにファイルを貼っておきます.

スタイルファイル形式ですがこれを丸ごとプリアンブルにコピペすれば動くはずです.コメントアウトの英語や日本語が弱弱しいのは御贔屓ください(笑)
ソースコードの上から丁寧に説明していきます.長くなると思うので飛ばし飛ばし読むことをおすすめします.

使用するパッケージの説明

\usepackage{xcolor}
\usepackage[dvipdfmx]{graphicx}
\usepackage{tikz}
\usepackage{ifthen} %Using \ifthenelse
\usepackage{etoolbox} %if else package of blank
\usepackage{amsthm} %Proof environment
\usepackage[many]{tcolorbox} %Insert tcolorbox package and its option

まずははじめの方のこいつらについて.xcolorはLaTeX文書に色を追加するパッケージです.これがないと全部白黒になるでしょう.graphicxはよくわかりませんがないとtcolorboxで作った枠が全部消滅します.tikzは枠の設定を細かくできるようにするためのパッケージです.ifthenはその名の通りifによる条件分岐を使えるようにするためのパッケージです.etoolboxもif条件分岐の追加ですが,

\begin{自作の環境名}[ラベルの名前]{ステートメントの種類}{ステートメントの名前}

と打った場合と

\begin{自作の環境名}{ステートメントの種類}{ステートメントの名前}

と打った場合の条件分岐ができる\ifblankというコマンドを使うためのパッケージです.amsthmは証明の環境を作るためのパッケージです.ここはカウンターとか参照とか無いので既存のパッケージに乗っかります.tcolorboxはまさに枠を自作するためのパッケージです.本来は枠を作るだけのパッケージなのですかね?しかしステートメントの枠を作るのに多く利用されます.

カウンターの実装

次にここ.

%Define counter
\newcounter{statementnum}[section]
\newcounter{axiomnum}[statementnum]
\newcounter{defnum}[statementnum]
\newcounter{thnum}[statementnum]
\newcounter{propnum}[statementnum]
\newcounter{lemnum}[statementnum]
\newcounter{cornum}[statementnum]
\newcounter{remnum}[statementnum]
\newcounter{exnum}[statementnum]
\newcounter{questnum}[statementnum]
\newcounter{prednum}[statementnum]
\renewcommand{\thestatementnum}{\arabic{section}.\arabic{statementnum}}

newcounterは前に説明したとおりです.次に\renewcounterの部分ですが,上のように\newcounterでカウンターを作ると自動で\the(カウンター名)というコマンドが生成されます.これは定義したカウンターのその時点での番号を表示するコマンドです.これを書き換えて現在のセクション番号も一緒に「1.5」のように表示させるコマンドに書き換えているのです.しかも表示形式はアラビア数字.後で説明しますが実はstatementnum以外のaxiomnumやdefnumといったカウンターは相互参照の兼ね合いで作らざるを得ないダミー変数です.表示に使うのはstatementnumだけで十分なので\renewcounterはstatementnumのものだけ用意しています.通し番号の方は実質statementnumというカウンターで制御しているということです.もちろん,通し番号ではなく公理は公理で,定義は定義で1から番号が別々に上がっていくようなものを作りたければこの限りではありません.このような番号のつけ方は参照性の観点から個人的に嫌な気持ちになりますが.

枠の色の設定

次にここ.

%Statement color
\definecolor{axiomcol}{rgb}{1,.8,.8}
\definecolor{defcol}{rgb}{1,.8,.8}
\definecolor{thcol}{rgb}{.8,.8,1}
\definecolor{propcol}{rgb}{.8,.8,1}
\definecolor{lemcol}{rgb}{.8,.8,1}
\definecolor{corcol}{rgb}{.8,.8,1}
\definecolor{remcol}{rgb}{1,1,.6}
\definecolor{excol}{rgb}{.8,.8,.8}
\definecolor{questcol}{rgb}{.8,1,.8}
\definecolor{predcol}{rgb}{1,.8,1}

これはステートメントの種類ごとに枠の色を設定する場所です.色を決めるだけなのでここでもう枠が完成する,なんてことはないです.\definecolor{A}{B}{C}でAという名前の色をBという「色の指定形式(RGBとかそういうこと)」でCのような色であると定義します,という意味ですね.例えば後から公理の枠の色を変えたいと思ったら,ここだけ変更すれば文書内の公理の枠すべての色が変わります.ひとつひとつ変える必要はないわけです.ちなみにRGBの順に0.8, 0.0, 1.0のように各色は0から1までの間で強さ指定します.全部1にすると真っ白になります.全部の色を混ぜると白になりますもんね.(光の場合の話です.絵具だと黒になりますが.)真っ赤にしたければ1.0, 0.0, 0.0にすればいいといった具合です..8とかは0.8の略です.こういう書き方も許されるようです.

枠の形状などの設定

次にここ.

%Foundamental design of tcolorbox
\tcbset{
    statement/.style={
            enhanced,
            coltitle=black,
            colframe=#1,
            boxrule=2pt,
            colback=white,
            breakable,
            sharp corners,
            attach boxed title to top left={xshift=3mm, yshift*=-\tcboxedtitleheight/2},
            boxed title style={
                    colframe=#1,
                    boxrule=2pt,
                    colback=#1,
                    sharp corners
                },
            after upper=\hfill $\square$
        }
}

ここはすべてのステートメントの種類に共通のデザインを定義する場所です.あとでtcolorboxパッケージを用いて枠のデザインを作るわけですが枠の形は冒頭お見せしたようにすべて同じです.違うのは色くらいですもんね.色の設定はあとで条件分岐ごとに行います.
tcolorboxで枠を作るときは以下のようにするのですが,

\begin{tcolorbox}[オプション]
 枠の中の文章など
\end{tcolorbox}

このオプションの部分に枠のデザインを入力するのです.しかしここが長くなったら見にくいし共通のデザインは決まっているのにすべての\begin{tcolorbox}のオプションに長い文言を入れるのはめんどくさいです.メンテナンスも大変.(例えば先端恐怖症だから枠の角は丸くしてくれ,と言われたらいちいち全部の\begin{tcolorbox}のオプションを見に行かなければなりません.)よって\tcbsetコマンドでこのオプションの部分を事前にカスタマイズしてstatementという名前のスタイルを作っているのです.これであとで

\begin{tcolorbox}[statement]

みたいにかくことで事前に作ったスタイルを読み込ませることができるのです.(正確にはもうちょい書くものがある.)
tcbsetの中身について説明します.
enhancedはtikzで見た目を制御するために必要な命令です.多分.よくわかってません.
coltitleはタイトルの文字の色です.今回はblack.
colframeは枠の線の色です.これはステートメントの種類によって変えたいところですね.しかしあとから\begin{tcolorbox}のオプションにいちいち書くのは面倒です.実はここを#1としておくと変数扱いになってあとから代入するという芸当が可能です.つまりここは#1としておいて公理環境を作るときに公理に対応する色を代入するんですね.
boxruleというのは枠の線の太さです.
colbackというのは枠の内部(位相空間的な意味での内部と思っていい)の背景色です.もし文書全体の背景色を別の色にしている場合は枠だけ白色になって浮きます.ここを文書の既定の色に自動的になるように設定することもできるんですけどめんどくさいので割愛.
breakable.これが1番欲しい機能です.これをここに書いておくだけで枠が自動的にページまたぎに対応します.しかし,現在のところtcolorboxの中にtcolorboxを入れた場合はbreakはうまく機能せずバグってしまうようです.tcolorboxの中にさらにtcolorboxを入れた場合にPage Breakできる方法をご存じでしたらご一報ください.
sharp cornersはその名の通り,枠の四隅を角ばらせます.個人的な好みに過ぎませんが.
attach boxed title to top leftは枠の左上にタイトル用の小さいボックスをこういう風に作ってねという命令です.

この中身の命令はこのボックスを右に3mm,下にボックスの縦の長さの半分の長さ,これだけ移動せよという命令です.これも個人的な好みです.
boxed title styleはその名の通りタイトルボックスの設定です.中身も見ればわかるコマンドかと思います.
after upperは枠の中身の最後の最後に付け加えることができる文や記号を設定できる命令です.個人的な好みでステートメントの末尾には白い四角を置きたいので今回は□を枠の中の最後の文の右端に置く設定をしています.

新環境の実装

次がいよいよ本題のステートメントの種類ごとの枠やカウンターの増幅,相互参照のラベルの設定をしているところです.ここは長いのでソースコードは貼りません.大雑把には

\newenvironment{新しい環境の名前}[オプションの個数][]{はじめの方で何を書くか}{おわりの方で何を書くか}

という\newenvironmentコマンドでstatesp(ステートメントスペシャル,の略のつもり)という環境を新たに作っています.これにより\begin{statesp}…\end{statesp}という構造の命令を自作し,本文で実行できるわけです.
オプションの個数というのは\begin{…}[こことか]{こことか}{こことか}に現れるオプションの数ということです.次の謎の[]は一つ目のオプションは必ず[]という角括弧になってますよ,という意味です.これを抜くとコンパイルに失敗します.よって[]をオプションでそもそも書かず,\begin{…}{A}{B}みたいに書いた場合は1つ目のオプションは無いと認識してくれます.{A}の部分が1つ目のオプションだ!とは認識されないわけです.そのため[]によるオプションは\newenvironmentでは1つしか指定できません.今回はこのオプションでラベル名を指定することにします.後から参照することがない命題などにラベルを振らなくてもよくなるということです.
はじめの方に何を書くか から 終わりの方で何を書くかの間に\begin{statesp}AAA\end{statesp}と書いたときのAAAが表示されます.事前に初めの方に書いておきたいものやAAAの前後に記述すべきものがあればここに書くということです.例えば

\newenvironment{nyannkocenter}{\begin{center}にゃんこ}{\end{center}}

というnyannkocenterという環境を作って

\begin{nyannkocenter}
 はかわいい!
\end{nyannkocenter}

とすると以下のように表示されるわけです.

話を戻します.\newenvironmentの{初めの方}{終わりの方}は大雑把には

\newenvironmrnt{statesp}[3][]{\begin{tcolorbox}}{\end{tcolorbox}}

としています.そして初めの方に色々と書いているわけです.ここを詳しく見ていきましょう.
statespというただ1つの環境で公理,定義,定理などの枠を作るのでどのステートメントの種類か,というのをオプションの第2引数(ひきすう)で指定するのですが,ここで指定されているものが何かを判定する必要があります.ここでifを使うのです.ifの使い方は見ればなんとなくわかるかと思います.ラフに書くなら次のようになります.

\newenvironment{statesp}[3][]{
if axiom と指定されたとき
...
\begin{tcolorbox}
else
if def と指定されたとき
...
\begin{tcolorbox}
else
if th と指定されたとき
...
\begin{tcolorbox}
...
else %なにも指定されなかったとき
...
\begin{tcolorbox}
}{\end{tcolorbox}}

pythonみたいにelseではなくelifみたいな感じで複数の分岐ができればもっとすっきりしたコードにできるんですけどね.そういうのがあればご一報願います.閑話休題.
if axiomと指定されたときと,最後のなにも指定されなかったときの部分を見ればあとは同じです.この2点それぞれを細かく見ていきます.まずはaxiomと指定された場合.
\ifblank{#1}とありますが,これは#1,つまり1つ目の引数である[]のオプション,今回はラベルの名前を指定する部分ですが,これが有るか無いか?を認識します.\ifblank{#1}{blankだったとき}{blankじゃなかったとき}みたいに書きます.blankだったときはシンプルにstatementnumカウンターを1個増やしておわりです.余談ですがこれにより他のaxiomnumやlemnumといったカウンターも同時に1上がります.これらはstatementnumの子カウンターだからです.blankではないときは以下のように書いています.

\refstepcounter{axiomnum}\label{axiom:#1} %Refference
\addtocounter{axiomnum}{-1}
\stepcounter{statementnum}

\refstepcounter{A}と打つとAという名前のカウンターを1個上げて,さらにこのコマンドのあとに\label{なんちゃら}と書くことによってこの「なんちゃら」という名前のラベルに追加で「カウンターAに付随するラベルです」という情報がつくようになります.あとで\refなどでこのラベルを参照すると,Aというカウンターであるという情報と,この時点でのカウンターAの値も参照できるようになるのです.参照のためだけに\refstepcounterとaxiomnumを用いたので即座にaxiomnumというカウンターの番号は\addtocounterというコマンドで1下げます.そして\stepcounterでstatementnumを1個上げてaxiomnumと今回登場しなかったdefnumやlemnumといった他のステートメント種に使うカウンターも軒並み,足並みそろえて増幅させます.これによって要請にある相互参照と通し番号の仕組みを同時に実現しているのです.ここで\label{axiom:#1}としておけばlabelの名前として指定したものの前に勝手にaxiom:が着いて要請の(2)に応えることができます.他のifの条件分岐ではここを\label{def:#1}などとすればいいのです.
次は

\ifthenelse{\equal{#3}{}}{
    \tcbset{
        blank/.style={title={\underline{Axiom~\thestatementnum}}}
    }
}{
    \tcbset{
        blank/.style={title={\underline{Axiom~\thestatementnum}~:~(#3)}}
    }
}
\begin{tcolorbox}[statement=axiomcol, blank]

となっていますね.これは#3,つまり3つ目の引数が空欄(といっても[]角括弧オプションとは違って省略はできないので,{}だけ書いて中に何も書かない,みたいな書き方をすることになります.)になっているかを判定します.#3はステートメントの名前ですね.ピタゴラスの定理とかクルルの次元定理とかそういうのを書く部分です.もし空欄だったら前半で\tcbsetによりtcolorboxのタイトルの表示はステートメント種と番号だけ表示する設定をしておきます.空欄でなければ適切な方法で名前も一緒に表示させます.~というのはただの半角スペース「 」を挿入する記号です.見栄え上の問題で入れているだけです.
最後にtcolorboxを使いますということを宣言します.ただし今回の条件分岐ではaxiomcol,つまり公理環境用に設定した色を使え,ということになります.ずっと前にも\tcbsetが出てきましたが一部#1とかいう変数になってましたよね.\begin{tcolorbox}のオプション内で上のようにstatement=axiomcolとすることで変数だった部分にaxiomcolを代入してね,という意味になります.これ,\tcbsetで複数の変数が用意された場合はここでどのように代入の記述をするんですかね?
さて最後のifの条件,なにも指定しなかった場合です.こうなってますね.

%If an environment name is not determined environment
    \ifblank{#1}{
        \relax
    }{
        \label{#1} %Refference
    }
    \ifthenelse{\equal{#3}{}}{
        \tcbset{
            blank/.style={title={\underline{#2}}}
        }
    }{
        \tcbset{
            blank/.style={title={\underline{#2}~:~(#3)}}
        }
    }
    \begin{tcolorbox}[statement=excol, blank]

最初の方の\relaxというのは「なにもするな,TeX」という記号です.ベン・ベッグマンみたいだね.条件の1個目はラベルを作成する必要がない場合ですが,ラベルがなければすることがないので\relaxを入れてなにもしません.何も書かなくても動きます.何もしてないよ,というのが分かりやすいから書いているだけです.
最後にこの場合のtcolorboxのオプションでスタイルを指定していますが色をexのものと同じにしています.これは好みです.私はexの色は灰色にしていてあまり目立たない色にしています.これと同じにすれば変な混同は起きないかな~くらいの意味しかありません.

証明環境の実装

証明用の環境を書きます.これは囲ったり番号をつけたりしないので簡単です.

%Proof environment
\renewcommand{\proofname}{\textit{pf}.)} %Change first style of proof
\renewcommand{\qedsymbol}{$\blacksquare$} %Change end style of proof
\makeatletter
\renewenvironment{proof}[1][\proofname]{\par
    \pushQED{\qed}%
    \normalfont \topsep6\p@\@plus6\p@\relax
    \trivlist
    \item\relax
    {
        #1\@addpunct{}}\hspace\labelsep\ignorespaces
}{%
    \popQED\endtrivlist\@endpefalse
}
\makeatother

\newenvironment{pfsp}{\begin{proof}}{\end{proof}}

前半ふたつは証明の際に現れる最初の文字を変えています.はじめは(証明)と表示させたい場合や最後はQ.E.D.と表示させたい場合はここをいじります.
\makeatletterというのは@という記号を文字として認識させますという宣言です.これにより新たに定義するコマンドやパッケージで既定の@を含むコマンドをコマンドであると認識させることができます.@を他のアルファベットと同じ扱いにしますという宣言といってもいいですね.
\renewenvironmentの部分は正直よくわかってないのですがamsthmパッケージの公式マニュアルの11ページのものを改造しました.これは友人にやってもらいました.

https://ftp.jaist.ac.jp/pub/CTAN/macros/latex/required/amscls/doc/amsthdoc.pdf

\makeatotherというのは@をもとの扱いに戻します,という意味です.\makeatletterの効果をここで打ち消すのです.やらなくてもいいとは思いますが一応.

相互参照の実装

次はこうなってますね.

%Refference
\mathtoolsset{showonlyrefs=true} %Give numbers of equation in equation and align environment only to refered them.
\usepackage[
    dvipdfmx,
    setpagesize=false,
    bookmarks=true,
    bookmarksdepth=tocdepth,
    bookmarksnumbered=true,
    colorlinks=true,
    linkcolor=blue,
    pdftitle={},
    pdfsubject={},
    pdfauthor={},
    pdfkeywords={}
]{hyperref} %Insert hyperlink into a document

\mathtoolssetというのはalign環境で必要もないのにすべての式に番号が振られるのを防ぎ,必要なものには付けられるようにするためのものです.
次のパッケージhyperrefというのは文書内の相互参照にハイパーリンク(ボタンを押すとその箇所に飛ぶやつ)をつけるやつです.\refコマンドなどにより参照した場合にハイパーリンクになってくれます.
オプションについてはよくわかりません.とりあえず全部書いて動いてるのでいいでしょう.ちなみに以下を参考にしました.

ただ,途中のcolorlinksでハイパーリンクの文字に色を付ける設定をしており,その色はlinkcolorで青にしています.リンクといえば青な気がするので.
次はこうなってますね.

\usepackage{pxjahyper} %PDFのしおり機能の日本語文字化けを防ぐ((u)pLaTeXのときのみかく)
\usepackage[
    noabbrev,
    capitalise,
    nameinlink,
]{cleveref} %Including label name into ref and coloring link name too

pxjahyperはよくわかりません.
次のcleverefは先に説明したように\refの参照先の\labelが何に引っ付いたラベルなのかによって表示形式を変えるために導入しているものです.どのように変えるのか?というのを次に書いているわけです.例えばこんな感じ

\crefname{axiomnum}{Axiom}{Axiom}
\Crefname{axiomnum}{Axiom}{Axiom}

下の大文字の方は念のため書いてるだけで多分いりません.なんでしょうねこれ.何を書いているかというと以下のようになってます.

\crefname{参照先ラベルがラベリングしているカウンター名}{出力冒頭に何を書くか}{出力冒頭に何を書くか}

最後ふたつは同じです.じつは最後ふたつは\refが文頭にあるかないかで変えることができるというものですが日本語なら関係ありません.
さて大切なのは「\refの参照先の\labelが"何"に引っ付いたラベルなのかによって表示形式を変える」ためにcleverefを導入したわけですがこの"何"というのは実はカウンターなのです.参照先の環境の名前や環境に使われているオプションの文字列などではないようです.creverefの仕様上,どうも参照先のラベルがラベリングしているものの認識はカウンターの名前を参照するようです.したがってわざわざstatementnumカウンター以外にカウンター名を定義し,\refstepcounterでカウンター名を\labelにラベリングさせる準備をしていたわけです.これで参照先がaxiomnumに引っ付いているラベルならAxiom (番号)のように表示できるわけです.しかも\refというコマンドだけで.参照のためだけにaxiomnumたちは存在しているので非常に無駄です.もし\refなどの参照コマンドの参照先の\labelがラベリングしている環境の名前や環境に使われている指定番目のオプション名などに応じて,\refの出力形式を自動で変更してくれるようなアイデア,パッケージなどがあればご一報ください.ソースコードがかなり短く,わかりやすくなります.
さて最後はこうなってます.

\newcommand{\refsp}[1]{\cref{#1}}

実はcleveref専用の\refコマンドがあり,それを\crefといいます.\refではなく\crefと書かないと参照先によって出力方法を変えてくれるという芸当はやってくれません.この¥crefというコマンドを\refspという名前で扱おうということで新しくコマンドを作っているだけです.コマンド名に統一感を持たせるためにやっているだけですので無駄だと感じたら削除しましょう.

おつかれさまでした.ソースコードの解説は以上です.

実装例

実際にスタイルファイルを用いてLaTeXを打ってみた結果とPDFにしたときの見た目がこちらです.
ちなみに極大イデアルの存在の証明やDedekind domainだがPIDではないものの例についての予想について触れています.

早く使いたい人へ(上級者(?)向け)

こちらが完成系のstyle fileになります.コマンドの競合などにお気を付けください.私の環境はtexlive2023,コンパイラはuplatexです.

動かない,意図したものにならない場合

このファイルでは\newcommandでコマンドを多く自作しています.万が一既に別の全く同じ名前のコマンドを自作していた場合や,それが起こっている他者のパッケージを使っていると(コマンドの被りのことを競合といいます.)うまく動作しないことがあります.
また,根本的にコンパイラや設定に問題がある場合もあります.その場合は私の以下の記事や他の方の記事,TeXのwikiなどをご覧ください.

また,どうもうまくいかないとか,ここの記述が分からない,などがあればお気軽に私にご連絡ください.TwitterのDMとかこのnoteのコメントでも大丈夫です.

この記事が気に入ったらサポートをしてみませんか?