パッケージにおけるマクロ定義用マクロの使い分け

パッケージにおけるマクロ定義用マクロの使い分け

- S. Ichijo の投稿
返信数: 1

パッケージにおけるマクロ定義用マクロの使い分け

\defか、それとも\newcommandか\providecommandか\DeclareRobustCommandか、はたまた\NewDocumentCommandか\ProvideDocumentCommandか\DeclareDocumentCommandか

パッケージを書かれた経験のある方に質問です。 件名の通りなのですが、パッケージでのマクロ定義に以下のどれを使うのが適切なのかよくわからない場合があり、皆様の「使い分け方」をご教示いただきたいです。 ・ \def ・ \newcommand ・ \providecommand ・ \DeclareRobustCommand ・ \NewDocumentCommand ・ \ProvideDocumentCommand ・ \DeclareDocumentCommand など

各マクロの挙動の差異自体は概ね把握していますが、パッケージでマクロの定義をする場合の使い分け方がうまく理解できておらず、ぜひアドバイスを頂きたいです。

背景

背景としましては、研究室の後輩向けに、各種レポートや卒論、修論、博論等の論文など用のスタイルファイル(とその説明書)を作っているのですが、特に「少なくとも自分は知らないが、既存のパッケージで提供されているかもしれない」ような名前の新たなマクロを定義する際、どれを使うべきか悩んでいます。 当然、既存のパッケージで提供されていることが知られているマクロ名、例えば、\ruby のような名前であれば当然provide~系で定義すべきでしょうが… 「既存のパッケージで提供されていると聞いたことはないけど、名前がシンプルなので被る可能性も否定しきれない」というような名前の場合はどうすべきなのでしょうか。 ※例えば、\figref のような名前です。

無難にnew~系で定義して、被っていることがわかるようにするべきなのかなとも思いましたが、後輩にはLaTeX初心者が多く、エラーはなるべく出したくないのが本心です。 そこで、 ・ 被るということは、恐らく入れた他のパッケージで提供されているマクロの方を使用したいケースが多いであろうと予想し、こちらはprovide~系で定義する とも考えましたが、万が一意図せず他のパッケージを入れていた場合、「説明書にあるマクロを使ったら違う出力になった」のような問題も出てきそうです。 とはいえ、 ・ こちらが意図しない挙動を防ぐべく、\defやdeclare~系で半ば強引に定義してしまう というのもやや危険に感じてしまいます。

また、各分類のマクロ(new~系やprovide~系)のいずれかに決めたとしても、例えばprovide~系であれば ・ \providecommand と ・ \ProvideDocumentCommand のどちらを使用すべきかも迷います。当然xparseの\ProvideDocumentCommandでしかできない(ないし\ProvideDocumentCommandの方が実装が容易な)ケースなら迷わず\ProvideDocumentCommandを使用しますが、「どっちでも書ける」ような場合はどちらを使えばよいものなのでしょうか。 基本的に~DocumentCommandで統一して構わないでしょうか。

総括

私も初心者に毛が生えた程度であり、また他人が使うパッケージを書くのは初めてなため、煮詰まってしまっています。 ちょっとしたアドバイスでも十二分にありがたいので、上のような状況の場合 ・ new~系・provide~系・declare~系のどれを採用すべきか ・ 標準のマクロ定義用マクロと、xparseの~DocumentCommandの使い分け の2点について、いずれかだけでも構いませんので、是非ともご教示お願いいたします。

S. Ichijo への返信

Re: パッケージにおけるマクロ定義用マクロの使い分け

- 和田 勇 の投稿

誰も答えていないので、ここ数日考えていたことを、叩き台として投稿します。

Table of Contents

  1. new~系・provide~系・declare~系のどれを採用すべきか
    1. 例えば、\ruby のような名前であれば当然provide~系で定義すべきでしょうが …
    2. 例えば、\figref のような名前 …
    3. 初心者にエラーを出させたくない
    4. 被るということは、恐らく入れた他のパッケージで提供されているマクロの方を使用したいケース
  2. 標準のマクロ定義用マクロと、xparseの~DocumentCommandの使い分け

new~系・provide~系・declare~系のどれを採用すべきか

  • 懸念される問題を排除が目的であれば「同名」宣言時にエラーになる \new系だと考えています

  • それ以外の方法は、副作用を誘発する可能性があるということを承知の上で使用してもらう

    • あくまでも「使用禁止」と宣言しないこと!!副作用もあるけれど便利な面もあるので。

例えば、\ruby のような名前であれば当然provide~系で定義すべきでしょうが …

個人的には「しない」だろうな。エラー表示をさせないよう工夫させるより、 共同利用環境を整備し、どこで処理しても同じ結果が得られるようにしておく。

  • 昨今のハードウェアの進歩もあり texlive を full でインストール
  • 共同利用するスタイルファイルや TEXMFHOME TEXMFLOCAL 等で利用できるよう整備
  • バージョン管理ソフトを併用し、更新内容を利用者が容易に更新できるよう整備しておく
  • 共同利用するものは \input で取り込む方法などを検討

例えば、\figref のような名前 …

  • これは \label との関係だと思うので「fig:hoge:nantokakantoka」という ように\XXXXref で使いやすいようにキーワードなどを「:」で区切ったら良いと思います。

初心者にエラーを出させたくない

  • これは逆です。「体罰だと思われるかもしれませんが」 初心者のうちに「どう記述すればエラー」になることを経験させ、 対処方法を身につけさせるよう指導したら良いと思います。

被るということは、恐らく入れた他のパッケージで提供されているマクロの方を使用したいケース

  • マクロ名などのコンフリクト等の問題は、接頭辞として 「my」とか研究室、 プロジェクトなどの略語を使われたら良いと思います。

  • また調べる術を指導されたらいかがでしょうか

  • texdoc の使い方

  • kpsewhich の使い方
  • texlive 同梱ではないのですが ripgrep / ripgrep-all の併用

    • 対象ファイルのパスは、texdoc -l / kpsewhich / ログファイルから取得し 以下のようなコマンドの出力結果らめぼしいものを探し、詳しくは texdoc なので調べる ….

      rg ホゲホゲ 対象ファイルのパス
      rga ホゲホゲ 対象ファイルのパス
      

標準のマクロ定義用マクロと、xparseの~DocumentCommandの使い分け

  • 規定値とかの考慮がなければ「標準のマクロ定義用マクロ」をベースに
  • 規定値を考慮するなら
    • 「標準のマクロ定義用マクロ」では表現し辛いなら「xparseの~DocumentCommand」かしら