條件宏

條件宏

目標:我想要一個宏,根據是否處於顯示的數學模式來替換不同的命令。特別是,它應該在文字行 中產生固定大小的尖括號,\langle ... \rangle但在顯示的數學中產生可變大小的尖括號\left<...\right>

動機:巨集應該是通用的,因為數學表達式可能經常在顯示和不顯示的表達式之間移動(我編寫教科書,編輯它,重新編輯等)。如果我每次從顯示的數學中移動表達式代碼或將其移至顯示的數學時都需要更改表達式代碼,這將是拼寫錯誤的根源。上面有尖括號的例子是物理文獻中求平均值的標準表示法。

第一次嘗試位於下面的 MWE 中。它適用於內聯數學,但在顯示模式下無法正確替換。 LaTeX 分別根據$$or\[和的使用情況,對「缺少 \right.insert」或「錯誤的數學環境分隔符號」做出反應\]。批次模式下的編譯會產生左括號大小正確但右括號大小錯誤的輸出。此結果不依賴 \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

\ifinner測試 TeX 狀態的低階方面,但它基本上不會在 tex 中對任何文件級元素做任何有用的事情。

在此處\la測試中真的在內聯數學中和錯誤的但會在顯示環境\[中測試 true,amsmath例如gatheralign當它們通過
$\displaystyle display math$not進入顯示樣式時
$$ display math$$

然而考驗總是真的in\ra因為表達式已經是內部的,或者如果\ifinner在開始時為 false\la將執行\left< ,這將設為\ifinnertrue,因為左右對中的所有數學都處於內部模式。所以你永遠不會執行匹配\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

\left當在數學模式下遇到 - 分隔符號時,TeX 將排版模式切換為「內部」 。

因此,問題似乎在於\ifinner在正確的時間擴張。

您可以在進行更多排版之前使用\expanded-tests\ifinner進行評估,並由此切換排版模式:

\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 環境中失敗,在 LaTeX 環境中,內容實際上不是在顯示模式下排版,而是在內聯模式下排版,並透過 來選擇顯示樣式\displaystyle

相關內容