条件宏

条件宏

目标:我希望有一个宏,根据是否处于显示数学模式来替换不同的命令。具体来说,它应该在文本行中生成固定大小的尖括号,\langle ... \rangle但在显示的数学中生成可变大小的尖括号\left<...\right>

动机:宏应该是通用的,因为数学表达式可能经常在显示和非显示表达式之间移动(我编写教科书、编辑它、重新编辑等)。如果我每次在从显示数学移动或移至显示数学时都需要更改表达式代码,那么这将成为拼写错误的来源。上面带有尖括号的示例是物理文献中平均的标准符号。

第一次尝试在下面的 MWE 中。它适用于内联数学,但在显示模式下无法正确替换。LaTeX 分别根据$$\[和的使用情况\],做出“缺少 \right. 插入”或“错误的数学环境分隔符”的反应。批处理模式下的编译会生成输出,其中左括号的大小正确,但右括号的大小错误。此结果与 \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测试真的在内联数学和错误的但在显示环境\[中会测试为真,amsmath例如gather或当他们通过不align进入 displaystyle 时
$\displaystyle display math$
$$ display math$$

然而测试总是真的因为\ra表达式已经是内部的,或者 if\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当在数学模式下遇到 -delimiter 时,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

相关内容