条件付きマクロ

条件付きマクロ

ゴール:表示された数式モードかどうかに応じて異なるコマンドを置き換えるマクロが必要です。特に、テキスト行では固定サイズの山括弧を生成し、\langle ... \rangle表示された数式では可変サイズの山括弧を生成する必要があります\left<...\right>

モチベーション:数式は表示される式と表示されない式の間で頻繁に移動される可能性があるため (教科書を書いて、編集して、再編集するなど)、マクロは汎用的である必要があります。表示される数式からまたは表示される数式に移動するときに、そのたびに式コードを変更する必要がある場合、タイプミスの原因になります。上記の山括弧の例は、物理学の文献で平均化を表す標準的な表記法です。

最初の試みは、以下の MWE にあります。インライン数式では機能しますが、表示モードでは正しく置換されません。LaTeX は、またはとの使用に応じて$$\[それぞれ「Missing \right. insert」または「Bad math environment delimiter」で反応します\]。バッチ モードでコンパイルすると、左括弧のサイズは正しいが、右括弧のサイズが間違っている出力が生成されます。この結果は、\def または \newcommand の使用には依存しません。角括弧でも同じであることがテストされています[...]

システム:Mac OS 12.7.2.、LaTeX: <これは pdfTeX、バージョン 3.141592653-2.6-1.40.24 (TeX Live 2022) (プリロードされた形式 = latex) 制限付き \write18 が有効です。拡張モードに入ります (./mwe.tex LaTeX2e <2021-11-15> パッチ レベル 1 L3 プログラミング レイヤー <2022-02-24>>

現在はMWEです:

\documentclass{article}
\def \la{\ifinner \langle \else \left< \fi }
\def \ra{\ifinner \rangle \else \right> \fi }
\begin{document}
The macros work in the text line: $\la \int \Omega_n^2 dt \ra$, 
but do not in the displayed math. Obviously, the 
false text is not expanded properly, but why?  
\[
\la \int \Omega_n^2 dt \ra 
\]
\end{document}

答え1

このアプローチは使わないことをお勧めします。一般的に「正しいこと」は行われません。

いずれにせよ、顧客は常に正しいので、amsmath \if@display条件を活用できます。

\documentclass{article}
\usepackage{amsmath}

\makeatletter
\newcommand{\la}{\if@display\left\fi\langle}
\newcommand{\ra}{\if@display\right\fi\rangle}
\makeatother

\begin{document}

The macros work in the text line: $\la \int \Omega_n^2 \, dt \ra$,
and also in displayed math
\[
\la \int \Omega_n^2 \, dt \ra
\]
\begin{align}
I=\la \int \Omega_n^2 \, dt \ra
\end{align}
\begin{gather}
I=\la \int \Omega_n^2 \, dt \ra
\end{gather}

\end{document}

ここに画像の説明を入力してください

答え2

\ifinnerTeX の状態の低レベルの側面をテストしますが、基本的に、ドキュメント レベルの要素に関連して TeX で役立つことは何も行いません。

ここでは、\laテストで真実インライン数式と間違いでは、またはなどの表示環境\[ではtrueと判定されますが、 notを介してdisplaystyleに入ると、amsmathgatheralign
$\displaystyle display math$
$$ display math$$

しかし、テストは常に真実\ra式がすでに内部モードであったか、または開始時に false であった場合はが\ifinner実行\laされ\left< 、左と右のペア内のすべての計算が内部モードであるため true が設定されます\ifinner。したがって、一致する は実行されません\right

また、\left..\right水平方向の間隔に影響するため、ストレッチが不要な場合には避ける必要があります。

mathtools左右の水平間隔も修正する、より堅牢なメカニズムが提供されます。

ここに画像の説明を入力してください

\documentclass{article}
\def\test{\relax\ifinner T\else F\fi}

\usepackage{mathtools}

\DeclarePairedDelimiter\ang\langle\rangle

\begin{document}

a $\test  \ang{\int \Omega_n^2 dt}  \ang[\big]{\int \Omega_n^2 dt}$

\[
\test \ang{\int \Omega_n^2 dt}  \ang*{\int \Omega_n^2 dt}  \ang[\Big]{\int \Omega_n^2 dt}
\]

\begin{equation}
  \test \ang{\int \Omega_n^2 dt}  \ang*{\int \Omega_n^2 dt} \ang[\Big]{\int \Omega_n^2 dt}
\end{equation}

\begin{gather}
  \test \ang{\int \Omega_n^2 dt}  \ang*{\int \Omega_n^2 dt} \ang[\Big]{\int \Omega_n^2 dt}
\end{gather}
\end{document}

答え3

TeX は、数式モードで区切り文字に遭遇すると、タイプ設定モードを「inner」に切り替えます\left

つまり、問題は\ifinner適切なタイミングで拡大することにあるようです。

を使用する\expandedと、\ifinnerタイプセットの前に -tests を評価し、タイプセット モードを切り替えることができます。

\documentclass{article}
\newcommand*\la{\ifinner\else\expandafter\left\fi\langle}%
\newcommand*\ra{\ifinner\else\expandafter\right\fi\rangle}%
\begin{document}
The macros work in the text line: $\la \int \Omega_n^2 dt \ra$, 
and also do work in the displayed math.
\[%
\expanded{\la \unexpanded{\int \Omega_n^2 dt} \ra}
\]%
\end{document}

\la状況によっては、このよう\raにして\langle/\left\langleおよび\rangle/ が完全に拡張される状況が\right\rangle問題になる可能性があります。

これらをマクロでラップすること\unexpandedもできます:

\documentclass{article}
\newcommand\inangle[1]{%
  \expanded{%
    \ifinner\else\unexpanded{\left}\fi\unexpanded{\langle}%
    \unexpanded{#1}%
    \ifinner\else\unexpanded{\right}\fi\unexpanded{\rangle}%
  }%
}%
\begin{document}
The macros work in the text line: $\inangle{\int \Omega_n^2 dt}$, 
and also do work in the displayed math.
\[\inangle{\int \Omega_n^2 dt}\]
\end{document}

ここに画像の説明を入力してください

警告:

すでに述べたようにデビッド・カーライルの回答ただし、これらのアプローチは、実際には表示モードでタイプセットされず、 で選択された表示スタイルを使用してインライン モードでタイプセットされる LaTeX 環境では失敗します\displaystyle

関連情報